Public
Edited
Apr 10, 2024
1 star
Insert cell
Insert cell
Insert cell
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();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
motions = d3.line()
.x((d, i) => x(i) + x.bandwidth())
.y(d => y(d.motions))
.curve(d3.curveBumpX);
Insert cell
Insert cell
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).tickSizeOuter(0).tickValues([..."0", "11", "21", "31" , "41" , "51"]).tickFormat(i => data[i].term)).call(g => g.append("text").attr("x", width/2).attr("y", 30).attr("text-anchor", "middle").attr("class" , "label").attr("fill", "black").text("Congressional Term"))
Insert cell
Insert cell
Insert cell
xBisect = d3.scaleLinear()
.domain(d3.extent(data, d => d.count))
.range([margin.left, width - margin.right])
Insert cell
Insert cell
Insert cell
Insert cell
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