This is my first attempt at a cartogram of any type. This is highly inaccurate, but I'm simply trying to combine a choropleth map (colored by food insecurity rate) and a cartogram (sized by obesity rate). It's worth as a visualization is dubious at best, but it still might work at a later point.
xxxxxxxxxx
<meta charset="utf-8">
<style>
svg {
font: 15px sans-serif;
}
.caption {
font-weight: bold;
}
.key path {
display: none;
}
.key line {
stroke: #000;
shape-rendering: crispEdges;
}
.county-border {
fill: none;
stroke: black;
}
.state-border {
fill: none;
stroke: black;
}
</style>
<title>Oklahoma Food Map</title>
<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://d3js.org/topojson.v1.min.js"></script>
<script>
var width = 1200, height = 700;
var format = d3.format(",")
var formatpercent = d3.format("%")
var color = d3.scale.threshold().domain([.1, .13, .16, .19, .22]).range(["#BFD3E6", '#9EBCDA', '#8C96C6', "#8C6BB1", "#88419D", "#6E016B"]);
// A position encoding for the key only.
var x = d3.scale.linear().domain([.1, .22]).range([0, 300]);
var xAxis = d3.svg.axis().scale(x).orient("bottom").tickSize(17).tickValues(color.domain()).tickFormat(formatpercent);
var projection = d3.geo.conicConformal().parallels([35 + 34 / 60, 36 + 46 / 60]).rotate([98 + 00 / 60, -35 - 00 / 60]).scale(7220).translate([width / 2, height / 2]);
var path = d3.geo.path().projection(projection);
var div = d3.select("body").append("div").attr("class", "tooltip").style("opacity", 0);
var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
var g = svg.append("g").attr("class", "key").attr("transform", "translate(20,350)");
g.selectAll("rect").data(color.range().map(function(d, i) {
return {
x0 : i ? x(color.domain()[i - 1]) : x.range()[0],
x1 : i < color.domain().length ? x(color.domain()[i]) : x.range()[1],
z : d
};
})).enter().append("rect").attr("height", 12).attr("x", function(d) {
return d.x0;
}).attr("width", function(d) {
return d.x1 - d.x0;
}).style("fill", function(d) {
return d.z;
});
g.call(xAxis).append("text").attr("class", "caption").attr("y", -6).text("Food insecurity rate");
d3.json("ok-countiesfood.json", function(error, ok) {
var counties = topojson.feature(ok, ok.objects.counties);
//counties
svg.append("g").attr("class", "county").selectAll("path").data(counties.features).enter().append("path").attr("d", path).style("fill", function(d) {
return color(d.properties.firate);
}).attr("transform", function(d) {
var centroid = path.centroid(d), x = centroid[0], y = centroid[1];
return "translate(" + x + "," + y + ")" + "scale(" + Math.sqrt((d.properties.percentobese) * 0.025 || 0) + ")" + "translate(" + -x + "," + -y + ")";
}).style("stroke-width", function(d) {
return 1 / Math.sqrt((d.properties.percentobese) * 0.025 || 1);
});
//county borders
svg.append("path").datum(topojson.mesh(ok, ok.objects.counties, function(a, b) {
return a !== b;
})).attr("class", "county-border").attr("d", path);
//state borders
svg.append("path").datum(topojson.mesh(ok, ok.objects.counties, function(a, b) {
return a === b;
})).attr("class", "state-border").attr("d", path);
});
d3.select(self.frameElement).style("height", height + "px");
</script>
Modified http://d3js.org/d3.v3.min.js to a secure url
Modified http://d3js.org/topojson.v1.min.js to a secure url
https://d3js.org/d3.v3.min.js
https://d3js.org/topojson.v1.min.js