VCL for PHP Charting components - Part 4 - Skeleton

By: David Intersimone

Abstract: Creating a VCL for PHP Charting component. This article is a reproduction of the blog post by Jose Leon, developer of Delphi for PHP.

VCL for PHP Charting components - Skeleton

On this article we are going to create the basic skeleton for the component, we will add properties and will render the component with dummy information.

Adding properties

On the first article, we gathered the requeriments and set a task list, and now is time to add all the properties we want to provide, so the user is able to customize the component.

For that, you can use the Edit | Add Published Property option, which saves some coding. You need to enter the name of the property and the default value. Once you press OK, the code will be added to the code editor where the cursor is placed.

For example, if you add a property named "Test" with a default value of "1", you will get this on the editor:

protected $_test=1;

function getTest() { return $this->_test; }

function setTest($value) { $this->_test=$value; }

function defaultTest() { return 1; }

Use the Add Published Property wizard as many times you need to add all the properties we planned, on this article, this is limited to simple properties, like strings, numbers, etc. We also add the series property as an array to get ready for the next article. When you finish, the code will look like this:

<?php

require_once("vcl/vcl.inc.php");

//Includes

use_unit("controls.inc.php");

class OpenChart extends Control

{

function __construct($aowner = null)

{

parent::__construct($aowner);

}

protected $_series = array();

function getSeries() { return $this->_series; }

function setSeries($value) { $this->_series = $value; }

function defaultSeries() { return array(); }

protected $_title = "";

function getTitle() { return $this->_title; }

function setTitle($value) { $this->_title = $value; }

function defaultTitle() { return ""; }

protected $_xlegend = "";

function getXLegend() { return $this->_xlegend; }

function setXLegend($value) { $this->_xlegend = $value; }

function defaultXLegend() { return ""; }

protected $_ylegend = "";

function getYLegend() { return $this->_ylegend; }

function setYLegend($value) { $this->_ylegend = $value; }

function defaultYLegend() { return ""; }

protected $_backgroundcolor = "";

function getBackgroundColor() { return $this->_backgroundcolor; }

function setBackgroundColor($value) { $this->_backgroundcolor = $value; }

function defaultBackgroundColor() { return ""; }

protected $_loadingmessage="";

function getLoadingMessage() { return $this->_loadingmessage; }

function setLoadingMessage($value) { $this->_loadingmessage=$value; }

function defaultLoadingMessage() { return ""; }

function dumpContents()

{

}

}

?>

Dumping the control code

The next step should be to render the control code in the browser, the main method to override for this is dumpContents(). For this component, we just need to render a div tag, which will be used by the flash object to render the chart inside. You can see this on the basic sample provided on the open flash chart documentation:

http://teethgrinder.co.uk/open-flash-chart-2/tutorial-4.php

<html>

<head>

<script type="text/javascript" src="js/swfobject.js"></script>

<script type="text/javascript">

swfobject.embedSWF("open-flash-chart.swf", "my_chart",

"550", "200", "9.0.0", "expressInstall.swf", {"data-file":"chart-3.php"} );

</script>

</head>

<body>

<p>Hello World</p>

<div id="my_chart"></div>

<p>Don't forget to "view source"</p>

</body>

</html>

So simply, dump the div, but you need to use a unique name, remember more charts can be placed on the same Page and each one must have it’s own div. The Name property for components should be unique on the same Page:

function dumpContents()

{

//Div where the chart will be inserted

echo "<div id=\"$this->Name\"></div>";

}

On the library sample, you can see some code is placed also on the HEAD of the HTML document, like the inclusion of the swfobject.js and also the call to the swfobject to embed the flash, so the next method to override is dumpHeaderCode(). This method is called by the Page component when is rendering the HEAD section of the document.

function dumpHeaderCode()

{

parent::dumpHeaderCode();

//Dumps the open flash chart library code

if(!defined('OPENFLASHCHART'))

{

define('OPENFLASHCHART', 1);

?>

<script type="text/javascript" src="<?php echo VCL_HTTP_PATH; ?>/openchart/js/swfobject.js">

</script>

<?php

}

$url='';

?>

<script type="text/javascript">

swfobject.embedSWF(

"<?php echo VCL_HTTP_PATH; ?>/openchart/open-flash-chart.swf", "<?php echo $this->Name; ?>",

"<?php echo $this->Width; ?>", "<?php echo $this->Height; ?>",

"9.0.0", "expressInstall.swf",

{"data-file":"<?php echo $url; ?>"}

);

</script>

<?php

}

The first block adds dumps the javascript inclusion of swfobject.js, remember this method will be executed as many times as instances of this component exist on the form, so we should find a way to prevent this code is dumped several times. That’s the reason that block is protected by checking if OPENFLASHCHART has been defined, if it’s not defined, then dump the code, if not, simply go ahead.

Another thing to check is the VCL_HTTP_PATH constant, which is defined by the VCL for PHP library, contains the right HTTP path to the location of the library, no matter where the VCL resides. This is an easy way to specify paths, as you don’t have to worry about them.

And after that, we dump the code for the flash object, setting the name of the div tag where to embed it by the name of the component, dumping also the width and height of the component, and finally, setting the URL where to look for the data for the graphic, which is set on the $url variable.

Generating the chart

At this moment, our component dumps the right javascript and HTML to create the chart, but that chart will be empty and will cause an error, because the URL where to find the chart information is also empty.

So let’s write the method that will dump such information, and we will use the PHP API provided.

private function generateChart()

{

//Includes the open flash chart library

use_unit('openchart/php-ofc-library/open-flash-chart.php');

//Creates the title

$title = new title($this->Title);

//Creates the chart

$chart = new open_flash_chart();

$chart->set_title($title);

$sobject = new line();

//Generate som random data

$min = 0;

$max = 10;

$values = array();

for($i = 1; $i <= 10; $i++) $values[ ] = rand($min, $max);

$sobject->set_values($values);

//Add the serie to the chart

$chart->add_element($sobject);

if($this->_backgroundcolor != "") $chart->set_bg_colour($this->_backgroundcolor);

//Get the json code

$chartoutput = $chart->toPrettyString();

$url = getScriptFilename();

$dir = dirname($url);

$tempfile = $dir.'\chart.json';

file_put_contents($tempfile, $chartoutput);

}

We need first to include the PHP API, using use_unit() guarantees the .php file will be found, as it resides on the VCL folder.

After that, create the title with the value of the Title property, creates the open_flash_chart object and sets the title. Now, we create a simple line serie and set some random data, this is just for testing purposes.

And finally, get the chart information in a string, and save it on a file named chart.json on the same folder the .php script the user is working on. This is for design-time purposes and on later articles you will see how this is done properly in run-time.

The getScriptFilename is a helper function that returns the name of the script is being executed.

Now is time to modify dumpHeaderCode() to tell the flash object to use the chart.json file to get the chart information.

Modify this line:

$url = '';

By these two lines:

$this->generateChart();

$url = 'chart.json';

And that’s it, if you place the component on the designer, you will get a basic line chart, with random information:

Hide image

Server Response from: ETNASC03