D3.js Rect with rect

by Arvind Pal

HTML

<svg id="main" height="350" width=510></svg>

JavaScript

let nodes = [
  [ "x", "y", "z", "xy", 'yz', "xz", "xyz" ],
  [ "a", "b", "c", "ab", "bc", "ac" ],
  [ "l", "m", "n", "lm", "mn", "ln" ]
];

let links = [
  { from : "x", to: "ac" },
  { from : "z", to: "a" },
  { from : "xz", to: "l" },
  { from : "bc", to: "lm" },
  { from : "b", to: "lm" }
];

let box = {
  height: 30,
  width: 100
};

let extraPadding = 8
	, topRectGap = 50
  , boxGap = 4;

var svg = d3
  .select("#main")
  .style("border", "1px solid black");

let x = 50, y = 50;

let xyStarts = [];

let g = svg.selectAll(".rect")
  .data(nodes)
  .enter()
  .append("g")
  .classed('parent-graph', true)

let rect = g.append("rect")
  .classed('parent-node', true)
  .attr("fill", "transparent")
  .attr('stroke-width', '2')
  .attr('stroke', 'black')
  .attr("height", (d) => (d.length * box.height) + ((d.length + 1) * boxGap ))
  .attr("width", box.width + extraPadding)
  .attr("y", y)
  .attr("x", (d) => {
    let a = x;
    x = (x + topRectGap) + box.width;
    xyStarts.push([ a, y ])
    return a
  });

let cordinates = {};
  
g.each(function (d, j) {
  
  let xy = xyStarts[j];
  let cY = xy[1];

  for (let i = 0; i < d.length; i++) {
    
    if (i == 0) {
      cY += boxGap;
    } else {
      cY += (box.height + boxGap);
    }
    
    let cX = (xy[0] + (extraPadding / 2) );

    cordinates[ d[i] ] = {
      in: [ cX, cY + (box.height / 2) ],
      out: [ (cX + box.width), cY + (box.height / 2) ]
    }

    d3.select(this)
      .append("rect")
      .attr("fill", "transparent")
      .attr('stroke-width', '1')
      .attr('stroke', 'black')
      .attr("height", box.height)
      .attr("width", box.width)
      .attr("x", cX)
      .attr("y", cY)
      .classed('node', true)
      
    d3.select(this).append("text")
      .text(d[i])
      .attr("x", cX + (box.width / 2))
      .attr("y", cY + (box.height / 2) + 3)
      .attr("fill", 'black');
  };
});

// console.log("cordinates ==> ", cordinates);

 svg
  .append('svg:defs')
  .append('svg:marker')
 ...