extranet/www/graphs/phpdemo/zoomscrolldemo2.php

426 lines
20 KiB
PHP
Raw Normal View History

<?php
require_once("../lib/phpchartdir.php");
#
# Copyright 2006 Advanced Software Engineering Limited
#
# You may use and modify the sample code in this file in your application, provided the Sample Code
# and its modifications are used only in conjunction with ChartDirector. Usage of this software is
# subjected to the terms and condition of the ChartDirector license.
#
#/
#/ We need to handle 3 types of request:
#/ - initial request for the full web page
#/ - partial update (AJAX chart update) to update the chart without reloading the page
#/ - full page update for old browsers that does not support partial updates
#/
#/ <summary>
#/ Handles the initial request
#/ </summary>
#/ <param name="WebChartViewer">The WebChartViewer object to handle the chart.</param>
function createFirstChart(&$viewer) {
# Initialize the Javascript ChartViewer
$viewer->setScrollDirection(DirectionHorizontalVertical);
$viewer->setZoomDirection(DirectionHorizontalVertical);
$viewer->setMouseUsage(MouseUsageScroll);
# Draw the chart
drawChart($viewer);
}
#/ <summary>
#/ Handles partial update (AJAX chart update)
#/ </summary>
#/ <param name="WebChartViewer">The WebChartViewer object to handle the chart.</param>
function processPartialUpdate(&$viewer) {
# In this demo, we just need to redraw the chart
drawChart($viewer);
}
#/ <summary>
#/ Handles full update
#/ </summary>
#/ <param name="WebChartViewer">The WebChartViewer object to handle the chart.</param>
function processFullUpdate(&$viewer) {
# In this demo, we just need to redraw the chart
drawChart($viewer);
}
#/ <summary>
#/ Draw the chart
#/ </summary>
#/ <param name="WebChartViewer">The WebChartViewer object to handle the chart.</param>
function drawChart(&$viewer) {
#
# For simplicity, in this demo, we just use hard coded data. In a real application, the data may
# come from a dynamic source such as a database. (See "Using Data Sources with ChartDirector" in
# the ChartDirector documentation if you need some sample code on how to read data from database
# to array variables.)
#
$dataX0 = array(10, 15, 6, -12, 14, -8, 13, -3, 16, 12, 10.5, -7, 3, -10, -5, 2, 5);
$dataY0 = array(130, 150, 80, 110, -110, -105, -130, -15, -170, 125, 125, 60, 25, 150, 150, 15,
120);
$dataX1 = array(6, 7, -4, 3.5, 7, 8, -9, -10, -12, 11, 8, -3, -2, 8, 4, -15, 15);
$dataY1 = array(65, -40, -40, 45, -70, -80, 80, 10, -100, 105, 60, 50, 20, 170, -25, 50, 75);
$dataX2 = array(-10, -12, 11, 8, 6, 12, -4, 3.5, 7, 8, -9, 3, -13, 16, -7.5, -10, -15);
$dataY2 = array(65, -80, -40, 45, -70, -80, 80, 90, -100, 105, 60, -75, -150, -40, 120, -50, -30
);
# Create an XYChart object 500 x 480 pixels in size, with light blue (c0c0ff) as background
# color
$c = new XYChart(500, 480, 0xc0c0ff);
# Set the plotarea at (50, 40) and of size 400 x 400 pixels. Use light grey (c0c0c0) horizontal
# and vertical grid lines. Set 4 quadrant coloring, where the colors of the quadrants alternate
# between lighter and deeper grey (dddddd/eeeeee).
$plotAreaObj = $c->setPlotArea(50, 40, 400, 400, -1, -1, -1, 0xc0c0c0, 0xc0c0c0);
$plotAreaObj->set4QBgColor(0xdddddd, 0xeeeeee, 0xdddddd, 0xeeeeee, 0x000000);
# Enable clipping mode to clip the part of the data that is outside the plot area.
$c->setClipping();
# Set 4 quadrant mode, with both x and y axes symetrical around the origin
$c->setAxisAtOrigin(XYAxisAtOrigin, XAxisSymmetric + YAxisSymmetric);
# Add a legend box at (450, 40) (top right corner of the chart) with vertical layout and 8 pts
# Arial Bold font. Set the background color to semi-transparent grey (40dddddd).
$legendBox = $c->addLegend(450, 40, true, "arialbd.ttf", 8);
$legendBox->setAlignment(TopRight);
$legendBox->setBackground(0x40dddddd);
# Add titles to axes
$c->xAxis->setTitle("Alpha Index");
$c->yAxis->setTitle("Beta Index");
# Set axes line width to 2 pixels
$c->xAxis->setWidth(2);
$c->yAxis->setWidth(2);
# The default ChartDirector settings has a denser y-axis grid spacing and less-dense x-axis grid
# spacing. In this demo, we want the tick spacing to be symmetrical. We use around 40 pixels
# between major ticks and 20 pixels between minor ticks.
$c->xAxis->setTickDensity(40, 20);
$c->yAxis->setTickDensity(40, 20);
#
# In this example, we represent the data by scatter points. If you want to represent the data by
# somethings else (lines, bars, areas, floating boxes, etc), just modify the code below to use
# the layer type of your choice.
#
# Add scatter layer, using 11 pixels red (ff33333) X shape symbols
$c->addScatterLayer($dataX0, $dataY0, "Group A", Cross2Shape(), 11, 0xff3333);
# Add scatter layer, using 11 pixels green (33ff33) circle symbols
$c->addScatterLayer($dataX1, $dataY1, "Group B", CircleShape, 11, 0x33ff33);
# Add scatter layer, using 11 pixels blue (3333ff) triangle symbols
$c->addScatterLayer($dataX2, $dataY2, "Group C", TriangleSymbol, 11, 0x3333ff);
# if (viewer.getCustomAttr("minY") == null) {
if (($viewer->getCustomAttr("minY") == null) || ($viewer->getCustomAttr("minY") == "")) {
# The axis scale has not yet been set up. This means this is the first time the chart is
# drawn and it is drawn with no zooming. We can use auto-scaling to determine the
# axis-scales, then remember them for future use.
# explicitly auto-scale axes so we can get the axis scales
$c->layout();
# save the axis scales for future use
$xAxisObj = $c->xAxis;
$viewer->setCustomAttr("minX", $xAxisObj->getMinValue());
$xAxisObj = $c->xAxis;
$viewer->setCustomAttr("maxX", $xAxisObj->getMaxValue());
$yAxisObj = $c->yAxis;
$viewer->setCustomAttr("minY", $yAxisObj->getMinValue());
$yAxisObj = $c->yAxis;
$viewer->setCustomAttr("maxY", $yAxisObj->getMaxValue());
} else {
# Retrieve the original full axes scale
$minX = $viewer->getCustomAttr("minX");
$maxX = $viewer->getCustomAttr("maxX");
$minY = $viewer->getCustomAttr("minY");
$maxY = $viewer->getCustomAttr("maxY");
# Compute the zoomed-in axis scales by multiplying the full axes scale with the view port
# ratio
$xScaleMin = $minX + ($maxX - $minX) * $viewer->getViewPortLeft();
$xScaleMax = $minX + ($maxX - $minX) * ($viewer->getViewPortLeft() +
$viewer->getViewPortWidth());
$yScaleMax = $maxY - ($maxY - $minY) * $viewer->getViewPortTop();
$yScaleMin = $maxY - ($maxY - $minY) * ($viewer->getViewPortTop() +
$viewer->getViewPortHeight());
# Set the axis scales
$c->xAxis->setLinearScale($xScaleMin, $xScaleMax);
$c->yAxis->setLinearScale($yScaleMin, $yScaleMax);
# By default, ChartDirector will round the axis scale to the tick position. For zooming, we
# want to use the exact computed axis scale and so we disable rounding.
$c->xAxis->setRounding(false, false);
$c->yAxis->setRounding(false, false);
}
# Create the image and save it in a temporary location
$chartQuery = $c->makeSession($viewer->getId());
# Include tool tip for the chart
$imageMap = $c->getHTMLImageMap("", "",
"title='[{dataSetName}] Alpha = {x|G}, Beta = {value|G}'");
# Set the chart URL, image map, and chart metrics to the viewer
$viewer->setImageUrl("getchart.php?".$chartQuery);
$viewer->setImageMap($imageMap);
$viewer->setChartMetrics($c->getChartMetrics());
}
# Create the WebChartViewer object
$viewer = new WebChartViewer("chart1");
if ($viewer->isPartialUpdateRequest()) {
# Is a partial update request (AJAX chart update)
processPartialUpdate($viewer);
# Since it is a partial update, there is no need to output the entire web page. We stream the
# chart and then terminate the script immediately.
print($viewer->partialUpdateChart());
exit();
} else if ($viewer->isFullUpdateRequest()) {
# Is a full update request
processFullUpdate($viewer);
} else {
# Is a initial request
createFirstChart($viewer);
}
?>
<html>
<head>
<title>ChartDirector Zoom and Scroll Demonstration (2)</title>
<script language="Javascript" src="cdjcv.js"></script>
<style>
div.chartPushButtonSelected { padding:5px; background:#ccffcc; cursor:hand; }
div.chartPushButton { padding:5px; cursor:hand; }
td.chartPushButton { font-family:Verdana; font-size:9pt; cursor:pointer; border-bottom:#000000 1px solid; }
</style>
</head>
<body leftMargin="0" topMargin="0" onload="initJsChartViewer()">
<script>
// Initialize browser side Javascript controls
function initJsChartViewer()
{
// Check if the Javascript ChartViewer library is loaded
if (!window.JsChartViewer)
return;
// Get the Javascript ChartViewer object
var viewer = JsChartViewer.get('<?php echo $viewer->getId()?>');
// Connect the mouse usage buttons to the Javascript ChartViewer object
connectViewerMouseUsage('ViewerMouseUsage1', viewer);
// Connect the view port window navigation pad to the Javascript ChartViewer object
connectViewerViewPort('ViewerViewPort1', viewer);
// Detect if browser is capable of support partial update (AJAX chart update)
if (JsChartViewer.canSupportPartialUpdate())
// Browser can support partial update, so connect the view port change event to
// trigger a partial update
viewer.attachHandler("ViewPortChanged", viewer.partialUpdate);
else
// Browser cannot support partial update - so use full page update
viewer.attachHandler("ViewPortChanged", function() { document.forms[0].submit(); });
}
</script>
<form method="post">
<table cellSpacing="0" cellPadding="0" border="0">
<tr>
<td align="right" bgColor="#000088" colSpan="2">
<div style="padding-bottom:2px; padding-right:3px; font-weight:bold; font-size:10pt; font-style:italic; font-family:Arial;">
<A style="color:#FFFF00; text-decoration:none" href="http://www.advsofteng.com/">Advanced Software Engineering</a>
</div>
</td>
</tr>
<tr valign="top">
<td style="border-left:black 1px solid; border-top:black 1px solid; border-bottom:black 1px solid;" width="130" bgColor="#e0e0e0">
<!-- The following table is to create 3 cells for 3 buttons. The buttons are used to control
the mouse usage mode of the Javascript ChartViewer. -->
<table id="ViewerMouseUsage1" cellSpacing="0" cellPadding="0" width="100%" border="0">
<tr>
<td class="chartPushButton">
<div class="chartPushButton" id="ViewerMouseUsage1_Scroll" title="Pointer">
<img src="pointer.gif" align="absMiddle" width="16" height="16">&nbsp;&nbsp;Pointer
</div>
</td>
</tr>
<tr>
<td class="chartPushButton">
<div class="chartPushButton" id="ViewerMouseUsage1_ZoomIn" title="Zoom In">
<img src="zoomInIcon.gif" align="absMiddle" width="16" height="16">&nbsp;&nbsp;Zoom In
</div>
</td>
</tr>
<tr>
<td class="chartPushButton">
<div class="chartPushButton" id="ViewerMouseUsage1_ZoomOut" title="Zoom Out">
<img src="zoomOutIcon.gif" align="absMiddle" width="16" height="16">&nbsp;&nbsp;Zoom Out
</div>
</td>
</tr>
</table>
<script>
// Connect the mouse usage buttons to the Javascript ChartViewer
function connectViewerMouseUsage(controlId, viewer)
{
// A cross browser utility to get the object by id.
function getObj(id) { return document.getElementById ? document.getElementById(id) : document.all[id]; }
// Set the button styles (colors) based on mouse usage mode
function syncButtons()
{
getObj(controlId + "_Scroll").className = (viewer.getMouseUsage() == JsChartViewer.Scroll) ?
"chartPushButtonSelected" : "chartPushButton";
getObj(controlId + "_ZoomIn").className = (viewer.getMouseUsage() == JsChartViewer.ZoomIn) ?
"chartPushButtonSelected" : "chartPushButton";
getObj(controlId + "_ZoomOut").className = (viewer.getMouseUsage() == JsChartViewer.ZoomOut) ?
"chartPushButtonSelected" : "chartPushButton";
}
syncButtons();
// Run syncButtons whenever the Javascript ChartViewer is updated
viewer.attachHandler("PostUpdate", syncButtons);
// Set the Javascript ChartViewer mouse usage mode if the buttons are clicked.
getObj(controlId + "_Scroll").onclick = function() { viewer.setMouseUsage(JsChartViewer.Scroll); syncButtons(); }
getObj(controlId + "_ZoomIn").onclick = function() { viewer.setMouseUsage(JsChartViewer.ZoomIn); syncButtons(); }
getObj(controlId + "_ZoomOut").onclick = function() { viewer.setMouseUsage(JsChartViewer.ZoomOut); syncButtons(); }
}
</script>
<br><br><br><br>
<!-- The following DIV blocks constitute the view port navigation pad. -->
<div id="ViewerViewPort1" style="margin: 10px 5px; text-align: center">
<div style="border:black 1px solid; padding:0px; margin:0px; width:120px; height:120px; background-color:#c0c0ff;
text-align:left">
<div id="ViewerViewPort1_ViewPort" style="border:black 1px solid; padding:0px; margin:0px; visibility:hidden;
width:60px; height:60px; position:relative; background-color:#c0c0c0">
<img style="display:none" height="1" width="1">
</div>
</div>
</div>
<script>
// Connect the view port navigation pad to the Javascript ChartViewer
function connectViewerViewPort(controlId, viewer)
{
// A cross browser utility to get the object by id.
function getObj(id) { return document.getElementById ? document.getElementById(id) : document.all[id]; }
// Get the inner rectangle representing the visible view port
var p = getObj(controlId + "_ViewPort");
// Set up the mouse down event handler
p.onmousedown = ViewerViewPort_startDrag;
p.viewer = viewer;
// Remember the width and height of the outer container of the navigation pad. The exact definition of
// width and height differs depending on browsers (some includes the borders and some exclude the borders).
var parent = p.parentElement || p.parentNode;
p.parentW = parent.offsetWidth - (document.all ? 2 : 4);
p.parentH = parent.offsetHeight - (document.all ? 2 : 4);
// Connect the view port to the viewer PostUpdate handler
connectViewPortHandler(controlId, viewer);
// The navigation pad has been set up, so can display it now.
p.style.visibility = "visible";
}
// Connect the view port to the viewer PostUpdate handler
function connectViewPortHandler(controlId, viewer)
{
// Set the navigation pad size and position depending on the Javascript ChartViewer view port state
var syncViewPort = function()
{
// A cross browser utility to get the object by id.
function getObj(id) { return document.getElementById ? document.getElementById(id) : document.all[id]; }
// Get the inner rectangle representing the visible view port
var p = getObj(controlId + "_ViewPort");
// Set the size and position based on Javascript ChartViewer view port state
p.currentWidth = p.style.width = Math.round(p.parentW * viewer.getViewPortWidth());
p.currentHeight = p.style.height = Math.round(p.parentH * viewer.getViewPortHeight());
p.currentX = p.style.left = Math.round(p.parentW * viewer.getViewPortLeft());
p.currentY = p.style.top = Math.round(p.parentH * viewer.getViewPortTop());
}
syncViewPort();
// Run syncViewPort whenever the Javascript ChartViewer is updated
viewer.attachHandler("PostUpdate", syncViewPort);
}
// Mouse down event handler
function ViewerViewPort_startDrag(e)
{
if (document.onmousemove != ViewerViewPort_mouseMove)
{
// Remember the current onmousemove and onmouseup event handler and replace them
// with our own handler
document.ViewerViewPort_onmousemovesave = document.onmousemove;
document.ViewerViewPort_onmouseupsave = document.onmouseup;
document.onmousemove = ViewerViewPort_mouseMove;
document.onmouseup = ViewerViewPort_endDrag;
}
// Remember the mouse down position
document.ViewerViewPort_dragObj = this;
this.refX = this.currentX - (window.event || e).clientX;
this.refY = this.currentY - (window.event || e).clientY;
}
// Mouse move event handler
function ViewerViewPort_mouseMove(e)
{
// Set the position of the navigation pad depending on how far the mouse has been dragged
var obj = document.ViewerViewPort_dragObj;
obj.currentX = obj.style.left =
Math.max(0, Math.min(obj.refX + (window.event || e).clientX, obj.parentW - obj.currentWidth));
obj.currentY = obj.style.top =
Math.max(0, Math.min(obj.refY + (window.event || e).clientY, obj.parentH - obj.currentHeight));
return false;
}
// Mouse up event handler
function ViewerViewPort_endDrag(e)
{
// Restore the previous nmousemove and onmouseup event handler
document.onmousemove = document.ViewerViewPort_onmousemovesave;
document.onmouseup = document.ViewerViewPort_onmouseupsave;
// Set the new view port position based on the mouse position
var obj = document.ViewerViewPort_dragObj;
var newVpLeft = obj.currentX / (obj.parentW - obj.currentWidth) * (1 - obj.viewer.getViewPortWidth());
var newVpTop = obj.currentY / (obj.parentH - obj.currentHeight) * (1 - obj.viewer.getViewPortHeight());
// Change the view port only when the new view port position is really different from
// existing position (to avoid unnecessary partial or full update)
if ((Math.abs(obj.viewer.getViewPortLeft() - newVpLeft) > 0.0000001) ||
(Math.abs(obj.viewer.getViewPortTop() - newVpTop) > 0.0000001))
{
obj.viewer.setViewPortLeft(newVpLeft);
obj.viewer.setViewPortTop(newVpTop);
obj.viewer.applyHandlers("ViewPortChanged");
}
}
</script>
</td>
<td style="border: black 1px solid; background-color: #c0c0ff">
<div style="padding:5px">
<!-- ****** Here is the chart image ****** -->
<?php echo $viewer->renderHTML()?>
</div>
</td>
</tr>
</table>
</form>
</body>
</html>