Home > OS >  vue-chart multiple instance initialization
vue-chart multiple instance initialization

Time:10-20

I would like to have multiple vue-chart.js graphs, each one refreshing (adding a new data point) every 5s. Value comes from a sensor and it is passed with props (I am writing UI for node-red application, which is I think not relevant to the problem).

I managed to get one graph working perfectly, but if I place 2 graphs, the passed values are displayed in both graphs simultaneously (not just in the one, that should diplay them).

See for youself here working CodeSandBox demo

What puzzles me is, that the console.log(this.myChart) in adddata shows "correct" graph (different id, different context). I think I have created individual graph instances and still, I can not add data to only one of those.

I do not use vue very offten, I may be missing something important. Thank you!

Component Test.vue

<template>
  <div>
    <canvas :id="name"></canvas>
  </div>
</template>

<script>
import Chart from "chart.js";

const chartSetting = {
  type: "line",
  data: {
    datasets: [
      {
        label: "setpoint",
        data: [],
        borderColor: "blue",
        borderWidth: 3,
      },
    ],
  },
  options: {},
};

let interval;

export default {
  name: "test",
  data() {
    return {
      myChart: null,
      chartSetting: chartSetting,
    };
  },
  props: ["id", "name", "setpoint"],
  methods: {
    adddata(setpoint, time) {
      this.myChart.data.datasets[0].data.push(setpoint);
      this.myChart.data.labels.push(time);
      this.myChart.update();
      console.log(`now printing ${setpoint} to this graph:`);
      console.log(this.myChart);
    },

    createChart(chartId, chardData) {
      const ctx = document.getElementById(chartId);
      // Save reference
      this.myChart = new Chart(ctx, {
        type: chardData.type,
        data: chardData.data,
        options: chardData.options,
      });

      interval = setInterval(() => {
        let date = new Date();
        let seconds = date.getSeconds();
        this.adddata(this.setpoint, seconds);
      }, 5000);
    },
  },

  mounted() {
    this.createChart(this.name, this.chartSetting);
  },
};
</script>

App.vue

<template>
  <div id="app">
    <p>
      graphs get new data from 2 different sensors every 5 seconds. Here
      simulated as "6" and "3"
    </p>
    <h3>this graph should only show 6</h3>
    <test name="grap1" id="1" setpoint="6" />
    <h3>this graph should only show 3</h3>
    <test name="grap2" id="2" setpoint="3" />
  </div>
</template>

<script>
import Test from "./components/Test";

export default {
  name: "App",
  components: {
    Test,
  },
};
</script>

CodePudding user response:

chartSetting object is the same for all component instances because it's defined once when component module is evaluated.

The reason data is factory function is that it returns a new data object for each instance that isn't shared between instances.

It should be:

  data() {
    const chartSetting = ...

    return {
      myChart: null,
      chartSetting: chartSetting,
    };
  }
  • Related