chart js in an especific label - javascript

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>

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

How to add margin bottom in Tittle ChartJS

I would like to know how to add bottom margin to my title in ChartJS to prevent Datalabels from overlapping the title, thanks.
you can view the graph in that link
View Image
I use:
ChartJS
ChartJS Datalabels
This is my code
//chart por rango de edad
var ctx_age_range = document.getElementById('chart_age_range');
var myDoughnutChart = new Chart(ctx_age_range, {
type: 'bar',
data: {
labels: ["<20", "20-29", "30-39", "40-55", ">56"],
datasets: [{
label: "Cantidad",
backgroundColor: ["#47b3d5", "#47b3d5","#47b3d5","#47b3d5","#47b3d5"],
data: [0.32,34.55,34.79,25.32,5.02]
}]
},
options: {
legend: {
display: false,
},
title: {
display: true,
text: 'CASOS POR RANGO DE EDAD',
fontSize:15,
color:"black"
},
scales: {
xAxes: [{
gridLines: {display: false},
ticks: {
stepSize: 1,
min: 0,
fontSize:12
},
barPercentage: 0.8,
categoryPercentage: 1,
}],
yAxes: [{
scaleLabel: {
display: false,
},
gridLines: {display: false,drawBorder:false},
ticks:{
display:false,
},
}]
},
plugins: {
datalabels: {
display: true,
align: 'end',
anchor: 'end',
formatter: function(value, ctx) {
return value+'%';
},
color:'black',
font:{
size: 11
}
}
}
}
});
I would like to know how add margin bottom to the title or how to add margin/padding top top of graphic.
You can use padding property on the title option to achieve that:
var ctx_age_range = document.getElementById('chart_age_range');
var myDoughnutChart = new Chart(ctx_age_range, {
type: 'bar',
data: {
labels: ["<20", "20-29", "30-39", "40-55", ">56"],
datasets: [{
label: "Cantidad",
backgroundColor: ["#47b3d5", "#47b3d5","#47b3d5","#47b3d5","#47b3d5"],
data: [0.32,34.55,34.79,25.32,5.02]
}]
},
options: {
legend: {
display: false,
},
title: {
display: true,
text: 'CASOS POR RANGO DE EDAD',
fontSize:15,
color:"black",
padding: 30
},
scales: {
xAxes: [{
gridLines: {display: false},
ticks: {
stepSize: 1,
min: 0,
fontSize:12
},
barPercentage: 0.8,
categoryPercentage: 1,
}],
yAxes: [{
scaleLabel: {
display: false,
},
gridLines: {display: false,drawBorder:false},
ticks:{
display:false,
},
}]
},
plugins: {
datalabels: {
display: true,
align: 'end',
anchor: 'end',
formatter: function(value, ctx) {
return value+'%';
},
color:'black',
font:{
size: 11
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#0.7.0/dist/chartjs-plugin-datalabels.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="chart_age_range" width="400" height="400"></canvas>

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>

How to display only one label in a multi line char?

I create a diagram with chart.js. This diagram has two lines. So it displays also two labels by default. But I need a configuration where one for example the red label should appear and the blue one should be hidden. The label not the line!!
Thanks for your help
var config = {
type: 'line',
data: {
labels: ['16:30', '17:30', '18:30', '19:30', '20:30'],
datasets: [{
label: 'High',
backgroundColor: 'blue',
borderColor: 'blue',
data: [10.43, 10.42, 10.44, 10.43, 10.40],
fill: false,
}, {
label: 'low',
fill: false,
backgroundColor: 'red',
borderColor: 'red',
data: [8.43, 8.5, 8.39, 8.38, 8.38],
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Test'
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Time'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
}
}
};
var ctx = $('#dia');
var myChart = new Chart(ctx, config);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>
<canvas id="dia"></canvas>
You can use legend.labels.generateLabels together with legend.onClick action to achieve this.
var config = {
type: 'line',
data: {
labels: ['16:30', '17:30', '18:30', '19:30', '20:30'],
datasets: [{
label: 'High',
backgroundColor: 'blue',
borderColor: 'blue',
data: [10.43, 10.42, 10.44, 10.43, 10.40],
fill: false,
}, {
label: 'low',
fill: false,
backgroundColor: 'red',
borderColor: 'red',
data: [8.43, 8.5, 8.39, 8.38, 8.38],
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Test'
},
legend: {
labels: {
generateLabels: chart => {
let dataset = chart.data.datasets[0];
return [{
chart: chart,
text: dataset.label,
fillStyle: dataset.backgroundColor,
strokeStyle: dataset.borderColor,
hidden: chart.getDatasetMeta(0).hidden
}]
}
},
onClick: (mouseEvent, legendItem) => {
legendItem.chart.getDatasetMeta(0).hidden = !legendItem.hidden;
legendItem.chart.update();
}
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Time'
}
}],
yAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
}
}
};
var ctx = $('#dia');
new Chart(ctx, config);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>
<canvas id="dia"></canvas>

Categories