Pentaho技术白皮书中文版(四)--创建 dashboards

这篇文档描述了如何使用 Pentaho BI 套件创建 dashboards。它描述了 Pentaho Demo 服务器提供的sample dashboard。

sample dashboard 以 JSP 和 PHP 形式提供。两个 dashboards 均使用相同的内容,提供相同的功能。JSP 实例显示了如何在 Pentaho UI 组件中使用 Java API,PHP 实例显示了如何在 Pentaho UI 组件中使用 Web 服务。

Java API 实例可用于 JSPs,Servlets,或 Java 应用。Web 服务实例可用于可发布 web 服务调用的任何技术,例如 PHP,IBM Domino 等。

1. Sample Dashboard

This page last changed on Mar 01, 2007 by wgorman.

Sample Dashboard 位于这个 URL (假设你将 Pentaho demo 安装于你本机的 8080 端口) 。http://localhost:8080/pentaho/jsp/SampleDashboard

sample dashboard 首先显示了一张饼图,其显示了四个区域中每个的 headcount costs。

关于如何定义饼图的更多信息请参考下面的 ‘Headcount Spending by Region Pie Chart’。

关于如何获得饼图的数据的更多信息请参考下面的 ‘Headcount Spending by Region Action Sequence’。

当用户点击饼图上的一个切片时,出现了另一张图表,对于选中的区域的每个部门,显示了 headcount budget 和 actual cost 间的不同。

饼图如何被定义的更多信息请参考下面的 ‘Headcount Variance Pie Chart’。

如何获取饼图的数据的更多信息请参考下面的 ‘Headcount Variance Action Sequence’。

当用户点击一个部门的 bar 时,dashboard 在图表下,显示了一个 dial 和一个数据表。dial 基于当前时间(因此它随着时间改变) 显示了一个值,表显示了选中部门内的 positions 的详细信息。

如何定义 dial 的更多信息请参考下面的 ‘动态 Dial’。

如何定义嵌入式报表的更多信息请参考下面的 ‘嵌入式报表’。

当用户点击表中的一个 position 的名字时,dashboard drills 到另一个页面,并传送 region,department 和 position 作为参数。

这一页的源代码请参考附录 8:Drill JSP

2. 体系结构

This page last changed on Dec 04, 2006 by mdamour.

3. 内容定义

This page last changed on Dec 04, 2006 by mdamour.

动态 Dial

This page last changed on Dec 05, 2006 by mdamour.

这个 dial 的定义在 pentaho-demo/pentaho-solutions/samples/dashboard/sampledial.widget.xml

这个 XML 文件定义了:

 

设置

描述

widget/dial/units

units of dial value

$

widget/dial/plot-background/text

dial area 的 re-image 背景

/samples/portal/dial_03 .gif

widget/dial/tick-interval

gap between ticks

5

widget/dial/tick-color

ticks 的颜色

#808080

widget/dial/needle-color

Needle 的颜色

#808080

widget/dial/chart-background/texture-image

Background chart image

/samples/portal/dial_03 .gif

widget/dial/interval/label

Interval name

'under'

widget/dial/interval/minimum

Interval lower limit

-15

widget/dial/interval/maximum

Interval upper limit

0

widget/dial/interval/color

Interval background color

#FFFFFF

widget/dial/interval/text-color

Interval text and tick color

#40BB40

widget/dial/interval/stroke-width

Interval line thickness

5

 

注意在文件中定义了两个 intervals:一个覆盖了从 -15 到 0 的范围,另一个是 0 到 +15。

除了在 widget XML 文件中定义的这些设置,caller 还指定了这些设置:

 

设置

描述

title

dial 的标题

'My Dial'

value

Dial 上显示的值

Varies over time from -10 to +15

image-width

dial image 的宽度

105

image-height

dial image 的高度

105

 

在 sample dashboard 中,基于当前时间,页面为 dial 创建了一个值。

嵌入式报表

This page last changed on Jan 30, 2007 by wgorman.

报表模版的定义在:pentaho-demo/pentaho-solutions/samples/dashboard/jsp/embedded_report.xml

报表模版被报表引擎(JFreeReport) 用于布局嵌入式报表。你可使用 Pentaho Report Wizard 设计一个报表定义。

你创建的是 HTML 的一个片段,而不是一个完整的 HTML 页面。你需要编辑报表定义 XML 文件以在 report/configuration 的报表配置区域添加一个属性。

<property name="org.jfree.report.modules .output .table.html.BodyFragment">true</property>

为将报表内容中的一个 drill link 添加进一个 URL,你需要编辑报表定义,并添加一个 URL 表达式,例如 sample dashboard 中的这个。

<expression name="URLCreateExpression"

class="org. jfree.report.function.TextFormatExpression">

<properties>

<property

name="pattern">SampleDrill? region={ 0} &amp;position={ 1} &amp; department={ 2} </property>

<property name="field[ 0] ">REGION</property>

<property name="field[ 1] ">POSITIONTITLE</property> <property name="field[ 2]">DEPARTMENT</property>

</properties>

</expression>

Headcount Spending By Region Pie Chart

This page last changed on Jan 30, 2007 by wgorman.

这张饼图的定义在: pentaho-demo/pentaho-solutions/samples/dashboard/regions.widget.xml

这个 XML 文件定义了:

设置

描述

chart/title

图的标题

Headcount Spending by Region

chart/title-position

图的标题的位置(上,下,左或右)

top

chart/title-font/font-family

标题字体的名字

Ariel

chart/title-font/size

标题字体的大小

20

chart/title-font/is-bold

标题字体是粗体么?

false

chart/title-font/is-italic

标题字体是斜体么?

false

chart/is-3D

饼图是 3D 的么?

false

chart/border-visible

Does chart have a border?

false

chart/include-legend

Does chart have a legend?

false

chart/data/data-solution

solution for action sequence providing data for this chart

samples

chart/data/data-path

action sequence 的路径

dashboard

chart/data/data-action

action sequence 的名字

regions_headcount_data.xaction

chart/data/data-output

action sequence 输出

rule-result

chart/data/data-name

包含 pie slice 名称的数据列

REGION

chart/data/data-value

包含 pie slice 值的数据列

ACTUAL

chart/data/data-orientation

direction in which to process data to get pie slices (rows/columns)

rows

 

除了 widget XML 中定义的这些设置,调用者还可指定这些设置:

 

设置

描述

drill-url

用于生成 drill 路径的一个 URL 模版。URL 可有包含在 ‘{‘ and ‘}’中的可替换参数。

SampleDashboard?region={REGION}

inner-param

在 URL 中包含将被替换的值的数据列

 

REGION

chart 组件从这个文件中读取所有的设置,然后执行指定的 action sequence 为图表获取数据。sample dashboard 中的 action sequences 仅使用一个单一的组件生成数据,但是 BI 组件的任何序列可用来执行复杂的(例如 scripting 或 in-line ETL) 或远程的(例如 Web 服务) 任务。

Headcount Variance Bar Chart

This page last changed on Jan 30, 2007 by wgorman.

这个 bar chart 的定义在:

pentaho-demo/pentaho-solutions/samples/dashboard/departments.widget.xml

这个 XML 文件定义了:

 

 

设置

描述

 

chart/type

图的类型(BarChart, LineChart, AreaChart)

BarChart

 

chart/title

图的标题

Headcount Variance

 

chart/title-position

图的标题的位置(上,下,左,右)

top

 

chart/title-font/font-family

标题字体的名字

Ariel

 

chart/title-font/size

标题字体的大小

20

 

chart/title-font/is-bold

图的标题是粗体么?

false

 

chart/title-font/is-italic

图的标题是斜体么?

false

 

chart/is-3D

图是 3D 的么?

false

 

chart/border-visible

Does chart have a border?

false

 

chart/include-legend

Does chart have a legend?

false

 

chart/chart-background

chart image 的背景。你可定义gradients, textures,images 或flat colors

type=color #FFFFFF

 

chart/plot-background

plot area 的背景

type=color #EEEEEE

 

chart/orientation

chart 的方向(垂直或水平)

horizontal

 

chart/is-stacked

Is chart stacked?

false

 

chart/color-palette/color

color to use for first series

#336699

 

chart/color-palette/color

color to use for second series

#99CCFF

 

chart/data/data-solution

solution for action sequence providing data for this chart

Samples

 

chart/data/data-path

action sequence 的路径

dashboard

 

chart/data/data-action

action sequence 的名字

regions_headcount_data.xaction

chart/data/data-output

action sequence 的输出

rule-result

 

chart/data/data-name

包含 pie slice names 的数据列

REGION

 

chart/data/data-value

包含 pie slice values 的数据列

ACTUAL

 

chart/data/data-orientation

direction in which to process data to get pie slices (rows/columns)

rows

 

             

 

除了在 widget XML 文件中定义的这些设置,caller 还指定了这些设置:

设置

描述

drill-url

一个 URL 模版用于生成 drill 路径。URL 可有包含在 ‘{‘ and ‘)’ 中的可替换的参数

SampleDashboard?region=Central&

inner-param

data column containing values to be replaced in URL

DEPARTMENT

REGION

在查询中用来选择数据的过滤器

Dynamically set e.g. 'Eastern'

image-width

chart image 的宽度

450

image-height

chart image 的高度

300

REGION 参数被传送进 action sequence 用作一个查询查询过滤器。

4. Action Sequences

This page last changed on Dec 04, 2006 by mdamour.

嵌入式报表 Action Sequence

This page last changed on Dec 04, 2006 by mdamour.

这个报表的定义在: pentaho-demo/pentaho-solutions/samples/dashboard/jsp/embedded_report.xaction

你可以在 Eclipse IDE 中使用 Pentaho Design Studio 编辑这个文件。这个 action sequence 包含一个 JFree Report 组件,其从 sample 数据库获取数据,使用一个报表模版生成一个HTML 片段。

action sequence 带有参数 ‘region’ 和 ‘department’,其用作查询中的过滤器。报表组件执行这个查询:

select QUADRANT _ACTUALS . REGION, QUADRANT _ACTUALS . DEPARTMENT, QUADRANT _ACTUALS . POSITIONTITLE,

QUADRANT _ACTUALS . ACTUAL, QUADRANT _ACTUALS . BUDGET,QUADRANT _ACTUALS.VARIANCE

from QUADRANT _ACTUALS

where QUADRANT _ACTUALS.REGION = '{region}'

and QUADRANT _ACTUALS.DEPARTMENT = '{department}'

order by QUADRANT _ACTUALS.REGION, QUADRANT_ACTUALS. DEPARTMENT

使用一个报表模板:pentaho-demo/pentaho-solutions/samples/dashboard/jsp/embedded_report.xml (参考上面的嵌入式报表)

报表组件在一个名为 ‘report’ 的输出中返回 HTML,action sequence 将这个输出转向到 response 的 output stream。

Headcount Spending by Region Action Sequence

This page last changed on Dec 04, 2006 by mdamour.

这个 action sequence 的定义在: pentaho-demo/pentaho-solutions/samples/dashboard/regions_headcount_data .xaction

你可以在 Eclipse IDE 中使用 Pentaho Design Studio 以编辑这个文件。

这个 action sequence 包含一个 SQL Query Rule,其从 Pentaho demo 服务器提供的 sample 数据库获取一些数据。action sequence 不带任何参数。

SQL Query Rule 执行这个查询:

select REGION, sum(ACTUAL) as ACTUAL

from quadrant _actuals

group by REGION order by ACTUAL

并在一个名为 ‘rule-result’ 的输出中返回数据。这个数据用于生成 ‘Headcount Spending By Region’ 饼图。

Headcount Variance Action Sequence

This page last changed on Dec 04, 2006 by mdamour.

这个 action sequence 的定义在:pentaho-demo/pentaho-solutions/samples/dashboard/department_variance_data .xaction

你可以在 Eclipse IDE 中使用 Pentaho Design Studio 以编辑这个文件。

这个 action sequence 包含一个 SQL Query Rule,其从 Pentaho demo 服务器提供的 sample 数据库获取一些数据。

action sequence 带有一个参数 REGION,其在查询中用作过滤器,SQL Query Rule 执行这个查询:

select department, sum(variance) from quadrant _actuals

where region='{ REGION}'

group by department

在名为 ‘rule-result’ 的输出中返回数据。这个数据用于生成 ‘Headcount Variance By Region’ 饼图。

5. 定制 PCI JSP Dashboard

This page last changed on Feb 01, 2007 by wgorman.

实例 1: 将饼图变成柱状图

这个实例描述了在 SampleDashboard solution 中,将一个饼图转换成一个柱状图所需要进行的修改。为了修改,必须同时更新 widget xml 和 SampleDashboard.jsp 中的 java 代码。

步骤 1: 更新 SampleDashboard. jsp 文件

不要调用 ChartHelper.doPieChart(),而是对 ChartHelper.doChart() 进行 java调用。方法标识是一样的, 包括 widget xml 的位置,可定制参数,输出要写进的 string buffer,user session,存储消息的 messages 对象,和一个 logger 对象(如果可用)。

修改 widget.xml 指向我们的新 _regions.widget.xml 文件,其在下一步被创建。

柱状图稍不同于饼图,当涉及到它们的 templated inner param 时。用 "{SERIES}" 替换 "drill-url" 参数的 "{REGIONS}" 部分,其允许图表适当生成 outgoing 链接。

步骤 2: 创建 new_regions .widget.xml 文件

饼图和柱状图 <chart> xml 文件包含用于定制的不同参数集合。不需要检查所有参数,将departments .widget.xml 复制到新的 _regions.widget.xml文件,其是一个预存在的柱状图实例。

注意 chart-type 元素,以及各种用于定制柱状图的 style 元素。将 title 元素修改回 "Headcount Spending by Region",data -> data-action 元素修改回 "regions_headcount_data.xaction"。现在我们就有一个配置好的柱状图了。

注意:你必须在 admin 工具中刷新 solution repository,使得对于 widget 的修改生效。

实例 2: Swapping Regions  Departments

这个实例描述了在 dashboard 中 swapping regions with departments。

步骤 1: 更新 SampleDashboard.jsp 文件

如果你从上面的实例 1 开始操作的,从实例中删除对于 JSP 的修改。

替换这段代码:

String title = "Select a region";

if( department != null ) {

title = "This is headcount spending for " + region + ", " + department;

}

else if ( region != null ) {

title = "This is headcount spending for " + region;

}

用这段代码:

String title = "Select a department";

if( region != null ) {

title = "This is headcount spending for " + department + ", " + region;

}

else if ( department != null ) {

title = "This is headcount spending for " + department;

}

为将 region pie chart 改成 departments:

用 "Select a Department By Clicking on Pie Chart" 替换 "Select a Region By Clicking on Pie Chart"。

用 "SampleDashboard?department= {DEPARTMENT}" 替换 "SampleDashboard?region ={REGION}"。

替换这行:

parameters.setParameter( "inner-param", "REGION");

用:

parameters.setParameter( "inner-param", "DEPARTMENT");

用 "new_departments.widget.xml" 替换 "regions.widget.xml"。

为将 department bar chart 改变成 regions:

替换这行:

if( region != null ) {

用:

if( department != null ) {

用 "Select a Region By Clicking on Bar Chart" 替换 "Select a Department By Clicking on Bar Chart "。

替换这行:

parameters. setParameter ( "drill-url", "SampleDashboard? region="+region+"&department={ SERIES}" );

用:

parameters. setParameter ( "drill-url",

"SampleDashboard? department="+department+"&region={ SERIES} " );

替换这行:

parameters.setParameter( "REGION", region );

用:

parameters.setParameter( "DEPARTMENT", department );

替换这行:

parameters.setParameter( "outer-params", "REGION" );

用:

parameters. setParameter ( "outer-params", "DEPARTMENT" );

替换这行:

parameters.setParameter( "inner-param", "DEPARTMENT");

用:

parameters.setParameter( "inner-param", "REGION");

用 "new_regions.widget.xml" 替换 "departments.widget.xml"。

替换包含这句的两行:

if( department != null ) {

用:

if( region != null ) {

步骤 2: 创建 new_departments.widget.xml 文件

复制 regions.widget.xml 文件成新的 _departments.widget.xml。

用 "Headcount Spending by Department" 替换 "Headcount Spending by Region"。

用 "departments_headcount_data.xaction" 替换 "regions_headcount_data .xaction"。

替换这句:

<data-name>REGION< / data-name>

用:

<data-name> DEPARTMENT< / data-name>

步骤 3: 创建 departments_headcou nt_data.xaction 文件

复制 regions _headcount _data.xaction 文件成 departments _headcount _data.xaction。

用 "Return actual headcount costs total for each department" 替换 "Return actual headcount costs total for each region"。

替换 SQL 查询:

select REGION, sum(ACTUAL) as ACTUAL from QUADRANT _ACTUALS group by REGION order by ACTUAL

用:

select DEPARTMENT, sum(ACTUAL) as ACTUAL from QUADRANT _ACTUALS group by DEPARTMENT order by ACTUAL

步骤 4: 创建 new_regions.widget.xml 文件

将文件 departments.widget.xml 复制成新的 _regions.widget.xml 文件。替换这句:

<data-action>department _variance _data. xaction</data-action>

用:

<data-action>region _variance _data. xaction</data-action>

步骤 5: 创建 region_variance_data.xaction 文件

复制 department _variance _data.xaction 文件成 region _variance _data.xaction。

用 "Return variance between headcount actual and budget for every region in specified department" 替换 "Return variance between headcount actual and budget for every department inspecified region"。

替换:

<inputs>

<REGION type="string">

<sources>

<request>REGION</request></ sources>

</REGION>

</inputs>

用:

<inputs>

<DEPARTMENT type="string">

<sources>

<request>DEPARTMENT< /request> </ sources>

</DEPARTMENT>

</inputs>

用 "Define an input called 'DEPARTMENT'." 替换 "Define an input called 'REGION'."。

替换

<REGION type="string"/>

用:

<DEPARTMENT type="string"/>

替换 SQL 查询:

select department, sum(variance) from QUADRANT _ACTUALS where region in ( {PREPARE:REGION} )

group by department

用:

select region, sum(variance) from QUADRANT _ACTUALS where department in ( {PREPARE:DEPARTMENT} ) group by region

附录01 Dashboard JSP

This page last changed on Jan 30, 2007 by wgorman.

这是 JSP Sample Dashboard 的源代码:

<%@ page language="java"

import="java.util.ArrayList,

java.util.Date,

java.io.ByteArrayOutputStream,

org.pentaho.core.ui.SimpleUrlFactory,

org.pentaho.messages.Messages,

org.pentaho.core.system.PentahoSystem,

org.pentaho.ui.component.DashboardWidgetComponent,

org. pentaho.core. solution. HttpRequestParameterProvider, org.pentaho.core.solution.HttpSessionParameterProvider,

org.pentaho.core.session.IPentahoSession,

org.pentaho.core.util.UIUtil,

org.pentaho.util.VersionHelper,

org.pentaho.messages.util.LocaleHelper,

org.pentaho.core.solution.ActionResource,

org.pentaho.core.solution.IActionResource,

org.pentaho .core. solution. SimpleParameterProvider, org.pentaho.ui.ChartHelper,

java. io .*"

%><%

/*

*    Copyright 2006 Pentaho Corporation. All rights reserved.

*    This software was developed by Pentaho Corporation and is provided under the terms

*    of the Mozilla Public License, Version 1.1, or any later version. You may not use

*    this file except in compliance with the license. If you need a copy of the license,

*    please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho

*    BI Platform. The Initial Developer is Pentaho Corporation.

*

*    Software distributed under the Mozilla Public License is distributed on an "AS IS"

*    basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to

*    the license for the specific language governing your rights and limitations.

*

*    Created Feb 16, 2006

*    @author James Dixon

*/

/*

*    This JSP is an example of how to use Pentaho components to build a dashboard.

*    The script in this file controls the layout and content generation of the dashboard.

*    See the document 'Dashboard Builder Guide' for more details

*/

// set the character encoding e.g. UFT-8

response. setCharacterEncoding (LocaleHelper.getSystemEncoding ());

// get the current Pentaho session or create a new one if needed

IPentahoSession userSession = UIUtil.getPentahoSession( request );

%>

<html>

<head>

<title>Pentaho Sample Dashboard - JSP</title>

</head> <body>

<%

// See if we have a 'department' parameter String department = request.getParameter ("department"); // See if we have a 'region' parameter

String region = request.getParameter("region");

// Create the title for the top of the page

String title = "Select a region"; if( department != null ) {

title = "This is headcount spending for " + region + ", " + department;

}

else if ( region != null ) {

title = "This is headcount spending for " + region;

}

%>

<h1 style='font-family:Arial'><%= title %></h1>

<table>

<tr>

<td valign="top"><span style="font-family:Arial; font-weight :bold">Select a Region By Clicking on the Pie Chart</span>

<%

// Make a pie chart showing the regions // create the parameres for the pie chart

SimpleParameterProvider parameters = new SimpleParameterProvider();

// define the click url template

parameters.setParameter( "drill-url", "SampleDashboard?region={ REGION} " );

// define the slices of the pie chart

parameters. setParameter ( "inner-param", "REGION"); //$NON-NLS-1$ //$NON-NLS-2$

// set the width and the height

parameters. setParameter ( "image-width", "450") ; //$NON-NLS-1$ //$NON-NLS-2$ parameters.setParameter( "image-height", "300"); //$NON-NLS-1$ //$NON-NLS-2$ StringBuffer content = new StringBuffer();

ArrayList messages = new ArrayList();

// call the chart helper to generate the pie chart image and to get the HTML

content

// use the chart definition in 'samples/dashboard/regions.widget.xml' ChartHelper.doPieChart ( "samples", "dashboard", "regions .widget.xml", parameters, content, userSession, messages, null );

%>

<%= content.toString() %>

</td>

<td valign="top"><span style="font-family:Arial; font-weight :bold">

<%

if( region != null ) {

// if the user has clicked on a slice of the pie chart we should have a

region to work with

%>

Select a Department By Clicking on the Bar Chart

<%

// Make a bar chart showing the department

// create the parameres for the bar chart

parameters = new SimpleParameterProvider();

// define the click url template

parameters. setParameter ( "drill-url",

"SampleDashboard? region="+region+"&amp; department={ SERIES} " );

parameters.setParameter( "REGION", region );

parameters.setParameter( "outer-params", "REGION" );

// define the category axis of the bar chart

parameters. setParameter ( "inner-param", "DEPARTMENT"); //$NON-NLS-1$

// $NON-NLS-2 $

// set the width and the height

parameters. setParameter ( "image-width", "450") ; //$NON-NLS-1$ //$NON-NLS-2$ parameters.setParameter( "image-height", "300"); //$NON-NLS-1$ //$NON-NLS-2$ content = new StringBuffer();

messages = new ArrayList();

// call the chart helper to generate the pie chart image and to get the

HTML content

// use the chart definition in 'samples/dashboard/regions.widget.xml'

ChartHelper.doChart ( "samples", "dashboard", "departments .widget.xml", parameters, content, userSession, messages, null );

%>

</span>

<br/>

<%= content.toString() %>

<%

}

%> </tr>

<tr>

<td colspan="2" valign="top" style="font-family:Arial; font-weight:bold"><hr

size="1"/>

</tr>

<tr>

<td valign="top"><span style="font-family:Arial; font-weight :bold">

<%

if( department != null ) {

// if the user has clicked on a bar of the bar chart we should have a region and department to work with

// create a dial and supply a value we create from the current time

Date now = new Date();

int seconds = now.getSeconds();

// create a value from -15 to +15

int dialValue = -15+seconds/2;

// create the parameres for the bar chart

parameters = new SimpleParameterProvider();

// set the value displayed on the dial

parameters. setParameter ( "value", ""+dialValue );

// set the title for the dial

parameters.setParameter( "title", "My Dial" );

// set the width and the height

parameters. setParameter ( "image-width", "105") ; //$NON-NLS-1$ //$NON-NLS-2$ parameters.setParameter( "image-height", "105"); //$NON-NLS-1$ //$NON-NLS-2$ content = new StringBuffer();

messages = new ArrayList();

// call the chart helper to generate the pie chart image and to get the

HTML content

// use the chart definition in 'samples/dashboard/regions.widget.xml'

ChartHelper.doDial ( "samples", "dashboard", "sampledial.widget .xml", parameters, content, userSession, messages, null );

%>

The value of this dial is based on the current time

</span>

<p/>

<%= content.toString() %>

<%

}

%>

</td>

<td valign="top" style="font-family:Arial; font-weight:bold">

<%

if( department != null ) {

// if the user has clicked on a bar of the bar chart we should have a region and department to work with

// run a report and embed the content into this page

// create the parameres for the report

parameters = new SimpleParameterProvider();

// pass the region and department to the report parameters.setParameter( "region", region );

parameters.setParameter( "department", department ); // create an output stream for the report content

ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); messages = new ArrayList();

// run the action sequence 'samples/dashboard/jsp/report.xaction'

ChartHelper.doAction ( "samples", "dashboard/jsp", "embedded_report .xaction",

"SampleDashboard", parameters, outputStream , userSession, messages, null ); // write the report content into this page

%>

Click on a position title to drill to another page </span>

<p/>

<% out.write( outputStream.toString() ); %>

<%

}

%>

</td>

</tr>

</table>

</body> </html>

附录02 Pie Chart 定义

This page last changed on Jan 30, 2007 by wgorman.

<chart>

<!--        This file defines the pie chart that shows the actual values for each
region -->

<!-- Specify the title of the chart --> <title>Headcount Spending by Region</title> <!-- Specify the location of the title --> <title-position>none</title-position> <!-- Specify the font of the title --> <title-font>

<font-family>Ariel< /font-family> <size>20</size>

<is-bold>false</is-bold>

<is-italic>false</is-italic> </title-font>

<width> 450</width>

<height> 300</height>

<!-- Specify the 3D-ness of the bars --> <is-3D> fal s e< / is-3D>

<!-- Specify if the chart has a border and the border color -->

<border-vis ible>false</border-visible> <border-paint>#bbbbff</border-paint>

<!-- Specify is the chart legend should be shown -->

<include-legend>false</ include-legend>

<!-- Specify where the data for the chart comes from -->

<data>

<!-- Specify the path to the action sequence that provides the data --> <data-solution>samples</data-solution> <data-path>dashboard</data-path>

<data-action>regions_headcount_data.xaction</data-action>

<!-- Specify the output of the action sequence that contains the data --> <data-output>rule-result</data-output> <data-name>POSITIONTITLE</data-name>

<data-value>ACTUAL< /data-value>

<!-- Specify whether to get the pie series from the rows or columns --> <data-orientation>columns</data-orientation>

</data>

</chart>

附录03 Region 数据

This page last changed on Jan 30, 2007 by wgorman.

<action-sequence>

<version> 1< /vers ion>

<title>Regions and departments</title> <logging-level>debug</logging-level> <documentation>

<author>James Dixon</author>

<description>Return the actual headcount costs total for each region</description>

<help></help>

</documentation>

<inputs/>

<!-- Define an output called 'rule-result' --> <outputs>

<rule-result>

<type> list< / type>

</rule-result>

</outputs>

<!-- This action sequence does not require any external resources --> <resources/>

<actions>

<action-definition>

<action-inputs/>

<!-- Define a local output called 'rule-result' -->

<action-outputs>

<rule-result type="list"/>

</action-outputs>

<!-- Specify the component to execute --> <component-name> SQLLookupRule< / component-name> <action-type>rule</action-type>

<!-- Define the settings for the component -->

<component-definition>

<!-- Define the datasource for the query -->

<jndi>SampleData</j ndi>

<!--                                       Define the query to execute. Note the parameter

{REGION} in the query -->

<query><![ CDATA[

select REGION, sum(ACTUAL)

from quadrant _actuals

group by REGION order by ACTUAL]]> </query>

</component-definition>

</action-definition>

</actions>

</action-sequence>

附录04 Department Bar Chart 定义

This page last changed on Jan 30, 2007 by wgorman.

<chart>

<!--        This file defines the bar chart that shows the actual-to-budget variance
for each department -->

<!-- Define the chart type --> <chart-type>BarChart</chart-type>

<!-- Specify the title of the chart -->

<title>Headcount Variance</title>

<!-- Specify the location of the title -->

<title-position>TOP</title-position> <!-- Specify the font of the title --> <title-font>

<font-family>Ariel< /font-family>

<size>20</size>

<is-bold>false</is-bold> <is-italic>false</is-italic>

</title-font>

<chart-background-color>#FF80FF</chart-background-color>

<plot-background-color> #FFFF00< /plot-background-color>

<!-- Specify the orientation of the bars -->

<orientat ion>Ho ri z ontal< / orientation> <!-- Specify the 3D-ness of the bars -->

<is-3D> fal s e< / is-3D>

<!-- Specify if the bars are stacked -->

<is-stacked>false</is-stacked>

<!-- Specify if the chart has a border and the border color -->

<border-vis ible>true</border-visible> <border-paint>#000000</border-paint>

<!-- Specify is the chart legend should be shown --> <include-legend>true</include-legend> <!-- Specify the color palette for the chart -->

<color-palette>

<color>#336699</color> <color>#99CCFF</color> <color>#999933</color> <color>#666699</color> <color>#CC9933</color> <color>#006666</color> <color>#3399FF</color> <color>#993300</color> <color>#CCCC99</color> <color>#666666</color> <color>#FFCC66</color> <color>#6699CC</color><color>#663366</color>

</color-palette>

<!-- Specify where the data for the chart comes from -->

<data>

<!-- Specify the path to the action sequence that provides the data --> <data-solution>samples</data-solution>

<data-path>dashboard</data-path> <data-action>department_variance_data.xaction</data-action>

<!-- Specify the output of the action sequence that contains the data --> <data-output>rule-result</data-output>

<!-- Specify whether to get the chart series from the rows or columns --> <data-orientation>rows< /data-orientation>

</data>

</chart>

附录05 Department Variance 数据

This page last changed on Jan 30, 2007 by wgorman.

这个 action sequence 指定一个 SQL 查询,获取一个指定区域的每个部门的 headcount 的真实值和预算的差值。

action sequence 定义于:

~/pentaho-demo/pentaho-solutions/samples/dashboard/department_variance_dial .xaction.

使用 Pentaho BI Studio

<?xml version="1 .0" encoding="UTF-8"?> <action-sequence>

<version> 1< /vers ion>

<title>Regions and departments</title> <logging-level>debug</logging-level> <documentation>

<author>James Dixon</author>

<description>Return the variance between headcount actual and budget for every

department in the specified region</description> <help>just testing. . .</help>

</documentation>

<!-- Define an input called 'REGION'. This will be passed in when the user clicks on a slice of the pie chart -->

<inputs>

<REGION type="string">

<sources>

<request>REGION</request> </ sources>

</REGION>

</inputs>

<!-- Define an output called 'rule-result' --> <outputs>

<rule-result>

<type> list< / type>

</rule-result>

</outputs>

<!-- This action sequence does not require any external resources -->

<resources/>

<actions>

<action-definition>

<!-- Define a local input called 'REGION' -->

<action-inputs>

<REGION type="string"/> </action-inputs>

<!-- Define a local output called 'rule-result' -->

<action-outputs>

<rule-result type="list"/> </action-outputs>

<!-- Specify the component to execute -->

<component-name> SQLLookupRule</component-name> <action-type>rule</action-type> <!-- Define the settings for the component -->

<component-definition>

<!-- Define the datasource for the query -->

<jndi>SampleData</jndi>

<!--     Define the query to execute. Note the parameter

{REGION} in the query -->

</query>

</component-definition>

</action-definition>

</actions>

</action-sequence>

附录06 Dial 定义

This page last changed on Jan 30, 2007 by wgorman.

<widget>

<dial>

<name>Gauge 1</name>

<units>$</units>

<!-- this is the background for the whole image -->

<!-- background-color>#ffffff</background-color -->

<!-- this ia the background for the dial -->

<!-- plot-background-color>#777700</plot-background-color -->

<plot-background type="texture"> <texture-image>/samples/portal/dial_03.gif</texture-image> </plot-background>

<tick-interval> 5</tick-interval> <value-color>#9 999bb</value-color> <tick-color>#808080</tick-color>

<!-- this is the color of the needle -->

<needle-color>#808080</needle-color> <chart-background type= "texture">

<texture-image>/samples/portal/dial_03.gif</texture-image> </chart-background>

<!--    intervals define ranges on the dial that are colored differently
from the dial background -->

<interval>

<label>under</label>

<!-- this is the value that the range starts at -->

<minimum>-1 5</minimum>

<!-- this is the value that the range stops at -->

<maximum> 0</maximum>

<!-- this is the color of the range -->

<color>#ffffff</color>

<!--   this is the color of the text for the range value and tick

marks -->

<text-color>#40bb40</text-color>

<stroke-width>5</stroke-width>

</interval>

<interval>

<label>over</label>

<minimum> 0</minimum>

<maximum> 15</maximum>

<color>#ffffff</color>

<text-color>#bb4040</text-color> <stroke-width>5</stroke-width> </interval>

</dial>

</widget>

附录07 嵌入式报表模板

This page last changed on Jan 30, 2007 by wgorman.

<?xml version="1 .0" encoding="UTF-8"?>

<action-sequence>

<version> 1< /vers ion>

<title>JFreeReport HTML Example</title> <logging-level>debug</logging-level> <documentation>

<author>James Dixon</author> <description><![ CDATA[

This is an example of an HTML report produced by JFreeReport.

<p/>It shows the actual headcount cost, budgeted headcount

cost, and variance for every position in the specified

department and region ] ] ></description>

<icon>/style/icons/jfree1 .png</icon>

<help></help>

</documentation>

<!--        Define an input called 'region' and an input called 'department'. These
will be passed in when the user clicks on a bar on the bar chart -->

<inputs>

<region type="string"> <sources>

<request>region</request>

</sources>

</region>

<department type="string">
<sources>

<request>department</request>

</sources>

</department>

</inputs>

<!-- Define an output called 'report' -->

<outputs>

<report type="content"> <destinations>

<response>content</response>

</destinations> </report>

</outputs>

<!-- This action sequence uses a report definition file embedded_report.xml --> <resources>

<report-definition>

<solution-file>

<location>embedded_report.xml</location>

<mime-type> text/xml</mime-type>

</solution-file> </report-definition></resources>

<actions>

<action-definition>

<!-- Define a local inputs called 'region' and 'department' --> <action-inputs>

<region type="string"/>

<department type="string"/>

</action-inputs>

<!-- Define a local output called 'report' -->

<action-outputs>

<report type="content"/>

</action-outputs>

<!-- Specify the component to execute --> <component-name>JFreeReportComponent< /component -name> <action-type>report</action-type>

<!-- Define the settings for the component -->

<component-definition>

<live>false</live>

<!-- Define the datasource for the query -->

<jndi>SampleData</j ndi>

<source> sql</source>

<!--         Define the query to execute. Note the parameter
{region} and {department} in the query -->

</ query>

<!-- Define the content type for the report --> <output-type>html< / output-type>

</component-definition>

</action-definition>

</actions> </action-sequence>

附录08 Drill JSP

This page last changed on Jan 30, 2007 by wgorman.

<%@ page language="java"

import="java.util.ArrayList,

java.util.Date,

java.io.ByteArrayOutput Stream,

org.pentaho.core.ui.SimpleUrlFactory,

org.pentaho.messages.Messages,

org.pentaho.core.system.PentahoSystem,

org.pentaho.ui.component.DashboardWidgetComponent,

org. pentaho .core. solution. HttpRequestParameterProvider, org. pentaho.core.solution.HttpSessionParameterProvider,org. pentaho.core.session.IPentahoSession,

org.pentaho.core.util.UIUtil,

org.pentaho.util.VersionHelper,

org.pentaho.messages.util.LocaleHelper,

org.pentaho.core.solution.ActionResource,

org.pentaho.core.solution.IActionResource,

org.pentaho .core. solution. SimpleParameterProvider, org. pentaho.ui.ChartHelper,

java. io .*"

%><%

/*

*    Copyright 2006 Pentaho Corporation. All rights reserved.

*    This software was developed by Pentaho Corporation and is provided under the terms

*    of the Mozilla Public License, Version 1.1, or any later version. You may not use

*    this file except in compliance with the license. If you need a copy of the license,

*    please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho

*    BI Platform. The Initial Developer is Pentaho Corporation.

*

*    Software distributed under the Mozilla Public License is distributed on an "AS IS"

*    basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to

*    the license for the specific language governing your rights and limitations.

*

*    Created Feb 16, 2006

*    @author James Dixon

*/

/*

This JSP page is part of the Pentaho samples that show how JSP can be

used to present and control content that is generated by the Pentaho BI Platform.

This JSP page is the page that is used after a user clicks on a link in the embedded report that is displayed in SampleDashboard.jsp.

The region, department, and job position title are passed in as parameters on the URL The url is formatted in the report definition file: ~/pentaho-demo/pentaho-solutions/samples/dashboard/j sp/embedded _report .xml

The url is set in the last function that is defined in the file. The important line is the "pattern"

<expression name="URLCreateExpression"

class="org. jfree.report . function.TextFormatExpression">

<properties> <property

name="pattern">SampleDrill? region={ 0} &amp;position={ 1} &amp; department={ 2} </property>

<property name="field[ 0] ">REGION</property>

<property name="field[ 1] ">POSITIONTITLE</property>

<property name="field[ 2] ">DEPARTMENT</property>

</properties> </ express ion>

You can change the url template to point to wherever you need it to

*/

String region = request.getParameter("region");

String department = request.getParameter("department"); String position = request.getParameter ("position");

%>

<html>

<head>

<title>Pentaho Regional Report - JSP Sample</title>

</he ad> <body>

<h1 style="font-family:Arial">Drill Destination</h1>

<span style="font-family:Arial">

The selected region is '<%= region %>'

<p/>

The selected department is '<%= department %>'

<p/>

The selected position is '<%= position %>'

</span>

</body> </html>

附录09 Steel Wheels JSP

This page last changed on Jan 30, 2007 by wgorman.

*    <%@ page language="java"

import="java.util .ArrayList,

java .util .Date,

java. io. ByteArrayOutput Stream,

org. pentaho . core. ui . SimpleUrlFactory,

org.pentaho .messages .Messages,

org. pentaho . core. system. PentahoSystem,

org. pentaho . ui.component. DashboardWidgetComponent,

org. pentaho .core. solution. HttpRequestParameterProvider, org. pentaho .core. solution. HttpSessionParameterProvider, org. pentaho .core. session. IPentahoSession,

org. pentaho .core. util . UIUtil,

org. pentaho . util .VersionHelper,

org. pentaho .mes sages. util . LocaleHelper,

org. pentaho .core. solution .ActionResource,

org. pentaho .core. solution. IActionResource,

org. pentaho .core. solution. SimpleParameterProvider, org. pentaho . ui. ChartHelper,

java. io .*"

%><%

/*

*    Copyright 2006 Pentaho Corporation. All rights reserved.

*    This software was developed by Pentaho Corporation and is provided under the terms

*    of the Mozilla Public License, Version 1.1, or any later version. You may not use

*    this file except in compliance with the license. If you need a copy of the license,

*    please go to http://www.mozilla.org/MPL/MPL-1.1.txt. The Original Code is the Pentaho

*    BI Platform. The Initial Developer is Pentaho Corporation.

*

*    Software distributed under the Mozilla Public License is distributed on an "AS IS"

*    basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to

*    the license for the specific language governing your rights and limitations.

*

*    Created Feb 16, 2006

*    @author James Dixon modified by Kurtis Cruzada

*/

/*

*    This JSP is an example of how to use Pentaho components to build a dashboard.

*    The script in this file controls the layout and content generation of the dashboard.

*    See the document 'Dashboard Builder Guide' for more details

*/

// set the character encoding e.g. UFT-8

response. setCharacterEncoding (LocaleHelper.getSystemEncoding ());

*    // create a new Pentaho session

IPentahoSession userSession = UIUtil.getPentahoSession( request );

%>

<html>

*    <head>

<title>Pentaho Sample Dashboard - JSP</title>

</he ad> <body>

<table class="Banner" cellpadding="0" width="100%">

<tbody>

<%

// See if we have a 'territory' parameter

String territory = request.getParameter("territory"); // See if we have a 'productline' parameter

String productline = request.getParameter ("productline");

// Create the title for the top of the page

String title = "Revenue Analysis";

if( productline != null ) {

title = "Sales for " + territory + ", " + productline;

}

else if ( territory != null ) {

title = "Sales for " + territory;

%>

<h1 style='font-family:Arial'></h1>

<table>

<tr>

<td width="75%"><img src="/sw-style/active/logo.png" border="0" /></a> </td>

<td align="right" style="font-family:Arial; font-weight:bold"

background="/sw-style/active/banner.png" valign="top" width="25%"></a><%= title %></td>

</tr>

<tr>

<td width="75%">

</td>

<td align="right" valign="top" width="25%"></td>

</tr>

</table>

<table style="text-align: left; width: 100%; background-color: rgb(231, 238, 248);">

<tr>

<td valign="top" align="center">

<%

// Make a pie chart showing the territories // create the parameres for the pie chart

SimpleParameterProvider parameters = new SimpleParameterProvider();

// define the click url template

parameters.setParameter( "drill-url", "SWDashboard?territory={ TERRITORY} " );

// define the slices of the pie chart

parameters. setParameter ( "inner-param", "TERRITORY"); //$NON-NLS-1$ //$NON-NLS-2$

// set the width and the height

parameters. setParameter ( "image-width", "350") ; //$NON-NLS-1$ //$NON-NLS-2$ parameters.setParameter( "image-height", "200"); //$NON-NLS-1$ //$NON-NLS-2$ StringBuffer content = new StringBuffer();

ArrayList messages = new ArrayList();

// call the chart helper to generate the pie chart image and to get the HTML

content

// use the chart definition in 'samples/dashboard/territory.widget.xml' ChartHelper.doPieChart ( "samples/steel-wheels", "dashboards", "territory.widget.xml",

parameters, content, userSession, messages, null ); %>

<%= content.toString() %>

<span style="font-family:Arial;font-size:12;font-weight:plain"> (Click

on a Territory) </span>

</td>

<td valign="top" align="center">

<%

if( territory == null ) {

// if the user has clicked on a slice of the pie chart we should have a

territory to work with

%>

<%

// Make a bar chart showing the department

// create the parameres for the bar chart

parameters = new SimpleParameterProvider();

// define the click url template

parameters. setParameter ( "drill-url",

"SWDashboard? territory="+territory+"&amp;productline={ SERIES} " );

parameters.setParameter( "TERRITORY", territory );

parameters. setParameter ( "outer-params", "TERRITORY" );

// define the category axis of the bar chart

parameters. setParameter ( "inner-param", "TERRITORY"); //$NON-NLS-1$

//$NON-NLS-2$

parameters. setParameter ( "inner-param", "PRODUCTLINE"); //$NON-NLS-1$

//$NON-NLS-2$

// set the width and the height

parameters. setParameter ( "image-width", "550") ; //$NON-NLS-1$ //$NON-NLS-2$ parameters.setParameter( "image-height", "200"); //$NON-NLS-1$ //$NON-NLS-2$ content = new StringBuffer();

messages = new ArrayList();

// call the chart helper to generate the pie chart image and to get the

HTML content

// use the chart definition in 'samples/dashboard/productline.widget.xml'

ChartHelper.doChart ( "samples/steel-wheels", "dashboards", "productline_all.widget.xml", parameters, content, userSession, messages, null );

%>

<%= content.toString() %>

<span style="font-family:Arial;font-size:12;font-weight:plain"> (Click on a Product Line) </span>

<%

}

%>

<%

if( territory != null ) {

// if the user has clicked on a slice of the pie chart we should have a

territory to work with

%>

<%

// Make a bar chart showing the department

// create the parameres for the bar chart

parameters = new SimpleParameterProvider();

// define the click url template

parameters. setParameter ( "drill-url",

"SWDashboard? territory="+territory+"&amp;productline={ SERIES} " );

parameters.setParameter( "TERRITORY", territory );

parameters. setParameter ( "outer-params", "TERRITORY" );

// define the category axis of the bar chart

parameters. setParameter ( "inner-param", "TERRITORY"); //$NON-NLS-1$

//$NON-NLS-2$

parameters. setParameter ( "inner-param", "PRODUCTLINE"); //$NON-NLS-1$

//$NON-NLS-2$

// set the width and the height

parameters. setParameter ( "image-width", "550") ; //$NON-NLS-1$ //$NON-NLS-2$ parameters.setParameter( "image-height", "200"); //$NON-NLS-1$ //$NON-NLS-2$ content = new StringBuffer();

messages = new ArrayList();

// call the chart helper to generate the pie chart image and to get the

HTML content

// use the chart definition in 'samples/dashboard/productline.widget.xml'

ChartHelper.doChart ( "samples/steel-wheels", "dashboards", "productline.widget.xml", parameters, content, userSession, messages, null );

%>

<%= content.toString() %>

<span style="font-family:Arial;font-size:12;font-weight:plain"> (Click on a Product Line) </span>

<%

}

%>

</td>

</tr>

</table>

<table style="text-align: left; width: 100%; background-color: rgb(231, 238,

248) ;">

<tr>

<td valign="top">

</td>

<td>

<%

if( productline != null ) {

// if the user has clicked on a bar of the bar chart we should have a territory and productline to work with

// create a dial and supply a value we create from the current

time

// create the parameters for the line chart parameters = new SimpleParameterProvider();parameters.setParameter( "TERRITORY", territory ); parameters. setParameter ( "outer-params", "TERRITORY" );parameters.setParameter( "PRODUCTLINE", productline ); parameters. setParameter ( "outer-params", "PRODUCTLINE" );

// define the category axis of the bar chart parameters.setParameter( "inner-param", "PRODUCTLINE");

//$NON-NLS-1$ //$NON-NLS-2$

// set the width and the height

parameters.setParameter( "image-width", "550"); //$NON-NLS-1$

//$NON-NLS-2$

parameters. setParameter ( "image-height", "200"); //$NON-NLS-1$

//$NON-NLS-2$

content = new StringBuffer();

messages = new ArrayList();

// call the chart helper to generate the pie chart image and to

get the HTML content

// use the chart definition in

'samples/dashboard/regions. widget. xml'

ChartHelper.doChart ( "samples/steel-wheels", "dashboards", "SalesOvertime.widget.xml", parameters, content, userSession, messages, null );

%>

<span style="font-family:Arial; font-weight:bold"></span>

<%= content.toString() %>

<%

}

%>

<%

if( productline == null ) {

// if the user has clicked on a bar of the bar chart we should have a territory and productline to work with

// create a dial and supply a value we create from the current

time

// create the parameters for the line chart parameters = new SimpleParameterProvider();parameters.setParameter( "TERRITORY", territory ); parameters. setParameter ( "outer-params", "TERRITORY" ); // define the category axis of the bar chart parameters.setParameter( "inner-param", "PRODUCTLINE");

//$NON-NLS-1$ //$NON-NLS-2$

//$NON-NLS-2$ //$NON-NLS-2$

get the HTML content  // set the width and the height

parameters.setParameter( "image-width", "550"); //$NON-NLS-1$

parameters. setParameter ( "image-height", "200"); //$NON-NLS-1$

content = new StringBuffer();

messages = new ArrayList();

// call the chart helper to generate the pie chart image and to

// use the chart definition in

'samples/dashboard/regions. widget. xml'

ChartHelper.doChart ( "samples/steel-wheels", "dashboards", "SalesOvertime_All.widget.xml", parameters, content, userSession, messages, null ); %>

<span style="font-family:Arial; font-weight:bold"></span> <%= content.toString() %>

}

</td>

</tr> </table>

</body> </html>

附录10 Steel Wheels Territory Chart

This page last changed on Jan 30, 2007 by wgorman.

<chart>

<!-- This file defines the pie chart that shows the actual values for each region -->

<!-- Specify the title of the chart --> <title>Territory</title>

<!-- Specify the location of the title --> <title-position>top</title-position>

<!-- Specify the font of the title --> <title-font>

<font-family>Ariel< /font-family> <size>14</size>

<is-bold>true</is-bold>

<is-italic>false</is-italic> </title-font>

<width> 350</width> <height>200</height>

<!-- Specify the 3D-ness of the bars --> <is-3D> fal s e< / is-3D>

<!-- Specify if the chart has a border and the border color --> <border-vis ible>false</border-visible>

<!-- Specify is the chart legend should be shown --> <include-legend>false</ include-legend>

<!-- Specify where the data for the chart comes from -->

<data>

<!-- Specify the path to the action sequence that provides the data --> <data-solution>samples/steel-wheels</data-solution> <data-path>dashboards</data-path>

<data-action>Sales _by _Territory. xaction</data-action>

<!-- Specify the output of the action sequence that contains the data --> <data-output>swresult</data-output>

<data-name> TERRITORY< /data-name> <data-value>SOLD_PRICE< /data-value>

<!-- Specify whether to get the pie series from the rows or columns --> <data-orientation>columns</data-orientation>

</data>

</chart>

附录11 Steel Wheels Product Line All Chart

This page last changed on Jan 30, 2007 by wgorman.

<chart>

<!-- This file defines the bar chart that shows the actual-to-budget variance for each department -->

<!-- Define the chart type --> <chart-type>BarChart</chart-type>

<!-- Specify the title of the chart --> <title>Product Line</title>

<!-- Specify the location of the title --> <title-position>TOP</title-position>

<!-- Specify the font of the title -->

<title-font>

<font-family>Ariel< /font-family>

<size>14</size>

<is-bold>true</is-bold>

<is-italic>false</is-italic>

</title-font>

<range-title></range-title>

<domain-label-rotation>1 .1</domain-label-rotation> <domain-label-rotation-dir></domain-label-rotation-dir> <domain-title>< /domain-title>

<chart-background type="color"> #FFFFFF< /chart-background> <plot-background type="color">#EEEEEE</plot-background> <!-- Specify the orientation of the bars -->

<orientation>horizontal</orientation>

<!-- Specify the 3D-ness of the bars --> <is-3D> false< / is-3D>

<!-- Specify if the bars are stacked --> <is-stacked>false</is-stacked>

<!-- Specify if the chart has a border and the border color --> <border-vis ible>false</border-visible>

<border-paint>#000000</border-paint>

<!-- Specify is the chart legend should be shown --> <include-legend>true</include-legend>

<!-- Specify the color palette for the chart -->

<color-palette>

<color>#336699</color> <color>#99CCFF</color> <color>#999933</color> <color>#666699</color> <color>#CC9933</color> <color>#006666</color> <color>#3399FF</color> <color>#993300</color> <color>#CCCC99</color> <color>#666666</color> <color>#FFCC66</color> <color>#6699CC</color><color>#663366</color>

</color-palette>

<!-- Specify where the data for the chart comes from -->

<data>

<!-- Specify the path to the action sequence that provides the data --> <data-solution>samples/steel-wheels</data-solution> <data-path>dashboards</data-path>

<data-action>Sales_by_Productline_all . xaction</data-action>

<!-- Specify the output of the action sequence that contains the data --> <data-output>swresult</data-output>

<!-- Specify whether to get the chart series from the rows or columns --> <data-orientation>rows< /data-orientation>

</data>

</chart>

附录12 Steel Wheels Product Line Widget

This page last changed on Jan 30, 2007 by wgorman.

<chart>

<!-- This file defines the bar chart that shows the actual-to-budget variance for each department -->

<!-- Define the chart type --> <chart-type>BarChart</chart-type>

<!-- Specify the title of the chart --> <title>Product Line</title>

<!-- Specify the location of the title --> <title-position>TOP</title-position>

<!-- Specify the font of the title -->

<title-font>

<font-family>Ariel< /font-family>

<size>14</size>

<is-bold>true</is-bold>

<is-italic>false</is-italic>

</title-font>

<range-title></range-title>

<domain-label-rotation>1 .1</domain-label-rotation> <domain-label-rotation-dir></domain-label-rotation-dir> <domain-title>< /domain-title>

<chart-background type="color"> #FFFFFF< /chart-background> <plot-background type="color">#EEEEEE</plot-background>

<!-- Specify the orientation of the bars --> <orientation>horizontal< /orientation>

<!-- Specify the 3D-ness of the bars --> <is-3D> false< / is-3D>

<!-- Specify if the bars are stacked --> <is-stacked>false</is-stacked>

<!-- Specify if the chart has a border and the border color --> <border-vis ible>false</border-visible>

<border-paint>#000000</border-paint>

<!-- Specify is the chart legend should be shown --> <include-legend>true</include-legend>

<!-- Specify the color palette for the chart -->

<color-palette>

<color>#336699</color> <color>#99CCFF</color> <color>#999933</color> <color>#666699</color> <color>#CC9933</color> <color>#006666</color> <color>#3399FF</color> <color>#993300</color> <color>#CCCC99</color> <color>#666666</color> <color>#FFCC66</color> <color>#6699CC</color><color>#663366</color>

</color-palette>

<!-- Specify where the data for the chart comes from -->

<data>

<!-- Specify the path to the action sequence that provides the data --> <data-solution>samples/steel-wheels</data-solution> <data-path>dashboards</data-path>

<data-action>Sales_by_Productline.xaction</data-action>

<!-- Specify the output of the action sequence that contains the data --> <data-output>swresult</data-output>

<!-- Specify whether to get the chart series from the rows or columns --> <data-orientation>rows< /data-orientation>

</data>

</chart>

附录13 Steel Wheels Sales Overtime Widget

This page last changed on Jan 30, 2007 by wgorman.

<chart>

<!-- This file defines the bar chart that shows the actual-to-budget variance for each department -->

<!-- Define the chart type --> <chart-type>LineChart</chart-type>

<!-- Specify the title of the chart --> <title>Sales Trends</title>

<!-- Specify the location of the title --> <title-position>TOP</title-position>

<!-- Specify the font of the title -->

<title-font>

<font-family>Ariel< /font-family>

<size>14</size>

<is-bold>true</is-bold>

<is-italic>false</is-italic>

</title-font>

<range-title></range-title>

<domain-label-rotation>1 .1</domain-label-rotation> <domain-label-rotation-dir></domain-label-rotation-dir> <domain-title>< /domain-title>

<chart-background type="color"> #FFFFFF< /chart-background> <plot-background type="color">#EEEEEE</plot-background>

<!-- Specify the orientation of the bars --> <orientation>vertical</orientation>

<!-- Specify the 3D-ness of the bars --> <is-3D> false< / is-3D>

<!-- Specify if the bars are stacked --> <is-stacked>false</is-stacked>

<!-- Specify if the chart has a border and the border color --> <border-visible>false</border-visible>

<border-paint>#000000</border-paint>

<!-- Specify is the chart legend should be shown --> <include-legend>false</ include-legend>

<!-- Specify the color palette for the chart -->

<color-palette>

<color>#336699</color> <color>#99CCFF</color> <color>#999933</color> <color>#666699</color> <color>#CC9933</color> <color>#006666</color> <color>#3399FF</color> <color>#993300</color> <color>#CCCC99</color> <color>#666666</color> <color>#FFCC66</color> <color>#6699CC</color><color>#663366</color>

</color-palette>

<!-- Specify where the data for the chart comes from -->

<data>

<!-- Specify the path to the action sequence that provides the data --> <data-solution>samples/steel-wheels</data-solution> <data-path>dashboards</data-path>

<data-action>sales _overtime .xaction</data-action>

<!-- Specify the output of the action sequence that contains the data --> <data-output>swresult</data-output>

<!-- Specify whether to get the chart series from the rows or columns --> <data-orientation>columns</data-orientation>

</data>

</chart>

附录14 Steel Wheels Sales Overtime All Widget

This page last changed on Jan 30, 2007 by wgorman.

<chart>

<!-- This file defines the bar chart that shows the actual-to-budget variance for each department -->

<!-- Define the chart type --> <chart-type>LineChart</chart-type>

<!-- Specify the title of the chart --> <title>Sales Trends</title>

<!-- Specify the location of the title --> <title-position>TOP</title-position>

<!-- Specify the font of the title -->

<title-font>

<font-family>Ariel< /font-family>

<size>14</size>

<is-bold>true</is-bold>

<is-italic>false</is-italic>

</title-font>

<range-title></range-title>

<domain-label-rotation>1.1</domain-label-rotation> <domain-label-rotation-dir></domain-label-rotation-dir> <domain-title>< /domain-title>

<chart-background type="color"> #FFFFFF< /chart-background> <plot-background type="color">#EEEEEE</plot-background>

<!-- Specify the orientation of the bars --> <orientation>vertical</orientation>

<!-- Specify the 3D-ness of the bars --> <is-3D> false< / is-3D>

<!-- Specify if the bars are stacked --> <is-stacked>false</is-stacked>

<!-- Specify if the chart has a border and the border color --> <border-vis ible>false</border-visible>

<border-paint>#000000</border-paint>

<!-- Specify is the chart legend should be shown --> <include-legend>false</ include-legend>

<!-- Specify the color palette for the chart -->

<color-palette>

<color>#336699</color> <color>#99CCFF</color> <color>#999933</color> <color>#666699</color> <color>#CC9933</color> <color>#006666</color> <color>#3399FF</color> <color>#993300</color> <color>#CCCC99</color> <color>#666666</color> <color>#FFCC66</color> <color>#6699CC</color><color>#663366</color>

</color-palette>

<!-- Specify where the data for the chart comes from -->

<data>

<!-- Specify the path to the action sequence that provides the data --> <data-solution>samples/steel-wheels</data-solution> <data-path>dashboards</data-path>

<data-action>sales _overtime _all .xaction</data-action>

<!-- Specify the output of the action sequence that contains the data --> <data-output>swresult</data-output>

<!-- Specify whether to get the chart series from the rows or columns --> <data-orientation>columns</data-orientation>

</data>

</chart>

附录15 Steel Wheels Sales By Territory XAction

This page last changed on Jan 30, 2007 by wgorman.

<?xml version="1 .0" encoding="UTF-8"?> <action-sequence>

<name> Sales _by _Territory.xaction</name> <title>05. SALES BY TERRITORY</title> <version> 1</version>

<logging-level>ERROR< /logging-level> <documentation>

<author>Kurtis Cruzada</author>

<description>List of Territories sorted by Sales. Select date range (Jan 2003 through May

2005). Includes chart.</description> <icon>slsbyter.png</icon>

<help/>

</documentation>

<inputs/>

<outputs>

<!-- an output stream will be provided by default --> <swresult>

<type>list</type>

</swresult>

</outputs>

<resources>

<!-- use this section to identify any files that the component needs to execute the report

- ->

</resources>

<actions>

<action-definition>

<component -name> SQLLookupRule< /component-name>

<action-type>SQL Query</action-type>

<action-inputs>

<territory_name type="string"/>

<product line_name type="string" />

</action-inputs> <action-outputs>

<query-result type="result-set" mapping="swresult"/>

</action-outputs> <component-definition>

<jndi>SampleData</jndi>

<query><![ CDATA[ SELECT OFFICES.TERRITORY,

SUM (ORDERDETAILS .QUANTITYORDERED*ORDERDETAILS . PRICEEACH) SOLD _PRICE FROM ORDERS INNER JOIN ORDERDETAILS ON ORDERS.ORDERNUMBER = ORDERDETAILS.ORDERNUMBER INNER JOIN PRODUCTS ON ORDERDETAILS.PRODUCTCODE =PRODUCTS.PRODUCTCODE INNER JOIN CUSTOMERS ON ORDERS.CUSTOMERNUMBER =CUSTOMERS. CUSTOMERNUMBER INNER JOIN EMPLOYEES ON CUSTOMERS. SALESREPEMPLOYEENUMBER = EMPLOYEES.EMPLOYEENUMBER INNER JOIN OFFICES ON EMPLOYEES.OFFICECODE=OFFICES.OFFICECODE GROUP

BY OFFICES.TERRITORY ORDER BY 2 DESC]]></query>

</component-definition>

</action-definition>

</actions> </action-sequence>

附录16 Steel Wheels Sales by Productline All XAction

This page last changed on Jan 30, 2007 by wgorman.

<?xml version="1 .0" encoding="UTF-8"?> <action-sequence>

<name> Sales _by _Productline.xaction</name> <title>06. SALES BY PRODUCTLINE</title> <version> 1</version>

<logging-level>ERROR< /logging-level> <documentation>

<author>Kurtis Cruzada</author>

<description>List of Product Lines sorted by Sales. Select date range (Jan 2003 through May

2005). Includes chart.</description> <icon>slsprdln.png</icon>

<help/>

</documentation>

<inputs/>

<outputs>

<!-- an output stream will be provided by default --> <swresult type="result-set"/>

</outputs>

<resources>

<!-- use this section to identify any files that the component needs to execute the report

- ->

</resources>

<actions>

<action-definition>

<component -name> SQLLookupRule< /component-name> <action-type>SQL Query</action-type>

<action-inputs/>

<action-outputs>

<query-result type="result-set" mapping="swresult"/> </action-outputs>

<component-definition>

<jndi>SampleData</jndi>

<query><![ CDATA[ SELECT PRODUCTS. PRODUCTLINE,

SUM (ORDERDETAILS .QUANTITYORDERED*ORDERDETAILS . PRICEEACH) REVENUE FROM ORDERS INNER JOIN ORDERDETAILS ON ORDERS.ORDERNUMBER = ORDERDETAILS.ORDERNUMBER INNER JOIN PRODUCTS ON ORDERDETAILS.PRODUCTCODE =PRODUCTS.PRODUCTCODE INNER JOIN CUSTOMERS ON ORDERS.CUSTOMERNUMBER =CUSTOMERS. CUSTOMERNUMBER INNER JOIN EMPLOYEES ON CUSTOMERS. SALESREPEMPLOYEENUMBER = EMPLOYEES.EMPLOYEENUMBER INNER JOIN OFFICES ON EMPLOYEES.OFFICECODE=OFFICES.OFFICECODE GROUP BY PRODUCTS.PRODUCTLINE ORDER BY 2 DESC]]></query>

</component-definition>

</action-definition>

</actions> </action-sequence>

附录17 Steel Wheels Sales by Productline XAction

This page last changed on Jan 30, 2007 by wgorman.

<?xml version="1 .0" encoding="UTF-8"?> <action-sequence>

<name> Sales _by _Productline .xaction</name> <title>06. SALES BY PRODUCTLINE</title> <version> 1</version>

<logging-level>ERROR< /logging-level> <documentation>

<author>Kurtis Cruzada</author>

<description>List of Product Lines sorted by Sales. Select date range (Jan 2003 through May

2005). Includes chart.</description> <icon>slsprdln.png</icon>

<help/>

</documentation>

<inputs>

<TERRITORY type="string">

<sources>

<request>TERRITORY< /request>

</sources> <default-value>NULL</default-value>

</TERRITORY> </inputs>

<outputs>

<!-- an output stream will be provided by default --> <swresult type="result-set"/>

</outputs>

<resources>

<!-- use this section to identify any files that the component needs to execute the report

- ->

</resources>

<actions>

<actions>

<condition><![ CDATA[ TERRITORY == "NULL"]] ></condition>

<action-definition>

<component-name> SQLLookupRule< / component-name>

<action-type>SQL Query</action-type>

<action-inputs /> <action-outputs>

<query-result type="result-set" mapping="swresult"/>

</action-outputs> <component-definition>

<jndi> SampleData< /jndi>

<query><![ CDATA[ SELECT PRODUCTS.PRODUCTLINE,

SUM (ORDERDETAILS .QUANTITYORDERED*ORDERDETAILS . PRICEEACH) REVENUE FROM ORDERS INNER JOIN ORDERDETAILS ON ORDERS.ORDERNUMBER = ORDERDETAILS.ORDERNUMBER INNER JOIN PRODUCTS ON ORDERDETAILS.PRODUCTCODE =PRODUCTS.PRODUCTCODE INNER JOIN CUSTOMERS ON ORDERS.CUSTOMERNUMBER =CUSTOMERS. CUSTOMERNUMBER INNER JOIN EMPLOYEES ON CUSTOMERS. SALESREPEMPLOYEENUMBER = EMPLOYEES.EMPLOYEENUMBER INNER JOIN OFFICES ON EMPLOYEES.OFFICECODE=OFFICES.OFFICECODE GROUP BY PRODUCTS.PRODUCTLINE ORDER BY 2 DESC]]></query>

</component-definition>

</action-definition>

</actions>

<action-definition>

<component -name> SQLLookupRule< /component-name> <action-type>SQL Query</action-type>

<action-inputs>

<TERRITORY type="string"/>

</action-inputs>

<action-outputs>

<query-result type="result-set" mapping="swresult"/> </action-outputs>

<component-definition>

<jndi>SampleData</jndi>

<query><![ CDATA[ SELECT PRODUCTS. PRODUCTLINE,

SUM (ORDERDETAILS .QUANTITYORDERED*ORDERDETAILS . PRICEEACH) REVENUE FROM ORDERS INNER JOIN

ORDERDETAILS ON ORDERS.ORDERNUMBER = ORDERDETAILS.ORDERNUMBER INNER JOIN PRODUCTS ON ORDERDETAILS.PRODUCTCODE =PRODUCTS.PRODUCTCODE INNER JOIN CUSTOMERS ON ORDERS.CUSTOMERNUMBER =CUSTOMERS. CUSTOMERNUMBER INNER JOIN EMPLOYEES ON CUSTOMERS. SALESREPEMPLOYEENUMBER = EMPLOYEES.EMPLOYEENUMBER INNER JOIN OFFICES ON EMPLOYEES.OFFICECODE=OFFICES.OFFICECODE WHERE TERRITORY={ PREPARE:TERRITORY} GROUP BY PRODUCTS.PRODUCTLINE ORDER BY 2 DESC] ] ></query>

</component-definition>

</action-definition>

</actions> </action-sequence>

附录18 Steel Wheels Sales Overtime XAction

This page last changed on Jan 30, 2007 by wgorman.

<?xml version="1 .0" encoding="UTF-8"?> <action-sequence>

<title/>

<version> 1</version>

<logging-level>ERROR< /logging-level> <documentation>

<author/>

<description>Empty blank action sequence document</description>

<help/>

<icon/>

</documentation>

<inputs>

<TERRITORY type="string">

<sources>

<request>TERRITORY< /request>

</sources> <default-value>NA</default-value>

</TERRITORY>

<PRODUCTLINE type="string">

<sources> <request>PRODUCTLINE</request>

</sources> <default-value>NULL</default-value>

</PRODUCTLINE> </inputs>

<outputs>

<swresult type="result-set"/> </outputs>

<resources/>

<actions>

<actions>

<condition><![ CDATA[ PRODUCTLINE != "NULL"]] ></condition> <action-definition>

<component-name> SQLLookupRule< / component-name> <action-type>SQL Query</action-type>

<action-inputs>

<territory type="string"/>

<productline type="string"/>

<PRODUCTLINE type="string"/>

<TERRITORY type="string"/>

</action-inputs>

<action-outputs>

<query-result type="result-set" mapping="swresult"/> </action-outputs>

<component-definition>

<jndi> SampleData< /jndi>

<query><![ CDATA[ SELECT CONCAT(CONCAT( YEAR(ORDERS.ORDERDATE),'-'

),MONTH (ORDERS.ORDERDATE)) AS TIME, SUM(ORDERDETAILS.QUANTITYORDERED*ORDERDETAILS.PRICEEACH)

SOLD _PRICE

FROM ORDERS

INNER JOIN ORDERDETAILS ON ORDERS.ORDERNUMBER = ORDERDETAILS.ORDERNUMBER INNER JOIN PRODUCTS ON ORDERDETAILS.PRODUCTCODE =PRODUCTS.PRODUCTCODE INNER JOIN CUSTOMERS ON ORDERS. CUSTOMERNUMBER =CUSTOMERS . CUSTOMERNUMBER

INNER JOIN EMPLOYEES ON CUSTOMERS.SALESREPEMPLOYEENUMBER = EMPLOYEES.EMPLOYEENUMBER

INNER JOIN OFFICES ON EMPLOYEES.OFFICECODE=OFFICES.OFFICECODE

WHERE PRODUCTS. PRODUCTLINE={ PREPARE: PRODUCTLINE} AND OFFICES. TERRITORY={ PREPARE: TERRITORY}

GROUP BY

CONCAT ( MONTH (ORDERS.ORDERDATE), YEAR(ORDERS.ORDERDATE) )] ] ></query> </component-definition>

</ act i on-de finition>

</actions> <actions>

<condition><![ CDATA[ PRODUCTLINE == "NULL"]] ></condition> <action-definition>

<component-name> SQLLookupRule< / component-name> <action-type>SQL Query</action-type>

<action-inputs>

<TERRITORY type="string"/>

</action-inputs>

<action-outputs>

<query-result type="result-set" mapping="swresult"/> </action-outputs>

<component-definition>

<j ndi> SampleData< /j ndi>

<query><![ CDATA[ SELECT CONCAT(CONCAT( YEAR(ORDERS.ORDERDATE),'-'

),MONTH (ORDERS.ORDERDATE)) AS TIME, SUM(ORDERDETAILS.QUANTITYORDERED*ORDERDETAILS.PRICEEACH)

SOLD _PRICE

FROM ORDERS

INNER JOIN ORDERDETAILS ON ORDERS.ORDERNUMBER = ORDERDETAILS.ORDERNUMBER INNER JOIN PRODUCTS ON ORDERDETAILS.PRODUCTCODE =PRODUCTS.PRODUCTCODE INNER JOIN CUSTOMERS ON ORDERS. CUSTOMERNUMBER =CUSTOMERS . CUSTOMERNUMBER

INNER JOIN EMPLOYEES ON CUSTOMERS.SALESREPEMPLOYEENUMBER = EMPLOYEES.EMPLOYEENUMBER

INNER JOIN OFFICES ON EMPLOYEES.OFFICECODE=OFFICES.OFFICECODE

WHERE OFFICE.TERRITORY='{ TERRITORY}'

GROUP BY

CONCAT ( MONTH (ORDERS.ORDERDATE), YEAR(ORDERS.ORDERDATE) )] ] ></query> </component-definition>

</action-definition>

</actions>

</actions> </action-sequence>

附录19 Sales Overtime All XAction

This page last changed on Jan 30, 2007 by wgorman.

<?xml version="1 .0" encoding="UTF-8"?> <action-sequence>

<title/>

<version> 1</version>

<logging-level>ERROR< /logging-level> <documentation>

<author/>

<description>Empty blank action sequence document</description>

<help/>

<icon/>

</documentation>

<inputs>

<TERRITORY type="string">

<sources>

<request>TERRITORY< /request>

</sources> <default-value>NULL</default-value>

</TERRITORY> </inputs>

<outputs>

<swresult type="result-set"/> </outputs>

<resources/>

<actions>

<actions>

<condition><![ CDATA[ TERRITORY == "NULL"]] ></condition>

<action-definition>

<component-name> SQLLookupRule< / component-name>

<action-type>SQL Query no territory</action-type>

<action-inputs/> <action-outputs>

<query-result type="result-set" mapping="swresult"/>

</action-outputs> <component-definition>

<j ndi> SampleData< /j ndi>

<query><![ CDATA[ SELECT CONCAT(CONCAT( YEAR(ORDERS.ORDERDATE),'-'

),MONTH (ORDERS.ORDERDATE)) AS TIME, SUM(ORDERDETAILS.QUANTITYORDERED*ORDERDETAILS.PRICEEACH)

SOLD _PRICE

FROM ORDERS

INNER JOIN ORDERDETAILS ON ORDERS.ORDERNUMBER = ORDERDETAILS.ORDERNUMBER

INNER JOIN PRODUCTS ON ORDERDETAILS.PRODUCTCODE =PRODUCTS.PRODUCTCODE

INNER JOIN CUSTOMERS ON ORDERS. CUSTOMERNUMBER =CUSTOMERS . CUSTOMERNUMBER

INNER JOIN EMPLOYEES ON CUSTOMERS.SALESREPEMPLOYEENUMBER = EMPLOYEES.EMPLOYEENUMBER

INNER JOIN OFFICES ON EMPLOYEES.OFFICECODE=OFFICES.OFFICECODE

GROUP BY

CONCAT ( MONTH (ORDERS.ORDERDATE), YEAR(ORDERS.ORDERDATE) )] ] ></query> </component-definition>

</ action-definition>

</actions>

<actions>

<condition><![ CDATA[ TERRITORY !== "NULL"] ] ></condition>

<action-definition>

<component-name> SQLLookupRule< / component-name>

<action-type>SQL Query with Territory</action-type>

<action-inputs>

<territory type="string"/> <productline type="string"/> <TERRITORY type="string"/>

</action-inputs>

<action-outputs>

<query-result type="result-set" mapping="swresult"/>

</action-outputs>

<component-definition>

<jndi> SampleData< /jndi>

<query><![ CDATA[ SELECT CONCAT(CONCAT( YEAR(ORDERS.ORDERDATE),'-'

),MONTH (ORDERS.ORDERDATE)) AS TIME, SUM(ORDERDETAILS.QUANTITYORDERED*ORDERDETAILS.PRICEEACH) SOLD _PRICE

FROM ORDERS

INNER JOIN ORDERDETAILS ON ORDERS.ORDERNUMBER = ORDERDETAILS.ORDERNUMBER

INNER JOIN PRODUCTS ON ORDERDETAILS.PRODUCTCODE =PRODUCTS.PRODUCTCODE

INNER JOIN CUSTOMERS ON ORDERS. CUSTOMERNUMBER =CUSTOMERS . CUSTOMERNUMBER

INNER JOIN EMPLOYEES ON CUSTOMERS.SALESREPEMPLOYEENUMBER = EMPLOYEES.EMPLOYEENUMBER INNER JOIN OFFICES ON EMPLOYEES.OFFICECODE=OFFICES.OFFICECODE

WHERE OFFICES. TERRITORY={ PREPARE: TERRITORY}

GROUP BY

CONCAT ( MONTH (ORDERS.ORDERDATE), YEAR(ORDERS.ORDERDATE) )] ] ></query> </component-definition>

</action-definition>

</actions>

</actions> </action-sequence>

使用 Filter Panel 开发 Portal Dashboard 

This page last changed on Feb 28, 2007 by sbarkdull.

动机

在 portal 中,digital dashboard是用户接口组件的一个集合(又名 portlets),其提供了相关商业数据的一个视图。digital dashboard 是很有用的一种机制,其可快速的在一个页面上展现一套 critical商业数据。开发人员可使用 Pentaho BI 平台以及 JSR168 portal 来实现 digital dashboard。此处我配置 Pentaho BI 平台运行于 JBoss Portal 服务器,使用一个 FilterPanelPortlet,一个ActionPortlet 和一些 Action Sequences 来在一个 portal 页面上实现一个 dashboard。

一个简单的 Portal

简单的说,portal 就是一个 portal 包含的一组相关 portal 页面。一个 portal 页面包含一套(1 或多个)窗口。每个窗口包含一个 portlet,每个 portlet 有服务端逻辑和客户端用户接口控制/显示。

Dashboard

在 Pentaho BI 平台中,可使用一个 filter panel 和一个或多个包含内嵌于相同的 portal 页面的可视化显示的portlets 来创建一个基于 portal 的 dashboard。可视化的显示通常指图表和报表。

Filter Panel

一个 filter panel 包含和一个 HTML form 相关的客户端 UI 控件,以及一个服务器端的 FilterPanelPortlet,其实 JSR168 GenericPortlet 的一个实现。当 form 提交给 Portal 服务器时,FilterPanelPortlet 将 form 中的数据放进 session scoped 参数中,然后这些参数就可以作为页面中其他 Portlets/Actions Sequences 的输入。

当页面中其他 Pentaho-based portlets 被要求重画自身时,它们可基于 filter panel 放进 session 中的参数值来重画自身。

用实现了 Dashboard 的页面配置 Portal

在 portal 中,配置 dashboard 有几个必需的步骤:

1.       修改 portlet.xml 文件在 dashboard 中定义 portlets。

2.       修改 portlet-instances.xml 文件定义 portlet 实例。

3.       修改 pentaho-portal-object.xml 文件将 portlet 实例放进 portal 中的一个页面。

4.     为 portlet 添加 localized Strings,在 portlet.properties 文件中添加 portal 页面标题。

5.       在 repository 中,创建一个 filter panel 定义文件。

6.       创建 Action Sequences 为 filter panel 的控件提供 list-of-values (LOV) 数据。

7.       创建和页面中的其他 portlets 相关的 Action Sequences。这些 Action Sequences 响应 filter panel 放进 session 中的参数的改变,并提供商业数据的视图。

8.       创建一个 JNDI 可访问的 datasource,为 Action Sequences 提供数据。

一个简单的 Portal Dashboard 实例

在这个实例中,配置 portal 显示一个 dashboard,通过:

1.       在 portal 添加两个 portlets。

2.       在 portal 上添加这些 portlets 中每个的实例。

3.       在 portal 中添加一个新的页面

4.       在页面中添加 2 个新的窗口。

5.       在两个窗口中添加 2 个portlets。

修改 portal 配置文件

在 Pentaho Pre-Configured Install (PCI) 中,portal 配置文件位于/server/default/deploy/pentaho.war/WEB-INF。其名字是 portlet .xml,portlet-instances .xml 和pentaho-portal-object .xml。

Ø         portlet.xml: 包含 portlet 定义。

Ø         portlet-instances.xml: 包含 portlet-instance 定义。

Ø         pentaho-portal-object.xml: 包含 page 和 window 定义。

JBoss Portal 服务器特定配置文件

portlet.xml 文件的名字和格式在 JSR168 规范中确定,对所有 JSR168 portals 都是一样的。portlet-instances.xml  pentaho-portal-object.xml 文件的名字和格式是特定于 JBoss Portal 服务器的。

修改 portlet.xml 文件定义 dashboard 中的 portlets

这个 XML fragment 描述了 FilterPanelPortlet 类实现的一个 portlet,其 UI 由simple-dashboard.filterpanel.xml filter panel 描述文件指定。

TODO more detail

portlet 定义文件的更多信息请参考 JBoss Portal server documentation 或 JSR168 spec

<portlet-app>

...

<portlet>

<portlet-name>SimpleFilterPanelPortlet</portlet-name>

<portlet-clas s>

org. pentaho . ui . portlet . FilterPanelPortlet

</portlet-class> <supports>

<mime-type>text/html</mime-type>

<portlet-mode>VIEW</portlet-mode>

</ supports>

<!-- package name containing the portlet.properties file, this file contains localized strings -->

<resource-bundle>

org .pentaho . locale .portlet

</resource-bundle> <portlet-info>

<!-- key into portlet.properties file containing the localized title of the portlet

displayed in the UI -->

<title>SimpleFilterPanelPortlet</title>

</portlet-info> <portlet-preferences>

<!-- filter panel description file -->

<preference> <name>filters</name>

<value>samples/simpleDashboard/simple-dashboard. filterpanel .xml</value>

</preference> </portlet-preferences>

</portlet>

...

</portlet-app>

这个 XML fragment 描述了 ActionPortlet 类实现的一个 portlet,其可视化显示由 JFree_ChartComponent.xaction Action Sequence 创建。

<portlet-app>

...

<portlet>

<portlet-name>SimplePieChartPortlet</portlet-name>

<portlet-clas s>

org. pentaho . ui . portlet . ActionPortlet

</portlet-class> <supports>

<mime-type>text/html</mime-type>

<portlet-mode>VIEW</portlet-mode>

</ supports>

<resource-bundle>

org .pentaho . locale .portlet

</resource-bundle> <portlet-info> <title>SimplePieChartPortlet</title>

</portlet-info> <portlet-preferences>

<preference> <name>action</name>

<value>samples/simpleDashboard/JFree_ChartComponent .xaction</value>

</preference> </portlet-preferences>

</portlet>

...

</portlet-app>

修改 portlet-instances.xml 文件定义 portlet 实例

portlet-instances.xml 文件描述了 portlet 名字(在 portlet.xml)文件和一个 portlet 实例名间的映射。在 portal 中,你可有一个 portlet 的多个实例,每个实例有自己的首选项。这个实例仅仅从 portlet 定义 '1inherits'1 它的首选项。实例名用于 add portlet instances to portal pages

portlet 实例定义文件的更多信息请参考 JBoss Portal 服务器文档。

<deployments>

...

<deployment> <if-exists>overwrite</if-exists>

<instance>

<instance-id>SimpleFilterPanelPortletInstance< /instance-id> <portlet-ref>SimpleFilterPanelPortlet< /portlet-ref>

</instance> </deployment> <deployment>

<if-exists>overwrite</if-exists>

<instance> <instance-id>SimplePieChartPortletInstance</instance-id> <portlet-ref>SimplePieChartPortlet</portlet-ref>

</instance> </deployment> ...

</deployments>

修改 pentaho-portal-object.xml 文件 to place portlet instances in a page in portal.

在 portal 上添加一个新的页面,通过在 <deployements> 根元素上添加一个 <deployment> 元素,然后在<deployment> 元素中添加 <page> 元素。

为每个 portlet 添加一个窗口,通过在 <page> 元素上添加相应的 <window> 元素。为每个窗口添加一个 portlet,通过在 <window> 元素上添加 <instance-ref> 元素,指定 portlet 实例的名字(如portlet-instances.xml 文件所定义)作为元素的文本。(TODO 中详细介绍了元素)

portal 实例定义文件的更多信息请参考每行的注释,以及 JBoss Portal server documentation

<deployments>

...

<deployment>

<parent-ref>pentaho</parent-ref>

<if-exists>overwrite</if-exists>

<page>

<page-name>Simple Dashboard</page-name>

<properties> <property>

<name>order< /name>

<value> 90</value>

</property>

<!-- references a localized string in the portlet.properties file -->

<property>

<name>res ourceKey< /name>

<!-- the name of the key in the properties file --> <value>SimpleDashboard</value>

</property> </properties> <window>

<window-name>PentahoPortalNavigationWindow< /window-name>

<instance-ref>

PentahoPortalNavigationInstance

</instance-ref>

<region>navigation< /region>

<height> 0</height>

<!-- keep portal and page properties for this window -->

<properties>

<!-- use the window renderer from the emptyRenderer renderSet -->

<property>

<name> theme. windowRendererId< /name>

<value>emptyRenderer< /value> </property>

<!-- use the decoration renderer from the emptyRenderer renderSet -->

<property>

<name> theme. decorationRendererId</name>

<value>emptyRenderer< /value> </property>

<!-- use the portlet renderer from the emptyRenderer renderSet -->

<property>

<name> theme .portletRendererId</name>

<value>emptyRenderer< /value> </property>

</properties>

</window>

<!-- Specification of window containing the filter panel portlet -->

<window>

<window-name> SimpleFilterPanelPortletWindow< /window-name> <instance-ref>SimpleFilterPanelPortletInstance< /instance-ref>

<region> left</region>

<height> 0</height>

</window>

<!-- Specification of a window containing the ViewAction/pie chart portlet -->

<window>

<window-name> SimplePieChartPort letWindow< /window-name> <instance-ref>SimplePieChartPortletInstance</instance-ref>

<region> left</region>

<height> 1</height>

</window>

<!-- insert Secure security-constraints --> <security-constraint>

<policy-permiss ion>

<role-name>User< /role-name> <action-name>view</action-name> </policy-permis sion>

</security-constraint>

</page>

</deployment>

...

</deployments>

portlet.properties 文件中,为 Portlet  Portal Page Titles,添加 Localized Strings 

之前的 XML 片段中的注释标识了文本串,其是引用了本地化属性文件(又名 resource bundles)中的文本串的键值。portlet.xml 文件标识了包含这些属性文件的包(org.pentaho.locale.portlet)。你可能需要在适当的本地化文件中,为你的键值添加 key/text-string 映射。

...

SimpleDashboard=SimPAL DashBORED

...

SimpleFilterPanelPortlet.javax.portlet. title=Simple Filter Panel Portlet SimplePieChartPortlet.javax.portlet .title=Simple Pie Chart Portlet

...

 

 Repository 中创建一个 Filter Panel 定义文件

在这个实例中,在 samples/simpleDashboard/simple-dashboard. filterpanel.xml 中指定 filter panel。

<filters><name>CustomerNamesFilter</name>

<filter>

<!-- Title text displayed in the filter panel --> <title>Customer</title>

<!-- name and id of the HTML form control representing this filter --> <name>customernumber< /name>

<!-- type of control to display in the filter panel --> <type>list</type>

<data-solution>samples</data-solution> <data-path>simpleDashboard</data-path> <data-action>getCustomerNames .xaction</data-action>

<!-- name of the action sequence's output parameter containing the LOV --> <data-output>customerNamesList</data-output> <!-- maps to the <option> element's text --> <data-display>customername</data-display> <!-- maps to the <option> element's value attribute in the HTML form --><data-value>customernumber</data-value>

</ filter>

</filters>

每个 filter panel 定义文件定义了一个 filter panel 的 filters。每个 filter 对应于用户接口上的一个控件(UI) (例如 comboboxes,lists,radio buttons等) 这些控件用于 "filter" 平台返回的数据。

创建一个 filter 定义,通过在 filter panel 定义文件的根节点(如 <filters>)上添加一个 <filter> 元素,然后在 <filter> 元素上添加适当的子元素。在 filter panel 上可指定 4 种不同的 filter 类型。每种类型使用一个不同的机制,用于获取它的 LOV。通过在  <filter> 元素上添加一个或多个不同的子元素来指定获取 LOV 的机制。

除了 <filter> 元素的一套不同子元素,还有一套所有 <filter> 元素共同拥有的元素。

List of Values (LOV)

A List of Values (LOV) 是描述 items 的列表的一个术语,每个 item 有一个名字和一个值。一个实例可能跨越了一年中的数月,第一个 item 的名字是 Jan,其值是 0,第二个 item 的名字是 Feb,其值是 等等。

在一个用户接口中,当一个用户需要从很多 items 中选择一个时,为用户显示 LOV 中的每个 item 的名字, 当用户作出一个选择时,将选中的 item 的值传送到服务器。

 

公有元素

(* 必需元素)

Ø         <title> title 元素的文本,其在 HTML form 中显示为 filter 的 label。

Ø         <name> * 用于设置表单中的 HTML 控件的 name 和 id 属性。例如,如果这个 filter 是用于生成一个列表(在 HTML 中也叫做 <select> 元素),<select> 元素的 id 和 name 属性将被设置成 <name> 元素的文本。

Ø         <type> 在 filter panel 中放置的 HTML 控件的类型。如果没有这个元素,或其值不能识别,生成一个 <select> 控件(又叫做复选框)。被识别的值有:

o      radio: 创建一套 radio buttons

o      list: 创建一个列表框

o      list-multi: 创建一个具有多个选择的选择列表

o      check-multi: 创建一套复选框,所有可见

o      check-multi-scroll: 在一个可滚动的面板里创建一套检查框

o      check-multi-scroll-2-column: 在一个可滚动的面板里创建 2 列检查框

o         check-multi-scroll-3-column: 在一个可滚动的面板里创建 3 列检查框

o         check-multi-scroll-4-column: 在一个可滚动的面板里创建 4 列检查框

Ø         <data-display> * LOV 中的列名,其用于提供 UI 显示文本。例如如果 filter panel 的类型是 list,这列的值用于提供列表框中的文本。

Ø         <data-value> * LOV 中的列名,其用于提供和 UI 显示文本相关的值。这些是当表单提交到服务器时,要发送的值。

Elements Unique to Each Filter Type

filter panel 中的每个 filter 可从以下 种源获取它的 list-of-values (LOV)

1.       session scoped 参数

2.       全局参数

3.       action sequence 输出

4.       <filter> 元素的 body 中定义的 static list

Session Scoped 参数

为配置 filter panel,从一个 session scoped 参数中获取它的 LOV,添加 <session-attribute> 作为 <filter> 元素的 child。元素的文本是一个 session scoped 参数的名字,其包含LOV。这个参数必须是以下类型之一:list,result-set(TODO 其他是什么?)。

Global Scoped 参数

为配置 filter panel,从全局参数中获取它的 LOV,添加 <global-attribute> 作为 <filter> 元素的 child。元素的文本是包含 LOV 的全局参数的名字。这个参数必须是以下类型之一:list,result-set(TODO 其他是什么?)。

Action Sequence 输出

为配置 filter panel,从一个 Action Sequence 中获取它的 LOV,添加元素 <data-solution>,<data-path>,<data-action> 和 <data-output> 作为 <filter> 元素的 children。每个元素的文本应该是:

Ø         <data-solution>: solution-repository 中的 solution 的名字,其包含 Action Sequence 定义文件。 例如,在 PCI solution-repository 的目录中叫做 pentaho-solutions。solution 自身包含在solution-repository 目录中。例如,PCI 自带的 solutions 叫:samples,admin 和 test solutions。

Ø         <data-path>: 从 solution 到 Action Sequence 定义文件的路径。

Ø         <data-action>: Action Sequence 定义文件的名字。

Ø         <data-output>: 如果这个元素存在,它的文本应该是 Action Sequence 将 LOV 放置其中的Action Sequence 输出参数的名字。如果这个元素不存在,filter panel 将在名为 resultset的Action Sequence 的输出参数中寻找 LOV。

Static List

配置 filter panel,从 filter panel 定义文件中的 static list 获取它的 LOV。

Static LOV 还不可用

用一个 static list 初始化一个 LOV 将在下一个版本中可用。

 

创建 Action Sequences  Filter Panel's Controls 提供list-of-values (LOV) 数据

在这个实例中,在 samples/simpleDashboard/getCustomerNames.xaction 中创建了 action sequence。这个 Action Sequence 包含一个单独的 Action,其运行一个 SQL 查询,获取客户名和至少发了一个订单的客户的数量。注意列名 (customername, customernumber) 映射到 filter panel 定义文件中的 <data-display> 和 <data-value> 元素。也注意到 action sequence中的 Result Set Name (customerNamesList) 映射到 <data-output> 元素。Result Set 的值显示在 filter panel's form 的 list 控件中。

创建和页面中的其他 Portlets 相关的 Action Sequences

在这个简单的实例中,在页面中仅有一个 portlet,SimplePieChartPortlet portlet (使用类 ActionPortlet 实现)。

你想起 SimplePieChartPortlet 的优先选择,指定应该运行samples/simpleDashboard/JFree_ChartComponent.xaction Action Sequence。这个 Action Sequence 响应 filter panel 所放置的session 参数的改变,提供了商业数据的视图。

这个 Action Sequence 包含:

1.       一个 Relational action,其获取要在 pie chart 上显示的数据。

2.       一个 Pie Chart action,其使用数据在服务器上创建一个 pie chart image。

3.       一个 Message Template,其创建一个 HTML fragment 将 pie chart image 放进 portlet 中。

Relational action 在 SimpleData 数据库上运行一个查询,确定一个特定顾客最优先购买的 5 种产品。在这个实例中,我正使用一个 pie chart。通常,对于一个 pie chart,你需要 2 列数据。第一列确定 pie slice 的 label,第二列确定 pie slice 的相对数量。行数确定了 slices 的数量。

在这个实例中,第一列包含购买的产品,第二列包含购买的产品的数量。

注意查询中的 customernumber 来自 session scoped 输入 customernumber。这个值由 filter panel 放进了session 中。

Pie Chart action 在服务器上生成一个.png 文件,其包含 pie chart image。注意 chart-filename 和 base-url 输出。这些输出由 Pie Chart action 自动创建。chart-filename 中有包含 pie chart image 的文件的名字。base-url 包含 pie chart image 文件的 portal 相关的 URL。Message Template action 继续执行,创建引用服务器上的 chart image 的 HTML <img> tag。

Pie Chart 的默认行为在 Portlet 中不生效

Pie Chart action 的缺省行为就是生成一个包含 chart image 的完整 HTML 页面。这对一个 JSP  Servlet 是适当的。然而,portlet 中的 HTML 包含一个 HTML fragment,而不是完整的 HTML 页面。

可以修改默认行为,通过为 Pie Chart action 指定输出。幸运的,Pie Chart action 提供了 chart-filename base-url 输出。通过为 Pie Chart action 指定这些输出,它们将对 Action Sequence 中剩下的 actions 可用。

Message Template action 创建一个 HTML <img> 元素,其引用服务器上的 chart's image 文件。Message Template 能构造一个具有有效 src 属性的 HTML <img> 元素,通过合并 Pie Chartaction 的 base-url 和 chart-filename 输入以引用服务器上生成的图像文件。这个 action 的输出(imgtag) 是一个 HTML fragment,其被添加到 Action Sequence 的输出。

Action Sequence 的输出(例如 HTML fragment) 由 ActionPortlet 捕获。ActionPortlet 将这个 HTML fragment 传送到 Portal,以和页面上其他 portlets 生成的 HTML fragments 进行聚合。然后聚合后的 HTML 内容被发送回浏览器,以显示 portal dashboard。

为了方便,我已经包含了 JFree_ChartComponent Action Sequence 的 XML。

<?xml version="1 .0" encoding="UTF-8"?> <action-sequence>

<name>JFree_ChartComponent . xaction</name> <title>Simple Chart</title>

<version> 1</version>

<logging-level>DEBUG< /logging-level> <documentation>

<author>Steven Barkdull</author>

<description>Creates a chart image based on a SQL query</description>

<icon/>

<help>You R going to need it.</help> <result-type>rule</result-type> </documentation>

<inputs>

<chart-type type="string">

<default-value>.png</default-value> <sources>

<request>type</request>

</sources>

</chart-type>

<customernumber type="string">

<sources>

<session>customernumber</session> </sources>

<default-value><![ CDATA[ 141]] ></default-value>

</customernumber>

</inputs>

<outputs>

<imgtag type="string">

<destinations>

<response>content</response> </destinations>

</ imgtag>

</outputs>

<resources/>

<actions>

<action-definition>

<component -name> SQLLookupRule< /component-name>

<action-type>Query For Chart Data</action-type>

<action-inputs>

<customernumber type="string"/>

</action-inputs> <action-outputs>

<query-result type="result-set" mapping="chartData"/>

</action-outputs> <component-definition>

<source> sql</source>

<live>true< /live> <jndi>SampleData</j ndi>

<query><![ CDATA[

select top 5 products.productname, count( orderfact.productcode) as Amount

from orderfact inner join products on orderfact.productcode = products.productcode and orderfact.customernumber = { PREPARE:customernumber}

group by orderfact.productcode, products.productname] ] ></query> </component-definition>

</action-definition>

<action-definition>

<component -name>ChartComponent< /component -name> <action-type>Create The Chart</action-type>

<action-inputs>

<output-type type=" string" mapping="chart-type" /> <chart-data type="result-set" mapping=" chartData" /></action-inputs>

<action-outputs>

<chart-filename type="string"/>

<base-url type="string"/>

</action-outputs>

<component-definition>

<by-row> false</by-row>

<height> 400</height>

<width> 600</width>

<title>Top 5 Models Sold by Customer</title>

<chart-attributes>

<!-- this is the background for the whole image --> <!-- TODO support gradient and texture painting --> <chart-type>PieChart< /chart-type>

<title-position>TOP</title-position>

<height/>

<width/>

<title/>

<title-font>

<font-family>Serif</font-family>

<size>36</size>

<is-bold>false</is-bold>

<is-italic>false</is-italic>

</title-font>

<range-title>US Dollars</range-title>

<chart-background type="color">#FFFFFF</chart-background> <plot-background-color>#FF000 0</plot-background-color><orientation>Horizontal</orientation>

<is-3D>false</is-3D>

<is-stacked>false</is-stacked>

<category-label-rotation> 0</category-label-rotation> <border-visible>false</border-vis ible>

<border-paint>#33 99FF</border-paint>

<include-legend>true< /include-legend>

</chart-attributes>

</component-definition>

</action-definition>

<action-definition>

<component -name>TemplateComponent< /component-name> <action-type>Message Template</action-type> <action-inputs>

<base-url type="string"/>

<chart-filename type="string"/>

</action-inputs>

<action-outputs>

<output-message type="string" mapping="imgtag"/> </action-outputs>

<component-definition>

<template><![ CDATA[ <img src="{ base-url} /get Image? image={ chart-f ilename}"

/>]] ></template>

</component-definition>

</action-definition>

</actions> </action-sequence>

创建一个 JNDI 可访问的 Datasource  Action Sequences 提供数据

在 PCI 中,指定 datasources,通过在 PCI 的 server/default/deploy 文件夹下添加一个 XML 文件。文件的名字必须以 "-ds.xml" 结束。

这个实例使用 SampleData JNDI 名字来引用它的 datasource。SampleData 的配置文件叫sampledata-ds.xml,如下所示:

<?xml version="1 .0" encoding="UTF-8"?> <datasources>

<local-tx-datasource>

<j ndi-name> SampleData</j ndi-name>

<connection-url>j dbc : hsqldb : hsql: //localhost: 9001/sampledata</connection-url> <driver-class>org . hsqldb. j dbcDriver</driver-class>

<user-name>pentaho_user</user-name> <pas sword>password< /pas sword> <check-valid-connection-sql>

select count(*) from INFORMATION _SCHEMA. SYSTEM_SEQUENCES

</check-valid-connection-sql> </ local-tx-datasource>

</datasources>

配置 JNDI Datasources for use in Pentaho BI Platform有在 PCI 中创建 JNDI datasources 的更多信息。

使用一个 System Action 改善 Filter Panel 的性能

filter panel 的当前配置每次从数据库获取 list-of-values (LOV)。filter panel 在 portal 页面中呈现。对于很少改变的 LOV,以这个频率获取数据,将会在数据库服务器上引发不必要的负载。

通过以下方式,我们可减少负载:

1.       配置一个 System Action 当平台启动时,一次从数据库获取值的列表,将之放进一个全局参数中。然后这个全局参数可用作任何 Action Sequence 的输入。

2.       修改 filter panel 的定义从全局参数获取 LOV,而不是运行 getCustomerNames Action Sequence 访问 LOV。

3.       修改 getCustomerNames Action Sequence 确保它关闭了数据库连接,将查询的结果存储在一个disconnected result set 中。

配置 System Action

简单的说,一个 System Action 是一个 Action Sequence,其被配置运行于系统启动时,或 session 启动时。System Actions 在 repository 的系统配置文件中进行配置,通常称作pentaho.xml。配置 System Actions 的详细信息请参考文章 System Actions

在系统配置文件中添加以下 xml fragment 将导致在系统启动时,运行getCustomerNames.xaction,那个 action sequence 的输出作为全局参数,可用于 portlets。

<pentaho-system>

...

<system-actions>

...

<org.pentaho.ui.portlet.PentahoPortletSession scope="global">

samples/simpleDashboardUsingSystemAction/getCustomerNames.xaction </org.pentaho.ui.portlet. PentahoPortletSession>

... </system-actions>

...

</pentaho-system>

 

修改 Filter Panel

修改 filter panel 的定义:删除节点 <data-solution>,<data-path>,<data-action> 和 <data-output>,用节点 <global-attribute> 替换它们。<global-attribute> 节点的文本应该和最初的 filter panel 配置文件中的 <data-output> 节点的文本一样(例如 getCustomerNames Action Sequence 输出的名字)。

在平台的 Pre-1.6 版本中配置 Filter Panel

在平台的 pre-1.6 版本中,不是使用 <global-attribute> 元素来标识输入的名字,而是使用 <session-attribute> 元素。

<filters>

<name>CustomerNamesFilter</name>

<filter>

<!-- Title text displayed in the filter panel -->

<title>Customer</title>

<!-- name and id of the HTML form control representing this filter --> <name>customernumber< /name>

<!-- type of control to display in the filter panel -->

<type>list</type>

<!-- name of global scoped parameter containing the LOV --> <global-attribute>customerNamesList</global-attribute>

<!-- maps to the <option> element's text -->

<data-display>customername</data-display>

<!-- maps to the <option> element's value attribute in the HTML form --> <data-value>customernumber</data-value>

</ filter>

</filters>

 

修改 getCustomerNames Action Sequence 确保它关闭了它的数据库连接

在 Relational action 中,默认选中 Keep Connection Open 复选框。你需要取消选中这个复选框。

"Keep Connections Open" 是什么意思?

如果没有选中 Keep Connections Open,当一个 Relational action 运行一个数据库查询时,它立即将查询的结果存储进一个 light-weight java 对象中,并关闭到数据库的连接。这个 light-weight java 对象可被存储为请求中的一个参数,session  global scope。这使得对象可用于 action sequence 中的其他 actions,以及在其他时间运行的其他action sequences。然而结果经常很大,使得将内容复制进一个 light-weight java 对象很昂贵。同时将这两个对象临时保存在内存中也很昂贵。在这种情况下,选中 "Keep Connections Open" 就很有意义。这将导致 result-set 到数据库的连接处于 open 状态。result-set 对这个 action sequence 中的其他 actions 可用。不会对 light-weight java 对象作一个副本。在所有情况下,执行完 action sequence,就会关闭到数据库的连接。这就暗示选中了 "Keep Connections Open" 之后创建的 result set不会是 session  global scope,因为当前 action sequence 执行完后,就会关闭 result set 的连接,使之不可用。

你需要重启你的服务器,使得这些改变生效。

测试 Portal-based Dashboard 实例文件

portlet.xml

portlet-instances.xml

pentaho-portal-object.xml

simple-dashboard.filterpanel.xml

JFree ChartComponent.xaction

getCustomerNames.xaction

alternate simple-dashboard.filterpanel.xml  pentaho.xml


你可能感兴趣的:(JOIN,image,filter,action,Parameters,portlet)