J'ai un problème que j'essaie de résoudre. Impossible de lire la propriété null (lire « conversion »). Qu'est-ce que ça veut dire? . J'ai coché l'option d'intégration de mychart.update() à partir de cette question https://github.com/chartjs/Chart.js/issues/5149. Mais lorsque j'essaie de démarrer, j'obtiens d'autres erreurs.
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)
Ci-dessous vous pouvez voir le dernier code que j'ai essayé de lancer.
<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>
J'ai également essayé cette option (en utilisant update()) :
<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>
Quand j'ouvre la chaîne dans le débogueur :
Vous pouvez voir une référence à cette ligne :
Si vous vérifiez la dernière référence :
Vous pouvez voir cette ligne :
La longueur de la propriété est pour un tableau et l'erreur indique que cette longueur ne peut pas être lue de nulle (l'important est le mot "null"), donc le problème est qu'un const ou var avec cette propriété devient nul pour une raison quelconque. p>
Le problème vient du modèle. J'ai oublié d'écrire l'identifiant correct pour la toile. Ça doit être comme ça :