d3模式,如果缺少则添加元素

时间:2013-01-23 03:21:17

标签: d3.js

使用D3,我发现自己做了很多这样的事情:

selectAll('foo').data(['foo']).enter().append('foo')

我想简单地添加一个节点(如果它还不存在),因为我需要在DOM树中的不同位置进行更新,而且我方便的数据并不完全与DOM平行。< / p>

这是否表明我应该重新构建我的数据以使其 并行,或者是否有一种不那么愚蠢的模式,人们会使用这种“创建如果缺少”的东西?

1 个答案:

答案 0 :(得分:16)

D3实现了DB世界中众所周知的JOIN + INSERT / UPDATE / DELETE模式。在d3中,您首先选择一些DOM元素,然后将其与数据连接:

//join existing 'g.class' DOM elements with `data` elements
var join = d3.select('g.class').data(data)   

//get the join pairs that did not have 'g.class' join partner and
//INSERT new 'g.class' DOM elements into the "empty slots"
join.enter().append('g').attr('class', 'class')

//get the join pairs that did not have a `data` element as join partner and
//DELETE the existing 'g.class' DOM elements
join.exit().remove()

//get the join pairs that have a `data` element join partner and
//UPDATE the 'g.class' DOM elements
join.attr("name","value")

您会发现,如果您的数据非常符合您的UI要求,您可以编写非常易于维护的代码。如果您尝试使用此模式之外的hack,您的UI代码很快就会让您感到非常伤心。您应该预处理数据以满足UI的需要。

D3为某些用例提供了一些预处理器。例如,treemap布局函数将分层数据集展平为列表treemap.nodes,然后您可以将其用作基于列表的简单数据集,为每个元素绘制一个矩形。树形图布局还会为您计算所有x,y,width,height值。你只需绘制rects而不再关心层次结构。

以同样的方式,您可以开发自己的帮助函数

  1. 将您的数据转换为更好的耗材格式
  2. 尝试用UI的“提示”来丰富数据,如何绘制它
  3. 这些“提示”可能包含几何值,标签文本,颜色,以及基本上无法通过查看单个数据元素(例如树形图几何体)得出的所有内容,并且需要您将每个元素与一些/所有其他元素(例如,确定树中节点的嵌套深度)。在一个预处理步骤中执行此类任务,可以为该任务编写更清晰,更快速的代码,并将数据处理与UI绘图分开。