#!/usr/bin/perl
# Include current script directory in the module path (needed on Microsoft IIS).
# This allows this script to work by copying ChartDirector to the same directory
# as the script (as an alternative to installation in Perl module directory)
use File::Basename;
use lib dirname($0) =~ /(.*)/;
use perlchartdir;
# Get HTTP query parameters
use CGI;
my $query = new CGI;
#
# In this demo, the generated web page needs to load the "cdjcv.js" Javascript file and several GIF
# files. For ease of installation, we put these files in the same directory as this script. However,
# if this script is installed in a CGI only directory (such as cgi-bin), the web server would not
# allow the browser to access these non-CGI files.
#
# To get around this potential issue, a special load resource script is used to load these files.
# Instead of using:
#
# <SCRIPT SRC="cdjcv.js">
#
# we now use:
#
# <SCRIPT SRC="loadresource.pl?file=cdjcv.js">
#
# Similar methods are used to load the GIF files.
#
# If this script is not in a CGI only directory, you may replace the following loadResource string
# with an empty string "" to improve performance.
#
my $loadResource = "loadresource.pl?file=";
#
# Initialize the WebChartViewer when the page is first loaded
#
sub initViewer
{
my ($viewer) = @_;
#
# In this example, we just use default values, so there is nothing to initialize.
#
}
#
# Draw the chart
#
sub drawChart
{
my ($viewer) = @_;
#
# For simplicity, in this demo, the data arrays are filled with hard coded data. In a real
# application, you may use a database or other data source to load up the arrays.
#
my $dataX0 = [10, 15, 6, -12, 14, -8, 13, -3, 16, 12, 10.5, -7, 3, -10, -5, 2, 5];
my $dataY0 = [130, 150, 80, 110, -110, -105, -130, -15, -170, 125, 125, 60, 25, 150, 150, 15,
120];
my $dataX1 = [6, 7, -4, 3.5, 7, 8, -9, -10, -12, 11, 8, -3, -2, 8, 4, -15, 15];
my $dataY1 = [65, -40, -40, 45, -70, -80, 80, 10, -100, 105, 60, 50, 20, 170, -25, 50, 75];
my $dataX2 = [-10, -12, 11, 8, 6, 12, -4, 3.5, 7, 8, -9, 3, -13, 16, -7.5, -10, -15];
my $dataY2 = [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
my $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).
$c->setPlotArea(50, 40, 400, 400, -1, -1, -1, 0xc0c0c0, 0xc0c0c0)->set4QBgColor(0xdddddd,
0xeeeeee, 0xdddddd, 0xeeeeee, 0x000000);
# As the data can lie outside the plotarea in a zoomed chart, we need enable clipping
$c->setClipping();
# Set 4 quadrant mode, with both x and y axes symetrical around the origin
$c->setAxisAtOrigin($perlchartdir::XYAxisAtOrigin, $perlchartdir::XAxisSymmetric +
$perlchartdir::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).
my $legendBox = $c->addLegend(450, 40, 1, "arialbd.ttf", 8);
$legendBox->setAlignment($perlchartdir::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. You may modify the code below to use
# other layer types (lines, areas, etc).
#
# Add scatter layer, using 11 pixels red (ff33333) X shape symbols
$c->addScatterLayer($dataX0, $dataY0, "Group A", perlchartdir::Cross2Shape(), 11, 0xff3333);
# Add scatter layer, using 11 pixels green (33ff33) circle symbols
$c->addScatterLayer($dataX1, $dataY1, "Group B", $perlchartdir::CircleShape, 11, 0x33ff33);
# Add scatter layer, using 11 pixels blue (3333ff) triangle symbols
$c->addScatterLayer($dataX2, $dataY2, "Group C", $perlchartdir::TriangleSymbol, 11, 0x3333ff);
#
# In this example, we have not explicitly configured the full x and y range. In this case, the
# first time syncLinearAxisWithViewPort is called, ChartDirector will auto-scale the axis and
# assume the resulting range is the full range. In subsequent calls, ChartDirector will set the
# axis range based on the view port and the full range.
#
$viewer->syncLinearAxisWithViewPort("x", $c->xAxis());
$viewer->syncLinearAxisWithViewPort("y", $c->yAxis());
# Output the chart
my $chartQuery = $c->makeTmpFile("/tmp/tmpcharts");
# Include tool tip for the chart
my $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.pl?img=/tmp/tmpcharts/".$chartQuery);
$viewer->setImageMap($imageMap);
$viewer->setChartMetrics($c->getChartMetrics());
}
#
# This script handles both the full page request, as well as the subsequent partial updates (AJAX
# chart updates). We need to determine the type of request first before we processing it.
#
# Create the WebChartViewer object
my $viewer = new WebChartViewer($query, "chart1");
if ($viewer->isPartialUpdateRequest()) {
# Is a partial update request. Draw the chart and perform a partial response.
drawChart($viewer);
print $viewer->partialUpdateChart();
exit 0;
}
#
# If the code reaches here, it is a full page request.
#
# In this exapmle, we just need to initialize the WebChartViewer and draw the chart.
initViewer($viewer);
drawChart($viewer);
print "Content-type: text/html\n\n";
print <<EndOfHTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>XY Zooming and Scrolling</title>
<script type="text/javascript" src="${loadResource}cdjcv.js"></script>
<style type="text/css">
div.chartPushButton { padding:5px; cursor:hand; }
div.chartPushButton:hover { background-color: #EEEEFF; }
div.chartPushButtonPressed { padding:5px; cursor:hand; background-color: #CCFFCC; }
td.chartPushButton { font:12px Verdana; border-bottom:#000000 1px solid; }
</style>
</head>
<body style="margin:0px">
<script type="text/javascript">
//
// Execute the following initialization code after the web page is loaded
//
JsChartViewer.addEventListener(window, 'load', function() {
// Update the chart when the view port has changed (eg. when the user zooms in using the mouse)
var viewer = JsChartViewer.get('@{[$viewer->getId()]}');
viewer.attachHandler("ViewPortChanged", viewer.partialUpdate);
// Set the zoom and scroll mode to bi-directional
viewer.setScrollDirection(JsChartViewer.HorizontalVertical);
viewer.setZoomDirection(JsChartViewer.HorizontalVertical);
// Set the initial mouse usage to "zoom in"
setMouseMode(JsChartViewer.ZoomIn);
// Initialize the navigation pad
initNavigationPad('NavigationPad', viewer.getId());
});
//
// This method is called when the user clicks on the Pointer, Zoom In or Zoom Out buttons
//
function setMouseMode(mode)
{
// Set the button color based on the selected mouse mode
document.getElementById("scrollButton").className =
(mode == JsChartViewer.Scroll) ? "chartPushButtonPressed" : "chartPushButton";
document.getElementById("zoomInButton").className =
(mode == JsChartViewer.ZoomIn) ? "chartPushButtonPressed" : "chartPushButton";
document.getElementById("zoomOutButton").className =
(mode == JsChartViewer.ZoomOut) ? "chartPushButtonPressed" : "chartPushButton";
// Set the mouse mode
JsChartViewer.get('@{[$viewer->getId()]}').setMouseUsage(mode);
}
//
// The following functions implements the Navigation Pad user interface
//
// Initialize the Navigation Pad user interface
function initNavigationPad(controlId, viewerId)
{
// Get the draggable rectangle of the Navigation Pad and the Javascript ChartViewer
var handle = document.getElementById(controlId);
var viewer = JsChartViewer.get(viewerId);
// Set up the mouse down event handler to initiate dragging
handle.onmousedown = NavigationPad_mouseDown;
// Remember the width and height of the outer container and the id of the associated Javascript ChartViewer
var parent = handle.parentElement || handle.parentNode;
handle.parentW = parent.clientWidth;
handle.parentH = parent.clientHeight;
handle.viewerId = viewerId;
// Set up the Navigation Pad to reflect the current view port
updateNavigationPad(controlId);
// When the chart is updated (eg. when zoomed in), the Navigation Pad needs to be updated too.
viewer.attachHandler("PostUpdate", function() { updateNavigationPad(controlId); });
// The Navigation Pad has been set up, so can display it now.
handle.style.visibility = "visible";
}
// Update the Navigation Pad to reflect the view port
function updateNavigationPad(controlId)
{
// Get the draggable rectangle of the Navigation Pad and the Javascript ChartViewer
var handle = document.getElementById(controlId);
var viewer = JsChartViewer.get(handle.viewerId);
// Set the size and position of the handle based on Javascript ChartViewer view port
handle.currentWidth = Math.round(handle.parentW * viewer.getViewPortWidth());
handle.currentHeight = Math.round(handle.parentH * viewer.getViewPortHeight());
handle.currentX = Math.round(handle.parentW * viewer.getViewPortLeft());
handle.currentY = Math.round(handle.parentH * viewer.getViewPortTop());
handle.style.width = Math.max(0, (handle.currentWidth - handle.offsetWidth + parseInt(handle.style.width))) + "px";
handle.style.height = Math.max(0, (handle.currentHeight - handle.offsetHeight + parseInt(handle.style.height))) + "px";
handle.style.left = handle.currentX + "px";
handle.style.top = handle.currentY + "px";
}
// The Navigation Pad mouse down event handler
function NavigationPad_mouseDown(e)
{
// Prevent browser default action, if any.
if (e && e.preventDefault) e.preventDefault();
// To initiate drag and drop, we need to capture the mouse and handle the mouse move and mouse up
if (document.onmousemove != NavigationPad_mouseMove)
{
if (this.setCapture) this.setCapture();
// Remember the current onmousemove and onmouseup event handlers and replace them with our own handlers
document.NavigationPad_onmousemovesave = document.onmousemove;
document.NavigationPad_onmouseupsave = document.onmouseup;
document.onmousemove = NavigationPad_mouseMove;
document.onmouseup = NavigationPad_mouseUp;
}
// Remember the mouse down position
document.activeNavigationPad = this;
this.refX = this.currentX - (window.event || e).clientX;
this.refY = this.currentY - (window.event || e).clientY;
}
// The Navigation Pad mouse move event handler
function NavigationPad_mouseMove(e)
{
// Set the position of the navigation pad depending on how far the mouse has been dragged
e = e || window.event;
var handle = document.activeNavigationPad;
handle.currentX = Math.max(0, Math.min(handle.refX + e.clientX, handle.parentW - handle.currentWidth));
handle.currentY = Math.max(0, Math.min(handle.refY + e.clientY, handle.parentH - handle.currentHeight));
handle.style.left = handle.currentX + "px";
handle.style.top = handle.currentY + "px";
return false;
}
// The Navigation Pad mouse up event handler
function NavigationPad_mouseUp(e)
{
// Release the mouse and restore the original nmousemove and onmouseup event handlers
if (this.releaseCapture) this.releaseCapture();
document.onmousemove = document.NavigationPad_onmousemovesave;
document.onmouseup = document.NavigationPad_onmouseupsave;
// Get the draggable rectangle of the Navigation Pad and the Javascript ChartViewer
var handle = document.activeNavigationPad;
var viewer = JsChartViewer.get(handle.viewerId);
// Compute the new view port position based on the handle position
var newVpLeft = 0;
var newVpTop = 0;
if (viewer.getViewPortWidth() < 1)
newVpLeft = handle.currentX / (handle.parentW - handle.currentWidth) * (1 - viewer.getViewPortWidth());
if (viewer.getViewPortHeight() < 1)
newVpTop = handle.currentY / (handle.parentH - handle.currentHeight) * (1 - viewer.getViewPortHeight());
// Update the view port if the new view port position is different from the old position
if ((Math.abs(viewer.getViewPortLeft() - newVpLeft) > 0.0000001) ||
(Math.abs(viewer.getViewPortTop() - newVpTop) > 0.0000001))
{
viewer.setViewPortLeft(newVpLeft);
viewer.setViewPortTop(newVpTop);
viewer.raiseViewPortChangedEvent();
}
}
</script>
<form method="post">
<table cellspacing="0" cellpadding="0" style="border:black 1px solid;">
<tr>
<td align="right" colspan="2" style="background:#000088; color:#ffff00; padding:0px 4px 2px 0px;">
<a style="color:#FFFF00; font:italic bold 10pt Arial; text-decoration:none" href="http://www.advsofteng.com/">
Advanced Software Engineering
</a>
</td>
</tr>
<tr valign="top">
<td style="width:130px; background:#e0e0e0;">
<!-- The following table is to create 3 cells for 3 buttons to control the mouse usage mode. -->
<table cellspacing="0" cellpadding="0" width="100%" border="0">
<tr>
<td class="chartPushButton">
<div class="chartPushButton" id="scrollButton" onclick="setMouseMode(JsChartViewer.Scroll)">
<img src="${loadResource}pointer.gif" style="vertical-align:middle" alt="Pointer" /> Pointer
</div>
</td>
</tr>
<tr>
<td class="chartPushButton">
<div class="chartPushButton" id="zoomInButton" onclick="setMouseMode(JsChartViewer.ZoomIn)">
<img src="${loadResource}zoomInIcon.gif" style="vertical-align:middle" alt="Zoom In" /> Zoom In
</div>
</td>
</tr>
<tr>
<td class="chartPushButton">
<div class="chartPushButton" id="zoomOutButton" onclick="setMouseMode(JsChartViewer.ZoomOut)">
<img src="${loadResource}zoomOutIcon.gif" style="vertical-align:middle" alt="Zoom Out" /> Zoom Out
</div>
</td>
</tr>
</table>
<br /><br /><br /><br />
<div style="margin:10px 4px; text-align:center">
<!-- The following two DIV blocks constitute the Navigation Pad and its container. -->
<div style="border:black 1px solid; width:120px; height:120px; background-color:#c0c0ff; text-align:left">
<div id="NavigationPad" style="border:black 1px solid; visibility:hidden; width:60px; height:60px;
position:relative; background-color:#c0c0c0">
<img src="" style="display:none" height="1" width="1" alt="" />
</div>
</div>
</div>
</td>
<td style="border-left: black 1px solid; background-color: #c0c0ff; padding:5px">
<!-- ****** Here is the chart image ****** -->
@{[$viewer->renderHTML()]}
</td>
</tr>
</table>
</form>
</body>
</html>
EndOfHTML
; |