5

在此处发布问题和答案,以便以后避免其他人遇到同样的麻烦...

当我使用d3.layout.partition创建两个旭日形图表时,第一个旭日形的切片比例在调整切片大小时被第二个旭日形的切片比例覆盖。

这两个图表将不同.value的访问器函数传递到分区布局中,例如

d3.layout.partition()
.sort(null)
.value(function(d) { return 1; });

对比

d3.layout.partition()
.sort(null)
.value(function(d) { return d.size; });

它们会生成自己的节点列表,这些节点不会在两个旭日形之间共享。但是,如果我重新调用d3.svg.arc生成器以调整更大的半径(但不改变整体比例),切片角度会突然被覆盖。

请参阅此处的示例:http: //bl.ocks.org/explunit/ab8cf15534f7fec5ac6d

4

2 回答 2

3

问题是,虽然partition.nodes() 似乎生成了一个新的数据结构(例如,如果你给它一些.key函数,它会将额外的属性(例如.x, .y, .dx, dy)写入底层数据并且不会复制数据。因此,如果数据结构在两个图表之间共享,这些.x, .y, .dx,dy属性将渗透到其他图表。

这对我来说似乎是一个错误,但在阅读这个旧的 GitHub 问题时,它似乎被视为“设计使然”。也许它会在未来的版本中重新考虑。

一种解决方法是使用 Lodash/UnderscorecloneDeep或 Angular 之类的东西copy来使每个图表都有自己的数据副本。

makeSunburst(null, _.cloneDeep(root), countAccessorFn);
makeSunburst(null, _.cloneDeep(root), sizeAccessorFn);

请参阅此处的示例:http: //bl.ocks.org/explunit/e9efb830439247eea1be

于 2014-06-30T22:12:31.967 回答
2

为每个图表复制整个数据集的替代方法是在重新渲染之前简单地重新计算分区。

与其makeSunburst()成为访问器的功能,不如使其成为分区的功能。将不同的分区函数传递给每个图表:

// create separate partition variables
var countPartition = d3.layout.partition().sort(null).value(countAccessorFn);
var sizePartition = d3.layout.partition().sort(null).value(sizeAccessorFn);

// make the charts as a function of partition
charts.push(makeSunburst(root, countPartition));
charts.push(makeSunburst(root, sizePartition));

然后在应用转换之前,只需更新nodes变量以反映关联的分区:

addToRadius: function(radiusChange) {
  radius += radiusChange;
  ringRadiusScale.range([0, radius]);

  // update the data before re-rendering each chart
  nodes = partition.nodes(dataRoot);
  path.transition().attr('d', arc);
}

现在,当您更新每个图表时,它使用的是正确的分区。

这是一个更新的示例

于 2014-06-30T23:27:14.157 回答