Vue Chart 3 - 中间带有文本的圆环图(注册插件时遇到问题)

Vue Chart 3 - Doughnut Charts with Text in the Middle (Trouble registering a plugin)

编辑: 我的 codesandbox 工作正常,但并不完美。在我的实际项目中,我更好地利用了 ts,我只是对图表类型进行 if 检查,这样字体就不会粘贴到您拥有的所有图表上。 我仍然需要努力使 fontsize 具有响应性和更漂亮,但我会尽可能多地尝试更新 codesandbox!

如果有人想添加,请添加!另外,post 你的 link 在评论中,这样其他有这些问题的人也可以看到它们!

我正在尝试制作一个如下所示的圆环图:

我一直在尝试弄清楚如何使用 VueChartJS (VueChart3 获取此示例中的代码是 VueChartJS 的 TS 安全重写并且工作方式相同,只是在组合 API) 中,但无法弄清楚如何让插件正常工作。

Working Example from post

上面 post 中的示例使用 textCenter() 函数并不断访问上下文 ctx 变量。然而,我得到的第一个错误是 Property 'pluginService' does not exist on type 'typeof Chart'Cannot read properties of undefined (reading 'register')。我认为这与 VueChart3 的方式有关,它是 Chart.register(...registerables) 行。

在尝试解决此问题时,我已经注释掉了当前破坏图表的所有代码。 我真的不知道现在该去哪里,真的需要一些指导。

干杯!

CodeSandbox Link

Chart2.vue

<template>
  <div style="display: flex; justify-content: center; margin: 5rem">
    <DoughnutChart :options="options" v-bind="doughnutChartProps" />
  </div>
</template>

<script lang='ts'>
import { computed, ref, onMounted } from "vue";
import { DoughnutChart, useDoughnutChart } from "vue-chart-3";
import { Chart, ChartData, ChartOptions, registerables } from "chart.js";
Chart.register(...registerables, plugin);
var plugin = function (chart) {
  var width = chart.chart.width;
  var height = chart.chart.height;
  var ctx = chart.chart.ctx;

  ctx.restore();
  var fontSize = (height / 114).toFixed(2);
  ctx.font = fontSize + "em sans-serif";
  ctx.textBaseline = "middle";

  var text = 800;
  var textX = Math.round((width - ctx.measureText(text).width) / 2);
  var textY = height / 2;

  ctx.fillText(text, textX, textY);
  ctx.save();
};

export default {
  name: "Home",
  components: { DoughnutChart },
  setup(props) {
    const isResponsive = ref(true);
    const getData = computed<ChartData<"doughnut">>(() => ({
      labels: ["Success"],
      datasets: [
        {
          data: [10, 90],
          backgroundColor: ["#56cd92", "#f0f7ff"],
        },
      ],
    }));
    onMounted(() => {
      addPlugin({
        id: "my-plugin",
        beforeDraw: plugin,
      });
      // renderChart(chartdata, options);
      // textCenter(1000);
    });
    const options = computed<ChartOptions<"doughnut">>(() => ({
      plugins: {
        legend: {
          position: "bottom",
        },
      },
    }));

    const { doughnutChartProps } = useDoughnutChart({
      options,
      chartData: getData,
    });
    return {
      isResponsive,
      getData,
      options,
      doughnutChartProps,
    };
  },
};
</script>

这是因为 pluginService 是 V2 语法,要在 V3 中全局注册插件,您可以像注册可注册对象一样这样做:

Chart.register(plugin)

您甚至可以像这样在同一个寄存器调用中执行此操作:

Chart.register(...registerables, plugin)

编辑:
插件也必须是对象,所以 chart.js 知道使用哪个钩子,就像你在挂载中所做的那样,所以你的插件变量必须看起来像这样(仍然是 V2 语法,你需要自己改变它)才能工作:

var plugin = {
 id: 'idOfPlugin', 
 beforeDraw: function (chart) {
  var width = chart.chart.width;
  var height = chart.chart.height;
  var ctx = chart.chart.ctx;

  ctx.restore();
  var fontSize = (height / 114).toFixed(2);
  ctx.font = fontSize + "em sans-serif";
  ctx.textBaseline = "middle";

  var text = 800;
  var textX = Math.round((width - ctx.measureText(text).width) / 2);
  var textY = height / 2;

  ctx.fillText(text, textX, textY);
  ctx.save();
 };
}