Annotations are not displayed in Chart.js - vue.js

I'm sorry for my poor English.
I'm trying to display a horizontal line in a graph using vue-chartjs and chartjs-plugin-annotation.
The graph appears and the options are applied, but the horizontal line does not appear because the settings in the annotation are not working.
If anyone knows how to fix this, please let me know.
The version and code is as follows
Chart.js v2.9.4
chartjs-plugin-annotation v0.5.7
Chart.js
import { Bar } from 'vue-chartjs'
import chartjsPluginAnnotation from 'chartjs-plugin-annotation'
export default {
extends: Bar,
props: ["chartData", "options"],
mounted() {
this.addPlugin(chartjsPluginAnnotation),
this.renderChart(this.chartData, this.options)
}
}
**Vue**
<template>
<Chart :chartData="chartItems" :options="chartOptions"/>
</template>
<script>
import Chart from './Chart.js'
export default {
components: {
Chart
},
data() {
return {
chartItems: {
labels: ["12月", "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月"],
datasets: [{
label: "月ごとの数",
data: [9500, 12000, 19000, 15000, 9500, 5000, 10000, 14000, 9500, 8000, 4500, 7000],
backgroundColor: 'lightblue'
}]
},
chartOptions: {
legend: {
display: false
},
scales: {
xAxes: [{
display: true,
gridLines: {
display:false
}
}],
yAxes: [{
display: true,
id: 'y-axis-0',
position: 'right',
ticks: {
beginAtZero: true,
maxTicksLimit: 5,
userCallback: (label, index, labels) => label.toLocaleString()
},
}]
},
annotation: {
annotations: [{
type: 'line',
id: 'hLine',
mode: 'horizontal',
scaleID: 'y-axis-0',
value: 9000,
borderWidth: 2,
borderColor: 'black'
}]
},
tooltips: {
enabled: false
},
animation: {
duration: 0
}
}
}
}
}
</script>

It seems like there might be problems with the annotations library in chartjs 2.9.4, try downgrading to 2.9.3
Git issue: https://github.com/chartjs/chartjs-plugin-annotation/issues/276

Related

Vue : Echart js how to export chart as image (Vuexy admin.)

I'm attempting to export the chart as a picture. I just joined eCharts. Can someone explain how the export button operates? I need to download charts as image.
Here's what I try : Do I have something wrong?
<template>
<b-card title="Data Science">
<app-echart-bar:option-data="option"/>
</b-card>
</template>
<script>
import { BCard } from 'bootstrap-vue'
import AppEchartBar from '#core/components/charts/echart/AppEchartBar.vue'
export default {
components: {
BCard,
AppEchartBar,
},
data() {
return {
option: {
toolbox: {
show: true,
orient: 'vertical',
left: 'right',
top: 'center',
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar', 'stack'] },
restore: { show: true },
saveAsImage: { show: true }
}
},
xAxis: [
{
type: 'category',
data: ['FB', 'IN', 'TW', 'YT',],
},
],
yAxis: [
{
type: 'value',
splitLine: { show: false },
},
],
grid: {
left: '40px',
right: '30px',
bottom: '30px',
},
series: [
{
name: 'Available',
type: 'bar',
barGap: 0,
emphasis: {
focus: 'series'
},
data: [22, 24, 20, 18]
},
{
name: 'Not Available',
type: 'bar',
barGap: 0,
emphasis: {
focus: 'series'
},
data: [12, 10, 14, 16]
},
],
},
}
},
}
</script>
Comp:
<template>
<e-charts
ref="line"
autoresize
:options="option"
theme="theme-color"
auto-resize/>
<script>
import ECharts from 'vue-echarts'
import 'echarts/lib/component/tooltip'
import 'echarts/lib/component/legend'
import 'echarts/lib/chart/bar'
import theme from './theme.json'
ECharts.registerTheme('theme-color', theme)
export default { components: {
ECharts,
}, props: {
optionData: {
type: Object,
default: null,
}, }, data() {
return {
option: {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
toolbox: {
show: true,
orient: 'vertical',
left: 'right',
top: 'center',
feature: {
mark: { show: true },
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar', 'stack'] },
restore: { show: true },
saveAsImage: { show: true }
}
},
legend: {
left: 0,
},
grid: this.optionData.grid,
xAxis: this.optionData.xAxis,
yAxis: this.optionData.yAxis,
series: this.optionData.series,
},
} }, }
</script>
The chart created by eCharts is shown below :
Can somebody assist me with adding a button or tell me whether I need to add a script to download an image.

Cannot change anything in chart options

I have a bar chart and I would like to change the font color, border width and some other tings, but it doesn't work. It is in my computed property. In the chartOptions I want to change the y axis min and max value but I don't know if it is correct. Can anyone help me?
Also I want to make a horizontal line in this bar chart. It is the "Enemy's Avarage" and now it is a constant. I set the type to line and now I have a dot in my chart.
This is my chart component:
<script>
import { defineComponent } from 'vue'
import { Bar } from 'vue3-chart-v2'
export default defineComponent({
name: 'ChanceChart',
extends: Bar,
props: {
chartData: {
type: Object,
required: true
},
chartOptions: {
type: Object,
required: false,
},
},
mounted () {
this.renderChart(this.chartData, this.chartOptions)
}
})
</script>
And this is my app:
<template>
<div id="chart">
<ChanceChart :chartData="chartData" :chartOptions="chartOptions" />
</div>
</template>
<script>
import Navigation from "../components/Navigation.vue";
import ChanceChart from "../components/ChanceChart.vue";
import PageLoader from "../components/PageLoader.vue";
export default {
components: {
ChanceChart,
},
computed: {
chartOptions() {
return {
options: {
scales: {
y: {
title: {
display: true,
text: 'Value'
},
min: 0,
max: 100,
ticks: {
stepSize: 10,
}
},
},
elements: {
point: {
radius: 0
},
line: {
borderWidth: 2
}
},
plugins: {
legend: {
labels: {
boxWidth: 0,
font: {
fontColor: "#fff",
color: "#fff"
},
},
},
},
}
}
},
chartData() {
return {
datasets: [
{
type: 'bar',
label: "Enemy's Chance",
borderColor: "#1161ed",
borderWidth: 2,
data: this.emnemyCardsFilled,
},
{
type: 'bar',
label: "My Chance",
borderColor: "#f87979",
borderWidth: 2,
data: this.myCardsFilled,
},
{
type: 'line',
label: "Enemy's Avarage",
borderColor: "rgb(238, 255, 0)",
borderWidth: 2,
data: [50],
},
],
}
},
},
You need to remove the options part in the computed chartOptions prop:
chartOptions() {
return {
scales: {
y: {
title: {
display: true,
text: 'Value'
},
min: 0,
max: 100,
ticks: {
stepSize: 10,
}
},
},
elements: {
point: {
radius: 0
},
line: {
borderWidth: 2
}
},
plugins: {
legend: {
labels: {
boxWidth: 0,
font: {
fontColor: "#fff",
color: "#fff"
},
},
},
},
}
},

How to create spacing between Charts and Legends in Chart.js

I'm sorry for my poor English.
I want to Create Spacing between Graphs and Legends in Chart.js.
I would appreciate it if you could help me.
The code is as follows.
ChartBox.vue
<template>
<Chart :chartData="chartItems" :options="chartOptions"/>
</template>
<script>
import Chart from './ChartBox/ChartBox.js'
export default {
components: {
Chart
},
data() {
return {
chartItems: {
labels: ["12月", "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月"],
datasets: [{
label: "月ごとの数",
data: [9500, 12000, 19000, 15000, 9500, 5000, 10000, 14000, 9500, 8000, 4500, 7000],
backgroundColor: 'lightblue'
}]
},
chartOptions: {
maintainAspectRatio: false,
scales: {
yAxes: [{
display: true,
position: 'right',
ticks: {
beginAtZero: true,
},
}]
}
}
}
}
}
</script>
ChartBox.js
import { Bar } from 'vue-chartjs'
export default {
extends: Bar,
props: ["chartData", "options"],
mounted() {
this.renderChart(this.chartData, this.options)
}
}
There is no built in way. What you can do is disable the legend and use the generateLabels function to get al the labels and make a custom legend https://www.chartjs.org/docs/latest/configuration/legend.html#legend-label-configuration

update vue chart-js y axis max value without re rendering entire chart

I am working on a project where I am implementing some charts from the Vue-Chartjs library. I need the Y-axis max value to change everytime the user changes the filters given. I Import an existing barchart from the vue-chartjs library. In the code there is a javascript file that has some defaults already, to set extra options I can use the extraOptions object as a prop to personalize each chart accordingly. Here is the default component:
import { Bar } from 'vue-chartjs'
import { hexToRGB } from "./utils";
import reactiveChartMixin from "./mixins/reactiveChart";
let defaultOptions = {
tooltips: {
tooltipFillColor: "rgba(0,0,0,0.5)",
tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
tooltipFontSize: 14,
tooltipFontStyle: "normal",
tooltipFontColor: "#fff",
tooltipTitleFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
tooltipTitleFontSize: 14,
tooltipTitleFontStyle: "bold",
tooltipTitleFontColor: "#fff",
tooltipYPadding: 6,
tooltipXPadding: 6,
tooltipCaretSize: 8,
tooltipCornerRadius: 6,
tooltipXOffset: 10,
},
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
fontColor: "#9f9f9f",
fontStyle: "bold",
beginAtZero: true,
display: false,
min: 0,
max: 100
},
gridLines: {
display: false,
drawBorder: false,
}
}],
xAxes: [{
gridLines: {
display: false,
drawBorder: false,
},
}],
}
};
export default {
name: 'BarChart',
extends: Bar,
mixins: [reactiveChartMixin],
props: {
labels: {
type: [Object, Array],
description: 'Chart labels. This is overridden when `data` is provided'
},
datasets: {
type: [Object, Array],
description: 'Chart datasets. This is overridden when `data` is provided'
},
data: {
type: [Object, Array],
description: 'Chart.js chart data (overrides all default data)'
},
color: {
type: String,
description: 'Chart color. This is overridden when `data` is provided'
},
extraOptions: {
type: Object,
description: 'Chart.js options'
},
title: {
type: String,
description: 'Chart title'
},
},
methods: {
assignChartData() {
let { gradientFill } = this.assignChartOptions(defaultOptions);
let color = this.color || this.fallBackColor;
return {
labels: this.labels || [],
datasets: this.datasets ? this.datasets : [{
label: this.title || '',
backgroundColor: gradientFill,
borderColor: color,
pointBorderColor: "#FFF",
pointBackgroundColor: color,
pointBorderWidth: 2,
pointHoverRadius: 4,
pointHoverBorderWidth: 1,
pointRadius: 4,
fill: true,
borderWidth: 1,
data: this.data || []
}]
}
},
assignChartOptions(initialConfig) {
let color = this.color || this.fallBackColor;
const ctx = document.getElementById(this.chartId).getContext('2d');
const gradientFill = ctx.createLinearGradient(0, 170, 0, 50);
gradientFill.addColorStop(0, "rgba(128, 182, 244, 0)");
gradientFill.addColorStop(1, hexToRGB(color, 0.6));
let extraOptions = this.extraOptions || {}
return {
...initialConfig,
...extraOptions,
gradientFill
};
}
},
mounted() {
this.chartData = this.assignChartData({});
this.options = this.assignChartOptions(defaultOptions);
this.renderChart(this.chartData, this.options, this.extraOptions);
}
}
I use this js file to import the bar chart inside a vue component like you see down below.
everytime the input of the form changes i need to re render the chart. I use the onInputChange() method to turn the boolean loaded to false and call the loadData() method.
Inside the loadData() method I make an axios request that gets me the right data every time. I also get the maximum value for my Y axis.
Then in the response I call on updateChart() so that I can update the data and the max value of the chart. then i turn the boolean loaded to true again so that my chart renders accordingly.
The problem with this approach is that the chart disappears completely for a split of a second. Before deciding to change the max Value of the Y axis I was able to update the data of my chart without having to use the v-if="loaded".
I need to find a solution where the chart re renders without it completely disappearing from the page. I know some suggested to use computed variables but i don't fully understand how it is supposed to work. Here is the component minus the form fields.
I guess in it's essence what I want is to update the Y axis max value without having to re render the entire chart.
<template>
<div>
<BarChart v-if="loaded" :labels="chartLabels"
:datasets="datasets"
:height="100"
:extraOptions="extraOptions"
>
</BarChart>
<br>
</div>
</template>
<script>
import BarChart from '../../components/Library/UIComponents/Charts/BarChart'
import Dropdown from "../../components/Library/UIComponents/Dropdown"
import GroupedMultiSelectWidget from "~/components/widgets/GroupedMultiSelectWidget"
import SelectWidget from "../../components/widgets/SelectWidget";
export default{
name: 'PopularChart',
components: {BarChart, Dropdown, SelectWidget, GroupedMultiSelectWidget},
data(){
return {
loaded:true,
form:{
day: 'Today',
workspace:'',
machine_family: [],
duration: [],
user_group: [],
dt_start:'',
dt_end:''
},
url: `/api/data_app/job_count_by_hour/`,
chart_data: [],
days: [ {day:"Today", id:"Today"},
{day:"Monday", id:"0"},
{day:"Tuesday",id:"1"},
{day:"Wednesday",id:"2"},
{day:"Thursday",id:"3"},
{day:"Friday",id:"4"},
{day:"Saturday",id:"5"},
{day:"sunday",id:"6"} ],
chartLabels: ["00u", "1u", "2u", "3u","4u","5u", "6u", "7u", "8u", "9u", "10u", "11u", "12u", "13u", "14u", "15u","16u", "17", "18u","19u","20u","21u","22u","23u"],
datasets: [],
maximumValue: '',
extraOptions:{}
}
},
methods: {
onInputChange() {
this.loaded = false
this.loadData()
},
async loadData() {
await this.$axios.get(`${this.url}?day=${this.form.day}&date_start=${this.form.dt_start}&date_end=${this.form.dt_end}&workspace=${this.form.workspace}&user_group=${this.form.user_group}&machine_family=${this.form.machine_family}`)
.then(response => {
this.updateChart(response.data.results,response.data.maximum)
this.loaded = true
})
},
updateChart(data,maxValue) {
this.datasets = [{
label: ["jobs %"],
backgroundColor:"#f93232",
data: data
},]
this.maximumValue = maxValue
this.extraOptions = {
tooltips: {
callbacks:{
label: function (tooltipItems,){
if (tooltipItems.value > ((50/100) * maxValue)){
return 'busy';
}else if (tooltipItems.value < ((30/ 100) * maxValue) ){
return ' not busy';
}else if ( tooltipItems.value < ((40/ 100) * maxValue )){
return 'kind of busy'
}
}
}
},
scales: {
yAxes: [{
gridLines: {
zeroLineColor: "transparent",
display: false,
drawBorder: false,
},
ticks: {
max: this.maximumValue,
display: true,
}
}],
xAxes: [{
gridLines: {
zeroLineColor: "transparent",
display: false,
drawBorder: false,
},
}],
},
}
},
},
mounted() {
this.loadData()
},
}
</script>
You can bind the chart to a variable in data(), initialize it with some defaults in mounted() and whenever you want to update the chart data, you use the Chart.js API.
An implementation could look something like this:
export default {
data() {
return {
chart: null
};
},
mounted() {
this.chart = new Chart(/* defaults */);
},
methods: {
updateChart(data) {
this.chart.data.datasets = data;
/* rest of the chart updating */
this.chart.update();
}
}
};

Why echarts are not showing on I.E-11 version

I had created a project using vuejs+Vue-CLI and integrated echarts in it. Echarts are working well in all browsers but when I open it in IE-11 version, page can't load and it shows following error:
[object Error]{description: "Expected ')'", message: "Expected ')'", name: "SyntaxError", number: -2146827282, stack: "SyntaxError...", Symbol()_n.kyufm4c0tec: undefined, Symbol()_p.kyufm4c0tec: undefined, Symbol()_q.kyufm4c0tec: undefined, Symbol()_r.kyufm4c0tec: undefined, Symbol(Lang fallback)_m.kyufm4c0tec: undefined, Symbol(util.promisify.custom)_o.kyufm4c0tec: undefined}
Here is my code:
<template>
<ECharts :options="pie" style="width:300px; height:260px">
</ECharts>
</template>
<script>
import ECharts from "vue-echarts/components/ECharts.vue";
import "echarts/lib/chart/pie";
import "echarts/lib/component/title";
export default {
components: {
ECharts
},
data() {
return {
pie: {
backgroundColor: "transparent",
tooltip: {
trigger: "item",
formatter: "{a} <br/>{b} : {c} ({d}%)"
},
series: [{
name: "Product Sales",
type: "pie",
radius: ["50%", "70%"],
avoidLabelOverlap: false,
data: [{
value: 1,
name: "Product A"
},
{
value: 2,
name: "Product B"
},
{
value: 3,
name: "Product C"
}
],
label: {
normal: {
show: false,
position: "center"
},
emphasis: {
show: true,
textStyle: {
fontSize: "20",
fontWeight: "bold"
}
}
},
labelLine: {
normal: {
show: false
}
}
}]
}
};
}
};
</script>
what's an issue in IE browser I also searched for the solution and tried it but did't get the result.
Versions:
echarts-4.1.0,
vue-echarts: 3.1.1
Any help will be appreciated! Thanks
The documentation of vue-echarts-v3 does not inform it, but you have to add the echarts on your webpack (or any other bundler you are using) configuration as well.
{
test: /\.js$/,
loader: 'babel-loader',
include: [
resolve('src'),
resolve('test'),
resolve('node_modules/vue-echarts-v3/src'), // Their suggestion https://www.npmjs.com/package/vue-echarts-v3
resolve('node_modules/echarts/lib'), // Not suggested, but required as well
]
},