javascriptvue.jsvuejs2chartist.js

Vue.js + Chartist: Using charts in a component


I have a component that has access to the data necessary to generate a Chartist graph but I'm not sure how to generate the chart. Here's my component:

Vue.component('chart-card', {
  template: "#chart-card",
  props: {
    location: Object,
    appointments: Object
  },
  data: function() {
    return {
      data: {}
    }
  },
  computed: {

    fetchAppointments: function() {
      var that = this;
      $.ajax({
        method: 'GET',
        data: { location_id: this.location.id },
        url: `/appointments.json`,
        success: function(res) {
          that.data = {
            labels: Object.keys(res),
            seried: Object.values(res)
          }
        }
      })
    }
  }
})

and data becomes something like:

data: {
  labels: [
    "Consultation",
    "Weekly Sessions",
    "Re-Eval Week",
    "Full Maintenance",
    "Limited Maintenance",
    "Re-Starting the Program"
  ],
  series: [4, 24, 3, 1, 4, 1]
}

I run into the issue when I try to generate the chart which requires a DOM element:

new Chartist.Pie(DOM_ELEMENT_HERE, data, options )

Where would I make that call in a Vue component?


Solution

  • Your data fetch does not belong in a computed property, it should be a method call instead as it is asynchronous. The value for fetchAppointments will always be undefined in your case.

    You can construct your graph in the mounted lifecycle hook and refer to the appropriate DOM node using the $el property.

    My version of what you're trying to do would look like:

    Vue.component({
      template: "#chart-card",
    
      props: {
        location: Object,
        appointments: Object
      },
    
      methods: {
        fetchAppointments() {
          return new Promise((resolve, reject) => {
            $.ajax({
              method: 'GET',
              data: { location_id: this.location.id },
              url: `/appointments.json`,
              
              success: res => resolve({
                labels: Object.keys(res),
                seried: Object.values(res)
              })
            });
          });
        }
      },
    
      mounted() {
        this.fetchAppointments().then(data => {
          new Chartist.Pie(this.$el, data, options);
        });
      }
    });