I am trying to allow users to display different charts by sending the id of the chosen chart to the fillData method. There are several issues with the code as is. Once a chart is loaded it takes two clicks of the other button to load the new chart, even though the data is retrieved successfully by the get method. After page load, chart 1 loads if I click either button.
Here is the main component:
<template>
<div class="small">
<line-chart :chart-data="datacollection"></line-chart>
<button @click="fillData(1)">Chart 1</button>
<button @click="fillData(2)">Chart 2</button>
</div>
</template>
<script>
import LineChart from './ResultsChart.vue'
export default {
components: {
LineChart
},
props: ['id'],
data () {
return {
datacollection: null
}
},
mounted (id) {
this.fillData(id)
},
computed: {
chartData: function() {
return this.data;
}
},
methods: {
fillData (id=1) {
this.datacollection = {
labels: this.getDates(id),
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: this.getData(id)
}
]
}
},
getDates: function(id){
axios.get('api/get_dates/' + id)
.then(function (response) {
this.dates = response.data;
}.bind(this));
return this.dates;
},
getData: function(id){
axios.get('api/get_results/' + id)
.then(function (response) {
this.rdata = response.data;
}.bind(this));
return this.rdata;
},
getStudents: function(){
axios.get('/get_students')
.then(function (response) {
this.students = response.data;
}.bind(this));
return students;
},
getCharts: function(){
axios.get('/get_charts')
.then(function (response) {
this.charts = response.data;
}.bind(this));
return charts;
},
}
}
</script>
<style>
.small {
max-width: 600px;
margin: 150px auto;
}
</style>
and the Mixin:
<script>
import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins
export default {
extends: Line,
mixins: [reactiveProp],
props: ['options','chartData'],
mounted () {
// this.chartData is created in the mixin.
// If you want to pass options please create a local options object
this.renderChart( this.options)
}
}
</script>
Any help appreciated. Thanks
After much casting about I found a solution that seems to work. I am new to both Chartjs and Vue, so I don't know if this is best practice. I moved the axios get requests inside the fillData function and updated the data inside the callback of the axios request.
<template>
<div class="small">
<line-chart :chart-data="datacollection"></line-chart>
<button v-model="chart_id" :value=1 @click="fillData(1)">Chart 1</button>
<button v-model="chart_id" value=2 @click="fillData(2)">Chart 2</button>
</div>
</template>
<script>
import LineChart from './ResultsChart.vue'
export default {
components: {
LineChart
},
data () {
return {
datacollection: null
}
},
mounted () {
this.fillData()
},
methods: {
fillData (id=1) {
axios.get('api/get_dates/' + id)
.then(function (response) {
this.dates = response.data;
axios.get('api/get_results/' + id)
.then(function (response) {
this.rdata = response.data;
this.datacollection = {
labels: this.dates,
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: this.rdata,
}
]
}
}.bind(this))
}.bind(this));
},
}
}
</script>