Chart.JS Global Options - javascript

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 !!!

Related

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

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/

Cleart Chart data upon ajax call [duplicate]

This question already has answers here:
chart.js load totally new data
(23 answers)
Closed 6 years ago.
I am loading a chart using Chart.js with hard coded data when the page starts. Following that upon a button click, I am making an ajax query; get external data from database and want to load that data into the chart.
I have the correct data retrieved and stored as an array. I want to clear the current chart data and input this new array as new data for the chart.
For starters I would need to empty the old data and tried, clear() and destroy() and neither of them works. The chart just keeps reloading with the old data. The old chart seems removed for a split second only to see it reappear. How can I resolve this?
$( document ).ready(function() {
var lineData = {
labels: ["Lap 1", "Lap 2", "Lap 3", "Lap 4", "Lap 5"],
datasets: [{
fillColor: "rgba(255,255,255,0)",
strokeColor: "rgba(63,169,245,1)",
pointColor: "rgba(63,169,245,1)",
pointStrokeColor: "#fff",
data: [10, 20, 30, 40, 55] // need to swap this with race1Data array
}, {
fillColor: "rgba(255,255,255,0)",
strokeColor: "rgba(102,45,145,1)",
pointColor: "rgba(102,45,145,1)",
pointStrokeColor: "#fff",
data: [97, 87, 55, 72, 66]
}]
}
var lineOptions = {
responsive: true,
animation: true,
pointDot: true,
scaleOverride : false,
scaleShowGridLines : false,
scaleShowLabels : true,
scaleSteps : 4,
scaleStepWidth : 25,
scaleStartValue : null
};
//Create Line chart
var ctx = document.getElementById("lineChart").getContext("2d");
myNewChart = new Chart(ctx).Line(lineData, lineOptions);
$("#form").submit(function(e) {
var race1 = $( "#racename1" ).val();
var race2 = $( "#racename2" ).val();
var race1Data = [];
$.post("MyServlet", {raceName1 : race1, raceName2 : race2}, function(responseText) {
race1Data = responseText; // <-- correct data
myNewChart.destroy(); // <--doesn't work
});
});
});
I didn't find any better solution but to iterate through the lineData and remove all the data by calling removeData()
Here's the example created for the code provided:
https://jsfiddle.net/4e3u5L89/2/

How to push datasets dynamically for chart.js (bar chart)?

Im using chartjs (bar chart) to display some data.
Im trying to dynamically add data to datasets array but its not working.
for example, lets say I have 2 objects in datasets array, and I dynamically creating this object and trying to push him into datasets (from Chrome console)
after the page loaded and chart is already up.
var e = {
fillColor : "#efefef",
strokeColor : "#efefef",
highlightFill: "#efefef",
highlightStroke: "#efefef",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
}
and then
barChartData.datasets.push(e)
I also tried to do window.myBar.update()
but again nothing happend.
Do you know this issue?
Thanks,
I don't think you can use addData to add a series - it's for adding points / bars to existing series.
However you can insert your new series directly into the chart object. With the chart object and new dataset like so
var ctx = document.getElementById("chart").getContext("2d");
var myBarChart = new Chart(ctx).Bar(data);
var myNewDataset = {
label: "My Second dataset",
fillColor: "rgba(187,205,151,0.5)",
strokeColor: "rgba(187,205,151,0.8)",
highlightFill: "rgba(187,205,151,0.75)",
highlightStroke: "rgba(187,205,151,1)",
data: [48, 40, 19, 86, 27, 90, 28]
}
the code to insert a new dataset would be
var bars = []
myNewDataset.data.forEach(function (value, i) {
bars.push(new myBarChart.BarClass({
value: value,
label: myBarChart.datasets[0].bars[i].label,
x: myBarChart.scale.calculateBarX(myBarChart.datasets.length + 1, myBarChart.datasets.length, i),
y: myBarChart.scale.endPoint,
width: myBarChart.scale.calculateBarWidth(myBarChart.datasets.length + 1),
base: myBarChart.scale.endPoint,
strokeColor: myNewDataset.strokeColor,
fillColor: myNewDataset.fillColor
}))
})
myBarChart.datasets.push({
bars: bars
})
myBarChart.update();
Fiddle - http://jsfiddle.net/pvak6rkx/ (inserts the new dataset after 3 seconds)
In version 2.x, you can add (or remove) data to the chart directly and then call update(), e.g.
barChart.data.datasets.push({
label: 'label2',
backgroundColor: '#ff0000',
data: [1,2,3]
});
barChart.update();
Here's a jsfiddle example.
Your missing the data key from your chart instance i.e. barChartData.data.datasets.push(e);
No need for any methods. The js chart object data.datasets key accepts an array of objects. Therefore in your case use :
var e = {
fillColor : "#efefef",
strokeColor : "#efefef",
highlightFill: "#efefef",
highlightStroke: "#efefef",
data : [randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor(),randomScalingFactor()]
}
barChartData.data.datasets[] = e; // this will append additional data to your chart
barChartData.update();
Just make sure that barChartData is an instance of your js chart.

Click events on Pie Charts in Chart.js

I've got a question regard Chart.js.
I've drawn multiple piecharts using the documentation provided. I was wondering if on click of a certain slice of one of the charts, I can make an ajax call depending on the value of that slice?
For example, if this is my data
var data = [
{
value: 300,
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
},
{
value: 50,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
},
{
value: 100,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
}
],
is it possible for me to click on the Red labelled slice and call a url of the following form:
example.com?label=red&value=300? If yes, how do I go about this?
Update: As #Soham Shetty comments, getSegmentsAtEvent(event) only works for 1.x and for 2.x getElementsAtEvent should be used.
.getElementsAtEvent(e)
Looks for the element under the event point, then returns all elements
at the same data index. This is used internally for 'label' mode
highlighting.
Calling getElementsAtEvent(event) on your Chart instance passing an
argument of an event, or jQuery event, will return the point elements
that are at that the same position of that event.
canvas.onclick = function(evt){
var activePoints = myLineChart.getElementsAtEvent(evt);
// => activePoints is an array of points on the canvas that are at the same position as the click event.
};
Example: https://jsfiddle.net/u1szh96g/208/
Original answer (valid for Chart.js 1.x version):
You can achieve this using getSegmentsAtEvent(event)
Calling getSegmentsAtEvent(event) on your Chart instance passing an
argument of an event, or jQuery event, will return the segment
elements that are at that the same position of that event.
From: Prototype Methods
So you can do:
$("#myChart").click(
function(evt){
var activePoints = myNewChart.getSegmentsAtEvent(evt);
/* do something */
}
);
Here is a full working example:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.0.2.js"></script>
<script type="text/javascript" src="Chart.js"></script>
<script type="text/javascript">
var data = [
{
value: 300,
color:"#F7464A",
highlight: "#FF5A5E",
label: "Red"
},
{
value: 50,
color: "#46BFBD",
highlight: "#5AD3D1",
label: "Green"
},
{
value: 100,
color: "#FDB45C",
highlight: "#FFC870",
label: "Yellow"
}
];
$(document).ready(
function () {
var ctx = document.getElementById("myChart").getContext("2d");
var myNewChart = new Chart(ctx).Pie(data);
$("#myChart").click(
function(evt){
var activePoints = myNewChart.getSegmentsAtEvent(evt);
var url = "http://example.com/?label=" + activePoints[0].label + "&value=" + activePoints[0].value;
alert(url);
}
);
}
);
</script>
</head>
<body>
<canvas id="myChart" width="400" height="400"></canvas>
</body>
</html>
Using Chart.JS version 2.1.3, answers older than this one aren't valid anymore.
Using getSegmentsAtEvent(event) method will output on console this message:
getSegmentsAtEvent is not a function
So i think it must be removed. I didn't read any changelog to be honest. To resolve that, just use getElementsAtEvent(event) method, as it can be found on the Docs.
Below it can be found the script to obtain effectively clicked slice label and value. Note that also retrieving label and value is slightly different.
var ctx = document.getElementById("chart-area").getContext("2d");
var chart = new Chart(ctx, config);
document.getElementById("chart-area").onclick = function(evt)
{
var activePoints = chart.getElementsAtEvent(evt);
if(activePoints.length > 0)
{
//get the internal index of slice in pie chart
var clickedElementindex = activePoints[0]["_index"];
//get specific label by index
var label = chart.data.labels[clickedElementindex];
//get value by index
var value = chart.data.datasets[0].data[clickedElementindex];
/* other stuff that requires slice's label and value */
}
}
Hope it helps.
Chart.js 2.0 has made this even easier.
You can find it under common chart configuration in the documentation. Should work on more then pie graphs.
options:{
onClick: graphClickEvent
}
function graphClickEvent(event, array){
if(array[0]){
foo.bar;
}
}
It triggers on the entire chart, but if you click on a pie the model of that pie including index which can be used to get the value.
Working fine chartJs sector onclick
ChartJS : pie Chart - Add options "onclick"
options: {
legend: {
display: false
},
'onClick' : function (evt, item) {
console.log ('legend onClick', evt);
console.log('legd item', item);
}
}
I was facing the same issues since several days, Today i have found the solution. I have shown the complete file which is ready to execute.
<html>
<head><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js">
</script>
</head>
<body>
<canvas id="myChart" width="200" height="200"></canvas>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
onClick:function(e){
var activePoints = myChart.getElementsAtEvent(e);
var selectedIndex = activePoints[0]._index;
alert(this.data.datasets[0].data[selectedIndex]);
}
}
});
</script>
</body>
</html>
If using a Donught Chart, and you want to prevent user to trigger your event on click inside the empty space around your chart circles, you can use the following alternative :
var myDoughnutChart = new Chart(ctx).Doughnut(data);
document.getElementById("myChart").onclick = function(evt){
var activePoints = myDoughnutChart.getSegmentsAtEvent(evt);
/* this is where we check if event has keys which means is not empty space */
if(Object.keys(activePoints).length > 0)
{
var label = activePoints[0]["label"];
var value = activePoints[0]["value"];
var url = "http://example.com/?label=" + label + "&value=" + value
/* process your url ... */
}
};
If you are using TypeScript, the code is a little funky because there is no type inference, but this works to get the index of the data that has been supplied to the chart:
// events
public chartClicked(e:any):void {
//console.log(e);
try {
console.log('DS ' + e.active['0']._datasetIndex);
console.log('ID ' + e.active['0']._index);
console.log('Label: ' + this.doughnutChartLabels[e.active['0']._index]);
console.log('Value: ' + this.doughnutChartData[e.active['0']._index]);
} catch (error) {
console.log("Error In LoadTopGraph", error);
}
try {
console.log(e[0].active);
} catch (error) {
//console.log("Error In LoadTopGraph", error);
}
}
To successfully track click events and on what graph element the user clicked, I did the following in my .js file I set up the following variables:
vm.chartOptions = {
onClick: function(event, array) {
let element = this.getElementAtEvent(event);
if (element.length > 0) {
var series= element[0]._model.datasetLabel;
var label = element[0]._model.label;
var value = this.data.datasets[element[0]._datasetIndex].data[element[0]._index];
}
}
};
vm.graphSeries = ["Series 1", "Serries 2"];
vm.chartLabels = ["07:00", "08:00", "09:00", "10:00"];
vm.chartData = [ [ 20, 30, 25, 15 ], [ 5, 10, 100, 20 ] ];
Then in my .html file I setup the graph as follows:
<canvas id="releaseByHourBar"
class="chart chart-bar"
chart-data="vm.graphData"
chart-labels="vm.graphLabels"
chart-series="vm.graphSeries"
chart-options="vm.chartOptions">
</canvas>
var ctx = document.getElementById('pie-chart').getContext('2d');
var myPieChart = new Chart(ctx, {
// The type of chart we want to create
type: 'pie',
});
//define click event
$("#pie-chart").click(
function (evt) {
var activePoints = myPieChart.getElementsAtEvent(evt);
var labeltag = activePoints[0]._view.label;
});
You can add in the options section an onClick function, like this:
options : {
cutoutPercentage: 50, //for donuts pie
onClick: function(event, chartElements){
if(chartElements){
console.log(chartElements[0].label);
}
},
},
the chartElements[0] is the clicked section of your chart, no need to use getElementsAtEvent anymore.
It works on Chart v2.9.4
I have an elegant solution to this problem. If you have multiple dataset, identifying which dataset was clicked gets tricky. The _datasetIndex always returns zero.
But this should do the trick. It will get you the label and the dataset label as well.
Please note ** this.getElementAtEvent** is without the s in getElement
options: {
onClick: function (e, items) {
var firstPoint = this.getElementAtEvent(e)[0];
if (firstPoint) {
var label = firstPoint._model.label;
var val = firstPoint._model.datasetLabel;
console.log(label+" - "+val);
}
}
}
Within options place your onclick and call the function you need as an example the ajax you need, I'll leave the example so that every click on a point tells you the value and you can use it in your new function.
options: {
plugins: {
// Change options for ALL labels of THIS CHART
datalabels: {
color: 'white',
//backgroundColor:'#ffce00',
align: 'start'
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero:true,
fontColor: "white"
},gridLines: {
color: 'rgba(255,255,255,0.1)',
display: true
}
}],
xAxes: [{
ticks: {
fontColor: "white"
},gridLines: {
display: false
}
}]
},
legend: {
display: false
},
//onClick: abre
onClick:function(e){
var activePoints = myChart.getElementsAtEvent(e);
var selectedIndex = activePoints[0]._index;
alert(this.data.datasets[0].data[selectedIndex]);
}
}

Chart.js tooltip not showing

I am attempting to add tooltips to my chart, the options are correctly loading, however tooltips are not showing, any ideas?
<script>
var lineChartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(139, 157, 195, 1)",
strokeColor : "#4c66a4",
pointColor : "#fff",
pointStrokeColor : "#3b5998",
pointHighlightFill: "#fff",
data : [{{implode(',', $fanCounts)}}]
}
]
}
var options = {
showTooltips: true,
tooltipEvents: ["mousemove", "touchstart", "touchmove"],
tooltipFillColor: "rgba(0,0,0,0.8)"
}
var myLine = new Chart(document.getElementById("fancanvas").getContext("2d")).Line(lineChartData, options);
</script>
I have also changed the chart.js global config to enable tooltips for line charts.
For anyone having problems with this using Chartjs v3, you need to make sure you have registered the Tooltip plugin:
import { Chart, Tooltip } from 'chart.js'
Chart.register([Tooltip])
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx).Line(lineChartData, {
responsive: true,
showTooltips: true,
multiTooltipTemplate: "<%= value %>",
});
use this (global settings)
You just need to put background with a single value:
datasets: [{
label: "# of beauty womens",
data: [12, 5, 3],
backgroundColor: "#FC940B",
fill: false,
borderColor: "#FC940B"
}]
Hugs...

Categories