Vue方法不会将d3标度识别为函数



我正在使用Vue.js和d3.js开发一个数据面板。数据是从API提供的。API数据存储在;allStates";道具这些数据被分发到所有组件的方法(粘贴在下面(。

四种方法中有三种正常工作/呈现。第四个drawDots不会将this.xScale和this.yScale识别为函数。我不断得到的错误是";TypeError:xScale不是函数"yScale也会出现同样的错误。

我已经将xScale和yScale移动到生命周期的不同部分,包括计算。运气不好。

我试图在drawDots方法中重新定义它们。再说一次,运气不好。

最后,我在watch中移动了我的所有方法,以确保只有在所有状态都收到了从promise推送到它的数据之后,才会调用这些函数。再说一次,运气不好。

如何使drawDots正确使用xScale和yScale?

完整组件如下。

<template>
<div class="plot-chart-wrapper">
<svg />
</div>
</template>
<script>
import * as d3 from "d3";
export default {
props: ["allStates"],
data() {
return {
width: 1000,
height: 300,
margin: { top: 50, bottom: 50, left: 12 },
xScale: "",
yScale: ""
};
},
methods: {
createYScale() {
this.yScale = d3
.scaleLinear()
.range([0, this.height])
.domain([80, 0]);
},
createXScale() {
this.xScale = d3
.scaleBand()
.range([0, this.width])
.domain(this.allStates[0].map(d => d[0]))
.padding(0.5);
},
drawPlotChart() {
d3.select(".plot-chart-wrapper svg")
.attr("width", this.width + this.margin.left)
.attr("height", this.height + this.margin.bottom + this.margin.top);
//x-axis
d3.select(".plot-chart-wrapper svg")
.append("g")
.attr("class", "x-axis")
.call(d3.axisBottom(this.xScale).tickSize([0]))
.attr(
"transform",
`translate(${this.margin.left},${this.height +
this.margin.bottom -
20})`
);
d3.select(".x-axis .domain").style("visibility", "hidden");
d3.selectAll(".x-axis .tick text")
.attr("text-anchor", "start")
.attr("transform", "rotate(90)")
.filter((d, i) => i === 7)
.text("D.C.");
//y-axis
d3.select(".plot-chart-wrapper svg")
.append("g")
.attr("class", "y-axis")
.call(
d3
.axisRight(this.yScale)
.tickSize([0])
.ticks(8)
)
.attr("transform", `translate(0,${this.margin.bottom - 20})`);
d3.select(".y-axis .domain").style("visibility", "hidden");
},
drawDots() {
d3.select(".plot-chart-wrapper svg")
.append("g")
.attr("class", "dots")
.attr(
"transform",
`translate(${this.margin.left},${this.margin.bottom - 20})`
)
.selectAll("circle")
.data(this.allStates[0])
.enter()
.append("circle")
.attr("r", 5)
.each(function(d) {
const xScale = this.xScale;
d3.select(this).attr("cx", xScale(d[4]));
})
.each(function(d) {
const yScale = this.yScale;
d3.select(this).attr("cy", yScale(d[0]));
});
}
},
watch: {
allStates() {
this.createYScale();
this.createXScale();
this.drawPlotChart();
this.drawDots();
}
}
};
</script>
<style scoped>
.plot-chart-wrapper {
border: 1px solid gainsboro;
border-radius: 5px;
box-shadow: 5px 5px 5px rgba(211, 211, 211, 0.378);
width: 1000px;
margin: 5% auto;
}
</style>

您在each回调函数中得到了错误的this值。

如果在函数外部的另一个标识符中捕获组件this,则可以在函数内部使用该标识符。

drawDots() {
const vm = this
d3.select(".plot-chart-wrapper svg")
// ... other code
.each(function(d) {
const xScale = vm.xScale;
d3.select(this).attr("cx", xScale(d[4]));
})

通常你会使用箭头函数来解决这类问题,但我假设你需要另一个this(用于d3.select(this)(作为each提供的this值。

我们也可以直接在选择中使用attr调用,而不是each,保留对函数中刻度的引用:

drawDots() {
const {xScale, yScale} = this
d3.select(".plot-chart-wrapper svg")
// ...
.attr("cx", d => xScale(d[4])
.attr("cy", d => yScale(d[0])

最新更新