Zach L
Zach L

Reputation: 1

Updating chart data realtime from separate component

I'm pretty new to vue-chartjs and chartjs in general but I have a nuxt app (with electron) which is supposed to render the graph data live. Right now I just have sample data with an event listener updating the array being passed to the graph data object, but for some reason it only updates when the electron window moves...

Here's the code for the page with the component usage and test data to update it live (it doesn't update)

<script setup>
    import { Line } from 'vue-chartjs';
    import * as chartConfig from '/assets/js/chartInfo.js'
    import {Chart as ChartJS,CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend,Filler,Decimation} from 'chart.js';
    ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend,Filler,Decimation);

    // Data for chart renders
    const voltageChart = chartConfig.voltageChart;
    const currentChart = chartConfig.currentChart;
    const voltage = ref(chartConfig.getVoltage([5,7,4,2,1]))
    const current = ref(chartConfig.getCurrent([2,5,7,0,0,0,0,6,4]))
    
    
    
    let newVoltage = [0, 0, 0, 0, 0];
    let newCurrent = [0, 0, 0, 0, 0, 0, 0, 0, 0];
    onMounted(() => {
        setInterval(() => {
            (newVoltage).push(15);
            (newVoltage).shift();
            (newCurrent).push(15);
            (newCurrent).shift();
            voltage.value = chartConfig.getVoltage(newVoltage);
            current.value = chartConfig.getCurrent(newCurrent);
            console.log("changed");
        console.log(voltage.value.datasets[0].data);
        console.log(current.value.datasets[0].data);
        }, 3000)
    });
</script>
<template>

   <LazyLineChart :chartData="current" :chartOptions="currentChart" class="bg-gray-200 rounded-md" />
                
</template>

Chart config with the data presets and options:

let current = {
    labels: [ '1s', '', '', '', '0.5s', '', '', '', 'Now'],
    datasets: [
      {
        label: 'Voltage',
        backgroundColor: 'rgb(0,0,128)',
        borderColor: '#f87979',
        color: '#ffffff',
        fill: {
            target: 'origin',
            above: 'rgba(255, 0, 0,0.3)',   // Area will be red above the origin
            below: 'rgba(127, 159, 229,0.8)'
        },
        tension: 0.1,
        pointStyle: false,
        borderCapStyle: 'round',
        cubicInterpolationMode: 'monotone',
        data: [0, 0, 0, 0, 0, 0, 0, 0, 0],
      },
    ]
};

export function getCurrent(newData){
    current.datasets[0].data = newData;
    return current;
}

export const currentChart = {
    responsive: true,
    maintainAspectRatio: true,
    plugins: {
        legend: {
            display: false,
        },
        tooltip: {
            enabled: false
        },
    },
    scales: {
        x: {
            ticks: {
                color: 'black',
                padding: 6
            },
            grid: {
                drawTicks: false
            }
        },
        y: {
            ticks: {
                color: 'black', 
                padding: 6
            },
            grid: {
                drawTicks: false,
            }
        }
    },
    aspectRatio: 1/1,
}

The Component with the logic for the chart which is supposed to update live

<template>
    <Line :data="chartData" :options="chartOptions" />
</template>
  
<script>
    import { Line } from 'vue-chartjs'
    import {Chart as ChartJS,CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend,Filler,Decimation} from 'chart.js';
    ChartJS.register(CategoryScale,LinearScale,PointElement,LineElement,Title,Tooltip,Legend,Filler,Decimation);
    
    export default {
            name: 'LineChart',
            components: { Line },
        props: {
        chartData: {
                    type: Object,
                    required: true
                },
        chartOptions: {
            type: Object,
            default: {
                        responsive: true,
                        maintainAspectRatio: true,
                        plugins: {
                            legend: {
                                display: false,
                            },
                            tooltip: {
                                enabled: false
                            },
                            decimation: {
                                enabled: true,
                                algorithm: 'lttb',
                                samples: 8,
                                threshold: 2,
                            }
                        },
                        scales: {
                            x: {
                                ticks: {
                                    source: 'auto',
                                    // Disabled rotation for performance
                                    maxRotation: 0,
                                    autoSkip: true,
                                    color: 'black',
                                    padding: 6
                                },
                                grid: {
                                    drawTicks: false
                                }
                            },
                            y: {
                                ticks: {
                                    color: 'black', 
                                    padding: 6
                                },
                                grid: {
                                    drawTicks: false,
                                }
                            }
                        },
                        aspectRatio: 1/1,
                    }
            }
        },
            computed: {
                chartData() { return this.chartData },
                chartOptions() { return this.chartOptions }
            },
        mounted () {
            this.renderLineChart();
        },
        methods: {
            renderLineChart() {
                this.renderChart(this.chartData, this.chartOptions);
            }
        },
        watch: {
                chartData () {
                this.$nextTick(() => {
                    this.renderLineChart();
                })
            }
        }
    }
    
</script>

I saw in the docs it was said to use computed exports? I'm not sure how to implement that though here and can't find any examples anywhere. Can I get some help?

Upvotes: 0

Views: 129

Answers (0)

Related Questions