var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"), margin = { top: 30, right: 130, bottom: 50, left: 340 }; const x = d3.scaleLinear().range([margin.left, width - margin.right]).domain([2013, 2017]); const y = d3.scaleLinear().range([height - margin.bottom, margin.top]); d3.json("yearNetwork.json", function (error, json) { if (error) throw error; y.domain([0, d3.max(json.networkLines, d => d.max)]); var line = d3.line().x(function (d) { return x(d.year); }).y(function (d) { return y(d.value); }); const networkLines = json.networkLines; const svg = d3.select("svg"); const colors = { HBO: "black", Netflix: "#D32F2F", NBC: "#ffc107", "FX Networks": "#0097a7", ABC: "#00BFA5", CBS: "#00BCD4", FOX: "#3f51b5", Showtime: "#C5CAE9", AMC: "#D32F2F", PBS: "#B39DDB", Amazon: "#ffc107", "Nat Geo": "#ff9800", Hulu: "#00BFA5" }; svg.append("g").attr("class", "lineChart"); const highlight = ["HBO", "Netflix"]; svg.select("g.lineChart").selectAll("path.segment").data(networkLines.sort((a, b) => a.total - b.total)).enter().append("path").attr("d", d => { return line(d.line); }).style("stroke", (d, i) => { return colors[d.network] || "grey"; }).style("stroke-dasharray", (d, i) => { return highlight.indexOf(d.network) !== -1 ? "none" : "2, 4"; }); /* Code below relevant for annotations */ let previousNY = 0; const labelAnnotations = networkLines.sort( //sort annotations by last data point for ordering (a, b) => b.line[b.line.length - 1].value - a.line[a.line.length - 1].value).reduce((p, c) => { //push annotation down if it will overlap const ypx = y(c.line[c.line.length - 1].value); let ny; if (ypx - previousNY < 10) { ny = previousNY + 15; } p.push({ note: { label: c.network, orientation: "leftRight", align: "middle" }, y: ypx, x: width - margin.right, dx: highlight.indexOf(c.network) !== -1 ? 20 : 5, id: c.network, color: colors[c.network], disable: ["connector"], ny //use ny to directly place the note in xy space if needed }); previousNY = ny || ypx; return p; }, []); const axisAnnotations = json.networkLines.filter(d => d.network === "HBO")[0].line.map(d => ({ note: { label: d.year, align: "middle", lineType: "none" }, type: d3.annotationXYThreshold, ny: 190, className: "axis", y: 190, x: x(d.year), subject: { y1: y(0), y2: y(d.value) } })); const labels = networkLines.filter(d => highlight.indexOf(d.network) !== -1).reduce((p, c) => { p = p.concat(c.line.map(d => { return { network: c.network, year: d.year, value: d.value }; })); return p; }, []); const badgeAnnotations = labels.map(d => { return { subject: { text: d.value, radius: 12 }, color: colors[d.network], type: d3.annotationBadge, x: x(d.year), y: y(d.value) }; }); const makeAnnotations = d3.annotation().type(d3.annotationLabel).annotations([...labelAnnotations, ...axisAnnotations, ...badgeAnnotations]); d3.select("svg").append("g").attr("class", "annotation-group").call(makeAnnotations); svg.append("line").attr("class", "baseline axis").attr("x1", x(2013)).attr("x2", x(2017)).attr("y1", y(0)).attr("y2", y(0)).style("stroke", "lightgrey"); });