Public
Edited
May 15, 2023
2 forks
Importers
91 stars
Insert cell
Insert cell
Insert cell
projection = d3.geoAlbers()
.fitSize([mapWidth, mapHeight], geoJsonUsa);
Insert cell
{
const svg = d3.select(DOM.svg(mapWidth, mapHeight));
svg.selectAll("path")
.data(geoJsonUsa.features)
.enter().append("path")
.attr("fill", "#eee")
.attr("stroke", "#bbb")
.attr("d", d3.geoPath(projection));
return svg.node();
}
Insert cell
Insert cell
scaleBar = d3.geoScaleBar()
.projection(projection)
.size([mapWidth, mapHeight]);
Insert cell
{
const svg = d3.select(DOM.svg(mapWidth, mapHeight));
svg.selectAll("path")
.data(geoJsonUsa.features)
.enter().append("path")
.attr("fill", "#eee")
.attr("stroke", "#bbb")
.attr("d", d3.geoPath(projection));
// Call the scale bar like this.
svg.append("g")
.call(scaleBar);
return svg.node();
}
Insert cell
Insert cell
scaleBarPositioned = d3.geoScaleBar()
.projection(projection)
.size([mapWidth, mapHeight])
.left(.05)
.top(.85)
.tickFormat(d3.format(",")); // A formatter function adds a comma to "1,000"
Insert cell
Insert cell
Insert cell
scaleBarWapo = d3.geoScaleBar()
.projection(projection)
.size([mapWidth, mapHeight])
.left(left)
.top(top)
.units(d3.geoScaleMiles) // The units will be miles instead of kilometers
.distance(500) // The distance of the scale bar
.label("500 miles") // The label on top of the scale bar
.labelAnchor("middle") // The position of the label (you can also pass "start" and "end")
.tickSize(null) // The height of the bar
.tickValues(null); // The tick values below the bar will be removed
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
scaleBarTop = d3.geoScaleBar()
.orient(d3.geoScaleTop) // The other orientation is d3.geoScaleBottom, which is the default
.top(.1)
.left(.5)
.distance(250)
.label(null)
.tickPadding(3) // How far the tick text labels are from the lines
.tickFormat((d, i, e) => i === e.length - 1 ? `${d} Kilometers` : d)
.tickValues([0, 250])
Insert cell
Insert cell
scaleBarBottom = d3.geoScaleBar()
.units(d3.geoScaleMiles) // Other options are d3.geoScaleFeet, d3.geoScaleKilometers, and d3.geoScaleMeters
.orient(d3.geoScaleBottom) // Redundant as this is the default
.top(.1)
.left(.5)
.distance(250)
.label(null)
.tickPadding(3) // How far the tick text labels are from the lines
.tickFormat((d, i, e) => i === e.length - 1 ? `${d} Miles` : d)
.tickValues([0, 250]);
Insert cell
Insert cell
projectionIndia = proj4d3(`+proj=aea +lat_2=12 +lat_1=28 +lat_0=20 +lon_0=78 +x_0=2000000 +y_0=2000000`)
Insert cell
Insert cell
Insert cell
scaleBarZoom = d3.geoScaleBar()
.zoomClamp(false) // Set this to true to keep the bar's width constant
.projection(projection)
.size([mapWidth, mapHeight])
.left(.05)
.top(.85)
.tickFormat(d => d3.format(",")(+d.toFixed(1))); // A formatter function rounds the tick values and adds a comma to "1,000"
Insert cell
{
const wrapper = d3.select(DOM.element("div"));
const svg = wrapper.append("svg")
.attr("width", mapWidth)
.attr("height", mapHeight);

const g = svg.append("g");
g.selectAll("path")
.data(geoJsonUsa.features)
.enter().append("path")
.attr("fill", "#eee")
.attr("stroke", "#bbb")
.attr("d", d3.geoPath(projection));
const bar = svg.append("g")
.attr("class", "scale-bar-wrapper")
.call(scaleBarZoom);
// Call d3.zoom on your SVG element
svg.call(d3.zoom()
.scaleExtent([1, 10])
.translateExtent([[0, 0], [mapWidth, mapHeight]])
.on("zoom", event => {
const t = event.transform;
g.attr("transform", t);
// Pass the k property of the zoom's transform
// to the scale bar's scaleFactor.
// Then call the scaleBar again.
scaleBarZoom.zoomFactor(t.k);
bar.call(scaleBarZoom);
})
);
wrapper.append("div")
.style("font-family", "sans-serif")
.style("font-size", "13px")
.style("color", "#555")
.text("You can zoom and pan this map.");
return wrapper.node();
}
Insert cell
Insert cell
scaleBarWapoZoom = d3.geoScaleBar()
.projection(projection)
.size([mapWidth, mapHeight])
.left(.1)
.top(.9)
.units(d3.geoScaleMiles)
.distance(500)
.label("500 miles")
.labelAnchor("middle")
.tickSize(null)
.tickValues(null);
Insert cell
Insert cell
Insert cell
scaleBarBottomZoom = d3.geoScaleBar()
.projection(projection)
.size([mapWidth, mapHeight])
.left(.1)
.top(.9)
.units(d3.geoScaleMiles)
.label(null)
.tickPadding(2)
.tickSize(0)
.tickFormat((d, i, e) => i === e.length - 1 ? `${d} mi.` : d)
.zoomClamp(false);
Insert cell
scaleBarTopZoom = d3.geoScaleBar()
.projection(projection)
.size([mapWidth, mapHeight])
.left(.1)
.top(.9)
.orient(d3.geoScaleTop)
.label(null)
.tickPadding(2)
.tickSize(0)
.tickFormat((d, i, e) => i === e.length - 1 ? `${d} km.` : d)
.zoomClamp(false);
Insert cell
Insert cell
Insert cell
Insert cell
scaleBarTransition = d3.geoScaleBar()
.top(.1)
.left(.01)
.tickFormat(d3.format(","));
Insert cell
Insert cell
Insert cell
scaleBarMoon = d3.geoScaleBar()
.radius(1737.4) // The radius of the moon is 1,737.4 kilometers
.top(.9)
.left(.05);
Insert cell
Insert cell
Insert cell
scaleBarDc = d3.geoScaleBar()
.top(.9)
.left(.05)
.radius(6967419.888)
.label("Yards")
// .units({units: "yards", radius: 6967419.888}) // Will do the same as the previous two lines
.distance(mapWidth <= 400 ? 1200 : 1000)
.tickFormat(d3.format(","));
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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