I am trying render Pie chart via vue-chartjs library.
But I have several mistakes, and I can't understand, how to solve it..
<template>
<div>
<div class="page-title">
<h3>История записей</h3>
</div>
<div class="history-chart">
<canvas ref="canvas"></canvas>
</div>
<Loader v-if="loading" />
<p class="center" v-else-if="!records.length">Записей пока нет. <router-link to="/record"> Добавьте первую
</router-link>
</p>
<section v-else>
<HistoryTable :records="items" />
<Paginate v-model="page" :page-count="pageCount" :click-handler="pageChangeHandler" :prev-text="'Назад'"
:next-text="'Вперед'" :container-class="'pagination'" :page-class="'waves-effect'" />
</section>
</div>
</template>
<script>
import paginationMixin from '#/mixins/pagination.mixin';
import HistoryTable from '#/components/HistoryTable.vue';
import Loader from '#/components/app/Loader.vue';
import { Pie } from 'vue-chartjs'
export default {
name: 'history',
extends: Pie,
mixins: [paginationMixin],
data: () => ({
loading: true,
records: [],
}),
components: {
HistoryTable,
Loader
},
async mounted() {
this.records = await this.$store.dispatch("fetchRecords");
const categories = await this.$store.dispatch("fetchCategories");
this.setup(categories)
this.loading = false
},
methods: {
setup(categories) {
this.setupPagination(this.records.map(record => {
return {
...record,
categoryName: categories.find(c => c.id === record.categoryId).title,
typeClass: record.type === 'income' ? 'green' : 'red',
typeText: record.type === 'income' ? 'Доход' : 'Расход',
}
}))
this.renderChart({
labels: categories.map(c => c.title),
datasets: [{
label: 'Расходы по категориям',
data: categories.map(c => {
return this.records.reduce((total, r) => {
if (r.categoryId === c.id && r.type === 'outcome') {
total += +r.amount
}
return total
}, 0)
}),
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255, 99, 132, 1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
})
},
},
}
</script>
These errors appears when start project..
What kind of 'chartData' console want?
Why this.renderChart is not a function? I wrote that this is a function in methods.
What kind of 'in' operator I uses?
I solved the problem.
If downgrade version from v4 -> v3 for vuechartjs and chart js from v3 -> v2 all be all right.
Related
I wanna set double yAxis, so I wrote down the code like below
const data = {
labels: ['a', 'b', 'c', 'd', 'e'],
datasets: [
{
type: 'bar',
label: this.$t('numberOfBuilding'),
data: [100, 20, 30, 5, 5],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(255, 159, 64, 0.2)',
'rgba(255, 205, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(54, 162, 235, 0.2)'
],
borderColor: ['rgb(255, 99, 132)', 'rgb(255, 159, 64)', 'rgb(255, 205, 86)', 'rgb(75, 192, 192)', 'rgb(54, 162, 235)'],
borderWidth: 1,
yAxisId: 'y'
},
// {
// type: 'line',
// fill: true,
// label: this.$t('output') + '(' + this.$t('criteriaMonth') + ')',
// data: [200, 500, 600, 800, 1000],
// borderColor: 'rgba(255, 201, 14, 1)',
// backgroundColor: 'rgba(255, 201, 14, 0.5)',
// lineTension: 0.2,
// yAxisId: 'y1'
// },
{
type: 'line',
fill: true,
label: this.$t('output') + '(' + this.$t('sum') + ')',
data: [300, 100, 700, 249, 588],
borderColor: 'rgba(55, 201, 14, 1)',
backgroundColor: 'rgba(55, 201, 14, 0.5)',
lineTension: 0.2,
yAxisId: 'y1'
}
]
}
const config = {
type: 'scatter',
data: data,
options: {
scales: {
y: {
beginAtZero: true,
position: 'left'
},
y1: {
position: 'right',
grid: {
drawOnChartArea: false
}
}
}
}
}
but it doesn't work properly
yAxis which id is 'y1' is at left and datasets[0] which has 'y' as yAxisId presents with 'y1' axis
it seems like yAxisId doesn't connect well with their own datasets
See the below pictures
[result of above code]
(https://i.stack.imgur.com/0moGR.png)
but my another code is work well I don't know what different it is
here's my another code which works well
const data = {
labels: [
1 + this.$t('month'),
2 + this.$t('month'),
3 + this.$t('month'),
4 + this.$t('month'),
5 + this.$t('month'),
6 + this.$t('month'),
7 + this.$t('month'),
8 + this.$t('month'),
9 + this.$t('month'),
10 + this.$t('month'),
11 + this.$t('month'),
12 + this.$t('month')
],
datasets: [
{
type: 'bar',
label: this.$t('totalConsumption') + '(' + this.unit + ')',
data: this.consumptionData,
borderColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgba(255, 99, 132, 0.2)',
yAxisID: 'y'
},
{
type: 'line',
label: this.$t('temperatureAVG') + '(℃)',
data: this.temperatureData,
fill: false,
borderColor: 'rgb(54, 162, 235)',
yAxisID: 'y1'
}
]
}
const config = {
type: 'scatter',
data: data,
options: {
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
position: 'left'
},
y1: {
position: 'right',
grid: {
drawOnChartArea: false
}
}
}
}
}
In the first code, the option name is wrong. You are using yAxisId but the correct one is yAxisID (as in the second sample), id must be uppercase
I use vue3-chart-v2 in my Vue3 app.
I would like to put array instead of predefined numbers.
Can anybody help me?
This is my chart component:
<script>
import { defineComponent } from 'vue'
import { Line } from 'vue3-chart-v2'
export default defineComponent({
name: 'ChanceChart',
extends: Line,
props: {
chartData: {
type: Object,
required: true
},
chartOptions: {
type: Object,
required: false
},
},
mounted () {
this.renderChart(this.chartData, this.chartOptions)
}
})
</script>
And this is how it looks like in the app:
<template>
<Navigation />
<div>
<ChanceChart :chartData="state.chartData"/>
</div>
</template>
<script>
import ChanceChart from '../components/ChanceChart.vue';
export default {
components: {
ChanceChart
},
data() {
return {
enemysCards : [1610, 169, 168, 167, 330, 329, 328, 327, 326, 325, 324, 323, 1, 1610, 1600, 169, 168, 167, 1610, 1600, 169, 168, 167, 11],
state: {
chartData: {
datasets: [
{
label: "Enemy's Chance",
borderColor: '#1161ed',
data: [40, 20, 12, 39, 10, 40, 39, 80, 40, 20, 12, 41, 190]
},
{
label: 'My Chance',
borderColor: '#f87979',
color: '#fff',
data: [60,60,60,60,60,60,60,60,60,60,60,60, 60]
}
],
labels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13'],
},
chartOptions: {
responsive: true
}
}
}
}
For example i want to take the enemysCards array in the data and the enemysCards.lenght in the labels.
Use computed properties instead of data property :
export default {
components: {
ChanceChart
},
computed: {
chartData(){
return {
datasets: [
{
label: "Enemy's Chance",
borderColor: '#1161ed',
data: this.myFirstArray // <- here
},
{
label: 'My Chance',
borderColor: '#f87979',
color: '#fff',
data: this.mySecondArray // <- here
}
],
labels: this.ennemyCards.map((x, index) => index + 1) // here you can calculate your labels
},
chartOptions: {
responsive: true
}
}
}
data() {
return {
enemysCards : [1610, 169, 168, 167, 330, 329, 328, 327, 326, 325, 324, 323, 1, 1610, 1600, 169, 168, 167, 1610, 1600, 169, 168, 167, 11],
myFirstArray: [40, 20, 12, 39, 10, 40, 39, 80, 40, 20, 12, 41, 190],
mySecondArray: [40, 20, 12, 39, 10, 40, 39, 80, 40, 20, 12, 41, 190],
}
}
I have a bar chart in vue-charts where when clicked I want to display the background data in a table. This is the render
startPie: function(canvas, type){
let chart = new Chart(canvas, {
type: type,
data: {
labels: this.labels,
datasets: this.chart_data
},
options: {
responsive: true,
animation:{ animateScale:true },
title: { display: false },
legend: { display: false },
scales: {
yAxes: [{
gridLines: {
color: "#989898"
},
ticks: {
fontColor: "#989898",
fontSize: 16,
beginAtZero: true,
callback: function(value) {
let ranges = [
{ divider: 1e6, suffix: 'M' },
{ divider: 1e3, suffix: 'k' }
];
function formatNumber(n) {
for (let i = 0; i < ranges.length; i++) {
if (n >= ranges[i].divider) {
return (n / ranges[i].divider).toString() + ranges[i].suffix;
}
}
return n;
}
return '$' + formatNumber(value);
}
}
}],
xAxes: [{
ticks: {
fontColor: "#989898",
fontSize: 12
}
}]
},
plugins: {
datalabels: {
anchor: 'center',
font: {
size: 16,
weight: 'bold'
},
formatter: function(value, context) {
return '$' + Number(value).toLocaleString();
},
color: 'white'
}
},
'onClick':(evt, item) => {
console.log('CLICK', item[0]);
}
}
})
}
In the onClick Event in the console I can see the index
CLICK ChartElement {_chart: Chart, _datasetIndex: 0, _index: 4,
hidden: false, _xScale: ChartElement, …}
I can't access it though without an error. I have tried
item[0]._index, item[0]['_index'], item[0]['ChartElement']._index, item[0]['ChartElement']['_index']
Any help is appreciated.
Unfortunately, the onClick event handler is poorly documented. You could try to define the data in a separate variable outside of the chart configuration.
const data = [55, 68, 82, 48, 75, 45, 67];
Then, you can define the onClick event handler as follows:
options: {
...
onClick: (event, item) => {
const idx = chart.getElementAtEvent(event)[0]._index;
console.log(data[idx]);
}
}
const labels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"];
const data = [55, 68, 82, 48, 75, 45, 67];
let chart = new Chart(document.getElementById('myChart'), {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: "My First Dataset",
data: data,
backgroundColor: ["rgba(255, 99, 132, 0.2)", "rgba(255, 159, 64, 0.2)", "rgba(255, 205, 86, 0.2)", "rgba(75, 192, 192, 0.2)", "rgba(54, 162, 235, 0.2)", "rgba(153, 102, 255, 0.2)", "rgba(201, 203, 207, 0.2)"],
borderColor: ["rgb(255, 99, 132)", "rgb(255, 159, 64)", "rgb(255, 205, 86)", "rgb(75, 192, 192)", "rgb(54, 162, 235)", "rgb(153, 102, 255)", "rgb(201, 203, 207)"],
borderWidth: 1
}]
},
options: {
responsive: true,
title: {
display: false
},
legend: {
display: false
},
scales: {
yAxes: [{
gridLines: {
color: "#989898"
},
ticks: {
fontColor: "#989898",
fontSize: 16,
beginAtZero: true
}
}]
},
plugins: {
datalabels: {
anchor: 'center',
font: {
size: 16,
weight: 'bold'
},
formatter: function(value, context) {
return '$' + Number(value).toLocaleString();
},
color: 'white'
}
},
onClick: (evt, item) => {
const idx = chart.getElementAtEvent(event)[0]._index;
console.log(data[idx]);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>
<canvas id="myChart" height="80"></canvas>
I want to for loop the labels and data so I'll never use this again labels: [this.transaction_per_day[0].Day... and data: [this.transaction_per_day[0].Amount.... I just realized when the user transacts on the next day, the data will not show in the bar graph. The problem is when I change the index into i inside the bracket instead of 0,1,2,3. It only displays the first index which is the 0. Can somebody help regarding my problem? Here's my code
retrieveTransactionPerDay : function() {
var self = this
axios.post(this.urlRoot + this.api + "retrieve_transaction_per_day.php")
.then(response => {
console.log(response);
vm.transaction_per_day = response.data
for(var i = 0; i < this.transaction_per_day.length; i++) {
var ctxChart = self.$refs.myChart.getContext('2d')
var myChart = new Chart(ctxChart, {
type: 'bar',
data: {
labels: [this.transaction_per_day[0].Day, this.transaction_per_day[1].Day, this.transaction_per_day[2].Day, this.transaction_per_day[3].Day],
datasets: [{
label: 'Transaction per day',
data: [this.transaction_per_day[0].Amount, this.transaction_per_day[1].Amount, this.transaction_per_day[2].Amount, this.transaction_per_day[3].Amount],
backgroundColor: [
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(255, 99, 132, 1)'
],
borderColor: [
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(255, 99, 132, 1)'
],
borderWidth: 1
}]
},
options: {
title : {
display : true,
text : "TRANSACTION GRAPH",
fontFamily: "sans-serif",
fontSize: 18
},
}
});
}
}).catch(e => {
console.log(e)
});
},
You can remove the for loop and use Array.map to get the label and data
vm.transaction_per_day = response.data
var myChart = new Chart(ctxChart, {
type: 'bar',
data: {
labels: vm.transaction_per_day.map(item => item.Day),
datasets: [{
label: 'Transaction per day',
data: vm.transaction_per_day.map(item => item.Amount),
backgroundColor: [
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(255, 99, 132, 1)'
],
borderColor: [
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(255, 99, 132, 1)'
],
borderWidth: 1
}]
},
options: {
title: {
display: true,
text: "TRANSACTION GRAPH",
fontFamily: "sans-serif",
fontSize: 18
},
}
});
Hey guys I am currently using example code for vue-chartjs but when I'm trying to add options it does not allow me to add it for some reason. Maybe I am misplacing it, but I'm not sure.
Here is my source code.
// CommitChart.js
import { Bar } from 'vue-chartjs'
function getNum(){return Math.floor(Math.random() * 100);}
export default {
extends: Bar,
mounted () {
// Overwriting base render method with actual data.
this.renderChart({
labels: ['Yeah', 'What', 'Turnup'],
datasets: [
{
label: 'Skimp me',
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
],
data: [getNum(), getNum(), getNum()],
borderWidth: 1
}
],
// ATTEMPTING TO ADD OPTIONS.
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
})
}
}
Everything works but I cannot figure out why this is wrong. Thanks!
You can overwrite the default chart options. Just pass the options object as a second parameter to the render method.
Right now your options are within the first object passed in.