Chart.js one label per stacked bar - javascript

I'm using chart.js with datalabels plugin but I'm having issues with displaying one label per stacked bar.
I have tried to access to the dataset meta to distinguish to show the labels but struggling to achieve. Help me to do that.
Please see my example here: https://jsfiddle.net/fraserr/9ezggxx5/314/
var datasets = JSON.parse('[{"username":"test name","stack":"2","label":"test name - actual","dataset":{"2018-12-17":"3","2018-12-24":"1"},"data":["3","1"],"borderColor":"#db005f","backgroundColor":"#f190b0","borderWidth":1},{"username":"test name","stack":"2","label":"test name - target","dataset":{"2018-12-17":"10","2018-12-24":"10"},"data":["10","10"],"borderColor":"#511158","backgroundColor":"#aa89ab","borderWidth":1},{"username":"Santa Claus","stack":"1","label":"Santa Claus - actual","dataset":{"2018-12-17":"2","2018-12-24":0},"data":["2",0],"borderColor":"#db005f","backgroundColor":"#f190b0","borderWidth":1},{"username":"Santa Claus","stack":"1","label":"Santa Claus - target","dataset":{"2018-12-17":"2","2018-12-24":"2"},"data":["2","2"],"borderColor":"#511158","backgroundColor":"#aa89ab","borderWidth":1}]');
new Chart('chart', {
type: 'bar',
data: {
labels: ['2018-12-17', '2018-12-24'],
datasets: datasets
},
options: {
scales: {
xAxes: [{
stacked: true,
ticks: {
beginAtZero: true,
suggestedMax: 50
}
}],
yAxes: [{
stacked: true
}]
},
plugins: {
datalabels: {
formatter: (value, ctx) => {
return ctx.dataset.username;
},
align: 'end',
anchor: 'end',
}
}
}
});
My desired result is to have "test name" on at the top of the 1st bar, "Santa Claus" on the 2nd, "test name" on 3rd and "Santa Claus" on 4th. Ideally I would always show one label per bar (even when one is bar per stack is hidden).
Thanks in advance!

Related

ChartJS options: Unable to retain options variable custom label font sizes when adding separate title option

I am trying to follow the DRY method and currently have a bar chart. I created a variable named "chartOptions" which contain my legend, x and y axes label font size preferences. What I would like to do, is for each of this bar chart to retain my "chartOption" settings, but allow me to have specific title for this chart (as I plan on adding other uniquely named charts).
Currently, it appears that no matter the order I've placed these options, it will display the title and reset the label sizes to default. From the Options specifications of ChartJS I am unclear if this is a limitation issue - where only one chart "options" argument is allowed/if nesting is allowed or if I need to look at this under global definitions or somewhere else. (both of which I have tried - but maybe not implemented correctly?)
Any thoughts or input on this is appreciated. I have attached my chartjs code - with a chart that demos what I am experiencing.
// This variable stores the global configurations for Chart Options
// such as font-sizes, axes scales...etc.
var chartOptions = {
legend: {
display: true,
labels: {
fontSize: labelFontSize
}
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Quarter',
fontSize: labelFontSize
},
ticks: {
fontSize: tickFontSize
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'Number of Calls',
fontSize: labelFontSize
},
ticks: {
beginAtZero: true,
fontSize: tickFontSize
}
}]
}
}
// Create Bar chart
var barChart1 = document.getElementById("barChart1").getContext("2d");
var supportCallsChart1 = new Chart(barChart1, {
type: 'bar',
data: {
labels: ["Q1-18", "Q2-18"],
datasets: [{
label: "test dataset",
backgroundColor: 'rgb(255, 99, 132)',
borderColor: 'rgb(255, 99, 132)',
data: [5, 10],
}]
},
options: chartOptions, // having the options title below overwrites my x/y axes labels & font sizes
options: { // removing this title option will allow chartOptions settings to occur
title: {
display: true,
text: "2018 Test Title",
fontSize: chartTitleFontSize
}
}
});

Last y-axis tick gridline not showing with chart title displayed

I'm making a stacked bar graph using Chart.js, with (total stacked) values ranging from 0 to 1 (displayed as 0-100%). I'd like to have a tick/gridline displayed every 0.20/20%, from 0 to and including 1/100%.
Right now, my chart will display the last gridline at 1/100% if I don't include a graph title, but will hide the gridline (but still have the tick label) if I display the title.
Any tips to get the gridline to show?
JS fiddle here: https://jsfiddle.net/amyzlc/n99xac76/, and relevant graph code below.
Link to image of graph with title and without top gridline here.
var stackedBar = new Chart(ctx, {
type: 'bar',
data: dataChart,
options: {
title: {
display: true, //top gridline displays if false, not if true
text: 'Month-wise Adherence'
},
legend: {
position: 'bottom'
},
scales: {
xAxes: [{
stacked: true,
gridLines: {display: false}
}],
yAxes: [{
stacked: true,
gridLines: {drawBorder: false, tickMarkLength: 3},
ticks: {
min: 0,
max: 1, //not showing with title
padding: 6,
stepSize: 0.2,
callback: function(value) {
return Math.round(value*100).toString() + "%";
}
}
}]
}
}
});
Thanks!

How to make y axis only integer scaling in ChartJS?

I just a newbie to ChartJS,enter image description here
I have 3 questions:
1.How can I make the Y axis only integer? where should I add it?
2.How can I turn off the title which is ""my open case"? I tried it to set it to null but dodn't work?
3.How can I turn off the background grids off? it looks weird
This is my code:
var columnChart = document.getElementById("columnChart").getContext('2d');
var myChart = new Chart(columnChart, {
type: 'bar',
data: {
labels: columnChartLabel,
datasets: [ {
label: 'My Open Case',
data: columnChartNumber,
backgroundColor: "rgba(255,153,0,1)"
}]
}
});
How can I make the Y axis only integer? where should I add it?
You can make the Y axis only integer by setting stepSize property to 1 for ticks in the chart options.
options: {
scales: {
yAxes: [{
ticks: {
stepSize: 1
}
}]
}
}
see tick configuration options
How can I turn off the title which is "my open case"?
You can turn off the title (aka Legend) by setting display property to false for the legend.
options: {
legend: {
display: false
}
}
see legend configuration
How can I turn off the background grids off?
You can turn off the background grids by setting gridLines's display property to false for both the x and y axis.
options: {
scales: {
xAxes: [{
gridLines: {
display: false
}
}],
yAxes: [{
gridLines: {
display: false
}
}]
}
}
see grid line configuration
ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ᴏɴ ᴊꜱꜰɪᴅᴅʟᴇ

Chart.js Y axis label, reverse tooltip order, shorten X axis labels

I am creating a stacked bar chart using Chart.js. However, I cannot find in the documentation how to change some things.
How to add a label on the Y axis.
How to shorten the label on the X axis so it displays only
the first 10 letters.
How to reverse the order in which the values are shown in
the tooltip.
Are these thigs are possible to implement?
I have marked what I want to change here.
Here are what my chart options look like now:
var ctx = $("#newchart");
var barGraph = new Chart(ctx, {
type: 'bar',
data: chartdata,
options: {
barValueSpacing: 20,
tooltips: {
enable: true,
mode: 'label',
callbacks: {
label: function(tooltipItem, data){
var datasetLabel = data.datasets[tooltipItem.datasetIndex].label || '';
return datasetLabel + ': ' + Number(tooltipItem.yLabel) + ' Users';
}
}
},
responsive: true,
segmentShowStroke: true,
scales: {
xAxes: [{
display: false,
stacked: true,
ticks:{
stepSize : 10,
},
gridLines: {
lineWidth: 0,
color: "#9E9E9E"
}
}],
yAxes: [{
stacked: true,
ticks: {
min: 0,
stepSize: 10,
},
gridLines: {
lineWidth: 0,
color: "#9E9E9E"
}
}]
}
}
});
1. Adding a Y-axis label
in the yAxes object give it a scaleLabel object that takes in labelString (example fiddle)
yAxes: [{
scaleLabel: {
labelString: 'Value'
}
}]
2. Shortening xAxis category labels
For this, you can pass a userCallback function to the xAxis ticks object that can return your desired output. The function will take in the original label in its first parameter so you can just return a substring at your desired length, example fiddle
xAxes: [{
ticks: {
userCallback: function(label, index, labels) {
if(typeof label === "string")
{
return label.substring(0,1)
}
return label;
},
}
}],
3. reverse tooltip order
The tooltips object accepts a function called itemSort that can be passed to Array.prototype.sort.
So you could so something like below, but you may also need to compare the objects index as well as the datasetIndex to get your desired result. (example fiddle)
tooltips: {
mode: 'label',
itemSort: function(a, b) {
return b.datasetIndex - a.datasetIndex
},
},

Single bar with background Chart.js [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 months ago.
Improve this question
I want to paint a horizontal bar with Chart.js, but i want a default background color (Which is the max value) and paint the current value with another color. Just like the image below. How can i do this?
There is no easy way to do this in Chart.js (such as a specific "100% stacked bar" type). What you need is two stacked horizontal bars.
First, define your chart-type as a horizontalBar
// html
<canvas id="chart" height="20"></canvas>
// javascript
var ctx = document.getElementById('chart');
var bar_chart = new Chart(ctx, {
type: 'horizontalBar' // this will give you a horizontal bar.
// ...
};
In order to have a single bar instead of two, they need to be stacked. You also need to hide the scales. Optionally, you can hide the legend and the tooltip. This is all configured in the options:
var bar_chart = new Chart(ctx, {
// ...
options: {
legend: {
display: false // hides the legend
},
tooltips: {
enabled: false // hides the tooltip.
}
scales: {
xAxes: [{
display: false, // hides the horizontal scale
stacked: true // stacks the bars on the x axis
}],
yAxes: [{
display: false, // hides the vertical scale
stacked: true // stacks the bars on the y axis
}]
}
}
};
As stacked bars are placed on top of each other, your first dataset contains your value (57.866), and the second dataset corresponds to max - value. Here's an example considering value = 57866 and max = 80000:
var value = 57866; // your value
var max = 80000; // the max
var bar_chart = new Chart(ctx, {
// ...
datasets: [{
data: [value],
backgroundColor: "rgba(51,230,125,1)"
}, {
data: [max - value],
backgroundColor: "lightgrey"
}]
};
Here's the jsfiddle with the full code.
In addition to #Tarek's answer,
If you need to get the percentage value in the bar,
https://jsfiddle.net/akshaykarajgikar/bk04frdn/53/
Dependensies:
https://www.chartjs.org/
https://chartjs-plugin-datalabels.netlify.app/
var bar_ctx = document.getElementById('bar-chart');
var bar_chart = new Chart(bar_ctx, {
type: 'horizontalBar',
data: {
labels: [],
datasets: [{
data: [57.866],
backgroundColor: "#00BC43",
datalabels: {
color: 'white' //Color for percentage value
}
}, {
data: [100 - 57.866],
backgroundColor: "lightgrey",
hoverBackgroundColor: "lightgrey",
datalabels: {
color: 'lightgray' // Make the color of the second bar percentage value same as the color of the bar
}
}, ]
},
options: {
legend: {
display: false
},
tooltips: {
enabled: false
},
scales: {
xAxes: [{
display: false,
stacked: true
}],
yAxes: [{
display: false,
stacked: true
}],
}, // scales
plugins: { // PROVIDE PLUGINS where you can specify custom style
datalabels: {
align: "start",
anchor: "end",
backgroundColor: null,
borderColor: null,
borderRadius: 4,
borderWidth: 1,
font: {
size: 20,
weight: "bold", //Provide Font family for fancier look
},
offset: 10,
formatter: function(value, context) {
return context.chart.data.labels[context.dataIndex]; //Provide value of the percentage manually or through data
},
},
},
}, // options
});
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels#0.7.0"></script>
<canvas id="bar-chart" height="20"></canvas>

Categories