Skip to content

Instantly share code, notes, and snippets.

@floledermann
Last active July 3, 2016 14:32
Show Gist options
  • Select an option

  • Save floledermann/75d31b71f7171ae00cb5c6abb6441297 to your computer and use it in GitHub Desktop.

Select an option

Save floledermann/75d31b71f7171ae00cb5c6abb6441297 to your computer and use it in GitHub Desktop.
Minard's map, implemented in mapmap.js
// http://benschmidt.org/D3-trail/minard.html
var napoleon = {};
napoleon.cities =
[{"lon": 24.0 ,"lat":55.0 ,"name":"Kowno" },
{"lon": 25.3 ,"lat":54.7 ,"name":"Wilna" },
{"lon": 26.4 ,"lat":54.4 ,"name":"Smorgoni",dir:-1},
{"lon": 26.8 ,"lat":54.3 ,"name":"Molodexno",dir:-1},
{"lon": 27.7 ,"lat":55.2 ,"name":"Gloubokoe"},
{"lon": 27.6 ,"lat":53.9 ,"name":"Minsk",dir:-1},
{"lon": 28.5 ,"lat":54.3 ,"name":"Studienska",dir:-1},
{"lon": 28.7 ,"lat":55.5 ,"name":"Polotzk"},
{"lon": 29.2 ,"lat":54.4 ,"name":"Bobr",dir:-1},
{"lon": 30.2 ,"lat":55.3 ,"name":"Witebsk"},
{"lon": 30.4 ,"lat":54.5 ,"name":"Orscha",dir:-1},
{"lon": 30.4 ,"lat":53.9 ,"name":"Mohilow",dir:-1},
{"lon": 32.0 ,"lat":54.8 ,"name":"Smolensk"},
{"lon": 33.2 ,"lat":54.9 ,"name":"Dorogobouge"},
{"lon": 34.3 ,"lat":55.2 ,"name":"Wixma",dir:-1},
{"lon": 34.4 ,"lat":55.5 ,"name":"Chjat"},
{"lon": 36.0 ,"lat":55.5 ,"name":"Mojaisk"},
{"lon": 37.6 ,"lat":55.8 ,"name":"Moscou"},
{"lon": 36.6 ,"lat":55.3 ,"name":"Tarantino",dir:-1},
{"lon": 36.5 ,"lat":55.0 ,"name":"Malo-jarosewli",dir:-1}
]
napoleon.temp = [
{lon:37.65, temp:0, date:"18 Oct 1812"},
{lon:36.8, temp:0, date:"24 Oct 1812"},
{lon:34.3, temp:-9, date:"09 Nov 1812"},
{lon:32.0, temp:-21, date:"14 Nov 1812"},
{lon:29.2, temp:-11, date:"24 Nov 1812"},
{lon:28.5, temp:-20, date:"28 Nov 1812"},
{lon:27.2, temp:-24, date:"01 Dec 1812"},
{lon:26.7, temp:-30, date:"06 Dec 1812"},
{lon:25.3, temp:-26, date:"07 Dec 1812"}
];
//switch to celsius.
napoleon.temp = napoleon.temp.map(function(d) {
d.dir = -1; d.temp = d.temp*1.25;
return d})
napoleon.army = [
/* Group 1 */
{lon:24.0, lat:54.9, size:340000, dir:1, group:1},
{lon:24.5, lat:55.0, size:340000, dir:1, group:1},
{lon:25.5, lat:54.6, size:340000, dir:1, group:1},
{lon:26.0, lat:54.7, size:320000, dir:1, group:1},
{lon:27.0, lat:54.8, size:300000, dir:1, group:1},
{lon:28.0, lat:54.9, size:280000, dir:1, group:1},
{lon:28.5, lat:55.0, size:240000, dir:1, group:1},
{lon:29.0, lat:55.1, size:210000, dir:1, group:1},
{lon:30.0, lat:55.2, size:180000, dir:1, group:1},
{lon:30.3, lat:55.3, size:175000, dir:1, group:1},
{lon:32.0, lat:54.8, size:145000, dir:1, group:1},
{lon:33.2, lat:54.9, size:140000, dir:1, group:1},
{lon:34.4, lat:55.5, size:127100, dir:1, group:1},
{lon:35.5, lat:55.4, size:100000, dir:1, group:1},
{lon:36.0, lat:55.5, size:100000, dir:1, group:1},
{lon:37.6, lat:55.8, size:100000, dir:1, group:1},
{lon:37.65, lat:55.65, size:100000, dir:-1, group:1},
{lon:37.45, lat:55.62, size:98000, dir:-1, group:1},
{lon:37.0, lat:55.0, size:97000, dir:-1, group:1},
{lon:36.8, lat:55.0, size:96000, dir:-1, group:1},
{lon:35.4, lat:55.3, size:87000, dir:-1, group:1},
{lon:34.3, lat:55.2, size:55000, dir:-1, group:1},
{lon:33.3, lat:54.8, size:37000, dir:-1, group:1},
{lon:32.0, lat:54.6, size:24000, dir:-1, group:1},
{lon:30.4, lat:54.4, size:20000, dir:-1, group:1},
{lon:29.2, lat:54.3, size:20000, dir:-1, group:1},
{lon:29.13, lat:54.29, size:50000, dir:-1, group:1}, /* joined by group 2 */
{lon:28.5, lat:54.2, size:50000, dir:-1, group:1},
{lon:28.3, lat:54.3, size:28000, dir:-1, group:1},
{lon:27.2, lat:54.3, size:12000, dir:-1, group:1},
{lon:26.7, lat:54.4, size:14000, dir:-1, group:1},
{lon:25.3, lat:54.4, size:8000, dir:-1, group:1},
{lon:24.4, lat:54.4, size:4000, dir:-1, group:1},
{lon:24.2, lat:54.4, size:4000, dir:-1, group:1},
{lon:24.1, lat:54.4, size:10000, dir:-1, group:1},
/* Group 2 */
{lon:24.0, lat:55.1, size:60000, dir:1, group:2},
{lon:24.5, lat:55.2, size:60000, dir:1, group:2},
{lon:25.5, lat:54.7, size:60000, dir:1, group:2},
{lon:26.6, lat:55.7, size:40000, dir:1, group:2},
{lon:27.4, lat:55.6, size:33000, dir:1, group:2},
{lon:28.7, lat:55.5, size:33000, dir:1, group:2},
{lon:28.7, lat:55.5, size:33000, dir:-1, group:2},
{lon:29.13, lat:54.29, size:30000, dir:-1, group:2},
/* Group 3 */
{lon:24.0, lat:55.2, size:22000, dir:1, group:3},
{lon:24.5, lat:55.3, size:22000, dir:1, group:3},
{lon:24.6, lat:55.8, size:6000, dir:1, group:3},
{lon:24.6, lat:55.8, size:6000, dir:-1, group:3},
{lon:24.2, lat:54.4, size:6000, dir:-1, group:3}
];
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<style type="text/css">
html {
min-height: 100%;
overflow-x: hidden;
}
body {
position: relative;
font-family: sans-serif;
font-size: 0.8em;
}
svg {
width: 100%;
}
#mapEl {
border-bottom: 2px solid #999;
}
</style>
</head>
<body>
<svg id="mapEl" width="800" height="300"></svg>
<svg id="chartEl" width="800" viewBox="0 0 800 200" preserveAspectRatio="xMidYMin slice"></svg>
<small>Map data taken from <a href="http://benschmidt.org/D3-trail/minard.html">Ben Schmidt</a></small>
<script src="//d3js.org/d3.v3.js"></script>
<script src="//floledermann.github.io/mapmap-examples/lib/mapmap-0.3.8.js"></script>
<script src="data.js"></script>
<script>
var dd = mapmap.datadata;
var map = mapmap('#mapEl')
// layer 1: ARMY MOVEMENT
.geometry(napoleon.army, {
map: dd.map.key('group'),
reduce: dd.emit.geo.segments()
})
.meta({
'size': {
label: "Troop Size",
numberFormat: ',.0d',
domain: [0,1000000],
scale: 'linear',
'stroke-width': [0, 100],
undefinedLabel: null
},
'dir': {
scale: 'ordinal',
domain: [-1,1],
'stroke': ['#000000', '#e5cbab'],
undefinedSymbols: {
'stroke': '#000000'
}
}
})
.hoverInfo('size')
.attr('stroke-linecap', 'round')
.symbolizeAttribute('size', 'stroke-width')
.symbolizeAttribute('dir', 'stroke')
// The anchorFunction "projects" any data to a point on the map
.anchorFunction(lonAnchors)
// layer 2: CITIES
.geometry(napoleon.cities, {
map: dd.map.geo.point('lat','lon')
})
.symbolize(mapmap.symbolize.addLabel('name', {
dx: 7,
'text-anchor': 'left'
}))
;
createChart('chartEl', napoleon.temp, map);
function lonAnchors(obj) {
// search data for given longitude, starting from end of journey
for (var i=napoleon.army.length - 1; i>=0; i--) {
var place = napoleon.army[i];
if (place.lon == obj.lon) {
return this.project([place.lon, place.lat]);
}
}
return null;
}
function createChart(el, data, map) {
var width = 800,
height = 100;
var y = d3.scale.linear()
.range([height, 10]);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
el = d3.select('#' + el);
y.domain(d3.extent(data, function(d) { return d.temp; }));
var path = d3.svg.line()
.x(function(d){
return map.anchor(d)[0];
})
.y(function(d){ return y(d.temp); });
el.append('path')
.datum(data)
.attr({
'class': 'temp',
fill: 'none',
stroke: '#333',
'stroke-width': '0.8'
})
.attr('d', path);
el.selectAll('line.anchor')
.data(data)
.enter()
.append('line')
.attr({
'class': 'anchor',
x1:function(d){return map.anchor(d)[0]},
y1:function(d){ return y(d.temp); },
x2:function(d){return map.anchor(d)[0]},
y2:0,
fill: 'none',
stroke: '#333',
'stroke-width': '0.3'
});
d3.select('#mapEl g.fixed')
.selectAll('line.anchor')
.data(data)
.enter()
.append('line')
.attr({
'class': 'anchor',
x1:function(d){return map.anchor(d)[0]},
y1:function(d){ return map.anchor(d)[1]; },
x2:function(d){return map.anchor(d)[0]},
y2:400,
fill: 'none',
stroke: '#333',
'stroke-width': '0.3'
});
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment