Skip to content

Instantly share code, notes, and snippets.

@laurencedorman
Last active November 7, 2018 09:45
Show Gist options
  • Save laurencedorman/a8158c5338d31e555a716cbb556a2198 to your computer and use it in GitHub Desktop.
Save laurencedorman/a8158c5338d31e555a716cbb556a2198 to your computer and use it in GitHub Desktop.
Dorling Circle
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>les-habitants-des-departements-ruraux-sont-les-mieux-dotes</title>
<link rel="stylesheet" href="https://data.alternatives-economiques.fr/assets/css/style.css">
<style>
#container {
height: 400px;
min-width: 310px;
margin: 0 auto;
}
.region {
stroke: #222;
stroke-width: 0.2px;
}
.square {
fill-opacity: .8;
stroke: #000;
fill: #fff;
stroke-width: .5px;
}
.label {
text-anchor: middle;
font-size: 20px;
color: black;
fill: black;
stroke: none;
}
#layer path {
fill: #fffcd8 !important;
}
.links line {
stroke-opacity: 0.1;
}
.circles {
stroke: white;
stroke-width: 1;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.3.6/papaparse.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@alter-eco/choropleth@0.1.6/dist/main.min.js"></script>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://rawgit.com/maxogden/geojson-js-utils/master/geojson-utils.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Turf.js/5.1.5/turf.min.js"></script>
<div id="container"></div>
<script>
var container = document.getElementById('container');
var valueKey = 'value';
var data = [
"name,value,code",
"Ain,275.2,01",
"Aisne,317.9,02",
"Allier,350.8,03",
"Alpes-de-Haute-Provence,349.8,04",
"Hautes-Alpes,370.2,05",
"Alpes-Maritimes,194.9,06",
"Ardèche,343.8,07",
"Ardennes,359.6,08",
"Ariège,419.9,09",
"Aube,283.1,10",
"Aude,394.4,11",
"Aveyron,407.1,12",
"Bouches-du-Rhône,268.8,13",
"Calvados,278.1,14",
"Cantal,539.5,15",
"Charente,307.2,16",
"Charente-Maritime,323,17",
"Cher,395.7,18",
"Corrèze,371.3,19",
"Côte-d'Or,264.9,21",
"Côtes-d'Armor,307,22",
"Creuse,648.6,23",
"Dordogne,368.8,24",
"Doubs,261,25",
"Drôme,280.5,26",
"Eure,234.5,27",
"Eure-et-Loir,265.4,28",
"Finistère,312.1,29",
"Corse-du-Sud,683.2,2A",
"Haute-Corse,522,2B",
"Gard,359.8,30",
"Haute-Garonne,196.9,31",
"Gers,414.8,32",
"Gironde,213.3,33",
"Hérault,255.2,34",
"Ille-et-Vilaine,248.1,35",
"Indre,333.8,36",
"Indre-et-Loire,228.9,37",
"Isère,264,38",
"Jura,322.1,39",
"Landes,279.6,40",
"Loir-et-Cher,270.2,41",
"Loire,265.6,42",
"Haute-Loire,340.4,43",
"Loire-Atlantique,210.4,44",
"Loiret,262.9,45",
"Lot,399.2,46",
"Lot-et-Garonne,359.8,47",
"Lozère,830.1,48",
"Maine-et-Loire,238,49",
"Manche,244.4,50",
"Marne,188.2,51",
"Haute-Marne,439.4,52",
"Mayenne,392.5,53",
"Meurthe-et-Moselle,268.3,54",
"Meuse,428.1,55",
"Morbihan,290.3,56",
"Moselle,220.4,57",
"Nièvre,443,58",
"Nord,328.9,59",
"Oise,287.9,60",
"Orne,478.5,61",
"Pas-de-Calais,365.1,62",
"Puy-de-Dôme,248.2,63",
"Pyrénées-Atlantiques,245.3,64",
"Hautes-Pyrénées,438.8,65",
"Pyrénées-Orientales,363.9,66",
"Bas-Rhin,237.8,67",
"Haut-Rhin,216.3,68",
"Rhône,104.5,69",
"Haute-Saône,341.8,70",
"Saône-et-Loire,295.3,71",
"Sarthe,270.7,72",
"Savoie,238.5,73",
"Haute-Savoie,243.1,74",
"Paris,2125.8,75",
"Seine-Maritime,308.3,76",
"Seine-et-Marne,170.1,77",
"Yvelines,106.3,78",
"Deux-Sèvres,288.5,79",
"Somme,301,80",
"Tarn,326.7,81",
"Tarn-et-Garonne,369.5,82",
"Var,201.1,83",
"Vaucluse,297.2,84",
"Vendée,274.6,85",
"Vienne,262.7,86",
"Haute-Vienne,323.6,87",
"Vosges,323,88",
"Yonne,336.5,89",
"Territoire de Belfort,262.1,90",
"Essonne,156.8,91",
"Hauts-de-Seine,129.7,92",
"Seine-Saint-Denis,304.5,93",
"Val-de-Marne,259.2,94",
"Val-d'Oise,168.3,95",
"Guadeloupe,561.9,971",
"Martinique,971,972",
"Guyane,1299.6,973",
"Réunion,638.1,974",
"Mayotte,786.7,976",
].join('\n');
Papa.parse(data, {
header: true,
complete: function(response) {
var data = response.data;
data = data.sort(function(a, b) {
return d3.descending(+a[valueKey], +b[valueKey]);
});
var min = d3.min(data, function(datum) { return +datum[valueKey]; });
var max = d3.max(data, function(datum) { return +datum[valueKey]; });
var choropleth = window.choropleth = Choropleth.create({
elem: '#container',
map: 'france-departements',
data: data,
valueColumn: valueKey,
neutralColor: '#ccc',
tooltip: true,
scale: d3.scaleThreshold()
.domain([200, 300])
.range(['#e5f5f9','#99d8c9','#2ca25f'])
});
var linksContainer = choropleth.map
.append('g')
.attr('id', 'links')
.attr('class', 'links');
var bubblesContainer = choropleth.map
.append('g')
.attr('id', 'circles')
.attr('class', 'circles');
var bubbleScale = d3.scaleSqrt()
.domain([min, max])
.range([10, 30]);
choropleth.on('draw', function() {
var featuresById = {};
var nodes = choropleth.geojson.features.map(function(d, i, features) {
featuresById[d.properties.code] = d;
var centroid = choropleth.path.centroid(d);
var polygon1 = d;
var polygon2 = features[i+1];
return {
geo: d,
id: d.properties.code,
properties: d.properties,
cx: centroid[0],
cy: centroid[1],
r: bubbleScale(+choropleth.dataById[d.properties.code][valueKey])
};
});
var linksData = [];
choropleth.geojson.features.forEach(function(d, i, features) {
var polygon = d;
var featuresMinusPolygon = features.slice(0);
featuresMinusPolygon.splice(i, 1);
featuresMinusPolygon.forEach(function(d) {
var value = turf.lineOverlap(polygon,d);
if (value.features.length > 0) {
linksData.push({ source: polygon.properties.code, target: d.properties.code })
}
});
});
var bubbles = bubblesContainer
.selectAll('.circles')
.data(nodes)
.enter()
.append('g')
.attr('class', 'circles')
.attr("transform", function(d) {
return "translate(" + d.cx + "," + d.cy + ")";
});
bubbles.append('circle')
.attr('id', function(d) {
return d.properties.nom;
})
.attr('r', function(d) {
return d.r;
})
.attr('fill', function(d) {
return choropleth.fill(d);
});
bubbles.append('text')
.classed('label', true)
.attr('dy', 5)
.text(function(d) {
return d.properties.code;
});
var links = linksContainer
.selectAll('.links')
.data(linksData)
.enter()
.append('line')
.attr('stroke-width', 2)
.attr('stroke', 'white');
var simulation = d3.forceSimulation(nodes)
.force('collide', d3.forceCollide()
.radius(function(d) {
return d.r + 3;
})
.strength(0.3))
.force('links', d3.forceLink(linksData)
.id(function(d) {
return d.id;
})
.iterations(100)
.distance(function(d) {
var source = choropleth.path.centroid(d.source.geo);
var target = choropleth.path.centroid(d.target.geo);
return Math.hypot(target[0]-source[0], target[1]-source[1]);
})
)
.force('x', d3.forceX(function(d) {
return d.cx;
}).strength(1))
.force('y', d3.forceY(function(d) {
return d.cy;
}).strength(1))
.on('tick', function() {
bubbles
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
links
.attr("x1", function(d) {
return d.source.x; })
.attr("y1", function(d) {
return d.source.y; })
.attr("x2", function(d) {
return d.target.x; })
.attr("y2", function(d) {
return d.target.y; });
})
.on('end', function() {
d3.select('.links').remove();
});
});
choropleth.d3.select('#layer').remove();
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment