Search code examples
vue.jscomponentschart.js

How do i have a single Chart.vue component instead of different chart components and then display charts from it by changing id of the API


I am displaying four charts, so i have created four different chart components, but all the components are same but they differ in API id.

In order to make code effective, i want to make a single Chart.vue component and then display the chart in any other component by their respective ID.

Here is one of my chart component:

 <template>
      <div class="chart-container" style="position: relative; height: 25vh; width:100%;">
        <canvas id="DisplayChart" ></canvas>
      </div>
    </template>
    
    <script>
    import moment from 'moment'
    export default {
      name: 'Chart',
      async mounted () {
        await this.$http.get('/farfrom/chart/3') //Here 3 is the ID of the chart.
          .then((response) => {
            const result = response.data
            const ctx = document.getElementById('DisplayChart').getContext('2d')
            const Chart_data = []
            for (let i = 0; i < result.date.length; i++) {
              Chart_data.push({
                x_axis: moment(result.date[i], 'X').toDate(),
                y_axis: result.challenge[i]
              })
            }
            let myChart
            if (myChart !== undefined) {
              myChart.destroy()
            }
            myChart = new Chart(ctx, {
              type: 'line',
              data: {
                datasets: [
                  {
                    label: 'Chart_from_API',
                    data: Chart_data,
                ]
              },
              options: {
                lineTension: 0,
                maintainAspectRatio: false,
                scales: {
                  yAxes: [
                    {
                      scaleLabel: {
                        display: false
                      },
                      ticks: {
                        beginAtZero: true,
                        // eslint-disable-next-line no-unused-vars
                        callback (value) {
                          return `${value  }k`    // y-axis value will append k to it
                        }
                      }
                    }
                  ],
                  xAxes: [
                    {
                      type: 'time',
                      time: {
                        unit: 'month'
                      },
                      scaleLabel: {
                        display: true
                      }
                    }
                  ]
                }
              }
            })
          })
          .catch((error) => {
            console.log(error)
          })
      }
    }
    </script>

i have imported this in another component like:

    <template>
      <div class="chart-container">
        <Chart></Chart>
      </div>
    </template>
  
    <script>
    import Chart from 'Chart.vue'
    ....
    </script>

Here i have shown the example of one of my chart among 4 charts, my other charts are also same only change is in the id of the API.

Now as i said i want to know how i can make one Single Chart.vue with some variable to API Id and use it in any component by their respective id. Please do help me in this.

Objective: I want to have a single Chart.vue component instead of 4 charts, and if i want to use any chart i should be able to use their respective id.


Solution

  • You could use props to pass data to a child component.

    https://v2.vuejs.org/v2/guide/components-props.html

    Example

    App.vue

    <template>
      <div id="app">
        <Chart :id="chartId" />
      </div>
    </template>
    
    <script>
    import Chart from "@/components/Chart.vue";
    // @/ means src/
    
    export default {
      name: "App",
      components: {
        Chart,
      },
      data: () => ({
        chartId: 2,
      }),
    };
    </script>
    

    Chart.vue

    <template>
      <div>
        {{ id }}
      </div>
    </template>
    
    <script>
    export default {
      name: "Chart",
      props: {
        id: {
          type: Number,
          required: true,
        },
      },
      mounted() {
        const apiURL = `/farfrom/chart/${this.id}`;
        // API call
      }
    };
    </script>