【问题标题】:Append shapes dynamically in d3 [duplicate]在d3中动态附加形状[重复]
【发布时间】:2018-08-15 11:18:34
【问题描述】:

我正在尝试根据datum 中包含的内容动态地append 形状。我的对象是这样的:

const boom = [
  {
    shape: 'rect',
    color: 'red',
    width: 50,
    height: 50,
    x: 50,
    y: 100
  }
]

我的代码是这样的:

const stage = d3.select('stageContainer')
    .append('svg')
    .attr('width', 100)
    .attr('height', 100)
    .style('border-width', '2')
    .style('border-color', 'red')
    .style('border-style', 'solid')

stage.selectAll('.group01')
      .data(boom)
      .enter()
      .append(d => document.createElement(d.shape))
      .attr('fill', d => d.color)
      .attr('width', d => d.width)
      .attr('height', d => d.height)
      .attr('x', d => d.x)
      .attr('y', d => d.y)

我可以看到它正在添加到 DOM,但实际上并没有呈现。

【问题讨论】:

  • 试试.append(d => d.shape)
  • 试过了。我不断收到:"TypeError: Failed to execute 'insertBefore' on 'Node': parameter 1 is not of type 'Node'."
  • 现在我仔细阅读了文档,如果它是一个函数,它必须返回与常量字符串不同的类型。该方法应该能够处理不同的函数返回(包括字符串)

标签: d3.js svg


【解决方案1】:

要创建 SVG 元素,您必须使用 document.createElementNS:

.append(d => document.createElementNS('http://www.w3.org/2000/svg', d.shape))

或者,您可以使用d3.namespaces 中的内置命名空间:

.append(d => document.createElementNS(d3.namespaces.svg, d.shape))

这是您的更改代码:

const boom = [{
  shape: 'rect',
  color: 'blue',
  width: 50,
  height: 50,
  x: 40,
  y: 10
}];

const stage = d3.select('body')
  .append('svg')
  .attr('width', 100)
  .attr('height', 100)
  .style('border-width', '2')
  .style('border-color', 'red')
  .style('border-style', 'solid')

stage.selectAll('.group01')
  .data(boom)
  .enter()
  .append(d => document.createElementNS(d3.namespaces.svg, d.shape))
  .attr('fill', d => d.color)
  .attr('width', d => d.width)
  .attr('height', d => d.height)
  .attr('x', d => d.x)
  .attr('y', d => d.y)
<script src="https://d3js.org/d3.v5.min.js"></script>

PS:更改该矩形的位置,否则它将落在 SVG 之外。

【讨论】:

  • 另外,舞台尺寸只是说明性的,但感谢您的提示:-)
  • @GerardoFurtado 尽管这个问题的答案已被接受,但您介意将其作为"How to create SVG elements of different types based on data?" 的副本进行欺骗吗?
  • @altocumulus 完成,实际上是一样的。这并没有出现在我所做的搜索中(S.O 搜索机制并不十分出色)。但现在我无法删除我的答案...
  • @altocumulus:我找到了另一种方法(无命名空间)并将其添加为上一个问题的答案stackoverflow.com/a/51860323/9938317
  • 哦,感谢关于标题的提示。欣赏这一点,并将记住未来:)
猜你喜欢
  • 1970-01-01
  • 2019-03-20
  • 2012-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-24
相关资源
最近更新 更多