看起来,当我使用"INSERT"函数时,新元素总是作为子元素插入,而不是作为sibling插入.

我仍然不明白为什么会这样,因为INSERT函数实际上应该在指定的元素之前插入一个新元素,而不是将指定的元素作为子元素插入.

基本上,我try 在"Text"元素旁边创建一个"rect"元素

这样做的目的是在我的d3 Sankey图表中的文本后面添加一个背景 colored颜色 .

 // NODE TEXT
this.nodes
  .selectAll('text')
  .data(this.data.nodes)
  .join(
    (enter) =>
      enter
        .append('text')
        .text((d) => `${d.name + ': ' + d.value}`)
        .style('fill', '#000000')
        .attr('text-anchor', 'right')
        .attr('x', (d, i) => {
          return d.x0 + (d.x1 - d.x0) / 0.5;
        })
        .attr('y', (d, i) => {
          return d.y0 + (d.y1 - d.y0) / 2;
        })
        .attr('dy', '0.35em')
        .attr('transform', (d, i) => {
          const x = d.x0 + (d.x1 - d.x0) / 2;
          const y = d.y0 + (d.y1 - d.y0) / 2;
          return `rotate(0, ${x}, ${y})`;
        })
        .call(getTextBox)
        .insert('rect', 'text')
        .attr('width', function (d) {
          return d.bbox.width;
        })
        .attr('height', function (d) {
          return d.bbox.height;
        })
        .attr('x', function (d) {
          return d.bbox.x;
        })
        .attr('y', function (d) {
          return d.bbox.y;
        })
        .style('fill', 'grey'),
    (update) =>
      update
        .transition()
        .duration(1000)
        .ease(d3_easeQuadInOut)
        .attr('x', (d, i) => {
          return d.x0 + (d.x1 - d.x0) / 2;
        })
        .attr('y', (d, i) => {
          return d.y0 + (d.y1 - d.y0) / 2;
        })
        .attr('transform', (d, i) => {
          const x = d.x0 + (d.x1 - d.x0) / 2;
          const y = d.y0 + (d.y1 - d.y0) / 2;
          return `rotate(0, ${x}, ${y})`;
        })
  );


function getTextBox(selection) {
  selection.each(function (d) {
    d.bbox = this.getBBox();
  });
}

以下是从我的浏览器呈现的HTML元素的图片.

请注意,"rect"元素是文本的子元素,而不是所需的sibling 元素.

HTML Elements

推荐答案

您所拥有的代码中的结果是意料之中的:之所以会出现这种情况,是因为对一组文本调用了insert,该文本充当父文本.

第一个简单的解决方案是打破链条,所以你有selection.append分和selection.insert分.例如:

const svg = d3.select("svg"),
  data = d3.range(5).map(e => ({
    value: e
  }));

svg.selectAll(null)
  .data(data)
  .join(enter => {
    enter.append("text")
      .attr("x", 20)
      .attr("y", d => 20 + 30 * d.value)
      .text(d => `text #${d.value}`)
      .call(getTextBox);

    enter.insert("rect", "text")
      .attr('width', d => d.bbox.width)
      .attr('height', d => d.bbox.height)
      .attr('x', d => d.bbox.x)
      .attr('y', d => d.bbox.y)
      .style('fill', 'grey')

  })

function getTextBox(selection) {
  selection.each(function(d) {
    d.bbox = this.getBBox();
  });
}
<script src="https://d3js.org/d3.v7.min.js"></script>
<svg></svg>

但是,此SVG将具有以下 struct :

<rect></rect>
<rect></rect>
<rect></rect>
...
<text></text>
<text></text>
<text></text>
...

也就是说,如果您想要使用以下 struct ...

<rect></rect>
<text></text>
<rect></rect>
<text></text>
<rect></rect>
<text></text>
...

...你需要更详细一点的insert.在本例中,我通过ID获取相应的文本元素:

const svg = d3.select("svg"),
  data = d3.range(5).map(e => ({
    value: e
  }));

svg.selectAll(null)
  .data(data)
  .join(enter => {
    enter.append("text")
      .attr("id", d => `text${d.value}`)
      .attr("x", 20)
      .attr("y", d => 20 + 30 * d.value)
      .text(d => `text #${d.value}`)
      .call(getTextBox);

    enter.insert("rect", d => d3.select(`#text${d.value}`).node())
      .attr('width', d => d.bbox.width)
      .attr('height', d => d.bbox.height)
      .attr('x', d => d.bbox.x)
      .attr('y', d => d.bbox.y)
      .style('fill', 'grey')

  })

function getTextBox(selection) {
  selection.each(function(d) {
    d.bbox = this.getBBox();
  });
}
<script src="https://d3js.org/d3.v7.min.js"></script>
<svg></svg>

Javascript相关问答推荐

为什么我的第二个OnClick Isloading值在TEK查询Mutations 查询中不起作用?

如何在加载的元数据上使用juserc和await中获得同步负载?

添加/删除时React图像上传重新渲染上传的图像

如何保持子画布元素的1:1宽高比?

如何通过onClick为一组按钮分配功能;

在分区内迭代分区

为什么从liveWire info js代码传递数组我出现错误?

警告!合同执行期间遇到错误[执行已恢复](Base Layer 2)

无法在nextjs应用程序中通过id从mongoDB删除'

在Vite React库中添加子模块路径

如何让npx在windows中运行js脚本?

第三方包不需要NODE_MODULES文件夹就可以工作吗?

类构造函数忽略Reaction Native中的可选字段,但在浏览器中按预期工作

有效路径同时显示有效路径组件和不存在的路径组件

MongoDB受困于太多的数据

如果没有页面重新加载Angular ,innerHTML属性绑定不会更新

使用Document.Evaluate() Select 一个包含撇号的HTML元素

FireBase云函数-函数外部的ENV变量

本地损坏的Java脚本

如何将对象推送到firestore数组?