table = () => {
const wrapper = d3.create("div")
.attr("class", "table-survey");
wrapper.append("div")
.attr("class", "table-title")
.text("People who say they would prefer to live in a community with...")
const legend = wrapper.append("div")
.attr("class", "legend");
const legendItem = legend.selectAll(".legend-item")
.data(["smaller_walking", "larger_driving"].map(d => legendLookup[d]))
.join("div")
.attr("class", "legend-item");
legendItem.append("div")
.attr("class", "legend-swatch")
.style("background", d => d.background)
legendItem.append("div")
.attr("class", "legend-label")
.text(d => d.text);
wrapper.append("style").html(css);
const category = wrapper.selectAll(".category")
.data(categories)
.join("div")
.attr("class", "category")
.style("position", "relative");
const axis = category.append("svg")
.style("position", "absolute")
.style("overflow", "visible")
.style("left", `${leftColWidth}px`)
.style("top", (_, i) => i ? "29px" : "0px")
.attr("width", chartWidth)
.attr("height", overlayHeight);
axis.filter((_, i) => !i).append("text")
.attr("fill", "#666666")
.attr("x", chartWidth / 2)
.attr("y", -3)
.attr("text-anchor", "middle")
.attr("font-size", 14)
.text("50%");
axis.append("line")
.attr("x1", chartWidth / 2)
.attr("x2", chartWidth / 2)
.attr("stroke", "#666666")
.attr("y2", overlayHeight)
category
.filter((_, i) => i)
.append("div")
.attr("class", "category-name")
.text(d => `${categoryLookup[d[0]] || d[0]}`);
const table = category.append("table");
const tbody = table.append("tbody");
const tr = tbody.selectAll("tr")
.data(d => d[1])
.join("tr");
const td = tr.selectAll("td")
.data(d => {
return cols
.map(key => ({
key,
value: d[key] || ["smaller_walking", "larger_driving"]
.map(c => ({
category: d.category,
c,
v: d[c]
}))
}))
})
.join("td")
.attr("class", d => d.key)
.text(d => subcategoryLookup[d.value] || (typeof d.value === "string"? d.value : ""));
const svg = td.filter((_, i) => i).append("svg")
.attr("width", chartWidth)
.attr("height", rowHeight);
svg.append("rect")
.attr("class", "bg")
.attr("width", chartWidth)
.attr("height", rowHeight)
svg.selectAll(".bar")
.data(d => d.value)
.join("rect")
.attr("class", d => `bar ${d.c}`)
.attr("height", rowHeight)
.attr("width", d => d.v / 100 * chartWidth)
.attr("x", (d, i) => i == 0 ? 0 : chartWidth - (d.v / 100 * chartWidth));
svg.selectAll(".value")
.data(d => d.value)
.join("text")
.attr("class", d => `value ${d.c}`)
.attr("dx", (d, i) => 6 * (1 - 2 * i))
.attr("dy", "0.4em")
.attr("text-anchor", (d, i) => i == 0 ? "start" : "end")
.attr("x", (d, i) => i == 0 ? 0 : chartWidth)
.attr("y", rowHeight / 2)
.text(d => `${d.v}${d.category === "total" ? "%" : ""}`);
return wrapper.node();
}