Public
Edited
Feb 23, 2023
Paused
2 forks
5 stars
Insert cell
Insert cell
function draw(r, msg) {
return r
.push()
.fill("rgb(220,170,130)")
.ellipse(0, 0, 0.5)
.stroke()
.fill("black")
.textAlign("middle")
.textBaseline("middle")
.text(msg, 0, 0)
.pop();
}
Insert cell
{
const r = new Renderer(300, 300).clear("bisque").fit();
return draw(r, "Hello, static image.").render();
}
Insert cell
Insert cell
{
const r = new Renderer(300, 300).clear("bisque").fit();
const msg = "Hello, zoomer!";
r.selection().call(
d3.zoom().on("zoom", ({ transform }) => {
// This is the function that will redraw whenever the user zooms or pans.
// The transform object contains the current translation and scaling settings.
r.clear("bisque")
.push()
.translate(transform.x, transform.y)
.scale(transform.k);
draw(r, msg).pop();
})
);
return draw(r, msg).render();
}
Insert cell
Insert cell
{
const r = new Renderer(300, 300).clear("bisque").fit();
const msg = "Bounded zoomer";
r.selection().call(
d3
.zoom()
.scaleExtent([1, 2]) // Allow zooming un up to 2x, and no zooming out (min scale of 1)
.translateExtent([
// Allow panning 50% outside original (-1 to 1) bounds.
r.dataToScreen([-1.5, -1.5]),
r.dataToScreen([1.5, 1.5])
])
.on("zoom", ({ transform }) => {
r.clear("bisque")
.push()
.translate(transform.x, transform.y)
.scale(transform.k);
draw(r, msg).pop();
})
);
return draw(r, msg).render();
}
Insert cell
Insert cell
{
const r = new Renderer(300, 300).clear("bisque").fit();
const msg = "Drag me";
r.selection().call(
d3.zoom().on("zoom", ({ transform }) => {
r.push().translate(transform.x, transform.y);
draw(r, msg).pop();
})
);
return draw(r, msg).render();
}
Insert cell
Insert cell
{
const r = new Renderer(300, 300).fit();
const msg = "Pan and zoom me";
r.selection().call(
d3.zoom().on("zoom", ({ transform }) => {
r.clear("rgba(255,255,255,0.15)", false);
r.push().translate(transform.x, transform.y).scale(transform.k);
draw(r, msg).pop();
})
);
return draw(r, msg).render();
}
Insert cell
Insert cell
{
const r = new Renderer(300, 300).fit();
const msg = "Move me";
r.selection().call(
d3.zoom().on("zoom", ({ transform }) => {
r.push()
.translate(transform.x, transform.y)
.scale(transform.k)
.clear("bisque");
draw(r, msg).pop();
})
);
return draw(r, msg).render();
}
Insert cell
Insert cell
{
const r = new Renderer(300, 300, "svg")
.fit()
.clear("bisque")
.textSize(12)
.stroke()
.text("I don't move", -0.9, -0.8)
.stroke("black");
const msg = "I don't change size when you zoom";
r.selection().call(
d3.zoom().on("zoom", ({ transform }) => {
r.clear("bisque")
.push()
.translate(transform.x, transform.y)
.scale(transform.k)
.textSize(12 / transform.k)
.strokeWidth(1 / transform.k)
.stroke("black");
draw(r, msg).pop();
r.stroke().text("I don't move", -0.9, -0.8);
})
);
return draw(r, msg).render();
}
Insert cell
Insert cell
{
const r = new Renderer(300, 300).clear("bisque").fit();
const msg = "I squish vertically";
r.selection().call(
d3.zoom().on("zoom", ({ transform }) => {
r.clear("bisque").push().translate(0, transform.y).scale(1, transform.k);
draw(r, msg).pop();
})
);
return draw(r, msg).render();
}
Insert cell
Insert cell
{
const [w, h] = [600, 100];

const drawAxis = (r, sc = 1) => {
const xSc = d3
.scaleLinear()
.domain([0, 1000 / sc])
.range([0.05 * w, 0.95 * w]);
const ySc = d3.scaleLinear().range([0.9 * h, 0.1 * h]);
return r
.text("Zoom to change axis scale", -0.5, -0.2)
.axisBottom(xSc, ySc, 0, 0.5);
};

const r = new Renderer(w, h).clear("bisque").fit().stroke();
r.selection().call(
d3.zoom().on("zoom", ({ transform }) => {
r.clear("bisque").push();
drawAxis(r, transform.k).pop();
})
);
return drawAxis(r).render();
}
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