PHPãšFlexã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã
ããã«çŽé¢ããŸãããïŒã€ã³ã¿ã©ã¯ãã£ããªã°ã©ããšã³ã³ãããŒã«ããã«ã¯ãWebã¢ããªã±ãŒã·ã§ã³ã§äžç·ã«äœ¿çšããããšã¯åžžã«å°é£ã§ããã ãã¡ãããPHPçšã®ã°ã©ãã£ã«ã«ã©ã€ãã©ãªããããŸãããæ¬åœã«èŠæ ãã®è¯ããã®ãããŠãŒã¶ãŒãå®éšã§ãããã®ãåŸãã®ã¯éåžžã«å°é£ã§ãã ãŸãã¯ãå°ãªããšãæšæ¥ã¯å°é£ã§ããã ä»æ¥ã¯ãPHPãããã¯ãšã³ããšããŠäœ¿çšããAdobe Flexãããã³ããšã³ããšããŠäœ¿çšããŠãã€ã³ã¿ã©ã¯ãã£ããª3Dã°ã©ãã衚瀺ããæ¹æ³ã瀺ããŸãã
éå§ããã«ã¯ãããã€ãã®ããŒã¿ãå¿
èŠã§ãã ãã®ããããã©ãã£ãã¯ããŒã¿ããŒã¹ãäœæããŸãããã®ããŒã¿ããŒã¹ã«ã¯ãæ¯æ¥ã®ããŒãžãã¥ãŒãªã©ã«é¢ããããŒã¿ãæ ŒçŽããã1ã€ã®ãã©ãã£ãã¯ããŒãã«ããããŸãã MySQLã¹ããŒãããªã¹ã1ã«ç€ºããŸãã
1. traffic.sql
DROP TABLE IF EXISTS traffic;
CREATE TABLE traffic (
day DATE,
users INT,
views INT,
pages INT,
xmlpages INT
);
5ã€ã®ãã£ãŒã«ãããããŸãïŒæ¥ä»ããŠãŒã¶ãŒæ°ãããŒãžãã¥ãŒæ°ãåŠçãããããŒãžæ°ãããã³XMLããŒãžæ°ã ïŒåœç¶ãä»»æã®ãã£ãŒã«ãã䜿çšã§ããŸããïŒããã§ãäœããåºåããããã«ãããŒãã«ã«ãã¹ãããŒã¿ãå
¥åããŸãã ãããè¡ãã«ã¯ãloader.phpã¹ã¯ãªãããå®è¡ããŸãïŒãªã¹ã2ïŒã
2. loader.php
<?php
require_once("MDB2.php");
$dsn = 'mysql://root@localhost/traffic';
$mdb2 =& MDB2::factory($dsn);
$dsth =& $mdb2->prepare( "DELETE FROM traffic" );
$dsth->execute( array( ) );
$sth =& $mdb2->prepare( "INSERT INTO traffic VALUE (?,?,?,?,?)" );
$users = 100;
$views = 10000;
$pages = 5000;
$xmlpages = 300;
for( $d = 1; $d <= 30; $d++ ) {
$date = "2008-04-".$d;
$sth->execute( array( $date, $users, $views, $pages, $xmlpages ) );
$users += ( rand( 20, 100 ) - 30 );
$views += ( rand( 200, 1000 ) - 300 );
$pages += ( rand( 100, 500 ) - 150 );
$xmlpages += ( rand( 60, 300 ) - 90 );
}
?>
ãã®ã¹ã¯ãªããã¯ãåã«ããŒã¿ããŒã¹ã«æ¥ç¶ããããŒãã«ãããã¹ãŠã®ããŒã¿ãåé€ããŠããããã®æã®ã©ã³ãã ããŒã¿ãå
¥åããŸãã ã°ã©ããã©ã³ãã ã«è¡šç€ºãããªãããã«ãåŸç¶ã®åæ°å€ãåã®æ°å€ã«å¯ŸããŠã©ã³ãã ãªéã ãã·ãããããæ¹æ³ã䜿çšããŸãã ãã®ããã«ããŠããã£ãŒãã¯åžžã«äžãããŸãã
ããŒã¿ãçæãããŠããŒã¿ããŒã¹ã«ä¿åãããã®ã§ãããããããŒã¿ãååŸããæ¹æ³ãå¿
èŠã§ãã æåã®æ¹æ³ã¯ãtraffic.phpããŒãžã䜿çšããŠXMLã䜿çšããããšã§ãïŒãªã¹ã3ïŒã
3. traffic.php
<?php
require_once("MDB2.php");
$dsn = 'mysql://root@localhost/traffic';
$mdb2 =& MDB2::factory($dsn);
$dom = new DomDocument();
$dom->formatOutput = true;
$root = $dom->createElement( "traffic" );
$dom->appendChild( $root );
$sth =& $mdb2->prepare( "SELECT * FROM traffic ORDER BY day" );
$res = $sth->execute( $id );
while ($row = $res->fetchRow(MDB2_FETCHMODE_ASSOC)) {
$dn = $dom->createElement( "day" );
$dn->setAttribute( 'day', $row['day'] );
$dn->setAttribute( 'users', $row['users'] );
$dn->setAttribute( 'views', $row['views'] );
$dn->setAttribute( 'pages', $row['pages'] );
$dn->setAttribute( 'xmlpages', $row['xmlpages'] );
$root->appendChild( $dn );
}
header( "Content-type: text/xml" );
echo $dom->saveXML();
?>
ãã®ããŒãžã¯ãPEAR :: MDB2ã䜿çšããŠããŒã¿ããŒã¹ã«æ¥ç¶ãããã¹ãŠã®ããŒã¿ãåä¿¡ããŸãã 次ã«ãDomDocumentãªããžã§ã¯ããäœæãããããŒã¿ãè¿œå ãããŸãã
ã¯ããDomDocumentãªãã§XMLãäœæããæ¹ãç°¡åãããããŸããã ãããããã®å Žåã¯ã³ãŒããèªã¿ããããããã«ãXMLãšã³ã³ãŒãã£ã³ã°ã«åé¡ããªãã£ãããã䜿çšããããšã奜ã¿ãŸãã
ã³ãã³ãã©ã€ã³ããã¹ã¯ãªãããå®è¡ãããšã次ã®ãããªããšãèµ·ãããŸãã
% php Traffic.php
<?xml version="1.0"?>
/>
/>
/>
/>
...
çŽ æŽãããã ããã§ãFlexã«æž¡ãããšãã§ããXMLã®ããŒã¿ãã§ããŸããã
FlexããŒãžã§ã³1ã§ã®ã€ã³ã¿ãŒãã§ã€ã¹ã®äœæ
æ£çŽã«èšããšã3次å
ã°ã©ãçšã®ã©ã€ãã©ãªãäœæããæéãæ欲ãããã®ã¯èª°ã§ããïŒ ããã§ã¯ãæ¢åã®ãã®ã䜿çšããŸãããã ããšãã°
ãILOGã®Elixirã©ã€ãã©ãªãéžæããŸããã ããã¯åçšè£œåã§ãããè©Šçšçããããããç¡æã§ããŠã³ããŒãããŠè©Šçšã§ããŸãã
Flexã§ã®ã¢ããªã±ãŒã·ã§ã³ã®æ§ç¯ã¯ãAdobe Flex BuilderããŒãžã§ã³3ã§Flexãããžã§ã¯ããäœæããããšããå§ãŸããŸãããã©ãŠã¶ãŒãããžã§ã¯ããšAdobe AIRããŒã¹ã®ãããžã§ã¯ãã®äž¡æ¹ãå©çšã§ããŸãã
次ã«ã[ãããžã§ã¯ãããããã£]ãã€ã¢ãã°ãéãã[Flexãã«ããã¹]ã¿ããã¯ãªãã¯ããŸãã ããã§[ã©ã€ãã©ãªãã¹]ãéžæãã[SWCã®è¿œå ]ãã¯ãªãã¯ããŠElixir ILOGã©ã€ãã©ãªãè¿œå ããŸãã ãããã®2ã€ïŒã¡ã€ã³ã¯ã©ã¹ãšè±èªãšæ¥æ¬èªã®ããŒã«ã©ã€ãºã©ã€ãã©ãªã ãã®çµæããã®ãããªãã®ã衚瀺ãããã¯ãã§ãã

å³1.ãããžã§ã¯ããžã®Elixirã©ã€ãã©ãªãŒã®è¿œå ã
ããã§Elixirã©ã€ãã©ãªãæ¥ç¶ãããXMLããŒã¿ã«æ¥ç¶ããŠ3次å
ã°ã©ããšããŠè¡šç€ºããã³ãŒããäœæã§ããŸãã ãã®ã³ãŒãããªã¹ã4ã«ç€ºããŸãã
4. traffic.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal"
xmlns:ilog="http://www.ilog.com/2007/ilog/flex" creationComplete="trafficReq.send()">
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
private var trackPt:Point = null;
private function onTraffic( event:ResultEvent ) : void {
var days:Array = [];
for each( var day:XML in event.result..day ) {
days.push( { day:day.@day.toString(),
users:parseInt(day.@users),
pages:parseInt(day.@pages),
views:parseInt(day.@views),
xmlpages:parseInt(day.@xmlpages) } );
}
chart.dataProvider = days;
}
private function onMouseUp( event:MouseEvent ) : void { trackPt = null; }
private function onMouseMove( event:MouseEvent ) : void {
if ( trackPt == null ) return;
chart.rotationAngle += ( event.localX - trackPt.x );
trackPt = new Point( event.localX, event.localY );
}
private function onMouseDown( event:MouseEvent ) : void {
trackPt = new Point( event.localX, event.localY );
}
]]>
</mx:Script>
<mx:HTTPService id="trafficReq" resultFormat="e4x" url="http://localhost/traffic/traffic.php" result="onTraffic(event)" />
<ilog:LineChart3D rotationAngle="10" width="100%" height="100%" id="chart" mouseDown="onMouseDown(event)"
mouseUp="onMouseUp(event)" mouseMove="onMouseMove(event)" showDataTips="true">
<ilog:horizontalAxis>
<mx:CategoryAxis categoryField="day" displayName="Day" />
</ilog:horizontalAxis>
<ilog:series>
<ilog:LineSeries3D xField="day" yField="users" displayName="Users" />
<ilog:LineSeries3D xField="day" yField="pages" displayName="Pages" />
<ilog:LineSeries3D xField="day" yField="views" displayName="Views" />
<ilog:LineSeries3D xField="day" yField="xmlpages" displayName="XML Pages" />
</ilog:series>
</ilog:LineChart3D>
<mx:Legend dataProvider="{chart}"/>
</mx:Application>
ã³ãŒãã¯ãHTTPServiceã³ã³ããŒãã³ãã®trafficReqãªããžã§ã¯ãã®sendã¡ãœãããåŒã³åºãããšããå§ãŸããŸãã ãã®ãµãŒãã¹ã¯ãXMLã§ããŒã¿ãè¿ãPHPããŒãžã®URLãæããŸãã ããŒã¿ãåä¿¡ããããšãonTrafficã¡ãœãããåŒã³åºãããXMLããã£ãŒããªããžã§ã¯ãã§äœ¿çšå¯èœãªããŒã¿ã»ããã«å€æãããŸãã ãã®ãªããžã§ã¯ãã¯ããã¡ã€ã«ã®äžéšã§å®çŸ©ãããŸãã
ã°ã©ããLineChart 3DãšããŠå®çŸ©ããŸããã ä»ã®ãªãã·ã§ã³ãå¯èœã§ãããšãªã¢ããã¹ãã°ã©ã ãåã°ã©ããªã©ã2次å
ãš3次å
ã®å€ãã®ã°ã©ãã ããããããªãŒå³ãã¬ã³ããã£ãŒããããã³ãã®ä»ã®ã°ã©ãäœææ¹æ³ãäœæããããã®ããŒã«ããããŸãã Elixirã«ä»å±ããäŸã¯ããªããé©ãããã§ãããã
ã³ãŒãã«æ»ããŸãã ããŠã¹ã¢ã¯ã·ã§ã³ã®ããã€ãã®ãã³ãã©ãŒãè¿œå ããŸãããã¯ãªãã¯ãšç§»åã¯ãã°ã©ãã®å転è§åºŠãå€æŽããŸãã ããã«ããããŠãŒã¶ãŒã¯ãã£ãŒããå°ãå転ãããããšãã§ããŸãã ãããã®æ¹æ³ã䜿çšããŠããŠãŒã¶ãŒãäžãŸãã¯æšªããèŠãããšãã§ããããã«èŠéè§ãå€æŽã§ããŸãã
Flex Builder 3ã§ã³ãŒããå®è¡ãããšã次ã®ãããªãã®ã衚瀺ãããŸãã

æªããªãããïŒ ãµã€ãã®å®éã®ããŒã¿ãæ¥ç¶ãããšãã®å€èŠ³ãèããŠãã ããã
ããã§ãPHPãšFlexã«ã€ããŠããå°ãåŠã¶ããã«ãããŒã¿è»¢éãåçŽåããŸãããã
AMFã䜿çšããããŒã¿ã®ååŸ
Flashã«ã¯ãAction Message FormatïŒAMFïŒãšåŒã°ãããã€ããªããŒã¿è»¢é圢åŒããããŸãã Flexããã³Adobe Flashäžââã®ã¢ããªã±ãŒã·ã§ã³ã¯ãéåžžã®ã¡ãœããåŒã³åºããšåæ§ã®åŒã³åºãã䜿çšããŠããµãŒããŒãããªããžã§ã¯ãå
šäœãéåä¿¡ã§ããŸãã ã¢ããªã±ãŒã·ã§ã³ãPHPãšãã¹ãããŒã¿ã»ããã«æ¥ç¶ããããã«ã
AMFPHPãããŠã³ããŒãããŠã€ã³ã¹ããŒã«ã
ãŸãã ã
ãŸããAMFPHPã®servicesãã©ã«ããŒã«TrafficServiceã¯ã©ã¹ãè¿œå ããŸããã ãªã¹ã5ã«ããã®ã¯ã©ã¹ã®ã³ãŒãã衚瀺ãããŸãã
5. TrafficService.php
<?php
require_once("MDB2.php");
include_once(AMFPHP_BASE . "shared/util/MethodTable.php");
class TrafficService
{
function getTraffic()
{
$dsn = 'mysql://root@localhost/traffic';
$mdb2 =& MDB2::factory($dsn);
$sth =& $mdb2->prepare( "SELECT * FROM traffic ORDER BY day" );
$res = $sth->execute( $id );
$days = array();
while ($row = $res->fetchRow(MDB2_FETCHMODE_ASSOC)) { $days []= $row; }
return $days;
}
}
ãã®ã³ãŒãã¯XMLãçæãããã®ãšäŒŒãŠããŸãããããã§ã¯ããŒã¿ããã©ãŒãããããŸããã é
åãè¿ãã ãã§ãã
ã³ãŒãããã¹ãããã«ã¯ãAMFPHPã«å«ãŸããŠãããã©ãŠã¶ãŒã䜿çšããŸãã

å³3. AMFãã©ãã£ãã¯ãµãŒãã¹ã®è¡šç€º
ã芧ã®ãšãããgetTrafficïŒïŒã¡ãœãããåŒã³åºããŠãããŒã¿ããŒã¹ãããã¹ãŠã®ã¬ã³ãŒããActionScriptãªããžã§ã¯ãã®é
åãšããŠè¿ãããšãã§ããŸãã éåžžã«ã·ã³ãã«ã§éåžžã«é«éã§ãã
AMFPHPã«æ¥ç¶ãã
AMFPHPãã©ãã£ãã¯ãµãŒãã¹ã«æ¥ç¶ããã«ã¯ãåã®äŸã§è¥å¹²ã®å€æŽãå¿
èŠã§ãã ãããããªã¹ã6ã«ç€ºããŸãã
6. Traffic_ro.php
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal"
xmlns:ilog="http://www.ilog.com/2007/ilog/flex" creationComplete="trafficRO.getTraffic.send()">
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
private var trackPt:Point = null;
private function onTraffic() : void {
chart.dataProvider = trafficRO.getTraffic.lastResult;
}
...
]]>
</mx:Script>
<mx:RemoteObject id="trafficRO"
endpoint="http://localhost/amfphp/gateway.php"
source="traffic.TrafficService" destination="traffic.TrafficService"
showBusyCursor="true">
<mx:method name="getTraffic" result="onTraffic()" />
</mx:RemoteObject>
<ilog:LineChart3D ...>
...
</ilog:LineChart3D>
<mx:Legend dataProvider="{chart}"/>
</mx:Application>
HTTPServiceã¯RemoteObjectã«çœ®ãæããããŸããRemoteObjectã¯AMFPHPãµãŒããŒãåç
§ããã¢ã¯ã»ã¹ããã¡ãœãããå®çŸ©ããŸãã ãŸããonTrafficã¡ãœããã¯ããµãŒããŒããåä¿¡ããããŒã¿ãã°ã©ããªããžã§ã¯ãã®dataProviderããããã£ã«é
眮ããã ãã§ãã Flex Builderã§ãã®ã³ãŒããå®è¡ããŠããçµæã¯æåã®äŸãšåããŸãŸã§ãã éãã¯ãã³ãŒããããç解ãããããªããããŒã¿è»¢éãXMLã䜿çšãããããé«éã§å°ãªããªãããšã§ãã ã¢ããªã±ãŒã·ã§ã³ãå°ãæ¹åããããã«ããŠãŒã¶ãŒãç¹å®ã®ããŒã¿ã»ããã®ã¿ã衚瀺ããŠåçã«å®è¡ã§ããããã«ããã¹ã©ã€ããŒãè¿œå ããŸããã æ°ããã³ãŒãããªã¹ã7ã«ç€ºããŸãã
7. traffic_ro2.php
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="horizontal"
xmlns:ilog="http://www.ilog.com/2007/ilog/flex" creationComplete="trafficRO.getTraffic.send()"
xmlns:flexlib="flexlib.controls.*">
<mx:Script>
<![CDATA[
import mx.rpc.events.ResultEvent;
private var trackPt:Point = null;
private var days:Array = [];
private function onTraffic() : void {
days = trafficRO.getTraffic.lastResult as Array;
dateRange.minimum = 0;
dateRange.maximum = days.length;
dateRange.values[0] = 0;
dateRange.values[1] = days.length;
chart.dataProvider = days;
}
private function onDateRangeChange() : void {
chart.dataProvider = days.slice( dateRange.values[0], dateRange.values[1] );
}
...
]]>
</mx:Script>
<mx:RemoteObject id="trafficRO"
endpoint="http://localhost/amfphp/gateway.php"
source="traffic.TrafficService" destination="traffic.TrafficService"
showBusyCursor="true">
<mx:method name="getTraffic" result="onTraffic()" />
</mx:RemoteObject>
<mx:VBox width="100%" height="100%">
<mx:HBox>
<mx:Label text="Date Range" />
<flexlib:HSlider id="dateRange" thumbCount="2" width="300" liveDragging="true" change="onDateRangeChange()"
snapInterval="1" />
</mx:HBox>
<ilog:LineChart3D ...>
...
</ilog:LineChart3D>
</mx:VBox>
<mx:Legend dataProvider="{chart}"/>
</mx:Application>
ããŒãžã®äžéšã«2ã€ã®ã¹ã©ã€ããŒãæã€HSliderãªããžã§ã¯ããè¿œå ããŸããã ã¹ã©ã€ããŒã移åãããšãonDateRangeChangeã¡ãœãããåŒã³åºããããã£ãŒããæŽæ°ããã2ã€ã®æ¥ä»ã®éã®ããŒã¿ã®ã¿ã衚瀺ãããŸãã
HSliderã¯ã©ã¹ã¯FlexLib
ã©ã€ãã©ãªã«ãããŸãã FlexLibã¯ãå
ã®Flex 3ããŒã«ã匷åããã³æ¡åŒµããFlexã¯ã©ã¹ã®ã»ããã§ããã®å ŽåãããŠã¹ã§ã¹ã©ã€ããŒãåãããŠç¯å²ãéžæã§ããŸãã
ãã®ã³ãŒãã®ä»çµã¿ãå³4ã«ç€ºããŸãã

å³4.æ¥ä»ç¯å²ãéžæããã°ã©ã
ãã®å³ã¯ãéå»æ°æ¥éã®ããŒã¿ã®ã¿ã瀺ããŠããŸãã ããããã¹ã©ã€ããŒãå·Šå³ã«åããããšã§ãããã«ããŒã¿ãè¿œå ã§ããŸãã
次ã«è¡ãå Žæ
ããã«ç€ºãããŠãããã¯ãããžãŒïŒPHPãFlexãILOG ElixirãAMFPHPãFlexLibïŒã®çµã¿åããã¯éåžžã«åŒ·åã§ãã ç¹ã«ãILOG Elixirã«ã¯ãã»ãŒãã¹ãŠã®æ§é åããŒã¿ãè£å®ãããã¬ãŒã³ããŒã·ã§ã³ãåçŽã«çŽ æŽããããã®ã«ããçŽ æŽãããèŠèŠåã»ããããããŸãã ãšãªã¯ãµãŒã®èŠæ ããæªãããããšã¯éåžžã«é£ãããšèšã£ãŠãéèšã§ã¯ãããŸããã Elixirã«æ¯æããããªãå Žåã¯ãFlexã«çµã¿èŸŒãŸããŠããã°ã©ãäœæããŒã«ã«æ³šæãæãããGoogleã§ããªãã«åã£ããªãŒãã³ãœãŒã¹ãããžã§ã¯ããæ¢ããŠãã ããã