Chartjs display bug when pushing data to graph - javascript

My friend and I have a problem with chartjs. We created an app to track your financial status. We wanted to push data to the graph, but after the third entry, the graph only displays two data points, eventhough three points are created pushed to the graph. Here are screenshots and the code. Can you help us? Thanks.
Chartjs displays only the datapoint before
Console shows 400
var config = {
type: 'line',
data: {
labels: [],
datasets: [{
label: $('#idDropdownKonto option')['0'].innerText,
backgroundColor: 'rgb(0, 87, 255)',
borderColor: 'rgb(0, 87, 255)',
data: [],
fill: false
}, {
label: $('#idDropdownKonto option')['1'].innerText,
fill: false,
backgroundColor: 'rgb(0, 255, 133)',
borderColor: 'rgb(0, 255, 133)',
data: []
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Finanzr Chart'
},
tooltips: {
mode: 'index',
intersect: true
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Datum'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Kontostand'
}
}]
}
}
};
window.onload = function() {
var ctx = document.getElementById('myChart').getContext('2d');
window.myLine = new Chart(ctx, config);
console.log("------Store--------");
console.log(store.get('dataSchema'));
console.log("--------------");
if(myLine.data.datasets[0].data.length == 0) {
console.log("STORE DATA");
window.myLine.data.datasets[0].data.push(store.get('dataSchema'));
window.myLine.update();
}
};
function addDataGraph() {
let Betrag = $('#inputBetrag').val();
let Konto = $('#inputKonto').val();
let Beschreibung = $('#inputBeschreibung').val();
var betragArray = [Betrag];
var kontoArray = [Konto];
var beschreibungArray = [Beschreibung];
var dataPointArray = beschreibungArray.concat(kontoArray);
var sortDateArray = [aktuellesDatum].sort(dateFns.compareAsc);
var dateArray = [sortDateArray];
var ArrayLength0;
var ArrayLength1;
if(myLine.data.datasets[0].data.length == 0) {
console.log("Dataset not found");
myLine.data.datasets[0].data.push(Betrag);
store.set('dataSchema', Betrag);
} else {
console.log("--------------");
console.log(store.get('dataSchema'));
console.log("--------------");
//=> 50
console.log("Dataset found");
if(Konto === 'Postbank') {
console.log('Postbank');
var BetragBerechnen = JSON.parse(store.get('dataSchema')) + JSON.parse(Betrag);
console.log(BetragBerechnen);
myLine.data.datasets[0].data.push(BetragBerechnen);
// myLine.data.datasets[0].label = 'Postbank';
myLine.data.labels.push(dateArray);
store.set('dataSchema', BetragBerechnen);
}
}
myLine.update();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0/dist/Chart.min.js"></script>
<canvas id="myChart" width="400" height="150"></canvas>
<button type="button" class="bg-blue-500 hover:bg-blue-700 text-white rounded-full py-2 px-4 m-2" onclick="addDataGraph()" name="button">Update Graph</button>

app.compontent.html
<canvas id="line-chart" style="width: 100%; height:250px;"></canvas>
app.component.ts
import { Chart } from 'chart.js';
chart: any = '';
ngOnInit() {
this.chart = new Chart('line-chart', {
type: 'line',
data: {
labels: ["JAN 05", "JAN 06", "JAN 07", "JAN 08", "JAN 10", "JAN 12", "JAN 15", "JAN 20", "JAN 21", "JAN 22", "JAN 23", "JAN 24"],
datasets: [
{
data: [10, 12, 15, 12, 18, 12, 10, 12, 17, 12, 12, 20],
label: "Africa",
borderColor: "#3e95cd",
fill: false
}
]
},
options: {
scales: {
yAxes: [{
display: false //this will remove all the x-axis grid lines
}],
xAxes: [{
gridLines: {
display: false
}
}]
},
legend: {
display: false
},
tooltips: {
callbacks: {
label: function (tooltipItem) {
console.log(tooltipItem)
return tooltipItem.yLabel;
}
}
}
}
});
}

Related

Chart.js timeline [Group for single bar]

I would like to create a time line like this:
[1]: https://i.stack.imgur.com/RQ819.png
But I don't understand how to put green into the top bar and yellow into the bottom bar.
This is what I got so far but I don't find anything how to make group only for one bar.
// Set Up
const labels = ["ONLINE", "IDLE"];
const data = {
labels: labels,
datasets: [
{
label: "ONLINE",
data: [
["2022-01-01", "2022-01-02"],
["2022-01-03", "2022-01-04"],
],
backgroundColor: ["green"],
},
{
label: "IDLE",
data: [
["2022-01-02", "2022-01-03"],
["2022-01-04", "2022-01-05"],
],
backgroundColor: ["orange"],
},
],
};
// Config
const config = {
type: "bar",
data: data,
options: {
responsive: true,
indexAxis: "y",
scales: {
xAxis: {
min: "2022-01-01",
type: "time",
time: {
unit: "day",
},
ticks: {
display: false,
},
},
yAxes: {
stacked: true,
beginAtZero: true,
},
},
},
};
// Render Chart
const myChart = new Chart(document.getElementById("myChart"), config);
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
<div>
<canvas id="myChart"></canvas>
</div>
You need to define a separate datasets for each floating bar.
Please take a look at your amended code and see how it works.
const data = {
labels: ["ONLINE", "IDLE"],
datasets: [{
label: "Jan 1 - Jan 2",
data: [["2022-01-01", "2022-01-02"],],
backgroundColor: "green"
},
{
label: "Jan 2 - Jan 3",
data: [,["2022-01-02", "2022-01-03"]],
backgroundColor: "orange"
},
{
label: "Jan 3 - Jan 4",
data: [["2022-01-03", "2022-01-04"],],
backgroundColor: "green"
},
{
label: "Jan 4 - Jan 5",
data: [,["2022-01-04", "2022-01-05"]],
backgroundColor: "orange"
}
]
};
const config = {
type: "bar",
data: data,
options: {
responsive: true,
indexAxis: "y",
scales: {
x: {
min: "2022-01-01",
type: "time",
time: {
unit: "day"
}
},
y: {
stacked: true
}
}
}
};
const myChart = new Chart("myChart", config);
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js/dist/chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
<div>
<canvas id="myChart"></canvas>
</div>

Handle Date Gaps in Chart JS

I am plotting a graph using chart js. I have a couple of inconsistent data. For instance, the example data I have shared starts with 1909 and the next is 1960. In other cases, they are properly displayed: 1980, 1981, 1982...
Is there a way for me to handle specific data with gaps? For instance, have the year displayed sequentially.
const ctx = canvas.getContext("2d");
const myChart = new Chart(ctx, {
type: "line",
data: {
labels: labels,
datasets: [{
label: "Country Population",
data: data,
}, ],
},
options: {
scales: {
x: {
title: {
display: true,
text: "Year",
},
xAxes: [{
type: 'time',
time: {
unit: 'year'
}
}]
},
y: {
title: {
display: true,
text: "Population",
},
},
},
},
});
How library you are using time and chart? I use chart(v3.8) and luxon(time) seems to work
const exampleData = [{
"x": +new Date('1909'),
"y": 48900202
},
{
"x": +new Date('1960'),
"y": 889030
},
{
"x": +new Date('1961'),
"y": 890203
},
{
"x": +new Date('1983'),
"y": 8904
},
]
const chartCfg = {
type: 'line',
data: {
datasets: [{
borderColor: 'green',
backgroundColor: 'green',
borderWidth: 1,
pointStyle: 'cross',
data: exampleData,
label: 'example',
}, ],
},
options: {
maintainAspectRatio: false,
animation: false,
parsing: false,
interaction: {
mode: 'index',
},
scales: {
x: {
type: 'time',
time: {
displayFormats: {
year: 'yyyy',
},
},
},
},
},
};
const chartCtx = document.getElementById('chart').getContext('2d');
const chart = new Chart(chartCtx, chartCfg);
chart.canvas.parentNode.style.height = '300px';
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.4.0/luxon.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-adapter-luxon/1.1.0/chartjs-adapter-luxon.min.js"></script>
<canvas id="chart""></canvas>

How to show thousand in k format for bar values in chart.js

I have many bars with a thousand values like 35000, 12000, and 76560. So these values are getting overlapped with each other. I need to change Bar values not StepSize.
I want to show these values 35k, 12k and 76.5k format. This is my code
public barStatus() {
var colors = ['#299DFF', '#80FFFF', '#F8362B', ];
var chBar = document.getElementById("chBar");
var chartData = {
datasets: [{
label: 'Success',
data: [35000, 12000, 76560],
backgroundColor: colors[0]
}, ]
}
var barOptions_stacked = {
onClick: this.Status,
tooltips: {
enabled: true
},
plugins: {
datalabels: {
anchor: 'end',
align: 'left',
formatter: Math.round,
font: {
color: 'black'
}
},
},
hover: {
animationDuration: 0
},
scales: {
xAxes: [{
barPercentage: 0.5,
categoryPercentage: 0.5
}
],
yAxes: [{
gridLines: {
display: false
},
type: 'logarithmic',
position: 'left',
ticks: {
min: 0, //minimum tick
max: 100000, //maximum tick
callback: function (value, index, values) {
return Number(value.toString()); //pass tick values as a string into Number function
}
},
afterBuildTicks: function (chartObj) { //Build ticks labelling as per your need
chartObj.ticks = [];
chartObj.ticks.push(0);
chartObj.ticks.push(10);
chartObj.ticks.push(100);
chartObj.ticks.push(1000);
chartObj.ticks.push(10000);
chartObj.ticks.push(100000);
},
scaleLabel: {
display: false
},
stacked: false
}]
},
};
this.Canvas = document.getElementById("chBar");
this.chart = new Chart(this.Canvas, {
type: "bar",
data: chartData,
options: barOptions_stacked
});
}
How can I do that?
Screenshot:
You need to pass a function in formatter option inside datalabels plugin configuration:
datalabels: {
anchor: "end",
align: "left",
formatter: function(context) {
return context / 1000 + "k";
},
font: {
color: "black"
}
}
You can check the solution in this demo: https://stackblitz.com/edit/angular-chart-js-thousand?file=src/app/app.component.ts
For styling only the labels you want something like this:
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: "line",
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: "# of Votes",
data: [12000, 1900, 3000, 5000, 2201, 3492]
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
setTimeout(function() {
myChart.options.scales = {
xAxes: [],
yAxes: [{
gridLines: {
display: false
},
type: 'logarithmic',
position: 'left',
ticks: {
min: 0, //minimum tick
max: 100000, //maximum tick
callback: function(value, index, values) {
return Number((value / 1000).toString()) + 'K'; //pass tick values as a string into Number function
}
},
afterBuildTicks: function(chartObj) { //Build ticks labelling as per your need
chartObj.ticks = [];
chartObj.ticks.push(0);
chartObj.ticks.push(10);
chartObj.ticks.push(100);
chartObj.ticks.push(1000);
chartObj.ticks.push(10000);
chartObj.ticks.push(100000);
},
scaleLabel: {
display: false
}
}]
};
myChart.update();
}, 1000);
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://npmcdn.com/chart.js#latest/dist/Chart.bundle.js"></script>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
In case you want to change the format of the value shown when hovering the chart and displaying the value inside the tooltip, you need to use the tooltip callbacks.
For example:
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: "line",
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [
{
label: "# of Votes",
data: [12000, 1900, 3000, 5000, 2201, 3492]
}
]
},
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
return (tooltipItem.yLabel/1000)+'K';
}
}
},
scales: {
yAxes: [
{
ticks: {
beginAtZero: true
}
}
]
}
}
});
setTimeout(function() {
myChart.options.scales = {
xAxes: [],
yAxes: [ {
gridLines: {
display: false
},
type: 'logarithmic',
position: 'left',
ticks: {
min: 0, //minimum tick
max: 100000, //maximum tick
callback: function (value, index, values) {
return Number((value/1000).toString())+'K'; //pass tick values as a string into Number function
}
},
afterBuildTicks: function (chartObj) { //Build ticks labelling as per your need
chartObj.ticks = [];
chartObj.ticks.push(0);
chartObj.ticks.push(10);
chartObj.ticks.push(100);
chartObj.ticks.push(1000);
chartObj.ticks.push(10000);
chartObj.ticks.push(100000);
},
scaleLabel: {
display: false
}
}
]
};
myChart.update();
}, 1000);
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://npmcdn.com/chart.js#latest/dist/Chart.bundle.js"></script>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
Last example involves the plugin you use in your question.
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: "line",
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
datalabels: {
color: '#000'
},
label: "# of Votes",
data: [12000, 1900, 3000, 5000, 2201, 3492]
}]
},
options: {
plugins: {
datalabels: {
color: '#000',
formatter: function(value, context) {
return context.chart.data.labels[context.dataIndex] + ': ' + Math.round(value / 1000) + 'K';
}
}
},
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
return (tooltipItem.yLabel / 1000) + 'K';
}
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
setTimeout(function() {
myChart.options.scales = {
xAxes: [],
yAxes: [{
gridLines: {
display: false
},
type: 'logarithmic',
position: 'left',
ticks: {
min: 0, //minimum tick
max: 100000, //maximum tick
callback: function(value, index, values) {
return Number((value / 1000).toString()) + 'K'; //pass tick values as a string into Number function
}
},
afterBuildTicks: function(chartObj) { //Build ticks labelling as per your need
chartObj.ticks = [];
chartObj.ticks.push(0);
chartObj.ticks.push(10);
chartObj.ticks.push(100);
chartObj.ticks.push(1000);
chartObj.ticks.push(10000);
chartObj.ticks.push(100000);
},
scaleLabel: {
display: false
}
}]
};
myChart.update();
}, 1000);
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://npmcdn.com/chart.js#latest/dist/Chart.bundle.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels"></script>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"></canvas>
</div>
I have found the solution (just now). In config option its will have animation and call back with function onComplete. Here you can draw the label with any format you want. Please see this picture for code

Change Vertical Line and Color bar chart in bar chart.js

help me !
how to delete numeric data on the bar chart in bar chartjs
let datas_1 = [97,70,87,43,35,18];
let colorHex_1 = ['#ebeef3','#ebeef3','#ebeef3','#ebeef3','#ebeef3','#ebeef3'];
let labels_1 = ['10대','12대','30대','40대','50대','60대이상'];
var myBarChart = new Chart(ctx_1, {
type: 'horizontalBar',
data: {
datasets: [{
data: datas_1 ,
backgroundColor: colorHex_1,
borderWidth: 0,
barPercentage: 1,
}],
labels: labels_1,
},
options: {
responsive: true,
legend: {
display:false,
},
scales: {
xAxes: [{
display:false,
}],
yAxes: [{
gridLines:{
display:false,
color: "black"
},
maxBarThickness: 20,
}]
}
}
});
how to delete numeric data on the bar chart in bar chart.js
Working Demo: https://jsfiddle.net/usmanmunir/hz3gLj19/3/
Try this code:
let datas_1 = [97,70,87,43,35,18];
let colorHex_1 = ['#ebeef3', '#ebeef3', '#ebeef3', '#ebeef3', '#ebeef3', '#ebeef3'];
let labels_1 = ['10대', '12대', '30대', '40대', '50대', '60대이상'];
var ctx = document.getElementById("myChart");
var myBarChart = new Chart(ctx, {
type: 'horizontalBar',
data: {
datasets: [{
data: datas_1,
backgroundColor: colorHex_1,
borderWidth: 0,
barPercentage: 1,
}],
labels: labels_1,
},
options: {
responsive: true,
legend: {
display: false,
},
scales: {
xAxes: [{
display: false,
}],
yAxes: [{
gridLines: {
display: false,
},
maxBarThickness: 20,
}]
}
}
});
Hope this helps.

chart.js v2: Align time scale labels with the center of the bars

I am trying to align the generated time scale labels using Chart.js v2.2 with the centre of the bars of a bar chart. I have tried the offsetGridLines option but this seems to have no effect when using Xaxis scale type time.
Here is an example, maybe I have missed something:
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var barChartData = {
labels: ["2015-01-01", "2015-02-01", "2015-03-01", "2015-04-01", "2015-05-01", "2015-07-01"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [10, 4, 5, 7, 2, 3]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
}
,
scales: {
xAxes: [{
categoryPercentage: .5,
barPercentage: 1,
type: 'time',
scaleLabel: {
display: true,
labelString: 'Year-Month'
},
time: {
min: '2014-12-01' ,
max: '2015-12-01',
unit: 'month',
displayFormats: {
month: "MMM YY"
}
},
gridLines: {
offsetGridLines: false,
drawTicks: true,
display: true
},
stacked: true
}],
yAxes: [{
ticks: {
beginAtZero: true
},
stacked: true
}]
}
}
});
};
</script>
This fiddle may help to place the data label in the center of the bar
https://jsfiddle.net/tea8dhgy/
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
var barChartData = {
labels: ["2015-01-01", "2015-02-01", "2015-03-01", "2015-04-01", "2015-05-01", "2015-07-01"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [10, 4, 5, 7, 2, 3]
}]
};
var ctx = document.getElementById("canvas").getContext("2d");
new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
},
scales: {
xAxes: [{
categoryPercentage: .5,
barPercentage: 1,
type: 'time',
scaleLabel: {
display: true,
labelString: 'Year-Month'
},
time: {
// min: '2014-12-01' ,
// max: '2015-12-01',
unit: 'month',
displayFormats: {
month: "MMM YY"
}
},
gridLines: {
offsetGridLines: false,
drawTicks: true,
display: true
},
stacked: true
}],
yAxes: [{
ticks: {
beginAtZero: true
},
stacked: true
}]
},
animation: {
onComplete: function() {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(10, "bold", Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'center';
this.data.datasets.forEach(function(dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function(bar, index) {
//var data = dataset.data[index];
var data = dataset.data[index];
console.log(bar);
if (data > 0) {
ctx.fillText(data, bar._model.x, bar._model.base - (bar._model.base - bar._model.y) / 2 - 5);
}
});
});
}
}
}
});
I was able to get a working chart by removing the min and max values set.
Here is the JSFiddle
Was the following image the desired outcome?

Categories