Problem getting access to an array variable in a javascript - javascript

Hi I have the following script
The page can also be seen in action here
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml2/DTD/xhtml1-strict.dtd">
<!-- Version: 1.0.0 -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples</title>
<link href="layout.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../jquery.flot.js"></script>
</head>
<body onLoad="myFunction()">
Show All Coverafdedge
Show: </div>
<p><span id="x">0</span>, <span id="y">0</span></p>
<p><input id="enableTooltip" type="checkbox">Enable tooltip</p>
<script type="text/javascript">
var datasets = [];
var xmlhttp;
function loadXMLDoc(url,cfunc){
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=cfunc;
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
function myFunction(){
loadXMLDoc("parsers.json",handleXML);
}
var checkState = function(xmlhttp, callback) {
//document.write(xmlhttp.readyState);
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
callback();
} else {
// Check back again 1 sec later
setTimeout(checkState, 1000);
}
};
function handleXML() {
checkState(xmlhttp, function() {
var txt=xmlhttp.responseText;
datasets = [];
var datasetsCounter =0;
var secondPos = 0;
var aPosition = 0;
var currentCharacterLocation =0;
var textLeft =txt;
do
{
aPosition = textLeft.indexOf("#");
secondPos = textLeft.indexOf(";");
evaluedText = textLeft.substring(aPosition+1,secondPos);
datasets[currentCharacterLocation] = eval("(" + evaluedText + ")");
currentCharacterLocation++;
textLeft = textLeft.substring(secondPos + 1);
}
while (textLeft.indexOf("#") > -1);
});
}
function printing(){
for(var g =0; g < datasets.length; g++ ){
document.write(datasets[g].cover.data + "__");
}
}
$(function () {
var d1 = [];
var d2 = datasets[0].cover.data;
// a null signifies separate line segments
var d3 = [[0, 12], [7, 12], null, [7, 2.5], [12, 2.5]];
$.plot($("#placeholder"), [ d1, d2, d3 ]);
});
</script>
</body>
</html>
Now to my problem that I have with the variable "datasets", if I for example try to print out "datasets[0].cover.data" (Like I do in my function printing(), I can do that (Try yourself clicking on the link on that page). But when I try to use the variable inside the
"var d2 = datasets[0].cover.data", I get the error that its datasets[0].cover.data is not defined :S
Anyone know what I am doing wrong here? =)
Thanks

Your issue is that the function in $(function() { ... }); is running when your body onload is called. You need to do something like
$(function () {
loadXMLDoc("parsers.json", function () {
handleXML(); // possibly add a callback to this function which calls the remaining code in this function
var d1 = [];
var d2 = datasets[0].cover.data;
// a null signifies separate line segments
var d3 = [[0, 12], [7, 12], null, [7, 2.5], [12, 2.5]];
$.plot($("#placeholder"), [d1, d2, d3]);
});
});
And then remove the call from body onload

Your function is running on document ready, but before the datasets variable is populated.
Move the code to the end of the callback function:
do
{
...
}
while (textLeft.indexOf("#") > -1);
var d1 = [];
var d2 = datasets[0].cover.data;
// a null signifies separate line segments
var d3 = [[0, 12], [7, 12], null, [7, 2.5], [12, 2.5]];
$.plot($("#placeholder"), [ d1, d2, d3 ]);
});
}

You haven't initialised the array at the time you call "var d2 = datasets[0].cover.data".

Well, there is nothing in datasets at that point, so there is no datasets[0], so of course there can be no datasets[0].cover.data!
Ask yourself: How is datasets supposed to be populated, and where and when is that to occur?
It gets populated in handleXML but that only happens after the var d2 line.
Also, using eval is generally frowned upon, see this stackoverflow question for details.

Related

How to show two charts in the same html page

I'm working on a project where I should show two kind of charts :
a Real time Chart and I'm using smoothie.js lib for this.
a normal chart with zoom option and I'm using canvas lib for this.
as it showen in the code below the smoothie.js use on the body tag an "onload" :
<!DOCTYPE html>
<meta charset="utf-8">
<html>
<head>
<title>Pression en temps réel</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script type="text/javascript" src="smoothie.js"></script>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript">
window.bufferX = [];
setInterval(function () {
if( typeof lastid == 'undefined' ) {
$.get( "../be.php/lastid_1", function( dataA ) {
lastid = dataA[0].id_x+1;
})
}
else {
$.get( "../be.php/1&"+lastid, function( dataB ) {
var i =0;
var j=0;
if( typeof counter == 'undefined' ) {
counter = 0;
}
if( typeof pck_prev == 'undefined' ) {
pck_prev = -1;
}
lastid = dataB[0].last_id;
for(i=0;i<dataB.length;i++) {
for(j=0;j<dataB[i].data.length;j++) {
if(dataB[i].data[j] !== "" && dataB[i].data[j] !== 0 && typeof dataB[i].data[j] !== 'undefined' && pck_prev !== dataB[i].pck) {
window.bufferX.push(dataB[i].data[j]);
}
}
pck_prev = dataB[i].pck;
}
if(typeof window.bufferX[counter] == 'undefined') {
data_p.append(new Date().getTime(), window.bufferX[counter-1]);
}
})
}
},3000);
var data_p = new TimeSeries();
setInterval(function() {
if(window.bufferX.length>50 && counter <window.bufferX.length)
{
if( typeof counter == 'undefined' ) {
counter = 0;
}
else {
data_p.append(new Date().getTime(), window.bufferX[counter]);
counter++;
}
}
}, 250);
function createTimeline() {
var chart = new SmoothieChart({responsive: true});
chart.addTimeSeries(data_p, { strokeStyle: 'rgba(0, 255, 0, 1)', fillStyle: 'rgba(0, 255, 0, 0.2)', lineWidth: 4 });
chart.streamTo(document.getElementById("chart"), 250);
}
</script>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer",
{
zoomEnabled: true,
title:{
text: "Try Zooming And Panning"
},
axisY:{
includeZero: false
},
data: data, // random generator below
});
chart.render();
}
var limit = 1000; //increase number of dataPoints by increasing this
var y = 0;
var data = []; var dataSeries = { type: "line" };
var dataPoints = [];
for (var i = 0; i < limit; i += 1) {
y += (Math.random() * 10 - 5);
dataPoints.push({
x: i - limit / 2,
y: y
});
}
dataSeries.dataPoints = dataPoints;
data.push(dataSeries);
</script>
</head>
<body onload="createTimeline()">
<canvas id="chart" style="width:100%; height:700px;"></canvas>
<div id="chartContainer" style="height: 700px; width: 100%;">
</div>
</body>
</html>
The problem is if I delete onload from body tag I will get the canvas chart only and if I let it I will get the real time chart only.
I would like to have both charts showen on my page.
Thanks for reading.
window.onload and <body onload="yourfunction();"> are different ways of using the same event and you are using both which is causing the issue. The easiest way to fix this problem is that you should write both the implementation in one event either in window.onload or in onload of body tag.
Find the updated fiddle here.
You can find both the chart are visible at the same time.

Dynamic chart with CanvasJs doesn't get update while reading from a file

I've been trying to get a dynamic chart working with CanvasJs. I have a file that gets updated (by another program) and I would like to update my chart each time I have a new record.
I've seen this example (last chart) and I tried to do the same but I'm actually reading from a file.
Here is my code :
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" src="https://canvasjs.com/assets/script/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript">
window.onload = function () {
var dps = [{x: new Date(2017, 04, 20, 07, 20, 00 ), y: 30}]; //dataPoints.
var chart = new CanvasJS.Chart("chartContainer",{
title:{
text: " Cooling Machine Status "
},
axisX:{
valueFormatString: "DD-MM-YY HH:mm:ss" ,
labelAngle: -50
},
axisY:{
title: "Cooling Temperature (F)"
},
data: [{
type: "line",
showInLegend: true,
name: "Temperature",
dataPoints : dps
}]
});
chart.render();
var updateChart = function () {
var rawFile = new XMLHttpRequest();
rawFile.open("GET","/analyticResults/coolingMachine.csv", true);
rawFile.onreadystatechange = function ()
{
if(rawFile.readyState === 4)
{
if(rawFile.status === 200 || rawFile.status == 0)
{
var dps = csvLines = points = [];
csvLines = rawFile.responseText.split(/[\r?\n|\r|\n]+/);
for (var i = 0; i < csvLines.length; i++)
if (csvLines[i].length > 0) {
points = csvLines[i].split(",");
var dateTime = points[0].split(" ");//dateTime[0] = date, dateTime[1] = time
var date = dateTime[0].split("-");
var time = dateTime[1].split(":");
dps.push({
x: new Date(date[2], date[1], date[0], time[0], time[1], time[2]),
y: parseFloat(points[1])
});
}
}
}
};
rawFile.send(null);
if (dps.length > 10 )
{
dps.shift();
}
chart.render();
};
setInterval(function(){updateChart()}, 1000);
}
</script>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width: 70%;">
</div>
</body>
</html>
When I debug the javascript I can see that the values are getting pushed in dps but the chart is not updating...
Did I miss someting ?
Thank you for your time
You are passing dps to chart-dataPoints. But at the same time you are pushing dps that is declared locally within updateChart method. Removing dps declaration within updateChart method should work in your case.

How to get HtmlUnit to update page after javascript has finished

I am trying to load the contents of a div which changes when a listener is triggered.
The java code I currently have is:
public static void main(String arg[]) throws IOException{
String url = "http://localhost/chartsTest/test.html";
WebClient wc = new WebClient();
HtmlPage p = null;
try {
System.out.println("Attempting to load page: " + url);
p = wc.getPage(url);
System.out.println("Sucsess!");
} catch (Exception e) {
System.err.println("Failed to get page");
}
JavaScriptJobManager m = p.getEnclosingWindow().getJobManager();
int c;
while ((c = m.getJobCount()) > 0){
System.out.println("Jobs: " + c);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
}
div = p.getHtmlElementById("test");
content = div.asText();
System.out.println(content);
wc.close();
}
and my test.html page (which loads a google chart) is:
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("visualization", '1', {packages:['corechart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
// var query = new google.visualization.Query('simpleexample?tq=select name,population');
// query.send(handleSimpleDsResponse);
handleSimpleDsResponse(true);
function handleSimpleDsResponse(response) {
// var data = response.getDataTable();
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses'],
['2013', 1000, 400],
['2014', 1170, 460],
['2015', 660, 1120],
['2016', 1030, 540]
]);
var chart_div = document.getElementById('chart_div');
var chart_data = document.getElementById('chart_data');
var test = document.getElementById('test');
var chart = new google.visualization.AreaChart(chart_div);
// Wait for the chart to finish drawing before calling the getImageURI() method.
google.visualization.events.addListener(chart, 'ready', function () {
chart_div.innerHTML = '<img src="' + chart.getImageURI() + '">';
chart_data.innerHTML = chart.getImageURI();
test.innerHTML = "after";
});
chart.draw(data);
}
}
</script>
</head>
<body>
<div id="test">before</div>
<div id='chart_div'></div>
<div id="chart_data"></div>
</body>
</html>
but when I print the div it always equals before and not after. How can I get the value for after the chart has finished loading?
This is a bug of handling Promise.resolve(), and it has been fixed in SVN.
Please use new WebClient(BrowserVersion.CHROME), with the latest build or snapshot.
There is no need to wait(), as it is not AJAX-based.

Flot not honoring series config for "dynamically" created charts

The second chart below should have a green line and red dots like the first one, however it didn't happen:
CHART IMAGE HERE: unfortunately i can't post images but the sample is simple enough to be opened in a browser to see it.
Here's my default.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>My Flot Sample</title>
<link href="Content/examples.css" rel="stylesheet" />
<script src="Scripts/jquery.js"></script>
<script src="Scripts/jquery.flot.js"></script>
</head>
<body>
<input id="Submit1" type="submit" value="submit"/>
<div id="myPlot13" style="width:600px;height:300px"></div>
<div id="myPlot24" style="width:600px;height:300px"></div>
<script src="Scripts/default.js"></script>
</body>
</html>
And here's default.js:
var x = 0;
var y = 0;
var numPoints = 50;
var delay = 50;
var d1 = [];
var d2 = [];
var d3 = [];
var d4 = [];
var serie1 = {
color: "#00FF00",
data: d1,
lines: {
lineWidth: 0.5
}
};
var serie2 = {
color: "#00FF00",
data: d2,
lines: {
lineWidth: 0.5
}
};
var serie3 = {
color: "#FF0000",
data: d3,
points: {
show: true,
lineWidth: 0,
fill: true,
fillColor: "#FF0000",
radius: 7
}
};
var serie4 = {
color: "#FF0000",
data: d4,
points: {
show: true,
lineWidth: 0,
fill: true,
fillColor: "#FF0000",
radius: 7
}
};
var data13 = [serie1, serie3];
var data24 = [serie2, serie4];
var options = {
grid: {
backgroundColor: "#000000",
color: "#FFFFFF"
}
};
function init_data13() {
for (x = 0; x < numPoints; x++) {
y += (Math.random() - 0.5);
d1.push([x, y]);
if (x % 15 == 0 && x > 0) {
d3.push([x, y]);
}
}
}
function getData24() {
if (d2.length < numPoints) {
y += (Math.random() - 0.5);
d2.push([x, y]);
if (x % 15 == 0 && x > 0) {
d4.push([x, y]);
}
x++;
}
return [d2, d4];
}
init_data13();
$.plot("#myPlot13", data13, options);
var btn = document.getElementById('Submit1');
btn.onclick = addChart;
function addChart() {
x = 0;
y = 0;
var somePlot = $.plot("#myPlot24", data24, options);
function updatePlot() {
somePlot.setData(getData24());
somePlot.draw();
somePlot.setupGrid();
setTimeout(updatePlot, delay);
}
updatePlot();
}
The only difference is that the second chart is created "dynamically" when the SUBMIT button is clicked.
Apologies for that, I understand now. See here for a working demo (that updates in real time). I modified the updatePlot() function as follows:
function updatePlot() {
// Destroy the current chart
somePlot.shutdown();
// Get the data with the new data point
getData24();
// Recreate the chart
somePlot = $.plot("#myPlot24", data24, options);
setTimeout(updatePlot, delay);
}
It computes the next point by calling getData24() then calls the $.plot function to recreate the chart with the new data point.
Edit
Have found another way to do it without creating a brand new chart. You can call the getData24() function then pass data24 as a parameter to somePlot.setData()
function updatePlot() {
// Add the next data point
getData24();
// Pass the data to the existing chart (along with series colours)
somePlot.setData(data24);
somePlot.draw();
somePlot.setupGrid();
setTimeout(updatePlot, delay);
}
See here for a Fiddle

Strange behaviour of included JS file in node.js

I am making a node app that is in it current state very simple, but I get an issue I can't figure out.
The generated html of my express app looks like this:
<html style="" class=" js no-touch svg inlinesvg svgclippaths no-ie8compat">
<head>
...
<script type="text/javascript" src="/javascripts/mouse.js"></script>
...
</head>
<body class="antialiased" style=""><div class="row"><div class="row">
<script>
var mouse;
var X = 0;
var Y = 0;
window.onload = function()
{
alert(Mouse());//=> undefined
mouse = Mouse();
mouse.setMouseMoveCallback(function(e){ //THIS LINE FAILS: "Cannot call method 'setMouseMoveCallback' of undefined"
X = e.x;
Y = e.y;
alert("move");
});
}
...
</html>
The include script tag in the header adds this javascript file:
function Mouse(onObject){
var mouseDown = [0, 0, 0, 0, 0, 0, 0, 0, 0],
mouseDownCount = 0;
var mouseDownCallbacks = [0, 0, 0, 0, 0, 0, 0, 0, 0];
var mouseTracer = 0;
var tracePosArray;
var target = onObject;
if(!onObject){
onObject = document;
}
onObject.onmousedown = function(evt) {
mouseDown[evt.button] = 1;
mouseDownCount--;
if(mouseDownCallbacks[evt.button] != 0){
mouseDownCallbacks[evt.button](evt);
}
}
onObject.onmouseup = function(evt) {
mouseDown[evt.button] = 0;
mouseDownCount--;
}
var mousemoveCallback;
onObject.onmousemove = function(evt){
//Tracing mouse here:
if(mouseTracer){
tracePosArray.push([evt.pageX,evt.pageY]);
}
if(mousemoveCallback){
mousemoveCallback(evt);
}
}
var mouseWheelCallback;
onObject.onmousewheel = function(evt){
if(mouseWheelCallback){
mouseWheelCallback(evt);
}
}
var mouseOverCallback;
onObject.onmouseover = function(evt){
if(mouseOverCallback){
mouseOverCallback(evt);
}
}
var mouseOutCallback;
onObject.onmouseout = function(evt){
if(mouseOutCallback){
mouseOutCallback(evt);
}
}
//TODO: There is a bug when you move the mouse out while you are pressing a button. The key is still counted as "pressed" even though you release it outside of the intended area
//NOTE: might have fixed the bug. Do some further investigation by making a smaller element.
this.anyDown = function(){
if(mouseDownCount){
for(p in mouseDown){
if(mouseDown[p]){
return true;
}
}
}
}
this.setLeftDownCallbackFunction = function(fun){
mouseDownCallbacks[0] = fun;
}
this.setRightDownCallbackFunction = function(fun){
mouseDownCallbacks[2] = fun;
}
this.setMiddleDownCallbackFunction = function(fun){
mouseDownCallbacks[4] = fun;
}
this.setSpcifiedDownCallbackFunction = function(num, fun){
mouseDownCallbacks[num] = fun;
}
this.leftDown = function(){
if(mouseDownCount){
return mouseDown[0] != 0;
}
}
this.rightDown = function(){
if(mouseDownCount){
return mouseDown[2] != 0;
}
}
this.middleDown = function(){
if(mouseDownCount){
return mouseDown[4] != 0;
}
}
this.setMouseMoveCallback = function (callback){
mousemoveCallback = callback;
}
this.setMouseWheelCallback = function (callback){
mouseWheelCallback = callback;
}
this.setMouseOverCallback = function (callback){
mouseOverCallback = callback;
}
this.setMouseOutCallback = function (callback){
mouseOutCallback = callback;
}
this.enableTracer = function(){
tracePosArray = new Array();
mouseTracer = 1;
}
this.getMouseTracerData = function() {
return tracePosArray;
}
}
So: I have assured that the JS file is loaded. But none the less I am not able to access the Mouse() method in my window.onload function in the body, it shows up as undefined. This is very strange to me because if I create a HTML file that does exactly the same thing I am able to access it.
What is going on here? Is there some magic trickery in node.js / express that disables this kind of interaction?
Additional notes:
I am using Jade as the template engine.
The "mouse.js" file works. I have used it several times before.
I am using socket.io for communication between the client and server.
Complete header:
<head><title>My awesome title</title><link rel="stylesheet" href="/stylesheets/foundation.min.css"><link rel="stylesheet" href="/stylesheets/normalize.css"><link rel="stylesheet" href="/stylesheets/style.css"><script type="text/javascript" src="/socket.io/socket.io.js"></script><style type="text/css"></style><script type="text/javascript" src="/javascripts/jquery.min.js"></script><script type="text/javascript" src="/javascripts/vendor/custom.modernizr.js"></script><script type="text/javascript" src="/javascripts/vendor/zepto.js"></script><script type="text/javascript" src="/javascripts/mouse.js"></script><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"><meta name="viewport" content="width=device-width"></head>
That would throw an error if the Mouse function is undefined. The reason alert shows 'undefined' is that the Mouse function doesn't return anything, hence undefined. It should be used as a constructor, as in 'new Mouse()'

Categories

Resources