Public
Edited
Jan 23
Insert cell
Insert cell
Insert cell
Insert cell
viewof category = Inputs.select(categoryGroups, {
label: "Group by",
value: "All Workers",
})
Insert cell
viewof threshold = Inputs.range(d3.extent(thresholdExtent), {
label: 'Paid less than ($/hr)',
step: 1,
value: 17
});
Insert cell
viewof table = {
const table = Inputs.table(tableData, {
maxHeight: 'none',
sort: 'low_wage_share',
reverse: true,
columns: [
'category',
'low_wage_share',
'low_wage_count',
],
header: {
category: "Group of workers",
low_wage_share: "Share under wage threshold",
low_wage_count: "Number under wage threshold",
},
align: {
category: "left",
low_wage_share: "center",
low_wage_count: "right",
},
format: {
low_wage_share: donutChart,
low_wage_count: d3.format(','),
},
});

// Array of sortable header <spans>
const sortSpans = [];

// Spans should be hidden if they have no content.
function toggle(span) {
span.classList.toggle('hidden', !span.textContent)
}

// Hide or show all spans as needed.
function toggleAll() {
sortSpans.forEach(toggle);
}
// Iterate over the headers to find the spans and bind to the click event.
table.querySelectorAll('th').forEach(th => {
const span = th.querySelector('span');
if (!span) {
return;
}
toggle(span);
sortSpans.push(span);
th.addEventListener('click', toggleAll)
})
return table;
}
Insert cell
function donutChart(value) {
const color = shareColor(value)
const donut = svg`
<svg viewbox="0 0 ${viewport} ${viewport}" style="width: 100%; max-width: ${viewport}px;">
<circle cx="${center}" cy="${center}" r="${bgRadius}" fill="transparent" stroke="rgb(220, 220, 220)" stroke-width="${arcWidth}"></circle><g transform="translate(${center},${center})">
<path stroke-width="0" fill="${color}" d="${arcGen(value)}"></path>
</g>
</svg>
`;
const label = `
<div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)">
${value}%
</div>
`;
return html`
<div style="display: inline-flex; position: relative">
${donut}
${label}
</div>
`;
}
Insert cell
Insert cell
ohqUser = 'economic-policy-institute-ws'
Insert cell
Insert cell
pieGen = d3.pie().sort((a, b) => a - b);
Insert cell
arcGen = d3.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
.startAngle(0)
.endAngle(valueAngle);
Insert cell
innerRadius = outerRadius - arcWidth
Insert cell
arcWidth = 40
Insert cell
outerRadius = 80
Insert cell
bgRadius = (outerRadius + innerRadius) / 2;
Insert cell
piePadding = 10;
Insert cell
center = outerRadius + piePadding
Insert cell
viewport = center * 2;
Insert cell
valueAngle = value => (Math.PI * 2) * (value / 100)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
file = FileAttachment("low_wage_data@9.csv")
Insert cell
fileUrl = file.url()
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