Saya ada masalah yang saya cuba selesaikan. Tidak boleh membaca sifat null (baca 'penukaran'). Apakah maksudnya? . Saya menyemak pilihan untuk menyepadukan mychart.update() daripada soalan ini https://github.com/chartjs/Chart.js/issues/5149. Tetapi apabila saya cuba untuk memulakan saya mendapat ralat lain.
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)
Di bawah anda boleh melihat kod terakhir yang saya cuba lancarkan.
<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>
Saya juga mencuba pilihan ini (menggunakan kemas kini()):
<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>
Apabila saya membuka rentetan dalam penyahpepijat:
Anda boleh melihat rujukan kepada baris ini:
Jika anda menyemak rujukan terakhir:
Anda boleh lihat baris ini:
Panjang sifat adalah untuk Array dan ralat mengatakan bahawa panjang tidak boleh dibaca nol (yang penting ialah perkataan "null"), jadi masalahnya ialah const atau var dengan sifat itu menjadi batal atas apa jua sebab. p>
Masalahnya ialah pada templat. Saya terlupa untuk menulis ID yang betul untuk kanvas. Mesti macam ni: