D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
mforando
Full window
Github gist
Radial Sets
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } </style> </head> <body> <script> var dimensions = d3.range(4); var data = [{'categoryA':'A', 'categoryB': 'A','categoryC':'A', 'categoryD': 'C'}, {'categoryA':'A', 'categoryB': 'B','categoryC':'B', 'categoryD': 'C'}, {'categoryA':'A', 'categoryB': 'B','categoryC':'A', 'categoryD': 'C'}, {'categoryA':'A', 'categoryB': 'C','categoryC':'A', 'categoryD': 'C'}, {'categoryA':'A', 'categoryB': 'B','categoryC':'A', 'categoryD': 'C'}, {'categoryA':'B', 'categoryB': 'A','categoryC':'B', 'categoryD': 'C'}, {'categoryA':'B', 'categoryB': 'A','categoryC':'A', 'categoryD': 'C'}, {'categoryA':'C', 'categoryB': 'B','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'C', 'categoryB': 'C','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'D', 'categoryB': 'C','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'D', 'categoryB': 'C','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'D', 'categoryB': 'C','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'D', 'categoryB': 'B','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'D', 'categoryB': 'A','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'D', 'categoryB': 'A','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'C', 'categoryB': 'A','categoryC':'B', 'categoryD': 'A'}, {'categoryA':'D', 'categoryB': 'A','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'B', 'categoryB': 'B','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'D', 'categoryB': 'B','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'D', 'categoryB': 'B','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'E', 'categoryB': 'A','categoryC':'A', 'categoryD': 'A'}, {'categoryA':'E', 'categoryB': 'A','categoryC':'A', 'categoryD': 'A'}] // var compiled = []; data.forEach((d, i)=>{ var combinations = d3.cross(Object.keys(d), Object.keys(d)).filter((z)=>{return z[0] != z[1];}); combinations.forEach((columns)=>{ compiled.push({'sourceDimension': columns[0], 'sourceCategory': d[columns[0]], 'targetDimension': columns[1], 'targetCategory': d[columns[1]],}); }) d.id = i; }) //calculate each groups percent of total for each category. var nested = d3.nest() .key((d)=>{return d.sourceDimension;}) .key((d)=>{return d.sourceCategory;}) .key((d)=>{return d.targetCategory;}) .entries(compiled); nested.forEach((sourceDim)=>{ var sourceTotal = 0; sourceDim.values.forEach((sourceCat)=>{ sourceCat.values.forEach((targetCategory)=>{ sourceTotal = sourceTotal + targetCategory.values.length; targetCategory.count = targetCategory.values.length; }); sourceCat.count = sourceTotal; }) sourceDim.count = sourceTotal; }); console.log(nested); // Feel free to change or delete any of the code you see in this editor! var width = 500; var height = 500; var pad = 50; var radius = Math.min(width - pad*2, height - pad*2)/2; // compute an initial pie layout var pie = d3.pie().value(1)(nested); var bars = []; //first level = dimensions //second level = stacked bars //third level = chords // use d3 interpolator to get x,y values along line. pie.forEach((d)=>{ var x1 = Math.cos(d.startAngle)*radius; var x2 = Math.cos(d.endAngle)*radius; var y1 = Math.sin(d.startAngle)*radius; var y2 = Math.sin(d.endAngle)*radius; // push coordinates for the stacked bars to begin and end. d.polarCoords = [d3.interpolate([x1,y1],[x2,y2])(0.2),d3.interpolate([x1,y1],[x2,y2])(.8)]; d.data.values.forEach((bar)=>{ var cumulative = 0; bar.pcnt = bar.count/d.data.count; bar.cumulative = cumulative; cumulative = cumulative + bar.pcnt; bars.push({'x1':d3.interpolate(d.polarCoords[0],d.polarCoords[1])(bar.cumulative)[0], 'x2':d3.interpolate(d.polarCoords[0],d.polarCoords[1])(bar.cumulative + bar.pcnt)[0], 'y1':d3.interpolate(d.polarCoords[0],d.polarCoords[1])(bar.cumulative)[1], 'y2':d3.interpolate(d.polarCoords[0],d.polarCoords[1])(bar.cumulative + bar.pcnt)[1], 'data':bar, }) }) console.log(d.data.values); console.log(bars); //figure out }) // figure out the distance for the total scale. // convert polar coordinates back to normal for easy axes. var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) var chart = svg.append('g') .attr('transform','translate(' + width/2 + ',' + height/2 + ')') var lines = chart.selectAll("line").data(bars); lines.enter() .append('line') .attr("x1", (d)=>{return d.x1}) .attr("x2", (d)=>{return d.x2}) .attr("y1", (d)=>{return d.y1}) .attr("y2", (d)=>{return d.y2}) .attr("stroke", "black") .style('opacity',(d,i)=>{ return i*.05; }) .style('stroke-width', '12px') </script> </body>
https://d3js.org/d3.v4.min.js