Skip to content

Instantly share code, notes, and snippets.

@canvaspixels
Created October 1, 2018 10:08
Show Gist options
  • Save canvaspixels/8af224061b43682f3d445710967afb06 to your computer and use it in GitHub Desktop.
Save canvaspixels/8af224061b43682f3d445710967afb06 to your computer and use it in GitHub Desktop.
D3 pie
.pie {
position: relative;
svg {
width: 100%;
.arc-path-0 {
fill: $color-matisse !important;
}
.arc-path-1 {
fill: $color-light2 !important;
}
}
}
import React from 'react';
import * as d3 from 'd3';
import './PieChart.scss';
export default class PieChart extends React.Component {
componentDidMount() {
const ops = {
el: this.containerRef,
data: this.props.data,
};
if (this.props.thickness) {
ops.thickness = this.props.thickness;
}
this.makePieChart(ops);
}
setRef = (ref) => this.containerRef = ref;
makePieChart (ops) {
const hole = 10;
function processThickness(val, iteration){ // Grabs the thickness, chekcs if array or not and return correct value
if(Array.isArray(val)){
return val[iteration];
} else {
return val;
}
};
const settings = Object.assign({
colour: ['#544', 'CCC'],
data: [45, 55],
dimension: 100,
// animate: true,
thickness: 0.1,
width: 200,
height: 200
}, ops);
if (typeof settings.data === 'number') {
settings.data = [settings.data, 100 - settings.data];
}
const firstTime = this.paper === undefined;
this.paper = this.paper || d3.select(settings.el)
.append('svg')
.attr('viewBox','34 34 32 32')
.attr('preserveAspectRatio', 'xMidYMin');
function sectorRadius(thickness){
let ir;
let or;
const scale = d3.scaleLinear()
.range([hole + 2, settings.dimension / 2]) // (hole + value) sets the minimum value of the radius, even when the thickness is zero
.domain([0, 1]);
if (thickness >= 0){
or = scale(thickness);
ir = hole;
} else {
or = settings.dimension / 2;
ir = (settings.dimension / 2) + (settings.dimension / 2 * thickness);
}
return [ir, or];
};
const arc = d3.arc();
const pie = d3.pie()
.sort(null)
.value(function(d) {
return d.value;
});
const dataForGraph = [];
settings.data.forEach((value, index) => {
const current = dataForGraph.push({
value: value,
// previous: 0,
colour: settings.colour[index],
thickness: processThickness(settings.thickness, index)
});
if (Array.isArray(settings.cb)){
dataForGraph[current-1].cb = settings.cb[current-1];
}
});
// if (firstTime){
this.paper.selectAll('.arc')
.data(pie(dataForGraph))
.enter()
.append('g')
.attr('class', 'arc')
.append('path')
.attr('transform', 'translate(' + settings.dimension / 2 + ', ' + settings.dimension / 2 + ')')
.attr('class', function(d, i){
return 'arc-path-'+i;
})
.style('fill', function(d){
return d.data.colour;
})
.each(function(d) {
this._current = d;
});
// This one sets the arc
this.paper.selectAll('path').transition()
.duration(400)
.attrTween('d', function(a){
const i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
const radius = sectorRadius(i(t).data.thickness);
return arc.innerRadius(radius[0])
.outerRadius(radius[1])(i(t));
};
});
// } else {
// var duration = 0,
// path = this.paper.selectAll('path')
// .data(pie(dataForGraph))
// .style('fill', function(d){
// return d.data.colour;
// });
// if(settings.noDataColour){
// path.style('fill', function(d){ return d.data.colour; });
// }
// // HAX! We're using time = 0 to update the graphs
// if (settings.animate){
// duration = 500;
// }
// path.transition()
// .duration(duration)
// .attrTween('d', function(a){
// var i = d3.interpolate(this._current, a);
// this._current = i(0);
// return function(t) {
// // i(t) is the data object tweened, sweet!
// var radius = sectorRadius(i(t).data.thickness);
// return arc.innerRadius(radius[0])
// .outerRadius(radius[1])(i(t));
// };
// });
// }
}
render() {
const { children } = this.props;
return (
<div className="pie">
<div className="pie__inner" ref={this.setRef}>
</div>
<div className="pie__children">
{ children }
</div>
</div>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment