Just wondering if someone can point me in the right direction here when it comes to dynamic data from vuex and applying it to radar charts in vue-chart.js.
Below is my vue file.
<template>
<div>
<h1>Chart Demo</h1>
<v-card class="question card__text pa-sm-5 py-5 px-2">
<div>
<radar-chart :data="radarChartData" :options="radarChartOptions" :height="400" />
</div>
</v-card>
<v-container fluid>
<v-row dense>
<v-col
v-for="card in getCards"
:key="card.id"
cols="12"
:sm="card.flex"
xs="1"
>
<v-card>
<v-card-title class="title" v-text="card.title">
</v-card-title>
<p class="pa-4">Importance: {{ card.importance }} <br />
Effectiveness: {{ card.effectiveness }} </p>
</v-card>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script>
import { mapGetters } from "vuex"
import RadarChart from "~/components/RadarChart"
export default {
layout: "tabs",
components: {
RadarChart,
},
data() {
return {
radarChartOptions: {
responsive: true,
scales: {
yAxes: [
{
ticks: {
beginAtZero: true,
display: false,
min: 0,
max: 10,
},
gridLines: {
display: false,
},
scaleLabel: {
display: false,
}
}
],
xAxes: [
{
gridLines: {
display: false,
},
}
]
}
},
/* radarChartData: {
labels: [
"Personal Growth",
"Work",
"Leisure",
"Health",
"Community",
"Family",
"Parenting",
"Intimate",
"Social",
"Spirituality",
],
datasets: [
{
label: "Importance",
backgroundColor: 'rgb(54, 162, 235, 0.75)',
data: [9, 8, 8, 9, 4, 6, 2, 8, 9, 5],
},
{
label: "Effectiveness",
backgroundColor: 'rgb(75, 192, 192, 0.75)',
data: [7, 7, 7, 6, 3, 5, 10, 6, 7, 4],
},
]
} */
}
},
computed: {
...mapGetters("cards", ["getCards"]),
//...mapState(["getCards"]),
barChartData() {
return {
labels: ['Importance', 'Effectiveness'],
datasets: [
{
// backgroundColor: ["red", "orange", "yellow"],
backgroundColor: [chartColors.blue, chartColors.green],
data: [this.importance, this.effectiveness]
}
]
}
},
radarChartData() {
return {
labels: [
"Personal Growth",
"Work",
"Leisure",
"Health",
"Community",
"Family",
"Parenting",
"Intimate",
"Social",
"Spirituality",
],
datasets: [
{
label: "Importance",
backgroundColor: 'rgb(54, 162, 235, 0.75)',
data: [9, 8, 8, 9, 4, 6, 2, 8, 9, 5],
},
{
label: "Effectiveness",
backgroundColor: 'rgb(75, 192, 192, 0.75)',
data: [7, 7, 7, 6, 3, 5, 10, 6, 7, 4],
},
]
}
},
card() {
return this.getCards.find((el) => el.id === this.id)
},
effectiveness: {
get() {
return this.card.effectiveness
},
set(effectiveness) {
this.$store.commit("cards/updateEffectiveness", { card: this.card, effectiveness})
},
},
importance: {
get() {
return this.card.importance
},
set(importance) {
this.$store.commit("cards/updateImportance", { card: this.card, importance})
},
},
keywords: {
get() {
return this.card.keywords
},
set(keywords) {
this.$store.commit("cards/updateKeywords", { card: this.card, keywords})
}
}
},
/* computed: {
radarChartData() {
return {
labels: [
"Personal Growth",
"Work",
"Leisure",
"Health",
"Community",
"Family",
"Parenting",
"Intimate Relationships",
"Social",
"Spirituality",
],
datasets: [
{
// backgroundColor: ["red", "orange", "yellow"],
data: [9, 8, 8, 9, 4, 6, 2, 8, 9, 5],
}
]
}
},
}*/
}
</script>
below the radar chart is an array of cards that dynamically display the information that I also want to use for the radar chart. I can get the info to show for the cards, but not the radar chart.
I am guessing I am missing something really obvious, and I know I have to somehow reference the card.id, but I am not sure how to do that. I have tried a :key binding on the radar-chart tag but that throws an error of:
‘card’ is not defined
below is the array of store data in my store js file:
import createPersistedState from "vuex-persistedstate"
export const state = () => ({
cards: [
{
title: “Personal Growth”,
src: require("~/assets/images/values/growth.svg"),
flex: 6,
id: “1”,
keywords: [],
importance: “”,
effectiveness: “”,
},
{
title: “Leisure”,
src: require("~/assets/images/customize.svg"),
flex: 6,
id: “2”,
keywords: [],
importance: “”,
effectiveness: “”,
},
{
title: “Sprituality”,
src: require("~/assets/images/values/spirituality.svg"),
flex: 6,
id: “3”,
keywords: [],
importance: “”,
effectiveness: “”,
},
{
title: “Work”,
src: require("~/assets/images/values/work.svg"),
flex: 6,
id: “4”,
keywords: [],
importance: “”,
effectiveness: “”,
},
{
title: “Health”,
src: require("~/assets/images/values/health.svg"),
flex: 6,
id: “5”,
keywords: [],
importance: “”,
effectiveness: “”,
},
{
title: “Community \n& Environment”,
src: require("~/assets/images/values/community.svg"),
flex: 6,
id: “6”,
keywords: [],
importance: “”,
effectiveness: “”,
},
{
title: “Family Relationships”,
src: require("~/assets/images/values/family.svg"),
flex: 6,
id: “7”,
keywords: [],
importance: “”,
effectiveness: “”,
},
{
title: “Social Relationships”,
src: require("~/assets/images/values/social.svg"),
flex: 6,
id: “8”,
keywords: [],
importance: “”,
effectiveness: “”,
},
{
title: “Intimate Relationships”,
src: require("~/assets/images/values/intimate.svg"),
flex: 6,
id: “9”,
keywords: [],
importance: “”,
effectiveness: “”,
},
{
title: “Parenting”,
src: require("~/assets/images/values/parenting.svg"),
flex: 6,
id: “10”,
keywords: [],
importance: “”,
effectiveness: “”,
},
],
})
export const plugins = [createPersistedState()]
export const getters = {
getCards: (state) => {
return state.cards
},
}
export const mutations = {
updateEffectiveness(state, {card, effectiveness}) {
card.effectiveness = effectiveness
},
updateImportance(state, {card, importance}) {
card.importance = importance
},
updateKeywords(state, {card, keywords}) {
card.keywords = keywords
}
}
Any tips, advice are welcome and thanks for any help! :)
Screenshots of what the radar chart looks like with static data are attached.
You can use reactiveProp
and reactiveData
to make your chart reactive. See Updating Charts for more details.
For reactiveProp
, it just creates a prop named chartData
and adds a vue watch on this prop then call renderChart()
when this prop changed.
Example for RadarChart.vue:
<script>
import { Radar, mixins } from "vue-chartjs";
export default {
extends: Radar,
mixins: [mixins.reactiveProp],
props: ["options"],
mounted() {
this.renderChart(this.chartData, this.options);
}
};
</script>
And then use the component:
<radar-chart :chart-data="radarChartData" :options="radarChartOptions"/>
CodeSandbox Example