Skip dates with no values in chart js - javascript

I would like to exclude the dates on the x-axis that has no values. Below is the image of my chart.
What my chart currently looks like
Here is also my current code for the options in chart js
var options = {
responsive: true,
maintainAspectRatio: false,
elements: {
line: {
fill: false
}
},
style: {
strokewidth: 10
},
title: {
display: true,
position: 'top',
fontSize: 18,
padding: 20
},
scales: {
xAxes:[{
ticks: {
z: 0,
autoskip: false,
callback: function(value, index, values){
return new moment(value).format('L');
}
},
type: 'time',
time: {
unit: 'week'
},
scaleLabel: { display: true,
labelString: 'Date'}
}],
yAxes: [{
ticks: { beginAtZero:true ,
min: 0,
max: 5 } ,
scaleLabel: { display: true,
labelString: 'Skill Rating'}
}]
}
};
I hope you guys can help me. Thanks!

When you pass your series/data to your chart, filter it
let data = [...];
data = data.filter(v => v[0] && v[1]);

Related

Approach to display graphical data on Home page

I have this design which I need to implement in our web application.
[Design Page] (https://i.stack.imgur.com/zW7v3.png)
Our application stack is c#, .Net MVC, JS, html, CSS
Anyone please provides your expertise how should I proceed with this?
Can I use any JS library to build bar chart?
However, data which will show will be dynamic, it changes based on USER.
Really appreciate your suggestion and advice.
I have tried with ChartJs library and able to create barchart in required format
[Using Chart JS bar chart design] (https://i.stack.imgur.com/YetMo.png)
to User Chart JS, I have create lots of Canvas + all canvas will need its own script.
<!DOCTYPE html>
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<body>
<div style="display:flex;" id="test">
<canvas id="myChart3" style="width:100%;max-width:50px;height:110px;"></canvas>
<canvas id="myChart" style="width:100%;max-width:100px;height:110px;"></canvas>
<canvas id="myChart2" style="width:100%;max-width:100px;height:110px;"></canvas>
</div>
<script>
var xValues = ["2021", "2022"];
var yValues = [1, 2.5];
var barColors = ["red", "green","blue","orange","brown"];
new Chart("myChart3", {
type: "bar",
options: {
maintainAspectRatio: false,
legend: {display: false},
scales: {
xAxes: [{
display: true,
gridLines: {
display: false,
drawBorder:false,
},
labels: {
show: true,
}
}],
yAxes: [{
type: "linear",
display: true,
position: "left",
id: "y-axis-1",
gridLines: {
display: true,
drawborder:false,
},
labels: {
show: true,
},
ticks: {
beginAtZero: true,
userCallback: function(label, index, labels) {
if (Math.floor(label) === label) {
return label;
}
},
max: 5.5,
stepSize: 1
}
}]
},
}
});
new Chart("myChart", {
type: "bar",
data: {
labels: xValues,
datasets: [{
backgroundColor: barColors,
data: yValues
}]
},
options: {
maintainAspectRatio: false,
legend: {display: false},
scales: {
xAxes: [{
display: true,
gridLines: {
display: false
},
labels: {
show: true,
}
}],
yAxes: [{
type: "linear",
display: true,
position: "left",
id: "y-axis-1",
gridLines: {
display: true,
drawBorder:false,
},
labels: {
show: true,
},
ticks: {
display:false,
beginAtZero: true,
userCallback: function(label, index, labels) {
if (Math.floor(label) === label) {
return label;
}
},
max: 5.5,
stepSize: 1
}
}]
},
}
});
new Chart("myChart2", {
type: "bar",
data: {
labels: xValues,
datasets: [{
backgroundColor: barColors,
data: [3, 3.5]
}]
},
options: {
maintainAspectRatio: false,
legend: {display: false},
scales: {
xAxes: [{
display: true,
gridLines: {
display: false
},
labels: {
show: true,
}
}],
yAxes: [{
type: "linear",
display: true,
position: "left",
id: "y-axis-1",
gridLines: {
display: true,
drawBorder: false,
},
labels: {
show: true,
},
ticks: {
display:false,
beginAtZero: true,
userCallback: function(label, index, labels) {
if (Math.floor(label) === label) {
return label;
}
},
max: 5.5,
stepSize: 1
}
}]
},
}
});
</script>
</body>
</html>
this is just for three canvas, I will have more than 100 data which needs to be display.
Any better approach which I can follow to make it proper and faster also.
Thanks and Regards,
Ankit

Chartjs Timestamp to Datetime labels

I'm using a timestamp format to create my scatter chart (datetime won't work for scatter). I need help changing the labels in the X axis from timestamp to datetime so that it's readable by users. Just the axis labels, not the actual timestamp values inserted to the chart.
let ctx = (<HTMLCanvasElement>(
document.getElementById("measurementChart")
)).getContext("2d");
this.myChart = new Chart(ctx, {
type: "scatter",
data: {
datasets: [
{
label: name,
backgroundColor: "black",
borderColor: "blue",
showLine: true,
data: d,
}
]
},
options: {
maintainAspectRatio: false,
responsive: true,
tooltips: {
mode: "interpolate", //interpolate
enabled: true,
intersect: false,
backgroundColor: "black",
},
scales: {
yAxes: [
{
display: true,
scaleLabel: {
display: true,
},
}
],
xAxes: [
{
display: true,
scaleLabel: {
display: false,
labelString: "Date"
},
}
]
},
legend: {
reverse: true,
display: true,
},
}
});
You can use the tick callback as described here: https://www.chartjs.org/docs/2.9.4/axes/labelling.html#creating-custom-tick-formats
scales: {
yAxes: [
{
ticks:{
callback: (val) => (new Date(val)) // or a different way to convert timestamp to date
},
display: true,
scaleLabel: {
display: true,
},
}
],
xAxes: [
{
ticks:{
callback: (val) => (new Date(val)) // or a different way to convert timestamp to date
}
display: true,
scaleLabel: {
display: false,
labelString: "Date"
},
}
]
}

Chart.js multiple datas between labels

i am using chart.js to display data. I would like to display several points per label.
A picture is better than sentences, here is an example of a poker platform :
We see that between the labels several points are recorded.
Here is my code with chart.js currently with test data :
var config = {
type: 'line',
data: {
labels: ['2', '4', '6', '8', '10','12','14','16'],
datasets: [{
label: 'Bankroll',
backgroundColor: window.chartColors.grey,
borderColor: window.chartColors.grey,
data: [20,60,80,90,120,150,170,210,260,220,150,10,220,150,220,150],
fill: false,
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Statistiques de votre bankroll'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
animation: {
duration: 2000
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Nombre de tournois'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Total Cumulé (Euros)'
}
}]
}
}
};
le rendu est le suivant :
We observe that I have not 8 data but 16 and only 8 are displayed. I would like to keep the same number of labels by displaying all the points, is this possible?
Thank you so much ! :)
You could deduct the data.labels from the data using Array.map().
labels: data.map((v, i) => i + 1)
Then you would have to define the desired ticks.stepSize for the x-axis.
xAxes: [{
ticks: {
stepSize: 2
},
optionally you may also define ticks.maxTicksLimit instead.
Please take a look at your amended code and see how it works.
var data = [20, 60, 80, 90, 120, 150, 170, 210, 260, 220, 150, 10, 220, 150, 220, 150];
var config = {
type: 'line',
data: {
labels: data.map((v, i) => i + 1),
datasets: [{
label: 'Bankroll',
backgroundColor: 'grey',
borderColor: 'grey',
data: data,
fill: false,
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Statistiques de votre bankroll'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
animation: {
duration: 2000
},
scales: {
xAxes: [{
ticks: {
stepSize: 2
},
scaleLabel: {
display: true,
labelString: 'Nombre de tournois'
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'Total Cumulé (Euros)'
}
}]
}
}
};
new Chart('canvas', config);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.bundle.min.js"></script>
<canvas id="canvas">

Failed to execute 'createLinearGradient' on 'CanvasRenderingContext2D': The provided double value is non-finite

I'm trying to create a linear gradient under plugins for my chartJs chart.Unfortunately I get an error called :
Failed to execute 'createLinearGradient' on 'CanvasRenderingContext2D': The provided double value is non-finite.
I'm trying to add my linearGradient inside plugins because I want that gradient to be aligned on each scale.
Here what I tried below
barChart = new Chart(elem, {
plugins: [
{
id: "responsiveGradient",
afterLayout: function(chart, options) {
var scales = chart.scales;
var color = chart.ctx.createLinearGradient(
scales["x-axis-0"].left,
scales["y-axis-0"].bottom,
scales["x-axis-0"].right,
scales["y-axis-0"].top
);
// add gradients stops
color.addColorStop(0, "black");
color.addColorStop(0.25, "red");
color.addColorStop(0.5, "orange");
color.addColorStop(0.75, "yellow");
color.addColorStop(1, "green");
// changes the background color option
chart.data.datasets[0].backgroundColor = color;
}
}
],
type: 'horizontalBar',
data: datasets,
options: {
maintainAspectRatio: false,
tooltips: { enabled: false },
title: {
display: false,
},
responsive: true,
legend: {
display: false,
position: "top"
},
scales: {
xAxes: [{
ticks: {
beginAtZero: false,
min:0.5,
max:0.8,
maxTicksLimit: 6,
},
scaleLabel: {
display: false
},
barThickness: 5,
gridLines: {
display: false,
zeroLineColor: "transparent",
}
}],
yAxes: [{
barThickness: 5,
ticks: {
maxTicksLimit: 6,
padding: 15,
},
gridLines: {
drawTicks: false,
display: false
}
}]
}
},
});
The problem is in the last line of your plugins.afterLayout function. There is no object such as chart.data, use chart.config.data instead.
// chart.data.datasets[0].backgroundColor = color; // replace this line
chart.config.data.datasets[0].backgroundColor = color;
Please have a look at your amended code below (I had to make an assumptions about your data).
const datasets = {
labels: ['A', 'B', 'C'],
datasets: [{
label: 'data',
data: [0.6, 0.7, 0.8],
barThickness: 5
}]
};
new Chart("myChart", {
plugins: [{
id: "responsiveGradient",
afterLayout: (chart, options) => {
var scales = chart.scales;
var color = chart.chart.ctx.createLinearGradient(
scales["x-axis-0"].left,
scales["y-axis-0"].bottom,
scales["x-axis-0"].right,
scales["y-axis-0"].top
);
// add gradients stops
color.addColorStop(0, "black");
color.addColorStop(0.25, "red");
color.addColorStop(0.5, "orange");
color.addColorStop(0.75, "yellow");
color.addColorStop(1, "green");
// changes the background color option
chart.config.data.datasets[0].backgroundColor = color;
}
}],
type: 'horizontalBar',
data: datasets,
options: {
maintainAspectRatio: false,
tooltips: {
enabled: false
},
title: {
display: false,
},
responsive: true,
legend: {
display: false,
position: "top"
},
scales: {
xAxes: [{
ticks: {
beginAtZero: false,
min: 0.5,
max: 0.8,
maxTicksLimit: 6,
},
scaleLabel: {
display: false
},
gridLines: {
display: false,
zeroLineColor: "transparent",
}
}],
yAxes: [{
ticks: {
maxTicksLimit: 6,
padding: 15,
},
gridLines: {
drawTicks: false,
display: false
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>

chart js in an especific label

I need to put a line in my chart to indicate where the day changes to the next. The initial label of the day is 00:00. Is there a function to put a line like this in my chart, that will always appear in the labels at 00:00?
The config of the chart below:
Chart.defaults.global.defaultFontColor = 'white';
graffic = new Chart(document.getElementById("graffic").getContext('2d'), {
type: 'line',
fill: false,
data: {
labels : date_label,
fill: false,
datasets:data_to_grafic
},
options: {
title: {
position:'top',
display: true,
text: device
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'HRS'
}
}],
yAxes: [{
ticks: {beginAtZero:true},
display: true,
scaleLabel: {
display: true,
labelString: 'BPS'
}
}]
}
}
});
graffic.update();
Solution using chartjs-plugin-annotation (https://github.com/chartjs/chartjs-plugin-annotation)
var date_label = ['8:00', '9:00', '10:00', '11:00', '00:00', '01:00', '02:00', '03:00', '4:00'];
var data_to_grafic = [{
label: "My First dataset",
backgroundColor: '#ddd',
borderColor: '#f00',
fill: false,
data: [0, 0, 15000, 35000, 10000, 36000, 0, 0, 0, 0]
}];
var graffic = new Chart(document.getElementById("graffic").getContext('2d'),{
type: 'line',
data: {
labels: date_label,
fill: false,
datasets: data_to_grafic
},
options: {
title: {
position: 'top',
display: true,
text: 'My Title'
},
annotation: {
annotations: [{
type: "line",
mode: "vertical",
scaleID: "x-axis-0",
value: "00:00",
borderColor: "red",
borderWidth: 2
}]
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'HRS'
}
}],
yAxes: [{
ticks: {
beginAtZero: true
},
display: true,
scaleLabel: {
display: true,
labelString: 'BPS'
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/0.5.5/chartjs-plugin-annotation.js"></script>
<canvas id="graffic"></canvas>

Categories