Public
Edited
Sep 14, 2023
Insert cell
Insert cell
Insert cell
string = `State, CAN, GN, GR, RES, RIV, SN
NWN,0.0437,0,0.0144,0.0419,1.76,0.639
NEN,0.00457,0,0.0125,0,0.0449,0.00146
WNA,1.49,4.08,13.8,4.28,32.7,20.5
CNA,1.06,30.1,40.9,0.427,11.3,3.96
ENA,0.0846,0.195,7.71,0.226,3.72,1.96
NCA,1.01,6.33,8.9,2.08,21.7,23.6
SCA,0.111,0.105,1.47,0.435,3.15,2.5
CAR,0,0,0.381,0.426,1.07,1.15
NWS,0.613,0.797,1.54,0.455,9.36,9.41
NSA,0.0183,0.00194,0.215,0.236,2.97,0.911
NES,0.138,0.01,1.26,0.199,5.48,1.7
SAM,0.0901,0,0.0741,0.00583,0.788,0.234
SWS,0.428,0.0882,0.298,0.109,3.88,7.14
SES,0.415,0.167,3.09,0.709,28.5,11.7
SSA,0,0,0.000254,0,0.305,0.00471
NEU,0.00375,0.000656,2.09,0.0356,2.21,0.354
WCE,0.778,0.028,6.13,0.059,30.2,10.4
EEU,0.12,0.00308,1.86,0.114,10.8,3.44
MED,1.2,4.24,24.2,5.2,58.6,42.2
SAH,0.567,1.38,1.2,0.0227,30.1,11.7
WAF,0.0973,0,0.305,0.116,5.4,0.958
CAF,0.044,0,0.0752,0.0612,0.541,0.173
NEAF,0.423,0,0.358,0.0306,8.8,8.15
SEAF,0.0567,0,0.0467,0.00942,2.71,0.624
WSAF,0.305,0.000474,0.318,0.52,3.24,1.74
ESAF,0.508,2.42E-05,0.505,1.76,6.24,2.97
MDG,0.111,0,0,0.164,9.21,5.1
WSB,0.866,0.0649,0.956,0.0137,7.7,5.93
ESB,1.65,0.393,3.92,0,5.82,1.69
RFE,0.379,0.0172,1.24,0,1.12,0.316
WCA,14.8,35.1,36,1.87,157,135
ECA,5.78,5.19,4.64,0.0146,28.8,39.6
TIB,5.83,19.1,14.9,0.836,13.3,18.3
EAS,18.9,20,43.8,53.9,337,231
ARP,0.0474,12.4,2.02,0,0.742,1.45
SAS,30.5,122,147,19.9,331,257
SEA,3.38,0.124,6.1,9.79,140,91.7
NAU,0.00867,0,0.028,0.00961,0.229,0.048
CAU,1.03E-07,0,0.000597,0,0.00104,1.95E-06
EAU,0.22,0.0154,1.19,0.0725,4.69,0.746
SAU,0.0244,0.0764,1.44,0.0818,8.56,3.65
NZ,0,0,0.546,0.0599,1.06,0.612
BOB,0,0,0.0515,2.38,3.73,5.39
EIO,0,0,0.00476,0.494,1.24,0.922`;
Insert cell
data = d3.csvParse(string, (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.State))
.endAngle(d => x(d.data.State) + x.bandwidth())
.padAngle(0.01)
.padRadius(innerRadius)
Insert cell
x = d3.scaleBand()
.domain(data.map(d => d.State))
.range([0, 2 * Math.PI])
.align(0)
Insert cell
y = {
// This scale maintains area proportionality of radial bars!
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.total)])
.range([innerRadius * innerRadius, outerRadius * outerRadius]);
return Object.assign(d => Math.sqrt(y(d)), y);
}
Insert cell
z = d3.scaleOrdinal()
.domain(data.columns.slice(1))
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"])
Insert cell
xAxis = g => g
.attr("text-anchor", "middle")
.call(g => g.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", d => `
rotate(${((x(d.State) + 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.State) + x.bandwidth() / 2 + Math.PI / 2) % (2 * Math.PI) < Math.PI
? "rotate(90)translate(0,16)"
: "rotate(-90)translate(0,-9)")
.text(d => d.State)))
Insert cell
yAxis = g => g
.attr("text-anchor", "middle")
.call(g => g.append("text")
.attr("y", d => -y(y.ticks(5).pop()))
.attr("dy", "-1em")
.text("This is title"))
.call(g => g.selectAll("g")
.data(y.ticks(5).slice(1))
.enter().append("g")
.attr("fill", "none")
.call(g => g.append("circle")
.attr("stroke", "#000")
.attr("stroke-opacity", 0.5)
.attr("r", y))
.call(g => g.append("text")
.attr("y", d => - y(d))
.attr("dy", "0.35em")
.attr("stroke", "#fff")
.attr("stroke-width", 5)
.text(y.tickFormat(5, "s"))
.clone(true)
.attr("fill", "#000")
.attr("stroke", "none")))
Insert cell
legend = g => g.append("g")
.selectAll("g")
.data(data.columns.slice(1).reverse())
.enter().append("g")
.attr("transform", (d, i) => `translate(-40,${(i - (data.columns.length - 1) / 2) * 20})`)
.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.35em")
.text(d => d))
Insert cell
width = 975
Insert cell
outerRadius = Math.min(width, height) / 2
Insert cell
innerRadius = 180
Insert cell
height = width
Insert cell
d3 = require("d3@5")
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