【发布时间】:2022-08-17 22:12:57
【问题描述】:
我有一个问题,我试图解决。 Cannot read properties of null (reading \'transition\'). What does it mean?。 我从这个问题中检查了带有集成 mychart.update() 的选项 https://github.com/chartjs/Chart.js/issues/5149。 但是当我尝试启动时出现其他错误。
TypeError: Cannot read properties of null (reading \'length\')
at Object.acquireContext (Chart.js?473e:7756:1)
at Chart.construct (Chart.js?473e:9324:1)
at new Chart (Chart.js?473e:9311:1)
at VueComponent.draw (Analytics-test.vue?b2a7:69:1)
at VueComponent.loadTrainings (Analytics-test.vue?b2a7:444:1)
at async VueComponent.mounted (Analytics-test.vue?b2a7:476:1)
在你可以看到我试图启动的最后一个代码。
<template>
<div> Прибыль/посещаемость <div class=\"small\">
<canvas id=\"mychart\" height=\"400\"></canvas>
</div>
</div>
</template>
<script>
import Chart from \'chart.js\'
export default {
data: () => ({
flagStartDate: false,
chartData: null,
labels: [],
dataset: {},
draftData: null,
data: [],
datacollection: [],
clubsId: [\'5c3c5e12ba86198828baa4a7\', \'5c3c5e20ba86198828baa4c5\', \'60353d6edbb58a135bf41856\', \'61e9995d4ec0f29dc8447f81\', \'61e999fc4ec0f29dc844835e\'],
// clubsId: [\'5c3c5e12ba86198828baa4a7\', \'61e999fc4ec0f29dc844835e\'],
// clubsId: [\'61e999fc4ec0f29dc844835e\'],
}),
methods: {
draw() {
if (this.mychart) {
this.mychart.destroy();
}
const ctx = document.getElementById(\'main-chart\');
this.mychart = new Chart(ctx,
{
type: \'line\',
data: {
labels: this.labels,
datasets: this.datacollection
},
options: {
responsive: true,
elements: {
line: {
tension: 0 // disables bezier curves
}
},
scales: {
xAxes: [{
type: \"time\",
display: true,
scaleLabel: {
display: true,
labelString: \'Time\'
},
ticks: {
major: {
fontStyle: \"bold\",
fontColor: \"#FF0000\"
}
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: this.labelY
},
ticks: {
min: 0, // it is for ignoring negative step.
beginAtZero: true,
stepSize: 1 // if i use this it always set it \'1\', which look very awkward if it have high value e.g. \'100\'.
}
}]
}
}
});
},
participantsCountClub(clubId) {
switch (clubId) {
case \'5c3c5e12ba86198828baa4a7\':
return { label: \"Тренировок на Фрунзенской\", borderColor: \"#3e95cd\", fill: false }
case \'5c3c5e20ba86198828baa4c5\':
return { label: \"Тренировок на Чернышевской\", borderColor: \"#8e5ea2\", fill: false };
case \'60353d6edbb58a135bf41856\':
return { label: \"Тренировок на Василеостровской\", borderColor: \"#e8c3b9\", fill: false };
case \'61e9995d4ec0f29dc8447f81\':
return { label: \"Тренировок на Московской\", borderColor: \"#3cba9f\", fill: false };
case \'61e999fc4ec0f29dc844835e\':
return { label: \"Тренировок на Лесной\", borderColor: \"#c45850\", fill: false };
default:
return \'Неизвестный клуб\';
}
},
async loadTrainings(clubsId) {
try {
for (let clubId in clubsId) {
clubId = clubsId[clubId]
let dateFrom = \'2021-06-01T00:00:00\'
let dateTo = \'2022-08-01T23:59:59\'
let groupBy = \'month\'
await this.$store.dispatch(\'loadAvgSchedule\', { clubId, dateFrom, dateTo, groupBy })
this.draftData = this.$store.state.avgShedule
if (this.labels.length === 0) {
this.getDatesAvgIncome()
}
this.flagStartDate = true
await this.getParticipantsCount(clubId)
this.flagStartDate = false
}
this.draw()
} catch (e) {
console.error(e)
}
},
async getParticipantsCount(clubId) {
for (let item in this.draftData) {
let positionDate = this.labels.indexOf(this.draftData[item].date.slice(0, 7))
if (this.flagStartDate && positionDate > 0) {
let zerroArray = await this.bindDataDates(positionDate)
this.data = this.data.concat(zerroArray)
}
this.data.push(this.draftData[item].participantsCount)
this.flagStartDate = false
}
this.dataset.data = this.data
Object.assign(this.dataset, this.participantsCountClub(clubId))
this.datacollection.push(this.dataset)
console.log(\'this.datacollection\', this.datacollection)
this.data = []
this.dataset = {}
},
},
async mounted() {
await this.loadTrainings(this.clubsId)
},
}
</script>
<style>
.small {
max-width: 600px;
margin: 150px auto;
}
</style>
而且我也尝试了这个选项(使用更新()):
<template>
<div> Прибыль/посещаемость <div class=\"small\">
<canvas id=\"mychart\" height=\"400\"></canvas>
</div>
</div>
</template>
<script>
import Chart from \'chart.js\'
export default {
data: () => ({
flagStartDate: false,
chartData: null,
labels: [],
dataset: {},
draftData: null,
data: [],
datacollection: [],
clubsId: [\'5c3c5e12ba86198828baa4a7\', \'5c3c5e20ba86198828baa4c5\', \'60353d6edbb58a135bf41856\', \'61e9995d4ec0f29dc8447f81\', \'61e999fc4ec0f29dc844835e\'],
// clubsId: [\'5c3c5e12ba86198828baa4a7\', \'61e999fc4ec0f29dc844835e\'],
// clubsId: [\'61e999fc4ec0f29dc844835e\'],
}),
methods: {
draw() {
if (this.mychart) {
this.mychart.destroy();
}
const ctx = document.getElementById(\'main-chart\');
this.mychart = new Chart(ctx,
{
type: \'line\',
data: {
labels: this.labels,
datasets: this.datacollection
},
options: {
responsive: true,
elements: {
line: {
tension: 0 // disables bezier curves
}
},
scales: {
xAxes: [{
type: \"time\",
display: true,
scaleLabel: {
display: true,
labelString: \'Time\'
},
ticks: {
major: {
fontStyle: \"bold\",
fontColor: \"#FF0000\"
}
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: this.labelY
},
ticks: {
min: 0, // it is for ignoring negative step.
beginAtZero: true,
stepSize: 1 // if i use this it always set it \'1\', which look very awkward if it have high value e.g. \'100\'.
}
}]
}
}
});
},
participantsCountClub(clubId) {
switch (clubId) {
case \'5c3c5e12ba86198828baa4a7\':
return { label: \"Тренировок на Фрунзенской\", borderColor: \"#3e95cd\", fill: false }
case \'5c3c5e20ba86198828baa4c5\':
return { label: \"Тренировок на Чернышевской\", borderColor: \"#8e5ea2\", fill: false };
case \'60353d6edbb58a135bf41856\':
return { label: \"Тренировок на Василеостровской\", borderColor: \"#e8c3b9\", fill: false };
case \'61e9995d4ec0f29dc8447f81\':
return { label: \"Тренировок на Московской\", borderColor: \"#3cba9f\", fill: false };
case \'61e999fc4ec0f29dc844835e\':
return { label: \"Тренировок на Лесной\", borderColor: \"#c45850\", fill: false };
default:
return \'Неизвестный клуб\';
}
},
async loadTrainings(clubsId) {
try {
for (let clubId in clubsId) {
clubId = clubsId[clubId]
let dateFrom = \'2021-06-01T00:00:00\'
let dateTo = \'2022-08-01T23:59:59\'
let groupBy = \'month\'
await this.$store.dispatch(\'loadAvgSchedule\', { clubId, dateFrom, dateTo, groupBy })
this.draftData = this.$store.state.avgShedule
if (this.labels.length === 0) {
this.getDatesAvgIncome()
}
this.flagStartDate = true
await this.getParticipantsCount(clubId)
this.flagStartDate = false
}
// Below I tried refresh charts after updates data
this.mychart.update()
} catch (e) {
console.error(e)
}
},
async getParticipantsCount(clubId) {
for (let item in this.draftData) {
let positionDate = this.labels.indexOf(this.draftData[item].date.slice(0, 7))
if (this.flagStartDate && positionDate > 0) {
let zerroArray = await this.bindDataDates(positionDate)
this.data = this.data.concat(zerroArray)
}
this.data.push(this.draftData[item].participantsCount)
this.flagStartDate = false
}
this.dataset.data = this.data
Object.assign(this.dataset, this.participantsCountClub(clubId))
this.datacollection.push(this.dataset)
console.log(\'this.datacollection\', this.datacollection)
this.data = []
this.dataset = {}
},
},
async mounted() {
await this.loadTrainings(this.clubsId)
this.draw()
},
}
</script>
<style>
.small {
max-width: 600px;
margin: 150px auto;
}
</style>
您可以看到该行的引用:
如果检查最后一个参考:
你可以看到这一行:
-
您代码中的
.length正在尝试读取this.labels.length。那么出现错误时this.labels是什么? -
这就是说,您无法读取 null (null.length) 上的属性。
-
@user1599011 this.labels - 这是一个日期(对于 X 轴)。而此时 this.label 不为空(当 chartjs 尝试构建图形时)。 i.stack.imgur.com/9kz2T.pngi.stack.imgur.com/Gvtv8.png
-
在检查它的长度之前尝试记录它。
-
@user1599011 我做到了:i.stack.imgur.com/9kz2T.png i.stack.imgur.com/Gvtv8.png。控制台日志出现在 new Chart() 之前
标签: javascript vue.js chart.js