I'm trying to make an app to graph tide data using vue.js and chart.js.
I get my data from the Wunderground API using axios, format it for chart.js, then pass it using props to a component to graph it. However, when I initially load the page, a blank chart loads. Upon resizing the window, or toggling the dataset the data appears properly.
I've read Chart.js will not render using vue.js until window resizes, which describes a similar problem, but unlike in that question, my canvas renders properly. The problem is only the dataset.
I've tried passing data through the props without using the API, and it works fine.
LineChart component
export default {
name: 'LineChart',
props: ['data', 'options'],
mounted() {
let ctx = document.getElementById('chart').getContext('2d')
let chart = new Chart(ctx, {
type: 'line',
data: this.data,
options: this.options
})
}
}
App component
export default {
name: 'app',
data() {
return {
url: 'http://api.wunderground.com/api/f219964b4d6ec312/tide/q/autoip.json',
chartData: {
labels: [],
datasets: [
{
label: 'Tide',
data: []
}
]
},
chartOptions: {
responsive: true,
scales: {
xAxes: [{
type: 'time',
}]
}
}
}
},
components: {
LineChart
},
created() {
this.getWeatherData()
},
methods: {
getWeatherData() {
axios.get(this.url).then((response) => {
response.data.tide.tideSummary.filter(this.isTideData).forEach((obj) => {
let d = new Date(0)
d.setUTCSeconds(obj.date.epoch)
this.chartData.labels.push(d)
this.chartData.datasets[0].data.push(parseFloat(obj.data.height))
})
})
},
isTideData(obj) {
return (obj.data.type == "Low Tide" || obj.data.type == "High Tide")
}
}
}
What am I doing wrong?
Like the question you linked here, it's probably another problem caused by async loading. You're doing the
new Chart(...)
in the child component'smounted
, by which time thedata
prop is probably still empty (on its way from the api url). Try removing themounted
and adding awatch
like this:I added a
loaded
flag here to make sure we only init the chart once, since it automatically adjusts to resizes, etc.