svg = {
const svg = d3.select(DOM.svg(width, height));
const x = d3.scaleLinear()
.domain(d3.extent(data, d => d.x))
.range([0, width - margin.left - margin.right])
.nice();
svg.append("g")
.classed("axis x-axis", true)
.attr("transform", `translate(${margin.left}, ${height - margin.bottom})`)
.call(d3.axisBottom(x));
const y = d3.scaleLinear()
.domain(d3.extent(data, d => d.y))
.range([height - margin.top - margin.bottom, 0])
.nice();
svg.append("g")
.classed("axis y-axis", true)
.attr("transform", `translate(${margin.left}, ${margin.top})`)
.call(d3.axisLeft(y));
const gView = svg.append("g")
.classed("view", true)
.attr("transform", `translate(${margin.left}, ${margin.top})`);
const line = d3.line()
.x(d => x(d.x))
.y(d => y(d.y));
gView.append("path")
.datum(data)
.classed("data", true)
.attr("d", d => line(d))
.attr("fill", "none")
.attr("stroke", lineColor)
.attr("stroke-width", 2);
gView.selectAll("g.marker")
.data(data)
.join("g")
.classed("marker", true)
.attr("transform", d => `translate(${x(d.x)}, ${y(d.y)})`)
.append("path")
.attr("d", shapeGenerator)
.attr("fill", colorGenerator)
.attr("stroke", "none");
return svg.node();
}