Reputation: 1427
I have been working with vue3 for some months now, and for a new project want to use chart.js - so I found vue-chartjs which I thought would help. The sample shown in the link is written in the 'options' API but I have been working with the 'composition' API so wish to use that with vue-chartjs. Iam also using typescript, but I am getting a ts error with the composition api version, and the code does not run. Here is the original example, with typescript enabled (which still works OK)
<template>
<Bar
id="my-chart-id"
:options="chartOptions"
:data="chartData"
/>
</template>
<script lang="ts">
import { Bar } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js'
ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale)
export default {
name: 'BarChart',
components: { Bar },
data() {
return {
chartData: {
labels: [ 'January', 'February', 'March' ],
datasets: [ { data: [40, 20, 12] } ]
},
chartOptions: {
responsive: true
}
}
}
}
</script>
...and my conversion, using the compostion API:
<script lang="ts">
import { ref, onBeforeMount } from 'vue'
import { Bar } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale } from 'chart.js'
const chartData = ref({
labels: [ 'January', 'February', 'March' ],
datasets: [ { data: [50, 30, 12] } ]
});
const chartOptions = ref( {
responsive: true
});
onBeforeMount(() => {
ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale);
console.log('bartest: onBeforeMount');
})
</script>
<template>
<Bar
:chartOptions = "chartOptions"
:chartData="chartData"
/>
</template>
but now I have an error on using Bar
in the template:
Argument of type '{ chartOptions: { responsive: boolean; }; chartData: { labels: string[]; datasets: { data: number[]; }[]; }; }' is not assignable to parameter of type '{ readonly data: ChartData<"bar", (number | [number, number] | null)[], unknown>; readonly options?: _DeepPartialObject<CoreChartOptions<"bar"> & ElementChartOptions<"bar"> & PluginChartOptions<...> & DatasetChartOptions<...> & ScaleChartOptions<...> & BarControllerChartOptions> | undefined; ... 14 more ...; style?:...'. Property 'data' is missing in type '{ chartOptions: { responsive: boolean; }; chartData: { labels: string[]; datasets: { data: number[]; }[]; }; }' but required in type '{ readonly data: ChartData<"bar", (number | [number, number] | null)[], unknown>; readonly options?: _DeepPartialObject<CoreChartOptions<"bar"> & ElementChartOptions<"bar"> & PluginChartOptions<...> & DatasetChartOptions<...> & ScaleChartOptions<...> & BarControllerChartOptions> | undefined; ... 14 more ...; style?:...'.ts(2345)
and also
types.d.ts(12, 5): 'data' is declared here.
types.d.ts
suggests that data
has a type ChartData
but if I try that:
const chartData : ChartData = ref({....
then I have a different error
Property 'datasets' is missing in type 'Ref<{ labels: string[]; datasets: { data: number[]; }[]; }>' but required in type 'ChartData<keyof ChartTypeRegistry, (number | [number, number] | Point | BubbleDataPoint | null)[], unknown>'.ts(2741)
When I try to run this code, I get:
[Vue warn]: Missing required prop: "data" at <Anonymous chartOptions= {responsive: true} chartData= {labels: Array(3), datasets: Array(1)} > at .....
followed by many subsequent errors.
So, why is the 'options API' version happy without type definitions, and how do I type the 'composition API' version?
Upvotes: 0
Views: 726
Reputation: 1427
Thanks to @Estus Flask's comment I have a partial solution - the code now runs, but there is still a typescript error on the 'data' property of Bar
:
<script setup lang="ts">
import { ref, onBeforeMount } from 'vue'
import type { Ref } from 'vue'
import { Bar } from 'vue-chartjs'
import { Chart as ChartJS, Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale, Chart, type ChartData, type ChartOptions } from 'chart.js'
const chartData = ref({
labels: [ 'January', 'February', 'March' ],
datasets: [ { data: [50, 30, 35] } ]
}) as Ref<ChartData>;
const chartOptions = ref( {
responsive: true
}) as Ref<ChartOptions>;
onBeforeMount(() => {
ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale);
console.log('bartest: onBeforeMount');
})
</script>
<template>
<Bar
:options = "chartOptions"
:data ="chartData"
/>
</template>
The typescript error is:
Type 'ChartData<keyof ChartTypeRegistry, (number | [number, number] | Point | BubbleDataPoint | null)[], unknown>' is not assignable to type 'ChartData<"bar", (number | [number, number] | null)[], unknown>'.ts(2322) types.d.ts(12, 5): The expected type comes from property 'data' which is declared here on type '{ readonly plugins?: Plugin<"bar", AnyObject>[] | undefined; readonly data: ChartData<"bar", (number | [number, number] | null)[], unknown>; readonly options?: _DeepPartialObject<...> | undefined; ... 13 more ...; style?: unknown; } & Record<...>' (property) data: ChartData<"bar", (number | [number, number] | null)[], unknown>
Upvotes: 1