Efficient real-time plotting using Plot.ly - javascript

I push data from node.js using socketio to the visualization website. The desired interval is 1ms.
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
</head>
<div id="tester" style="width:90%;height:70%;"></div>
<script type="text/javascript">
window.onload = function() {
console.log("testing")
TESTER = document.getElementById('tester');
var N = 1000
signals = {
time: [],
top: [],
bottom: []
};
var layout = {
yaxis: {range:[0, 1024]}
}
var socket = io();
console.log("Set up succefully!")
socket.on('data', function (msg) {
if (signals.time.length > N) {
signals.time.shift();
signals.top.shift();
signals.bottom.shift();
}
signals.time.push(msg['time'])
signals.top.push(msg['top'])
signals.bottom.push(msg['bottom'])
var trace1 = { x: signals.time,
y: signals.top}
var trace2 = { x: signals.time,
y: signals.bottom}
Plotly.newPlot( TESTER, [trace1, trace2], layout);
});
}
</script>
This works if I set the interval to be 1s. If I set it smaller than 0.5s, the whole page is not responding. I checked in the chrome application, and can see the socket io frames arriving. How can I fix this problem?

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.

CanvasJS line chart generation?

I am busy trying to make a javascript chart for real-time data display. I found this CanvasJS API. The default code for that specific chart on their webpage is nice, but of course the part where they get the data, they have left the variable array empty and used a math randomize data function instead, in order that specific data will be randomly generated and used in the graph.
However I would like to full that array with my database data coming from a specific table I would like to use!
I have tried many things but if I implement my part, the graph won't display anymore. What am I doing wrong?
Here are the 3 codes I use:
The default code (just for comparison purpose):
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
window.onload = function () {
var dps = []; // dataPoints
var chart = new CanvasJS.Chart("chartContainer",{
title :{
text: "Live Random Data"
},
data: [{
type: "line",
dataPoints: dps
}]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 20;
var dataLength = 500; // number of dataPoints visible at any point
var updateChart = function (count) {
count = count || 1;
// count is number of times loop runs to generate random dataPoints.
for (var j = 0; j < count; j++) {
yVal = yVal + Math.round(5 + Math.random() *(-5-5));
dps.push({
x: xVal,
y: yVal
});
xVal++;
};
if (dps.length > dataLength)
{
dps.shift();
}
chart.render();
};
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
setInterval(function(){updateChart()}, updateInterval);
}
</script>
<script type="text/javascript" src="/assets/script/canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width:100%;">
</div>
</body>
</html>
My own chart-code, based on the above code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title></title>
<script src="jquery.js"></script>
<script src="jquery.canvasjs.js" ></script>
<script src="canvasjs.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$.getJSON("data.php", function (result) {
var chart = new CanvasJS.Chart("chartContainer", {
data: [
{
dataPoints: result
}
]
});
chart.render();
});
});
</script>
</head>
<body>
<div id="chartContainer" style="width: 800px; height: 380px;"></div>
</body>
</html>
and my data.php which displays the following output:
[{"x":"1","y":"5"},{"x":"2","y":"5"},{"x":"3","y":"4"},{"x":"4","y":"1"},{"x":"5","y":"8"},{"x":"6","y":"9"},{"x":"7","y":"5"},{"x":"8","y":"6"},{"x":"9","y":"4"},{"x":"10","y":"7"}]
<?php
//header('Content-Type: application/json');
$con = mysqli_connect("localhost","root","","WebApplication");
// Check connection
if (mysqli_connect_errno($con))
{
echo "Failed to connect to DataBase: " . mysqli_connect_error();
}
else
{
$data_points = array();
$result = mysqli_query($con, "SELECT * FROM info");
while($row = mysqli_fetch_array($result))
{
$point = array("x" => $row['id'] , "y" => $row['acceleration']);
array_push($data_points, $point);
}
echo json_encode($data_points, 32); //define('JSON_NUMERIC_CHECK',32); // Since PHP 5.3.3
}
mysqli_close($con);
?>
Hopefully you have enough info!
Thank you
Mieer
EDIT
I swapped the code from 'my own chart' -code for the following, based on #feedback-comment from: Anjali Jain
-->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title></title>
<script src="jquery.js"></script>
<script src="jquery.canvasjs.js" ></script>
<script src="canvasjs.js"></script>
<script type="text/javascript" src="canvasjs.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$.getJSON("data.php", function (result) {
var dataPoints = [];
for (var i = 0; i <= result.length - 1; i++) {
dataPoints.push({ x: Number(result[i].x), y: Number(result[i].y) });
}
var chart = new CanvasJS.Chart("chartContainer", {
data: [
{
dataPoints: dataPoints
}
]
});
chart.render();
});
});
</script>
</head>
<body>
<div id="chartContainer" style="width: 800px; height: 380px;"></div>
</body>
</html>
Yet, I still get nothing.
CanvasJS requires x and y values to be numbers while you are passing strings directly. You can convert them to numbers as shown below
$.getJSON("data.php", function (result) {
var dataPoints = [];
for (var i = 0; i <= result.length - 1; i++) {
dataPoints.push({ x: Number(result[i].x), y: Number(result[i].y) });
}
var chart = new CanvasJS.Chart("chartContainer", {
data: [
{
dataPoints: dataPoints
}
]
});
chart.render();
});

Insert realtime data in Canvas js

I have been working some days with Canvas JS and made some amazing realtime diagrams, but the problem is; data is only random generated. I have managed to get some data from an sensor, and I wish to insert this data into Canvas JS, and remove random generated data, but I can not figure out how to replace the real data with random generated data?
Just to repeat my question, what modifications do I need to do in order to insert realtime data instead of random generated data?
Here is the code I got from Canvas JS (Code Example from canvasjs).
<script type="text/javascript">
window.onload = function () {
var dps = []; // dataPoints
var chart = new CanvasJS.Chart("chartContainer",{
title :{
text: "Live Random Data"
},
data: [{
type: "line",
dataPoints: dps
}]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 20;
var dataLength = 500; // number of dataPoints visible at any point
var updateChart = function (count) {
count = count || 1;
// count is number of times loop runs to generate random dataPoints.
for (var j = 0; j < count; j++) {
yVal = yVal + Math.round(5 + Math.random() *(-5-5));
dps.push({
x: xVal,
y: yVal
});
xVal++;
};
if (dps.length > dataLength)
{
dps.shift();
}
chart.render();
};
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
setInterval(function(){updateChart()}, updateInterval);
}
</script>
This should do the job
<script type="text/javascript">
window.onload = function () {
var dps = []; // dataPoints
var ws = new WebSocket("ws://IP(hidden):8081/osc");
var chart = new CanvasJS.Chart("chartContainer",{
title :{
text: "Live Random Data"
},
data: [{
type: "line",
dataPoints: dps
}]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 20;
var dataLength = 500; // number of dataPoints visible at any point
ws.onmessage = function(evt) {
var point = evt.data.split(",");
// To ensure we have recieved both x and y values
if ( point.length === 2 ){
dps.push({
x: parseInt( point[0] ),
y: parseInt( point[1] )
});
}
if (dps.length > dataLength){
dps.shift();
}
chart.render();
}
}
</script>
Thanks for helping me Mr. Lakha Singh Namdhari! The diagram is now receiving data, the only thing I had to do was to remove the if statement around the code. Because this if statement gave me only 0s for dps.length.. The problem was that dps.length was equal to 0 (constant). So when I removed the if statement, the dps.length started to increment correctly.
I have some things left such as design and time delay etc, but I will start a new thread because this questions is solved.
I changed this:
if ( point.length === 2 ){
dps.push({
x: parseInt( point[0] ),
y: parseInt( point[1] )
});
}
To this:
dps.push({
x: parseInt( point[0] ),
y: parseInt( point[1] )
});
I have basically created a diagram where it stores temperature values. Everything works great, the only problem is that the x-axis does not go out from the frame. I want the x-axis to move with the data. Like the link below.
Here is the example!
This is the code, I have hidden the IP for security reasons. What shall I implement in order to make the x-axis move with the data?
<script type="text/javascript">
window.onload = function () {
var dps = []; // dataPoints
// Connect to the server.
var server_url = "ws://";
var ip = 'xxx.xxx.x.xx';
server_url = server_url.concat(ip,":8081/osc")
ws = new WebSocket(server_url);
var chart = new CanvasJS.Chart("chartContainer",{
title :{
text: "Temp Bank Sensor 1 - (TBS1)"
},
data: [{
type: "splineArea",
color: "rgba(255, 0, 29, 0.79)",
dataPoints: dps
}]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 20;
var dataLength = 500; // number of dataPoints visible at any point
ws.onmessage = function(evt) {
var point = evt.data.split(",");
dps.push({
x: xVal,
y: parseInt( point[1] )
});
xVal++;
if (dps.length > dataLength){
dps.shift();
}
chart.render();
} // end method ws.onmessage
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
setInterval(function(){updateChart()}, updateInterval);
}; // end method window.onload
</script>

How to fuse these two javascript files?

I have a javascript file that is loading up the google charts API and drawing a graph, and another javascript file that handles an html form on the page. I'd like to fuse these two together, as the form will be providing the graph with data. However, when I try to put there google charts js file (graph.js), it refuses to load the graph. I've tried putting it in several locations, but it only loads if the graph.js is a separate js file that is linked within the html document. Can someone tell me how I can properly combine these two files:
CostComparer.js (the form handler):
$(document).ready(function(){
//variable setup
var wifi;
var firewall;
var backup;
var vpn;
var install;
var result;
$('#submit').click(function(){
$("#chart_div").show('slow');
$("#table_div").show('slow');
wifi = $('input[name=wifiPrice]').val();
firewall = $('input[name=firewallPrice]').val();
backup = $('input[name=backupPrice]').val();
vpn = $('input[name=vpnPrice]').val();
install = $('input[name=installPrice]').val();
result = parseInt(wifi) + parseInt(firewall) + parseInt(backup) + parseInt(vpn) + parseInt(install);
var resultbox = $('#result');
var cccontainer = $('#cccontainer');
if(resultbox.height() < 10){
cccontainer.hide('slow').delay(500);
cccontainer.show('slow');
setTimeout(function() {
resultbox.append('<h1>You Paid: <br />$' + result + '</h1>')
}, 500);
} else {
resultbox.empty()
cccontainer.hide('slow').delay(500);
cccontainer.show('slow');
setTimeout(function() {
resultbox.append('<h1>You Paid: <br />$' + result + '</h1>')
}, 500);
}
});
});
and graph.js:
google.load("visualization", "1", {packages: ["corechart"]});
google.setOnLoadCallback(drawChart);
var competitorCost = function(time){
return 3000 + (time * 300)
};
var ourCost = function(time){
return 1000 + (time * 50);
};
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Months', 'Entreda', 'Competitors'],
['0', ourCost(0), competitorCost(0)],
['6', ourCost(6), competitorCost(6)],
['12', ourCost(12), competitorCost(12)],
['18', ourCost(18), competitorCost(18)],
['24', ourCost(24), competitorCost(24)]
]);
var options = {
title: 'Entreda vs Competitor Costs',
width: 445,
height: 250,
pointSize: 5
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
There was a problem with my compiler it seems. It worked after appending graph.js to the bottom outside of $document.ready():
$(document).ready(function(){
//variable setup
var wifi;
var firewall;
var backup;
var vpn;
var install;
var result;
$('#submit').click(function(){
$("#chart_div").show('slow');
$("#table_div").show('slow');
wifi = $('input[name=wifiPrice]').val();
firewall = $('input[name=firewallPrice]').val();
backup = $('input[name=backupPrice]').val();
vpn = $('input[name=vpnPrice]').val();
install = $('input[name=installPrice]').val();
result = parseInt(wifi) + parseInt(firewall) + parseInt(backup) + parseInt(vpn) + parseInt(install);
var resultbox = $('#result');
var cccontainer = $('#cccontainer');
if(resultbox.height() < 10){
cccontainer.hide('slow').delay(500);
cccontainer.show('slow');
setTimeout(function() {
resultbox.append('<h1>You Paid: <br />$' + result + '</h1>')
}, 500);
} else {
resultbox.empty()
cccontainer.hide('slow').delay(500);
cccontainer.show('slow');
setTimeout(function() {
resultbox.append('<h1>You Paid: <br />$' + result + '</h1>')
}, 500);
}
});
});
google.load("visualization", "1", {packages: ["corechart"]});
google.setOnLoadCallback(drawChart);
var competitorCost = function(time){
return 3000 + (time * 300)
};
var ourCost = function(time){
return 1000 + (time * 50);
};
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Months', 'Entreda', 'Competitors'],
['0', ourCost(0), competitorCost(0)],
['6', ourCost(6), competitorCost(6)],
['12', ourCost(12), competitorCost(12)],
['18', ourCost(18), competitorCost(18)],
['24', ourCost(24), competitorCost(24)]
]);
var options = {
title: 'Entreda vs Competitor Costs Over Time',
width: 480,
height: 270,
pointSize: 5
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}

Categories

Resources