【发布时间】: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-function 或 d3.js - rect on exit() is not being removed,但我仍然看不到我做错了什么。
谢谢。
【问题讨论】:
标签: javascript d3.js bar-chart vuejs3