【问题标题】:D3 not removing rect before updating itD3 在更新之前不删除 rect
【发布时间】:2021-10-22 01:03:47
【问题描述】:

我在 Vuejs 中使用 d3 库。我从 API 调用数据,这些数据使用 vuex 存储在一个变量中。我的目标是重现这个情节 - > https://bl.ocks.org/LemoNode/73dbb9d6a144476565386f48a2df2e3b 但我在更新数据时遇到了问题。当我使用 d3 中的 exit().remove() 函数时,即使选择了 rect 对象也不会被删除(参见日志图片)。

<template>     
  <div class="billabilityPlot" v-if="$store.state.monthlyBillability.items?.length > 0">
      {{ chart($store.state.monthlyBillability.items) }}
 </div>
 <div class="chart">
        <b>Dynamic bar-chart example.</b>
        <svg id="chart" width="960" height="400"></svg>

        Choose year: 
        <select id="year"></select>

        <input type="checkbox" id="sort">   
        Toggle sort 

    </div>
  
</template>
<script>
import * as d3 from 'd3'
export default {
    methods: {
      chart(billabilityData) {

            //var billabilityData = this.$store.state.monthlyBillability.items

            var width="960"
            var height="400"

            var months = [...new Set(billabilityData.map(d => d.month))],
                years  = [...new Set(billabilityData.map(d => d.year))];


            var options = d3.select("div.chart").select("#year").selectAll("option")
                .data(years)
            .enter().append("option")
                .text(d => d)

            // Setting plot metrics
            var svg = d3.select("div.chart").select("#chart");

            var margin = {top: 25, bottom: 25, left: 25, right: 10};
                
            var w = +svg.attr("width") - margin.left - margin.right;

            var h = +svg.attr("height") - margin.top - margin.bottom;

            var x = d3.scaleBand()
                .range([margin.left, w - margin.right])
                .padding(0.1)
                .paddingOuter(0.2)

            var y = d3.scaleLinear()
                .range([h, margin.top])
                

            var xAxis = g => g
                .attr("transform", "translate(0," + (h) + ")")
                .call(d3.axisBottom(x).tickSizeOuter(0))

            var yAxis = g => g
                .attr("transform", "translate(" + margin.left + ",0)")
                .call(d3.axisLeft(y))

            svg.append("g")
                .attr("class", "x-axis")

            svg.append("g")
                .attr("class", "y-axis")

            
            update(d3.select("div.chart").select("#year").property("value"), 1000)

            function update(year, speed) {
            
                // We take only the data for a specific year
                var data = billabilityData.filter(function (d) {
                return d.year <= year
                });
                
                y.domain([0, d3.max(data, d => d.billability)]).nice();

                svg.selectAll(".y-axis").transition().duration(speed)
                    .call(yAxis);
                
                data.sort(d3.select("div.chart").select("#sort").property("checked")
                    ? (a, b) => b.billability - a.billability
                    : (a, b) => months.indexOf(a.month) - months.indexOf(b.month))
                
                x.domain(data.map(d => d.month))

                svg.selectAll(".x-axis").transition().duration(speed)
                    .call(xAxis)
                    

                var bar = svg.selectAll("rect")
                    .data(data, d => d.month)

                    console.log(bar)

                bar.exit().remove();

                bar.enter().append("rect")
                    .attr("class", "bar")
                    .attr("fill", "steelblue")
                    .attr("width", x.bandwidth())
                    .merge(bar)
                .transition().duration(speed)
                    .attr("x", d => x(d.month))
                    .attr("y", d => y(d.billability))
                    .attr("height", d => y(0) - y(d.billability))
                    
                }
            chart.update = update;

            var select = d3.select("div.chart").select("#year")
            .style("border-radius", "5px")
            .on("change", function() {
            chart.update(this.value, 4000)
            })

            var checkbox = d3.select("div.chart").select("#sort")
            .style("margin-left", "45%")
            .on("click", function() {
            chart.update(select.property("value"), 4000)
          })
    
    }   
    },
    mounted(){
    }    

}
</script>

这是 bar 变量的日志: 第一个选择是当我加载页面时,第二个是当我更新年份时。

选择似乎不错,但我不明白为什么它没有删除条形。

我阅读了一些博客,例如:https://observablehq.com/@dnarvaez27/understanding-enter-exit-merge-key-functiond3.js - rect on exit() is not being removed,但我仍然看不到我做错了什么。

谢谢。

【问题讨论】:

    标签: javascript d3.js bar-chart vuejs3


    【解决方案1】:

    问题不在于 exit().remove() 而是这部分代码

    var data = billabilityData.filter(function (d) {
               return d.year <= year
    });
    

    当我获取 2020 年的数据时很好,但是当我查找 2021 年的数据时,由于

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2015-04-27
      • 2010-09-21
      • 2020-05-25
      • 1970-01-01
      相关资源
      最近更新 更多