Public
Edited
Jun 5
Importers
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
viewof table = {
const target = Inputs.table(penguins);
const context = htl.html`<div style="overflow:hidden;border:1px solid #aaa">${target}`;
zoomableElement(context, target);
// Pass the .value prop through.
Object.defineProperty(context, "value", Object.getOwnPropertyDescriptor(target, "value"));
return context;
}
Insert cell
table
Insert cell
Insert cell
function zoomableElement(context, element, {
transformOrigin = "0 0",
scaleExtent = [.1, 4],
} = {}) {
if(transformOrigin) element.style.transformOrigin = transformOrigin;
const zoom = d3.zoom()
.scaleExtent(scaleExtent)
.constrain(constrain)
.on("zoom", onZoom);
d3.select(context)
.call(zoom)
.on("dblclick.zoom", null)
.on("wheel", e => e.preventDefault(), {passive: false});
return element;

//const clamp = (a, b, v) => v <= a ? a : v >= b ? b : v;

// Reference: https://github.com/d3/d3-zoom/blob/1bccd3f/src/zoom.js#L42
function constrain(transform, extent, translateExtent) {
const cw = element.clientWidth;
const ch = element.clientHeight;
const dx0 = transform.invertX(extent[0][0]) - translateExtent[0][0];
const dx1 = transform.invertX(extent[1][0]) - translateExtent[1][0];
const dy0 = transform.invertY(extent[0][1]) - translateExtent[0][1];
const dy1 = transform.invertY(extent[1][1]) - translateExtent[1][1];
return transform.translate(
dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),
dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)
);
}

function onZoom({transform: {x, y, k}}) {
element.style.transform = `translate(${x}px,${y}px) scale(${k})`;
}

}
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