Skip to content

Instantly share code, notes, and snippets.

@nstrayer
Forked from bbest/.block
Last active August 29, 2015 14:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nstrayer/c6576b5b236f7f73cf8b to your computer and use it in GitHub Desktop.
Save nstrayer/c6576b5b236f7f73cf8b to your computer and use it in GitHub Desktop.
Aster Plot in D3

This aster plot displays pie slices as lengths extending outward to the edge (0 at inner to 100 at outer). Widths of the pie slices represent the weight of each pie, which gets used to arrive at a weighted mean of the length scores in the center.

Contributors

Jim Regetz @regetz developed the initial aster plot function in R (see aster-plot on github)

Parker Abercrombie @parkerabercrombie developed the initial D3 prototype varying 3 of the 4 arc elements starting with Mike Bostock's Donut Chart:

  • outerRadius
  • startAngle
  • endAngle

This is the only example pie chart I've encountered on the web (after much searching) which varied individual arc segments by all 3 (usually just startAngle and endAngle with fixed innerRadius and outerRadius, even if done with multiple rows as with the very cool Zoomable Sunburst). The outline of the pie chart is generated in addition to the outerRadius-varying segments. For more details, see the d3 Pie Layout documentation.

Tooltips on hover are rendered via the d3-tip library.

This effort was made possible through the NCEAS Open Science CodeFest Sep 2-4, 2014 in Santa Barbara, CA.

Ben Best @bbest adapted Parker's prototype to CSV data from the Ocean Health Index. For more details on the data prep, see ohi-aster on github.

id order score weight color label
FIS 1.1 59 0.5 #9E0041 Fisheries
MAR 1.3 24 0.5 #C32F4B Mariculture
AO 2 98 1 #E1514B Artisanal Fishing Opportunities
NP 3 60 1 #F47245 Natural Products
CS 4 74 1 #FB9F59 Carbon Storage
CP 5 70 1 #FEC574 Coastal Protection
TR 6 42 1 #FAE38C Tourism & Recreation
LIV 7.1 77 0.5 #EAF195 Livelihoods
ECO 7.3 88 0.5 #C7E89E Economies
ICO 8.1 60 0.5 #9CD6A4 Iconic Species
LSP 8.3 65 0.5 #6CC4A4 Lasting Special Places
CW 9 71 1 #4D9DB4 Clean Waters
HAB 10.1 88 0.5 #4776B4 Habitats
SPP 10.3 83 0.5 #5E4EA1 Species
var width = 500,
height = 500,
radius = Math.min(width, height) / 2,
innerRadius = 0.3 * radius;
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.width; });
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([0, 0])
.html(function(d) {
return d.data.label + ": <span style='color:orangered'>" + d.data.score + "</span>";
});
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(function (d) {
return (radius - innerRadius) * (d.data.score / 100.0) + innerRadius;
});
var outlineArc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(radius);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
svg.call(tip);
d3.csv('aster_data.csv', function(error, data) {
data.forEach(function(d) {
d.id = d.id;
d.order = +d.order;
d.color = d.color;
d.weight = +d.weight;
d.score = +d.score;
d.width = +d.weight;
d.label = d.label;
});
// for (var i = 0; i < data.score; i++) { console.log(data[i].id) }
var path = svg.selectAll(".solidArc")
.data(pie(data))
.enter().append("path")
.attr("fill", function(d) { return d.data.color; })
.attr("class", "solidArc")
.attr("stroke", "gray")
.attr("d", arc)
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
var outerPath = svg.selectAll(".outlineArc")
.data(pie(data))
.enter().append("path")
.attr("fill", "none")
.attr("stroke", "gray")
.attr("class", "outlineArc")
.attr("d", outlineArc);
// calculate the weighted mean score
var score =
data.reduce(function(a, b) {
//console.log('a:' + a + ', b.score: ' + b.score + ', b.weight: ' + b.weight);
return a + (b.score * b.weight);
}, 0) /
data.reduce(function(a, b) {
return a + b.weight;
}, 0);
svg.append("svg:text")
.attr("class", "aster-score")
.attr("dy", ".35em")
.attr("text-anchor", "middle") // text-align: right
.text(Math.round(score));
});
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script src="draw.js" ></script>
</body>
</html>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: orange;
}
.solidArc:hover {
fill: orangered ;
}
.solidArc {
-moz-transition: all 0.3s;
-o-transition: all 0.3s;
-webkit-transition: all 0.3s;
transition: all 0.3s;
}
.x.axis path {
display: none;
}
.aster-score {
line-height: 1;
font-weight: bold;
font-size: 500%;
}
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.8);
color: #fff;
border-radius: 2px;
}
/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
content: "\25BC";
position: absolute;
text-align: center;
}
/* Style northward tooltips differently */
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment