Linechart.js
import { Line } from 'vue-chartjs'
export default {
extends: Line,
props:['chart']
mounted () {
this.renderChart({
labels: ['1','2','3','4','5','6','7'],
datasets: [
{
label: 'Data One',
backgroundColor: '#F64A32',
data: this.chart
}
]
}, {responsive: true, maintainAspectRatio: false})
}
}
I use the props to pass the data
example.vue
<template>
<line-chart :width="370" :height="246" :chart="chartdata"></line-chart>
</template>
<script>
import LineChart from './vue-chartjs/LineChart'
export default {
components: {
LineChart
},
},
data(){
return{
chartdata:[]
}
}
methods:{
getdata(){
this.chartdata=[10,20,30,40,50]
}
}
</script>
when I click the getdata() the chartdata I think it has been passed to the Linechart.js, But why the chart does not update? Still empty
If you want the data to change on the fly, you either need the reactiveMixin http://vue-chartjs.org/#/home?id=reactive-data
Or you have to trigger an chart update by yourself.
This is because, even Vue.js is reactive, Chart.js per se is not.
If you want to update your chart, simply add a watcher to your LineChart.js component and watch for changes in chart. And then call .update()
import { Line } from 'vue-chartjs'
export default {
extends: Line,
props:['chart']
watch: {
chart () {
this.$data._chart.update()
}
}
mounted () {
this.renderChart({
labels: ['1','2','3','4','5','6','7'],
datasets: [
{
label: 'Data One',
backgroundColor: '#F64A32',
data: this.chart
}
]
}, {responsive: true, maintainAspectRatio: false})
}
}
Related
I am trying to use vue-chartjs but implement it with composition api. Most examples are either in typescript which I am not familiar with or using options api. I am unable to get chartOptions to work. I am not sure if I should be removing the chart-options and just do options or if there is something else I am missing such as an import. I tried to import ChartOptions in the chart-js import statement but it draws an error. Any help on how to implement this would be very helpful. Thanks!
<template>
<Pie
:chart-options="chartOptions"
:chart-data="chartData"
:chart-id="chartId"
:dataset-id-key="datasetIdKey"
:plugins="plugins"
:css-classes="cssClasses"
:styles="styles"
:width="width"
:height="height"
/>
</template>
<script>
import {ref, defineComponent, onMounted} from 'vue'
import {Pie} from 'vue-chartjs'
import {Chart as ChartJS, Title, Tooltip, Legend, ArcElement, CategoryScale} from 'chart.js'
ChartJS.register(Title, Tooltip, Legend, ArcElement, CategoryScale)
export default defineComponent({
name: 'SectorPieChart',
components: { Pie },
props: {
chartId: {
type: String,
default: 'pie-chart'
},
datasetIdKey: {
type: String,
default: 'label'
},
width: {
type: Number,
default: 500
},
height: {
type: Number,
default: 500
},
cssClasses: {
default: '',
type: String
},
styles: {
type: Object,
default: () => {}
},
plugins: {
type: Object,
default: () => {}
}
},
setup() {
//stores
const portfolioStore = usePortfolioStore()
const {portfolio} = storeToRefs(portfolioStore)
//dataset
const chartData = ref({
labels: [ 'Basic Materials', 'Consumer Cyclical', 'Financial Services', 'Real Estate', 'Consumer Defensive', 'Healthcare', 'Utilities', 'Communication Services', 'Energy', 'Industrials', 'Technology'],
datasets: [
{
backgroundColor: ['#FF4A4A','#FFAC4A','#FFE9C9','#F9C87C','#F97432','#7a7979','#FFCC00','#FF9900','#86370e','#FFFF66','#ed9e67'],
data: [1,1,1,1,1,1,1,1,1,1,1]
},
{
backgroundColor: ['#FF4A4A','#FFAC4A','#FFE9C9','#F9C87C','#F97432','#7a7979','#FFCC00','#FF9900','#86370e','#FFFF66','#ed9e67'],
data: [1,1,1,1,1,1,1,1,1,1,1]
}
]
})
//chart options to change settings
const chartOptions = ref({
responsive: true,
maintainAspectRatio: true,
legend: {
display: false,
}
})
//methods
const loadData = () => {
}
//add on mount API request
onMounted(() => {
loadData()
})
return {
chartData, chartOptions, loadData
}
}
})
</script>
According to the vue-chartjs there is no ChartOptions object/function that you can import. You're just meant to create your own array of options and bind it to the :chart-options prop, exactly how you're doing already.
In order to properly set chart options you should follow the chart.js documentation. As the documentation there notes, the legend options are namespaced as options.plugins.legend, and includes boolean property display that can turn off the legend display. This means we should format our chart options like so:
const chartOptions = ref({
responsive: true,
maintainAspectRatio: true,
plugins: {
legend: {
display: false,
},
},
});
See codesandbox here.
I've added tooltips.backgroundColor in chartOptions but still doesn't work, so anyone can help me?
Here is my code
<template>
<Doughnut
:chart-options="chartOptions"
:chart-data="chartData"
:chart-id="'doughnut-chart'"
:styles="styles"
:width="width"
:height="height"
/>
</template>
<script lang="ts">
import { defineComponent, type PropType } from "vue";
import TypographyComponent from "#/core/ui/components/typography/Typography.component.vue";
import { Doughnut } from "vue-chartjs";
import {
Chart as ChartJS,
Title,
Tooltip,
Legend,
ArcElement,
CategoryScale,
type Plugin,
} from "chart.js";
ChartJS.register(Title, Tooltip, Legend, ArcElement, CategoryScale);
export default defineComponent({
name: "ProgressChartComponent",
components: { Doughnut, TypographyComponent },
props: {
width: {
type: Number,
default: 400,
},
height: {
type: Number,
default: 400,
},
styles: {
type: Object as PropType<Partial<CSSStyleDeclaration>>,
default: () => {},
},
chartData: {
type: Object,
required: false,
default: () => {},
},
},
setup() {
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
cutout: "64%",
tooltips: {
enabled: false,
backgroundColor: "#227799",
},
};
return {
chartOptions,
};
},
});
</script>
...
Guessing that you're using Chart.js v3, be aware that the tooltips are defined in the namespace options.plugins.tooltip but not options.tooltips as in your code. Therefore chartOptions needs to be changed as follows:
const chartOptions = {
responsive: true,
maintainAspectRatio: false,
cutout: "64%",
plugins: {
tooltip: {
backgroundColor: "#227799"
}
}
};
For further information, please consult Tooltip Configuration from the Chart.js documentation.
Im trying to display chart using chartjs by calling API, but unable to do so.
Here s my LineChart.vue:
<script>
import {Line, mixins} from 'vue-chartjs' // We specify what type of chart we want from vue-chartjs and the mixins module
const { reactiveProp } = mixins
export default { //We are extending the base chart class as mentioned above
extends: Line,
mixins: [reactiveProp],
data () {
return {
options: { //chart options
lineTension: 0,
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
yAxes: [
{
scaleLabel: {
display: false
},
ticks: {
beginAtZero: true,
// eslint-disable-next-line no-unused-vars
callback (value, index, values) {
return `${value }%`
}
}
}
],
xAxes: [
{
type: 'time',
time: {
unit: 'month'
},
scaleLabel: {
display: true,
labelString: ''
}
}
]
}
}
}
},
mounted () {
// this.chartData is created in the mixin
this.renderChart(this.chartData, this.options)
}
}
</script>
And here is my Home.vue where i have imported the LineChart:
<template>
<div class="chart">
<line-chart :chart-data="datacollection"></line-chart>
</div>
</template>
<script>
import LineChart from './LineChart'
import axios from 'axios'
import DateTime from 'luxon'
export default {
data () {
return {
date: {},
challenge: {},
datacollection: {}
}
},
component: {LineChart},
created() {
this.fillData()
},
mounted () {
this.fillData()
},
methods: {
fillData () {
axios.get('https://my_api_goes_here')
.then(response => {
const results = response.data
const dateresult = results.map(a => a.date)
const challengeresult = results.map(a => a.challenge)
this.date = dateresult
this.challenge = challengeresult
this.datacollection = {
labels: [this.date].map(labels => DateTime.fromMillis(labels * 1000).toFormat('MMM yyyy')),
datasets: [
{
data: [this.challenge],
label: 'Africa',
borderColor: '#7367F0'
}
]
}
})
.catch(error => {
console.log(error)
})
}
}
}
</script>
Dont know why the chart did not appear even though my other resources have been loaded from the API call, when i checked out my console, this is what error im getting:
TypeError: results.map is not a function
Please check out my logic and let me where the error is.
I am a beginner in Vue and I want to create a project that uses Chart.js. I am using Vuex and am having a trouble to generate the data into the component.
<script>
import{Line} from 'vue-chartjs';
import {mapGetters,mapActions} from 'vuex';
export default {
extends:Line,
data: () => ({
chartdata: {
labels: ['January', 'February'],
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: this.currentDeath
}
]
},
options: {
responsive: true,
maintainAspectRatio: false
}
}),
methods:{
...mapActions(["fetchData"]),
},
computed:{
...mapGetters(["currentDeath"])
},
created(){
this.fetchData()
},
mounted(){
const dates = this.
this.renderChart(this.chartData,this.options)
}
}
</script>
<style scoped>
</style>
It says on localhost that "currentDeath is undefined". However if I were to print it on screen it is populated with an array of data. Anyone knows how I can access its data?
I'm trying to make a stacked line chart using Vue-ChartJS but am having difficulties getting it to stack.
I tried adding the following into the fill data function but saw no change.
scales: {
yAxes: [{ stacked: true}]
}
I also tried creating a this.options entry but that didn't work either. The minimal reproducible code for the chart is as follows, any advice or help would be much appreciated!
## LineChart.js
import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins
export default {
extends: Line,
mixins: [reactiveProp],
props: ['options'],
mounted() {
this.renderChart(this.chartData, this.options)
}
}
## LineChart.vue
<template>
<div class="small">
<line-chart :chart-data="chartData"></line-chart>
<button #click="fillData()">Randomize</button>
</div>
</template>
<script>
import LineChart from '../store/LineChart.js'
export default {
components: {
LineChart
},
data() {
return {
chartData: null
}
},
mounted() {
this.fillData()
},
methods: {
fillData() {
this.chartData = {
labels: [this.getRandomInt(), this.getRandomInt()],
datasets: [
{
label: 'Data One',
backgroundColor: '#f87979',
data: [this.getRandomInt(), this.getRandomInt()]
},
{
label: 'Data Two',
backgroundColor: '#C23596',
data: [this.getRandomInt(), this.getRandomInt()]
}
]
}
},
getRandomInt() {
return Math.floor(Math.random() * (50 - 5 + 1)) + 5
}
}
}
</script>
<style>
.small {
max-width: 600px;
margin: 150px auto;
}
</style>
You need to pass scales in the options:
...
<div class="small">
<line-chart :chart-data="chartData" :options="options"></line-chart>
<button #click="fillData()">Randomize</button>
</div>
...
data() {
return {
chartData: null,
options: {
scales: {
yAxes: [
{
stacked: true
}
]
},
},
}
},