使用D3,我发现自己经常这样做:
selectAll('foo').data(['foo']).enter().append('foo')
我想简单地添加一个尚不存在的节点,因为我需要在DOM树的不同位置进行更新,并且我手头上的数据并不完全与DOM平行。
这是我应该重新整理数据以使其平行的征兆,还是人们用于这种“丢失时创建”的事情的愚蠢模式?
最佳答案
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要求,那么您可以编写非常易于维护的代码。如果您尝试在此模式之外进行黑客攻击,则您的UI代码会让您很快感到难过。您应该预处理数据以适合UI的需求。
D3为某些用例提供了一些预处理器。例如,treemap布局函数将分层数据集展平为列表
treemap.nodes
,然后您可以将其用作基于列表的简单数据集,为每个元素绘制一个矩形。树形图布局还可以为您计算所有x,y,width,height
值。您只绘制矩形,不再关心层次结构。您可以用相同的方式开发自己的帮助程序功能来
这些“提示”可能包括几何值,标签文本,颜色,以及基本上所有无法从查看单个数据元素(例如树形图几何)直接获得的内容,而这将需要您将每个元素与某些/全部相关联。其他元素(例如,确定树中节点的嵌套深度)。在一个预处理步骤中执行此类任务可以使您为该任务编写更干净,更快速的代码,并将数据处理与UI绘图分离。
关于d3.js - d3模式,如果缺少则添加元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14471923/