Public
Edited
Jan 14, 2024
Insert cell
Insert cell
Insert cell
Insert cell
viewof pizzaCategories = {
function onLineClick(e) {
const index = getTargetIndex(e);
if (focus === index) {
focus = null;
return;
}
if (focus !== null) fill(focus);
if (index >= 0) {
fill(index, true);
focus = index;
updateCategory(lookupCategory(index));
} else {
focus = null;
updateCategory(null);
line.nodes().forEach((node, idx) => {
fill(idx);
});
}
}
function handlePointerDown(e) {
const index = getTargetIndex(e);
if (index >= 0) fill(index, true, 0.5);
}
function handlePointerUp(e) {
const index = getTargetIndex(e);
if (index >= 0) {
fill(index, true);
line.nodes().forEach((node, idx) => {
if (idx !== index) {
fill(idx, false, true);
}
});
}
d3.select(this).style("default");
}
function highlight(e) {
if (focus !== null) return;
const index = getTargetIndex(e);
d3.select(this).style("cursor", index >= 0 ? "pointer" : "default");
fill(index, true);
if (timeout) clearTimeout(timeout);
timeout = setTimeout(
() => updateCategory(index >= 0 ? lookupCategory(index) : null),
25
);
}
function restore(e) {
if (focus !== null) return;
const index = getTargetIndex(e);
fill(index);
}
function fillType(color, darker, lowlight) {
if (darker) return d3.color(color).darker(darker);
else if (lowlight) return "grey";
else return color;
}
function fill(index, highlight, lowlight, darker) {
if (index >= 0) {
const color = categoryColors[index].color;
d3.select(line.nodes()[index])
.attr("stroke", fillType(color, darker, lowlight))
.attr("stroke-width", highlight ? 10 : 5);
}
}
function getTargetIndex(e) {
let tar = e.target;
return tar instanceof SVGPathElement
? [...tar.parentElement.children].indexOf(tar)
: -1;
}
const plot = Plot.plot({
style: {fontSize: "20px"},
ariaLabel: "categoryChart",
title: "Pizza Categories",
width: 2000,
height: 800,
margin: 100,
grid: true,
x: { label: "Month", ariaHidden: true },
y: { label: "Revenue", ariaHidden: true },
symbol: { legend: true },
color: {
legend: true,
range: [
categoryColors[0].color,
categoryColors[1].color,
categoryColors[2].color,
],
},
marks: [
Plot.gridX({ ariaHidden: true }),
Plot.dot(
monthlyRevenuesPerCategory.filter((d) =>
obtenirAnysFiltre().includes(d.year)
),
{
x: "date",
y: "sumRevenue",
r: "sumRevenue",
fill: "grey",
ariaHidden: true,
}
),
Plot.line(
monthlyRevenuesPerCategory.filter((d) =>
obtenirAnysFiltre().includes(d.year)
),
{
x: "date",
y: "sumRevenue",
z: "category",
ariaHidden: false,
stroke: "category",
opacity: 0.8,
strokeWidth: 5,
curve: "bump-x",
tip: {
fontSize: 20,
dy: -20,
format: {
y: (d) => `${d3.format(".1f")(d)}$`,
z: false,
x: (d) => `${d.toLocaleString("en-US", "numeric")}`,
},
},
}
),
Plot.ruleY([0], { ariaHidden: true }),
],
});
const plotMap = d3.select(plot);
let timeout,
focus = null;
const line = plotMap.selectAll("[aria-label*='line']").selectChildren();
plotMap
.on("pointerover", highlight)
.on("pointerout", restore)
.on("click", onLineClick)
.on("pointerdown", handlePointerDown)
.on("pointerup", handlePointerUp)
.style("cursor", "default");
const map = html`<div>
${plotMap.node()}
<div style="display:flex;justify-content:space-between">
<div
style="align-self:self-end;font-style:italic;font-size:9pt;text-align:end"
></div>
</div>
</div>`;
updateCategory(null);
return map;
function lookupCategory(index) {
return categoryMap[index].category;
}
function updateCategory(category) {
map.value = category;
map.dispatchEvent(new CustomEvent("input"));
}
}


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