Skip to content

Instantly share code, notes, and snippets.

@Saigesp
Last active October 19, 2018 18:11
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 Saigesp/ab01821e77d2f1c44e9d71c826e54db6 to your computer and use it in GitHub Desktop.
Save Saigesp/ab01821e77d2f1c44e9d71c826e54db6 to your computer and use it in GitHub Desktop.
D3v4 piechart with js classes
ab01821e77d2f1c44e9d71c826e54db6

Pie chart

D3 implementation of piechart

See the demo and more charts from d3graphs repository

Features:

  • Object oriented approach
  • Responsive

Requires:

  • D3 v4+

Default options:

{
    'margin': {'top': 50, 'right': 30, 'bottom': 50, 'left': 30},
    'key': 'key',
    'label': 'label',
    'colors': ['#1f77b4','#ff7f0e','#2ca02c','#d62728','#9467bd','#8c564b','#e377c2','#7f7f7f','#bcbd22','#17becf'],
    'radius': false,
    'innerradius': 0,
}
class PieChart{
constructor(selection, data, config = {}) {
let self = this;
this.selection = selection;
this.data = data;
// Graph configuration
this.cfg = {
'margin': {'top': 50, 'right': 30, 'bottom': 50, 'left': 30},
'key': 'key',
'label': 'label',
'colors': ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf'],
'radius': false,
'innerradius': 0,
};
Object.keys(config).forEach(function(key) {
if(config[key] instanceof Object && config[key] instanceof Array === false){
Object.keys(config[key]).forEach(function(sk) {
self.cfg[key][sk] = config[key][sk];
});
} else self.cfg[key] = config[key];
});
this.cfg.width = parseInt(this.selection.node().offsetWidth) - this.cfg.margin.left - this.cfg.margin.right,
this.cfg.height = parseInt(this.selection.node().offsetHeight)- this.cfg.margin.top - this.cfg.margin.bottom;
this.cfg.radius = this.cfg.radius ? this.cfg.radius : Math.min(this.cfg.width, this.cfg.height) / 2;
this.cScale = d3.scaleOrdinal().range(this.cfg.colors);
this.arc = d3.arc().outerRadius(this.cfg.radius).innerRadius(this.cfg.innerradius);
this.outerArc = d3.arc().outerRadius(this.cfg.radius*1.1).innerRadius(this.cfg.radius*1.1);
this.pie = d3.pie().sort(null).value(function(d) { return d[self.cfg.key]; });
this.initGraph();
}
initGraph() {
let self = this;
this.svg = this.selection.append('svg')
.attr("class", "chart barchart")
.attr("viewBox", "0 0 "+(this.cfg.width + this.cfg.margin.left + this.cfg.margin.right)+" "+(this.cfg.height + this.cfg.margin.top + this.cfg.margin.bottom))
.attr("width", this.cfg.width + this.cfg.margin.left + this.cfg.margin.right)
.attr("height", this.cfg.height + this.cfg.margin.top + this.cfg.margin.bottom);
this.g = this.svg.append("g")
.attr("transform", "translate(" + (self.cfg.margin.left) + "," + (self.cfg.margin.top) + ")");
this.itemg = this.g.selectAll('.itemg')
.data(this.pie(self.data))
.enter().append('g')
.attr("transform", "translate(" + (self.cfg.width/2) + "," + (self.cfg.height/2) + ")")
.attr("class", "itemg")
// PATHS
this.itemg.append("path")
.attr("d", this.arc)
.style("fill", function(d) { return self.cScale(d.data[self.cfg.key]); });
// LABELS
this.itemg.append('text')
.attr("class", "label")
.attr("transform", function(d){
var pos = self.outerArc.centroid(d);
pos[0] = self.cfg.radius * (self.midAngle(d) < Math.PI ? 1.1 : -1.1);
return "translate("+pos+")";
})
.attr('text-anchor', function(d){
return self.midAngle(d) < Math.PI ? 'start' : 'end';
})
.text(function(d){
return d.data[self.cfg.label];
})
// LINES
this.itemg.append('polyline')
.attr("class", "line line-label")
.attr('points', function(d){
var pos = self.outerArc.centroid(d);
pos[0] = self.cfg.radius * 0.95 * (self.midAngle(d) < Math.PI ? 1.1 : -1.1);
return [self.arc.centroid(d), self.outerArc.centroid(d), pos]
})
}
midAngle(d){
return d.startAngle + (d.endAngle - d.startAngle)/2;
}
}
name income outcome
Peter 30 10
Jack 100 20
Andrew 123 57
Santi 80 24
John 24 86
Jesus 164 87
<html>
<head>
<meta charset="utf-8">
</head>
<style>
.label {
font-family: sans-serif;
font-size: 12px;
}
.chart .line {
fill: transparent;
stroke: black;
opacity: 0.6;
}
</style>
<body>
<div id="container" style="width: 960px; height: 440px;"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<script src="d3.piechart.js"></script>
<script>
d3.csv('data.csv', function(data) {
var chart = new PieChart(d3.select('#container'), data, {
'key': 'income',
'label': 'name',
'radius': 140,
'innerradius': 120,
})
})
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment