Published
Edited
Mar 6, 2020
Importers
Insert cell
Insert cell
getMultiLineGraph = (data, options) => {
const { height, margin, width, yRange, xRange, xLabel } = options;
let T, X, Y;

const xAxis = d3.scaleLinear().domain(xRange).range([margin.left, width - margin.right]);
const yAxis = d3.scaleLinear().domain(yRange).range([height - margin.bottom, margin.top]);

const svg = d3.select(DOM.svg(width, height));

svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(xAxis))
.call(g => g.select(".tick:first-of-type text").text(xLabel));

svg.append("g")
.attr("transform", `translate(${margin.left - 12},0)`)
.call(d3.axisLeft(yAxis).ticks(8))
.call(g => g.select(".domain").remove());
// create legend
// based on https://www.d3-graph-gallery.com/graph/custom_legend.html
// and https://stackoverflow.com/questions/41090920/how-to-position-the-legend-in-a-d3-chart
// display only elements with a label
const legendData = data.filter(d => d.label !== undefined)
const legend = svg.selectAll('.legend').data(legendData)
.enter().append("g")
.attr("class", "legend")
.attr("transform", "translate(" + (width - 300) + "," + -80 + ")");
legend
.append("circle")
.attr("cx", 100)
.attr("cy", (_d,i) => 100 + i*25 )
.attr("r", 7)
.style("fill", d => d.color )
legend
.append("text")
.attr("x", 120)
.attr("y", (_d,i) => 100 + i*25 )
.style("fill", d => d.color )
.text(d => d.label)
.attr("text-anchor", "left")
.style("alignment-baseline", "middle")
for (let i=0; i<data.length; i++) {
const { x: xData, y: yData, size, color } = data[i];
for (let j=0; j<size; j++) {
// TODO ensure that yData[i] is vector
const path = svg.append("path")
.attr("fill", "none")
.attr("stroke", color)
.attr("stroke-width", 1.55);
path.attr("d", d3.line().x(xAxis).y((_, i) => yAxis(yData[i][j]))(xData));


}

// TODO add custom interactive graph elements
}
return svg.node();
}
Insert cell
{
const value = x;
const lines = [];
for (let i=0; i<3; i++) {
const line = { x: [], y: [], size: 1, color: colors[i], label: `line ${i}` }
for (let j=0; j<10; j++) {
line.x.push(j);
line.y.push([x*i]);
}
lines.push(line);
}
return getMultiLineGraph(lines, {
width: width,
height: 420,
margin: {top: 20, right: 30, bottom: 30, left: 40},
xRange: [0, 1],
yRange: [0, 10],
xLabel: 'time'
})
}
Insert cell
x
Insert cell
viewof x = html`<input type=range min=0 max=1 step=any>`
Insert cell
d3 = require("d3@5")
Insert cell
colors = d3[`schemeCategory10`];
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more