1

I'm trying to update a Bar Graph every time data in a object changes, however I'm not able to get it working in any way. I'm using reactive() and ref(), but the graph will not update until I refresh the page.

Here's my chart component:

<script setup 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)

const props = defineProps<{ userHours: {} }>()

const chartData = ref({
    labels: Object.keys(props.userHours),
    datasets: [
        {
            label: "Worker Hours per Employee",
            data: [...Object.values(props.userHours)] as number[],
            maxBarThickness: 32,
            backgroundColor: "#ffb53c",
        },
    ],
})

const chartOptions = ref({
    responsive: true,
    maintainAspectRatio: true,
    scales: {
        x: {
            grid: {
                color: "black",
            },
            ticks: {
                color: "#eee",
            },
        },
        y: {
            grid: {
                color: "black",
            },
            ticks: {
                color: "#eee",
            },
        },
    },
    legend: {
        labels: {
            fontColor: "#eee",
        },
    },
})

const chartStyles = computed(() => {
    return {
        width: "100%",
        height: "20ch",
    }
})
</script>

<template>
    <Bar
        id="workhr-chart"
        :options="chartOptions"
        :data="chartData"
        :style="chartStyles"
    >
    </Bar>
</template>

And here is my main page (parent):

<script setup lang="ts">
import { User, Subtask } from ".prisma/client"
import { optionalMemberExpression } from "@babel/types"

const memberHours = reactive(initHours())

function initHours(): { [key: string]: number } {
    const hoursByMember: { [key: string]: number } = {}

    const tasks = project.value!.tasks.filter(
        task => task.status === 0 || task.status === 1,
    )
    for (const task of tasks) {
        for (const member of projectMembers) {
            if (task.assignees.includes(member)) {
                if (hoursByMember.hasOwnProperty(member.name)) {
                    hoursByMember[member.name] += task.workerHours
                } else {
                    hoursByMember[member.name] = task.workerHours
                }
            }
        }
    }
    return hoursByMember
}

function updateHours(uid: number, status: boolean) {
    let task = project.value!.tasks.find(task => task.uid === uid)
    let foundSubtask: Subtask | undefined

    if (!task) {
        // Check if the uid is a subtask
        for (const t of project.value!.tasks) {
            foundSubtask = t.subtasks.find(subtask => subtask.uid === uid)
            if (foundSubtask) {
                task = t
                break
            }
        }
    }
    if (!task) {
        return
    }

    const assignees = new Set(task.assignees.map(member => member.name))

    for (const memberName of Object.keys(memberHours)) {
        if (assignees.has(memberName)) {
            if (status) {
                memberHours[memberName] -= foundSubtask
                    ? foundSubtask.workerHours
                    : task.workerHours
            } else {
                memberHours[memberName] += foundSubtask
                    ? foundSubtask.workerHours
                    : task.workerHours
            }
        }
    }

    console.log(memberHours)
}

}
</script>

<template>
    <TaskSwitcher :tasks="project!.tasks" @update="updateHours" />

    <ProjectChart :user-hours="memberHours" />
</template>

Can someone please help with making my chart reactive? I've been trying to do that for the past few days but I'm not sure how I can do it.

Thanks!

1 Answer 1

2

Because chartData is a ref, it will not listen to props change. You need to either watch on props change and update chartData or change chartData to computed property which will listen to props change.

Sign up to request clarification or add additional context in comments.

1 Comment

COuld you provide a code example or the docs on how to do it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.