Public
Edited
Mar 14, 2024
10 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
v2 = {
// version 2: legend not included then build in a separate step

const sl = d3.scaleLinear();

const data = penguins;
const arr = [];
arr.push(
Plot.dot(data, {
x: "flipper_length_mm",
y: "body_mass_g",
fill: "sex",
clip: true,
tip: { lineHeight: 1.3, maxRadius: 5 }
}),
Plot.density(data, {
x: "flipper_length_mm",
y: "body_mass_g",
stroke: "sex",
thresholds: 10,
clip: true
})
);

const renderPlot = (xDomain, yDomain) =>
Plot.plot({
className: "my-plot-2",
width: 900,
height: 500,
x: { domain: xDomain },
y: { domain: yDomain },
inset: 10,
grid: true,
marks: arr,
// overrides all elements not chart - will remove title, subtitle, caption, legend
figure: false
});

const insertPlot = (xDomain = [150, 250], yDomain = [2000, 6500]) => {
const chart = renderPlot(xDomain, yDomain);
container.html("").append(() => chart);
// div.html("").append(() => chart);
div_legend.html("").append(() => chart.legend("color"));

return [chart.scale("x"), chart.scale("y")];
};

const zoomed = (e) => {
console.log(e.transform);

const x = sl.domain(xScale.domain).range(xScale.range);
const xDomain = e.transform.rescaleX(x).domain();

const y = sl.domain(yScale.domain).range(yScale.range);
const yDomain = e.transform.rescaleY(y).domain();

insertPlot(xDomain, yDomain);
};

const div = d3.create("div");
const container = div
.append("svg")
.attr("width", 960)
.attr("height", 500)
.append("g");
const div_legend = d3.create("div");
const [xScale, yScale, legend] = insertPlot();

const zoom = d3.zoom().on("zoom", zoomed);
div.call(zoom);

return [div.node(), div_legend.node()];
}
Insert cell
v2[0]
Insert cell
v2[1]
Insert cell
penguins.csv
Type SQL, then Shift-Enter. Ctrl-space for more options.

Insert cell
d3 = require("d3@7")
Insert cell
Insert cell
{
// version 3: brush to control zoom

const [width, height] = [1000, 750];
const sl = d3.scaleLinear();

const data = penguins;
const arr = [];
arr.push(
Plot.dot(data, {
x: "flipper_length_mm",
y: "body_mass_g",
fill: "sex",
clip: true,
tip: { lineHeight: 1.3, maxRadius: 5 }
}),
Plot.density(data, {
x: "flipper_length_mm",
y: "body_mass_g",
stroke: "sex",
thresholds: 10,
clip: true
})
);

const idleDelay = 350;
const idled = () => {
idleTimeout = null;
};

const renderPlot = (xDomain, yDomain) =>
Plot.plot({
className: "my-plot-3",
width,
height,
x: { domain: xDomain },
y: { domain: yDomain },
inset: 10,
grid: true,
marks: arr,
figure: false
});

const insertPlot = ({ xDomain, yDomain }) => {
const chart = renderPlot(xDomain, yDomain);
container.html("").append(() => chart);
return [chart.scale("x"), chart.scale("y")];
};

const brushed = ({ selection }) => {
var s = selection;
let xDomain, yDomain;
if (!s) {
if (!idleTimeout) return (idleTimeout = setTimeout(idled, idleDelay));
xDomain = xDomain0;
yDomain = yDomain0;
} else {
xDomain = [s[0][0], s[1][0]].map(xScale.invert, xScale);
yDomain = [s[1][1], s[0][1]].map(yScale.invert, yScale);
container.call(brush.move, null);
}

[xScale, yScale] = insertPlot({ xDomain, yDomain });
container.call(brush);
};

const zoom2 = () => {};

const zoomed = (e) => {
console.log(e.transform);

const x = sl.domain(xScale.domain).range(xScale.range);
const xDomain = e.transform.rescaleX(x).domain();

const y = sl.domain(yScale.domain).range(yScale.range);
const yDomain = e.transform.rescaleY(y).domain();

insertPlot({ xDomain, yDomain });
};

const xDomain0 = [150, 250];
const yDomain0 = [2000, 6500];

let idleTimeout = null;
const div = d3.create("div");
const container = div
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g");

const brush = d3.brush().on("end", brushed);

let [xScale, yScale] = insertPlot({
xDomain: xDomain0,
yDomain: yDomain0
});
container.call(brush);

return div.node();
}
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