Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

...

In this example, a ChartTableModel is created consisting of 21 rows and 3 columns. This example also adds some row and column metadata.

Code Block
javajava
titlecreateChartTableModel: Dummy Data
java
private static ChartTableModel createChartTableModel() {
    // 21 rows and 3 columns
    Object[][] dataArray = { 
                             {   5.55,  10.11,  20.22 }, 
                             {  30.33,  40.44,  50.55 }, 
                             {  31.33,  99.44, 150.55 },
                             {  32.33,   1.44,  30.55 }, 
                             {  34.33,  88.44,  77.55 }, 
                             {  35.33,  22.44,  54.55 }, 
                             {  36.33,  33.44,  52.55 },
                             {  37.33,  76.44,  54.55 }, 
                             {  38.33,   7.44,  59.55 }, 
                             {  39.33,  48.44,  56.55 }, 
                             {  40.33,  19.44,  57.55 },
                             {  50.33, 104.44,  36.55 }, 
                             {  60.33,  23.44,  74.55 }, 
                             {  20.33,  90.44,  80.55 }, 
                             {  60.33,  18.44,  27.55 },
                             {  10.33,  22.44,  97.55 }, 
                             {  20.33,  59.44,  55.55 }, 
                             {  90.33, 140.44,  22.55 }, 
                             { 100.33,  56.44,  76.55 },
                             {  40.33,  50.44,  50.55 }, 
                             {  60.66,  70.77,  80.88 } 
                           };

    ChartTableModel data = new ChartTableModel();
    data.setData(dataArray);

    // give names to the categories
    data.setColumnName(0, "budget");
    data.setColumnName(1, "sales");
    data.setColumnName(2, "forecast");

    // give names to the series
    final String ROW_NAME_KEY = "row-name";
    data.setRowMetadata(0, ROW_NAME_KEY, "1");
    data.setRowMetadata(1, ROW_NAME_KEY, "2");
    // ----- lines omitted -----
    data.setRowMetadata(20, ROW_NAME_KEY, "21");
    return data;
  }

...

This example adds 21 series to the plot which in turn gets added to the chart.

java
Code Block
java
titlecreateChartModel: Dummy Chart Structure
java
private static ChartModel createChartModel() {

    List<Series> seriesList = new ArrayList<Series>();
    Series series1 = new Series();
    series1.setForegroundColor(0x2D00FF);
    seriesList.add(series1);
    Series series2 = new Series();
    series2.setForegroundColor(0x11FFE4);
    seriesList.add(series2);

    // lines omitted

    Series series21 = new Series();
    series21.setForegroundColor(0x0596FF);
    seriesList.add(series21);

    CategoricalBarPlot plot = new CategoricalBarPlot();
    plot.setSeries(seriesList);
    plot.setOrientation(Orientation.HORIZONTAL);

    ChartModel chartModel = new ChartModel();
    chartModel.setTitle("Bar Chart Using Pentaho ChartBeans");
    chartModel.setPlot(plot);
    return chartModel;
  }

...

Now all of the pieces can be pulled together. First there is a main method that "boots" Pentaho ChartBeans. This reads various configuration files and otherwise readies the system for chart processing requests. Next, one chart is rendered using the JFreeChart plugin for Pentaho ChartBeans and then another chart is rendered using the Open Flash Chart plugin for Pentaho ChartBeans. Note that both use the same ChartModel and ChartTableModel.

java
Code Block
java
titlemain method
java
public static void main(String[] args) throws Exception {
    // "boot" ChartBeans
    ChartBoot.getInstance().start();

    // remove any output from previous runs
    cleanOutput();

    // render chart using JFreeChart plugin for Pentaho ChartBeans
    renderUsingJFreeChartPlugin(createChartModel(), createChartTableModel(), "chartoutput/Bar.png");

    // render same chart using Open Flash Chart plugin for Pentaho ChartBeans
    renderUsingOpenFlashChartPlugin(createChartModel(), createChartTableModel(), "chartoutput/Bar.html");
  }

See how one specifies the plugin class in the first line?

java
Code Block
java
titlerenderUsingJFreeChartPlugin method
java
private static void renderUsingJFreeChartPlugin(final ChartModel chartModel, final ChartTableModel chartTableModel,
      final String chartOutputFilename) throws Exception {
    final IChartPlugin plugin = ChartPluginFactory.getInstance("org.pentaho.chart.plugin.jfreechart.JFreeChartPlugin");
    ChartDocumentContext cdc = ChartFactory.generateChart(chartModel, chartTableModel);
    IOutput output = plugin.renderChartDocument(cdc, chartTableModel);
    OutputUtils.persistChart(output, chartOutputFilename, IOutput.OutputTypes.FILE_TYPE_PNG, 400/*px*/, 400/*px*/);
  }

...

Note: This example uses open-flash-chart-full-embedded-font.swf, found at http://www.ofc2dz.com/, which is a patched version of Open Flash Chart 2.

java
Code Block
java
titlerenderUsingOpenFlashChartPlugin method
java
private static void renderUsingOpenFlashChartPlugin(final ChartModel chartModel,
      final ChartTableModel chartTableModel, final String chartOutputFilename) throws Exception {
    final IChartPlugin plugin = ChartPluginFactory
        .getInstance("org.pentaho.chart.plugin.openflashchart.OpenFlashChartPlugin");

    ChartDocumentContext cdc = ChartFactory.generateChart(chartModel, chartTableModel);
    IOutput output = plugin.renderChartDocument(cdc, chartTableModel);

    ByteArrayOutputStream tmpOut = new ByteArrayOutputStream();
    output.persistChart(tmpOut, IOutput.OutputTypes.DATA_TYPE_STREAM, 400, 400);
    final String ENCODING = "UTF-8";
    ByteArrayInputStream in = new ByteArrayInputStream(tmpOut.toByteArray());
    IOUtils.closeQuietly(tmpOut);
    String openFlashChartJson = IOUtils.toString(in, ENCODING);
    IOUtils.closeQuietly(in);

    final String HTML_TEMPLATE = "<html>\n" + "  <head>\n"
        + "    <title>Bar Chart Using Open Flash Chart Plugin</title>\n"
        + "    <script type=\"text/javascript\">window.getChartData = function() '{' return ''{0}''; '}'</script>\n"
        + "  </head>\n" + "  <body>\n"
        + "    <object id=\"ofco00b1c87708fe11dea97da1e1ba5b86bc\" height=\"100%\" align=\"middle\" width=\"100%\" \n"
        + "    codebase=\"http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0\" \n"
        + "    classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"> \n"
        + "    <param value=\"sameDomain\" name=\"allowScriptAccess\"/><param value=\"opaque\" name=\"wmode\"/> \n"
        + "    <param value=\"open-flash-chart.swf?get-data=getChartData\" name=\"movie\"/> \n"
        + "    <param value=\"high\" name=\"quality\"/><embed id=\"ofce00b1c87708fe11dea97da1e1ba5b86bc\" \n"
        + "    height=\"100%\" align=\"middle\" width=\"100%\" \n"
        + "    pluginspage=\"http://www.macromedia.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" \n"
        + "    allowscriptaccess=\"sameDomain\" bgcolor=\"#FFFFFF\" quality=\"high\" wmode=\"opaque\" \n"
        + "    src=\"open-flash-chart.swf?get-data=getChartData\"/></object>\n" + "  </body>\n" + "</html>";

    String html = MessageFormat.format(HTML_TEMPLATE, new String[] { openFlashChartJson });
    FileUtils.writeStringToFile(new File(chartOutputFilename), html, "UTF-8");
  }

...

The ChartBeans XML document for this example is below. Its relatively brief because the data and styling is separate from the chart structure. The elements in this document define a stylesheet reference, a chart title, the series, and the chart orientation.

xml
Code Block
xml
titleBar.xml: The Chart Document
xml
<chart xmlns="http://reporting.pentaho.org/namespaces/charting/1.0">

  <!-- external style sheet -->
  <stylesheet href="theme.css" />

  <!-- chart title -->
  <title>Bar Chart Using Pentaho ChartBeans</title>

  <!-- styling on individual series using style and class attributes -->
  <series style="-x-pentaho-chart-series-type: bar; -x-pentaho-chart-bar-style: bar;" class="series1" />
  <series class="series2" />
  <!-- lines omitted -->
  <series class="series18" />

  <!-- wrap colors because there are more series than colors in the theme -->
  <series class="series1" />
  <series class="series2" />
  <series class="series3" />

  <!-- styling on plot using style attribute -->
  <plot style="-x-pentaho-chart-orientation: horizontal"/>
</chart>

...

Here is the external style sheet referenced above. Here class selectors are being used. Note the W3C standard color property as well as a custom Pentaho ChartBeans' -x-pentaho-chart-line-width property.

none
Code Block
none
titletheme.css
none
.series1 {
  color: #2D00FF;
  -x-pentaho-chart-line-width: 2px;
}

.series2 {
  color: #11FFE4;
  -x-pentaho-chart-line-width: 2px;
}

/* lines omitted */

.series18 {
  color: #B7FFE5;
  -x-pentaho-chart-line-width: 2px;
}

...

Note: The ChartComponent mentioned below is not complete! It is a work in progress and cannot be used as is. This example is for illustration only.

xml
Code Block
xml
titlePentaho Action Sequence (for use in the Pentaho BI Platform)
xml
<?xml version="1.0" encoding="UTF-8"?>
<action-sequence>
  <name>chartbeans_demo.xaction</name>
  <title>chartbeans_demo.xaction</title>
  <version>1</version>
  <logging-level>debug</logging-level>
  <documentation>
    <description>Generate a chart through ChartBeans from an MQL statement.</description>
    <help>Pass in an MQL statement that returns a table of three columns. The first column is the series, the second is the category and the third is the data.</help>
    <result-type>rule</result-type>
  </documentation>

  <inputs>
    <query type="string">
      <sources>
        <request>query</request>
      </sources>
    </query>
    <chart-model type="string">
      <sources>
        <request>chart-model</request>
      </sources>
    </chart-model>
    <chart-width type="integer">
      <sources>
        <request>chart-width</request>
      </sources>
      <default-value>-1</default-value>
    </chart-width>
    <chart-height type="integer">
      <sources>
        <request>chart-height</request>
      </sources>
      <default-value>-1</default-value>
    </chart-height>
    <series-column type="string">
      <sources>
        <request>series-column</request>
      </sources>
      <default-value/>
    </series-column>
    <category-column type="string">
      <sources>
        <request>category-column</request>
      </sources>
      <default-value/>
    </category-column>
    <value-column type="string">
      <sources>
        <request>value-column</request>
      </sources>
      <default-value/>
    </value-column>
  </inputs>

  <outputs>
    <outputstream type="content">
      <destinations>
        <response>content</response>
      </destinations>
    </outputstream>
  </outputs>

  <resources/>

  <actions>

    <action-definition>
      <action-inputs>
        <query />
      </action-inputs>
      <action-outputs>
        <rule-result type="result-set" mapping="chartdata"/>
      </action-outputs>
      <component-name>MQLRelationalDataComponent</component-name>
      <action-type>rule</action-type>
      <component-definition>
        <live>true</live>
        <display-names>false</display-names>
      </component-definition>
    </action-definition>

    <action-definition>
      <component-name>org.pentaho.platform.engine.services.solution.PojoComponent</component-name>
      <action-inputs>
        <chart-model type="string"/>
        <chartdata type="result-set" />
        <chart-width type="integer"/>
        <chart-height type="integer"/>
        <series-column type="string"/>
        <category-column type="string"/>
        <value-column type="string"/>
      </action-inputs>
      <action-outputs>
        <outputstream/>
      </action-outputs>
      <component-definition>
        <class>org.pentaho.platform.plugin.action.chartbeans.ChartComponent</class>
      </component-definition>
      <action-name>Test the test POJO</action-name>
      <logging-level>DEBUG</logging-level>
    </action-definition>

  </actions>
</action-sequence>

...