如何在chart.js中传递图表数据而不会出现类型错误

问题描述 投票:0回答:1

我正在创建一个具有图表的应用程序,目前我正在尝试将商店中的信息插入其中。但是,我收到错误。当我尝试将 ChartData 对象传递给折线图的 data 属性(图表组件中的 3°line)时,会发生此错误

Property 'datasets' is missing in type 'Record<string, any>' but required in type 'ChartData<"line", (number | Point | null)[], unknown>'.ts(2741)

index.d.ts(3790, 3): 'datasets' is declared here.

types.d.ts(12, 5): The expected type comes from property 'data' which is declared here on type '{ readonly data: ChartData<"line", (number | Point | null)[], unknown>;

我的图表组件正在 User.vue 组件中渲染。

    <template>
        <div class="profile-container">
    
            <div class="user-container card">
                <img class="round-image" src="https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png">
                <div class="username">{{user?.name}}</div>
            </div>
            <div class="card statistcs-container">
                <div class="rank"><span><font-awesome-icon class="icon" icon="fa-solid fa-crown" /></span> 2nd place</div>
                <div class="statistcs">
                    <div><span>MAX WPM:</span> {{ user?.analytics.max_wpm }}</div>
                    <div><span>AVG WPM:</span> {{ user?.analytics.average_wpm }}</div>
                    <div><span>AVG ACC:</span> {{ user?.analytics.average_accuracy }}%</div>
                    <div><span>TOTAL TESTS:</span> {{ user?.analytics.number_of_tests }}</div>
                </div>
            </div>
            
            <chart class="chart" :chartData="chartData" :chartOptions="chartOptions"></chart>
            
    
        </div>
    </template>
    
    <script setup lang="ts">
        import { ref } from 'vue';
        import Chart from '../components/Profile/Chart.vue'
        import { useUserStore } from '~/store/User/UserStore';
        import {  ChartType } from 'chart.js';
    
        const { $axios } = useNuxtApp();
    
        const userStore = useUserStore();
    
        const showPassword = ref(false);
    
        const chartData = computed(() => {
            const currentUser = user.value; // Não é necessário usar .value aqui
            const typingTestResults = currentUser?.typingTestResults;
    
            return {
                type: 'line' as ChartType,
                labels: typingTestResults?.map(result => result.created_at),
                datasets: [
                    {
                        label: 'WPM',
                        data: typingTestResults?.map(result => result.wpm),
                        acc: typingTestResults?.map(result => result.accuracy),
                        time: typingTestResults?.map(result => result.duration_seconds),
                        backgroundColor: 'rgba(255, 174, 0, 0.2)',
                        borderColor: 'rgb(255, 174, 0)',
                        borderWidth: 3,
                        pointRadius: 6,
                        tension: 0.1,
                    }
                ],
            };
        });
    
            
        const chartOptions = {
            responsive: true,
            maintainAspectRatio: false,
            scales: {
                x: {
                    title: {
                        display: true,
                        text: 'Dates',
                        font: {
                            size: 16, // Ajuste o tamanho da fonte para o título do eixo X
                            family: 'RobotMono'
                        }
                    }
                },
                y: {
                    title: {
                        display: true,
                        text: 'WPM',
                        font: {
                            size: 16, // Ajuste o tamanho da fonte para o título do eixo X
                            family: 'RobotMono'
                        }
                    }
                }
            },
            plugins: {
                tooltip: {
                    mode: 'index',
                    intersect: false,
                    callbacks: {
                        label: (context: any) => {
                            const wpm = `- WPM: ${context.parsed.y}`;
                            const acc = `- ACC: ${context.dataset.acc[context.dataIndex]}%`;
                            const time = `- Time: ${context.dataset.time[context.dataIndex]}s`;
                            return [wpm, acc, time];
                        }
                    },
                    displayColors: false,
                    bodyFont: {
                        size: 17,
                        family: 'RobotMono'
                    }
                    
                },
                legend: {
                    display: false // Oculta a exibição da legenda
                }
            }
        }
    
        const togglePasswordVisibility = () => {
            showPassword.value = !showPassword.value;
        };
    
        const user = computed(()=>{
            return userStore.user;
        })
    
        onMounted(async () =>{
            if(!userStore.user){
                userStore.user = (await $axios.get('/user')).data.data;
            }
            console.log(user);
        })
    </script>

我的图表组件定义如下:

<template>
    <div>
      <Line :data="chartData" :options="chartOptions"></Line>
    </div>
</template>

<script setup lang="ts">
    import { Line } from 'vue-chartjs'
    import {
        Chart as ChartJS,
        CategoryScale,
        LinearScale,
        PointElement,
        LineElement,
        Title,
        Tooltip,
        Legend
    } from 'chart.js'

    ChartJS.register(
        CategoryScale,
        LinearScale,
        PointElement,
        LineElement,
        Title,
        Tooltip,
        Legend
    )

    const props = defineProps({
        chartData: {
            type: Object,
            required: true
        },
        chartOptions: {
            type: Object,
            required: true
        }
    });
</script>

我的店铺

import { TypingTestResult, User } from './../../types/User';
import { defineStore } from 'pinia';

export const useUserStore = defineStore('user', {
  state: () => ({
    user: {
      id: 0,
      name: '',
      email: '',
      typingTestResults: [] as TypingTestResult[],
      analytics: {
        max_wpm: 0,
        average_wpm: 0,
        average_accuracy: 0,
        number_of_tests: 0,
      },
    } as User,
  }),
});
javascript vue.js chart.js nuxt.js
1个回答
0
投票

该错误在于您定义图表数据的方式。尝试用这个代替您的图表数据定义

const chartData = computed(() => {
    const currentUser = user.value;
    const typingTestResults = currentUser?.typingTestResults;

    return {
        labels: typingTestResults?.map(result => result.created_at),
        datasets: [
            {
                label: 'WPM',
                data: typingTestResults?.map(result => result.wpm),
                backgroundColor: 'rgba(255, 174, 0, 0.2)',
                borderColor: 'rgb(255, 174, 0)',
                borderWidth: 3,
                pointRadius: 6,
                tension: 0.1,
                acc: typingTestResults?.map(result => result.accuracy),
                time: typingTestResults?.map(result => result.duration_seconds),
            }
        ],
    };
});

应该可以。

© www.soinside.com 2019 - 2024. All rights reserved.