Demo of leaflet & D3 from Mike Bostock's tutorial, updated with an openstreetmap URL that works.
forked from pbogden's block: D3 + Leaflet
forked from brandonhaydu's block: D3 + Leaflet
forked from brandonhaydu's block: D3 + Leaflet v1
forked from brandonhaydu's block: D3 + Leaflet v2
forked from curran's block: Horizontal Bar Chart
forked from brandonhaydu's block: Horizontal Bar Chart
forked from brandonhaydu's block: Horizontal Bar Chart v2
forked from brandonhaydu's block: D3 + Leaflet v3
xxxxxxxxxx
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://d3js.org/d3.v4.min.js"></script>
<title>2016 Presedential Votes</title>
<style>
@import url(//cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.2/leaflet.css);
body {
margin: 0px;
}
.domain {
display: none;
}
.tick line {
stroke: #C0C0BB;
}
.tick text {
fill: #8E8883;
font-size: 10pt;
font-family: sans-serif;
}
.axis-label {
fill: #635F5D;
font-size: 16pt;
font-family: sans-serif;
}
.topcorner{
position:absolute;
top:0;
right:0;
height: 250px;
width: 480px;
z-index: 100;
background:white;
}
#map {
width: 960px;
height: 500px;
}
path {
fill: #000;
fill-opacity: .2;
stroke: #fff;
stroke-width: 1.5px;
}
path:hover {
fill: brown;
fill-opacity: .7;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.2/leaflet.js"></script>
<body>
<div class="topcorner">
<svg width="480" height="250"></svg>
</div>
<div id="map"</div>
<script>
//**************************chart*****************************************
var barChart = function(countyFP){
const xValue = d => d.value;
const xLabel = 'Votes';
const yValue = d => d.name;
const yLabel = 'Candidate';
const margin = { left: 150, right: 30, top: 5, bottom: 75 };
const svg = d3.select('svg');
const svgRemove = svg.selectAll('*').remove();
const width = svg.attr('width');
const height = svg.attr('height');
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const xAxisG = g.append('g')
.attr('transform', `translate(0, ${innerHeight})`);
const yAxisG = g.append('g');
xAxisG.append('text')
.attr('class', 'axis-label')
.attr('x', innerWidth / 2)
.attr('y', 55)
.text(xLabel);
const xScale = d3.scaleLinear();
const yScale = d3.scaleBand()
.paddingInner(0.3)
.paddingOuter(0);
const xTicks = 5;
const xAxis = d3.axisBottom()
.scale(xScale)
.ticks(xTicks)
.tickPadding(5)
.tickFormat(d3.format('.0s'))
.tickSize(-innerHeight);
const yAxis = d3.axisLeft()
.scale(yScale)
.tickPadding(5)
.tickSize(-innerWidth);
const row = d => {
return {
county: d.countyfp10,
attributes:[
{
name: 'Clinton',
value: Number(d.pres_clinton)
},
{
name: 'Trump',
value: Number(d.pres_trump)
},
{
name: 'Johnson',
value: Number(d.pres_johnson)
},
{
name: 'Stein',
value: Number(d.pres_stein)
},
{
name: 'Lariva',
value: Number(d.pres_lariva)
},
{
name: 'Other',
value: Number(d.pres_other)
}
]
};
};
const top5 = data => data.slice(0, 5);
//function filterCriteria(d) {
// return d.county === '037';
//};
function filterCriteria(d) {
return d.county === countyFP;
};
d3.csv('california-2016-county-results.csv', row, data => {
//data = top5(data);
data = data.filter(filterCriteria);
data = data[0]['attributes'];
//console.log(data);
//console.log(Object.keys(data)[0]);
yScale
.domain(data.map(yValue).reverse())
.range([innerHeight, 0]);
xScale
.domain([0, d3.max(data, xValue)])
.range([0, innerWidth])
.nice(xTicks);
g.selectAll('rect').data(data)
.enter().append('rect')
.attr('x', 0)
.attr('y', d => yScale(yValue(d)))
.attr('width', d => xScale(xValue(d)))
.attr('height', d => yScale.bandwidth())
.attr('fill', 'steelblue');
xAxisG.call(xAxis);
yAxisG.call(yAxis);
yAxisG.selectAll('.tick line').remove();
});
};
barChart('037');
//**************************chart*****************************************
//**************************map*******************************************
var osmUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
osmAttrib = '© <a href="https://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
osm = L.tileLayer(osmUrl, {maxZoom: 18, attribution: osmAttrib});
var map = L.map('map').setView([37.5, -115], 6).addLayer(osm);
var svgMap = d3.select(map.getPanes().overlayPane).append("svg"),
gMap = svgMap.append("g").attr("class", "leaflet-zoom-hide");
var transform = d3.geoTransform({point: projectPoint}),
path = d3.geoPath().projection(transform);
d3.json("counties.json", function(error, ca) {
var features = ca.objects.CA.geometries.map(function(d) { return topojson.feature(ca, d); });
var all = topojson.merge(ca, ca.objects.CA.geometries);
var states = gMap.selectAll("path")
.data(features)
.enter()
.append("path")
.on("mouseover", function(d){
//d3.select(this).transition(0).duration(0);
//console.log(d.properties.COUNTYFP)
barChart(d.properties.COUNTYFP);
});
map.on("viewreset", reset);
reset();
// Reposition the SVG to cover the features.
function reset() {
var bounds = path.bounds(all),
topLeft = bounds[0],
bottomRight = bounds[1];
svgMap .attr("width", bottomRight[0] - topLeft[0])
.attr("height", bottomRight[1] - topLeft[1])
.style("left", topLeft[0] + "px")
.style("top", topLeft[1] + "px");
gMap.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
states.attr("d", path);
}
});
// Use Leaflet to implement a D3 geometric transformation.
function projectPoint(x, y) {
// Returns the map layer point that corresponds to the given geographical coordinates
var point = map.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
//**************************map*******************************************
</script>
Modified http://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.2/leaflet.js to a secure url
https://d3js.org/d3.v4.min.js
https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.js
https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.2/leaflet.js