<!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]--> <link rel="stylesheet" type="text/css" href="../jquery.jqplot.min.css" /> <link rel="stylesheet" type="text/css" href="examples.css" /> <!-- BEGIN: load jquery --> <script language="javascript" type="text/javascript" src="../jquery.min.js"></script> <!-- END: load jquery --> <!-- BEGIN: load jqplot --> <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> <!-- 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> <?php include "topbanner.inc"; ?> <div class="example-content"> <?php include "nav.inc"; ?> <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> </div> </body> </html>