Public
Edited
Aug 29, 2020
Fork of Shapers
Insert cell
Insert cell
Insert cell
viewof ingredientsInput = form(html`<form>
${ingredients.map(
d => `
<div>
<strong>${d}</strong>
<input name="${d}" type="range" min=0 max=360>
</div>
`
)}
</form>`)
Insert cell
chart = {
const svg = d3
.select(DOM.svg(width, height))
.attr("viewBox", `${-width / 2} ${-height / 2} ${width} ${height}`)
.style("font", "11px monospace")
.style("background", "black")
.style("fill", "white");

const g = svg.append("g").attr("transform", "translate(-200, 0)");

const radius = Math.min(width, height) * 0.35;

const arcsIngredients = pie(dataIngredients);

const arcIngredients = d3
.arc()
.innerRadius(radius - 10)
.outerRadius(radius - 1);

const arcText = d3
.arc()
.innerRadius(radius)
.outerRadius(radius + 30);

const groupIngredients = g.append("g").attr("class", "ingredients");

groupIngredients
.selectAll(".arc")
.data(arcsIngredients)
.join("path")
.attr("class", "arc")
.attr("d", d => {
const a = arcIngredients(d);
console.log(a);
return a;
});

let minY = -1000;
const minGap = 20;
const targetXPos = 380;

const textY = (d, arc) => {
const c = arc.centroid(d);
let y = c[1];
if (y < minY + minGap) {
y = minY + minGap;
}
minY = y;
return y;
};

groupIngredients
.selectAll(".label-connector")
.data(arcsIngredients)
.join("path")
.attr("class", "label-connector")
.attr("stroke", "white")
.attr("d", d => {
const c = arcText.centroid(d);
const y = textY(d, arcText);
return `M${c[0]} ${c[1]} L${targetXPos} ${y})`;
});

minY = -1000;
groupIngredients
.selectAll(".label")
.data(arcsIngredients)
.join("text")
.attr("class", "label")
.text(d => d.data.name)
.attr("transform", d => {
const y = textY(d, arcText);
return `translate(${targetXPos},${y})`;
})
.call(stroke("white", "black", "10"));

groupIngredients
.selectAll(".line")
.data(arcsIngredients)
.join("text")
.attr("class", "line");

const arcsModes = d3
.pie()
.padAngle(0.05)
.startAngle(-0.025)
.endAngle(Math.PI + 0.025)
.value(d => d.value)
.sort(null)(dataModes);

const arcModes = d3
.arc()
.innerRadius(radius - 45)
.outerRadius(radius - 20);

const arcModesText = d3
.arc()
.innerRadius(radius - 60)
.outerRadius(radius - 60);

const groupModes = g.append("g").attr("class", "modes");

groupModes
.selectAll(".arc")
.data(arcsModes)
.join("path")
.attr("class", "arc")
.attr("fill", "black")
.attr("stroke", "white")
.attr("stroke-width", "1")
.attr("d", d => {
const a = arcModes(d);
console.log(a);
return a;
});

minY = -1000;
groupModes
.selectAll(".label-connector")
.data(arcsModes)
.join("path")
.attr("class", "label-connector")
.attr("stroke", "white")
.attr("d", d => {
const c = arcModesText.centroid(d);
const y = textY(d, arcModesText);
return `M${c[0]} ${y} L${0} ${y})`;
});

minY = -1000;
groupModes
.selectAll(".label")
.data(arcsModes)
.join("text")
.attr("class", "label")
.text(d => d.data.name)
.attr("transform", d => {
const y = textY(d, arcModesText);
return `translate(0,${y})`;
})
.call(stroke("white", "black", "10"));

return svg.node();
}
Insert cell
Insert cell
dataModes = modes.map(d => ({ name: d, value: modesInput[d] }))
Insert cell
pie = d3
.pie()
.padAngle(0.01)
.startAngle(-0.005)
.endAngle(Math.PI + 0.005)
.value(d => d.value)
.sort(null)
Insert cell
color = d3.scaleOrdinal().range(colors)
Insert cell
stroke = (textColor, strokeColor, strokeWidth) => {
return d => {
d.attr("stroke", strokeColor)
.attr("stroke-width", strokeWidth)
.clone(true)
.attr("stroke-width", 0)
.attr("fill", textColor);
};
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {form} from "@mbostock/form-input"

Insert cell
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