Skip to content

Instantly share code, notes, and snippets.

@me1er
Last active January 16, 2020 09:32
Show Gist options
  • Save me1er/efc7fae86b071b0fd0cc8c5ed51c2088 to your computer and use it in GitHub Desktop.
Save me1er/efc7fae86b071b0fd0cc8c5ed51c2088 to your computer and use it in GitHub Desktop.
Quality Profile
license: mit
height: 300
scrolling: no
border: no

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.

forked from bbest's block: Aster Plot in D3

forked from anonymous's block: Quality Profile

forked from me1er's block: Quality Profile

order score weight color label
1.1 3.0 0.15 #00A859 Macro location
1.3 1.0 0.15 #34A87F Micro location
2 4.5 0.2 #008DD2 Usetype
3 3.5 0.2 #35A5D9 Standard
4 2.5 0.1 #74BEE0 Condition
5 5.0 0.05 #EA4424 Lettability
6 3.5 0.15 #ED6E52 Sellability
var MAX_RADIUS = 4.5;
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 - 0.5) / MAX_RADIUS) + 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;
});
var path = svg.selectAll(".solidArc")
.data(pie(data))
.enter().append("path")
.attr("fill", function(d) { return d.data.color; })
.attr("class", "solidArc")
.attr("stroke", "#000000")
.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", "#000000")
.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);
var formatDecimal = d3.format(".1f")
svg.append("svg:text")
.attr("class", "aster-score")
.attr("dy", ".35em")
.attr("text-anchor", "middle") // text-align: right
.text(formatDecimal(score));
for (var i = 0; i < 10; i++) {
var aradius = (radius - innerRadius) * (i / 2 / MAX_RADIUS) + innerRadius;
var outerPath = svg.selectAll(".outlineArc" + i)
.data(pie(data))
.enter().append("path")
.attr("fill", "none")
.attr("stroke", "#000000")
.attr("class", "outlineArc")
.attr("d", d3.svg.arc()
.innerRadius(aradius)
.outerRadius(aradius));
}
svg.selectAll("text")
.data(d3.range(1,9).reverse())
.enter().append("text")
.attr("x", 4)
.attr("y", function(d){return (radius - innerRadius) * (-(d-0.5 + 0.5) / MAX_RADIUS) - innerRadius;})
.attr("dy", "2em")
.style("font-size", "18px")
.style("font-weight", "bold")
.attr("fill", "#000")
.text(function (d) { return d3.format("f")(d); });
});
<!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