I try to display data retrieved from web API via a ajex request using rickshaw. Data is retrieved correctly and added to an array. However the chart does not render any data. When I console the series data array it shows all data. Here is my code
var seriesData = [
[]
];
$.ajax({
url: "http://things.ubidots.com/api/v1.6/devices/Smart-
FAD/Temperature/values?page_size=50&format=json&&token=A1E-
BR1Y0dMLAULMNmMLbk0Y8qADGOdS5h",
type: "GET"
}).done(function(data) {
var result = data.results;
for (var i = 0; i < result.length; i++) {
var value = result[i].value;
var time = result[i].timestamp;
seriesData[0][i].push({
"x": time,
"y": value
});
};
}).fail(function() {
console.log("REQUEST FAILED");
});
var graph = new Rickshaw.Graph({
element: document.querySelector("#chart"),
width: 540,
height: 240,
series: [{
data: seriesData[0],
color: 'steelblue',
name: 'Server1'
}]
});
var x_axis = new Rickshaw.Graph.Axis.Time({
graph: graph
});
var y_axis = new Rickshaw.Graph.Axis.Y({
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis'),
});
graph.render();
Can some help me to solve this?
Rickshaw doesn't watch for changes in the dataset automatically so you need to call graph.update() at the end of you ajax.done function.
.done(function(data) {
var result = data.results;
for (var i = 0; i < result.length; i++) {
var value = result[i].value;
var time = result[i].timestamp;
seriesData[0].push({
"x": time,
"y": value
});
};
graph.update()
Related
I am trying to convert a JSON string into an integer so that I can use this data in a google chart. As of right now I can only get one set of data to be displayed in my chart.
Here is my JQUERY code:
$("#shotsandbigcc").click(function(){
//alert("Button works");
$("#shotsandbigcc_popup").toggle();
var integer = $("#shotsandbigcc").attr("name");
//alert("integer: " + integer);
$.ajax('includes/test.php', {
type: 'POST', // http method
data: {myData: integer},// data to submit
dataType: 'json',
success: function(response){
google.charts.load('current', {packages: ['corechart', 'bar']});
google.charts.setOnLoadCallback(drawMultSeries);
function drawMultSeries() {
var len = response.length;
for(var i=0; i<len; i++){
var year = response[i].Year;
var ontarget = parseInt(response[i].Shots_on_Target);
var offtarget = parseInt(response[i].Shots_off_Target);
alert(ontarget);
}
alert(year);
var data = google.visualization.arrayToDataTable([
['Year', 'Shots on Target', 'Shots off Target'],
[year, ontarget, offtarget],
[year, ontarget, offtarget]
]);
var options = {
title: 'Shooting Accuracy',
chartArea: {width: '50%'},
hAxis: {
title: 'Amount of Shots',
minValue: 0
},
vAxis: {
title: 'Year'
}
};
var chart = new google.visualization.BarChart(document.getElementById('shotsandbigcc_chart'));
chart.draw(data, options);
}
}
});
});
The JSON data is in an array which has this format [{"Year":"2019/2020","Shots_on_Target":"302","Shots_off_Target":"578","Accuracy":"0.34"},{"Year":"2020/2021","Shots_on_Target":"74","Shots_off_Target":"93","Accuracy":"0.44"}]
If someone could tell me how I can display both 2019/2020 and 2020/2021 data to be displayed. I would be most grateful as right now only the 2020/2021 data is being displayed. Thank you.
For integet value part:
var ontarget = parseInt(response[i].Shots_on_Target);
For your data part:
var vizData = [];
vizData.push(['Year', 'Shots on Target', 'Shots off Target']);
for(var i=0; i<len; i++){
var year = response[i].Year;
var ontarget = parseInt(response[i].Shots_on_Target);
var offtarget = parseInt(response[i].Shots_off_Target);
vizData.push([year, ontarget, offtarget]);
alert(ontarget);
}
alert(year);
var data = google.visualization.arrayToDataTable(vizData);
explaination: since in the loop the values are getting updated in every iteration so, the 'year', 'ontarget' and 'offtarget' will have the latest values only. So on every iteration you have to store values so that they do not get overwritten. For that now this code is pushing in array in every iteration preserving the previous values. Which now you can use in the google.visualization function.
Happy Coding!
Im trying to plot 2 separate graphs (actually it will be 9 but for now there are only 2) using flotJS, somehow the data mixes and plots the same mixed data on both graphs
Here is my JS code:
var graphData1, graphData2, graphData3 = [];
var graphBuffer = 1000;
var xmin = 0;
var xmax = 5;
var options = {
xaxes: [
{position: 'bottom', autoScale: 'none', min: 0, max: 5}
],
yaxes: [
{position: 'left', autoScale: 'none', min: -1.5, max: 1.5}
],
zoom: {interactive: true},
pan: {interactive: true}
};
function deleteGraph() {
graphData1 = graphData2 = graphData3 = [];
$.plot("#graph1", [{graphData1}], options);
$.plot("#graph2", [{graphData2}], options);
//$.plot("#graph3", [{graphData3}], options);
}
function updateGraph(data) {
var datatmp = data.data;
// Formatea y Almacena datos a graficar
datatmp.forEach(function (sample) {
graphData1.push([parseFloat(sample.timestamp.toFixed(4)), parseFloat(sample.sensor1.toFixed(4))]);
//graphData2.push([parseFloat(sample.timestamp.toFixed(4)), parseFloat(sample.sensor2.toFixed(4))]);
});
$.plot("#graph1", [graphData1], options);
$.plot("#graph2", [graphData2], options);
}
and with this code the output is:
As you can see its plotting the same information on both graphs even when //graphData2.push([parseFloat(sample.timestamp.toFixed(4)), parseFloat(sample.sensor2.toFixed(4))]); is commented
However if i remove the comment the result is this:
As you can see its mixing the data and plotting the same mixed data on both graphs
How can i plot different data on different graphs?
Thanks for your help...
You are setting graphData1 = graphData2 so they are the same array. Then you push all your data points into that one array which is shown in both charts.
Replace
var graphData1, graphData2, graphData3 = [];
// and
function deleteGraph() {
graphData1 = graphData2 = graphData3 = [];
with
var graphData1 = [], graphData2 = [], graphData3 = [];
// and
function deleteGraph() {
graphData1 = [];
graphData2 = [];
graphData3 = [];
I am using the following code to render an OHLC chart in CanvasJS:
<script>
var candleData = [];
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: 'Demo Stacker Candlestick Chart (Realtime)'
},
zoomEnabled: true,
axisY: {
includeZero: false,
title: 'Price',
prefix: '$'
},
axisX: {
interval: 1,
},
data: [{
type: 'ohlc',
dataPoints: candleData
}
]
});
function mapDataToPointObject(data) {
var dataPoints = [];
for(var i = 0; i < data.length; i++) {
var obj = data[i];
var newObj = {
x: new Date(obj.time),
y: [
obj.open,
obj.high,
obj.low,
obj.close
]
}
dataPoints.push(newObj);
}
return dataPoints;
}
function updateChart() {
$.ajax({
url: 'http://localhost:8080',
success: function(data) {
candleData = JSON.parse(data);
candleData = mapDataToPointObject(candleData);
chart.render();
}
});
}
$(function(){
setInterval(() => {
updateChart();
}, 500);
});
The data properly loads, parses into the correct format, and render() is called on the interval like it should. The problem is, while the chart axes and titles all render properly, no data shows up. The chart is empty.
What DOES work is setting the data directly to the chart using
chart.options.data[0].dataPoints = candleData;
Why does my above solution not work then? Is there a way I can update the chart's dataPoints without having to hardcode a direct accessor to the chart's dataPoints?
It's related to JavaScript pass by value and pass by reference.
After execution of the following line.
dataPoints: candleData
dataPoints will refer to the current value of candleData. ie. dataPoints = [];
Now if you redefine candleData to any other value.
candleData = JSON.parse(data);
candleData = mapDataToPointObject(candleData);
Then dataPoints won't be aware of this update and will still refer to the empty array (that you pointed earlier).
The following snippet will make it easy to understand
//pass by value
var a = "string1";
var b = a;
a = "string2";
alert("b is: " + b); //this will alert "string1"
//pass by reference
var c = { s: "string1" };
var d = c;
c.s = "string2";
alert("d.s is: " + d.s); //this will alert "string2"
For more, you can read about pass by value and pass by reference.
Javascript by reference vs. by value
Explaining Value vs. Reference in Javascript
I used this ,to multiply doughnut chart according as array(arr) has,but it can't change to object,(data has string type).So chart doesn't appear here..,how fix it
var arr=['HTML','CSS','JS'],i,data;
data ='[';
for(i=0;i<arr.length;i++){
if(i==arr.length-1){
data+='{value:"300",color:"#fff",highlight:"#aaa",label:arr[i]}';
}
else{
data+='{value:"300",color:"#fff",highlight:"#aaa",label:arr[i]},';
}
}
data += ']';
var dat = data;
window.onload = function () {
var ctx = document.getElementById("chart-area").getContext("2d");
window.myBar = new Chart(ctx).Doughnut(dat,{
responsive: true,
});
};
//want like this
dat =[{value:"300",color:"#fff",highlight:"#aaa",label:"HTML"},
{value:"200",color:"#fff",highlight:"#aaa",label:"CSS"}];
You are creating your array as a String.
You need to create an array of objects [{},{},{}].
The method used to INSERT a new object in an array is PUSH().
Check the fiddle. Now it´s working OK (move the mouse on the screen to see the chart is there (you will only see it when mouse is over it):
window.onload = function() {
var arr = ['HTML', 'CSS', 'JS'],
i, data;
data = [];
for (i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
data.push({
value: "300",
color: "#fff",
highlight: "#aaa",
label: arr[i]
});
} else {
data.push({
value: "300",
color: "#fff",
highlight: "#aaa",
label: arr[i]
});
}
}
var dat = data;
var ctx = document.getElementById("chart-area").getContext("2d");
window.myBar = new Chart(ctx).Doughnut(dat, {
responsive: true,
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/nnnick/Chart.js/master/Chart.js"></script>
<canvas id="chart-area"></canvas>
I need to know how I can easily add another series to an existing plot using Flot.
Here is how I currently plot a single series:
function sendQuery() {
var host_name = $('#hostNameInput').val();
var objectName = $('#objectNameSelect option:selected').text();
var instanceName = $('#instanceNameSelect option:selected').text();
var counterName = $('#counterNameSelect option:selected').text();
$.ajax({
beforeSend: function () {
$('#loading').show();
},
type: "GET",
url: "http://okcmondev102/cgi-bin/itor_PerfQuery.pl?machine=" + host_name + "&objectName=" + objectName + "&instanceName=" + instanceName + "&counterName=" + counterName,
dataType: "XML",
success: function (xml) {
var results = new Array();
var counter = 0;
var $xml = $.xmlDOM(xml);
$xml.find('DATA').each(function () {
results[counter] = new Array(2);
results[counter][0] = $(this).find('TIMESTAMP').text();
results[counter][1] = $(this).find('VALUE').text();
counter++;
});
plot = $.plot($("#resultsArea"), [{
data: results,
label: host_name
}], {
series: {
lines: {
show: true
}
},
xaxis: {
mode: "time",
timeformat: "%m/%d/%y %h:%S%P"
},
colors: ["#000099"],
crosshair: {
mode: "x"
},
grid: {
hoverable: true,
clickable: true
}
});
You can just add another results set:
// build two data sets
var dataset1 = new Array();
var dataset2 = new Array();
var $xml = $.xmlDOM(xml);
$xml.find('DATA').each(function(){
// use the time stamp for the x axis of both data sets
dataset1[counter][0] = $(this).find('TIMESTAMP').text();
dataset2[counter][0] = $(this).find('TIMESTAMP').text();
// use the different data values for the y axis
dataset1[counter][1] = $(this).find('VALUE1').text();
dataset2[counter][2] = $(this).find('VALUE2').text();
counter++;
});
// build the result array and push the two data sets in it
var results = new Array();
results.push({label: "label1", data: dataset1});
results.push({label: "label2", data: dataset2});
// display the results as before
plot = $.plot($("#resultsArea"), results, {
// your display options
});
At a high-level, the result of your call into itor_PerfQuery.pl will need to be extended to include the additional series data. You'll then want to make your "results" variable a multi-dimensional array to support the additional data and you'll need to update the current xml "find" loop which populates results accordingly. The remainder of the code should stay the same as flot should be able to plot the extended dataset. I think a review of the flot example will help you out. Best of luck.