Creating Interactive Dashboard applications using the LiveCycle Data Services Message Service



Similar documents
MAX 2006 Beyond Boundaries

Accessing Data with ADOBE FLEX 4.6

AT&T Global Network Client for Windows Product Support Matrix January 29, 2015

ADVANCED DATA VISUALIZATION DEVELOPER GUIDE

Analysis One Code Desc. Transaction Amount. Fiscal Period

COMPARISON OF FIXED & VARIABLE RATES (25 YEARS) CHARTERED BANK ADMINISTERED INTEREST RATES - PRIME BUSINESS*

COMPARISON OF FIXED & VARIABLE RATES (25 YEARS) CHARTERED BANK ADMINISTERED INTEREST RATES - PRIME BUSINESS*

Configuring the LCDS Load Test Tool

Chapter 22: Integrating Flex applications with portal servers

Streaming Real-Time Data into Xcelsius Apps

ADMINISTERING ADOBE LIVECYCLE MOSAIC 9.5

bbc Developing Service Providers Adobe Flash Media Rights Management Server November 2008 Version 1.5

Using EMC Documentum with Adobe LiveCycle ES

Case 2:08-cv ABC-E Document 1-4 Filed 04/15/2008 Page 1 of 138. Exhibit 8

WebObjects Web Applications Programming Guide. (Legacy)

Enhanced Vessel Traffic Management System Booking Slots Available and Vessels Booked per Day From 12-JAN-2016 To 30-JUN-2017

Computing & Telecommunications Services Monthly Report March 2015

Portals and Hosted Files

Creating and Deploying an Air Application

Data Visualization in Ext Js 3.4

NDE Adobe Flex Instructions

Creating Form Rendering ASP.NET Applications

Reading and Writing Files Using the File Utilities service

Using vcenter Orchestrator AMQP Plug-in

White Paper. Flex Data Services Performance Tests. Version 1.0 January 19 th 2007 Sven Ramuschkat Dirk Eismann HERRLICH & RAMUSCHKAT GmbH

Reports and Documents Generator for SharePoint ver.: 2.2

IBM InfoSphere MDM Server v9.0. Version: Demo. Page <<1/11>>

Tutorial: Building a Dojo Application using IBM Rational Application Developer Loan Payment Calculator

Introduction to pop-ups

PLM integration with Adobe LiveCycle ES (Enterprise Suite)

Adobe LiveCycle Data Services 3 Performance Brief

RGU Honours Project (Soft Real-time Data Viewer using WITSML)

Introducing Apache Pivot. Greg Brown, Todd Volkert 6/10/2010

MAX 2006 Using ColdFusion w/ Flex Data Services

Property & Casualty Insurance Solutions from CCS Technology Solutions

Listeners. Formats. Free Form. Formatted

Monitoring Trading Applications with Flex. Yakov Fain Farata Systems

Exam Name: IBM InfoSphere MDM Server v9.0

Accessing Data with ADOBE FLEX 4

Caplin Trader 1.4. Catalog Of Documents. August 2009 C O N F I D E N T I A L

Building and Using Web Services With JDeveloper 11g

Roles: Scrum Master & Project Manager

Oracle Service Bus Examples and Tutorials

WASv6_Scheduler.ppt Page 1 of 18

Adam Rauch Partner, LabKey Software Extending LabKey Server Part 1: Retrieving and Presenting Data

bbc Adobe LiveCycle Data Services Using the F5 BIG-IP LTM Introduction APPLIES TO CONTENTS

Sending an Message from a Process

CREATE A CUSTOM THEME WEBSPHERE PORTAL

Developing rich Internet applications for SAP with Adobe Flex

Deepak Patil (Technical Director) iasys Technologies Pvt. Ltd.

CS297 Report. Online Video Chatting Tool. Sapna Blesson

Drupal CMS for marketing sites

Adobe ColdFusion 11 Enterprise Edition

Using Application Insights to Monitor your Applications

HarePoint Workflow Extensions for Office 365. Quick Start Guide

Using the LiveCycle Data Services ES2 Sample Application Version 3.1

Ashley Institute of Training Schedule of VET Tuition Fees 2015

metaengine DataConnect For SharePoint 2007 Configuration Guide

Comparing share-price performance of a stock

EasyPush Push Notifications Extension for ios

T320 E-business technologies: foundations and practice

ORACLE BUSINESS INTELLIGENCE WORKSHOP

Improve application performance and scalability with Adobe ColdFusion 9

Sitecore Dashboard User Guide

Engagement Analytics Configuration Reference Guide

Using ADOBE FLASH TM BUILDER 4.7

Adobe LiveCycle Mosaic ES2 Implementations

Creating a folder in a library and submitting a form

Configuring Business Monitor for Event Consumption from WebSphere MQ

WebSphere Business Monitor V7.0 Script adapter lab

KC Data Integration Web Service Developer Guide

This presentation covers virtual application shared services supplied with IBM Workload Deployer version 3.1.

SAP Web Application Server 6.30: Learning Map for Development Consultants

United States Department of Agriculture (USDA) Agricultural Marketing Service (AMS) Livestock and Grain Market News (LGMN)

Client-side Web Engineering From HTML to AJAX


SysAid Remote Discovery Tool

EVALUATION. WA1844 WebSphere Process Server 7.0 Programming Using WebSphere Integration COPY. Developer

Feith Dashboard iq Server Version 8.1 Install Guide

TechTips. Connecting Xcelsius Dashboards to External Data Sources using: Web Services (Dynamic Web Query)

CENTERPOINT ENERGY TEXARKANA SERVICE AREA GAS SUPPLY RATE (GSR) JULY Small Commercial Service (SCS-1) GSR

Terms and Definitions for CMS Administrators, Architects, and Developers

Consuming and Producing Web Services with WST and JST. Christopher M. Judd. President/Consultant Judd Solutions, LLC

WORKING WITH LOAD BALANCING AND QUEUEING FOR ADOBE INDESIGN CS5 SERVER

Overview of Web Services API

How to consume a Domino Web Services from Visual Studio under Security

Instant Chime for IBM Sametime Installation Guide for Apache Tomcat and Microsoft SQL

bbc Installing Your Development Environment Adobe LiveCycle ES July 2007 Version 8.0

Rich-Internet Anwendungen auf Basis von ColdFusion und Ajax

How to Write AllSeen Alliance Self- Certification Test Cases September 25, 2014

PHP Integration Kit. Version User Guide

Choosing a Cell Phone Plan-Verizon

Presentation Reporting Quick Start

Consumer ID Theft Total Costs

EMC Documentum Repository Services for Microsoft SharePoint

Load Testing RIA using WebLOAD. Amir Shoval, VP Product Management

WebSphere Business Monitor

WIRIS quizzes web services Getting started with PHP and Java

3M Information Technology

LeSueur, Jeff. Marketing Automation: Practical Steps to More Effective Direct Marketing. Copyright 2007, SAS Institute Inc., Cary, North Carolina,

Transcription:

Creating Interactive Dashboard applications using the LiveCycle Data Services Message Service Table of contents Introduction... 1 Start the J2EE application server hosting LiveCycle Data Services... 5 Create a Flash Builder project... 5 Develop the application logic for the dashboard application... 5 Configure LiveCycle Data Services... 29 Introduction You can programmatically create a Rich Internet Application (RIA) that displays enterprise data by using the LiveCycle Data Services Message Service. You use the Flex client-side API and the server-side Message service to create messaging applications. A client application connects to a message destination on the server, sends messages to the server, and receives messages that were initiated by other client applications. Messages sent to the server are routed to other client applications that have subscribed to the same destination. Therefore if data is modified in one client application, other client applications that subscribe to the destination are updated in real time. That is, any other dashboard application that subscribes to the same destination has the exact same data view. Client applications that send messages to LiveCycle Data Services are called message producers. You define a producer in a client application by creating a Producer object. Client applications that receive messages from LiveCycle Data Services are called message consumers. You define a consumer in a client application by creating a Consumer object. An application can be both a message producer and a message consumer. When using both a message producer and a message consumer in the same application, ensure that they both reference the same destination. For information about the LiveCycle Data Services Message service, see the Message Service chapter in the Using Adobe LiveCycle Data Services Guide.

The following illustration shows messages being passed between producer applications, consumer applications, and LiveCycle Data Services. Figure 1 Producer and Consumer client applications interacting with LiveCycle Data Services The dashboard application enables users to view data in controls such as a pie chart and a data grid control. When the user modifies data located in a control, for example, adjusts the range control, the view is changed. As a result, a message is created and sent to the Message service. All client applications that subscribe to the destination are updated. The following illustration provides a visual representation of the dashboard application built using Flash Builder 4.0.

Figure 2 The DashBoard application displaying data by using the LiveCycle Data Services Message service For simplicity, the data that is used by the Dashboard application is located in an XML file named results.xml. Typically data is provided by Java server-side classes deployed on the LiveCycle Data Services server. The following code represents a portion of the data located in the results.xml file. <list> <month name="jan-04" revenue="400263" average="80052"> <region name="apac" revenue="46130"/> <region name="europe" revenue="106976"/> <region name="japan" revenue="79554"/> <region name="latin America" revenue="39252"/> <region name="north America" revenue="128351"/> </month> <month name="feb-04" revenue="379145" average="75829"> <region name="apac" revenue="70324"/> <region name="europe" revenue="88912"/> <region name="japan" revenue="69677"/> <region name="latin America" revenue="59428"/>

<region name="north America" revenue="90804"/> </month> </list> The complete XML file that is used to populate the Dashboard application is available as a file attachment to the PDF document that corresponds to this development article. The data located in the XML file is retrieved by using a HTTPService object. The URL property of the HTTPService object is set to result.xml, which means that the XML file is located in the project s root folder. The controls in the dashboard application display the data located in the XML file. The objective of this development article is to guide you through how to build this application and to explain some key concepts related to the Message service. To create a dashboard application by using the Message service, perform the following tasks: 1. Start the J2EE application server hosting LiveCycle Data Services. 2. Create a Flash Builder 4 project. 3. Develop the application logic for the dashboard application. 4. Configure LiveCycle Data Services. Sample Files Files created in this development article correspond to sample files that are available with LiveCycle Data Services. As you read through this article, it is recommended that you reference the sample files. This article explains the main application logic located in the MXML files that create this application. For example, the Consumer and Producer objects are explained. All the application logic that is required to run this application is provided in this article. Prerequisite knowledge This development article is intended for ActionScript developers whom want to create applications for LiveCycle Data Services. About the author Scott Macdonald is a senior SDK content and community lead at Adobe Systems with 13 years in the software industry working with Java, C/C++/C#, ActionScript as well as other programming languages.

Start the J2EE application server hosting LiveCycle Data Services Start the J2EE application server hosting LiveCycle Data Services. Click Start, All Programs, Adobe, LiveCycle Data Services ES 3.1, Start LiveCycle Data Services Server. Create a Flash Builder project Create a Flash Builder project that is used to create the client application. This project references the J2EE application server hosting LiveCycle Data Services. That is, when you create the project, select J2EE as the Application Server type and LiveCycle Data Services as the application server. After you create the project, all of the client libraries required to interact with the J2EE application server are added to your project s class path. To create a client project by using Flash Builder 4, perform the following steps: 1. Start Flash Builder 4 by clicking Start, All Programs, Adobe Flash Builder 4. 2. Create a new project. 3. In the Project Name box, specify a name for your project. 4. Under Application Type, select Web. 5. Specify version 3.5 for the Flex SDK version. 6. In the Application Server list, select J2EE. 7. Select the Use Remote Access Service check box. 8. Select LiveCycle Data Services check box. 9. In the Root folder box, specify the root folder value. For example, specify C:\lcds\tomcat\webapps\lcds. 10. In the Root URL box, specify the root URL folder value. For example, specify http://localhost:8400/lcds/. 11. In the Content root box, specify the Context root value. For example, specify /lcds. 12. Accept the Output folder default value. 13. Click Finish. Develop the application logic for the dashboard application The dashboard client application consists of the following files:

dashboard.mxml - represents the main application file. This file defines the Consumer and the Producer objects that interact with LiveCycle Data Services. This file also defines a HTTPService object that retrieves data from the XML data source. The views defined in this file are separated into three sections: the regional breakdown, regional details view, and the revenue timeline view. (The illustration of the Dashboard application shown at the beginning of this development article shows the three views.) RegionalBreakdown.mxml - represents a pie chart control that displays the five regions defined in the results.xml file. You can click a specific area to obtain information about the region. RegionDetail.mxml - represents a column chart control that displays data located in the results.xml file. For example, when you click a section in the pie chart, the view in the column chart is updated. RevenueTimeline.mxml - represents a line chart control that displays revenue data over a time period. A slider control located in the dashboard.mxml file is bound to the line chart control and enables you to change the time period view. Once the time period view is adjusted, the data in the column chart is updated. SortUtils - represents a utility class that sorts data by dates. The following illustration shows the Flash Builder project that creates the dashboard application.

The SWC files are automatically added to the project as described in the Create a Flash Builder project topic. The main.css file is available with the sample files available with LiveCycle Data Services. Also, be sure to include the result.xml file to your project. This XML file is available as a file attachment to the PDF document that corresponds to this development article. Create the dashboard file The dashboard.mxml file is the main application file for the Dashboard application. This file defines the Producer and Consumer objects that interact with the LiveCycle Data Services server. The destination for both objects is dashboard, which is defined in the messagingconfig.xml file. For example, when data is modified in a control (for example, the time period is adjusted), a message is created and sent to the dashboard destination. The following code snippet creates the Producer and Consumer objects using mxml tags. <!-- Define the Producer and Consumer that interacts with the Message Service --> <mx:producer id="producer" destination="dashboard"/> <mx:consumer id="consumer" destination="dashboard" message="messagehandler(event)"/>

An HTTPService object is also defined in the dashboard.mxml file. This object is responsible for retrieving data from the results.xml file. The following code snippet defines the HTTPService object named srv. <!-- Define the HTTPService component that retrieves data from the results.xml file --> <mx:httpservice id="srv" url="results.xml" useproxy="false" result="resulthandler(event)"/> When the application is started, the initapp function defined in dashboard.mxml is invoked. Within this method, the following tasks occur: The Consumer object s subscribe method is called. This method creates a subscription to the dashboard destination, which is defined in the messaging-config.xml file. (See Configure LiveCycle Data Services.) The HTTPService object s send method is invoked. Data located in the result.xml file is retrieved. After the data is retrieved, the resulthandler method is invoked. This event handler is defined in the MXML tag that defines the HTTPService object. When the XML data that the HTTPService object references is retrieved, the resulthandler method is invoked. The first task that occurs in resulthandler is a monthdata array is populated with the data returned by the HTTPService object: //Populate the monthdata array with XML data returned by the HTTP service monthdata = event.result.list.month.source as Array; The monthdata array populates the HSlider object s maximum and values data members. The HSlider object represents the slider control that is displayed in the Revenue Timeline view. When the user adjusts the slider control, the rangechange method is invoked (the rangechange method is defined in the HSlider object s change field). The following code snippet shows the MXML tag that defines a panel that represents the Revenue Timeline view. <mx:panel id="timelinepanel" title="revenue Timeline" width="100%" height="100%"> <RevenueTimeline id="timeline" revenuedata="slicedmonthdata.source" monthchange="monthchange()"/> <mx:controlbar horizontalgap="4"> <mx:togglebuttonbar dataprovider="timeline"/> <mx:spacer width="10"/>

<mx:label text="range:"/> <mx:hslider id="slider" width="150" thumbcount="2" snapinterval="1" minimum="0" datatipformatfunction="getsliderlabel" change="rangechange()"/> </mx:controlbar> </mx:panel> The bolded code represents the HSlider object that is associated with the Revenue Timeline view. Creating messages when the range control is adjusted The rangechange method creates an IMessage instance by using the AsyncMessage constructor. This instance represents the message that is sent to LiveCycle Data Services when the user adjusts the slider range control. The HSlider object s minimum and maximum values are used to populate the body of the message. The message is sent to LiveCycle Data Services by invoking the Producer object s send message and passing the IMessage object. As a result, client applications that subscribe to the dashboard destination are updated with the new range view. The following code snippet shows the rangechange method. //Create a new message when the slider control is adjusted private function rangechange():void var message:imessage = new AsyncMessage(); message.body = min: slider.values[0], max: slider.values[1]+1; producer.send(message); Creating messages when the pie chart is clicked The monthdata array also populates the regiondata array in the resulthandler method. The regiondata array is populated by iterating through the monthdata array and calculating data such as the monthly total for each region. The regiondata array populates an ArrayCollection instance named slicedregiondata. The slicedregiondata instance populates the Region Breakdown view (the pie chart control). When a user clicks the pie chart, then the regionchange method is invoked. Like the rangechange method, the regionchange method creates an IMessage instance by using the AsyncMessage constructor. This message represents the message that is sent to LiveCycle Data Services when the user clicks the pie chart control. The RegionBreakdown

object s selectedregion data member populates the message body. The message is sent to LiveCycle Data Services by invoking the Producer object s send message and passing the IMessage object. The following code snippet shows the regionchange method. //Create a new message when the pie chart is clicked private function regionchange():void var message: IMessage = new AsyncMessage(); message.body = region: regionbreakdown.selectedregion; producer.send(message); Handling incoming messages When the Consumer object is created, the message data member is assigned the value messagehandler. This results in the messagehandler method handling incoming messages sent from LiveCycle Data Services. An Object instance is created by retrieving the massage from the event parameter, as shown in the following code snippet. var body:object = event.message.body; The remaining application logic in messagehandler populates the data collection objects that are used to populate the controls located in the dashboard application. The following application logic represents the messagehandler method. // Handle incoming messages private function messagehandler(event:messageevent):void var body:object = event.message.body; if (body.min!= null) //range slider.values = [body.min, body.max - 1]; if (monthdata!= null) slicedmonthdata.source = monthdata.slice(body.min, body.max); if (regiondata!= null) slicedregiondata.source = regiondata.slice(body.min, body.max); else if (body.month!= null) //month in timeline regionbreakdown.month = body.month;

else if (body.region!= null) //region from breakdown regionbreakdown.selectedregion = body.region; regiondetail.region = body.region.name; for (var i: Number = 0; i < monthdata.length; i++) var regions: Array = monthdata[i].region.source; for (var j: Number = 0; j < regions.length; j++) if (regions[j].name == body.region.name) regiondata[i].revenue = regions[j].revenue; break; slicedregiondata.source = regiondata.slice(slider.values[0], slider.values[1] + 1); dashboard.mxml file The following code represents the entire dashboard.mxml file. <?xml version="1.0" encoding="utf-8"?> <mx:application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" pagetitle="collaborative Dashboard" creationcomplete="initapp()"> <mx:style source="main.css"/> <mx:script> <![CDATA[ import mx.messaging.messages.asyncmessage; import mx.messaging.messages.imessage; import mx.collections.arraycollection; import mx.messaging.events.messageevent; import mx.rpc.events.resultevent; [Bindable] public var slicedmonthdata:arraycollection; [Bindable] public var slicedregiondata:arraycollection;

private var monthdata:array; private var regiondata:array; private function initapp():void consumer.subscribe(); srv.send(); slicedmonthdata = new ArrayCollection(); slicedregiondata = new ArrayCollection(); private function resulthandler(event:resultevent):void monthdata = event.result.list.month.source as Array; slider.maximum = monthdata.length - 1; slider.values = [0, monthdata.length - 1]; slicedmonthdata.source = monthdata; regionbreakdown.month = monthdata[0]; regiondata = new Array(monthData.length); var monthtotal:number; for (var i:number = 0; i < monthdata.length; i++) regiondata[i] = name: monthdata[i].name, average: 0, revenue: 0; var regions:array = monthdata[i].region.source; monthtotal = 0; for (var j:number = 0; j < regions.length; j++) monthtotal += regions[j].revenue; regiondata[i].average = monthtotal/monthdata[i].region.length slicedregiondata.source = regiondata.slice(slider.values[0], slider.values[1]); private function getsliderlabel(value:string):string return monthdata[parseint(value)].name; // Send messages when user's selection changes private function monthchange():void

var message:imessage = new AsyncMessage(); message.body = month: timeline.selectedmonth; producer.send(message); private function rangechange():void var message:imessage = new AsyncMessage(); message.body = min: slider.values[0], max: slider.values[1]+1; producer.send(message); private function regionchange():void var message: IMessage = new AsyncMessage(); message.body = region: regionbreakdown.selectedregion; producer.send(message); // Handle incoming messages private function messagehandler(event:messageevent):void var body:object = event.message.body; if (body.min!= null) //range slider.values = [body.min, body.max - 1]; if (monthdata!= null) slicedmonthdata.source = monthdata.slice(body.min, body.max); if (regiondata!= null) slicedregiondata.source = regiondata.slice(body.min, body.max); else if (body.month!= null) //month in timeline regionbreakdown.month = body.month; else if (body.region!= null) //region from breakdown regionbreakdown.selectedregion = body.region; regiondetail.region = body.region.name; for (var i: Number = 0; i < monthdata.length; i++) var regions: Array = monthdata[i].region.source; for (var j: Number = 0; j < regions.length; j++)

if (regions[j].name == body.region.name) regiondata[i].revenue = regions[j].revenue; break; slicedregiondata.source = regiondata.slice(slider.values[0], slider.values[1] + 1); private function toggleseries():void var message: IMessage = new AsyncMessage(); if (currentstate=="series") currentstate = ""; message.body.series = false; else currentstate = "series"; message.body.series = true; producer.send(message); private function datagridcurrencyformat(item:object, column:object):string return cf.format(item[column.datafield]); ]]> </mx:script> <mx:producer id="producer" destination="dashboard"/> <mx:consumer id="consumer" destination="dashboard" message="messagehandler(event)"/> <mx:httpservice id="srv" url="results.xml" useproxy="false" result="resulthandler(event)"/> <mx:currencyformatter id="cf"/>

<mx:hbox width="100%" verticalalign="middle" horizontalalign="right" paddingright="40"> <mx:label text="welcome, Guest "/> <mx:combobox id="cb"> <mx:dataprovider> <mx:string>revenue Timeline</mx:String> </mx:dataprovider> </mx:combobox> </mx:hbox> <mx:hdividedbox width="100%" height="100%"> <mx:panel id="timelinepanel" title="revenue Timeline" width="100%" height="100%"> <RevenueTimeline id="timeline" revenuedata="slicedmonthdata.source" monthchange="monthchange()"/> <mx:controlbar horizontalgap="4"> <mx:togglebuttonbar dataprovider="timeline"/> <mx:spacer width="10"/> <mx:label text="range:"/> <mx:hslider id="slider" width="150" thumbcount="2" snapinterval="1" minimum="0" datatipformatfunction="getsliderlabel" change="rangechange()"/> </mx:controlbar> </mx:panel> <mx:vdividedbox width="100%" height="100%"> <RegionBreakdown id="regionbreakdown" regionchange="regionchange()" width="100%" height="50%" /> <RegionDetail id="regiondetail" revenuedata="slicedregiondata.source" width="100%" height="50%" /> </mx:vdividedbox> </mx:hdividedbox> </mx:application> Create the RegionalBreakdown file The RegionalBreakdown.mxml file displays the region data in the region.xml file within a pie chart control. The pie chart control is defined by using a PieChart MXML tag. The name of the PieChart instance is pcregion, as shown in the following code snippet.

<mx:piechart id="pcregion" dataprovider="_month.region" showdatatips="true" width="100%" height="100%" itemclick="regionchange(event.hitdata.item)" datatipfunction="formatdatatip"> As defined in this tag, when a user clicks the pie chart, the regionchange method is invoked. A HitData object is dispatched to this method when a user clicks an item in the series. The data provider for the pie chart control is an object named _month, as defined in the following code snippet. [Bindable] private var _month:object; The _month data provider is populated by using the set month method, as shown in the following code snippet. public function set month(m:object):void _month = m; this.title = "Regional Breakdown [" + _month.name + "]"; This set method is invoked in the resulthandler method that is defined in the dashboard.mxml file, as shown in the following code snippet. regionbreakdown.month = monthdata[0]; Each time a new message is detected, this set method is invoked in the messagehandler method (defined in the dashboard.mxml file). That is, when the Consumer object detects a new incoming message, the messagehandler method handles the incoming message and the set method defined in the RegionalBreakdown.mxml file is invoked. When a user clicks an item in the pie chart, the selectedregion method is invoked. The clicked item is exploded, as shown in the following code snippet. public function set selectedregion(item:object):void _selectedregion = item; var index:int = -1; for (var i:int=0; i < _month.region.length && index == -1; i++) if (_month.region[i].name == item.name) index = i; //Only explode the selected region

var explodedata:array = []; explodedata[index] = 0.15; pcregion.series[0].perwedgeexploderadius = explodedata; A RegionBreakdown object named regionbreakdown is defined in the dashboard.mxml file by using an MXML tag, as shown by the bolded line in the following code snippet. <mx:vdividedbox width="100%" height="100%"> <RegionBreakdown id="regionbreakdown" regionchange="regionchange()" width="100%" height="50%" /> <RegionDetail id="regiondetail" revenuedata="slicedregiondata.source" width="100%" height="50%" /> </mx:vdividedbox> The following code represents the entire RegionalBreakdown.mxml file. <?xml version="1.0" encoding="utf-8"?> <mx:panel xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"> <mx:metadata> [Event("regionChange")] </mx:metadata> <mx:script> <![CDATA[ import mx.charts.hitdata; public function set month(m:object):void _month = m; this.title = "Regional Breakdown [" + _month.name + "]"; [Bindable] private var _month:object; private function getslicelabel(item:object, arg2:string, arg3:number, arg4:number):string return item==null?"":item.name; private var _selectedregion:object; public function get selectedregion():object

return _selectedregion; public function set selectedregion(item:object):void _selectedregion = item; var index:int = -1; for (var i:int=0; i < _month.region.length && index == -1; i++) if (_month.region[i].name == item.name) index = i; //we only want to explode the selected region var explodedata:array = []; explodedata[index] = 0.15; pcregion.series[0].perwedgeexploderadius = explodedata; private function regionchange(item:object):void selectedregion = item; dispatchevent(new Event("regionChange")); private function datagridcurrencyformat(item:object, column:object):string return cf.format(item[column.datafield]); private function formatdatatip(hitdata:hitdata):string var name:string = hitdata.item.name; var revenue:number = hitdata.item.revenue; return "<b>region: "+name+"</b><br>revenue: "+cf.format(revenue); ]]> </mx:script> <mx:currencyformatter id="cf"/> <mx:seriesinterpolate id="interpolate" elementoffset="10"/> <mx:viewstack id="vs" width="100%" height="100%">

<mx:vbox width="100%" height="100%" icon="@embed('icon_chart.png')" tooltip="view in Chart" hideeffect="fade" showeffect="fade"> <mx:piechart id="pcregion" dataprovider="_month.region" showdatatips="true" width="100%" height="100%" itemclick="regionchange(event.hitdata.item)" datatipfunction="formatdatatip"> <mx:series> <mx:array> <mx:pieseries field="revenue" namefield="name" labelposition="callout" labelfunction="getslicelabel" showdataeffect="interpolate"> <mx:fills> <mx:array> <mx:radialgradient> <mx:entries> <mx:array> <mx:gradiententry color="#ef7651" ratio="0"/> <mx:gradiententry color="#994c34" ratio="1"/> </mx:array> </mx:entries> </mx:radialgradient> <mx:radialgradient> <mx:entries> <mx:array> <mx:gradiententry color="#e9c836" ratio="0"/> <mx:gradiententry color="#aa9127" ratio="1"/> </mx:array> </mx:entries> </mx:radialgradient> <mx:radialgradient> <mx:entries> <mx:array> <mx:gradiententry color="#6fb35f" ratio="0"/> <mx:gradiententry color="#497b54" ratio="1"/> </mx:array> </mx:entries> </mx:radialgradient> <mx:radialgradient> <mx:entries> <mx:array> <mx:gradiententry color="#a1aecf" ratio="0"/> <mx:gradiententry color="#47447a" ratio="1"/> </mx:array> </mx:entries>

</mx:radialgradient> <mx:radialgradient> <mx:entries> <mx:array> <mx:gradiententry color="#ba9886" ratio="0"/> <mx:gradiententry color="#ae775b" ratio="1"/> </mx:array> </mx:entries> </mx:radialgradient> </mx:array> </mx:fills> </mx:pieseries> </mx:array> </mx:series> </mx:piechart> </mx:vbox> <mx:vbox width="100%" height="100%" icon="@embed('icon_grid.png')" tooltip="view in Grid" hideeffect="fade" showeffect="fade"> <mx:datagrid dataprovider="_month.region" width="100%" height="100%" change="regionchange(datagrid(event.target).selecteditem)"> <mx:columns> <mx:array> <mx:datagridcolumn datafield="name" headertext="region"/> <mx:datagridcolumn datafield="revenue" headertext="revenue" labelfunction="datagridcurrencyformat" /> </mx:array> </mx:columns> </mx:datagrid> </mx:vbox> </mx:viewstack> <mx:controlbar> <mx:togglebuttonbar dataprovider="vs"/> </mx:controlbar> </mx:panel> Create the RegionDetail file The RegionDetail.mxml displays the data returned from the result.xml file in a column chart control. The column chart control is defined by using a ColumnChart MXML tag. The data source is an array named revenuedata that contains region data, as shown in the following code snippet. <mx:columnchart dataprovider="revenuedata" width="100%" height="100%" showdatatips="true" datatipfunction="formatdatatip">

The revenuedata array created in the ActionScript section of RegionDetail.mxml file is bindable array, as shown in the following code snippet. The data stored in revenuedata is displayed in the column chart control. [Bindable] public var revenuedata:array; A RegionDetail object named regiondetail is defined in the dashboard.mxml file by using an MXML tag, as shown by the following bolded line. <mx:vdividedbox width="100%" height="100%"> <RegionBreakdown id="regionbreakdown" regionchange="regionchange()" width="100%" height="50%" /> <RegionDetail id="regiondetail" revenuedata="slicedregiondata.source" width="100%" height="50%" /> </mx:vdividedbox> Notice that revenuedata is referenced in the RegionDetail tag. An ArrayCollection object named slicedregiondata (declared in the dashboard.mxml file) populates the revenuedata array. The revenuedata array is populated in the resulthandler method defined in dashboard.mxml file. (The resulthandler method is invoked when data from the HTTPService object is returned). The second placed where revenuedata is populated is in the MessageHandler method defined in the dashboard.mxml file. The MessageHandler method is invoked when the Consumer object detects a new message from LiveCycle Data Services. The following code represents the entire RegionDetail.mxml file. <?xml version="1.0" encoding="utf-8"?> <mx:panel xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" title="region Details"> <mx:script> <![CDATA[ import mx.charts.hitdata; import mx.controls.alert; import mx.charts.chartclasses.chartbase; private var _region:string; [Bindable] public var revenuedata:array;

[Bindable] public var selectedmonth:object; protected function monthchange(month:object):void selectedmonth = month; dispatchevent(new Event("monthChange")); protected function currencyformat(value:object, arg2:object, arg3:object):string return cf.format(value); private function datagridcurrencyformat(item:object, column:object):string return cf.format(item[column.datafield]); private function sortbydates(obj1:object, obj2:object):number var n:number = SortUtils.sortByDates(obj1, obj2, "name"); return n; public function set region(r:string):void _region = r; this.title = "Region Details [" + r + "]"; private function formatdatatip(hitdata:hitdata):string var month:string = hitdata.item.name; var revenue:number = hitdata.item.revenue; var average:number = hitdata.item.average; return "<b>month: " + month + "</b><br>" + _region + ": " + cf.format(revenue) + "<br>average: " + cf.format(average); ]]> </mx:script> <mx:seriesinterpolate id="interpolate" elementoffset="10"/>

<mx:currencyformatter id="cf"/> <mx:viewstack id="vs" width="100%" height="100%"> <mx:vbox id="chartvbox" width="100%" height="100%" icon="@embed('icon_chart.png')" tooltip="chart View" paddingleft="4" paddingtop="4" paddingbottom="4" paddingright="4"> <mx:columnchart dataprovider="revenuedata" width="100%" height="100%" showdatatips="true" datatipfunction="formatdatatip"> <mx:horizontalaxis> <mx:categoryaxis dataprovider="revenuedata" categoryfield="name"/> </mx:horizontalaxis> <mx:verticalaxis> <mx:linearaxis maximum="160000" labelfunction="currencyformat"/> </mx:verticalaxis> <mx:series> <mx:array> <mx:columnseries yfield="revenue" showdataeffect="interpolate"> <mx:fill> <mx:lineargradient> <mx:entries> <mx:array> <mx:gradiententry color="#c6d5dd" ratio="0" alpha="100"/> <mx:gradiententry color="#336699" ratio="0.1" alpha="100"/> <mx:gradiententry color="#24496d" ratio="0.9" alpha="100"/> <mx:gradiententry color="#000000" ratio="1" alpha="100"/> </mx:array> </mx:entries> </mx:lineargradient> </mx:fill> </mx:columnseries> <mx:lineseries yfield="average" form="curve" showdataeffect="interpolate"> <mx:stroke> <mx:stroke color="#708ea4" weight="1"/> </mx:stroke> </mx:lineseries> </mx:array> </mx:series> <mx:backgroundelements>

<mx:array> <!-- SDK4 <mx:gridlines griddirection="both"> --> <!-- SDK3 --> <mx:gridlines direction="both"> <mx:verticalstroke> <mx:stroke weight="1" color="#cccccc"/> </mx:verticalstroke> </mx:gridlines> </mx:array> </mx:backgroundelements> </mx:columnchart> </mx:vbox> <mx:vbox width="100%" height="100%" icon="@embed('icon_grid.png')" tooltip="grid View" hideeffect="fade" showeffect="fade"> <mx:datagrid dataprovider="revenuedata" width="100%" height="100%" change="monthchange(datagrid(event.target).selecteditem)"> <mx:columns> <mx:array> <mx:datagridcolumn datafield="name" headertext="month" sortcomparefunction="sortbydates" /> <mx:datagridcolumn datafield="revenue" headertext="total Revenue" labelfunction="datagridcurrencyformat" /> <mx:datagridcolumn datafield="average" headertext="average Across Regions" labelfunction="datagridcurrencyformat" /> </mx:array> </mx:columns> </mx:datagrid> </mx:vbox> </mx:viewstack> <mx:controlbar> <mx:togglebuttonbar dataprovider="vs"/> </mx:controlbar> </mx:panel> Create the RevenueTimeline file The RevenueTimeline.mxml represents a LineChart control that displays revenue data over a time period. An MXML tag in RevenueTimeline.mxml file defines a LineChart object named lc, as shown in the following code snippet.

<mx:linechart id="lc" dataprovider="revenuedata" showdatatips="true" width="100%" height="100%" datatipfunction="formatdatatip" itemclick="monthchange(event.hitdata.item)"> The RevenueTimeline.mxml file contains a bindable array named revenuedata. This object binds to the LineChart object. The RevenueTimeline object located in dashboard.mxml file is created by using an MXML tag. The following code snippet shows the RevenueTimeline instance named timeline that is defined in the dashboard.mxml file. <mx:panel id="timelinepanel" title="revenue Timeline" width="100%" height="100%"> <RevenueTimeline id="timeline" revenuedata="slicedmonthdata.source" monthchange="monthchange()"/> The revenuedata array defined in the RevenueTimeline.mxml file is populated by using an ArrayCollection instance named slicedmonthdata. This ArrayCollection instance is populated in the resulthandler method defined in dashboard.mxml. The data stored in the slicedmonthdata object is displayed in the RevenueTimeline instance when the dashboard application is started. The RevenueTimeline.mxml file defines an event named monthchange. Notice that the monthchange event is associated with the monthchange method. That is, when the month is changed, the monthchange method in dashboard.mxml is invoked. The following code snippet shows the body of the monthchange method. // Send messages when user's selection changes private function monthchange():void var message:imessage = new AsyncMessage(); message.body = month: timeline.selectedmonth; producer.send(message); A new message is created and sent to LiveCycle Data Services by invoking the Producer object s send method. The selectedmonth data member defined in the RevenueTimeline.mxml file is used to create the message. The following code represents the entire RevenueTimeline.mxml file. <?xml version="1.0" encoding="utf-8"?>

<mx:viewstack xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*" width="100%" height="100%"> <mx:script> <![CDATA[ import mx.charts.hitdata; [Bindable] public var revenuedata:array; [Bindable] public var selectedmonth:object; private var colors:array = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0x00FFFF]; protected function monthchange(month:object):void selectedmonth = month; dispatchevent(new Event("monthChange")); protected function currencyformat(value:object, arg2:object, arg3:object):string return cf.format(value); private function datagridcurrencyformat(item:object, column:object):string return cf.format(item[column.datafield]); private function sortbydates(obj1:object, obj2:object):number var n:number = SortUtils.sortByDates(obj1, obj2, "name"); return n; private function formatdatatip(hitdata:hitdata):string var name:string = hitdata.item.name; var revenue:number = hitdata.item.revenue; return "<b>month: "+name+"</b><br>revenue: "+cf.format(revenue);

]]> </mx:script> <mx:metadata> [Event("monthChange")] </mx:metadata> <mx:seriesinterpolate id="interpolate" elementoffset="10"/> <mx:currencyformatter id="cf"/> <mx:vbox id="chartvbox" width="100%" height="100%" icon="@embed('icon_chart.png')" tooltip="chart View" paddingleft="4" paddingtop="4" paddingbottom="4" paddingright="4"> <mx:linechart id="lc" dataprovider="revenuedata" showdatatips="true" width="100%" height="100%" datatipfunction="formatdatatip" itemclick="monthchange(event.hitdata.item)"> <mx:horizontalaxis> <mx:categoryaxis dataprovider="revenuedata" categoryfield="name"/> </mx:horizontalaxis> <mx:verticalaxis> <mx:linearaxis labelfunction="currencyformat"/> </mx:verticalaxis> <mx:series> <mx:lineseries yfield="revenue" showdataeffect="interpolate"> <mx:linestroke> <mx:stroke color="#708ea4" weight="1"/> </mx:linestroke> </mx:lineseries> <mx:lineseries yfield="license" showdataeffect="interpolate"> <mx:linestroke> <mx:stroke weight="1"/> </mx:linestroke> </mx:lineseries> </mx:series> <mx:backgroundelements> <mx:array> <!-- SDK4 <mx:gridlines griddirection="both"> --> <!-- SDK3 -->

<mx:gridlines direction="both"> <mx:verticalstroke> <mx:stroke weight="1" color="#cccccc"/> </mx:verticalstroke> </mx:gridlines> </mx:array> </mx:backgroundelements> </mx:linechart> </mx:vbox> <mx:vbox width="100%" height="100%" icon="@embed('icon_grid.png')" tooltip="grid View"> <mx:datagrid dataprovider="revenuedata" width="100%" height="100%" change="monthchange(datagrid(event.target).selecteditem)"> <mx:columns> <mx:datagridcolumn datafield="name" headertext="month" sortcomparefunction="sortbydates" /> <mx:datagridcolumn datafield="revenue" headertext="total Revenue" labelfunction="datagridcurrencyformat" /> <mx:datagridcolumn datafield="average" headertext="region Average" labelfunction="datagridcurrencyformat" /> </mx:columns> </mx:datagrid> </mx:vbox> </mx:viewstack> Create the SortUtils file The SortUtils.as file is a helper class that sorts data values by dates. This class uses a mx.utils.objectutil instance to compare two date values. The ObjectUtil instance s datecompare method returns a numeric value. The following code represents the entire SortUtils.as file. package import mx.utils.objectutil; public class SortUtils //lookup the index based on month abbreviation static public var monthmap:object = Jan: 0, Feb: 1, Mar: 2, Apr: 3, May: 4,

Jun: 5, Jul: 6, Aug: 7, Sep: 8, Oct: 9, Nov: 10, Dec: 11 ; public function SortUtils() super(); static public function sortbydates(obj1:object, obj2:object, prop:string):number var month:string = obj1[prop].substr(0,3); var month1:number = monthmap[month]; var year1:string = "20" + obj1[prop].substr(4,2); month = obj2[prop].substr(0,3); var month2:number = monthmap[month]; var year2:string = "20" + obj2[prop].substr(4,2); var date1:date = new Date(Number(year1), month1, 01); var date2:date = new Date(Number(year2), month2, 01); return ObjectUtil.dateCompare(date1, date2); Configure LiveCycle Data Services When a client application sends a message to LiveCycle Data Services, the message is sent to a destination on the server. You configure a destination by modifying XML files. Because the dashboard application uses the Message service, you configure the messagingconfig.xml file. Assuming that the name of the web application is named lcds, this xml file is located in the following folder: [LiveCycle Data Services Install path]\tomcat\webapps\lcds\web-inf\flex The Producer and Consumer objects defined in the dashboard.mxml file both reference the dashboard destination. The dashboard destination is defined in the messaging-config.xml

file, as shown in the following example. The unique id element value is referenced by the client application. <destination id="dashboard"> <properties> <network> <session-timeout>0</session-timeout> </network> <server> <max-cache-size>1000</max-cache-size> <message-time-to-live>0</message-time-to-live> <durable>true</durable> </server> </properties> <channels> <channel ref="my-rtmp"/> </channels> </destination> For information about the elements in the messaging-config.xml file, see the Using Adobe LiveCycle Data Service ES2 guide. Notice that the defined channel is my-rtmp (RTPM stands for real time messaging protocol). The my-rtmp channel is defined in the services-config.xml file, as shown in the following example. <channel-definition id="my-rtmp" class="mx.messaging.channels.rtmpchannel"> <endpoint url="rtmp://server.name:2037" class="flex.messaging.endpoints.rtmpendpoint"/> <properties> <idle-timeout-minutes>20</idle-timeout-minutes> <!-- for deployment on WebSphere, must be mapped to a WorkManager available in the web application's jndi context. <websphere-workmanager-jndiname>java:comp/env/wm/messagingworkmanager</websphere-workmanager-jndi-name> --> </properties> </channel-definition> Notice that the class for the channel is flex.messaging.endpoints.rtmpendpoint. There is no need to create a Java class on the server to run the dashboard application

Where to go from here For more information about creating Data Management applications, see the Using Adobe LiveCycle Data Services ES2 Guide.