Skip to content

Instantly share code, notes, and snippets.

@vigorousnorth
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vigorousnorth/9370888 to your computer and use it in GitHub Desktop.
Save vigorousnorth/9370888 to your computer and use it in GitHub Desktop.
D3 weather map

D3 weather map

A basic map of weather data displayed as text annotations in D3.

var temps = {};
// Define historic climate data
temps = {
'Bangor' :
{
thiswinter_low: -20, thiswinter_lowdate: 'Jan. 4',
record_low: -32, record_lowdate: 'Feb. 2, 1948', record_lowsince: 1925
},
'Caribou' :
{
thiswinter_low: -28, thiswinter_lowdate: 'Jan. 2',
record_low: -41, record_lowdate: 'Feb. 1, 1955', record_lowsince: 1939
},
'Presque Isle':
{
thiswinter_low: -29, thiswinter_lowdate: 'Jan. 2, Jan. 4',
record_low: -41, record_lowdate: 'Jan. 19, 1925', record_lowsince: 1893
},
'Houlton' :
{
thiswinter_low: -24, thiswinter_lowdate: 'Jan. 2',
record_low: -41, record_lowdate: 'Jan. 4, 1981', record_lowsince: 1948
},
'Millinocket' :
{
thiswinter_low: -16, thiswinter_lowdate: 'Jan. 1, Jan. 2',
record_low: -40, record_lowdate: 'Feb. 2, 1962', record_lowsince: 1944
},
'Waterville' :
{
thiswinter_low: -18, thiswinter_lowdate: 'Jan. 4', record_low: -39, record_lowdate: 'Dec. 30, 1933', record_lowsince: 1896
},
'Bar Harbor' :
{
thiswinter_low: -9, thiswinter_lowdate: 'Jan. 4'
} ,
'Sanford' :
{
thiswinter_low: -22, thiswinter_lowdate: 'Jan. 4'
} ,
'Portland' :
{
thiswinter_low: -14, thiswinter_lowdate: 'Jan. 4',
record_low: -39, record_lowdate: 'Feb. 16, 1943', record_lowsince: 1874
},
'Augusta' :
{
thiswinter_low: -13, thiswinter_lowdate: 'Jan. 4', record_low: -23, record_lowdate: 'Feb. 2, 1962', record_lowsince: 1948
},
'Auburn' :
{
thiswinter_low: -18, thiswinter_lowdate: 'Jan. 4'
}
};
// Definte current temperature data (can be pulled via a php script from weather.gov)
temps['Sanford'].currenttemp = 11 ;
temps['Portland'].currenttemp = 10 ;
temps['Augusta'].currenttemp = -2 ;
temps['Bar Harbor'].currenttemp = 12 ;
temps['Auburn'].currenttemp = 1 ;
temps['Waterville'].currenttemp = -15 ;
temps['Millinocket'].currenttemp = -10 ;
temps['Houlton'].currenttemp = -3 ;
temps['Caribou'].currenttemp = -20 ;
temps['Presque Isle'].currenttemp = -9 ;
temps['Bangor'].currenttemp = -19 ;
$(document).ready(function() {
// Build the map
var width = 700,
height = 800;
var projection = d3.geo.conicConformal()
.parallels([38 + 02 / 60, 39 + 12 / 60])
.rotate([70, 0])
.scale(8500)
.translate([0.4*width, 9.5*height]);
var path = d3.geo.path()
.projection(projection)
.pointRadius(30);
var svg = d3.select("#mainmap").append("svg")
.attr("width", width)
.attr("height", height);
var g = svg.append("g");
var colorrange = d3.scale.linear()
.domain([-30, 50])
.range(["rgb(0,191,255)", "rgb(255,0,0)"]);
d3.json("mainecitiesandcounties_topo.json", function(error, topo) {
// Append temperature data to data object
for (city in temps) {
for (var i=0,len=topo.objects.cities.geometries.length; i<len; i++) {
if (topo.objects.cities.geometries[i]['properties']['name'] === city) {
topo.objects.cities.geometries[i]['properties']['temps'] = temps[city]
}
}
}
var counties = g.append("g")
.attr("class", "counties")
.selectAll("path")
.data(topojson.feature(topo, topo.objects.counties).features)
.enter().append("path")
.attr("d", path);
var cities =
g.append("g")
.selectAll("path")
.data(topojson.feature(topo, topo.objects.cities).features)
.enter().append("path")
.attr("class", "place")
.attr("d", path)
.attr("centroid-x", function(d) {
var centroid = path.centroid(d);
return centroid[0];
} )
.attr("centroid-y", function(d) {
var centroid = path.centroid(d);
return centroid[1];
});
var citylabels =
g.append("g").selectAll(".currenttemperature-label")
.data(topojson.feature(topo, topo.objects.cities).features)
.enter().append("text")
.attr("class", "currenttemperature-label")
.attr("transform", function(d) { return "translate(" + projection(d.geometry.coordinates) + ")"; })
.attr("dy", ".35em")
.attr("dx", "-.5em")
.text(function(d) {
if (d.properties.temps) return d.properties.temps.currenttemp;
})
.style("fill", function(d) {
if (d.properties.temps) return colorrange(d.properties.temps.currenttemp);
})
.on("mouseover", function(d) {
$('.currenttemperature-label').not(this).animate({opacity:0.1},200);
var s = d.properties.name;
var id = "#" + s.split(' ');
console.log(id);
$(id).fadeIn(500);
})
.on("mouseout", function(d) {
$('.currenttemperature-label').animate({opacity:1},100);
var s = d.properties.name;
var id = "#" + s.split(' ');
$(id).fadeOut(500);
});
var annotations =
g.append("g").selectAll(".more")
.data(topojson.feature(topo, topo.objects.cities).features)
.enter().append("text")
.text(function(d) {
return d.properties.name;
})
.attr("class", "more")
.attr("id", function(d) {
var s = d.properties.name;
return s.split(" ")[0];
})
.attr("transform", function(d) { return "translate(" + projection(d.geometry.coordinates) + ")"; })
.attr("dy", "2em")
.attr("dx", "-.5em");
annotations.append('tspan')
.text(function(d) {
if (d.properties.temps && d.properties.temps.thiswinter_low) {
return ("This winter's record low: ");
}
})
.attr("x","-.5em").attr("dy","1em")
.append('tspan').text(function(d) {
if (d.properties.temps && d.properties.temps.thiswinter_low) {
return d.properties.temps.thiswinter_low;
}
})
.attr('class','number')
.style("fill", function(d) {
if (d.properties.temps && d.properties.temps.thiswinter_low) {
return colorrange(d.properties.temps.thiswinter_low);
}
});
annotations.append("tspan").text(function(d) {
if (d.properties.temps && d.properties.temps.thiswinter_low) {
return "on " + d.properties.temps.thiswinter_lowdate;
}
}).attr("x","-.5em").attr("dy","1em");
annotations.append("tspan").text(function(d) {
if (d.properties.temps && d.properties.temps.record_low) {
return "Record low (since " + d.properties.temps.record_lowsince + "): ";
}
}).attr("x","-.5em").attr("dy","1.1em")
.append('tspan').text(function(d) {
if (d.properties.temps && d.properties.temps.record_low) {
return d.properties.temps.record_low;
}
})
.attr('class','number')
.style("fill", function(d) {
if (d.properties.temps && d.properties.temps.record_low) { return colorrange(d.properties.temps.record_low); }
});
annotations.append("tspan").text(function(d) {
if (d.properties.temps && d.properties.temps.record_low) {
return "on " + d.properties.temps.record_lowdate;
}
})
.attr("x","-.5em").attr("dy","1em")
});
});
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300' rel='stylesheet' type='text/css'>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,600,800' rel='stylesheet' type='text/css'>
<link href='style.css' rel='stylesheet' type='text/css'>
<script src="http://d3js.org/d3.v3.js"></script>
<script src="http://d3js.org/d3.geo.projection.v0.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="d3weathermap.js"></script>
</head>
<body>
<div id="coldtracchatter">
<h1>Current temperatures</h1>
<p>Mouse over the map's temperature readings to compare record lows for each location.</p>
</div>
<div id="mainmap">
</div>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<style type='text/css'>
body {width: 680px}
path {
stroke-linejoin: round;
stroke-linecap: round;
}
#mainmap {position: relative;}
#mainmap .state {
fill: #eee;
stroke: #222;
stroke-width: 2px;
}
#mainmap .counties {
fill: rgb(245,245,245);
stroke: #000;
stroke-width: 0.25px;
stroke-linejoin: round;
stroke-linecap: round;
}
#mainmap .active {
stroke: #eee; stroke-width: 0.5px;
}
#mainmap .currenttemperature-label {
font-family: "Open Sans", sans-serif;
font-weight: 800;
z-index: 1000;
color: #222;
font-size: 2.2em;
}
#mainmap .more {
font-family: "Open Sans", sans-serif;
font-weight: 400;
z-index: 1000;
color: #222;
font-size: 1em;
display: none;
}
#mainmap .more tspan {
font-size: 0.9em;
}
#mainmap tspan .number {
font-weight: 800;
font-size: 1em;
}
#mainmap .place { fill: none; stroke: none; }
#mainmap .label {font-family: 'Open Sans',sans-serif; float: right; width: 450px}
h1, h2 {font-family: 'Open Sans',sans-serif; }
#coldtracchatter {
font-family: 'Open Sans',sans-serif;
position: absolute;
left: 10px;
top: 40px;
width: 380px;
z-index: 100;
}
#coldtracchatter p {
width: 230px;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment