Shows the car exchanges in the Cash for Clunkers program aggregated by automaker nationality.
Click here to see how I transformed the data.
Source of data
[{"name":"Germany","color":0},{"name":"Japan","color":1},{"name":"South Korea","color":2},{"name":"Sweden","color":3},{"name":"United Kingdom","color":4},{"name":"United States","color":5},{"name":"Germany","color":6},{"name":"Japan","color":7},{"name":"South Korea","color":8},{"name":"Sweden","color":9},{"name":"United Kingdom","color":10},{"name":"United States","color":11}] |
<html> | |
<head> | |
<title>Cash for Clunkers Chord</title> | |
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<script src="//d3js.org/queue.v1.min.js"></script> | |
<link rel="stylesheet" type="text/css" href="style.css"> | |
</head> | |
<body></body> | |
</html> | |
<script type="text/javascript"> | |
var c = function colores_google(n) { | |
"use strict"; | |
var colores_g = ["#3366cc", "#dc3912", "#ff9900", "#109618", "#990099", "#0099c6", "#dd4477", "#66aa00", "#b82e2e", "#316395", "#994499", "#22aa99", "#aaaa11", "#6633cc", "#e67300", "#8b0707", "#651067", "#329262", "#5574a6", "#3b3eac"]; | |
return colores_g[n % colores_g.length]; | |
}; | |
// graph parameters | |
var width = 960, | |
height = 500, | |
outerRadius = Math.min(width, height) - 320, | |
innerRadius = outerRadius - 22; | |
// data maps | |
var indexByName = d3.map(), | |
nameByIndex = d3.map(), | |
matrix = [], | |
n = 0; | |
// set up svg & chord diagram | |
var arc = d3.svg.arc() | |
.innerRadius(innerRadius) | |
.outerRadius(outerRadius); | |
var layout = d3.layout.chord() | |
.padding(0.04) | |
.sortSubgroups(d3.descending) | |
.sortChords(d3.ascending); | |
var path = d3.svg.chord() | |
.radius(innerRadius); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height) | |
.append("g") | |
.attr("id", "circle") | |
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); | |
svg.append("circle") | |
.attr("r", outerRadius); | |
d3.json("countries.json", function (cities) { | |
d3.json("matrix.json", function (matrix) { | |
// Compute the chord layout. | |
layout.matrix(matrix); | |
cities.forEach(function (d) { | |
if (!indexByName.has(d = d.name)) { | |
nameByIndex.set(n, d); | |
indexByName.set(d, n++); | |
} else { | |
nameByIndex.set(indexByName.get(d) + cities.length / 2, d); | |
} | |
}); | |
console.log(nameByIndex) | |
// Add a group per neighborhood. | |
var group = svg.selectAll(".group") | |
.data(layout.groups) | |
.enter().append("g") | |
.attr("class", "group") | |
.on("mouseover", mouseover); | |
group.append("text") | |
.each(function (d) { d.angle = (d.startAngle + d.endAngle) / 2; }) | |
.attr("dy", ".35em") | |
.attr("transform", function (d) { | |
return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")" | |
+ "translate(" + (innerRadius + 40) + ")" | |
+ (d.angle > Math.PI ? "rotate(180)" : ""); | |
}) | |
.style("text-anchor", function (d) { return d.angle > Math.PI ? "end" : null; }) | |
.text(function (d) { return nameByIndex.get(d.index); }); | |
// Add the group arc. | |
var groupPath = group.append("path") | |
.attr("id", function (d, i) { return "group" + i; }) | |
.attr("d", arc) | |
.style("fill", function (d, i) { return d.index < cities.length / 2 ? '#444444' : c(+cities[i].color); }); | |
// Add the chords. | |
var chord = svg.selectAll(".chord") | |
.data(layout.chords) | |
.enter().append("path") | |
.attr("class", "chord") | |
.style("fill", function (d) { return c(+cities[d.target.index].color); }) | |
.attr("d", path); | |
// Add legend | |
var legendRectSize = 12, | |
legendSpacing = 1; | |
var legend = svg.selectAll('.legend') | |
.data(cities.slice(cities.length/2, cities.length)) | |
.enter() | |
.append('g') | |
.attr('class', 'legend') | |
.attr('transform', function (d, i) { | |
var height = legendRectSize, | |
horz = -i * legendRectSize + 300, | |
vert = height - 200; | |
return 'translate(' + horz + ',' + vert + ')'; | |
}); | |
legend.append('rect') | |
.attr('width', legendRectSize) | |
.attr('height', legendRectSize) | |
.style('fill', function (d) { return d.index < cities.length / 2 ? '#444444' : c(+d.color); }) | |
.style('stroke', function (d) { return d.index < cities.length / 2 ? '#444444' : c(+d.color); }) | |
.style('opacity', 0.7); | |
legend.data(['clunkers', 'new vehicles']).append('text') | |
.attr('x', function (d, i) { return legendRectSize + 20 + 10 * i; }) | |
.attr('y', function (d, i) {return 2 * i * legendRectSize + legendRectSize - 3; }) | |
.text(function (d) {return d; }) | |
.style('text-align', 'right'); | |
legend.data(cities.slice(cities.length / 2, cities.length)).append('rect') | |
.attr('width', legendRectSize) | |
.attr('height', legendRectSize) | |
.attr('transform', function () { | |
var horz = 0, | |
vert = 23; | |
return 'translate(' + horz + ',' + vert + ')'; | |
}) | |
.style('fill', '#444444') | |
.style('stroke', '#444444') | |
.style('opacity', 0.9) | |
.attr('class', 'test'); | |
function mouseover(d, i) { | |
chord.classed("fade", function (p) { | |
return p.source.index !== i && p.target.index !== i; | |
}); | |
} | |
}); | |
}); | |
</script> | |
[[0, 0, 0, 0, 0, 0, 907, 2261, 52, 183, 243, 10973], [0, 0, 0, 0, 0, 0, 6803, 58633, 1739, 1861, 1780, 248344], [0, 0, 0, 0, 0, 0, 1107, 8498, 1170, 302, 350, 66324], [0, 0, 0, 0, 0, 0, 43, 130, 4, 42, 44, 752], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1424, 10880, 740, 370, 626, 241050], [907, 6803, 1107, 43, 0, 1424, 0, 0, 0, 0, 0, 0], [2261, 58633, 8498, 130, 0, 10880, 0, 0, 0, 0, 0, 0], [52, 1739, 1170, 4, 0, 740, 0, 0, 0, 0, 0, 0], [183, 1861, 302, 42, 0, 370, 0, 0, 0, 0, 0, 0], [243, 1780, 350, 44, 0, 626, 0, 0, 0, 0, 0, 0], [10973, 248344, 66324, 752, 0, 241050, 0, 0, 0, 0, 0, 0]] |
body { | |
background: #fcfcfa; | |
color: #333; | |
font-family: "PT Serif", serif; | |
position: relative; | |
width: 960px; | |
} | |
svg { | |
font: 10px sans-serif; | |
} | |
.axis path, .axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
#circle circle { | |
fill: none; | |
pointer-events: all; | |
} | |
.group path { | |
fill-opacity: 1; | |
} | |
path.chord { | |
stroke-width: .25px; | |
fill-opacity: 0.5; | |
} | |
#circle:hover path.fade { | |
display: none; | |
} | |