Published
Edited
May 15, 2019
Insert cell
Insert cell
map = svg`<svg viewBox="0 0 ${width} ${height}" style="width:100%;height:auto;">${tile().map(([x, y, z], i, tiles) => svg`
<image xlink:href="${url(x, y, z)}" x="${Math.round((x + tiles.translate[0]) * tiles.scale)}" y="${Math.round((y + tiles.translate[1]) * tiles.scale)}" width="${tiles.scale}" height="${tiles.scale}">`)}
<!--<path fill="none" stroke="red" d="${path(topology)}"/>-->
</svg>`
Insert cell
url = (x, y, z) => `http://tile.stamen.com/toner/${z}/${x}/${y}.png`
Insert cell
projection = d3.geoMercator()
Insert cell
path = d3.geoPath(projection)
Insert cell
tile = d3.tile()
.size([width, height])
.scale(projection.scale() * 2 * Math.PI)
.translate(projection([0, 0]))
Insert cell
height = {
const [[x0, y0], [x1, y1]] = d3.geoPath().bounds(topology);
const height = 800; //Math.ceil(y1 - y0);
//const scale = projection.scale() * (2 * Math.PI);
//projection.center(projection.invert([width / 2, height / 2]));
//projection.scale(Math.pow(2, Math.floor(Math.log2(scale))) / (2 * Math.PI));
//projection.translate([width / 2, height / 2]);
projection.scale(257055.08109204995);
projection.center([ -97.07555334199328, 49.85157748037587 ]);
projection.translate([ 350.0311677218043, 359.97649624406677 ]);
return height;
}
Insert cell
vectors = topology.features
Insert cell
topology = fetch("https://gist.githubusercontent.com/mbarison/39e9eef5c8da38499958ecc379e9623d/raw/36f3169efc652072cca6ead559d03f2affcfbf02/FOLM_St_Boniface.geojson").then(response => response.json())
Insert cell
topojson = require("topojson-client@3")
Insert cell
d3 = require("d3@^5.8", "d3-geo@1", "d3-tile@0.0.3")
Insert cell
color = d3.scaleQuantize()
.domain([0, 45])
.range(d3.schemeReds[9]);
Insert cell
d3.select("svg").selectAll("path").data(vectors).enter().append("path")
.attr("d", path)
.style("fill", (d) => color(d.properties.FOLM_PCT))
.style("stroke-width", "1")
.style("stroke", "#6e6e6e")
.style("opacity", 0.5);
Insert cell
legend = g => {
const x = d3.scaleLinear()
.domain(d3.extent(color.domain()))
.rangeRound([0, 260]);

g.selectAll("rect")
.data(color.range().map(d => color.invertExtent(d)))
.join("rect")
.attr("height", 8)
.attr("x", d => x(d[0]))
.attr("width", d => x(d[1]) - x(d[0]))
.attr("fill", d => color(d[0]));

g.append("text")
.attr("class", "caption")
.attr("x", x.range()[0])
.attr("y", -6)
.attr("fill", "#000")
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text("First official language minority (%)");

g.call(d3.axisBottom(x)
.tickSize(13)
.tickFormat(format)
.tickValues(color.range().slice(1).map(d => color.invertExtent(d)[0])))
.select(".domain")
.remove();
};
Insert cell
format = d3.format("");
Insert cell
d3.select("svg").append("g")
.attr("transform", "translate(310,20)")
.call(legend);
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