使用D3 / SVG将文本添加到矩形元素

时间:2019-05-25 16:29:58

标签: javascript d3.js svg

我正在如下加载外部SVG文件,并且需要向我可以引用和操纵的每个rect添加文本。为此,我知道我需要将每个矩形放入一个组中,并将text元素插入同一组中。如果可能的话,我想通过代码来完成此操作,因为更改SVG文件的结构将花费一生,因为可能会有100多个rects。

实现此目标的最佳方法是什么?我确实浏览了其他一些问题,但是找不到我需要的答案。

目前我能假设的最好的情况是,我需要选择所有rect并追加组,或者循环遍历并分别选择每个rect?

floor.svg

    <rect id="SR001" x="288.62" y="220.7" class="st10" width="25.74" height="46.08"/>
<rect id="SR002" x="288.62" y="266.7" class="st10" width="25.74" height="46.08"/>
<rect id="SR003" x="288.62" y="312.49" class="st10" width="25.74" height="46.08"/>
<rect id="SR004" x="288.62" y="375.62" class="st10" width="25.74" height="46.08"/>
<rect id="SR005" x="288.62" y="421.7" class="st10" width="25.74" height="46.08"/>
<rect id="SR006" x="288.62" y="467.49" class="st10" width="25.74" height="46.08"/>
<rect id="SR007" x="288.62" y="513.62" class="st10" width="25.74" height="46.08"/>

这是加载SVG文件的方式,似乎工作正常。我还有其他功能可以使我在某些鼠标事件等情况下与矩形进行交互。

javascript

d3.xml("floor.svg", function(xml) {
  document.body.appendChild(xml.documentElement);});

1 个答案:

答案 0 :(得分:0)

我要采取的方法是,首先从rect中提取数据,然后删除所有rect,然后在想要的结构中重新创建它们。要提取,您可以使用selection.each(callback)。内部回调this指向元素,因此您可以执行例如d3.select(this).attr('x')以获得其x属性

<!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;
    }
  </style>
</head>

<body>
  <svg>
    <rect id="SR001" x="288.62" y="220.7" class="st10" width="25.74" height="46.08"/>
		<rect id="SR002" x="288.62" y="266.7" class="st10" width="25.74" height="46.08"/>
		<rect id="SR003" x="288.62" y="312.49" class="st10" width="25.74" height="46.08"/>
		<rect id="SR004" x="288.62" y="375.62" class="st10" width="25.74" height="46.08"/>
		<rect id="SR005" x="288.62" y="421.7" class="st10" width="25.74" height="46.08"/>
		<rect id="SR006" x="288.62" y="467.49" class="st10" width="25.74" height="46.08"/>
		<rect id="SR007" x="288.62" y="513.62" class="st10" width="25.74" height="46.08"/>
  </svg>
  <script>
    var rectData = [];
    var svg = d3.select("svg")
      .attr('width', 600)
      .attr('height', 600);
    svg.selectAll("rect")
      .each(function() {
        var r = d3.select(this);
        rectData.push({
          id: r.attr('id'),
          x: r.attr('x'),
          y: r.attr('y'),
          class: r.attr('class'),
          width: r.attr('width'),
          height: r.attr('height')
        });
      }).remove();

    var g = svg.selectAll('g')
      .data(rectData)
      .enter()
      .append('g')
      .attr('id', function(d) {
        return d.id;
      });

    g.append('rect')
      .attr('class', function(d) {
        return d.class;
      })
      .attr('x', function(d) {
        return d.x;
      })
      .attr('y', function(d) {
        return d.y;
      })
      .attr('width', function(d) {
        return d.width;
      })
      .attr('height', function(d) {
        return d.height;
      });

    g.append('text')
      .attr('y', function(d) {
        return d.y;
      })
      .attr('x', function(d) {
        return d.x;
      })
      .text(function(d) {
        return d.id;
      })
  </script>
</body>