D3更新条形图VUE.js

问题描述 投票:0回答:1

嘿,我在Vue中的d3图表有问题。除了更新数据,其他一切都很好。

我正在使用道具传递数据,并且当数据更改我的图表而不是更新它时,它会在当前图表的下方创建另一个图表。

我想做的是保留当前图形,并在数据变化时仅更新条形图

<script>
export default {
    props: {
      arr: {
          type: Array
      }, 
      colors: {
          type: Array
      }
  },
  watch: {
    arr: {
      immediate: true,
      handler(val) {
        setTimeout(() => {
          this.barCharts(val)
        }, 100);
      }
    }
  },
  methods: {
    barCharts(data) {
      let margin = { top: 40, right: 20, bottom: 50, left: 60 };
      let width = 650
      let height = 240; 

      let color = d3.scaleOrdinal().range(this.colors);
      let t = d3.transition().duration(750);

      let g = d3
        .select("#barChart")
        .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", "100%")
        .append("g")
        .attr("transform", `translate(${margin.left}, ${margin.top})`);

      let xAxisGroup = g
        .append("g")
        .attr("class", "x axis")
        .attr("transform", `translate(0, ${height})`);

      let yAxisGroup = g.append("g").attr("class", "y axis");

      // X Scale
      let x = d3
        .scaleBand()
        .range([0, width])
        .padding(0.2);

      // Y Scale
      let y = d3.scaleLinear().range([height, 0]);

      // axis
      x.domain(data.map(d => d.name));
      y.domain([
        0,
        d3.max(data, function(d) {
          return d.value;
        })
      ]);

      g.append("g")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x))
        .attr("class", "axis")
        .selectAll("text")
        .style("text-anchor", "end")
        .attr("dx", "-.8em")
        .attr("dy", ".15em")
        .attr("transform", "rotate(-30)");

      g.append("g")
        .call(d3.axisLeft(y))
        .attr("class", "axis");

      // draw bars
      let rects = g.selectAll("rect").data(data);

      rects
        .transition(t)
        .attr("y", function(d) {
          return y(d.value);
        })
        .attr("x", function(d) {
          return x(d.name);
        })
        .attr("height", function(d) {
          return height - y(d.value);
        })
        .attr("width", x.bandwidth())
        .attr("fill", (d, i) => color(i));

      rects
        .enter()
        .append("rect")
        .attr("x", function(d) {
          return x(d.name);
        })
        .attr("width", x.bandwidth())
        .attr("fill", (d, i) => color(i))
        .attr("y", y(0))
        .attr("height", 0)
        .transition(t)
        .attr("y", function(d) {
          return y(d.value);
        })
        .attr("height", function(d) {
          return height - y(d.value);
        });

    }
  }
};
}
</script>

我可以实现另一个功能吗?更新以在此函数内调用以仅更新吟游诗人?

提前感谢!

vue.js d3.js methods bar-chart data-visualization
1个回答
0
投票

您生成了一个新的条形图,因为您要在barCharts方法中向目标添加新的SVG元素。每次调用时,它将在新的SVG后面附加更新后的数据,从而导致出现重复图表的问题。

由于Vue具有自己的呈现和更新DOM元素的方法,因此您不应该使用d3来执行此操作,因为这会干扰Vue的反应性和清除(这意味着您可能最终会遇到内存泄漏或元素未被删除的情况。) >

我的建议是在vue <svg>中定义<g><template>和其他元素,并使用v-bind指令将条形图值传递给vue渲染的SVG元素。例如,您可以使用d3-scale中的方法来计算xScale方法,该方法返回某个元素应在图形中准确表示宽度的宽度。然后,您可以使用<rect v-for="bar in bars" :width="xScale(bar.value)" />或类似方法绑定每个条的结果。

让我知道这是否足以让您继续前进,否则今天晚些时候我将为您提供完整的示例。我也推荐这部非常有见地的视频:https://www.youtube.com/watch?v=CkFktv0p3pw

© www.soinside.com 2019 - 2024. All rights reserved.