Home > database >  How to dynamically add data to chart js line graph on vue upon form submission?
How to dynamically add data to chart js line graph on vue upon form submission?

Time:10-16

I am having trouble dynamically adding data into my line chart. I plan for the line chart to be updated with new data every time the user submits a form with new data. Currently, I am able to push new data into the datasets array in App.vue's data function, but the chart would not generate the new data. It works if I manually type new data into the dataset array which confuses me even more. What should I do to fix it?

App.vue

<template>
<div>
  <form>
     <div >
      <div >
          <label >Score</label>
          <input type="number" min="0" max="100"  id="score"
              name="score" placeholder="Score in %" v-model='score' />
      </div>
      <div >
          <label >Exam Type</label>
          <select 
              aria-label=".form-select-sm example" id="examType"
              v-model='examType'>
              <option value="CA1">CA1</option>
              <option value="SA1">SA1</option>
              <option value="CA2">CA2</option>
              <option value="SA2">SA2</option>
          </select>
      </div>
  </div>
  <div >
      <div >
          <label >Subject</label>
          <input type="text"  id="subject" name="subject"
              placeholder="" v-model='subject' />
      </div>
  </div>

   <div >

      <button type="submit" data-bs-dismiss="modal"
           @click="addResult">Submit</button>
  </div>
 </form>
<div>
 <ChartTest :data="data" :title='title' />
</div>
</div>
</template>

<script>
    import ChartTest from "../components/ProgressPage/ChartTest.vue";
    export default {
        name: "Progress",
        components: {
            ChartTest
    },
        
        data() {
            return {
                score: '',
                examType: '',
                subject: '',
                existingSubjects: [],
                colors: ["#3e95cd", "#8e5ea2", "#3cba9f", "#e8c3b9", "#c45850"],
                title: '',
                data: {
                    labels: ['CA1', 'SA1', 'CA2', 'SA2'],
                    datasets: [
                              //dynamically add data here
                    ]
                },

            }
        },
    methods: {
            addResult() {
             
                let count = this.existingSubjects.length
             
                if (!this.existingSubjects.includes(this.subject)) {
                    this.existingSubjects.push(this.subject)
                    console.log(this.subject)
                    const newData = {
                        data: [this.score,54,43],
                        label: this.subject,
                        borderColor: this.colors[count],
                        fill: false
                    }
                    this.data.datasets.push(newData)
                    console.log( this.data.datasets)

                } else {
                    //TBC
                }
            


            }
        },
    }
</script>

ChartTest.vue

<template>
    <canvas id="progress-chart" width="600" height="450"></canvas>
</template>

<script>
    import Chart from 'chart.js/auto';
    export default {
        name: 'ChartTest',
        props: {
            data: Object,
            title: String

        },
        mounted() {
            new Chart(document.getElementById("progress-chart"), {
                type: 'line',
                data: this.data,
                options: {
                    plugins: {
                        title: {
                            display: true,
                            text: this.title
                        }
                    },
                    scales: {

                        y: {
                            display: true,
                            stacked: true,
                            max: 0,
                            min: 100,
                            title: {
                                display: true,
                                text: 'Your Score (%)'
                            }
                        }
                    }
                }
            });
        }
    }
</script>

CodePudding user response:

I think a reasonable solution here is to observe props change in ChartTest component. Firstly, create chart instance (const chart = new Chart(....)). Every time chart data changes, you should call chart.update() to update the chart.

Follow this thread to know how to observe props change .

  • Related