chart = {
const svg = d3.select(DOM.svg(width, height));
svg.append("g").call(xAxis);
svg.append("g").call(yAxis);
const line = svg
.append("g")
.append("line")
.attr("y1", height - margin.bottom)
.attr("y2", margin.top)
.attr("stroke", "#999999")
.attr("stroke-width", 1)
.attr("opacity", 0);
const circleMotions = svg
.append("g")
.append("circle")
.attr("r", 5)
.attr("fill", "steelblue")
.attr("opacity", 0);
const circleVotes = svg
.append("g")
.append("circle")
.attr("r", 5)
.attr("fill", "purple")
.attr("opacity", 0);
const circleInvoked = svg
.append("g")
.append("circle")
.attr("r", 5)
.attr("fill", "red")
.attr("opacity", 0);
svg
.append("g")
.append("path")
.datum(data)
.attr("class", "motions")
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 2.5)
.attr("d", motions);
svg
.append("g")
.append("path")
.datum(data)
.attr("class", "votes")
.attr("fill", "none")
.attr("stroke", "purple")
.attr("stroke-width", 2.5)
.attr("d", votes);
svg
.append("g")
.append("path")
.datum(data)
.attr("class", "invoked")
.attr("fill", "none")
.attr("stroke", "red")
.attr("stroke-width", 2.5)
.attr("d", invoked);
const tooltip = svg.append("g");
svg.on("touchmove mousemove", function (event) {
const { term, motions, votes, invoked, count } = bisect(
d3.pointer(event, this)[0]
);
if (x(count) + 105 < width - margin.right) {
tooltip
.attr(
"transform",
`translate(${x(count + 5)},${
height / 2 - margin.top - margin.bottom
})`
)
.call(
callout,
`Term: ${term}
Motions: ${motions}
Votes: ${votes}
Invoked: ${invoked}`
);
} else {
tooltip
.attr(
"transform",
`translate(${x(count - 5)},${
height / 2 - margin.top - margin.bottom
})`
)
.call(
callout,
`Term: ${term}
Motions: ${motions}
Votes: ${votes}
Invoked: ${invoked}`
);
}
line
.attr("x1", (d) => x(count))
.attr("x2", (d) => x(count))
.attr("opacity", 1);
circleMotions
.attr("cx", (d) => x(count))
.attr("cy", (d) => y(motions))
.attr("opacity", 1);
circleVotes
.attr("cx", (d) => x(count))
.attr("cy", (d) => y(votes))
.attr("opacity", 1);
circleInvoked
.attr("cx", (d) => x(count))
.attr("cy", (d) => y(invoked))
.attr("opacity", 1);
});
svg.on("touchend mouseleave", function () {
tooltip.call(callout, null);
line.attr("opacity", 0);
circleMotions.attr("opacity", 0);
circleVotes.attr("opacity", 0);
circleInvoked.attr("opacity", 0);
});
return svg.node();
}