Public
Edited
Mar 1, 2021
1 fork
Insert cell
md`# Graphe Lyon

- importe le graphe de la ville de lyon
- stockage des sommets
- stockage des arrêtes
- dessin dans une visu
- ajout d'une projection
- coloriage des sommets/arrêtes
- ajout d'un fond de carte
- import de webcams_lyon et dessin sur le graphe
- ajout de données de traffic et coloriage
-> color scales de traffic

`
Insert cell
md` Etape 1: Récupérer les données du Grand Lyon`
Insert cell
md` Etape 2: Télécharger et inspecter les données`
Insert cell
md` Etape 3: Charger et pré-visualiser dans Observable`
Insert cell
edges
Insert cell
function createGraph(edges) {
const graph = { sources: [], targets: [], costs: [] };
edges.forEach(({ u, v, length },i) => {
const cost = length;

graph.sources.push(u);
graph.targets.push(v);
graph.costs.push(cost);

graph.sources.push(v);
graph.targets.push(u);
graph.costs.push(cost);
});

return graph;
}
Insert cell
graph = createGraph(edges)
Insert cell
nodes[2022]
Insert cell
import {edges, nodes} from "@pierreleripoll/small-lyon-voronoi"
Insert cell
// https://observablehq.com/@d3/chart-template
chart = {

const margin = ({top: 20, right: 30, bottom: 30, left: 40})
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

const x = d3.scaleLinear()
.domain(d3.extent(nodes, d => d.x))
.range([margin.left, width - margin.right])
const y = d3.scaleLinear()
.domain(d3.extent(nodes, d => d.y))
.range([height - margin.bottom, margin.top])
svg.selectAll(".line").data(Array.from(d3.range(graph.targets.length))).enter()
.append("line")
.attr("class", "line")
.attr("x1", function(d, i) { return x(nodes[graph.sources[i]].x); })
.attr("x2", function(d, i) { return x(nodes[graph.targets[i]].x); })
.attr("y1", function(d, i) { return y(nodes[graph.sources[i]].y); })
.attr("y2", function(d, i) { return y(nodes[graph.targets[i]].y); })
.attr("stroke", "black")
.attr("stroke-width", 2)
.attr("fill", "none");

return svg.node();
}
Insert cell
height = 500
Insert cell
graph
Insert cell
Array.from(d3.range(graph.targets.length))
Insert cell
d3 = require('d3@6', "d3-tile@1")
Insert cell
md` Etape X: Projection`
Insert cell
projection = d3.geoMercator().fitExtent([[10, 10], [width - 10, height - 10]], {
type: "MultiPoint",
coordinates: nodes.map(d => [d.x, d.y])
})
Insert cell
pts = nodes.map(d => projection([d.x, d.y]))
Insert cell
// https://observablehq.com/@d3/chart-template
chart2 = {

const margin = ({top: 20, right: 30, bottom: 30, left: 40})
const origin = projection([0, 0]);
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);
let image = svg
.append("g")
.attr("pointer-events", "none")
.selectAll("image");
const tile = d3.tile()
.size([width, height])
.scale(projection.scale() * 2 * Math.PI)
.translate(projection([0, 0]).map(Math.round))
.tileSize(512)
const tiles = tile();

image
.data(tiles, d => d)
.join("image")
.attr("xlink:href", d => url(...d3.tileWrap(d)))
.attr("x", ([x]) => (x + tiles.translate[0]) * tiles.scale)
.attr("y", ([, y]) => (y + tiles.translate[1]) * tiles.scale)
.attr("width", tiles.scale)
.attr("height", tiles.scale);
const x = d3.scaleLinear()
.domain(d3.extent(pts, d => d[0]))
.range([margin.left, width - margin.right])
const y = d3.scaleLinear()
.domain(d3.extent(pts, d => d[1]))
.range([margin.top, height - margin.bottom])
svg.selectAll(".line").data(Array.from(d3.range(graph.targets.length))).enter()
.append("line")
.attr("class", "line")
.attr("x1", function(d, i) { return x(pts[graph.sources[i]][0]); })
.attr("x2", function(d, i) { return x(pts[graph.targets[i]][0]); })
.attr("y1", function(d, i) { return y(pts[graph.sources[i]][1]); })
.attr("y2", function(d, i) { return y(pts[graph.targets[i]][1]); })
.attr("stroke", function(d, i) {
console.log(graph.sources[i])
if(typeof values_inverted[graph.sources[i]] != "undefined") {
console.log(values_inverted[graph.sources[i]])
return "black"
} else {
return "black"
}

})
.attr("stroke-width", 2)
// .style("fill", "red");

return svg.node();
}
Insert cell
json = d3.json("https://download.data.grandlyon.com/ws/grandlyon/pvo_patrimoine_voirie.pvocomptagecriter/all.json")
Insert cell
values = json.values.map(d => d.identifiantptm)
Insert cell
values_inverted = Object.assign({}, ...Object.entries(values).map(([a,b]) => ({ [b]: a })))
Insert cell
import {url} from "@pierreleripoll/city-graph-events"
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