Public
Edited
Oct 11, 2023
1 fork
Insert cell
Insert cell
Insert cell
Insert cell
data
Insert cell
chart = {
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.style("border", "1px solid lightgrey");

// Draw axes
const gx = svg.append("g").call(xAxis, xScale);
const gy = svg.append("g").call(yAxis, yScale);

// Draw circles
const gc = svg.append("g");
const circles = gc
.selectAll("circle")
.data(data)
.join("circle")
.style("fill", "steelblue")
//.style("fill", (d) => cScale(d.PopGrowthRate))
.style("opacity", 0.8)
.attr("cx", (d) => xScale(d.Longitude))
.attr("cy", (d) => yScale(d.Latitude))
.attr("r", 3);
//.attr("r", d => aScale(d.Population));
circles.append("title").text((d) => d.FullName);

// Zooming code goes here...

//setupBrush(svg, circles, xScale.copy(), yScale.copy(), gx, gy);
//setupZoom(svg, circles, xScale, yScale, gx, gy);
//setupZoomTransf(svg, circles, gc, gx, gy);

// Update with new x&y scales for zooming (without re-running the whole cell)
svg.node().update = function (xScaleNew, yScaleNew) {
// update code goes here ...
};

return svg.node();
}
Insert cell
Insert cell
xScale = d3
.scaleLinear()
.domain(d3.extent(data, (r) => r.Longitude))
//.domain([-90, -67])
.range([margin.left, width - margin.right])
//.range([-900, 944])
Insert cell
xScale.domain() // view the x domain extent in Longitude coords
Insert cell
xScale.range() // view the x range extent in pixels
Insert cell
yScale = d3
.scaleLinear()
.domain(d3.extent(data, (r) => r.Latitude))
.range([height - margin.bottom, margin.top])
Insert cell
Insert cell
function setupBrush(svg, circles, xscale, yscale, gx, gy) {
// D3 Brush API
const brush = d3.brush().on("end", brushing); // Only zoom on brush 'end' event
const gb = svg.append("g").call(brush);

// Brush event callback
function brushing(event) {
if (event.selection) {
const [[x0, y0], [x1, y1]] = (mutable brushCoords = event.selection); // Get brush pixel coordinates
// Do brush zoom here...

// update the scales
// update the plot, given new x & y scales
}
}
}
Insert cell
mutable brushCoords = null
Insert cell
viewof resetbutton = Inputs.button("Reset Map")
Insert cell
Insert cell
function setupZoom(svg, circles, xscale, yscale, gx, gy) {
// D3 Zoom API
const extent = [
[margin.left, margin.top],
[width - margin.right, height - margin.top]
];
const zoom = d3
.zoom()
.extent(extent) // Where the interaction occurs
.translateExtent(extent) // Limits panning to the original extent
.scaleExtent([1, 32]) // Sets the maximum zoom factor
.on("zoom", zooming);
svg.call(zoom);

// Zoom event callback
function zooming(event) {
mutable transform = event.transform;
// Do zooming here, event.transform expresses the pan+zoom from original x & y scales

// update the scales
// update the plot
}
}
Insert cell
mutable transform = null
// k = scale; x,y = translate
// zooming is exponential, double click changes scale by factor of 2
Insert cell
Insert cell
// Zoom slider
viewof zoom = html`<input type="range" min=0 max=8 value=0 step=0.1>`
Insert cell
zoom
Insert cell
{
// Compute new transform
// Apply transform to Scales
// update the plot
}
Insert cell
Insert cell
function setupZoomTransf(svg, circles, gc, gx, gy) {
// D3 Zoom API
const extent = [
[margin.left, margin.top],
[width - margin.right, height - margin.top]
];
const zoom = d3
.zoom()
.extent(extent) // Where the interaction occurs
.translateExtent(extent) // Limits panning to the original extent
.scaleExtent([1, 32]) // Sets the maximum zoom factor
.on("zoom", zooming);
svg.call(zoom);

// Zoom event callback
function zooming(event) {
mutable transform = event.transform;
// Do zooming here, event.transform expresses the pan+zoom from original x & y scales

// Geometric zoom:

// Spatial zoom:
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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