Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

TimeSocks's avatar

In a complete mess with Vue and Charts.js

Hi folks,

I am getting myself in a complete mess trying to put together a simple chart for a weather station I am putting together. The idea is that a wifi enabled micro-controller will, via a Python script, populate an SQLite database with temperature, humidity, and pressure data. That part is all set up. For the moment I have test data in the database.

I have set up a Laravel app and am trying to follow along with the Vue/Charts.js series here on Laracasts, but it's muddied slightly by a different version of Vue being used, and the fact that I'm a moron. Vue has too many damned curly brackets for my liking.

Anyway. I have an API route set up that, at the moment, grabs my dummy temperature data and returns it like this:

[{"hour":"2206","temperature":"12"},{"hour":"2206","temperature":"13"},{"hour":"2206","temperature":"5"},{"hour":"2206","temperature":"8"},{"hour":"2207","temperature":"11"},{"hour":"2207","temperature":"10"}]

The idea being that my chart will display the last 24 hours of data, recorded once per hour.

However, this is as far as I can get. I have no idea how to get the data where it needs to go in my Graph component.:

<template>
  <section>
    <canvas width="300" height="300" ref="chart"></canvas>
  </section>
</template>

<script>
    export default {
        props: ['url'],
        mounted() {
            console.log('Graph component mounted.')
            var context = this.$refs.chart.getContext('2d');
            this.$http.get(this.url)
                .then(response => {
                  console.log(response.data);

                  var data = {
                                labels: Object.keys(response.data),
                                datasets: [{
                                             label: 'My First dataset',
                                             data: [
                                                       Object.keys(response.data).map(key => response.data[key])
                                                   ],
                                    fill: false,
                                }   
                      }
                  new Chart(context, { type: "line", data: data });
                })
        }
    }
</script>

(url is a prop passed in the view - ideally I'd like to be able to reuse the chart for humidity and pressure simply by hitting a different API route to grab the relevant set of data)

This just descends into a mess of 'unexpected token' errors and I have no idea how to fix it. Help, please and thank you!

0 likes
4 replies
realrandyallen's avatar
Level 44

The unexpected token is because you're missing a ] after you define datasets...and you may not be pulling the data from the response right, try using lodash:

var data = {
    labels: _.map(response.data, 'hour'),
    datasets: [{
        label: 'My First dataset',
        data: _.map(response.data, 'temperature'),
        fill: false,
    }] // <-- missing ]
};
burlresearch's avatar

You basically had most of it. I tidied up what you had - and fixed a couple of the little data issues. Not sure what you're going for exactly, cause your data was a little weird (too many of the same keys...). Here is a working example with some little tweaks:

<template>
  <div class="container">
    <div class="row">
      <div class="col">
        <canvas width="300" height="150" ref="chart"></canvas>
      </div>
    </div>
  </div>
</template>

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

  export default {
    name: 'GraphJs',
    components: ['Chart'],

    data() {
      return {
        vtemps: [
          {'hour': '2202', 'temperature': '12'},
          {'hour': '2203', 'temperature': '13'},
          {'hour': '2204', 'temperature': '5'},
          {'hour': '2205', 'temperature': '8'},
          {'hour': '2206', 'temperature': '11'},
          {'hour': '2207', 'temperature': '10'},
        ],
      };
    },

    mounted() {
      let context = this.$refs.chart.getContext('2d');

      let cdata = {
        labels: this.vtemps.map(function (i) { return i.hour }),
        datasets: [
          {
            label: 'Hourly Temperatures',
            data: this.vtemps.map(function (i) { return i.temperature }),
            fill: false,
          },
        ],
      };
      new Chart(context, {type: 'line', data: cdata});
    },
  };
</script>
TimeSocks's avatar

@REALRANDYALLEN - Thanks! This works nicely, now that I have imported vue-resource (for some reason I thought that was unnecessary with Vue 2). I've added in a prop to handle which dataset the chart displays so I can reuse the component too.

1 like
realrandyallen's avatar

@TIMESOCKS - You're welcome! Well technically you could remove vue-resource and just use axios

axios.get(this.url)
                .then(response => {

Please or to participate in this conversation.