|
<!DOCTYPE html> |
|
|
|
<!-- Based on https://gist.github.com/mukhtyar/9958903 --> |
|
|
|
<html> |
|
<head> |
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> |
|
<script src="http://pigshell.com/common/d3.v3/d3.v3.min.js"></script> |
|
<script src="http://pigshell.com/common/d3.v3/topojson.v1.min.js"></script> |
|
<script src="http://pigshell.com/common/d3.v3/colorbrewer.v1.min.js"></script> |
|
<script src="http://pigshell.com/common/d3.v3/queue.v1.min.js"></script> |
|
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'></script> |
|
|
|
<style type="text/css"> |
|
|
|
body { |
|
font-family: Arial, sans-serif; |
|
} |
|
|
|
.pc { |
|
fill: #bdbdbd; |
|
stroke: #636363; |
|
stroke-width: 0.25px; |
|
} |
|
|
|
.state { |
|
fill: none; |
|
stroke: #636363; |
|
stroke-width: 0.5px; |
|
stroke-linejoin: round; |
|
} |
|
|
|
div.tooltip { |
|
position: absolute; |
|
text-align: center; |
|
padding: 0.5em; |
|
font-size: 10px; |
|
color: #222; |
|
background: #FFF; |
|
border-radius: 2px; |
|
pointer-events: none; |
|
box-shadow: 0px 0px 2px 0px #a6a6a6; |
|
text-shadow:#f5f5f5 0 1px 0; |
|
} |
|
|
|
.caption { |
|
font: 12px sans-serif; |
|
font-weight: bold; |
|
} |
|
|
|
.key path { |
|
display: none; |
|
} |
|
|
|
.key line { |
|
stroke: #000; |
|
shape-rendering: crispEdges; |
|
} |
|
|
|
.key { |
|
font: 10px sans-serif; |
|
position: absolute; |
|
top: 0; |
|
left: 0; |
|
} |
|
|
|
#container { |
|
min-width: 480px; |
|
max-width: 720px; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
|
|
<div id="container"> |
|
</div> |
|
|
|
<script type="text/javascript"> |
|
|
|
var defaults = { |
|
title: "", |
|
keyfield: "key", |
|
field: "data", |
|
colorscale: "RdYlGn", |
|
inverse: "" |
|
}; |
|
|
|
window.addEventListener('message', function(e) { |
|
var opts = e.data.opts, |
|
data = e.data.data; |
|
|
|
return main(opts, data); |
|
}); |
|
|
|
function main(o, data) { |
|
var opts = $.extend({}, defaults, o); |
|
|
|
if (colorbrewer[opts.colorscale] === undefined) { |
|
opts.colorscale = "RdYlGn"; |
|
} |
|
|
|
var margin = {top: 10, bottom: 10, left: 10, right: 10}, |
|
wwidth = document.getElementById("container").offsetWidth, |
|
width = wwidth - margin.left - margin.right, |
|
_proj = d3.geo.mercator() |
|
.scale(1) |
|
.translate([0, 0]), |
|
topleft = _proj([68, 36]), |
|
botright = _proj([98, 6]), |
|
scale = width / (botright[0] - topleft[0]), |
|
wheight = scale * (botright[1] - topleft[1]) |
|
height = wheight - margin.top - margin.bottom, |
|
sheight = height + 50, |
|
scalewidth = 400; |
|
|
|
console.log("topleft", topleft); |
|
console.log("botright", botright); |
|
console.log("scale", scale); |
|
|
|
//Set tooltip |
|
var popupdiv = d3.select("body").append("div") |
|
.attr("class", "tooltip") |
|
.style("opacity", 0); |
|
|
|
//Set d3 projection, path and svg |
|
|
|
var projection = d3.geo.mercator() |
|
.center([83, 23.5]) |
|
.translate([width / 2, height / 2]) |
|
.scale(scale); |
|
|
|
var path = d3.geo.path() |
|
.projection(projection); |
|
|
|
var svg = d3.select("#container") |
|
.append("svg") |
|
.attr("width", width) |
|
.attr("height", sheight); |
|
|
|
var g = svg.append("g"); |
|
|
|
data = data.map(function(d) { |
|
d[opts.field] = (d[opts.field] !== undefined && isNaN(+d[opts.field])) ? null : +d[opts.field]; |
|
return d; |
|
}); |
|
var datadomain = d3.extent(data.map(function(x) { return x[opts.field]; })), |
|
colors = d3.scale.quantize() |
|
.domain(opts.inverse ? [datadomain[1], datadomain[0]] : datadomain) |
|
.range(colorbrewer[opts.colorscale][9]); |
|
|
|
console.log(datadomain); |
|
var x = d3.scale.linear() |
|
.domain(datadomain) |
|
.range([0, scalewidth]); |
|
|
|
var tf = ",.0f", |
|
tsign = "", |
|
drange = datadomain[1] - datadomain[0], |
|
num_format; |
|
if (datadomain[0] < 0) { |
|
tsign = "+"; |
|
} |
|
if (drange <= 2.0) { |
|
tf = ",.2f"; |
|
} else if (drange < 10.0) { |
|
tf = ",.1f"; |
|
} |
|
num_format = d3.format(tsign + tf); |
|
|
|
var xAxis = d3.svg.axis() |
|
.orient("bottom") |
|
.scale(x) |
|
.tickSize(13) |
|
.tickFormat(num_format); |
|
|
|
var xbar = svg.append("g") |
|
.attr("transform", "translate(" + (width / 2 - scalewidth / 2) + "," + (sheight - 30) + ")") |
|
.attr("class", "key"); |
|
|
|
xbar.selectAll("rect") |
|
.data(d3.pairs(x.ticks(10))) |
|
.enter().append("rect") |
|
.attr("height", 8) |
|
.attr("x", function(d) { return x(d[0]); }) |
|
.attr("width", function(d) { return x(d[1]) - x(d[0]); }) |
|
.style("fill", function(d) { return colors(d[0]); }); |
|
|
|
xbar.call(xAxis).append("text") |
|
.attr("class", "caption") |
|
.attr("y", -6) |
|
.attr("x", x(x.ticks(10)[0])) |
|
.text(opts.title); |
|
|
|
queue() |
|
.defer(d3.json, "india_pc_2014_simplified.topojson") |
|
.defer(d3.json, "india_state_2014_simplified.topojson") |
|
.await(ready); |
|
|
|
function ready(error, pc, state) { |
|
|
|
//Drawing pc boundaries |
|
var constituencies = topojson.feature(pc, pc.objects.india_pc_2014).features; |
|
|
|
constituencies = constituencies.map(function(c) { |
|
var pc = (c.properties && c.properties["ST_NAME"]) ? c.properties["ST_NAME"] + c.properties["PC_CODE"] : null; |
|
if (!pc) { |
|
return c; |
|
} |
|
c.properties["_data"] = data.filter(function(x) { |
|
return ((x && x[opts.keyfield]) ? x[opts.keyfield] : null) === pc; |
|
})[0]; |
|
return c; |
|
}); |
|
g.selectAll(".pc") |
|
.data(constituencies) |
|
.enter().append("path") |
|
.attr("class", "pc") |
|
.attr("d", path) |
|
.style ( "fill" , function (d) { |
|
return (d.properties["_data"] && d.properties["_data"][opts.field] !== null) ? colors(d.properties["_data"][opts.field]) : '#888'; |
|
}) |
|
.style("opacity", 0.8) |
|
.on("mouseover", function(d) { |
|
d3.select(this).transition().duration(300).style("opacity", 1); |
|
|
|
popupdiv.transition().duration(300) |
|
.style("opacity", 1); |
|
|
|
var str = d.properties.PC_NAME + " : " |
|
if (d.properties._data && d.properties._data[opts.field] !== undefined) { |
|
var val = d.properties._data[opts.field]; |
|
str += isNaN(+val) ? val : num_format(+val); |
|
} |
|
popupdiv.text(str) |
|
.style("left", (d3.event.pageX) + "px") |
|
.style("top", (d3.event.pageY -30) + "px"); |
|
}) |
|
.on("mouseout", function() { |
|
d3.select(this) |
|
.transition().duration(300) |
|
.style("opacity", 0.8); |
|
popupdiv.transition().duration(300) |
|
.style("opacity", 0); |
|
}) |
|
; |
|
//Drawing state boundaries |
|
var state_geojson = topojson.feature(state, state.objects.india_state_2014); |
|
g.selectAll(".state") |
|
.data(state_geojson.features) |
|
.enter().append("path") |
|
.attr("class", "state") |
|
.attr("d", path); |
|
|
|
var zoom = d3.behavior.zoom() |
|
.on("zoom",function() { |
|
g.attr("transform","translate("+ |
|
d3.event.translate.join(",")+")scale("+d3.event.scale+")"); |
|
}); |
|
svg.call(zoom); |
|
} |
|
if (window.parent !== window) { |
|
var myheight = document.documentElement.scrollHeight || document.body.scrollHeight; |
|
window.parent.postMessage({height: myheight}, '*'); |
|
} |
|
} |
|
|
|
</script> |
|
</body> |
|
</html> |