I've searched thoroughly for an answer and haven't been able to track anything down that clears this up for me.
I'm building a simple webapp that has a java/mySQL backend and html/js front end. In my front end, I'm using values from my database in tandem with the chart.js library to visualize data. I'm using the Jersey framework on the backend and have written code that will return a desired value when the appropriate url is passed - for example:
http://localhost:8080/rest/database/chart/get/labels
returns
["test","test2","test3","test4","test5"]
I need to pass my chart an array of names for the axis on the chart.
Right now, my chart axis are names with placeholders, which is dictated by the .js script:
function loadChartLabels() {
var xhttp = new XMLHttpRequest();
var returnArray = [];
xhttp.onreadystatechange = function () {
if (xhttp.readyState == 4 && xhttp.status == 200) {
returnArray = xhttp.responseText;
}
};
xhttp.open("GET", "http://localhost:8080/rest/database/chart/get/labels", true);
xhttp.send();
return ["Eating", "Drinking", "21Test", "21Test1", "21Test2", "21Test3", "21Test4"];
//window.alert(returnArray.toString);
//return returnArray;
}
and here is my chart script:
var testArray = loadChartLabels();
var radarData = {
labels: testArray,
datasets: [
{
label: "My First dataset",
fillColor: "rgba(140,70,120,0.5)",
strokeColor: "#ACC26D",
pointColor: "#fff",
pointStrokeColor: "#9DB86D",
data: [65, 59, 90, 81, 56, 55, 40]
},
{
label: "My Second dataset",
fillColor: "rgba(172,194,132,0.4)",
strokeColor: "#ACC26D",
pointColor: "#fff",
pointStrokeColor: "#9DB86D",
data: [28, 48, 40, 19, 96, 27, 100]
}
]
};
var habits = document.getElementById("habits").getContext("2d");
new Chart(habits).Radar(radarData);
I'm assuming some variant of AJAX will allow me to call and return the database values and set them as the chart axis values, but how exactly do I accomplish this?
Any help is much appreciated!
If you need to process the data from AJAX, you can change the way the server outputs it. I would recommend a JSON - easy to use within JS and on server too.
However, If you need to work with data format as '["test","test2","test3","test4","test5"]', you can try using something like this
var myarray=eval('["test","test2","test3","test4","test5"]');
But remember! Eval might not be safe! See https://stackoverflow.com/a/86580/3129342
Related
I am using angular js and moment.js. Right now I am generating levels for line graph. So I need to set some levels for x axis values. I want to set hours interval in x'axis. Right now I am using these(x'aix) values statically, But now I want to set dynamically with javascript function.
var lineData = { labels: ["0hr", "1hr", "2hr", "3hr", "4hr", "5hr", "6hr"],
datasets: [
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 80]
}
]
};
var startFromTime=11;
var endToTime=15;
I want to set time interval from 11 to 15 in labels.
labels: ["0hr", "1hr", "2hr", "3hr", "4hr", "5hr", "6hr"]
can I set assign these value in array form to variable and this variable assign into labels:[1,2,3,4]
You don't need moment.JS for this rather a plain old JavaScript function would do the job.
function getTimeLabels(start) {
var timeStart = start;
var limit = 7;
var resultArr = [];
var counter = 0;
for (var x = 0; x < (timeStart + limit); x++) {
if (x > 24) {
resultArr.push(counter + "hr");
}
resultArr.push(x + "hr");
}
return resultArr;
}
Here you pass the number you wish to start at and it will generate your labels, it also takes into account when x goes over 24 and uses a different counter to finish operations occurring after.
your code modified:
var lineData = { labels: getTimeLabels(0),
datasets: [
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 80]
}
]
};
var startFromTime=11;
var endToTime=15;
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/
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 !!!
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.
I use chart JS
var chartGood = "rgba(50,182,93,0.5)";
var lineChartData = {
labels : ["3/14","3/15","3/16","3/17","3/18","3/19","3/20","3/21","3/22","3/23"],
datasets : [
{
fillColor : chartGood,
strokeColor : "rgba(255,255,255,1)",
pointColor : "rgba(50,182,93,1)",
pointStrokeColor : "#fff",
data : [12, 21, 28, 29, 31, 55, 52, 50, 49, 59]
}
]
}
var myLine = new Chart(document.getElementById("cpu-chart").getContext("2d")).Line(lineChartData);
I have 2 questions
How to make last bar another color
How to make last label as image
You can use the ChartNew.Js libary available at https://github.com/FVANCOP/ChartNew.js/ . This libary adds the functionality to add an array of object for the color options. It does add some options for changing the labels as well, but I do not think it is possible to use an image for the actual chart's labels. You may be able to modify the tooltip that pops up for that label doing something like: How to add image to chart.js tooltip?, but I cant say for sure. Here is some code that I used in a recent app to color code each bar based on the percent value of the data:
//Set all canvas options and fill with data
self.chartJs = function () {
//create an array for each column to be set into the chart properties -- also create arrays for the colors of the columns
var arrayOfJobData = self.chartData();
var descArray = [];
var effArray = [];
var colorArray = [];
for (i = 0; i < arrayOfJobData.length; i++) {
//console.log(arrayOfJobData[i].Cost_Code_Description);
descArray.push(arrayOfJobData[i].Cost_Code_Description);
//console.log(arrayOfJobData[i].Efficency);
effArray.push(arrayOfJobData[i].Efficency);
//Create an array of colors to match with the corresponding efficency % to show a + - relationship in the color scheme
if (arrayOfJobData[i].Efficency < 100) {
colorArray.push("red");
}
else if (arrayOfJobData[i].Efficency >= 100) {
colorArray.push("green");
}
}
//chart data is set and colors selected
var barChartData = {
labels: descArray, //array labels holding the desc for each cost code
datasets: [
{
type: "Bar",
//label: "Efficency %",
fillColor: colorArray,
strokeColor: "black",
pointColor: "rgba(220,220,220,1)",
pointstrokeColor: "white",
drawMathLine: "mean", //using the math functions add-in draw a line with the average %
mathLineStrokeColor: "orange",
data: effArray //array of efficency percent values
}]
}
You can basically build your own array of colors using a method somewhat like was mentioned by the other guy to set only the last color if you want too. The important thing is that you should use ChartNew.js to do what you want with ease.
Here is something more aligned with what you want in colors:
var chartGood = "rgba(50,182,93,0.5)";
var lineChartData = {
labels : ["3/20","3/21","3/22","3/23"],
datasets : [
{
fillColor: ["chartGood ","chartGood ","chartGood ","red"],
strokeColor : "rgba(255,255,255,1)",
pointColor : "rgba(50,182,93,1)",
pointStrokeColor : "#fff",
data : [ 52, 50, 49, 59]
}
]
}
There is also pretty good documentation for ChartNew.js at : https://github.com/FVANCOP/ChartNew.js/wiki/100.Available_options
for the point 1 :
To plot your last bar with different color, you can divide your dataset to different data arrays as follow : the first data array : you replace the last value by null ... and for the second data array, all the values are null except the last one !!
"datasets": [{
fillColor : chartGood,
strokeColor : "rgba(255,255,255,1)",
pointColor : "rgba(50,182,93,1)",
pointStrokeColor : "#fff",
data : [12, 21, 28, 29, 31, 55, 52, 50, 49, null]
},
{
fillColor : chartGood,
strokeColor : "rgba(255,0,0,1)",
pointColor : "rgba(50,182,93,1)",
pointStrokeColor : "#fff",
data : [null, null, null, null, null, null, null, null, null, 59]
}],
For the second point :
If you want that the last label will be an image : this is not possible with Chart.js .... however you can use some (html, css) tricks to place your image over the last label ...
As example you can plot a table below the labels, the number of columns = length of the labels set (in your case = 10)
You set as style = visibility: hidden for each column .. only the last one (visible)
You put a negative margin-top value (to place your image over the label)
Hope this help