Chart.js chart positions variable at 0 even though value is >0 - javascript

I am trying to display a chart by assigning values to an array that will be referenced in charts data.
For whatever reason the chart registers the value in the Array but does not position the value correctly in the chart. I thought it was something to do with the type of the variable, so I tried casting and parsing to no avail.
What can I do to resolve this?
Edit1 - I can add and subtract with the JSON variable, so must be something else rather than a type issue.
Here is my test script
var applied = new Array();
month = ("0" + (date.getMonth() + 1)).slice(-2);
applied.push(2);
applied.push(23);
applied.push(21);
applied.push(2);
applied.push(2);
applied.push(2);
applied.push(2);
applied.push(2);
applied.push(2);
applied.push(2);
var json = $.get("../rest/hello?from=01/"+month+"/2018&to=31/"+month+"/2018", function (data){
applied.push(parseInt(data);
console.log(applied[0]);
});
Here is my chart script
const months = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
var chartlabels = new Array();
for(var i = 11; i > -1; i--){
var date = new Date();
date.setMonth(date.getMonth()-i)
chartlabels.push(months[date.getMonth()]);
}
var ctx = document.getElementById("approvedtoemployed");
var myChart = new Chart(ctx, {
type : 'line',
data : {
labels: chartlabels,
datasets : [ {
label : '# of approved',
data : applied,
backgroundColor : [
'rgba(255, 99, 132, 0)'
],
borderColor : [
'rgba(255, 99, 132, 1)',
],
borderWidth : 1
}]
},
options : {
responsive : false,
maintainAspectRatio : false,
legend: {
display: true,
position: 'bottom',
boxWidth: '15'
},
}
});

Issue must sit with how and when JSON data is loaded.
The chart has to be built within the $.get method, once this is done the chart maps variable correctly.

Related

How to add on click event to chart js

Hello I have a question concerning js charts. I have already created one in django application and i want to generate a javascript alert by clicking a certain point in the chart.
How can the alert get the value of the point that i choose?
For example with the value 92 like what is shown in the figure below:
This can be done with an onClick even handler as follows:
onClick: (event, elements, chart) => {
if (elements[0]) {
const i = elements[0].index;
alert(chart.data.labels[i] + ': ' + chart.data.datasets[0].data[i]);
}
}
Please take a look at below runnable code and see how it works.
new Chart('myChart', {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: '# of Votes',
data: [65, 59, 80, 81, 56, 55, 40],
borderColor: '#a00'
}]
},
options: {
onClick: (event, elements, chart) => {
if (elements[0]) {
const i = elements[0].index;
alert(chart.data.labels[i] + ': ' + chart.data.datasets[0].data[i]);
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<canvas id="myChart" width="400" height="95"></canvas>

How do I get a different label for each bar in a bar chart in ChartJS?

I've been working with ChartJS for the last couple of weeks and I'm getting used to it, however, I'm trying to add individual labels to my bars in my barchart and I can't figure it out.
Below is the code I'm using.
var config = {
type : 'bar',
data : {
datasets : [ {
label: numberOfFailures, //This line is the problem
data : failureData,
backgroundColor : colours,
} ],
labels : labels
},
options : {
responsive : true,
legend : {
position : 'bottom'
}
}
};
If I change the word label to labels they don't show up at all, but when it says label they all show up together. What I want is for array element 1 to appear on bar 1, etc.
If your aim is to take the values from an array and have them appear along the bottom of the bar chart so that each array value is the label for a bar then you need to set the data.labels value, not the data.datasets.label value.
For example, this basic chart is taken from the Chart.js documentation for bar chart data structure and shows how to use an array of month names to label the bars. Notice that the label bars go into the data.labels node.
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
borderWidth: 1,
hoverBackgroundColor: "rgba(255,99,132,0.4)",
hoverBorderColor: "rgba(255,99,132,1)",
data: [65, 59, 80, 81, 56, 55, 40],
}
]
};
If you programmatically create an array with one label for each point of data then it might look something like this:
var chartConfig = {};
for (score = 0; score < maxScore; ++score) {
chartConfig.scoreLabels[score] = score;
chartConfig.scoreData[score] = howManyAchievedScore(score);
}
var data = {
labels: chartConfig.scoreLabels,
datasets: [
{
label: "Number of players who achieved score",
backgroundColor: "rgba(255,99,132,0.2)",
borderColor: "rgba(255,99,132,1)",
borderWidth: 1,
hoverBackgroundColor: "rgba(255,99,132,0.4)",
hoverBorderColor: "rgba(255,99,132,1)",
data: chartConfig.scoreData,
}
]
};
You don't have to create the labels and data values inside a single object, but it's usually tidier if you can group your chart configuration data into one object so that you can pass it from one function to another with one parameter.
The data.datasets.label value does something different, providing text which appears in the chart legend and in tooltips which appear when you hover over a bar.

addData() dropped from latest chart.js 2.1.3 - whats up?

I've been reading the docs, and there are ways to replace the data then update the chart:
myLineChart.data.datasets[0].data[2] = 50; // Would update the first dataset's value of 'March' to be 50
myLineChart.update(); // Calling update now animates the position of March from 90 to 50.
https://github.com/chartjs/Chart.js/blob/master/docs/07-Advanced.md
But addData() appears to be gone, am I stuck with making my own addData for local data and then updating the whole chart? or am I missing something.
The update() handles adding data too. Just push your new data / labels into the config object that you passed when creating the chart and then call update()
For instance,
var config = {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
data: [65, 0, 80, 81, 56, 85, 40],
fill: false
}]
}
};
var ctx = document.getElementById("myChart").getContext("2d");
var myChart = new Chart(ctx, config);
setTimeout(function(){
config.data.labels.push('Test');
config.data.datasets[0].data.push(3);
myChart.update();
}, 1000);
Fiddle - http://jsfiddle.net/zpnx8ppb/

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

Meteor Collection to ChartJs Data

I have a Meteor Collection which I want to be presented into a graph using ChartJS. I was able to follow how ChartJS documentation.
My problem now is how to transform my collection and pass it on to ChartJS.
ChartJs Data format :
function drawChart() {
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
data: [28, 48, 40, 19, 86, 27, 90]
}]
};
This is how my collection was saved :
Categories.insert({
categoryname : $('#categoryname').val(),
value : $('#categoryvalue').val()
});
I wanted to use the categoryname as the chart labels and the value as the data. How am I going to do this?
This is how I made it work after another try after I posted my question.
function drawChart() {
var cur = Categories.find();
collData = [];
cur.forEach(function(cat){
collData.push([cat.value]);
});
collLabel = [];
cur.forEach(function(cat){
collLabel.push([cat.categoryname]);
});
var data = {
labels: collLabel,
datasets: [{
data: collData
}]
};
};
I am not sure if this the right way to do it but it works for now.

Categories