Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src='https://api.mapbox.com/mapbox.js/v2.2.3/mapbox.js'></script>
<link href='https://api.mapbox.com/mapbox.js/v2.2.3/mapbox.css' rel='stylesheet' />
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
#map {
position:absolute;
width: 100%;
height: 100%;
}
</style>
<style> /* set the CSS */
body { font: 12px Arial;}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 1;
shape-rendering: crispEdges;
}
div.tooltip {
position: absolute;
text-align: center;
width: 200px;
height: 80px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
</style>
<style>
.color-legend text {
font-family: 'Open Sans', sans-serif;
font-size: 12pt;
font-weight: 600
}
</style>
</head>
<body>
<div id="map"></div>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3-legend/1.1.0/d3-legend.js"></script>
<script>
L.mapbox.accessToken = 'pk.eyJ1IjoiZW5qYWxvdCIsImEiOiJjaWhtdmxhNTIwb25zdHBsejk0NGdhODJhIn0.2-F2hS_oTZenAWc0BMf_uw'
//Setup our Leaflet map using Mapbox.js
var map = L.mapbox.map('map', 'mapbox.pencil', {maxZoom: 18, minZoom: 12})
.setView([45.7531152, 4.827906], 12);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
maxZoom: 18,
attribution: 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="https://mapbox.com">Mapbox</a>',
id: 'mapbox.streets'
}).addTo(map);
// Setup our svg layer that we can manipulate with d3
var svg = d3.select(map.getPanes().overlayPane)
.append("svg");
// Define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
/*****************************/
const outerWidth = 960;
const outerHeight = 500;
const margin = { left: 0, top: 0, right: 0, bottom: 0 };
const radiusMax = 180;
const xColumn = 'name';
const sliceSizeColumn = 'proportion';
const colorColumn = 'feature';
const skyBlue = '#3a5d8f';
const sunnySide = '#d8a34d';
const shadySide = '#633c27';
const pyramidColors = [
skyBlue,
shadySide,
sunnySide,
];
const legendColors = [
skyBlue,
sunnySide,
shadySide
];
const innerWidth = outerWidth - margin.left - margin.right;
const innerHeight = outerHeight - margin.top - margin.bottom;
const svgPie = d3.select('body').append('svg')
.attr('width', outerWidth)
.attr('height', outerHeight);
const gPie = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
const xAxisG = gPie.append('g')
.attr('class', 'x axis')
.attr('transform', `translate(0, ${innerHeight})`);
const pieG = gPie.append('g');
const colorLegendG = gPie.append('g')
.attr('class', 'color-legend')
.attr('transform', 'translate(620, 145)');
const xScale = d3.scale.ordinal().rangePoints([0, innerWidth]);
const colorScale = d3.scale.ordinal()
.range(pyramidColors);
const labels = [
'Sky',
'Sunny side of the pyramid',
'Shady side of the pyramid'
];
// a hack to get the legend elements to appear
// in the desired order
const legendColorScale = d3.scale.ordinal()
.domain(labels)
.range(legendColors);
const pie = d3.layout.pie()
.sort(null);
const arc = d3.svg.arc();
arc.outerRadius(radiusMax);
arc.innerRadius(0);
const colorLegend = d3.legend.color()
.scale(legendColorScale)
.shape('circle')
.shapePadding(50)
.shapeRadius(25)
.labelOffset(12);
function renderPie(dd) {
var data=[{data:{proportion:"0.74",feature:"sky"}},{data:{proportion:"0.04",feature:"shadySide"}},{data:{proportion:"0.22",feature:"sunnySide"}}];
//console.log(pie(data))
colorScale.domain(data.map(d => d[colorColumn]));
console.log(data.map(d => d[colorColumn]));
pie.value(d => d[sliceSizeColumn]);
;
const pieData = pie(data);
//console.log( pie(data))
pieG.attr('transform', `translate(${innerWidth / 3}, ${innerHeight / 2})`);
console.log(pieData);
const slices = pieG.selectAll('path').data(pieData);
slices.enter().append('path');
/*slices
.attr('d', arc)
.attr('fill', d => colorScale(d.data['feature']));*/
console.log( d => colorScale(d.data['feature']));
slices.exit().remove();
slices
.attr('transform', `rotate(220)`);
colorLegend.labels(labels);
colorLegendG.call(colorLegend);
d3.selectAll('text.label')
.attr('dy', '0em');
}
/***************************/
// Define the div for the tooltip
//var pieChart = d3.select("body").append("div")
//.attr("class", "tooltip")
//.style("opacity", 0);
var g = svg.append("g").attr("class", "leaflet-zoom-hide");
function project(ll) {
// our data came from csv, make it Leaflet friendly
var a = [+ll.lat, +ll.lon];
//console.log(ll)
// convert it to pixel coordinates
var point = map.latLngToLayerPoint(L.latLng(ll))
return point;
}
d3.json("stations.json", function(err, data) {
var dots = g.selectAll("circle.dot")
.data(data.values)
//console.log(dots)
dots.enter().append("circle").classed("dot", true)
.attr("r", 1)
.style({
fill: "#0082a3",
"fill-opacity": 0.6,
stroke: "#004d60",
"stroke-width": 1
})
.transition().duration(1000)
.attr("r",6)
function render() {
// We need to reposition our SVG and our containing group when the map
// repositions via zoom or pan
// https://github.com/zetter/voronoi-maps/blob/master/lib/voronoi_map.js
var bounds = map.getBounds();
var topLeft = map.latLngToLayerPoint(bounds.getNorthWest())
var bottomRight = map.latLngToLayerPoint(bounds.getSouthEast())
svg.style("width", map.getSize().x + "px")
.style("height", map.getSize().y + "px")
.style("left", topLeft.x + "px")
.style("top", topLeft.y + "px");
g.attr("transform", "translate(" + -topLeft.x + "," + -topLeft.y + ")");
// We reproject our data with the updated projection from leaflet
g.selectAll("circle.dot")
.attr({
cx: function(d) { return project(d).x},
cy: function(d) { return project(d).y},
r: function(d) { return d.bike_stands/5;
},
}).style("fill", function(d) {
// console.log(d) ;
if(d.available_bikes==0) return "#cc0010" ; else return "#ffffff" }).on("mouseover", handleMouseOver).on("mouseout", handleMouseOut).on("click",handleMouseClicked);
}
function handleMouseOut(d, i) {
// Use D3 to select element, change color back to normal
div.transition()
.duration(500)
.style("opacity", 0);
render();
}
function handleMouseClicked(d, i) {
renderPie(d);
// Use D3 to select element, change color back to normal
div.transition()
.duration(500)
.style("opacity", 0).style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
render();
}
function handleMouseOver(d, i) { // Add interactivity
console.log(d) ;
d3.select(this).attr({
r: function(d) { return d.bike_stands;
},
}).style("fill", function(d) {
if(d.available_bikes==0) return "#cc0010" ; else return "#ffffff" });
div.transition()
.duration(200)
.style("opacity", .7);
div.html( "<h2>name:"+d.name+"</h2><br/> " )
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
// Use D3 to select element, change color and size
}
// re-render our visualization whenever the view changes
map.on("viewreset", function() {
render()
})
map.on("move", function() {
render()
})
// render our initial visualization
render()
})
</script>
</body>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js
https://api.mapbox.com/mapbox.js/v2.2.3/mapbox.js
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.1.0/d3-legend.js