Using ChartJs in Vue3 /not vue-chartjs/ - javascript

I know vue-chartjs is not supported in Vue3. So I decided to do it using ChartJs itself.
I have a form containing radio button and calendar and passing it to the chart component.
I couldn't write it in methods and I wrote it in created.
Because of this when I change the form inputs my chart is not reacting. I tried watching the values of prop coming from my form and it's reactive.
Help me
Here's my TestGraph.vue component
<template>
<div class="param-container">
<h3>Params</h3>
<p> {{radioCalendarUrl.frequency}}, {{radioCalendarUrl.from}}, {{radioCalendarUrl.to}} </p>
<button #click="testMethod">Click</button>
</div>
<canvas id="test_chart" style="margin-left: auto; margin-right: auto; width: 80%; height: 600px;"/>
</template>
<script>
import { ref, computed, defineComponent, onMounted} from "vue";
export default {
name: 'Posts',
data() {
return{
}
},
computed: {
propsToUrl() {
return '/?frequency='+`${this.radioCalendarUrl.frequency}`+'&from='+`${this.radioCalendarUrl.from}`+'&to='+`${this.radioCalendarUrl.to}`
}
},
methods: {
testMethod() {
console.log(`${this.radioCalendarUrl.frequency}`)
console.log(`${this.radioCalendarUrl.from}`)
console.log(`${this.radioCalendarUrl.to}`)
console.log(this.propsToUrl)
},
},
watch: {
radioCalendarUrl: function(newVal, oldVal) { // watch it
console.log('Prop changed: ', newVal, ' | was: ', oldVal)
}
},
props: {
radioCalendarUrl: {
type: Object,
required: true
}
},
async created() {
const getData = (result) => {
return [result.map(function(e) {
return e.date;
}),
result.map(function(e) {
return e.desktop;
}),
result.map(function(e) {
return e.tablet;
}),
result.map(function(e) {
return e.mobile;
}),
result.map(function(e) {
return e.total;
})]
}
let url1 = "http://localhost:8085/all-page-view" + this.propsToUrl
const res1 = await fetch(url1)
const result_pv = await res1.json()
const res2 = await fetch("http://localhost:8085/uniq-user" + this.propsToUrl)
const result_uu = await res2.json()
console.log(url1)
console.log("DATA")
console.log(result_pv)
const [xlabels, pc_pv_data, tablet_pv_data, smartphone_pv_data, total_pv_data] = [...getData(result_pv)]
console.log([xlabels, pc_pv_data, tablet_pv_data, smartphone_pv_data, total_pv_data])
const [xlabels_useless, pc_uu_data, tablet_uu_data, smartphone_uu_data, total_uu_data] = [...getData(result_uu)]
// eslint-disable-next-line
//function createChart(){
var ctx = document.getElementById('test_chart');
//グラフ詳細
// eslint-disable-next-line
new Chart(ctx, {
type: 'bar',
data: {
datasets: [
//ページビュー
//PCページビュー
{
type: 'bar',
label: 'PCページビュー',
data: pc_pv_data,
order: 5,
backgroundColor: 'rgb(116,181,236)',
borderColor: 'rgb(116,181,236)',
barPercentage: 0.4
},
//タブレットページビュー
{
type: 'bar',
label: 'タブレットページビュー',
data: tablet_pv_data,
order: 6,
backgroundColor: 'rgb(244,192,121)',
borderColor: 'rgb(244,192,121)',
barPercentage: 0.4
},
// スマホページビュー
{
type: 'bar',
label: 'スマホページビュー',
data: smartphone_pv_data,
order: 7,
backgroundColor: 'rgb(255,191,227)',
borderColor: 'rgb(255,191,227)',
barPercentage: 0.4
},
//ページビュー合計
{
type: 'bar',
label: 'ページビュー合計',
data: total_pv_data,
order: 8,
backgroundColor: 'rgb(205,243,179)',
borderColor: 'rgb(205,243,179)',
barPercentage: 0.4
},
//UU
//PCUU
{
type: 'line',
label: 'PCUU',
data: pc_uu_data,
fill: false,
order: 1,
backgroundColor: 'rgb(59,128,186)',
borderColor: 'rgb(59,128,186)',
pointBorderWidth: 1,
pointHoverRadius: 10,
lineTension: 0,
pointStyle: 'rectRot'
},
//タブレットUU
{
type: 'line',
label: 'タブレットUU',
data: tablet_uu_data,
fill: false,
order: 2,
backgroundColor: 'rgb(247,129,42)',
borderColor: 'rgb(247,129,42)',
pointBorderWidth: 1,
pointHoverRadius: 10,
lineTension: 0,
pointStyle: 'triangle'
},
//スマホUU
{
type: 'line',
label: 'スマホUU',
data: smartphone_uu_data,
order: 3,
backgroundColor: 'rgb(183,111,151)',
borderColor: 'rgb(183,111,151)',
fill: false,
pointBorderWidth: 1,
pointHoverRadius: 10,
lineTension: 0,
pointStyle: 'rect'
},
//UU合計
{
type: 'line',
label: 'UU合計',
data: total_uu_data,
fill: false,
order: 4,
backgroundColor: 'rgb(142,177,110)',
borderColor: 'rgb(142,177,110)',
pointBorderWidth: 1,
pointHoverRadius: 10,
lineTension: 0,
pointStyle: 'circle'
}
],
labels: xlabels
},
options: {
responsive: false,
legend: {
position: 'bottom',
labels: {
fontColor: '#333',
usePointStyle: true,
fontSize: 12,
boxWidth: 40,
},
},
scales: {
yAxes: [{
scaleLabel: {
display: false,
labelString: 'ページビューとUU回数'
},
stacked: true,
ticks: {
suggestedMin: 100,
callback: function(value) {
return value + '回';
}
}
}],
xAxes: [{
stacked: true
}],
}
}
});
//}
},
mounted() {
},
}
</script>

Related

Chartjs Doughnut data given in seconds needs to show a formatted version on hover [duplicate]

I have the following snippet :
function updateGraph(type, chart){
$.ajax({
type: 'GET',
url: "https://api.npoint.io/2700899037d8e83d5318",
dataType: 'json',
context: document.body,
global: false,
async: true,
success: function(response) {
var count_result = response.labels;
if(count_result.length > 1){
chart.data.labels = response.labels;
chart.data.datasets[0].data = response.data;
chart.update();
}
}
});
}
var chartTooltip = {
borderWidth: 0.5,
bodySpacing: 10,
xPadding: 15,
yPadding: 15,
cornerRadius: 0.15,
displayColors: false,
callbacks: {
afterLabel: function(tooltipItem, data) {
return dataset.data[tooltipItem.index] + 'cm';
}
}
};
if (document.getElementById("chart_id")) {
var chart_id = document
.getElementById("chart_id")
.getContext("2d");
var chart = new Chart(chart_id, {
type: "line",
options: {
plugins: {
legend: {
display: false
},
datalabels: {
display: false
}
},
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
gridLines: {
display: true,
lineWidth: 1,
color: "rgba(0,0,0,0.1)",
drawBorder: false
},
ticks: {
beginAtZero: true,
stepSize: 5,
min: 50,
max: 70,
padding: 0
}
}],
xAxes: [{
type: 'time',
distribution: 'linear',
gridLines: {
display: false
}
}]
},
legend: {
display: false
},
tooltips: chartTooltip
},
data: {
datasets: [{
pointRadius: 4,
pointBorderWidth: 2,
pointHoverRadius: 5,
fill: true,
borderWidth: 2,
}]
}
});
}
updateGraph('1', chart)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.4.0/chart.min.js"></script>
<div class="chart-container chart">
<canvas style="padding: 25px;" id="chart_id"></canvas>
</div>
Expected output:
How can I add cm in the tooltip ?
I tried with :
callbacks: {
afterLabel: function(tooltipItem, data) {
return dataset.data[tooltipItem.index] + 'cm';
}
}
But there is no error and no result.
Changing the label behaviour is part of the configuration.
You can use the following option plugin to alter the tooltip text in Chart.js v3:
options: {
plugins: {
tooltip: {
callbacks: {
label: function(context) {
return context.parsed.y + ' cm';
}
}
}
}
}
For more information about the label callback, please check there documentation.
Fixed snippet:
function updateGraph(type, chart){
$.ajax({
type: 'GET',
url: "https://api.npoint.io/2700899037d8e83d5318",
dataType: 'json',
context: document.body,
global: false,
async: true,
success: function(response) {
var count_result = response.labels;
if(count_result.length > 1){
chart.data.labels = response.labels;
chart.data.datasets[0].data = response.data;
chart.update();
}
}
});
}
var chartTooltip = {
borderWidth: 0.5,
bodySpacing: 10,
xPadding: 15,
yPadding: 15,
cornerRadius: 0.15,
displayColors: false
};
if (document.getElementById("chart_id")) {
var chart_id = document
.getElementById("chart_id")
.getContext("2d");
var chart = new Chart(chart_id, {
type: "line",
options: {
plugins: {
legend: {
display: false
},
datalabels: {
display: false
},
tooltip: {
callbacks: {
label: function(context) {
return context.parsed.y + ' cm';
}
}
}
},
responsive: true,
maintainAspectRatio: false,
scales: {
yAxes: [{
gridLines: {
display: true,
lineWidth: 1,
color: "rgba(0,0,0,0.1)",
drawBorder: false
},
ticks: {
beginAtZero: true,
stepSize: 5,
min: 50,
max: 70,
padding: 0
}
}],
xAxes: [{
type: 'time',
distribution: 'linear',
gridLines: {
display: false
}
}]
},
legend: {
display: false
},
tooltips: chartTooltip
},
data: {
datasets: [{
pointRadius: 4,
pointBorderWidth: 2,
pointHoverRadius: 5,
fill: true,
borderWidth: 2,
}]
}
});
}
updateGraph('1', chart)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.4.0/chart.min.js"></script>
<div class="chart-container chart">
<canvas style="padding: 25px;" id="chart_id"></canvas>
</div>
you can do something like that
plugins: {
tooltip: {
callbacks: {
label:(value) => `${value?.parsed?.y || 0} days`
},
},
}

implementing horizontal bar chart

I am a noob in angular. I already have a bar-chart component and I am using that component in several places across the project. now I want to implement the horizontal bar chart by modifying that bar chart component but I am stuck at this point and not moving forward. there are no errors and below code implementing a normal bar chart. Thanks in advance
bar-chart component
dataCtx: any;
bar_chart: any;
#ViewChild('barChart') barChartRef: ElementRef;
#Input() data = [];
#Input() type: string;
#Input() hoverData: Array<string>;
#Input() yLabel: any;
#Input() xLabel: any;
#Input() label?: string;
#Input() barLabel?: string;
#Input() nameObj?: any;
#Input() showLabel: boolean;
#Input() charType: string;
color = [];
#Output() onSegClick = new EventEmitter<any>();
colors: Array<string> = ["rgba(98, 228, 98, 1)", "rgba(248, 227, 117, 1)", "rgba(250, 99,131, 1)", 'red', 'blue', 'violet', 'orange'];
constructor() { }
ngOnInit() {
}
ngAfterViewInit() {
this.renderChart();
}
ngOnChanges() {
if (this.barChartRef)
this.renderChart();
}
renderChart() {
let self = this;
this.dataCtx = this.barChartRef.nativeElement.getContext('2d');
let gradient_1 = this.dataCtx.createLinearGradient(0, 0, 0, 250);
gradient_1.addColorStop(0, ' #c4743e');
gradient_1.addColorStop(1, 'transparent');
let gradient_2 = this.dataCtx.createLinearGradient(0, 0, 0, 250);
gradient_2.addColorStop(0, 'beige');
gradient_2.addColorStop(1, 'transparent');
let gradient_3 = this.dataCtx.createLinearGradient(0, 0, 0, 250);
gradient_3.addColorStop(0, '#2f7ca7');
gradient_3.addColorStop(1, "transparent");
this.bar_chart = new Chart(this.dataCtx, {
type: this.charType || 'bar',
data: {
labels: this.nameObj.map(obj => obj.name),
datasets: this.setChartData()
},
options: {
legend: {
display: this.showLabel,
labels: {
padding: 20,
fontStyle: 'bold',
fontSize: 16,
}
},
title: {
display: this.label ? true : false,
text: this.label,
fontStyle: 'bold',
fontSize: 20,
},
showAllTooltips: true,
toolTips: {
mode: 'index',
intersect: true
},
scales: {
xAxes: [{
categoryPercentage: 0.65,
// barPercentage: 1.0,
// barThickness: 50,
maxBarThickness: 50,
display: true,
scaleLabel: {
display: true,
fontStyle: 'bold',
labelString: this.yLabel
},
ticks: {
autoSkip: false
},
gridLines: {
color: 'rgba(88, 88, 88, 0.35)',
lineWidth: 2.5
}
}],
yAxes: [{
// stacked: true,
display: true,
scaleLabel: {
display: true,
fontStyle: 'bold',
labelString: this.xLabel
},
ticks: {
min: 0,
max: 100,
},
gridLines: {
color: 'rgba(0, 78, 162, 0.5)',
lineWidth: 0.5
}
}]
},
responsive: true,
onClick: function (evt, arr) {
if (arr[0]) {
self.onSegClick.emit(arr[0]._index);
}
},
}
});
}
cohortProf(options) {
let cohortData = [{
data: this.data.map(coh => Math.floor(coh.proficiency * 100)),
backgroundColor: '#0080FF',
options
}]
return cohortData;
}
testData() {
let testData = [];
this.data.forEach((d, i) => {
let val = Math.floor(d.data * 100);
testData.push(val);
this.color.push('#' + (Math.random() * 0xFFFFFF << 0).toString(16));
// this.color.push('hsl('+ val +', 100%, 50%)')
});
return testData;
}
testProf(options) {
let testData = [{
data: this.testData(),
backgroundColor: this.color,
options
}]
return testData;
}
subjectProf(options) {
let subData = [];
let strat = this.hoverData;
this.data.filter((d, index) => { subData.push({ "data": d, "backgroundColor": this.colors[index], options, label: strat[index] }) });
return subData;
}
setChartData() {
let dataSet: any;
let fixed_options = {
borderColor: 'tranparent',
borderWidth: 2,
pointBorderColor: 'transparent',
pointBackgroundColor: 'transparent',
pointHoverBackgroundColor: "#fff",
pointHighlightFill: "#fff",
pointRadius: 3,
pointHitRadius: 20,
pointBorderWidth: 1,
};
switch (this.type) {
case 'test': {
dataSet = this.testProf(fixed_options);
break;
}
case 'cohort': {
dataSet = this.cohortProf(fixed_options);
break;
}
case 'grouped-chart': {
dataSet = this.subjectProf(fixed_options);
break;
}
case 'single-bar': {
dataSet = [{
data: this.data,
backgroundColor: this.colors,
label: 'Analytics'
}];
break;
}
default: {
break;
}
}
return dataSet;
}
}
reusing the same component to implement horizontal bar chart
horizantalChart = {
data:[[10,20],[30,40]]
}
<bar-chart [type]="'single-bar'" [hoverData]="['Experts Avg. Score', 'Others Avg. Score']" barLabel="Proficiency"
[data]="horizontalChart.data" [nameObj]="uploadAnalytics.analytics" yLabel="Quizzes" chartType="horizontalBar"
[xLabel]="'Average Upload Score'" [showLabel]="true" (onSegClick)="selectBar($event)"></bar-chart>
The output of the code looks like this
Inside the renderChart method of your bar-chart component, the chart is currently created as follows:
this.bar_chart = new Chart(this.dataCtx, {
type: 'bar',
...
This will always create a vertical bar chart. It should be rewritten as follows in order to consider the type provided by the #Input() decorator.
this.bar_chart = new Chart(this.dataCtx, {
type: this.type,
...
Probably this.bar_chart is then no longer an appropriate name and should be amended to avoid future misunderstandings.

How to make fixed width of column without ticks.min/max in chart.js?

I need to be able to set fixed column width.
For example, if i specified 50 pixels and canvas width is 500 pixels, Chart.JS render 10 columns and automatically setup ticks.min/max to 0 and 9.
I know about barThickness and barPercentage in bar-charts.
But i have line-chart. I know about maxTicksLimit but it's work only for 'linear' scale type (i have 'category' scale type). I found a solution. I use onResize callback and make some tricks (pick canvas width and divide it by column needed width then setup ticks.min/max). It's works but works bad because the result doesn't near expected width. And more problem if you have 500px canvas and 5 data items and you need 50px width of column. In this case Chart.JS will stretch columns by canvas width.
Clear example without my tricks.
const ITEMS_COUNT = 50;
const MIN = -5000;
const MAX = 8000;
const defaultDatasetOptions = {
pointRadius: 0,
pointHoverRadius: 0,
pointBorderWidth: 0,
pointHoverBorderWidth: 0,
pointHitRadius: 10,
borderWidth: 0
};
const data = {
labels: _.range(1, ITEMS_COUNT),
datasets: [
{
...defaultDatasetOptions,
label: 'Series 1',
data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)),
backgroundColor: 'rgba(255, 0, 0, .3)'
},
{
...defaultDatasetOptions,
label: 'Series 2',
data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)),
backgroundColor: 'rgba(0, 255, 0, .3)'
},
{
...defaultDatasetOptions,
label: 'Series 3',
data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)),
backgroundColor: 'rgba(0, 0, 255, .3)'
}
]
};
const options = {
legend: {
display: false
},
scales: {
xAxes: [
{
type: 'category',
gridLines: {
offsetGridLines: true,
color: 'orange',
tickMarkLength: 0,
drawBorder: false
},
ticks: {
display: false,
maxRotation: 0,
beginAtZero: true,
autoSkip: false,
stepSize: 1
},
offset: true
}
],
yAxes: [{ display: false }]
},
tooltips: {
mode: 'index',
intersect: false
},
hover: {
mode: 'index',
intersect: false
}
};
new Chart(document.querySelector('canvas'), {
type: 'line',
data,
options
});
canvas { border: 1px solid black; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<canvas></canvas>
Example with my solution.
const ITEMS_COUNT = 50;
const MIN = -5000;
const MAX = 8000;
const COLUMN_WIDTH = 50;
const defaultDatasetOptions = {
pointRadius: 0,
pointHoverRadius: 0,
pointBorderWidth: 0,
pointHoverBorderWidth: 0,
pointHitRadius: 10,
borderWidth: 0
};
const data = {
labels: _.range(1, ITEMS_COUNT + 1),
datasets: [
{
...defaultDatasetOptions,
label: 'Series 1',
data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)),
backgroundColor: 'rgba(255, 0, 0, .3)'
},
{
...defaultDatasetOptions,
label: 'Series 2',
data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)),
backgroundColor: 'rgba(0, 255, 0, .3)'
},
{
...defaultDatasetOptions,
label: 'Series 3',
data: Array.from(Array(ITEMS_COUNT), () => _.random(MIN, MAX)),
backgroundColor: 'rgba(0, 0, 255, .3)'
}
]
};
const options = {
onResize: setupTicksMinMax,
legend: {
display: false
},
scales: {
xAxes: [
{
type: 'category',
gridLines: {
offsetGridLines: true,
color: 'orange',
tickMarkLength: 0,
drawBorder: false
},
ticks: {
display: false,
maxRotation: 0,
beginAtZero: true,
autoSkip: false,
stepSize: 1
},
offset: true
}
],
yAxes: [{ display: false }]
},
tooltips: {
mode: 'index',
intersect: false
},
hover: {
mode: 'index',
intersect: false
}
};
const setupTicksMinMax = (chartInstance) => {
const xScale = chartInstance.scales['x-axis-0'];
xScale.options.ticks.min = chartInstance.data.labels[0];
xScale.options.ticks.max = chartInstance.data.labels[Math.ceil(chartInstance.canvas.width / COLUMN_WIDTH)];
chartInstance.update(0);
};
const chartInstance = new Chart(document.querySelector('canvas'), {
type: 'line',
data,
options
});
setupTicksMinMax(chartInstance);
canvas { border: 1px solid black; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<canvas></canvas>
If I've understood your question correctly then the below snippet achieves the result you want.
From two input parameters (width and count of points) it adjusts the right padding of the chart to keep the points at the specified width, regardless of whether there are too many or too few points to fill the width of the canvas.
For demonstration purposes you can change the input values and press the "Update" button to see the result.
let chart = new Chart(document.getElementById("chart"), {
type: "line",
data: {
datasets: [{
data: []
}]
},
options: {
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
xAxes: [{
type: 'category',
gridLines: {
offsetGridLines: true,
color: 'orange',
tickMarkLength: 0,
drawBorder: false
},
ticks: {
display: false,
maxRotation: 0,
beginAtZero: true,
autoSkip: false,
stepSize: 1
},
offset: true
}],
yAxes: [{
display: false
}]
}
},
plugins: [{
resize: function(chart) {
update(chart);
}
}]
});
function update(chart) {
let pointWidth = parseInt(document.getElementById("pw").value),
pointCount = parseInt(document.getElementById("pc").value),
width = chart.width - chart.chartArea.left,
points = Math.floor(width / pointWidth);
if (points > pointCount) {
points = pointCount;
}
chart.config.data.labels = _.range(1, points + 1);
chart.config.data.datasets[0].data = Array.from(Array(points), () => _.random(-5000, 8000));
chart.options.layout.padding.right = width - (pointWidth * points);
chart.update();
}
document.getElementById("update").addEventListener("click", function() {
update(chart);
});
canvas {
background-color: #f5f5f5
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<p>
Width: <input id="pw" type="text" value="50">px Count: <input id="pc" type="text" value="5"><button id="update">Update</button>
</p>
<canvas id="chart"></canvas>

Chartjs with multiple y axes and different scales

How can I use different scales in Y Axes with ChartJs?
I have this datasets:
[ 1450478,2645844,1840524,640057,1145844,1530500,1695844,1778654,1450478,1645844,1450478,1645844 ]
[ 3.14, 4.15, 3.09, 3.48, 4.05, 3.99, 4.39, 4.15, 4.10, 3.98, 3.54, 3.50 ]
https://jsfiddle.net/psycocandy/ad18Lc4u/18/
The smallest scale represented by the line is obviously very close to the scale of 0. How do I make this same line visible without having to filter by legend?
I found the problem, updated fiddle: https://jsfiddle.net/psycocandy/fwncq25a/14/
To set the correspondent ID in the dataset with the yAxes, the correct way is to use yAxisID:
var chartData = [
[1450478, 2645844, 1840524, 640057, 1145844, 1530500, 1695844, 1778654, 1450478, 1645844, 1450478, 1645844],
[3.14, 4.15, 3.09, 3.48, 4.05, 3.99, 4.39, 4.15, 4.10, 3.98, 3.54, 3.50]
];
var dataSet = {
labels: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho',
'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'
],
datasets: [{
type: 'line',
label: 'Preço Médio Mensal',
yAxisID: 'y-axis-0',
borderColor: '#17522f',
fill: false,
backgroundColor: '#17522f',
borderWidth: 3,
radius: 4,
hoverBorderWidth: 4,
rotate: 90,
data: chartData[1],
datalabels: {
display: true,
align: 'end',
anchor: 'end',
rotation: -90,
clamp: true,
clip: true,
color: '#17522f',
padding: 10,
formatter: function (value, context) {
return numeral(value).format('0,0.00');
},
font: {
weight: 'bold',
}
}
},{
type: 'bar',
label: 'Total Mensal',
yAxisID: 'y-axis-1',
backgroundColor: '#7579ef',
borderColor: '#171951',
borderWidth: 2,
data: chartData[0],
datalabels: {
display: true,
clamp: true,
anchor: 'start',
align: 'end',
offset: 10,
rotation: -90,
color: '#171951',
formatter: function (value, context) {
return numeral(value).format('0,0');
},
font: {
weight: 'bold',
}
}
}]
};
var chart = new Chart(document.getElementById('myChart'), {
type: 'bar',
data: dataSet,
options: {
title: {
display: false
},
tooltips: {
mode: 'label',
callbacks: {
label: function(tooltipItem, data) {
var value = parseFloat(tooltipItem.value);
var formatedValue;
if(tooltipItem.datasetIndex > 0){
formatedValue = numeral(value).format('$ 0,0.00');
}else{
formatedValue = numeral(value).format('$ 0,0.00');
}
return ' ' + formatedValue;
},
}
},
responsive: true,
scales: {
xAxes: [{
stacked: true
}],
yAxes: [{
stacked: true,
position: 'left',
type: 'linear',
scaleLabel: {
display: true,
},
id: 'y-axis-1',
ticks: {
beginAtZero:true,
callback: function (tick, index, ticks) {
return numeral(tick).format('(0,0)');
},
}
}, {
stacked: false,
position: 'right',
type: 'linear',
id: 'y-axis-0',
ticks: {
max: 10,
stepSize: 1,
display: true,
beginAtZero: true,
fontSize: 13,
padding: 10,
callback: function (tick, index, ticks) {
return numeral(tick).format('$ 0,0');
}
}
}]
}
}
});
In Chart.js 3, the syntax is slightly different. The axes are identified by their scaleId:
Namespace: options.scales[scaleId]
datasets: [
{
type: 'line',
yAxisID: 'y1',
},
{
type: 'line',
yAxisID: 'y2',
}
]
scales: {
x: {
stacked: false,
y1: {
position: 'left',
stacked: false,
},
y2: {
position: 'right',
stacked: false,
},
}
See the Charts.js axes documentation for more.

ChartJS makes unwanted horizontal line on Safari

I'm currently working with ChartJS.
It works fine on Firefox and Chrome.
On Safari there is horizontal lines which appear. (here there is one good on orange and two others unwanted )
I have a lot of datapoint (2 lines of 1600 data point). I don't know if it could be a cause.
My code is here.
In some other part, I update time uni and time min.
_displayChart: function(label1, label2){
var timeFormat = 'DD/MM/YYYY HH:mm';
var ctx = document.getElementById(this.heading).getContext('2d');
const data = {
// Labels should be Date objects
//labels:this._stats[1],
datasets: [{
fill: false,
label: label1,
data: this._stats[2],
borderColor: '#fe8b36',
pointRadius: 0,
backgroundColor: [
'#fe8b36'
]
},{
label: label2,
fill: false,
data: this._stats[3],
borderWidth: 1,
pointRadius: 0,
borderColor: 'rgba(99, 100, 200, 1)',
backgroundColor: [
'rgba(99, 100, 200, 0.2)'
]
}]
}
const options = {
type: 'line',
data: data,
options: {
responsive: false,
fill: false,
responsive: true,
maintainAspectRatio:!this._isMobile(),
max: this.max,
hover: {
// Overrides the global setting
mode: 'index'
},
annotation: {
drawTime: 'beforeDatasetsDraw',
events: ['click'],
annotations: []
},
legend: {
labels: {
filter: function(legendItem, chartData) {
if(legendItem.datasetIndex == 2 || legendItem.datasetIndex == 3 ){
return false;
}
return true;
}
}
},
tooltips: {
mode:'index',
intersect : false,
callbacks: {
title: function(tooltipItems, data) {
return tooltipItems[0].xLabel.format(timeFormat);
},
label: function(tooltipItems, data) {
return tooltipItems.yLabel+'%';
}
}
},
scales: {
xAxes: [{
type: 'time',
display: true,
time:{
unit:'day',
min:moment(Date.now()-this.monthTs),
max:this._stats[1][this._stats[1].length]
}
}],
yAxes: [{
ticks: {
beginAtZero: true,
},
display: true
}]
}
}
}
this._chart = new Chart(ctx, options);
},
When I'm applying this, I have no problem:
this._chart.options.scales.xAxes[0].time.unit = 'month';
this._chart.options.scales.xAxes[0].time.stepSize = 1;
this._chart.options.scales.xAxes[0].time.min = this._stats[1][0];
this._chart.options.scales.xAxes[0].time.max = this._stats[1][this._stats[1].length-1];
Thanks

Categories