Public
Edited
Feb 16, 2024
Insert cell
Insert cell
Insert cell
viewof map = {
const target = html`<div style="height: 400px;">`;
yield target; // Give the container dimensions.
const map = (target.value = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target,
view: new ol.View({
center: ol.proj.fromLonLat([-97, 38]),
zoom: 4
})
// view: new ol.View({
// center: ol.proj.fromLonLat([110.5, -7]),
// zoom: 10
// })
}));

d3.json(usUrl).then(function (us) {
// console.log(us);
const layer = new CanvasLayer2({
features: topojson.feature(us, us.objects.counties)
});
map.addLayer(layer);
});

invalidation.then(() => map.dispose());
return target;
}
Insert cell
Insert cell
class CanvasLayer2 extends ol.layer.Layer {
constructor(options) {
super(options);

this.features = options.features;

this.canvas = document.createElement("canvas");
this.canvas.style.position = "absolute";
this.ctx = this.canvas.getContext("2d");
}

getSourceState() {
return "ready";
}

render(frameState) {
const width = frameState.size[0];
const height = frameState.size[1];
const projection = frameState.viewState.projection;
const d3Projection = d3.geoMercator().scale(1).translate([0, 0]);
let d3Path = d3.geoPath().projection(d3Projection);

const pixelBounds = d3Path.bounds(this.features);
// console.log(pixelBounds);
const pixelBoundsWidth = pixelBounds[1][0] - pixelBounds[0][0];
const pixelBoundsHeight = pixelBounds[1][1] - pixelBounds[0][1];

const geoBounds = d3.geoBounds(this.features);
const geoBoundsLeftBottom = ol.proj.fromLonLat(geoBounds[0], projection);
const geoBoundsRightTop = ol.proj.fromLonLat(geoBounds[1], projection);
let geoBoundsWidth = geoBoundsRightTop[0] - geoBoundsLeftBottom[0];
if (geoBoundsWidth < 0) {
geoBoundsWidth += ol.extent.getWidth(projection.getExtent());
}
const geoBoundsHeight = geoBoundsRightTop[1] - geoBoundsLeftBottom[1];

const widthResolution = geoBoundsWidth / pixelBoundsWidth;
const heightResolution = geoBoundsHeight / pixelBoundsHeight;
const r = Math.max(widthResolution, heightResolution);
const scale = r / frameState.viewState.resolution;

const center = ol.proj.toLonLat(
ol.extent.getCenter(frameState.extent),
projection
);
const angle = (-frameState.viewState.rotation * 180) / Math.PI;

d3Projection
.scale(scale)
.center(center)
.translate([width / 2, height / 2])
.angle(angle);

d3Path = d3Path.projection(d3Projection);

this.canvas.width = width;
this.canvas.height = height;
this.ctx.clearRect(0, 0, width, height);

d3Path.context(this.ctx);
this.ctx.beginPath();
d3Path(this.features);
this.ctx.stroke();

this.ctx.fillStyle = "rgba(0, 250, 0, 0.5)"; // Adjust fill style as needed
this.ctx.fill();

return this.canvas;
}
}
Insert cell
viewof a5 = slider({
min: 0,
max: 100,
step: 1,
value: 10,
title: "Cautious input",
description:
"This range slider only yields its input when interactions seem finished - on mouseup, keyup, or touch end.",
cautious: true
})
Insert cell
viewof pv = Object.assign(Inputs.range([0, 1], { label: "tests" }), {
oninput: (event) => event.isTrusted && event.stopImmediatePropagation(),
onchange: (event) => event.currentTarget.dispatchEvent(new Event("input"))
})
Insert cell
Insert cell
historical_score = {
const data = {
employment: stored_pv,
supermarket: [0, 40.392084282460136, 80.088025150042869, 99.38509194611073]
};
return data;
}
Insert cell
viewof form = Inputs.form({
option1: viewof pv,
option2: Inputs.range([0, 100], { label: "Amount", step: 1 })
})
Insert cell
Insert cell
htl.html`<canvas width="960" height="300"></canvas>`
Insert cell
// {
// var context = d3.select("canvas").node().getContext("2d"),
// path = d3.geoPath().context(context);

// d3.json("https://unpkg.com/us-atlas@1/us/10m.json", function (error, us) {
// if (error) throw error;

// context.beginPath();
// path(topojson.mesh(us));
// context.stroke();
// });

// return context;
// }
Insert cell
d3.json(usUrl, function (data) {
console.log(data);
})
Insert cell
// usCounties = topojson.feature(usTopology, usTopology.objects.counties).features
Insert cell
usUrl = "https://gist.githubusercontent.com/mbostock/4090846/raw/d534aba169207548a8a3d670c9c2cc719ff05c47/us.json"
Insert cell
// usTopology = FileAttachment("usTopology.json").json()
Insert cell
Insert cell
topojson = require("topojson")
Insert cell
html`

<style>
path.boundary {
fill: none;
stroke: #777;
}
</style>
`
Insert cell
Insert cell
Insert cell
// watcher = {
// pv_input;
// ashp_input;
// gshp_input;
// insulation_input;
// electricity_input;
// gas_input;
// fuel_input;
// depriv_input;
// {
// mutable ovlScores = mutable ovlScores.concat(depriv_input);
// localStorage.setItem("grid_scores", JSON.stringify(mutable ovlScores));
// }
// }
Insert cell
// mutable ovlScores = {
// var initial = JSON.parse(localStorage.getItem("grid_scores") || "[]");
// return initial;
// }
Insert cell
Insert cell
// createBaseMap = {
// const svg = d3
// .create("svg")
// .attr("viewBox", [0, 0, width, 400])
// .style("width", "100%")
// .style("height", "auto");

// svg
// .append("path")
// .datum(lsoaData)
// .attr("fill", "transparent")
// .attr("stroke", "pink")
// .attr("stroke-width", 0.8)
// .attr("d", geoPath);

// return svg.node();
// }
Insert cell
// geoPath = d3.geoPath(projection)
Insert cell
// projection = d3.geoMercator().fitSize([600, 500], lsoaData)
Insert cell
// function drawGeoPathsToCanvas(geojson, ctx) {
// ctx.save();
// // ctx.globalCompositeOperation = "destination-out";

// // Create a geopath generator with the provided context
// const geoPath = d3.geoPath().context(ctx).projection(projection);

// // Draw all features in the GeoJSON onto the canvas at once
// ctx.beginPath();
// geoPath(geojson);
// // Set desired fill and stroke styles
// ctx.fillStyle = "transparent"; // Example fill color
// ctx.strokeStyle = "pink";
// ctx.fill();
// ctx.lineWidth = 0.7;
// ctx.stroke();
// ctx.closePath();

// // Restore context state
// // ctx.globalCompositeOperation = "source-over";
// ctx.restore();
// }
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