如何在具有不同数据的情况下重用Chartjs Chart组件,并克服 **Canvas is already in use** 错误?

fruv7luv  于 2022-11-07  发布在  Chart.js
关注(0)|答案(1)|浏览(235)

我在Vue项目中有一个箱线图组件,我想在同一页上为我正在构建的表重用它。

但是,尽管事实上我的数据是不同的,我仍然得到这个Canvas is already in use. Chart with ID '0' must be destroyed before the canvas can be reused.错误。
我以前在这里看到过这个问题,但是没有一个线程的“修复”真的帮助了我。(Threads I've seenvideo I tried to replicate)。
因为我不知道需要使用多少行(和图表),所以我认为this fix不是很实用。有没有任何方法可以解决这种错误?
我需要为我使用的每个图表生成一个新的id吗?因为这是利用基本的Chartjs库,而不是我在应用程序的其余部分一直使用的普通VueChart3 syntax,我有点困惑。
任何帮助或建议都将不胜感激!干杯!
CodeSandbox Link

箱线图.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.log(`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>

表格.版本

<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>
qmelpv7a

qmelpv7a1#

网页设计中的ID应该是唯一的。每次你创建一个新的BoxPlotChart组件时,它都会在DOM中添加一个ID为'myChart'的画布。
您必须在BoxPlotChart图表组件中生成一个随机ID,或者在给予给画布的道具中沿着一个ID

相关问题