2011-08-10 01:10:50 +02:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
|
|
<html lang="en">
|
|
|
|
<head>
|
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
|
|
<title></title>
|
|
|
|
<!--[if lt IE 9]><script language="javascript" type="text/javascript" src="../excanvas.js"></script><![endif]-->
|
|
|
|
|
2011-11-07 21:37:55 +01:00
|
|
|
<link rel="stylesheet" type="text/css" href="../jquery.jqplot.min.css" />
|
2011-08-10 01:10:50 +02:00
|
|
|
<link rel="stylesheet" type="text/css" href="examples.css" />
|
|
|
|
|
|
|
|
<!-- BEGIN: load jquery -->
|
2011-11-07 21:37:55 +01:00
|
|
|
<script language="javascript" type="text/javascript" src="../jquery.min.js"></script>
|
2011-08-10 01:10:50 +02:00
|
|
|
<!-- END: load jquery -->
|
|
|
|
|
|
|
|
<!-- BEGIN: load jqplot -->
|
2011-11-07 21:37:55 +01:00
|
|
|
<script language="javascript" type="text/javascript" src="../jquery.jqplot.min.js"></script>
|
|
|
|
<script language="javascript" type="text/javascript" src="../plugins/jqplot.dateAxisRenderer.min.js"></script>
|
|
|
|
<script language="javascript" type="text/javascript" src="../plugins/jqplot.categoryAxisRenderer.min.js"></script>
|
|
|
|
<script language="javascript" type="text/javascript" src="../plugins/jqplot.canvasOverlay.min.js"></script>
|
2011-08-10 01:10:50 +02:00
|
|
|
|
|
|
|
<!-- END: load jqplot -->
|
|
|
|
<script language="javascript" type="text/javascript">
|
|
|
|
|
|
|
|
var data = [['2011-04-05 16:00', 1332.63],
|
|
|
|
['2011-04-04 16:00', 1332.87],
|
|
|
|
['2011-04-01 16:00', 1332.41],
|
|
|
|
['2011-03-31 16:00', 1325.83],
|
|
|
|
['2011-03-30 16:00', 1328.26],
|
|
|
|
['2011-03-29 16:00', 1319.44],
|
|
|
|
['2011-03-28 16:00', 1310.19],
|
|
|
|
['2011-03-25 16:00', 1313.8],
|
|
|
|
['2011-03-24 16:00', 1309.66],
|
|
|
|
['2011-03-23 16:00', 1297.54],
|
|
|
|
['2011-03-22 16:00', 1293.77],
|
|
|
|
['2011-03-21 16:00', 1298.38],
|
|
|
|
['2011-03-18 16:00', 1279.21],
|
|
|
|
['2011-03-17 16:00', 1273.72],
|
|
|
|
['2011-03-16 16:00', 1256.88],
|
|
|
|
['2011-03-15 16:00', 1281.87],
|
|
|
|
['2011-03-14 16:00', 1296.39],
|
|
|
|
['2011-03-11 16:00', 1304.28],
|
|
|
|
['2011-03-10 16:00', 1295.11],
|
|
|
|
['2011-03-09 16:00', 1320.02],
|
|
|
|
['2011-03-08 16:00', 1321.82],
|
|
|
|
['2011-03-07 16:00', 1310.13],
|
|
|
|
['2011-03-04 16:00', 1321.15],
|
|
|
|
['2011-03-03 16:00', 1330.97],
|
|
|
|
['2011-03-02 16:00', 1308.44],
|
|
|
|
['2011-03-01 16:00', 1306.33],
|
|
|
|
['2011-02-28 16:00', 1327.22],
|
|
|
|
['2011-02-25 16:00', 1319.88],
|
|
|
|
['2011-02-24 16:00', 1306.1],
|
|
|
|
['2011-02-23 16:00', 1307.4],
|
|
|
|
['2011-02-22 16:00', 1315.44],
|
|
|
|
['2011-02-18 16:00', 1343.01],
|
|
|
|
['2011-02-17 16:00', 1340.43],
|
|
|
|
['2011-02-16 16:00', 1336.32],
|
|
|
|
['2011-02-15 16:00', 1328.01],
|
|
|
|
['2011-02-14 16:00', 1332.32],
|
|
|
|
['2011-02-11 16:00', 1329.15],
|
|
|
|
['2011-02-10 16:00', 1321.87],
|
|
|
|
['2011-02-09 16:00', 1320.88],
|
|
|
|
['2011-02-08 16:00', 1324.57],
|
|
|
|
['2011-02-07 16:00', 1319.05]];
|
|
|
|
|
|
|
|
///////
|
|
|
|
// Put plot options in seperate object as a convienence.
|
|
|
|
// These will be reused when calling $.jqplot()
|
|
|
|
///////
|
|
|
|
var plotOptions = {
|
|
|
|
gridPadding: {top: 1},
|
|
|
|
grid: {shadow:false, borderWidth:1.0},
|
|
|
|
seriesDefaults: {
|
|
|
|
yaxis: 'y2axis'
|
|
|
|
},
|
|
|
|
axes: {
|
|
|
|
xaxis: {
|
|
|
|
renderer:$.jqplot.DateAxisRenderer,
|
|
|
|
tickOptions:{formatString:'%b %d'},
|
|
|
|
},
|
|
|
|
y2axis: {
|
|
|
|
tickOptions:{formatString:'%.4f'}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
series: [{
|
|
|
|
showMarker: false
|
|
|
|
}],
|
|
|
|
// noDataIndicator option. If no data is passed in on plot creation,
|
|
|
|
// A div will be placed roughly in the center of the plot. Whatever
|
|
|
|
// text or html is given in the "indicator" option will be rendered
|
|
|
|
// inside the div.
|
|
|
|
noDataIndicator: {
|
|
|
|
show: true,
|
|
|
|
// Here, an animated gif image is rendered with some loading text.
|
|
|
|
indicator: '<img src="ajax-loader.gif" /><br />Loading Data...',
|
|
|
|
// IMPORTANT: Have axes options set since y2axis is off by default
|
|
|
|
// and the yaxis is on be default. This is necessary due to the way
|
|
|
|
// plots are constructed from data and we don't have any data
|
|
|
|
// when using the "noDataIndicator".
|
|
|
|
axes: {
|
|
|
|
xaxis: {
|
|
|
|
min: 0,
|
|
|
|
max: 5,
|
|
|
|
tickInterval: 1,
|
|
|
|
showTicks: false
|
|
|
|
},
|
|
|
|
yaxis: {
|
|
|
|
show: false
|
|
|
|
},
|
|
|
|
y2axis: {
|
|
|
|
show: true,
|
|
|
|
min: 0,
|
|
|
|
max: 8,
|
|
|
|
tickInterval: 2,
|
|
|
|
showTicks: false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// Canvas overlay provides display of arbitrary lines on the plot and
|
|
|
|
// provides a convienent api to manipulate those lines after creation.
|
|
|
|
canvasOverlay: {
|
|
|
|
show: true,
|
|
|
|
// An array of objects to draw over plot. Here two horizontal lines.
|
|
|
|
// Options to control linne width, color, position and shadow are set.
|
|
|
|
// Can also provide a "name" option to refer to the line by name.
|
|
|
|
// IMPORTANT: set the proper yaxis to "bind" the line to.
|
|
|
|
objects: [
|
|
|
|
{dashedHorizontalLine: {
|
|
|
|
name: 'current',
|
|
|
|
y: 6,
|
|
|
|
lineWidth: 1.5,
|
|
|
|
color: 'rgb(60, 60, 60)',
|
|
|
|
yaxis: 'y2axis',
|
|
|
|
shadow: false,
|
|
|
|
dashPattern: [12, 12]
|
|
|
|
}}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
////////
|
|
|
|
// Build the initial plot with no data.
|
|
|
|
// It will show the animated gif indicator since we have
|
|
|
|
// the "noDataIndicator" option set on the plot.
|
|
|
|
///////
|
|
|
|
$(document).ready(function(){
|
|
|
|
plot1 = $.jqplot('chart1',[],plotOptions);
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
///////
|
|
|
|
// Functions to handle recreation of plot when data is available
|
|
|
|
// and to simulate new data coming into the plot and plot updates.
|
|
|
|
///////
|
|
|
|
|
|
|
|
|
|
|
|
///////
|
|
|
|
// Callback executed when "start" button on web page is pressed.
|
|
|
|
// Simulates recreation of plot when actual data is available. Sequence is:
|
|
|
|
//
|
|
|
|
// 1) empty plot container.
|
|
|
|
// 2) Recreate plot with call to $.jqplot()
|
|
|
|
// 3) Update position of current price line based on data.
|
|
|
|
// 4) Create the "pricePointer", a div inidcating the current price.
|
|
|
|
// 5) Call updatePricePointer to set current price text and position div.
|
|
|
|
// 6) Mock up streaming with a setInterval call.
|
|
|
|
///////
|
|
|
|
function startit(initialData) {
|
|
|
|
// 1) Empty container.
|
|
|
|
$('#chart1').empty();
|
|
|
|
// 2) Recreate plot.
|
|
|
|
// Note, only call the $.jqplot() method when entire plot needs recreated.
|
|
|
|
plot1 = $.jqplot('chart1', [initialData], plotOptions);
|
|
|
|
|
|
|
|
// get handle on last data point and current price line.
|
|
|
|
var dp = initialData[initialData.length-1];
|
|
|
|
var co = plot1.plugins.canvasOverlay;
|
|
|
|
var current = co.get('current');
|
|
|
|
|
|
|
|
// 3) Update the limit and stop lines based on the latest data.
|
|
|
|
current.options.y = dp[1];
|
|
|
|
co.draw(plot1);
|
|
|
|
|
|
|
|
// 4) Create the 'pricePointer', element and append to the plot.
|
|
|
|
$('<div id="pricePointer" style="position:absolute;"></div>').appendTo(plot1.target);
|
|
|
|
// 5) updatePricePointer method sets text and position to value passed in.
|
|
|
|
updatePricePointer(dp[1]);
|
|
|
|
|
|
|
|
// 6) Stuff to mock up streaming.
|
|
|
|
counter = 0;
|
|
|
|
Interval = setInterval(runUpdate, 500);
|
|
|
|
d = dp = co = limit = stop = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
///////
|
|
|
|
// Function to generate an updated data value
|
|
|
|
// for the last data point in the series.
|
|
|
|
// This does not change the timestamp, just the data value.
|
|
|
|
///////
|
|
|
|
function getNewDataPoint() {
|
|
|
|
// Need to generate some mock data. Will use the last data from
|
|
|
|
// the plot as a base set. Adjust the close value by a random amount,
|
|
|
|
|
|
|
|
// a slight adjustment to current price
|
|
|
|
var val = Math.random()*20 * (Math.random() - 0.1);
|
|
|
|
var d = plot1.series[0].data;
|
|
|
|
var dp = d[d.length-1];
|
|
|
|
// get the current values.
|
|
|
|
var ts = dp[0];
|
|
|
|
var curclose = dp[1];
|
|
|
|
|
|
|
|
// Set the new close value
|
|
|
|
var newval = curclose + val;
|
|
|
|
|
|
|
|
val = d = dp = curclose = null;
|
|
|
|
// Now return a new data set, note haven't changed or used the datetime value.
|
|
|
|
return ([ts, newval]);
|
|
|
|
}
|
|
|
|
|
|
|
|
////////
|
|
|
|
// function to simulate application loop, where app does something
|
|
|
|
// every time it gets a new data point.
|
|
|
|
////////
|
|
|
|
function runUpdate() {
|
|
|
|
|
|
|
|
// Simulate 1000 iterations of streaming for testing purposes.
|
|
|
|
if (counter < 10000) {
|
|
|
|
var newdata = getNewDataPoint();
|
|
|
|
// updatePlot method each time have an updated data point.
|
|
|
|
updatePlot(newdata);
|
|
|
|
// update pointer div with latest data val.
|
|
|
|
updatePricePointer(newdata[1]);
|
|
|
|
|
|
|
|
// Stuff for mock streaming
|
|
|
|
counter++;
|
|
|
|
newdata = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove the setInterval after 1000 iterations.
|
|
|
|
else {
|
|
|
|
clearInterval(Interval);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
////////
|
|
|
|
// Function updating plot when last data point is updated. If totally new
|
|
|
|
// data is fed in, can recreate plot with call to $.jqplot();
|
|
|
|
////////
|
|
|
|
function updatePlot(newdata) {
|
|
|
|
|
|
|
|
// get references for convienence.
|
|
|
|
var d = plot1.series[0].data;
|
|
|
|
var dp = d[d.length-1];
|
|
|
|
|
|
|
|
// Update the data on the series in the plot.
|
|
|
|
// Becuase of some inconsistent reference handling in some browsers,
|
|
|
|
// it is safest to set individual data elements by value.
|
|
|
|
dp[0] = newdata[0]; // the datetme
|
|
|
|
dp[1] = newdata[1]; // Close
|
|
|
|
|
|
|
|
// Get handle on the canvas overlary for the current price line.
|
|
|
|
var co = plot1.plugins.canvasOverlay;
|
|
|
|
var current = co.get('current');
|
|
|
|
|
|
|
|
// Update the y value of the current price line.
|
|
|
|
// This does not redraw the lines, just updates the values.
|
|
|
|
current.options.y = dp[1];
|
|
|
|
|
|
|
|
// Check to see if we need to rescale the plot,
|
|
|
|
// if the data is now above/below the axes.
|
|
|
|
if (dp[1] > plot1.axes.y2axis.max) {
|
|
|
|
plot1.replot({resetAxes:true});
|
|
|
|
// Need to re-create the 'pricePointer' element as it will be destoyed
|
|
|
|
// when the plot is recreated.
|
|
|
|
$('<div id="pricePointer" style="position:absolute;"></div>').appendTo(plot1.target);
|
|
|
|
// Set the "pricePointer" to the current price.
|
|
|
|
updatePricePointer(dp[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (dp[1] < plot1.axes.y2axis.min) {
|
|
|
|
plot1.replot({resetAxes:true});
|
|
|
|
// Need to re-create the 'pricePointer' element as it will be destoyed
|
|
|
|
// when the plot is recreated.
|
|
|
|
$('<div id="pricePointer" style="position:absolute;"></div>').appendTo(plot1.target);
|
|
|
|
// Set the "pricePointer" to the current price.
|
|
|
|
updatePricePointer(dp[1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If no axes rescaling needed, just redraw the series on the canvas
|
|
|
|
// and redraw the current price line at new positions.
|
|
|
|
else {
|
|
|
|
plot1.drawSeries({}, 0);
|
|
|
|
co.draw(plot1);
|
|
|
|
}
|
|
|
|
|
|
|
|
d = dp = newdata = limit = stop = co = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////
|
|
|
|
// function to update the text and reposition the price pointer
|
|
|
|
////////
|
|
|
|
function updatePricePointer(val) {
|
|
|
|
// get handle on the price pointer element.
|
|
|
|
var div = $('#pricePointer');
|
|
|
|
// Get a handle on the plot axes and one of the y2axis ticks.
|
|
|
|
var axis = plot1.axes.y2axis;
|
|
|
|
var tick = axis._ticks[0];
|
|
|
|
// use the tick's formatter to format the value string.
|
|
|
|
var str = tick.formatter(tick.formatString, val);
|
|
|
|
// set the text of the pointer.
|
|
|
|
div.html('« '+str);
|
|
|
|
// Create css positioning strings for the pointer.
|
|
|
|
var left = plot1._gridPadding.left + plot1.grid._width + 3 + 'px';
|
|
|
|
// use the axis positioning functions to set the right y position.
|
|
|
|
var top = axis.u2p(val) - div.outerHeight()/2 + 'px';
|
|
|
|
// set the div in the right spot
|
|
|
|
div.css({left:left, top:top});
|
|
|
|
|
|
|
|
div = axis = tick = str = left = top = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
function stopit() {
|
|
|
|
clearInterval(Interval);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style type="text/css">
|
|
|
|
#pricePointer {
|
|
|
|
background-color: rgba(40,40,40,0.7);
|
|
|
|
color: rgb(240,240,240);
|
|
|
|
padding: 2px 2px 2px 0px;
|
|
|
|
}
|
|
|
|
</style>
|
|
|
|
|
|
|
|
</head>
|
|
|
|
<body>
|
2011-11-07 21:37:55 +01:00
|
|
|
<?php include "topbanner.inc"; ?>
|
|
|
|
<div class="example-content">
|
|
|
|
<?php include "nav.inc"; ?>
|
2011-08-10 01:10:50 +02:00
|
|
|
<div id="chart1" style="margin:20px;height:400px; width:800px;"></div>
|
|
|
|
<div id="pricePointer" style="display:none;"></div>
|
|
|
|
<button onclick="startit(data)">Start</button>
|
|
|
|
<button onclick="stopit()">Stop</button>
|
2011-11-07 21:37:55 +01:00
|
|
|
|
|
|
|
</div>
|
|
|
|
</body>
|
2011-08-10 01:10:50 +02:00
|
|
|
</html>
|