Charts.js DataIndex not updating based on selected datasets - javascript

Fiddle :https://jsfiddle.net/jfft219g/
You can see here I have 3 datasets i.e Hospital, Referral, Total. I am displaying the the dataindexes on top of each bar.
But now when I disable one dataset the dataIndexes are still there for the disabled dataset. How to manage this. Please check the fiddle for the running codes.
Any help will be appreciated.
<div id="patientsBarGraphDiv" style="border: 1px solid black">
<canvas id="patientsBarGraph"></canvas>
</div>
var paitentData = {
labels: ["Today", "Week", "Month", "Year"],
datasets: [{
label: "Hospital Patients",
fillColor: "#79D1CF",
strokeColor: "#79D1CF",
data:[ 24, 20, 30, 40] // adding data for the hospital section
}, {
label: "Referral Patients",
fillColor: "#79D1CF",
strokeColor: "#79D1CF",
data:[ 14, 24, 34, 44] // adding data for referral section
},
{
label: "Total Patients",
fillColor: "#79D1CF",
strokeColor: "#79D1CF",
data:[ 22, 32, 43, 52] // adding data for Total section
} ]
};
var opt = {
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Patients Graph'
},
hover: {
animationDuration: 1
},
animation: {
duration: 1,
onComplete: function () {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.textAlign = 'center';
ctx.fillStyle = "rgba(0, 0, 0, 1)";
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
var data = dataset.data[index];
ctx.fillText(data, bar._model.x, bar._model.y - 5);
});
});
}
}
};
var ctx = document.getElementById("patientsBarGraph").getContext("2d");// getting the id of canvas
var MyNewChart = new Chart(ctx,{
type: 'bar',
data: paitentData,
options:opt
});

Add the following lines of code inside your forEach loop, that will take care of the dataIndex updating issue :
var isDatasetVisible = chartInstance.controller.isDatasetVisible(i);
if (!isDatasetVisible) return;
Here is the working example on JSFiddle

Related

Create space between legend and chart in charts.js [duplicate]

This question already has answers here:
Chart.js - Increase spacing between legend and chart
(13 answers)
Closed 1 year ago.
I am working with charts.js but I'm facing an issue. My legend and bar chart value overlaps a bit.
I am not able to resolve this issue, It would be appreciated if there is a solution to this issue
I have shared JS fiddle link below
https://jsfiddle.net/qh0yzmjf/1/
var ctx = document.getElementById("canvas").getContext("2d");
var nomi = [2017, 2018, 2019];
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: nomi,
datasets: [{
label: 'PP PERVENUTI',
data: [50, 30, 45],
backgroundColor: "#8A0808",
fill: false,
borderColor: "#8A0808",
borderWidth: 3
},
{
label: 'PP EVASI',
data: [60, 45, 12],
backgroundColor: "#0B610B",
fill: false,
borderColor: "#0B610B",
borderWidth: 3
},
{
label: 'PI PERVENUTI',
data: [20, 25, 35],
backgroundColor: "#8A0886",
fill: false,
borderColor: "#8A0886",
borderWidth: 3
},
{
label: 'PI EVASI',
data: [10, 20, 30],
backgroundColor: "#0404B4",
fill: false,
borderColor: "#0404B4",
borderWidth: 3
}
]
},
options: {
legend: {
display: true,
position: "top"
},
hover: {
animationDuration: 0
},
animation: {
onComplete: function() {
var ctx = this.chart.ctx;
const chart = this.chart;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
ctx.fillStyle = "black";
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function(dataset, i) {
if (chart.getDatasetMeta(i).hidden) {
return;
}
for (var i = 0; i < dataset.data.length; i++) {
for (var key in dataset._meta) {
var model = dataset._meta[key].data[i]._model;
ctx.fillText(dataset.data[i], model.x, model.y);
}
}
});
}
}
}
});
I have also shared my code above
I don't know how to create space between legend and chart, and help will be appreciated thanks
If I am not wrong, there isnt a configuration built by chart js to put padding between the labels and the chart,although, the padding to the labels are applied in wor format, this means that chart js applies padding between labels, on the other hand, you can apply padding between the title of the chart and the labels.
If you want padding between the tittle of the chart and the chart you can use the following code:
plugins: {
title: {
display: true,
text:'Historico Mensual',
},
legend: {
labels: {
padding: 100
}
}
},
Another solution it could be to change the position of the labels to the bottom with the following code:
options: {
legend: {
display: true,
position: "bottom"
},
And adding a layput padding so the values dont get outside the canvas.
options: {
layout:{
padding:20
}
},

How to show values on top of bars in a PDF using chart.js and chartjs-node-canvas?

I need to show the values on the top of bars using chartjs-node-canvas to create a PDF in Node
I have been able to recreate what I am looking in HTML but the plugin has the limitation of not accepting the "animation" property, for this reason I am looking to know if there is another way to do it in Node without the need for another external plugin. This is my current code
var ctx = document.getElementById("myChart");
var chart = new Chart(ctx, {
type: "bar",
data: {
labels: ["a", "b", "c", "d", "e", "f"],
datasets: [
{
type: "bar",
backgroundColor: "blue",
borderColor: "blue",
borderWidth: 1,
label: "promedio",
order: 1,
data: [60, 49, 72, 90, 100, 60]
},
{
type: "bar",
backgroundColor: "orange",
borderColor: "orange",
borderWidth: 1,
label: "promedio",
order: 1,
data: [40, 5, 20, 30, 10, 6]
},
{
type: "line",
label: "casos",
data: [25, 13, 30, 35, 25, 40],
lineTension: 0,
backgroundColor: "red",
borderColor: "red",
order: 0,
fill: false
}
]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
},
animation: {
duration: 1,
onComplete: function () {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(16, 20, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
var data = dataset.data[index];
ctx.fillText(data, bar._model.x, bar._model.y - 2);
});
});
}
},
legend: {
display: false
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<body>
<canvas id="myChart" width="400" height="200"></canvas>
</body>
Short answer is no, you either have to implement your own external inline plugin or use the datalabels plugin (https://chartjs-plugin-datalabels.netlify.app/samples/charts/bar.html) since there is no build in way to achieve this

ChartJs, How can I get different color fills between my two datasets in a line graph?

Above is a graph I made using ChartJS. I have two datasets. I also have the space between the two datasets filled just like I want it. But I need to get two different colors for the fill. When the Hours dataset is bigger than the Goal dataset, I want the fill to be green, and when the Hours dataset is smaller than Goal, I want it to be red. I'm really hoping there is a way to do this using ChartJS, so that I don't have to recreate this in Canvas.
If it matters, this is in Vue.Js.
Here is the code for the two datasets:
const dataSets = [{
label: this.dataSetLabel,
data: this.dataArray,
backgroundColor: new Array(this.dataArray.length).fill('rgba(255, 0, 0, 0.8)'), // red
borderColor: new Array(this.dataArray.length).fill('rgba(255, 0, 0, 0.8)'),
borderWidth: 1,
fill: '+1'
}]
if (this.fi !== 3) {
dataSets.push({
label: 'Goal',
data: new Array(this.dataArray.length).fill(this.user.braceHours),
type: 'line',
backgroundColor: new Array(this.dataArray.length).fill('rgba(84, 232, 198, 0.8)'), // green
borderColor: new Array(this.dataArray.length).fill('rgba(84, 232, 198, 0.8)'),
borderWidth: 1,
fill: '-1'
})
}
Any help with this would be much appreciated.
You can extend an existing line chart as shown by the runnable code snippted below.
This solution is based on the answer https://stackoverflow.com/a/36941860/2358409 that had to be slightly adapted to work with the latest stable version of Chart.js (2.9.3).
const goal = 2;
Chart.defaults.areaConditionalColors = Chart.defaults.line;
Chart.controllers.areaConditionalColors = Chart.controllers.line.extend({
update: function(reset) {
var yAxis = this.chart.scales['y-axis-0'];
var max = Math.max.apply(null, this.chart.data.datasets[0].data);
var yTop = yAxis.getPixelForValue(max);
var yGoal = yAxis.getPixelForValue(goal);
var min = Math.min.apply(null, this.chart.data.datasets[0].data);
var yBottom = yAxis.getPixelForValue(min);
// build a gradient that changes the color at the goal
var ctx = this.chart.chart.ctx;
var gradient = ctx.createLinearGradient(0, yTop, 0, yBottom);
var ratio = Math.min((yGoal - yTop) / (yBottom - yTop), 1);
gradient.addColorStop(0, 'green');
gradient.addColorStop(ratio, 'green');
gradient.addColorStop(ratio, 'red');
gradient.addColorStop(1, 'red');
this.chart.data.datasets[0].backgroundColor = gradient;
return Chart.controllers.line.prototype.update.apply(this, arguments);
}
});
new Chart('myChart', {
type: 'areaConditionalColors',
data: {
labels: ['FRI', 'SAT', 'SUN', 'MON', 'TUE', 'WED', 'THU'],
datasets: [{
label: 'Hours',
backgroundColor: 'green',
data: [0, 3, 0, 9, 4, 0, 0],
fill: '+1'
},
{
label: 'Goal',
backgroundColor: 'rgba(84, 232, 198, 0.8)',
data: [goal, goal, goal, goal, goal, goal, goal],
fill: '-1'
}]
},
options: {
legend: {
onClick: e => e.stopPropagation()
},
tooltips: {
mode: 'x'
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="80"></canvas>

How to remove grid on chart.js

I'm testing with Chart.js and trying to remove the grid. My code:
function grafica(){
var chartData = {
labels: [" ", " ", " "],
datasets: [
{
fillColor: "#79D1CF",
strokeColor: "#79D1CF",//marges
data: [30, 40, 45]
}, {
fillColor: "rgb(210,27,71)",
strokeColor: "rgb(210,27,71)",//marges
data: [56, 55, 40]
}, {
fillColor: "rgba(210,27,71,0)",
strokeColor: "rgba(210,27,71,0)",//marges
data: [0, 0, 0]
}
]
};
var ctx = document.getElementById("myChart").getContext("2d");
var myBar = new Chart(ctx).Bar(chartData, {
showTooltips: false,
onAnimationComplete: function () {
var ctx = this.chart.ctx;
ctx.font = this.scale.font;
ctx.fillStyle = this.scale.textColor;
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
}
});
}
How can I do it? I tried some things like add "ctx.gridLines = false;" and "ctx.ticks = false;" but at the moment anything works.
Edit:
I did some changes following your instructions but I don't know why anything work.
The version I'm using is 2.0.0-alpha
On v3 (Updated docs) is changed to
options: {
scales: {
x: {
grid: {
display: false
}
},
y: {
grid: {
display: false
}
}
},
}
I am now using version 2.0Alpha, same as you.
Updated Documentation Link
Below is an example for a simple bar chart without grid lines.
You need to set the 'gridLines' key on the y and xAxis keys of the options object.
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(151,187,205,0.5)",
data: [100,99,98,97,96,95,94]
}]
};
window.myBar = new Chart(ctx).Bar({
data: barChartData,
options: {
responsive: true,
scales: {
xAxes: [{
gridLines: {
show: true
}
}],
yAxes: [{
gridLines: {
show: false
}
}]
}
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0-alpha/Chart.min.js"></script>
<div>
<canvas id="canvas"></canvas>
</div>
Try it with:
xAxis: {
gridLineWidth: 0
},
yAxis: {
gridLineWidth: 0,
minorTickInterval: null
}
Add this to the chart data,

angular-chart.js : how to show numbers in each bar of stacked bar chart

I am using angular-chart.js to draw some charts. We know now chart.js supports stacked bar chart. But I have not found how to show numbers in each bar, like following:
From above pic we can see each bar has number on it. Does anyone know how to realize that in angular-chart.js?
You can show numbers in each bar of stacked bar chart by adding this code in your options function
animation: {
duration: 1,
onComplete: function () {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.textAlign = 'center';
ctx.fillStyle = "rgba(0, 0, 0, 1)";
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
var data = dataset.data[index];
ctx.fillText(data, bar._model.x, bar._model.y - 5);
});
});
}
}
You can do this, it will be displayed as a tooltip,
ctrl.socialChart = {
options : {
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
},
type: 'StackedBar',
labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
series: ['FACEBOOK', 'GOOGLE', 'TWITTER', 'INSTAGRAM'],
colors: ['#ED402A', '#F0AB05', '#A0B421', '#00A39F'],
data : [
[65, 59, 90, 81, 56, 55, 40],
[28, 48, 40, 19, 96, 27, 100]
]
}
DEMO

Categories

Resources