JSFiddle - React, Tailwind, and code Playground

by taa1953

JavaScript

// uses: D3.js, v3.x
// see: https://stackoverflow.com/questions/20908801/how-to-make-this-binomial-lattice-in-d3-js
var N = 12;
//var vOffset = 50;
var vOffset = 70;
// var hOffset = 100; // 100
var hOffset = 120;
//var rootXoffset = 30;
var rootXoffset = 30;
var rootYoffset = vOffset * N;
//var hBox = 30;
var hBox = 45; // box height
var wBox = 80; // box width
var width = rootXoffset + hOffset * N;
//var height = rootYoffset + vOffset * N + 30;
var height = rootYoffset + vOffset * N + hBox;
// var rectWidth = 60;
var rectWidth = wBox;
//var rectHeight = 30;
var rectHeight = hBox;

var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var i, j;
var textbox;
var startX;
var startY;
var targetX;
var targetY;

// first draw lines
for (i = 0; i < N; i++) {
  for (j = 0; j < i + 1; j++) {
    if (j == 0) {
      startX = rootXoffset + hOffset * i + rectWidth / 2;
      startY = rootYoffset - vOffset * i + rectHeight / 2;
      svg.append("line")
        .attr("x1", startX)
        .attr("y1", startY)
        .attr("x2", startX + hOffset * (N - i - 1))
        .attr("y2", startY + vOffset * (N - i - 1))
        .attr("stroke-width", 1)
        .attr("stroke", "black");
    }
    if (j == i) {
      startX = rootXoffset + hOffset * i + rectWidth / 2;
      startY = rootYoffset + vOffset * i + rectHeight / 2;
      svg.append("line")
        .attr("x1", startX)
        .attr("y1", startY)
        .attr("x2", startX + hOffset * (N - i - 1))
        .attr("y2", startY - vOffset * (N - i - 1))
        .attr("stroke-width", 1)
        .attr("stroke", "black");
    };
  }
}

// ...than arrows and link labels...
for (i = 0; i < N - 1; i++) {
  for (j = 0; j < i + 1; j++) {

    // targetX, targetY corner location of new box
    targetX = rootXoffset + hOffset * i + hOffset;
    targetY = rootYoffset - vOffset * i + (2 * vOffset) * j - vOffset + rectHeight;

    // up pointing arrow
    svg.append("line")
      .attr("x1", targetX)
 ...