Public
Edited
Feb 20
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
ternaryData = selectedNutrition?.map((d) => {
const [x, y] = t(d);
return { x, y, ...d };
})
Insert cell
b = barycentric()
.a(aAccessor)
.b(bAccessor)
.c(cAccessor)
Insert cell
aAccessor = d => +d.FatContent
Insert cell
bAccessor = d => +d.ProteinContent
Insert cell
cAccessor = d => +d.CarbohydrateContent
Insert cell
labels = ["A: Fat", "B: Protein", "C: Carbs"]
Insert cell
t = ternaryPlot(b)
.radius(radius)
.labels(labels)
Insert cell
height = (2 / 3) * width
Insert cell
// to keep the triangle centered at [0,0] of the svg
yOffset = radius / 4
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
radiusLegend = (g, scale, title) => {
const fontSize = 10;

const margin = {
top: 30,
bottom: 30,
left: 30,
right: 30
};

const numCircles = Math.min(4, Math.ceil((scale.range()[1] * 2) / fontSize));

const r = d3.range(numCircles);
const s = d3
.scaleLinear()
.domain([r[0], r[r.length - 1]])
.range(scale.domain());

g.attr('font-size', `${fontSize}px`);
g.selectAll('g')
.data(r)
.join(enter => {
const g = enter.append('g');
g.append('circle')
.attr('cx', margin.left + 50)
.attr('cy', d => margin.top + scale(s(d)))
.attr('r', d => scale(s(d)))
.attr('stroke', 'black')
.attr('fill', 'none');

g.append('line')
.attr('x1', margin.left + 50)
.attr('x2', margin.left + 80)
.attr('y1', d => margin.top + 2 * scale(s(d)))
.attr('y2', d => margin.top + 2 * scale(s(d)))
.attr('stroke', 'gray');

g.append('text')
.attr('x', margin.left + 84)
.attr('y', d => margin.top + 5 + 2 * scale(s(d)))
.text(d => Math.round(s(d)));

return g;
});

g.append('text')
.text(title)
.attr('y', margin.top + 2 * scale(s(numCircles - 1)) + 18)
.attr('x', margin.left + 60)
.attr('text-anchor', 'middle');
}
Insert cell
Insert cell
formatPercentage = d3.format(".2%")
Insert cell
nutriDensityScale = d3
.scaleSqrt()
.domain(nutritionalDensityExtent)
.range([0, 15])
Insert cell
Insert cell
nutritionalDensityExtent = d3.extent(
selectedNutrition,
(d) => d.nutritionalDensity
)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
selectedNutrition = nutrition.filter(
(d, i) =>
nutritionalDensity[i] > nutriFilter.range[0] &&
nutritionalDensity[i] < nutriFilter.range[1]
)
Insert cell
Insert cell
Insert cell
import {
grid,
ticks,
axisLabels
} from "@julesblm/d3-ternary"
Insert cell
d3Ternary = import("d3-ternary")
Insert cell
barycentric = d3Ternary.barycentric
Insert cell
ternaryPlot = d3Ternary.ternaryPlot
Insert cell
Insert cell
Insert cell
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