Skip to content

Instantly share code, notes, and snippets.

@Saigesp Saigesp/.block
Last active Oct 19, 2018

Embed
What would you like to do?
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
You can’t perform that action at this time.