Chart.js 折线图大部分时间不显示
Chart.js line graph doesn't show up most of the time
我想显示一个图表,其中包含捐款和捐款日期。奇怪的是,图表有时会显示(大约 5% 的时间),但在其他 95% 的时间里不会显示(见底部图片)。
我对自己遇到的这个问题感到很困惑。我想使用从 API 获得的一些数据创建折线图。我正在使用 chart.js。有时它出现有时不出现。它与立即获取 API 数据无关(通过查看控制台)。所以我确定我使用 Chart.js.
的方式有问题
这是我的 LineChart.vue:
<script>
import { Line } from 'vue-chartjs'
export default {
name: 'LineChart',
extends: Line,
props: {
label: {
type: String
},
chartData: {
type: Array
},
options: {
type: Object
}
},
mounted () {
const dates = this.chartData.map(d => d.donationDate).reverse()
const totals = this.chartData.map(d => d.totalMoney).reverse()
this.renderChart({
labels: dates,
datasets: [{
label: this.label,
data: totals
}]
},
this.options)
}
}
</script>
这是我的 Fundraiser.vue 代码:
<template>
<div class="container">
<div class="row mt-5">
<div class="col">
<h2>Positive</h2>
<line-chart :chart-data=recentDonations :options=chartOptions label='Positive'>
</line-chart>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import moment from 'moment'
import LineChart from '../components/LineChart.vue'
export default {
name: 'Fundraiser',
components: { LineChart },
data () {
return {
recentDonations: [],
chartOptions: {
responsive: true,
maintainAspectRatio: false
}
}
},
async created () {
const { data } = await axios({
url: 'http://api.justgiving.com/[MY API KEY]/v1/crowdfunding/pages/[SOME-PAGE]/pledges',
method: 'get',
headers: {
Accept: 'application/json'
}
})
console.log(data)
data.pledges.forEach(d => { // this part works fine.
if (d.donationAmount != null) {
const dateInEpochFormat = d.activityDate.substring(6, 16)
const donationMade = moment.unix(dateInEpochFormat).format('MM/DD')
this.recentDonations.push({ donationDate: donationMade, totalMoney: d.donationAmount })
}
console.log(this.recentDonations)
})
}
}
</script>
正如您从下图中看到的那样,数据正在正常提取(具有两个属性的对象数组:donateDate 和 totalMoney)
所以有时它会出现(非常非常少):
[][
然后我刷新页面(没有触及任何代码),突然间:
谁能帮我解开这个谜?
尝试在收到来自 http 请求的响应后呈现图形,可能使用 if
语句和变量 flag
:
<template>
<div class="container">
<div class="row mt-5">
<div class="col" v-if="show">
<h2>Positive</h2>
<line-chart
:chart-data="recentDonations"
:options="chartOptions"
label="Positive"
>
</line-chart>
</div>
</div>
</div>
</template>
在你的 export default
对象中,你可以有这个:
export default {
name: 'Fundraiser',
components: { LineChart },
data () {
return {
show: false,
recentDonations: [],
chartOptions: {
responsive: true,
maintainAspectRatio: false
}
}
},
async created () {
const { data } = await axios({
url: 'http://api.justgiving.com/[MY API KEY]/v1/crowdfunding/pages/[SOME-
PAGE]/pledges',
method: 'get',
headers: {
Accept: 'application/json'
}
})
console.log(data)
data.pledges.forEach(d => { // this part works fine.
if (d.donationAmount != null) {
const dateInEpochFormat = d.activityDate.substring(6, 16)
const donationMade = moment.unix(dateInEpochFormat).format('MM/DD')
this.recentDonations.push({ donationDate: donationMade, totalMoney:
d.donationAmount })
}
console.log(this.recentDonations)
})
this.show = true;
}
}
这是一个解决方法,您在渲染图形之前等待获得数据,而不是第一次渲染图形时,它可以使用数据并显示信息。
之所以看不到图表中的数据,是因为渲染图表时没有要显示的信息,一旦您从 http 请求获得响应,图表就不会更新,为此,您必须观察 chartData 道具,chartData 更新后,您必须调用 chart.js 更新图形方法(您可以在此处阅读更多相关信息:https://www.chartjs.org/docs/latest/developers/updates.html)
处理数据更新的更好方法是在 forEach 之后将值分配给 this.recentDonations
,这样您就不会在每次推送质押时都获得更新:
...
const 捐款 = [];
data.pledges.forEach(d => { // 这部分工作正常。
如果(d.donationAmount!=空){
常数 dateInEpochFormat = d.activityDate.substring(6, 16)
常量 donationMade = moment.unix(dateInEpochFormat).format('MM/DD')
donations.push({ donationDate: donationMade, totalMoney:
d.donationAmount})
}
console.log(this.recentDonations)
})
this.recentDonation = 捐款;
this.show = 真;
...
我用这段代码做了一个超时函数的测试(我不知道如何使用 justgiving api):
<template>
<div class="container">
<div class="row mt-5">
<div class="col" v-if="show">
<h2>Positive</h2>
<line-chart
:chart-data="recentDonations"
:options="chartOptions"
label="Positive"
>
</line-chart>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import moment from "moment";
import LineChart from "../components/LineChart.vue";
export default {
name: "Fundraiser",
components: { LineChart },
data() {
return {
show: false,
recentDonations: [],
chartOptions: {
responsive: true,
maintainAspectRatio: false
}
};
},
methods: {
request() {
const pledges = [
{ donationDate: "11/08", donationAmount: 5 },
{ donationDate: "11/09", donationAmount: 5 },
{ donationDate: "11/10", donationAmount: 5 },
{ donationDate: "11/11", donationAmount: 5 },
{ donationDate: "11/12", donationAmount: 5 },
{ donationDate: "11/13", donationAmount: 5 },
{ donationDate: "11/14", donationAmount: 5 },
{ donationDate: "11/15", donationAmount: 5 },
{ donationDate: "11/16", donationAmount: 5 },
{ donationDate: "11/17", donationAmount: 5 },
{ donationDate: "11/18", donationAmount: 5 },
{ donationDate: "11/19", donationAmount: 5 },
{ donationDate: "11/20", donationAmount: 5 },
{ donationDate: "11/21", donationAmount: 5 },
{ donationDate: "11/22", donationAmount: 5 }
];
pledges.forEach(d => {
// this part works fine.
// if (d.donationAmount != null) {
// const dateInEpochFormat = d.activityDate.substring(6, 16);
// const donationMade = moment.unix(dateInEpochFormat).format("MM/DD");
this.recentDonations.push({
donationDate: d.donationDate,
totalMoney: d.donationAmount
});
// }
console.log(this.recentDonations);
});
this.show = true;
}
},
async created() {
await setTimeout(this.request, 1000);
}
};
</script>
如果删除 if 语句,图表将不显示任何数据
我想显示一个图表,其中包含捐款和捐款日期。奇怪的是,图表有时会显示(大约 5% 的时间),但在其他 95% 的时间里不会显示(见底部图片)。
我对自己遇到的这个问题感到很困惑。我想使用从 API 获得的一些数据创建折线图。我正在使用 chart.js。有时它出现有时不出现。它与立即获取 API 数据无关(通过查看控制台)。所以我确定我使用 Chart.js.
的方式有问题这是我的 LineChart.vue:
<script>
import { Line } from 'vue-chartjs'
export default {
name: 'LineChart',
extends: Line,
props: {
label: {
type: String
},
chartData: {
type: Array
},
options: {
type: Object
}
},
mounted () {
const dates = this.chartData.map(d => d.donationDate).reverse()
const totals = this.chartData.map(d => d.totalMoney).reverse()
this.renderChart({
labels: dates,
datasets: [{
label: this.label,
data: totals
}]
},
this.options)
}
}
</script>
这是我的 Fundraiser.vue 代码:
<template>
<div class="container">
<div class="row mt-5">
<div class="col">
<h2>Positive</h2>
<line-chart :chart-data=recentDonations :options=chartOptions label='Positive'>
</line-chart>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import moment from 'moment'
import LineChart from '../components/LineChart.vue'
export default {
name: 'Fundraiser',
components: { LineChart },
data () {
return {
recentDonations: [],
chartOptions: {
responsive: true,
maintainAspectRatio: false
}
}
},
async created () {
const { data } = await axios({
url: 'http://api.justgiving.com/[MY API KEY]/v1/crowdfunding/pages/[SOME-PAGE]/pledges',
method: 'get',
headers: {
Accept: 'application/json'
}
})
console.log(data)
data.pledges.forEach(d => { // this part works fine.
if (d.donationAmount != null) {
const dateInEpochFormat = d.activityDate.substring(6, 16)
const donationMade = moment.unix(dateInEpochFormat).format('MM/DD')
this.recentDonations.push({ donationDate: donationMade, totalMoney: d.donationAmount })
}
console.log(this.recentDonations)
})
}
}
</script>
正如您从下图中看到的那样,数据正在正常提取(具有两个属性的对象数组:donateDate 和 totalMoney)
所以有时它会出现(非常非常少):
[
然后我刷新页面(没有触及任何代码),突然间:
谁能帮我解开这个谜?
尝试在收到来自 http 请求的响应后呈现图形,可能使用 if
语句和变量 flag
:
<template>
<div class="container">
<div class="row mt-5">
<div class="col" v-if="show">
<h2>Positive</h2>
<line-chart
:chart-data="recentDonations"
:options="chartOptions"
label="Positive"
>
</line-chart>
</div>
</div>
</div>
</template>
在你的 export default
对象中,你可以有这个:
export default {
name: 'Fundraiser',
components: { LineChart },
data () {
return {
show: false,
recentDonations: [],
chartOptions: {
responsive: true,
maintainAspectRatio: false
}
}
},
async created () {
const { data } = await axios({
url: 'http://api.justgiving.com/[MY API KEY]/v1/crowdfunding/pages/[SOME-
PAGE]/pledges',
method: 'get',
headers: {
Accept: 'application/json'
}
})
console.log(data)
data.pledges.forEach(d => { // this part works fine.
if (d.donationAmount != null) {
const dateInEpochFormat = d.activityDate.substring(6, 16)
const donationMade = moment.unix(dateInEpochFormat).format('MM/DD')
this.recentDonations.push({ donationDate: donationMade, totalMoney:
d.donationAmount })
}
console.log(this.recentDonations)
})
this.show = true;
}
}
这是一个解决方法,您在渲染图形之前等待获得数据,而不是第一次渲染图形时,它可以使用数据并显示信息。
之所以看不到图表中的数据,是因为渲染图表时没有要显示的信息,一旦您从 http 请求获得响应,图表就不会更新,为此,您必须观察 chartData 道具,chartData 更新后,您必须调用 chart.js 更新图形方法(您可以在此处阅读更多相关信息:https://www.chartjs.org/docs/latest/developers/updates.html)
处理数据更新的更好方法是在 forEach 之后将值分配给 this.recentDonations
,这样您就不会在每次推送质押时都获得更新:
...
const 捐款 = [];
data.pledges.forEach(d => { // 这部分工作正常。
如果(d.donationAmount!=空){
常数 dateInEpochFormat = d.activityDate.substring(6, 16)
常量 donationMade = moment.unix(dateInEpochFormat).format('MM/DD')
donations.push({ donationDate: donationMade, totalMoney:
d.donationAmount})
}
console.log(this.recentDonations)
})
this.recentDonation = 捐款;
this.show = 真;
...
我用这段代码做了一个超时函数的测试(我不知道如何使用 justgiving api):
<template>
<div class="container">
<div class="row mt-5">
<div class="col" v-if="show">
<h2>Positive</h2>
<line-chart
:chart-data="recentDonations"
:options="chartOptions"
label="Positive"
>
</line-chart>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import moment from "moment";
import LineChart from "../components/LineChart.vue";
export default {
name: "Fundraiser",
components: { LineChart },
data() {
return {
show: false,
recentDonations: [],
chartOptions: {
responsive: true,
maintainAspectRatio: false
}
};
},
methods: {
request() {
const pledges = [
{ donationDate: "11/08", donationAmount: 5 },
{ donationDate: "11/09", donationAmount: 5 },
{ donationDate: "11/10", donationAmount: 5 },
{ donationDate: "11/11", donationAmount: 5 },
{ donationDate: "11/12", donationAmount: 5 },
{ donationDate: "11/13", donationAmount: 5 },
{ donationDate: "11/14", donationAmount: 5 },
{ donationDate: "11/15", donationAmount: 5 },
{ donationDate: "11/16", donationAmount: 5 },
{ donationDate: "11/17", donationAmount: 5 },
{ donationDate: "11/18", donationAmount: 5 },
{ donationDate: "11/19", donationAmount: 5 },
{ donationDate: "11/20", donationAmount: 5 },
{ donationDate: "11/21", donationAmount: 5 },
{ donationDate: "11/22", donationAmount: 5 }
];
pledges.forEach(d => {
// this part works fine.
// if (d.donationAmount != null) {
// const dateInEpochFormat = d.activityDate.substring(6, 16);
// const donationMade = moment.unix(dateInEpochFormat).format("MM/DD");
this.recentDonations.push({
donationDate: d.donationDate,
totalMoney: d.donationAmount
});
// }
console.log(this.recentDonations);
});
this.show = true;
}
},
async created() {
await setTimeout(this.request, 1000);
}
};
</script>
如果删除 if 语句,图表将不显示任何数据