Public
Edited
Nov 8, 2022
Insert cell
Insert cell
scaleCompareChart = showScaleGrouping(data, {
scaleQuantile: quantile,
// scaleThreshold: threshold,
scaleJenks: jenks,
scaleQuantize: quantize,
scaleQuantizeNice: quantize.copy().nice()
})
Insert cell
data = [
11002, 29017, 45793, 7000, 120040, 30138, 21699, 47058, 24001, 6000, 69007,
40000, 55001, 30001, 61150, 12000, 85530, 83000, 23100, 96225, 45003, 34300,
43000, 63131, 52001, 36000, 10001, 225786, 0, 75000, 195100, 33010, 5000,
31213, 79050, 40010, 37002, 50000, 60000, 66529, 39048, 27276, 28007, 153420,
44500, 145443, 89550, 16024, 50, 25001, 300577, 102035, 20581, 170240, 126101,
18001, 15000, 4000, 0, 100003, 35000, 14001, 72046, 30000, 0, 65006, 56000,
42000, 17158, 135096, 70040, 114068, 22216, 60020, 2742, 35030, 25000, 76005,
40600, 48335, 58000, 900, 8000, 19002, 92000, 13000, 50008, 20000, 15100,
108023, 50600, 26483, 38002, 53440, 32007, 25654, 80130, 20000, 9500, 1968
]
Insert cell
linear = d3.scaleLinear()
.domain([0, d3.max(data)])
.range(["white", "red"])
Insert cell
quantize = d3.scaleQuantize()
.domain(d3.extent(data)) // pass only the extreme values to a scaleQuantize’s domain
.range(["white", "pink", "red"])
Insert cell
quantile = d3.scaleQuantile()
.domain(data) // pass the whole dataset to a scaleQuantile’s domain
.range(["white", "pink", "red"])
Insert cell
jenks = d3
.scaleThreshold()
.domain([53440, 135096])
.range(["white", "pink", "red"])
Insert cell
Insert cell
d3 = require("d3-array@2", "d3-format@2", "d3-scale@3", "d3-selection@2")
Insert cell
function numericSort(x) {
return (
x
// ensure the array is not changed in-place
.slice()
// comparator function that treats input as numeric
.sort((a, b) => a - b)
);
}
Insert cell
function chart(data, scale) {
const w = 30,
cols = Math.floor(Math.min(600, width) / w),
lines = Math.ceil(100 / cols);
const chart = d3
.create("svg")
.attr("width", cols * w)
.attr("height", lines * w);

chart
.append("g")
.attr("transform", "translate(2,2)")
.attr("style", "stroke:black; fill:white;")
.selectAll("rect")
.data(data)
.join("rect")
.attr("width", w - 3)
.attr("height", w - 3)
.attr("x", (_, i) => w * (i % cols))
.attr("y", (_, i) => w * ((i / cols) | 0))
.style("fill", d => (scale ? scale(d) : "#ddd"));
return chart.node();
}
Insert cell
function showScaleGrouping(data, scales) {
const margins = { left: 130 };
const x = d3
.scaleLinear()
.domain(d3.extent(data))
.range([margins.left, width - 5]);
const r = 3;
const rectHeight = 20;

const chart = svg`
<svg width=${width} height="${40 * (1.5 + Object.entries(scales).length)}"
style="font-family: sans-serif; alignment-baseline: middle; font-size:12px">
<g transform="translate(2,2)">
<text x="5" y=${5 + r}>Data</text>
${data.map(
(d) => `<circle r=${r} cx=${x(d)} cy=5 fill=black opacity="0.3" />`
)}
</g>
<g transform="translate(2,30)">
${Object.entries(scales).map(([name, s], i) => {
const scaleCuts = s.thresholds
? s.thresholds()
: s.quantiles
? s.quantiles()
: s.domain();
const limits = [0, ...scaleCuts, d3.max(data)];
const boxLimits = limits
.slice(0, limits.length - 1)
.map((d, j) => [limits[j], limits[j + 1]]);
return (
`<text x="5" y=${(2 * i + 1) * rectHeight}>${name}</text>` +
boxLimits.map(
(l, k) => `
<rect x=${x(l[0])} y=${i * 2 * rectHeight} height=30
width=${x(l[1]) - x(l[0])}
style="stroke:black;fill:${s.range()[k]};"
/>`
)
);
})}
</g>
</svg>`;
return chart;
}
Insert cell
simple = require("simple-statistics@7/dist/simple-statistics.min.js")
Insert cell
ckmeansThresholds = simple.ckmeans(data, 3).map(v => v.pop())
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