D3更新条形图VUE.js

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D3更新条形图VUE.js相关的知识,希望对你有一定的参考价值。

嘿,我在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>

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

提前感谢!

答案

您生成了一个新的条形图,因为您要在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

以上是关于D3更新条形图VUE.js的主要内容,如果未能解决你的问题,请参考以下文章

d3.js化工管条形图

使用 d3.js 制作分组条形图

x轴范围选择器的d3条形图(如dygraphs)

html D3:带边距的条形图

如何从 Vue.Js 中的变量向数组添加值以制作条形图

D3浮动条形图中的多色条形图由时间计算确定