Javascript 在D3中具有唯一ID和链接的大矩形中添加小矩形?在特定ID之后

Javascript 在D3中具有唯一ID和链接的大矩形中添加小矩形?在特定ID之后,javascript,d3.js,Javascript,D3.js,在上一个问题中,我问如何为生成的矩形生成唯一ID 现在,我一直在尝试在这些矩形中绘制小矩形。但是,id=“rectup0”只能有4个具有唯一xlink:href属性的小rect 其余的可以有2个矩形内 <body> <div id="chart"> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.js"></script> <script typ

在上一个问题中,我问如何为生成的矩形生成唯一ID

现在,我一直在尝试在这些矩形中绘制小矩形。但是,
id=“rectup0”
只能有4个具有唯一
xlink:href
属性的小rect 其余的可以有2个矩形内

<body>
<div id="chart">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.js"></script>

    <script type="text/javascript">

      var width = 1000,
          height = 250,
          margin = 7,
          nRect = 11,
          rectWidth = (width - (nRect - 1) * margin) / nRect,

          svgContainer = d3.select('#chart').append('svg')
              .attr('width', width)
              .attr('height', height),

          svgWalkway = d3.select('#chart').append('svg')
            .attr('width', '1000')
            .attr('height', '150'),

          svgContainer2 = d3.select('#chart').append('svg')
            .attr('width', width)
            .attr('height', height);


// Rectangles scaling

      var firstRow = d3.range(nRect),
          posxScale = d3.scaleLinear()
            .domain(d3.extent(firstRow))
            .range([0, width - rectWidth]);

      var middleRow = d3.range(1),
          posxScale3 = d3.scaleLinear()
            .domain(d3.extent(middleRow))
            .range([0, width - rectWidth]);

      var secondRow = d3.range(nRect),
          posxScale2 = d3.scaleLinear()
            .domain(d3.extent(secondRow))
            .range([0, width - rectWidth]);

      //Drawing the actual objects HTML rects    
      svgContainer.selectAll('rect.up')
        .data(firstRow)
        .enter()
        .append('rect')
        .attr("id", function(d,i){ return "rectup" + i })
        .attr('x', posxScale)
        .attr('width', rectWidth)
        .attr('height', height)
        .attr('class','up');

      svgWalkway.selectAll('rect.middle')
        .data(middleRow)
        .enter()
        .append('rect')
        .attr('x', posxScale3)
        .attr('width','1000')
        .attr('height','150')
        .attr('class', 'middle');


      svgContainer2.selectAll('rect.down')
        .data(secondRow)
        .enter()
        .append('rect')
        .attr('id', function (d,i) { return "rectdown" + i })
        .attr('x', posxScale2)
        .attr('width', rectWidth)
        .attr('height', height)
        .attr('class', 'down')
        .attr('y', 0);
    </script>
</div>
</body>
我知道
JQuery
允许您向其他类添加类属性,但不确定D3,这类似于以编程方式添加新的
rect
标记。这可能吗

更新2

我想可以使用d3。插入,使用以下内容:

d3.select('#rectup0').insert('rect')
  .attr('id', 'redrect')
  .attr('x', 0)
  .attr('width', '20')
  .attr('height', '40');

但是它在开头和结尾的中间得到代码< > ReCT标签,像这个< /P>

<rect id="rectup0">
    <rect id="redrect" x="0" width="20" height="40"></rect>
</rect>


不用说,这不起作用,因为关闭
rect
标记

您可以使用所选数据的
每个
包装器。它接受3个参数:当前数据
d
、当前索引
i
、以及整个数据数组
arr
。因此,如果您需要某种检查,您是否应该附加小的
rect
,您可以创建一个helper函数:

var testIndex = function(d, i, arr) {
    return
      // test index
      i == 5 ||
      // test current data
      d == 10 ||
      // test other array members, which would be an EnterNode here
      (i > 0 && arr[i - 1]['__data__'] == 7);  
}

// do checks in one line:
var testIndex = function (d, i, arr) { return i == 4 || i == 10 || i == 7; }

var data = svgContainer.selectAll('rect.up')
  .data(firstRow);

data
  .enter()
  .each(function (d, i, arr) {
    // select DOM element to add the rects
    t = d3.select(this);

    t
      .append('rect')
      // note that here we use empty the parameters list
      .attr('id', 'rectup' + i)
      .attr('x', posxScale)
      .attr('width', rectWidth)
      .attr('height', height)
      .attr('class','up');

    if (!testIndex(d, i, arr)) {
      return;
    }

    t
      .append('rect')
      .attr('id', 'redrect' + i)
      // note that we need to define x-coord similar to first rect
      .attr('x', posxScale)
      .attr('class', 'redrect');
});

// remove your data before redraw
data
  .exit()
  .remove();
输出:

<svg width="1000" height="250">
  <rect id="rectup0" x="0" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup1" x="91.54545454545456" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup2" x="183.09090909090912" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup3" x="274.6363636363636" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup4" x="366.18181818181824" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup5" x="457.72727272727275" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="redrect5" x="457.72727272727275" class="redrect"></rect>
  <rect id="rectup6" x="549.2727272727273" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup7" x="640.8181818181818" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="redrect7" x="732.3636363636365" class="redrect"></rect>
  <rect id="rectup8" x="732.3636363636365" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup9" x="823.909090909091" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup10" x="915.4545454545455" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="redrect10" x="915.4545454545455" class="redrect"></rect>
</svg>

你的问题现在有点让人困惑。你想要:1。在另一个元素之后追加一个元素?(顺便说一句,这没有视觉上的区别)2。是否在不删除前一个类的情况下添加类?3.在另一个矩形内画一个矩形?在另一个矩形内画一个矩形…其余的都是我试图解决最初的问题。我认为整个问题取决于这样一个事实:inisde矩形必须在确定的id之后绘制。在这种情况下,矩形不能嵌套在标记中。要在另一个矩形内绘制矩形,只需将它们绘制为兄弟,第二个将在第一个矩形的顶部绘制,如果其坐标在第一个矩形的边界内,它将显示为“内部”,正如Robert Longson刚才所说,在另一个矩形内绘制矩形唯一重要的是坐标。矩形甚至可以在完全分离的组中。这就是为什么我不清楚你的问题。
<svg width="1000" height="250">
  <rect id="rectup0" x="0" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup1" x="91.54545454545456" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup2" x="183.09090909090912" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup3" x="274.6363636363636" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup4" x="366.18181818181824" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup5" x="457.72727272727275" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="redrect5" x="457.72727272727275" class="redrect"></rect>
  <rect id="rectup6" x="549.2727272727273" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup7" x="640.8181818181818" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="redrect7" x="732.3636363636365" class="redrect"></rect>
  <rect id="rectup8" x="732.3636363636365" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup9" x="823.909090909091" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="rectup10" x="915.4545454545455" width="84.54545454545455" height="250" class="up"></rect>
  <rect id="redrect10" x="915.4545454545455" class="redrect"></rect>
</svg>
// wouldn't work
.attr({
  id: 'redrect',
  x: posxScale,
  width: '20',
  height: '40'
});