Published
Edited
Feb 15, 2022
1 fork
Insert cell
# Negative bar chart
Insert cell
chart = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);

// Positive values
svg
.append("g")
.attr("fill", "steelblue")
.selectAll("rect")
.data(data.map((d) => (d["gender assortativity"] > 0 ? d : { value: 0 })))
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", (d) => y(d["gender assortativity"]))
.attr("height", (d) => y(0) - y(d["gender assortativity"]))
.attr("width", x.bandwidth());

// Negative values
svg
.append("g")
.attr("fill", "coral") // red, but just not too bright
.selectAll("rect")
.data(data.map((d) => (d["gender assortativity"] < 0 ? d : { value: 0 })))
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", (d) => y(0))
.attr("height", (d) => y(0) - y(-d["gender assortativity"]))
.attr("width", x.bandwidth());

svg.append("g").call(xAxisPos);

svg.append("g").call(xAxisNeg);

svg.append("g").call(yAxis);

return svg.node();
}
Insert cell
data = FileAttachment("networkstats.csv").csv()
Insert cell
x = d3.scaleBand()
.domain(d3.range(data.length))
.range([margin.left, width - margin.right])
.padding(0.1)
Insert cell
y = {
// Find the largest absolute value
const absMax = d3.max(data, (d) => Math.abs(d["gender assortativity"]));
// Use that for the scale
return d3
.scaleLinear()
.domain([-absMax, absMax])
.nice()
.range([height - margin.bottom, margin.top + 10]);
}
Insert cell
xAxisPos = g => g
.attr("transform", `translate(0,${height / 2})`)
.call(d3.axisBottom(x).tickFormat(i => data[i].congregation).tickSizeOuter(0))
.selectAll('g.tick')
.attr('display', i => data[i]["gender assortativity"] < 0 ? 'none' : '')
Insert cell
xAxisNeg = (g) =>
g
.attr("transform", `translate(0,${height / 2})`)
.call(
d3
.axisTop(x)
.tickFormat((i) => data[i].congregation)
.tickSizeOuter(0)
)
.selectAll("g.tick")
.attr("display", (i) => (data[i]["gender assortativity"] > 0 ? "none" : ""))
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y).ticks(null, data.format))
.call(g => g.select(".domain").remove())
.call(g => g.append("text")
.attr("x", -margin.left)
.attr("y", 10)
.attr("fill", "currentColor")
.attr("text-anchor", "start")
.text(data.y))
Insert cell
height = 500
Insert cell
color = "steelblue"
Insert cell
margin = ({ top: 20, right: 30, bottom: 30, left: 40 })
Insert cell
d3 = require("d3@6")
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