Insert realtime data in Canvas js - javascript

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>

Related

Getting a canvasjs graph to fit in a collapsed table row in Bootstrap?

I have created a canvasjs graph and want it to fit in a responsive table in Bootstrap.
I have created a large table in Bootstrap/HTML5 with one row defined as follows:
<tr>
<td colspan="100%" class="hiddenRow">
<div class="collapse" id="cellOneExp">
<div id="chartContainer1"></div>
</div>
</td>
</tr>
chartContainer1 refers to a dynamic graph created using canvasjs and has the following code:
window.onload = function () {
var dps = []; // dataPoints
var chart = new CanvasJS.Chart("chartContainer1",{
zoomEnabled: true,
title :{
text: "Cell 1 Temperature (\xB0C)"
},
axisX: {
title:"Time (seconds)",
},
axisY:{
title: "Temperature (\xB0C)",
},
data: [{
type: "line",
dataPoints: dps
}]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 100;
var dataLength = 5000; // 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();
if (yVal>"100") {
$('#alertHigh').slideDown(); //callback function will go in the brackets to slide the alert back up
$('#alertLow').slideUp();
} else if (yVal<"-100") {
$('#alertLow').slideDown();
$('#alertHigh').slideUp();
} else {
$('#alertLow').slideUp();
$('#alertHigh').slideUp();
};
//print stuff
document.getElementById("cell1").innerHTML=yVal + "°C";
};
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
setInterval(function(){updateChart()}, updateInterval); }
The table has a button in it which has the id cellOneExp, so when that button is pressed the table should expand to show the graph.
If is replaced with anything else (for example a p tag) the table expands appropriately. However with the graph present the table does not expand correctly. Instead the graph overlays the rest of the table elements and I cannot figure out how to solve this. Thanks!

Adding dynamic alerts (with fixed position) using HTML5/Bootstrap and Javascript?

I want to add alerts to the top of a web page. The javascript is as follows;
window.onload = function () {
var dps = []; // dataPoints
var chart = new CanvasJS.Chart("chartContainer",{
title :{
text: "Cell 1 Temperature (\xB0C)"
},
axisX: {
title:"Time (seconds)",
},
axisY:{
title: "Temperature (\xB0C)",
},
data: [{
type: "line",
dataPoints: dps
}]
});
var xVal = 0;
var yVal = 100;
var updateInterval = 100;
var dataLength = 5000; // 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();
//print stuff
document.getElementById("cell1").innerHTML=yVal + "°C";
};
// generates first set of dataPoints
updateChart(dataLength);
// update chart after specified time.
setInterval(function(){updateChart()}, updateInterval);
}
Essentially when that yVal variable is less than -100 or greater than 100 I want to print an alert dialog to the top of the web page. I want the alert to disappear when the value goes back between -100 and 100. I also want the alert to be fixed to the top of the web page so when it does appear it remains there even if the user scrolls down.
I attempted to add the following code to the javascript:
if (-100>yVal>100) {
document.getElementById("alert1").innerHTML="DANGA'";
} else {
document.getElementById("alert2").innerHTML="S'All GOOOD";
}
and have the following alerts in the HTML:
<div class="alert alert-danger" style="position: fixed" id="alert1"></div>
<div class="alert alert-success" style="position: fixed" id="alert2"></div>
But there are several problems. First, once triggered these alerts never change. And to begin with these alerts are always present, there just isn't any text in them until triggered.
If someone knew a way to have these alerts appear and disappear only when desired, and when present to remain in a fixed position, that would be appreciated.
Thanks

Canvas.js slows down

The problem:
The problem I am encountering is that for each "JQuery event" click, the canvas.js diagram slows down proporsjonal to the click? I believe $(document).ready(function(){ is responsible.
That is to say 10 clicks slows down the applciation 10 times. Keep in mind that I have five canvas.js diagrams (tables). Canvas.js
Table1.js (The same code structure goes for the other diagrams, table2,table3 etc).
(function table1(){
$(document).ready(function(){
var dps = []; // data
var chart = new CanvasJS.Chart("table1",
{
title:{
text: "Exhaust Temperature"
data: [
{
type: "spline",
name: "Temp Cylinder 1",
showInLegend: "true",
legendText: "Temp Cylinder 1",
dataPoints: dps1
}
});
var xVal = 0;
var updateInterval = 50;
var dataLength = 50;
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++) {
dps.push({
x: xVal,
y: EXTS[1]
});
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);
});
}());
This is JQuery event that is responsible for showing and hiding the diagrams, keep in mind that the user can only view one diagram at time.
$('[data-row]').on('click', function() {
var row = $(this).attr('data-row');
$('.active').removeClass('active');
$('#table' + row).addClass('active');
if (row == 1){
$.getScript("table1.js", function(){});
table1();
} else if (row == 2) {
$.getScript("table2.js", function(){});
table2();
} else if (row == 3) {
$.getScript("table3.js", function(){});
table3();
}
});

NVD3 - How to refresh the data function to product new data on click

I have a line chart and every time the page refresh it changes the data, which is great but I need to to refresh by a user click. This is because there will eventually be other input fields on the page and refreshing the page would destroy their current session.
jsfiddle - http://jsfiddle.net/darcyvoutt/dXtv2/
Here is the code setup to create the line:
function economyData() {
// Rounds
var numRounds = 10;
// Stability of economy
var stable = 0.2;
var unstable = 0.6;
var stability = unstable;
// Type of economy
var boom = 0.02;
var flat = 0;
var poor = -0.02;
var economyTrend = boom;
// Range
var start = 1;
var max = start + stability;
var min = start - stability;
// Arrays
var baseLine = [];
var economy = [];
// Loop
for (var i = 0; i < numRounds + 1; i++) {
baseLine.push({x: i, y: 1});
if (i == 0) {
economyValue = 1;
} else {
var curve = Math.min(Math.max( start + ((Math.random() - 0.5) * stability), min), max);
economyValue = Math.round( ((1 + (economyTrend * i)) * curve) * 100) / 100;
}
economy.push({x: i, y: economyValue});
}
return [
{
key: 'Base Line',
values: baseLine
},
{
key: 'Economy',
values: economy
}
];
}
Here is what I tried to write but failed for updating:
function update() {
sel = svg.selectAll(".nv-line")
.datum(data);
sel
.exit()
.remove();
sel
.enter()
.append('path')
.attr('class','.nv-line');
sel
.transition().duration(1000);
};
d3.select("#update").on("click", data);
Here is what I did differently with your code.
// Maintian an instance of the chart
var chart;
// Maintain an Instance of the SVG selection with its data
var chartData;
nv.addGraph(function() {
chart = nv.models.lineChart().margin({
top : 5,
right : 10,
bottom : 38,
left : 10
}).color(["lightgrey", "rgba(242,94,34,0.58)"])
.useInteractiveGuideline(false)
.transitionDuration(350)
.showLegend(true).showYAxis(false)
.showXAxis(true).forceY([0.4, 1.6]);
chart.xAxis.tickFormat(d3.format('d')).axisLabel("Rounds");
chart.yAxis.tickFormat(d3.format('0.1f'));
var data = economyData();
// Assign the SVG selction
chartData = d3.select('#economyChart svg').datum(data);
chartData.transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
Here's how the update() function looks like:
function update() {
var data = economyData();
// Update the SVG with the new data and call chart
chartData.datum(data).transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
};
// Update the CHART
d3.select("#update").on("click", update);
Here is a link to a working version of your code.
Hope it helps.

JQuery FLOT chart dynamic Y-axis

I have a flot chart that calculates the max Y-axis value based on the last 100 data points and then plots successfully...
BUT
Sometimes, the running total of an ongoing plot (5 second delay with new data point plotted) exceeds the current max limit.
Is there a way to have the Y-axis scale dynamically while plotting new points on the chart?
This is a valid question about how to dynamically scale the Y Axis of the chart if the current Y-axis is exceeded, since the chart is plotted over time with new points being added every 5 seconds, I was asking how to scale the Y-Axis to fit the NEW plot data if it reaches above the current Max Y Axis value..
UPDATE:
here is the code I use (Json returned data) as well as the plot update timer:
The "highY" takes the last 100 datapoints from a database and sets the max value to the highest count + 10%
<script type="text/javascript">
$(function () {
var str1 = [], totalPoints = 300;
var str2 = [], totalPoints = 300;
var pts1 = '';
var pts2 = '';
if (pts1 == "" || pts == null) { pts = '2012-10-02 17:17:02'; }
if (pts2 == "" || pts == null) { pts = '2012-10-02 17:17:02'; }
var maxYaxis = <?PHP echo $highY; ?>;
function getStr1() {
var ts1 = new Date().getTime();
var json1 = (function () {
var json1 = null;
var myURL = '<?PHP echo $updateURL; ?>?s=1&ts=' + ts1;
$.ajax({
'async': false,
'global': false,
'url': myURL,
'dataType': "json",
'success': function (data) {
json1 = data;
}
});
return json1;
})();
var y1 = json1['data']['avgpersec'];
var total_1 = json1['data']['running_total'];
document.getElementById('<?PHP echo $string1; ?>Total').innerHTML = total_1;
if (str1.length > 0) { str1 = str1.slice(1); }
while (str1.length < totalPoints) {
var prev = str1.length > 0 ? str1[str1.length - 1] : 50;
str1.push(y1);
}
// zip the generated y values with the x values
var res = [];
for (var i = 0; i < str1.length; ++i){ res.push([i, str1[i]]) }
return res;
}
function getStr2() {
var ts2 = new Date().getTime();
var json2 = (function () {
var json2 = null;
var myURL = '<?PHP echo $updateURL; ?>?s=2&ts=' + ts2;
$.ajax({
'async': false,
'global': false,
'url': myURL,
'dataType': "json",
'success': function (data) {
json2 = data;
}
});
return json2;
})();
var y2 = json2['data']['avgpersec'];
var total_2 = json2['data']['running_total'];
document.getElementById('<?PHP echo $string2; ?>Total').innerHTML = total_2;
if (str2.length > 0) { str2 = str2.slice(1); }
while (str2.length < totalPoints) {
var prev = str2.length > 0 ? str2[str2.length - 1] : 50;
str2.push(y2);
}
// zip the generated y values with the x values
var res = [];
for (var i = 0; i < str2.length; ++i){ res.push([i, str2[i]]) }
return res;
}
// setup control widget
var updateInterval = 5000;
$("#updateInterval").val(updateInterval).change(function () {
var v = $(this).val();
if (v && !isNaN(+v)) {
updateInterval = +v;
if (updateInterval < 1)
updateInterval = 1;
if (updateInterval > 2000)
updateInterval = 2000;
$(this).val("" + updateInterval);
}
});
// setup plot
var options = {
series: { shadowSize: 0 }, // drawing is faster without shadows
yaxis: { min: 0, max: maxYaxis},
xaxis: { show: false },
colors: ["<?PHP echo $string1Color; ?>","<?PHP echo $string2Color; ?>"]
};
var plot = $.plot($("#placeholder"), [ getStr1(), getStr2() ], options);
function update() {
plot.setData([ getStr1(), getStr2() ]);
plot.draw();
setTimeout(update, updateInterval);
}
update();
});
</script>
What i am hoping to accomplish is to adjust the "$highY" (Y-axis) value real time as i plot new data points so that the chart will scale if the value of the new data plot point exceeds the current "yaxis { max: # }" set in the chart options.
I'm assuming that right now you're using flot.setData and flot.draw?
The simplest solution is just to call $.plot with the new data each time you receive it. At various times, this has been recommended by the authors of the flot plugin as a reasonably efficient way of dealing with this situation. I've used this on graphs that refresh every second and found that it does not use an excessive amount of CPU on the user's computer, even with 3-4 graphs refreshing every second on one page.
EDIT based on the code you added (and your suggested edit), I would change the update function to look like this:
function update() {
var data = [ getStr1(), getStr2() ];
//modify options to set the y max to the new y max
options.yaxis.max = maxYaxis;
$.plot($("#placeholder"), data, options);
setTimeout(update, updateInterval);
}
Additionally, you would add code to getStr and getStr that keep the maxYaxis variable up to date.

Categories

Resources