Is it possible to add individual labels to Chart.JS bars? - javascript

I have a fully functional Chart.JS Barchart which loads as intended, however I would like to add the username to each bar which is associated to them so administrators (who can see all entries) can distinguish between them.
function BarChart(data) {
var barChartData = {
labels: data.Month,
datasets: [
{
label: 'Weight (kg)',
fillColor: "rgba(220,220,220,0.5)",
backgroundColor: "rgba(46, 44, 211, 0.7)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data: data.Weight
},
{
label: 'Steps',
fillColor: "rgba(0,0,0,0.5)",
backgroundColor: "rgba(215, 44, 44, 0.7)",
highlightFill: "rgba(0,0,0,0.5)",
highlightStroke: "rgba(0,0,0,0.5)",
data: data.Steps
}
]
}
var ctx = document.getElementById("barchart").getContext("2d");
window.myBar =new Chart(ctx, {
type: 'bar',
data: barChartData,
options: { responsive: true }
});
I have successfully passed through the Usernames and they can be called by using data.User, however when I append this to the Steps or Weight label, I end up with "Steps for: admin,admin,admin" (since I have three entries, all from admin).
Is it possible to have it so each bar has the username it belongs to?

Maybe not quite what you asked for, but you could add it to the tooltip.
options: {
tooltips:{
callbacks: {
afterLabel: function(e){return "added By:" +data.User[e.datasetIndex][e.index]}
}
}
}
https://jsfiddle.net/r71no58a/7/

Related

How do I display a different chartjs tooltip title?

I am displaying a mixed bar and line chart using chartjs. I have successfully managed to display different content in the tooltip when your hover over the line chart, or the bars, but using the same condition does not work to display a different title:
callbacks: {
title: function(tooltipItem, data) {
if (tooltipItem.datasetIndex === 0){
return data['datasets'][0]['label'];
}else{
return data['datasets'][1]['label'];
}
}
}
I am using PHP values to populate data into the main chart. Here is the code for the main chart:
var ctx_<?=$chartname?> = document.getElementById('<?=$chartname?>').getContext('2d');
new Chart(ctx_<?=$chartname?>, {
type: 'bar',
data: {
labels: [<?=$labels?>], //label array needs to go here
datasets: [{
label: 'Overall Average Score',
notes: ['','','','',''],
data: [<?=$averages?>],
pointBackgroundColor: '#6600CC',
pointRadius: 6,
pointBorderColor: 'rgb(255, 255, 255)',
pointHoverRadius:8,
pointHoverBorderWidth: 2,
pointHoverBorderColor: 'rgb(255, 255, 255)',
fill: false,
// Changes this dataset to become a line
type: 'line'
},{
label: '<?=$forename?>\'s Score',
notes: [<?=$notes?>],
data: [<?=$scores?>] //data array needs to go in here
}],
},
options: groupBarChartOptions
});
However, instead of populating the tooltip title as 'Overall Average Score' it populates the line graph tooltip title of 'Pupil Name's Score'
I am using the same
if (tooltipItem.datasetIndex === 0){
condition in the following label callback, and it works.
This should work for what you want:
title: (tooltipItem, data) => {
return data['datasets'][tooltipItem[0].datasetIndex]['label']
}
working example: https://jsfiddle.net/Leelenaleee/bcwky40z/4/

Chart js. How to change font styles for "labels" array?

I got a chart from Chart JS library.
Screenshot
var ctx = document.getElementById("myChart");
var data = {
labels: ["HTML", "CSS", "JavaScript", "jQuery", "Bootstrap", "Gulp", "PHP", 'SQL', 'Git'],
datasets: [
{
defaultFontColor: 'red',
backgroundColor: "rgba(0,255,255,.4)",
borderColor: "rgba(0,255,255,.4)",
pointBackgroundColor: "red",
pointBorderColor: "#fff",
lineTension: 0,
pointHoverBackgroundColor: "#fff",
pointHoverBorderColor: "rgba(179,181,198,1)",
data: [95, 99, 60, 91, 36, 95, 40, 95, 95]
}
]
};
var myRadarChart = new Chart(ctx, {
type: 'radar',
data: data,
options: {
responsive: true,
scale: {
reverse: false,
ticks: {
// defaultFontSize: true
}
}
}
});
I need to change font styles for underlined labels. I've dug over documentation and i tried all what i could. Even global font settings didn't change label styles, though it worked for the rest of other text. Have you met such a problem? Thanks.
It's well hidden, but you can find this under "Point Label Options"
http://www.chartjs.org/docs/#scales-radial-linear-scale
here is a example:
https://jsfiddle.net/qvrt01jp/1/
options: {
scale: {
pointLabels :{
fontStyle: "bold",
}
}
}
global should also work if set it like this:
Chart.defaults.global.defaultFontStyle = 'italic'
To give an update for v3.5.1:
Like this for font weights:
Chart.defaults.font.weight = '600';
Or if you want to do it inside the options object:
options: {
plugins: {
legend: {
labels: {
font: {
style: 'italic',
weight: '600',
}
}
}
}
}
Documentation with more info: https://www.chartjs.org/docs/latest/general/fonts.html

chart.js 2, animate right to left (not top-down)

the jsfiddle below shows the problem.
The first data inserts are fine, but when the length of the data set is capped at 10 you see the undesired behaviour where data points are animated top-down instead of moving left. It's extremely distracting.
http://jsfiddle.net/kLg5ntou/32/
setInterval(function () {
data.labels.push(Math.floor(Date.now() / 1000));
data.datasets[0].data.push(Math.floor(10 + Math.random() * 80));
// limit to 10
data.labels = data.labels.splice(-10);
data.datasets[0].data = data.datasets[0].data.splice(-10);
chart.update(); // addData/removeData replaced with update in v2
}, 1000);
Is there a way to have the line chart move left having the newly inserted data point appear on the right? As opposed to the wavy distracting animation?
thanks
This code uses streaming plugin and works as expected.
http://jsfiddle.net/nagix/kvu0r6j2/
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-streaming#1.5.0/dist/chartjs-plugin-streaming.min.js"></script>
var ctx = document.getElementById("chart").getContext("2d");
var chart = new Chart(ctx, {
type: 'line',
data: {
labels: [],
datasets: [{
label: "My First dataset",
backgroundColor: "rgba(95,186,88,0.7)",
borderColor: "rgba(95,186,88,1)",
pointBackgroundColor: "rgba(0,0,0,0)",
pointBorderColor: "rgba(0,0,0,0)",
pointHoverBackgroundColor: "rgba(95,186,88,1)",
pointHoverBorderColor: "rgba(95,186,88,1)",
data: []
}]
},
options: {
scales: {
xAxes: [{
type: 'realtime'
}]
},
plugins: {
streaming: {
onRefresh: function(chart) {
chart.data.labels.push(Date.now());
chart.data.datasets[0].data.push(
Math.floor(10 + Math.random() * 80)
);
},
delay: 2000
}
}
}
});
You should use 2.5.0 chartsjs
here it works :
http://jsfiddle.net/kLg5ntou/93
var data = {
labels: ["0", "1", "2", "3", "4", "5", "6"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(95,186,88,0.7)",
strokeColor: "rgba(95,186,88,1)",
pointColor: "rgba(0,0,0,0)",
pointStrokeColor: "rgba(0,0,0,0)",
pointHighlightFill: "rgba(95,186,88,1)",
pointHighlightStroke: "rgba(95,186,88,1)",
data: [65, 59, 80, 81, 56, 55, 40]
}
]
};
var ctx = document.getElementById("chart").getContext("2d");
var chart = new Chart(ctx, {type: 'line', data: data});
setInterval(function () {
chart.config.data.labels.push(Math.floor(Date.now() / 1000));
chart.config.data.datasets[0].data.push(Math.floor(10 + Math.random() * 80));
// limit to 10
chart.config.data.labels.shift();
chart.config.data.datasets[0].data.shift();

Chart.JS Global Options

I seem to be getting errors in Chart.JS for some reason. It's related to the global options that you can set.
The is as follows
Here is my code
var chart1 = document.getElementById("chart1").getContext("2d"),
chart2 = document.getElementById("chart2").getContext("2d"),
chart3 = document.getElementById("chart3").getContext("2d"),
datatest1 = document.getElementById("datatest1").value,
datatest2 = document.getElementById("datatest2").value,
color_bg = "#00b5e4",
color_fg = "#007799",
data1 = [{ value: Math.floor(Math.random() * 100), color: color_bg}, { value: Math.floor(Math.random() * 100), color: color_fg}],
data2 = [{ value: datatest1, color: color_bg}, { value: datatest2, color: color_fg}],
data3 = {
labels: ["Jan", "Feb", "Mar"],
datasets: [
{
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 81, 56, 55, 40]
},
{
fillColor: "rgba(151,187,205,0.5)",
strokeColor: "rgba(151,187,205,0.8)",
highlightFill: "rgba(151,187,205,0.75)",
highlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
//
// #Global Chart Settings
var options = Chart.defaults.global = {
animation: true,
animationSteps: 160,
animationEasing: "easeOutQuart",
responsive: true,
showTooltips: true,
segmentShowStroke: false,
maintainAspectRatio: true,
percentageInnerCutout: 70,
onAnimationComplete: function () {
"use strict";
//console.log("Animation Done");
}
};
$(document).ready(function () {
"use strict";
//
// #Initialise and bind to data and global options
new Chart(chart1).Doughnut(data1, options);
new Chart(chart2).Doughnut(data2, options);
new Chart(chart3).Radar(data3);
});
If you remove the options from the charts they work, if you add options and set them globally as per their documentation you get the error I've mentioned. Am I missing something obvious or is there an issue here?
When you do
var options = Chart.defaults.global = {
...
you are setting the COMPLETE Chart global default to your object. Unless you have ALL the Chart global options in your object, this will cause many of the options to end up as undefined. The right way to set the global options is like so
Chart.defaults.global.animation = true;
Chart.defaults.global.animationSteps = 160;
...
i.e. change the value of the individual properties in global instead of setting the entire global property.
Global options for charts can be set like this:
Chart.defaults.global = {
//Set options
So you can just delete the
var = options
This sets default values for all of your future charts
Please refer to the documentation for further instructions: http://www.chartjs.org/docs/
If you want to specify options for each charts do this:
new Chart(ctx).Line(data, {
// options here
});
First it must be understood that the main property to be tweaked so as to handle the animations is "Chart.defaults.global.animation".
Then keeping this as the base, you will need to adjust the sub-properties as mentioned above and in the documentation page.
So, You can change as follows:
Chart.defaults.global.animation.animationSteps=160;
Chart.defaults.global.animation.duration=5000;
...
For positioning of these lines of code, follow the first answer by potatopeelings.
I have tried changing in this way and it works !!!

chart js tooltip how to control the data that show

I'm using chart.js plugin and using a group chart by bar view.
when i hover a group of bars i can see a tooltip that show me the data of this bars.
but i what to change the tooltip to show my only single data when I'll hover the bar data.
and I what to show diffrent data info.
jsfiddle example
var ctx = document.getElementById("errorChart").getContext("2d");
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data: [65, 0, 0, 0, 0, 0, 0]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.5)",
strokeColor: "rgba(151,187,205,0.8)",
highlightFill: "rgba(151,187,205,0.75)",
highlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
var myBarChart = new Chart(ctx).Bar(data);
You could extend the bar graph to include this functionality. By default it will return both bars at the index you have hovered over, it will also check for multiple bars at the area you hovered before creating the tooltip and put any extras in that were missing.
So to do this you will need to override two functions getBarsAtEvent and showToolTip here is an example and fiddle
I have tried to make it clear the two important areas that have changed look at the comments in the extended bar type. Small changes were also made to any reference of the helpers as before they were within the scope but now they need to explicitly call Chart.helpers
Chart.types.Bar.extend({
name: "BarOneTip",
initialize: function(data){
Chart.types.Bar.prototype.initialize.apply(this, arguments);
},
getBarsAtEvent : function(e){
var barsArray = [],
eventPosition = Chart.helpers.getRelativePosition(e),
datasetIterator = function(dataset){
barsArray.push(dataset.bars[barIndex]);
},
barIndex;
for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {
if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){
//change here to only return the intrested bar not the group
barsArray.push(this.datasets[datasetIndex].bars[barIndex]);
return barsArray;
}
}
}
return barsArray;
},
showTooltip : function(ChartElements, forceRedraw){
console.log(ChartElements);
// Only redraw the chart if we've actually changed what we're hovering on.
if (typeof this.activeElements === 'undefined') this.activeElements = [];
var isChanged = (function(Elements){
var changed = false;
if (Elements.length !== this.activeElements.length){
changed = true;
return changed;
}
Chart.helpers.each(Elements, function(element, index){
if (element !== this.activeElements[index]){
changed = true;
}
}, this);
return changed;
}).call(this, ChartElements);
if (!isChanged && !forceRedraw){
return;
}
else{
this.activeElements = ChartElements;
}
this.draw();
console.log(this)
if (ChartElements.length > 0){
//removed the check for multiple bars at the index now just want one
Chart.helpers.each(ChartElements, function(Element) {
var tooltipPosition = Element.tooltipPosition();
new Chart.Tooltip({
x: Math.round(tooltipPosition.x),
y: Math.round(tooltipPosition.y),
xPadding: this.options.tooltipXPadding,
yPadding: this.options.tooltipYPadding,
fillColor: this.options.tooltipFillColor,
textColor: this.options.tooltipFontColor,
fontFamily: this.options.tooltipFontFamily,
fontStyle: this.options.tooltipFontStyle,
fontSize: this.options.tooltipFontSize,
caretHeight: this.options.tooltipCaretSize,
cornerRadius: this.options.tooltipCornerRadius,
text: Chart.helpers.template(this.options.tooltipTemplate, Element),
chart: this.chart
}).draw();
}, this);
}
return this;
}
});
then to use it just do what you did before but use BarOneTip (call it whatever you like, what ever is in the name attribute of the extended chart will be available to you.
var ctx = document.getElementById("errorChart").getContext("2d");
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,0.8)",
highlightFill: "rgba(220,220,220,0.75)",
highlightStroke: "rgba(220,220,220,1)",
data: [65, 0, 0, 0, 0, 0, 0]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.5)",
strokeColor: "rgba(151,187,205,0.8)",
highlightFill: "rgba(151,187,205,0.75)",
highlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
var myBarChart = new Chart(ctx).BarOneTip(data);
I should mention that if chartjs gets updated you would need to manually put any changes to the functions into the overridden ones

Categories