Published
Edited
Sep 1, 2021
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
viewof angle4 = Inputs.range([-90, -90], { label: 'angle' })
Insert cell
Insert cell
chart = {
const svg = d3
.select(DOM.svg(width, height))
.attr("viewBox", `${-width / 2} ${-height / 2} ${width} ${height}`)
.style("width", "90%")
.style("height", "auto")
.style("font", "14px sans-serif")
.attr('transform', `rotate(${angle1})`);

svg
.append("g")
.attr('transform', `rotate(${angle2})`)
.selectAll("g")
.data(d3.stack().keys(data.columns.slice(1))(data))
.join("g")
.attr("fill", d => z(d.key))
.selectAll("path")
.data(d => d)
.join("path")
.attr("d", arc);

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

svg
.append("g")
.attr('transform', `rotate(${angle3})`)
.call(yAxis);

svg.append("g").call(legend)
.attr('transform', `rotate(${angle4})`);
return svg.node();
}
Insert cell
data = d3.csvParse(`Month,Impact Space and Community,Impact Ecosystem,Impact Captial
Business acumen,5,0,0
Overall well-being,3,0,0
Increase awareness,5,0,0
Diverse and meaningful connections,4,0,0

Information transpareny,0,3,0
Exposure,0,3.5,0
Collaborativeness,0,4.5,0
Stakeholder involvement,0,4,0
.
Knowledge,0,0,4
Opportunities & Support,0,0,3
`, (d, _, columns) => {
let total = 0;
for (let i = 1; i < columns.length; ++i) total += d[columns[i]] = +d[columns[i]];
d.total = total;
return d;
})
Insert cell
arc = d3.arc()
.innerRadius(d => y(d[0]))
.outerRadius(d => y(d[1]))
.startAngle(d => x(d.data.Month))
.endAngle(d => x(d.data.Month) + x.bandwidth())
.padRadius(innerRadius)
Insert cell
x = d3.scaleBand()
.domain(data.map(d => d.Month))
.range([-0.5*Math.PI, 0.5*Math.PI])
.align(0)
Insert cell
// This scale maintains area proportionality of radial bars
y = d3.scaleRadial()
.domain([0, d3.max(data, d => d.total)])
.range([innerRadius, outerRadius])
Insert cell
z = d3.scaleOrdinal()
.domain(data.columns.slice(1))//.range(["#DB004C", "#8CCBFF", "#FF3700"])
.range(["#FF3700", "#FF8C00", "#E26310"])
Insert cell
xAxis = g => g
.attr("text-anchor", "start:end")
.call(g => g.selectAll("g")
.data(data)
.join("g")
.attr("transform", d => `
rotate(${((x(d.Month) + x.bandwidth() / 2) * 180 / Math.PI - 90)})
translate(${innerRadius},0)
`)
.call(g => g.append("line")
.attr("x2", -5)
.attr("stroke", "#000"))
.call(g => g.append("text")
.attr("transform", d => (x(d.Month) + x.bandwidth() / 2 + Math.PI / 2) % (Math.PI) < 0.5*Math.PI
? "rotate(0)translate(10,3)"
: "rotate(0)translate(10,3)")
.text(d => d.Month)))
Insert cell
yAxis = g => g
.attr("text-anchor", "end")
.call(g => g.selectAll("g")
.data(y.ticks(5).slice(1))
.join("g")
.attr("fill", "none")
.call(g => g.append("path")
.attr("stroke", "#000")
.attr("stroke-opacity", 0.22)
.attr("d", d3.arc()
.innerRadius(y)
.outerRadius(y)
.startAngle(-0.5*Math.PI)
.endAngle(0.5*Math.PI) ))

.call(g => g.append("text")
.attr("x", d => -y(d))
.attr("dx", "0.8em")
.attr("dy", "0.8em")
.attr("stroke", "#fff")
.attr("stroke-width", 5)
.text(y.tickFormat())
.clone(true)
.attr("fill", "#000")
.attr("stroke", "none"))
.call(g => g.append("text")
.attr("x", d => y(d))
.attr("dx", "0.35em")
.attr("dy", "-0.35em")
.attr("stroke", "#fff")
.attr("stroke-width", 5)
.text(y.tickFormat())
.clone(true)
.attr("fill", "#000")
.attr("stroke", "none"))
.attr("transform", d => `
rotate(${((x(d.Month) + x.bandwidth() / 2) * 180 / Math.PI - 0)})
translate(${innerRadius},0)
`)
)
Insert cell
legend = g => g.append("g")
.selectAll("g")
.data(data.columns.slice(1).reverse())
.join("g")

.attr("transform", (d, i) => `translate(-110,${(i - (data.columns.length - 2.5) / 2) * 50-40})`)


.call(g => g.append("rect")
.attr("width", 18)
.attr("height", 18)
.attr("fill", z))
.call(g => g.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", "0.8em")
.text(d => d))

Insert cell
width = 975
Insert cell
height = width
Insert cell
innerRadius = 200
Insert cell
outerRadius = Math.min(width, height) / 2
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