This code generates a tiered pie chart visualization using D3.js to represent hierarchical data, allowing for a clear visual representation of data structure and proportions.
npm run import -- "d3 tiered pie chart"
// source: https://github.com/rangle/augury/blob/dev/src/frontend/components/router-tree/router-tree.ts
var D3Node = require('d3-node');
var margin = {top: 25, right: 150, bottom: 25, left: 150},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
function d3TieredPieSVG(nodes) {
var d3n = new D3Node(); // initializes D3 with container element
var d3 = d3n.d3;
var fill = d3.scaleOrdinal(d3.schemeCategory20);
var svg = d3n.createSVG(
width + margin.left + margin.right,
height + margin.top + margin.bottom)
var g = svg.append('g');
// display sunburst with lines between
var radius = Math.min(width, height) / 4
var x = d3.scaleLinear().range([0, 2 * Math.PI]);
var y = d3.scaleLinear().range([0, radius]);
var partition = d3.partition()
var tree = d3.hierarchy(nodes[0], d => d.children);
var root = // partition(
tree.sum(d => 1)
.sort((a, b) => b.size - a.size || b.value - a.value)
//)
.descendants();
root.forEach(r => {
r.name = r.data.name;
r.index = r.data.index;
r.branch = r.data.branch;
})
var tree = d3.hierarchy(root[0], d => d.depth < 3 ? d.children : []);
var root = partition(tree.sum(d => 1)).descendants();
var arc = d3.arc()
.startAngle(function (d) {
return Math.max(0, Math.min(2 * Math.PI, x(d.x0)));
})
.endAngle(function (d) {
return Math.max(0, Math.min(2 * Math.PI, x(d.x1)));
})
.innerRadius(function (d) {
return Math.max(0, d.depth == 0
? 0 : (d.depth == 1 ? y(1 / 3) : y(d.depth)));
})
.outerRadius(function (d) {
return Math.max(0, d.depth == 0
? 0 : y(d.depth + 1));
});
// Interpolate the arcs in data space.
function arcTween(a) {
var i = d3.interpolate({x: a.x0, dx: a.dx0}, a);
return function (t) {
var b = i(t);
a.x0 = b.x;
a.dx0 = b.dx;
return arc(b);
};
}
var path = g.selectAll('path')
.data(root)
.enter().append('path')
// .attr("display", function(d) { return d.depth ? null : "none"; }) // hide inner ring
.attr('d', arc)
.style('stroke', '#fff')
.style('fill', function (d, i) {
return fill(i);
})
.style('fill-rule', 'evenodd')
function computeTextRotation(d) {
return (x((d.x0 + d.x1) / 2) - Math.PI / 2) / Math.PI * 180;
}
g.selectAll('text')
.data(root.filter(d => d.depth == 1))
.enter().append('text')
.attr('transform', function (d) {
return 'rotate(' + computeTextRotation(d) + ')';
})
.attr('x', d => y(d.depth + 1))
.attr('dx', '-6') // margin
.attr('dy', '.35em') // vertical-align
.attr('text-anchor', (d) => 'end')
.text(d => (d.data).name)
.attr('class', 'monospace');
/*
path
.data(partition.value(d => d.data.size).nodes)
.attrTween("d", arcTween);
*/
// reset transform
g.attr('transform', 'translate(0, 0)');
g.attr(
'transform',
'translate(' + (margin.left + width / 2) + ',' + (margin.top + height / 2) + ')')
return Promise.resolve(d3n.svgString());
};
module.exports = d3TieredPieSVG;
// Import required libraries
const D3Node = require('d3-node');
// Constants
const margin = { top: 25, right: 150, bottom: 25, left: 150 };
const width = 960 - margin.left - margin.right;
const height = 500 - margin.top - margin.bottom;
/**
* Creates a tiered pie chart using D3.js
* @param {Object[]} nodes - Input data for the chart
* @returns {Promise<string>} SVG string representation of the chart
*/
function d3TieredPieSVG(nodes) {
// Initialize D3-node
const d3n = new D3Node();
const d3 = d3n.d3;
// Color scale
const fill = d3.scaleOrdinal(d3.schemeCategory20);
// SVG creation
const svg = d3n.createSVG(width + margin.left + margin.right, height + margin.top + margin.bottom);
const g = svg.append('g');
// Radius calculation
const radius = Math.min(width, height) / 4;
// Scales
const x = d3.scaleLinear().range([0, 2 * Math.PI]);
const y = d3.scaleLinear().range([0, radius]);
// Partition calculation
const partition = d3.partition();
const tree = d3.hierarchy(nodes[0], d => d.children);
const root = tree.sum(d => 1).sort((a, b) => b.size - a.size || b.value - a.value).descendants();
// Assign properties to nodes
root.forEach(r => {
r.name = r.data.name;
r.index = r.data.index;
r.branch = r.data.branch;
});
// Partition calculation
const treeData = d3.hierarchy(root[0], d => d.depth < 3? d.children : []);
const rootData = partition(treeData.sum(d => 1)).descendants();
// Arc calculation
const arc = d3.arc()
.startAngle(function (d) {
return Math.max(0, Math.min(2 * Math.PI, x(d.x0)));
})
.endAngle(function (d) {
return Math.max(0, Math.min(2 * Math.PI, x(d.x1)));
})
.innerRadius(function (d) {
return Math.max(0, d.depth == 0? 0 : (d.depth == 1? y(1 / 3) : y(d.depth)));
})
.outerRadius(function (d) {
return Math.max(0, d.depth == 0? 0 : y(d.depth + 1));
});
// Arc tweening
function arcTween(a) {
const i = d3.interpolate({ x: a.x0, dx: a.dx0 }, a);
return function (t) {
const b = i(t);
a.x0 = b.x;
a.dx0 = b.dx;
return arc(b);
};
}
// Path creation
const path = g.selectAll('path')
.data(rootData)
.enter().append('path')
.attr('d', arc)
.style('stroke', '#fff')
.style('fill', function (d, i) {
return fill(i);
})
.style('fill-rule', 'evenodd');
// Text creation
function computeTextRotation(d) {
return (x((d.x0 + d.x1) / 2) - Math.PI / 2) / Math.PI * 180;
}
g.selectAll('text')
.data(root.filter(d => d.depth == 1))
.enter().append('text')
.attr('transform', function (d) {
return 'rotate(' + computeTextRotation(d) + ')';
})
.attr('x', d => y(d.depth + 1))
.attr('dx', '-6') // margin
.attr('dy', '.35em') // vertical-align
.attr('text-anchor', (d) => 'end')
.text(d => (d.data).name)
.attr('class','monospace');
// Transform calculation
g.attr('transform', 'translate(' + (margin.left + width / 2) + ',' + (margin.top + height / 2) + ')');
// Return the SVG string
return Promise.resolve(d3n.svgString());
}
module.exports = d3TieredPieSVG;
This code generates a tiered pie chart visualization using D3.js.
Here's a breakdown:
Setup:
d3-node
for using D3.js in a Node.js environment.d3TieredPieSVG
Function:
nodes
) as input, representing the data for the pie chart.D3Node
.Data Preparation:
x
) and radii (y
).d3.partition()
to create a hierarchical partition of the data.Visualization:
arc
generator function to create arcs for each slice of the pie chart.d3.arc()
to generate arcs based on the calculated data and scales.arcTween
) to smoothly animate the arcs.Rendering:
In essence, this code takes hierarchical data and visualizes it as a tiered pie chart using D3.js, allowing for a clear representation of the data structure and proportions.