Commit df39200c authored by Sascha Herzinger's avatar Sascha Herzinger
Browse files

nested piechart

parent bb5ee995
......@@ -28,7 +28,7 @@
piechart.toSVG();
}
function randomPieces() {
function generateCircle() {
const num = Math.floor(Math.random() * (15 - 4 + 1) + 4);
const pieces = [];
for (let i = 0; i < num; i++) {
......@@ -40,11 +40,20 @@
return pieces;
}
function generateValues() {
const num = Math.floor(Math.random() * 5 + 1);
const values = [];
for (let i = 0; i < num; i++) {
values.push(generateCircle());
}
return values;
}
function update() {
piechart.update({
caption: 'Random Piechart',
clickCallback: d => console.log(d),
values: randomPieces()
values: generateValues()
});
}
......
......@@ -4,6 +4,10 @@
.ac-pie-slice {
cursor: pointer;
stroke: #fff;
stroke: #444;
stroke-width: 2px;
}
.ac-pie-slice:hover {
opacity: 0.6;
}
\ No newline at end of file
......@@ -27,6 +27,12 @@ export default class extends Chart {
clickCallback,
values,
}) {
const data = values.reduce((acc, d, i) => acc.concat(d.map(e => ({
group: e.group,
circleIdx: i,
value: e.value,
})), []));
const margin = {
top: this.containerWidth / 20,
right: this.containerWidth / 20,
......@@ -37,16 +43,12 @@ export default class extends Chart {
const width = this.containerWidth - margin.left - margin.right;
const height = this.containerWidth - margin.top - margin.bottom;
const groups = [...new Set(data.map(d => d.group))];
const color = d3.scaleOrdinal()
.domain(values.map(d => d.group))
.domain(groups)
.range(d3.schemeSet3);
const data = d3.pie()
.value(d => d.value)
.sort((a, b) => d3.ascending(a.value, b.value))(values);
const radius = Math.min(width / 2, height / 2);
d3.select(this.container).select('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom);
......@@ -57,18 +59,31 @@ export default class extends Chart {
.attr('transform', `translate(${width / 2}, ${-margin.top / 2})`)
.text(caption);
const slice = this.svg.selectAll('.ac-pie-slice')
.data(data);
const circleDepth = values.length;
const maxRadius = Math.min(width / 2, height / 2);
for (let circleIdx = 0; circleIdx < circleDepth; circleIdx += 1) {
const circleData = data.filter(d => d.circleIdx === circleIdx);
const circleThickness = maxRadius / circleDepth;
const outerRadius = maxRadius - circleIdx * circleThickness;
const innerRadius = outerRadius - circleThickness;
const pie = d3.pie()
.value(d => d.value)
.sort((a, b) => d3.ascending(a.value, b.value))(circleData);
const slice = this.svg.selectAll(`.ac-pie-slice .circle-idx-${circleIdx}`)
.data(pie);
slice.enter()
.append('path')
.attr('class', 'ac-pie-slice')
.attr('transform', `translate(${width / 2}, ${height / 2})`)
.attr('d', d3.arc().innerRadius(0).outerRadius(radius))
.attr('fill', d => color(d.value))
.on('click', clickCallback);
slice.enter()
.append('path')
.attr('class', `ac-pie-slice circle-idx-${circleIdx}`)
.attr('transform', `translate(${width / 2}, ${height / 2})`)
.attr('d', d3.arc().innerRadius(innerRadius).outerRadius(outerRadius))
.attr('fill', d => color(d.data.group))
.on('click', d => clickCallback(d.data));
slice.exit()
.remove();
slice.exit()
.remove();
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment