JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://d3js.org/d3.v3.min.js"></script>
<button id="doSomething">Do Something</button>
<div class="chart cluster-chart" id="clusters"></div>
CSS
.total-cluster circle {fill: orange;}
.total-cluster text {
fill: #FFF;
text-anchor: middle;
}
.cluster circle {
fill: blue;
stroke-width: 5px;
stroke: #FFF;
}
.cluster.empty circle {
fill: CCC;
}
.cluster.empty circle:hover {
stroke: #FFF;
cursor: default;
}
.cluster circle:hover {
cursor: pointer;
stroke: dark-blue;
}
.cluster text {
fill: #FFF;
text-anchor: middle;
pointer-events: none;
}
.value {
font-size: 2em;
font-weight: bold;
}
.group-name {
font-size: 0.7em;
text-transform: uppercase;
}
JavaScript
$(function() {
d3.select('#clusters')
.datum({
Name: 'Total Widgets',
Value: 224,
Clusters: [
['Other', 45],
['FooBars', 30],
['Foos', 50],
['Bars', 124],
['BarFoos', 0]
]
})
.call( clusterChart() );
$("#doSomething").on("click", function(){
//update the data
});
});
function clusterChart() {
var width = 500,
radiusAll = 90,
maxRadius = radiusAll - 5,
padding = 8,
height = 3 * (radiusAll*2 + padding),
startAngle = Math.PI / 2,
val = function(d) { return d; },
onTotalMouseOver = null,
onTotalClick = null,
onClusterMouseOver = null,
onClusterClick = null;
function chart(selection) {
selection.each(function(data) {
var cx = width / 2,
cy = height / 2,
stepAngle = 2 * Math.PI / data.Clusters.length,
outerRadius = 2*radiusAll + padding;
// Remove svg, if already exist
d3.select(this).select('svg').remove();
//cluster radius range and scale
var r = d3.scale.linear()
.domain([0, d3.max(data.Clusters, function(d){return d[1];})])
.range([50, maxRadius]);
// Add svg element
var svg = d3.select(this).append('svg')
.attr('class', 'cluster-chart')
.attr("viewBox", "0 0 " + width + " " + height )
.attr("preserveAspectRatio", "xMidYMin meet")
.attr('width', width)
.attr('height', height);
// Total group value
var totalCluster = svg.append('g')
.attr('class', 'total-cluster');
totalCluster.append('circle')
.attr('cx', cx)
.attr('cy', cy)
.attr('r', radiusAll)
...