D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
GitNoise
Full window
Github gist
overlapping circles
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; } svg { border: 1px solid black; margin: 20px; } .overlap { fill: orange; fill-opacity: 0.2; stroke: orange; } .alone { fill: steelblue; fill-opacity: 0.2; stroke: steelblue; } line { stroke-width: 1px; stroke: black; stroke-opacity: 0.7 } .dot { fill: none; stroke: black; } </style> </head> <body> <script> const width = 500; const height = 500; const radius = 20; const joinRadius = 20; const svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) for(let i=0; i<4; i++) { svg.append("circle") .classed("overlap", true) .attr("id", "c_" + i) .attr("cy", height/2) .attr("cx", width/2) .attr("r", radius) } svg.append("circle") .classed("alone", true) .attr("cy", height/2 + 10) .attr("cx", width/2 + 10) .attr("r", radius) const bins = []; svg.selectAll("circle").each( (xxx, i, d) => { const elem = d3.select(d[i]); const x = elem.attr("cx"); const y = elem.attr("cy"); const indexOf = bins.findIndex(b => b.id === x + "" + y); if (indexOf === -1) { bins.push({ id: x + "" + y, items: [elem] }); } else { bins[indexOf].items.push(elem); } }); bins.forEach(bin => { if(bin.items.length > 1) { const cx = parseInt(bin.items[0].attr("cx")); const cy = parseInt(bin.items[0].attr("cy")); bin.items.forEach((circle, i) => { circle.attr("transform", `translate(${50 + i*radius*2 + i*4}, -50)`); }) svg.append("line") .attr("x1", cx) .attr("y1", cy) .attr("x2", cx + 50 - radius) .attr("y2", cy - 50 + radius + 4); svg.append("line") .attr("x1", cx + 50 - radius) .attr("y1", cy - 50 + radius + 4) .attr("x2", cx + 50 + bin.items.length * radius * 2) .attr("y2", cy - 50 + radius + 4); } }); </script> </body>
https://d3js.org/d3.v4.min.js