Reputation: 21
I want to switch the chart from using the data stored in one object property to another (from data stored under the key value
to the key value2
) by clicking a button (@click
).
I don't know how to use @click
for updating the data.
I'm using Axios to get the data using async await
.
My JSON data:
// Pulled from
// https://raw.githubusercontent.com/narudolimudom/Hospital/main/examplefile.json
[
{
"id": 1,
"name": "A",
"value": 20,
"value2": 50,
"value3": "90",
"value4": "100"
},
{
"id": 2,
"name": "B",
"value": 47,
"value2": 48,
"value3": "66",
"value4": "87"
},
. . .
]
I want to go from using resp.data[index].value
in my chart to using resp.data[index].value2
.
This is my code:
Test.vue
<template>
<div class="container">
<button>Click</button>
<barchart v-if="loaded" :chartdata="chartData" :options="options" />
</div>
</template>
<script>
import axios from "axios";
import barchart from "./Render.vue";
export default {
name: "LineChartContainer",
components: { barchart },
data: () => ({
loaded: false,
chartData: {
labels: [],
datasets: [
{
label: "Bar Chart",
borderWidth: 1,
pointBorderColor: "#2554FF",
data: [],
},
],
},
options: {.....},
}),
async mounted() {
this.loaded = false;
try {
const resp = await axios.get(
"https://raw.githubusercontent.com/narudolimudom/Hospital/main/examplefile.json"
);
for (let index = 0; index < resp.data.length; index++) {
this.chartData.labels.push(resp.data[index].name);
this.chartData.datasets[0].data.push(resp.data[index].value);
}
this.loaded = true;
} catch (e) {
console.error(e);
}
},
};
</script>
Render.vue
<script>
import { Bar } from "vue-chartjs";
export default {
extends: Bar,
props: {
chartdata: {
type: Object,
default: null,
},
options: {
type: Object,
default: null,
},
},
mounted() {
this.renderChart(this.chartdata, this.options);
},
};
</script>
Upvotes: 2
Views: 1503
Reputation: 553
Simply introduce a new property that defines which value you want to use and load the data using that one instead of your fixed ".value" property.
I have not tested the below code, I just changed your snippet to clarify my approach
<template>
<div class="container">
<!-- toggle the selectedProp when ever you click the buttons -->
<button @click="selectedProp = 'value'">Use value</button>
<button @click="selectedProp = 'value2'">Use value2</button>
<button @click="selectedProp = 'value3'">Use value3</button>
<button @click="selectedProp = 'value4'">Use value4</button>
<barchart v-if="loaded" :chartdata="chartData" :options="options" />
</div>
</template>
<script>
import axios from "axios";
import barchart from "./Render.vue";
export default {
name: "LineChartContainer",
components: { barchart },
data: () => ({
loaded: false,
selectedProp: 'value',
chartData: {
labels: [],
datasets: [
{
label: "Bar Chart",
borderWidth: 1,
pointBorderColor: "#2554FF",
data: [],
},
],
},
options: {.....},
}),
async mounted() {
this.loaded = false;
try {
const resp = await axios.get(
"https://raw.githubusercontent.com/narudolimudom/Hospital/main/examplefile.json"
);
// Get all the labels from the response
this.chartData.labels = resp.data.map(i => i.name)
// Get all the data from the response
// using [this.selectedProp] to get the variable field selector
this.chartData.datasets[0].data = resp.data.map(i => i[this.selectedProp])
this.loaded = true;
} catch (e) {
console.error(e);
}
},
};
</script>
Please be aware that you might have to refresh the bar, depending on if it is reactive on the changes on chartData or not.
Upvotes: 1