0

我很好奇为什么我的 d3 画布会保存数据,即使在我对浏览器进行了硬刷新之后也是如此。现在,如果我“放大”一个 g 元素,它的 dy、dx、w 和 h 会发生变化。因此,如果我使用过滤器并重新渲染冰柱,g 元素的位置与之前相同,但高度和宽度就像是新加载的一样。这会留下很多空白。通过一些试验,我发现 d3 以某种方式保存了绑定到 g 元素的所有数据。我将其构建为 Ruby on Rails 项目的前端。我试图用 canvas.selectAll("svg > *") 清除选择,但它似乎不起作用。我构建布局如下:

w = 1200
h = 800
x = d3.scale.linear().range([0,w])
y = d3.scale.linear().range([0,h])

renderIcicle = ()->
  canvas = getCanvas('#canvas')
  url = "/icicle/data.json"
  renderOnData(url, canvas)

getCanvas = (id)->
  d3.select(id).select("svg").remove()
  canvas = d3.select(id).append("svg").attr("width", w).attr("height", h)
  return canvas

calculateLayout = (root)->
  partition = d3.layout.partition()
  data = partition.nodes(root)
  return data

d3.json url, (root)->
  data = calculateLayout(root)
  drawCanvas(canvas, data, root)

  $('#filter-button').click ->
    rerender()

  rerender = ()->
    clearCanvas(canvas)
    data = calculateLayout(root)
    drawCanvas(canvas, data, root)

  drawCanvas = (canvas, data, root)->
    g = canvas.selectAll("g").data(data)

    g.enter().append("g").attr("transform", (d) ->
      "translate(" + x(d.y) + "," + y(d.x) + ")"
    ).on("click", (d)->
      click(d)
    ).append("rect").attr("width", root.dy * kx).attr("height", (d)->
      d.dx * ky
    )

    g.exit().remove()

    click = (d)->
      kx = (if d.y then w - 40 else w) / (1 - d.y)
      ky = h / d.dx
      x.domain([d.y, 1]).range [(if d.y then 40 else 0), w ]
      y.domain [d.x, d.x + d.dx]

      t = g.transition().duration(750).attr("transform", (d)->
        "translate(" + x(d.y) + "," + y(d.x) + ")"
      )

      t.select("rect").attr("width", (d)->
        d.dy * kx
      ).attr "height", (d)->
        d.dx * ky

      t.select("text").attr("transform", (d)->
        "translate(" + (d.x + d.dx / 2) + "," + (d.y + d.dy / 2) + ")"
      ).style "opacity", (d)->
        (if d.dx * ky > 12 then 1 else 0)

      d3.event.stopPropagation()

      return

clearCanvas = (canvas)->
  canvas.selectAll("svg").remove()
  canvas.selectAll("g").remove()
  canvas.selectAll("rect").remove()
  canvas.selectAll("text").remove()

--------------------更新--------
我解决了我最初的 d3 保存问题通过将宽度和高度设置为画布的宽度和高度来确定组的宽度和高度。

.append("rect").attr("width", w).attr("height", h)

这是一种非常 hacky 的方式,但是在重新渲染画布后不再有空格。然而,现在出现的问题是一些矩形开始与其他矩形重叠,导致并非所有数据都显示出来。这是因为它分层渲染项目而不是基于 x,y 位置。所以我的问题仍然存在:

D3 是否缓存元素上的数据(如宽度)?

4

0 回答 0