I spent a lot of time trying to reproduce the attached diagram in SVG / D3.js. The closest I came is to use the attached code. I explored using the tree function, but I can only create one range of circles.
The problem with the attached code will be very complex to make it look smooth and smart by manually typing in which pixel coordinates each circle should have.
For information, the data set will do nothing more than the color of these circles, so it can be completely static in terms of shape. The code just needs to generate a form, and I can then control the color based on the data set.
image of what I'm trying to create:

This is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3 Test</title>
<style type="text/css">
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
</head>
<body>
<script type="text/javascript">
var w = 1000;
var h = 1000;
var dataset = [6, 2, 5, 4, 5, 5, 5, 5, 3, 4, 5, 6];
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
var circles = svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle");
circles.attr("cx", function(d, i) {
var Xaxis;
if (i === 0) {
Xaxis = "500";
} else if (i === 1) {
Xaxis = "400";
} else if (i === 2) {
Xaxis = "420";
} else if (i === 3) {
Xaxis = "452.5";
} else if (i === 4) {
Xaxis = "485";
} else if (i === 5) {
Xaxis = "515";
} else if (i === 6) {
Xaxis = "547.5";
} else if (i === 7) {
Xaxis = "580";
} else if (i === 8) {
Xaxis = "600";
} else if (i === 9) {
Xaxis = "600";
} else if (i === 10) {
Xaxis = "650";
} else if (i === 11) {
Xaxis = "700";
} else if (i === 12) {
Xaxis = "750";
} else if (i === 13) {
Xaxis = "750";
} else if (i === 14) {
Xaxis = "750";
} else if (i === 15) {
Xaxis = "750";
} else if (i === 16) {
Xaxis = "750";
}
return Xaxis;
})
circles.attr("cy", function(d, i) {
var Yaxis;
if (i === 0) {
Yaxis = "500";
} else if (i === 1) {
Yaxis = "500";
} else if (i === 2) {
Yaxis = "535";
} else if (i === 3) {
Yaxis = "560";
} else if (i === 4) {
Yaxis = "585";
} else if (i === 5) {
Yaxis = "585";
} else if (i === 6) {
Yaxis = "560";
} else if (i === 7) {
Yaxis = "535";
} else if (i === 8) {
Yaxis = "500";
} else if (i === 9) {
Yaxis = "600";
} else if (i === 10) {
Yaxis = "550";
} else if (i === 11) {
Yaxis = "500";
} else if (i === 12) {
Yaxis = "450";
} else if (i === 13) {
Yaxis = "600";
} else if (i === 14) {
Yaxis = "550";
} else if (i === 15) {
Yaxis = "500";
} else if (i === 16) {
Yaxis = "450";
}
return Yaxis;
})
.attr("r", function(d, i) {
var size;
if (i === 0) {
size = "30";
} else if (i > 0) {
size = "20";
}
return size;
})
.attr("fill", function(d, i) {
var returnColor;
if (d === 1) {
returnColor = "green";
} else if (d === 2) {
returnColor = "lightgreen";
} else if (d === 3) {
returnColor = "gold";
} else if (d === 4) {
returnColor = "darkorange";
} else if (d === 5) {
returnColor = "red";
} else if (d === 6) {
returnColor = "lightgrey";
}
return returnColor;
});
</script>
</body>
</html>
Run codeHide result
Jnper