Published
Edited
Oct 18, 2021
1 fork
Insert cell
Insert cell
import { swatches } from "@d3/color-legend"
Insert cell
swatches({ color: colorScale })
Insert cell
viewof watching = Inputs.checkbox(d3.group(cov,x => x.prname), {label: "Watching", unique: true})
Insert cell
chart2 = addLegend(
Plot.dot(watching.flat(), {
x: "date",
y: "numdeaths",
stroke: "prname",
title: "Province"
})
.plot({ grid: true }),
colorLegend(colorScale)
)
Insert cell
function addLegend (chart, legend) {
let [lw, cw] = [+legend.getAttribute("width"), +chart.getAttribute("width")];
let [lh, ch] = [
+legend.getAttribute("height"),
+chart.getAttribute("height")
];
return svg`<svg width=${lw + cw} height=${Math.max(
lh,
ch
)}>${chart}<g transform=translate(${cw},0)>${legend}</g></svg>`;
}
Insert cell
function colorLegend(colorScale, options = {}) {
let { tickPadding = 5, width = 110, marginRight = 80 } = options;
return Plot.plot({
marks: [
Plot.cellX(colorScale.domain(), {
y: colorScale.domain(),
x: 0,
color: colorScale.range()
})
],
y: {
axis: "right",
tickSize: 0,
tickPadding
},
x: {
axis: null
},
width,
marginRight
});
}
Insert cell
function addColorLegend(
chart,
colorScale,
options = { sampleSize: 20, lineSpacing: 1.2, margin: 5, x0: 640, y0: 10 }
) {
const { sampleSize, lineSpacing, margin, x0, y0 } = options;
const leg = svg`<g style="font-family:sans-serif; font-size:x-small; ">`;
const domain = colorScale.domain();
const range = colorScale.range();
domain.forEach((label, i) => {
const x = x0;
const y = y0 + sampleSize * lineSpacing * i;
const group = svg`<g transform='translate(${x},${y})'>`;
leg.append(group);
group.append(
svg`<rect fill=${
range[i % range.length]
} width=${sampleSize} height=${sampleSize}>`
);
group.append(
svg`<text text-anchor=start dx=${sampleSize + margin} dy=${sampleSize *
0.7}>${label}</text>`
);
});
if (chart.nodeName === "svg") chart.append(leg);
else
d3.select(chart)
.select("svg")
.append(() => leg);
return chart;
}
Insert cell
colorScale = d3.scaleOrdinal(
[...new Set(data.map((d) => d.prname))],
d3.schemeTableau10
)
Insert cell
d3.extent(data, d=>d.date)
Insert cell
html`<svg viewBox="0 0 ${width} ${height}" style="max-width: ${width}px; font: 10px sans-serif;">
<g fill="steelblue">
${data.map(d => svg`<rect y="${y(d.prname)}" x="${x(0)}" width="${x(d.numtotal) - x(0)}" height="${y.bandwidth()}"></rect>`)}
</g>
<g fill="white" text-anchor="end" transform="translate(-6,${y.bandwidth() / 2})">
${data.map(d => svg`<text y="${y(d.prname)}" x="${x(d.numtotal)}" dy="0.35em">${d.numtotal}</text>`)}
</g>
${d3.select(svg`<g transform="translate(0,${margin.top})">`)
.call(d3.axisTop(x))
.call(g => g.select(".domain").remove())
.node()}
${d3.select(svg`<g transform="translate(${margin.left},0)">`)
.call(d3.axisLeft(y))
.call(g => g.select(".domain").remove())
.node()}
</svg>`
Insert cell
Insert cell
x = d3.scaleLinear()
.domain([0,d3.max(data, d=>d.numtotal)])
.range([margin.left + 20, width - margin.right])
.interpolate(d3.interpolateRound)
Insert cell
y = d3.scaleBand()
.domain(data.map(d =>d.prname))
.range([margin.top, height - margin.bottom ])
.padding(0.1)
.round(true)
Insert cell
total = data.map(d => d.rateactive)
Insert cell
import {chart as totalHistogram} with {total as data, height} from "@d3/histogram"
Insert cell
totalHistogram
Insert cell
cov = d3.csvParse(await FileAttachment("covid19-data@1.csv").text(),d3.autoType)
Insert cell
data = FileAttachment("covid19-data@1.csv").csv()
Insert cell
Insert cell
margin = ({top:20, right: 0, bottom:0, left:100})
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