Public
Edited
Feb 8, 2023
Insert cell
Insert cell
<div id='map' style="width: 600px ; height: 600px"></div>
Insert cell
topojson
Insert cell
france = FileAttachment("france-data.topojson").json()
Insert cell
departements = topojson
.feature(france, france.objects.departements)
.features
Insert cell
centroids = departements
.map(function(d){
return path.centroid(d)
})
Insert cell
paris = centroids.filter(function(c, i){
return departements[i].properties.Département==='Paris'
})[0]
Insert cell
scale2 = d3.scaleSqrt()
.domain([0, 2000000])
.range([0, 30])
.clamp(true)
Insert cell
force = d3.forceSimulation()
Insert cell
path = d3.geoPath()
.projection(projection)
Insert cell
projection = d3.geoAlbers()
.center([0, 49.5])
.rotate([-2.8, 3])
.parallels([45, 55])
.scale(2500)
.translate([width / 2, height / 2])
Insert cell
height = +map.style('height').replace('px', '')
Insert cell
width = + map.style('width').replace('px', '')
Insert cell
map = d3.select('#map')
Insert cell
force.nodes(departements)
.force("repell", d3.forceCollide(function(d){
return scale2(d.properties['Inscrits'])
}).strength(1))
.force("x-align", d3.forceX(function(d, i) {
return centroids[i][0]
}).strength(0.1))
.force("y-align", d3.forceY(function(d, i) {
return centroids[i][1]
}).strength(0.1))
Insert cell
regions = map.selectAll(".departement")
Insert cell
paths_map = []
Insert cell
paths_circle = []
Insert cell
regions
.data(departements)
.enter().append("path")
.each(function(d, i){
d.x0 = centroids[i][0];
d.y0 = centroids[i][1];
var distance_to_paris = Math.sqrt(
Math.pow(centroids[i][0]-paris[0], 2)+
Math.pow(centroids[i][1]-paris[1], 2)
);
var k = distance_to_paris==0? 1 :100/distance_to_paris+1;
d.x = centroids[i][0]+k*(centroids[i][0]-paris[0]);
d.y = centroids[i][1]+k*(centroids[i][1]-paris[1]);
})
.attr("class", "departement")
.attr("id", function(departement){
return departement.properties['Département']
})
.attr("d", function(departement){
var path_map = path(departement);
var path_circle = circle(
departement
);
paths_map.push(path_map);
paths_circle.push(path_circle);
return path_map;
})
.style("fill",function(departement){
var ma = std(departement.properties['Macron']);
var le = std(departement.properties['Le Pen']);
var fi = std(departement.properties['Fillon']);
var me = std(departement.properties['Mélenchon']);
var color = new d3.rgb(me, ma, fi);
color = d3.hsl(color);
color.l = 0.5-le/(2*255);
color.h = color.h+hue_offset;
departement.color1 = color;
return color;
})
Insert cell
function circle(departement) {

var center = path.centroid(departement),
inscrits = departement.properties['Inscrits'],
radius = scale2(inscrits),
n = departement.geometry.coordinates
.map(function(coord) {return coord[0].length})
.reduce(function(a,b) {return a+b}) - 1,
angle, angleOffset = 0,
x0, y0,
i = -1,
points = []

while (++i < n) {

// do the math on the centered unit circle
angle = angleOffset + i * 2 * Math.PI / n;
x0 = Math.cos(angle);
y0 = Math.sin(angle);

// scale and translate
x0 = x0*radius + center[0];
y0 = y0*radius + center[1];
points.push(x0 + ' ' + y0);
}

// create a path
return "M " + points.join(' L ') +" Z";
};
Insert cell
function std(n){ return 255*(n-10)/20 }
Insert cell
hue_offset = 330
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