当我反复调用它的原始绘图功能时,为什么这个D3图表没有重绘?

时间:2016-02-04 12:26:32

标签: css jquery-ui d3.js

我正在尝试使用D3.js库创建一个带有可调整大小图表的仪表板。 为此,我在DIV中创建图表SVG元素,并使用jQuery-ui .resizable类使这些DIV可调整大小。

DIV的resized事件由另一个库(css-element-queries)监视并按像素触发,它应调用我的drawGraph()函数并按照其父DIV的比例重绘图形,但这不会发生而且我不确定为什么。我做了些蠢事吗?

看到这个小提琴:https://jsfiddle.net/Hoppertron/ymf90p6v/17/

顺便说一句,我知道在制作中我想要限制这个重绘事件 - 我只是想让它先工作。

以下是代码:

<body>
  <div id="div1" class="container resizable draggable">
    <svg id="chart1" class="chart"></svg>

    <script>
      //Watches for div resize event (using ResizeSensor.js) and calls drawGraph() to redraw SVG
      var element = document.getElementById('div1');
      new ResizeSensor(element, function(element) {
        var chartWidth = $("#div1").width(),
          chartHeight = $("#div1").height();
        drawGraph(chartWidth, chartHeight)
      });

    </script>
  </div>

  <script>
    //Calls drawGraph() on initial page load
    var chartWidth = $("#div1").width(),
      chartHeight = $("#div1").height();
    $(function() {
      drawGraph(chartWidth, chartHeight);
    });

  </script>

</body>

<script>
  function drawGraph(width, height) {

    var data = [4, 8, 15, 16, 23, 42];

    var barHeight = height / data.length;

    var x = d3.scale.linear()
      .domain([0, d3.max(data)])
      .range([0, width]);

    var chart = d3.select(".chart")
      .attr("width", width)
      .attr("height", height);

    var bar = chart.selectAll("g")
      .data(data)
      .enter().append("g")
      .attr("transform", function(d, i) {
        return "translate(0," + i * barHeight + ")";
      });

    bar.append("rect")
      .attr("width", x)
      .attr("height", barHeight - 1);

    bar.append("text")
      .attr("x", function(d) {
        return x(d) - 3;
      })
      .attr("y", barHeight / 2)
      .attr("dy", ".35em")
      .text(function(d) {
        return d;
      });
  };

</script>

2 个答案:

答案 0 :(得分:1)

您需要在重绘之前清除图表。在drawGraph函数的开头添加此行:

d3.selectAll(".chart > *").remove();

这里小提琴: https://jsfiddle.net/ymf90p6v/19/

如果您不清除它,数据仍会附加到现有元素,并且不会创建新元素。

答案 1 :(得分:1)

这可能听起来很愚蠢,但我认为你需要在重绘它之前先破坏原始图形。

当您执行d3.selectAll(元素)时,在后台,d3将检查元素的数量与数据元素的数量。然后当你输入()时,d3会查看是否有数据项还没有匹配元素,并在执行.append()时绘制这些元素。在您的情况下,数据不会更改,只会更改图表的大小。所以什么都不会重新绘制。