I am creating a component ScatterChart.vue within my Nuxt 3 or Vue 3 application and I am sending value to it from the parent component based on which I want the line graph to be drawn. Currently, I am able to get the data in the child component but it's not drawing any graph neither its throwing any error.
I believe I need to destroy and recreat it but unable to understand how.
Following is my parent component:
components/Parent.vue:
<template>
<button
type="button"
@click="getData"
>GET DATA</button>
<!-- Chart based on values -->
<ScatterChart :chartData="chartData" />
</template>
<script setup>
//Chart related variables
const chartData = useState("chartData", () => ({ labels: [], datasets: [] }));
const datasetColors = useState("datasetColors", () => [
"#FF6384",
"#36A2EB",
"#FFCE56",
"#4BC0C0",
]);
function getData(){
//read some file and get data and populate timeValues and then assign to chartData
if (!chartData.value.labels.includes(dateString)) {
chartData.value.labels.push(dateString);
}
chartData.value.datasets.push({
label: "TIME ",
type: "line",
borderColor: datasetColors[chartData.value.datasets.length + 1],
backgroundColor: datasetColors[chartData.value.datasets.length + 1],
borderWidth: 1,
data: timeValues,
});
}
components/ScatterChart.vue:
<template>
<div class="line-chart dark:bg-gray-800 dark:text-white">
<Line :data="chartData" :options="chartOptions" />
</div>
</template>
<script setup>
import { Line } from "vue-chartjs";
import {
Chart as ChartJS,
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend,
} from "chart.js";
import { ref, watch, onMounted } from "vue";
ChartJS.register(
CategoryScale,
LinearScale,
PointElement,
LineElement,
Title,
Tooltip,
Legend
);
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
};
const props = defineProps({
chartData: {
type: Array, //Data for the chart
required: false,
},
});
const chartData = ref(props.chartData);
const lineChart = ref(null);
const chartInstance = ref(null);
onMounted(() => {
if (chartInstance.value) {
chartInstance.value.destroy();
}
if (chartData.value && chartData.value.datasets.length > 0) {
chartInstance.value = new Line(lineChart.value, {
data: chartData.value,
options: chartOptions,
});
}
});
watch(
() => props.chartData,
(newData) => {
chartData.value = newData;
if (chartInstance.value) {
chartInstance.value.destroy();
}
if (chartData.value && chartData.value.datasets.length > 0) {
chartInstance.value = new Line(lineChart.value, {
data: chartData.value,
options: chartOptions,
});
}
}
);
</script>
I am unable to to trigger the method onMounted or the watcher within child component but if I log the values in template then able to see the values:
<template>
{{chartData}}
<div class="line-chart dark:bg-gray-800 dark:text-white">
<Line :data="chartData" :options="chartOptions" />
</div>
</template>