У меня есть компонент boxplot в моем проекте Vue, и я хочу повторно использовать его на той же странице для таблицы, которую я создаю.
Однако, несмотря на то, что мои данные отличаются, я все равно получаю эту Canvas is already in use. Chart with ID '0' must be destroyed before the canvas can be reused.
ошибку.
Я видел, как этот вопрос задавался ранее здесь, но ни одно из «исправлений» потоков действительно не помогло мне здесь. (Темы, которые я видел и видео, которое я пытался воспроизвести).
Поскольку я понятия не имею, сколько строк (и диаграмм) мне нужно будет использовать, я не думаю, что это исправление очень практичен. Есть ли в любом случае вокруг этого типа ошибки?
Нужен ли мне новый идентификатор, сгенерированный для каждой диаграммы, которую я использую? Поскольку здесь используется базовая библиотека Chartjs, а не обычный Синтаксис VueChart3, который я использовал в остальной части своего приложения, я немного озадачен.
Любая помощь или совет будут очень признательны! Ваше здоровье!
BoxPlotChart.vue
<template>
<canvas id = "myChart"></canvas>
</template>
<script>
import { defineComponent, onMounted } from "vue";
import { Chart, registerables } from "chart.js";
import { BoxPlotChart } from "@sgratzl/chartjs-chart-boxplot";
Chart.register(...registerables);
export default defineComponent({
name: "CBoxPlotChart",
props: {
data: {
type: Object,
required: true,
},
width: {
type: String,
// default: '400px'
},
height: {
type: String,
// default: '300px'
},
showLegend: {
type: Boolean,
default: true,
},
},
setup(props) {
onMounted(() => {
// @ts-ignore
const ctx = document.getElementById("myChart")?.getContext("2d");
ctx.canvas.parentNode.style.width = `${props.width}px`;
ctx.canvas.parentNode.style.height = `${props.height}px`;
if (!ctx) return;
const myChart = new BoxPlotChart(ctx, {
// type: 'boxplot',
// @ts-ignore
data: props.data,
options: {
responsive: true,
maintainAspectRatio: false,
indexAxis: "y",
// @ts-ignore
clip: false,
title: {
display: true,
text: "Chart.js Box Plot Chart",
},
plugins: {
datalabels: {
display: false,
},
legend: {
display: false,
},
tooltip: {
// if you want to hide the tooltip, just uncomment the line below
// enabled: false,
displayColors: false,
bodyFont: {
size: 12,
family: "Inter",
},
bodyColor: "#4771FA",
backgroundColor: "white",
callbacks: {
title: () => "",
label: (context) => {
console.info(`context!`, context.parsed.max);
const mean = context.parsed.mean.toFixed(3);
const q1 = context.parsed.q1.toFixed(3);
const q3 = context.parsed.q3.toFixed(3);
const boxplotValues = [
`Q3: ${q3}`,
`Mean: ${mean}`,
`Q1: ${q1}`,
];
return boxplotValues;
},
},
},
},
layout: {
padding: {
left: 10,
right: 5,
top: 0,
bottom: 10,
},
},
scales: {
x: {
display: false,
},
y: {
display: false,
},
},
},
});
});
return {
// isResponsive,
// getData,
// options,
// barChartProps,
// myStyles,
};
},
});
</script>
Таблица.vue
<template>
<table class = "no-spacing" cellspacing = "0">
<tr>
<th>Date</th>
<th>Value</th>
<th>Chart</th>
</tr>
<tr>
<td>
<div style = "margin: 0.5rem">05/03/22</div>
</td>
<td>
<div
style = "
background: #FFE2E2;
padding: 1rem;
margin: 0.5rem;
border-radius: 8px;
"
>
12.93
</div>
</td>
<td style = "width: max-content">
<BoxPlotChart :data = "boxplotData" />
</td>
</tr>
<tr>
<td>
<div style = "margin: 0.5rem">05/03/22</div>
</td>
<td>
<div
style = "
background: #FFE2E2;
padding: 1rem;
margin: 0.5rem;
border-radius: 8px;
"
>
12.93
</div>
</td>
<!-- <td style = "width: max-content">
<BoxPlotChart :data = "boxplotData2" />
</td> -->
</tr>
</table>
</template>
<script lang = "ts">
import { defineComponent } from "vue";
import BoxPlotChart from "./BoxPlotChart.vue";
import { boxplotData, boxplotData2 } from "./boxplot-mock-data";
export default defineComponent({
name: "",
props: {},
emits: [],
components: { BoxPlotChart },
setup() {
return { boxplotData, boxplotData2 };
},
});
</script>
<style lang = "sass" scoped>
table
th
text-align: center
tr, td
border: 1px solid #DCE5FA
</style>
ID в веб-дизайне должны быть уникальными. На данный момент каждый раз, когда вы создаете новый компонент BoxPlotChart
, он добавляет холст с идентификатором 'myChart'
в DOM.
Вам нужно либо сгенерировать случайный идентификатор в компоненте диаграммы BoxPlotChart
, либо передать идентификатор в реквизитах, которые вы даете холсту.
Вы не передали реквизит id на холст, вы установили идентификатор на id
, вам нужно использовать v-bind
для динамического добавления идентификатора, также вам нужен обертывающий div вокруг холста, иначе он будет постоянно расширяться. Рабочая песочница: codeandbox.io/s/boxplot-in-a-table-multiple-rows-forked-m4u9t2
Большое спасибо за помощь здесь! Это потрясающе
Еще раз спасибо за ваш комментарий! Интересно, я никогда не думал об этом. Проблема, с которой я сейчас сталкиваюсь, — это раздел
const myChart = new BoxPlotChart()
. Я обновил свой пример, чтобы попытаться пройти иid
prop, но безрезультатно. У вас есть идеи, что вам нужно сделать с этимconst myChart
? Обновлены коды и поле: codeandbox.io/s/boxplot-in-a-table-multiple-rows-nyi0o0?file=/….