How to show two charts in the same html page - javascript

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.

Related

Draw line in Phaser 3

I need your help. I am newbie in Phaser 3. I want to create game with simple rules. There are 36 dots, which situated in 6 rows. Player needs to unite dots with a line, but he can only unite dots with same color and union can happen only vertically and horizontally. So, you can't draw daigonal line. When you will finish union, dots will vanish. How I can realize union with line? My current code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/phaser.min.js"></script>
</head>
<body>
<script>
let config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#f0ebeb',
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
},
scale: {
autoCenter: Phaser.Scale.CENTER_BOTH
}
};
let game = new Phaser.Game(config);
let items = [];
function preload() {
for (let i = 1; i < 6; i++)
this.load.image(i, 'img/' + i + '.png');
}
function create() {
let x = 100;
let y = 0;
for (i = 0; i < 36; i++) {
if (i % 6 === 0) {
y += 85;
x = 100;
}
this.add.image(x, y, getRandomInt(5).toString())
x += 125;
}
}
function update() { }
function getRandomInt(max) {
return Math.floor(Math.random() * max) + 1;
}
</script>
</body>
</html>
I want something like this
I would just allow the user only to select (draw a line) to next valid circles.
A valid circle being, on the same row or same column or same color or max union length or ...
And when the drawing is finished I would, only allow union, when more than one circle is selected (is in the given path).
Here a short demo, how it could look like:
let config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 400,
height: 200,
banner: false,
scene: { create }
};
let game = new Phaser.Game(config);
let isDragging = false;
let lineStartPosition = {x:0 , y:0};
let currentPath = [];
let currentColor;
let line;
let pathGraphics;
function create ()
{
let cicles = []
for(let rowIdx = 0; rowIdx < 4; rowIdx++ ){
for(let colIdx = 0; colIdx < 2; colIdx++ ){
let circle = this.add.circle(50 + 100 * rowIdx, 50 + 100 * colIdx, 25, 0x6666ff).setOrigin(.5);
// Just to test a different color
if(rowIdx + colIdx ==2){
circle.fillColor = 0xff0000;
}
circle.setInteractive();
cicles.push(circle);
}
}
line = this.add.line(0,0, 0,0, 100, 100, 0xffffff).setOrigin(0);
line.setLineWidth(5);
line.visible = false;
pathGraphics = this.add.graphics();
// adding the events to the scene
this.input.on('pointerdown', dragStart);
this.input.on('pointerup', dragEnd);
this.input.on('pointermove', drag);
}
function dragStart(pointer, gameObjects){
if(gameObjects.length == 0){
return;
}
isDragging = true;
// remember Starting Color
currentColor = gameObjects[0].fillColor;
// initialize Path
currentPath = [gameObjects[0]];
// draw/save last segment of the path
lineStartPosition.x = gameObjects[0].x;
lineStartPosition.y = gameObjects[0].y;
line.x = gameObjects[0].x;
line.y = gameObjects[0].y;
line.setTo(0, 0, 0, 0);
line.visible = true;
}
function drag(pointer, gameObjects ){
if(isDragging == true){
// Check If Circle is allowed to be added, to path
// Here you would also check if the line is horizontal or vertical (this part is currently not implemented)
if(gameObjects[0] && currentPath.indexOf(gameObjects[0]) === -1 && currentColor == gameObjects[0].fillColor){
currentPath.push(gameObjects[0]);
line.x = gameObjects[0].x;
line.y = gameObjects[0].y;
lineStartPosition.x = gameObjects[0].x;
lineStartPosition.y = gameObjects[0].y;
}
line.setTo(0, 0, pointer.x - lineStartPosition.x, pointer.y - lineStartPosition.y);
drawPath();
}
}
function drawPath(){
pathGraphics.clear();
if(currentPath.length > 0){
pathGraphics.lineStyle(10, 0xffffff);
let path = new Phaser.Curves.Path(currentPath[0].x, currentPath[0].y);
for(let idx = 1; idx < currentPath.length; idx++){
let point = currentPath[idx];
path.lineTo(point.x, point.y);
}
path.draw(pathGraphics);
}
}
function dragEnd(pointer, gameObjects){
if(gameObjects.length == 0){
return;
}
if(currentPath.length < 2) {
console.info('No valid path');
return
} else {
console.info(`Valid Union path, length: ${currentPath.length}`);
}
line.visible = false;
isDragging = false;
}
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>

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();
});

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