d3动态更新树图

时间:2013-11-12 17:45:08

标签: javascript d3.js

我正在尝试更新树形图中的元素:

    drawTreeMap = (data) ->
      margin =
        top: 0
        right: 0
        bottom: 0
        left: 0

      width = window.innerWidth
      height = window.innerHeight
      color = d3.scale.category20c()

      treemap = d3.layout.treemap().size([width, height]).sticky(true).value((d) -> d.size)

      div = d3.select("body").append("div")
        .style("position", "relative")
        .style("width", (width + margin.left + margin.right) + "px")
        .style("height", (height + margin.top + margin.bottom) + "px")
        .style("left", margin.left + "px")
        .style("top", margin.top + "px")

      node = div.datum(data).selectAll(".node")
          .data(treemap.nodes)

      node.enter()
          .append("div")
            .attr("class", "node")
            .call(position)
            .style("background", (d) -> (if d.children then color(d.name) else null))
            .on "click", ->
              el = d3.select(this)
              data = el[0][0].__data__
              while (data.parent.parent)
                data = data.parent
              console.log("updated to data:")
              console.log(data)
              drawTreeMap(data)
              #updateTreemap(div, treemap, data)

      node.exit()
        .remove()

      node.transition().duration(1500).call position

data是我希望它出现在console.log语句中,但树形图没有得到更新。大多数代码都直接来自树形图示例。

1 个答案:

答案 0 :(得分:1)

就像Lars指出的那样,每次拨打div时,您都会创建一个新的div(分配给var drawTreeMap()的div)。对于初学者,您需要简单地将该div创建移到drawTreeMap之外,以便它只运行一次。或者,如果你想获得幻想,你可以将创作留在函数中,但是这样做:

div = d3.select("body").selectAll("div.treemap-container").data([null])
div.enter()
  .append('div')// only creates the div the first time this runs
  .attr('class', 'treemap-container')
  // etc...

这是我能看到的唯一奇怪的事情。也许还有另一个错误,但如果没有一个正常工作的jsFiddle,很难找到它。如果你能提供一个,请在这里发表评论,我会进一步了解。

顺便说一下,对于风格,而不是这样做:data = el[0][0].__data__,你应该这样做:data = el.datum()

最后,请注意,您没有使用键函数进行数据绑定,因此即使您重新渲染树形图,也不会有对象持久性(即现有的div可能会被重新分配到不同的数据点)任意地)。