<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-14521551</id><updated>2012-01-31T04:24:13.675-08:00</updated><category term='Charts'/><category term='format'/><category term='scripts'/><category term='Fonts'/><title type='text'>BIRT World</title><subtitle type='html'>The Eclipse Business Intelligence and Reporting Tools project is an open-source project focused on the development and delivery of framework tools for reporting and business intelligence within the Eclipse platform.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default?start-index=101&amp;max-results=100'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>189</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-14521551.post-6090395781931731760</id><published>2012-01-27T07:54:00.000-08:00</published><updated>2012-01-27T07:57:33.375-08:00</updated><title type='text'>BIRT Runtime Addition</title><content type='html'>As part of the 3.7 release BIRT now uses a BIRT POJO runtime.  This change was described in the &lt;a href="http://www.eclipse.org/birt/phoenix/project/notable3.7.php"&gt;BIRT 3.7 New and Notable&lt;/a&gt;.  If you are using a version of BIRT prior to 3.7 be sure to check out the &lt;a href="http://wiki.eclipse.org/Birt_3.7_Migration_Guide"&gt;Migration Guide&lt;/a&gt;.  As part of the 3.7.2 release of BIRT which will be released in a couple of weeks, the team has decided to release a second runtime that uses the OSGi runtime.  This new download will function similar to the BIRT runtime prior to BIRT 3.7 and is available on the full downloads page.  You can try out the 3.7.2 release candidate version of this download by selecting the release candidate on the &lt;a href="http://download.eclipse.org/birt/downloads/build_list.php "&gt;recent builds page&lt;/a&gt;.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-P3S8kkSbBJw/TyLJWacdv1I/AAAAAAAAAcA/BX83MWY4mso/s1600/osgibirtruntime.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 199px;" src="http://3.bp.blogspot.com/-P3S8kkSbBJw/TyLJWacdv1I/AAAAAAAAAcA/BX83MWY4mso/s400/osgibirtruntime.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5702341465097486162" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-6090395781931731760?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/6090395781931731760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=6090395781931731760' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6090395781931731760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6090395781931731760'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2012/01/birt-runtime-addition.html' title='BIRT Runtime Addition'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-P3S8kkSbBJw/TyLJWacdv1I/AAAAAAAAAcA/BX83MWY4mso/s72-c/osgibirtruntime.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-3650074470488179098</id><published>2011-10-26T11:18:00.000-07:00</published><updated>2011-10-26T11:46:25.973-07:00</updated><title type='text'>BIRT Chart Palette</title><content type='html'>We have posted many times about the different facets of scripting (client and server side) for BIRT charts.  Some of these posts are shown below.  In many cases users want to modify chart colors based on some data value or some external logic.  While this is very simple with the standard palette colors, some of the other palette options are not as straight forward.  In this post we will discuss the different palette options developers have and how to access and modify them from script.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Previous Chart Scripting Posts&lt;/h2&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2010/08/birt-charting-scripting-overview.html"&gt;Chart Scripting Overview&lt;/a&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2009/08/using-script-to-modify-birt-chart.html"&gt;Using Script to Modify a BIRT Chart&lt;/a&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2008/10/dynamically-adding-series-to-birt-chart.html"&gt;Dynamically Adding a Series to a BIRT Chart&lt;/a&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2009/12/calling-client-side-javascript-from.html"&gt;Calling Client Side JavaScript From a BIRT Chart&lt;/a&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2010/05/more-on-chart-interactivity.html"&gt;More on Chart Interactivity&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;BIRT Palette Options&lt;/h2&gt;&lt;br /&gt;The BIRT Chart Palette supports standard and custom colors, gradients, images, positive/negative entries and patterns.&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-inm-Fzl2gg0/TqhQ9rRyqwI/AAAAAAAAAaI/AQGyOOxKLx8/s1600/DesignerPalette.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 290px;" src="http://3.bp.blogspot.com/-inm-Fzl2gg0/TqhQ9rRyqwI/AAAAAAAAAaI/AQGyOOxKLx8/s400/DesignerPalette.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5667869151565359874" /&gt;&lt;/a&gt;&lt;br /&gt;While standard and custom colors are simple some of the other types offer some interesting possibilities.  The Gradient palette entry allows a start and end color as well as a rotation angle for the gradient.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-vb4bPOuR8Uk/TqhRLsffr6I/AAAAAAAAAaU/B6f5dLi1Psw/s1600/GradientPalette.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 305px;" src="http://4.bp.blogspot.com/-vb4bPOuR8Uk/TqhRLsffr6I/AAAAAAAAAaU/B6f5dLi1Psw/s400/GradientPalette.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5667869392409440162" /&gt;&lt;/a&gt;&lt;br /&gt;The Image Palette entry allows a developer to specify a URL or embed an image directly into the chart model.&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-40bZwbqcYdQ/TqhRTmng8wI/AAAAAAAAAag/s3_rY0DwPrw/s1600/ImagePalette.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 280px;" src="http://1.bp.blogspot.com/-40bZwbqcYdQ/TqhRTmng8wI/AAAAAAAAAag/s3_rY0DwPrw/s400/ImagePalette.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5667869528271418114" /&gt;&lt;/a&gt;&lt;br /&gt;The Positive/Negative palette entry uses one palette color for positive values and one for negative values.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-K5BzYQKL_oc/TqhReQAAU_I/AAAAAAAAAas/oh5CgA0B4p4/s1600/PositiveNegativePalette.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 280px;" src="http://4.bp.blogspot.com/-K5BzYQKL_oc/TqhReQAAU_I/AAAAAAAAAas/oh5CgA0B4p4/s400/PositiveNegativePalette.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5667869711178683378" /&gt;&lt;/a&gt;&lt;br /&gt;The Pattern palette entry allows the developer to define a pattern with foreground and background colors.  The pattern can be one of the predefined patterns or one that is customized.&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-jJHXDrfn5oc/TqhRsBaTdzI/AAAAAAAAAa4/M_nbTB2SAec/s1600/HashPattern.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 280px;" src="http://2.bp.blogspot.com/-jJHXDrfn5oc/TqhRsBaTdzI/AAAAAAAAAa4/M_nbTB2SAec/s400/HashPattern.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5667869947780626226" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h2&gt;Palette Scripting&lt;/h2&gt;&lt;br /&gt;Many of the events that are triggered during the creation of the chart are passed a fill object.  The actual data type of the fill object will depend on how the palette has been setup.  The Fill object will be one of the following types:&lt;br /&gt;&lt;br /&gt;org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl – Color/Custom Color Palette Entry&lt;br /&gt;org.eclipse.birt.chart.model.attribute.impl.GradientImpl – Gradient Palette Entry&lt;br /&gt;org.eclipse.birt.chart.model.attribute.impl.ImageImpl – Image URL Entry&lt;br /&gt;org.eclipse.birt.chart.model.attribute.impl.EmbeddedImageImpl – Embedded Image Entry&lt;br /&gt;org.eclipse.birt.chart.model.attribute.impl.MultipleFillImpl – Positive/Negative Entry&lt;br /&gt;eclipse.birt.chart.model.attribute.impl.PatternImageImpl – Pattern Entry&lt;br /&gt;&lt;br /&gt;For example assume that you have a Bar chart that uses one bar color and you want to change this color based on the Y-Axis value of the data point.  The following beforeDrawDataPoint Script could be used.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeDrawDataPoint(dph, fill, icsc)&lt;br /&gt;{&lt;br /&gt;//Fill implements Fill interface &lt;br /&gt;//ImageImpl&lt;br /&gt;//ColorDefinitionImpl&lt;br /&gt;//GradientImpl&lt;br /&gt;//MultipleFillImpl&lt;br /&gt;//EmbeddedImageImpl&lt;br /&gt;//PatternImageImpl&lt;br /&gt;&lt;br /&gt;importPackage( Packages.org.eclipse.birt.chart.model.attribute.impl );&lt;br /&gt;val = dph.getOrthogonalValue();&lt;br /&gt; if( fill.getClass().isAssignableFrom(ColorDefinitionImpl)){&lt;br /&gt;  if (val &lt; 40){&lt;br /&gt;        fill.set(255, 0, 0);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;In this particular example the fill object is a ColorDefinitionImpl object that supports setting the R,G,B value of the color.  Notice also that we import the org.eclipse.birt.chart.model.attribute.impl package to get access to the ColorDefinitionImpl class.  If the palette entry was a gradient the script could be changed to something like the following:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeDrawDataPoint(dph, fill, icsc)&lt;br /&gt;{&lt;br /&gt;//Fill implements Fill interface &lt;br /&gt;//ImageImpl&lt;br /&gt;//ColorDefinitionImpl&lt;br /&gt;//GradientImpl&lt;br /&gt;//MultipleFillImpl&lt;br /&gt;//EmbeddedImageImpl&lt;br /&gt;//PatternImageImpl&lt;br /&gt;&lt;br /&gt;importPackage( Packages.org.eclipse.birt.chart.model.attribute.impl );&lt;br /&gt;val = dph.getOrthogonalValue();&lt;br /&gt; if( fill.getClass().isAssignableFrom(GradientImpl)){&lt;br /&gt;  if (val &lt; 40){&lt;br /&gt;     fill.getStartColor().set(255,0,0);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;In this example we set the start color of the gradient.&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-pVUWhmRVkls/TqhS5J9Mz3I/AAAAAAAAAbE/B3CLDeIUoMw/s1600/beforeDrawDataPoint.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 138px;" src="http://3.bp.blogspot.com/-pVUWhmRVkls/TqhS5J9Mz3I/AAAAAAAAAbE/B3CLDeIUoMw/s400/beforeDrawDataPoint.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5667871272924401522" /&gt;&lt;/a&gt;&lt;br /&gt;If you are using a Bubble chart with a Positive/Negative palette entry, by default one color will be used for positive values and the other for negative colors.  You could alter this behavior for certain data points.  For example the following script changes the positive and negative colors for some of the data points.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeDrawDataPoint(dph, fill, icsc)&lt;br /&gt;{&lt;br /&gt;//Fill implements Fill interface &lt;br /&gt;//ImageImpl&lt;br /&gt;//ColorDefinitionImpl&lt;br /&gt;//GradientImpl&lt;br /&gt;//MultipleFillImpl&lt;br /&gt;//EmbeddedImageImpl&lt;br /&gt;//PatternImageImpl&lt;br /&gt;&lt;br /&gt;importPackage( Packages.org.eclipse.birt.chart.model.attribute.impl );&lt;br /&gt;importPackage( Packages.org.eclipse.birt.chart.extension.datafeed);&lt;br /&gt;//for bubble chart this returns a BubbleEntry &lt;br /&gt;val = dph.getOrthogonalValue();&lt;br /&gt;yval = val.getValue()&lt;br /&gt; if( fill.getClass().isAssignableFrom(MultipleFillImpl)){&lt;br /&gt;  if( yval &gt; -500 &amp;&amp; yval &lt; 500 ){&lt;br /&gt;   fill.getFills().clear();&lt;br /&gt;   fill.getFills( ).add( ColorDefinitionImpl.BLUE( ) );&lt;br /&gt;   fill.getFills( ).add( ColorDefinitionImpl.WHITE( ) );&lt;br /&gt;  } &lt;br /&gt;   &lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-nVyU0BRjHrQ/TqhTNjxT7xI/AAAAAAAAAbQ/mPCwTgXWCCU/s1600/bubbleexample.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 167px;" src="http://4.bp.blogspot.com/-nVyU0BRjHrQ/TqhTNjxT7xI/AAAAAAAAAbQ/mPCwTgXWCCU/s400/bubbleexample.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5667871623451242258" /&gt;&lt;/a&gt;&lt;br /&gt;Notice that we needed to import the datafeed package as the bubble chart has size and value entries for the y-axis.  We also used the ColorDefinitionImpl predefined colors for blue and white.  We could have created the color using R,G,B values like ColorDefinitionImpl.create( 255, 255, 225 ).&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Palette Model Location&lt;/h2&gt;&lt;br /&gt;While the above examples illustrate how to manipulate palette entries that are passed to the other events, it is often desirable to alter one or more palette entries.  This can be done in the beforeGeneration event. How you access the chart palette will depend on what type of chart it is: Chart with Axes or Chart without Axes.  For example suppose you want to replace the chart palette with a set of predefined gradients.  To do this with a pie chart the following script could be used.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeGeneration( chart, icsc )&lt;br /&gt;{&lt;br /&gt;  importPackage(Packages.org.eclipse.birt.chart.model.attribute.impl);&lt;br /&gt;  sd = chart.getSeriesDefinitions( ).get( 0 );&lt;br /&gt;  sd.getSeriesPalette( ).getEntries( ).clear( );&lt;br /&gt;&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(220,237,248), ColorDefinitionImpl.create(80,166,218), 0, false));&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(255,213,213), ColorDefinitionImpl.create(242,88,106), 0, false));&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(255,247,213), ColorDefinitionImpl.create(232,172,57), 0, false));&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(213,255,213), ColorDefinitionImpl.create(128,255,128), 0, false));&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(213,255,255), ColorDefinitionImpl.create(64,128,128), 0, false));&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(226,226,241), ColorDefinitionImpl.create(128,128,192), 0, false));&lt;br /&gt;   &lt;br /&gt;      &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-LcrCyXYSFSk/TqhTx9qTeDI/AAAAAAAAAbc/b7LfbsDEIw0/s1600/GradientPaletteExample.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 123px;" src="http://1.bp.blogspot.com/-LcrCyXYSFSk/TqhTx9qTeDI/AAAAAAAAAbc/b7LfbsDEIw0/s400/GradientPaletteExample.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5667872248876464178" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In this example we clear the existing palette and replace it with a set of gradients.  The palette is attached to the charts first series definition.&lt;br /&gt;For a Bar chart the following script would be used.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeGeneration( chart, icsc )&lt;br /&gt;{&lt;br /&gt;  importPackage(Packages.org.eclipse.birt.chart.model.attribute.impl);&lt;br /&gt;&lt;br /&gt;  var xAxis = chart.getAxes().get(0);&lt;br /&gt;  var yAxis = xAxis.getAssociatedAxes().get(0);&lt;br /&gt;  var sd = xAxis.getSeriesDefinitions().get(0);&lt;br /&gt;&lt;br /&gt;  sd.getSeriesPalette( ).getEntries( ).clear( );&lt;br /&gt;&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(220,237,248), ColorDefinitionImpl.create(80,166,218), 0, false));&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(255,213,213), ColorDefinitionImpl.create(242,88,106), 0, false));&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(255,247,213), ColorDefinitionImpl.create(232,172,57), 0, false));&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(213,255,213), ColorDefinitionImpl.create(128,255,128), 0, false));&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(213,255,255), ColorDefinitionImpl.create(64,128,128), 0, false));&lt;br /&gt;  sd.getSeriesPalette().getEntries().add( GradientImpl.create( ColorDefinitionImpl.create(226,226,241), ColorDefinitionImpl.create(128,128,192), 0, false));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-6OSxlgPuKRM/TqhT8mTS3GI/AAAAAAAAAbo/WBDMvgQEAp8/s1600/GradientPaletteExampleBar.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 177px;" src="http://3.bp.blogspot.com/-6OSxlgPuKRM/TqhT8mTS3GI/AAAAAAAAAbo/WBDMvgQEAp8/s400/GradientPaletteExampleBar.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5667872431584500834" /&gt;&lt;/a&gt;&lt;br /&gt;In this example the palette is attached to the series definition associated with the x-axis.&lt;br /&gt;As a more complex example, and afterDataSetFilled script could be used to calculate the number of data points in a particular bar chart.  The beforeGeneration event could then use this value to create a palette that gives entire chart a gradient look by moving a start color to an end color. &lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;cnt = 0;&lt;br /&gt;startColor = null;&lt;br /&gt;endColor = null;&lt;br /&gt;importPackage( Packages.org.eclipse.birt.chart.model.attribute.impl );&lt;br /&gt;&lt;br /&gt;function afterDataSetFilled(series, dataSet, icsc)&lt;br /&gt;{&lt;br /&gt; importPackage( Packages.java.io );&lt;br /&gt; importPackage( Packages.org.eclipse.birt.chart.model.type.impl );&lt;br /&gt;&lt;br /&gt; if( series.getClass() == BarSeriesImpl ){&lt;br /&gt;  if( series.getSeriesIdentifier() == "Series 1" ){&lt;br /&gt;      var list = dataSet.getValues();&lt;br /&gt;      cnt = list.length;&lt;br /&gt;     }&lt;br /&gt;     &lt;br /&gt; &lt;br /&gt; }&lt;br /&gt; startColor = ColorDefinitionImpl.RED(); &lt;br /&gt; endColor = ColorDefinitionImpl.ORANGE(); &lt;br /&gt;}&lt;br /&gt;function buildPalette( mNumber )&lt;br /&gt;{&lt;br /&gt;     var sr = startColor.getRed();&lt;br /&gt;        var sg = startColor.getGreen();&lt;br /&gt;        var sb = startColor.getBlue();&lt;br /&gt;&lt;br /&gt;     var er = endColor.getRed();&lt;br /&gt;        var eg = endColor.getGreen();&lt;br /&gt;        var eb = endColor.getBlue();&lt;br /&gt;&lt;br /&gt;  var nr = ((er-sr)/cnt)*mNumber + sr;&lt;br /&gt;  var ng = ((eg-sg)/cnt)*mNumber + sg;&lt;br /&gt;  var nb = ((eb-sb)/cnt)*mNumber + sb;        &lt;br /&gt;        &lt;br /&gt;        var nc = ColorDefinitionImpl.create( nr, ng, nb );        &lt;br /&gt;  return nc;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function beforeGeneration( chart, icsc )&lt;br /&gt;{&lt;br /&gt;var xAxis = chart.getAxes().get(0);&lt;br /&gt;var yAxis = xAxis.getAssociatedAxes().get(0);&lt;br /&gt;var xSerieDef = xAxis.getSeriesDefinitions().get(0);&lt;br /&gt;var ySerieDef = yAxis.getSeriesDefinitions().get(0);&lt;br /&gt;&lt;br /&gt;  xSerieDef.getSeriesPalette().getEntries().clear( );  &lt;br /&gt;  for ( i = 1; i &lt;= cnt; i++ )&lt;br /&gt;  {&lt;br /&gt;   xSerieDef.getSeriesPalette().getEntries().add( buildPalette(i) );&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-BBxWt36l-Us/TqhUNk4WuOI/AAAAAAAAAb0/DZCzKuEQ_6A/s1600/GradientPaletteAcrossBars.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 173px;" src="http://3.bp.blogspot.com/-BBxWt36l-Us/TqhUNk4WuOI/AAAAAAAAAb0/DZCzKuEQ_6A/s400/GradientPaletteAcrossBars.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5667872723260848354" /&gt;&lt;/a&gt;&lt;br /&gt;The example shown here are available at &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1437-birt-palette-examples/"&gt;BIRT Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-3650074470488179098?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/3650074470488179098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=3650074470488179098' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3650074470488179098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3650074470488179098'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/10/birt-chart-palette.html' title='BIRT Chart Palette'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-inm-Fzl2gg0/TqhQ9rRyqwI/AAAAAAAAAaI/AQGyOOxKLx8/s72-c/DesignerPalette.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-5711267868283621224</id><published>2011-08-30T07:49:00.000-07:00</published><updated>2011-08-30T08:00:42.515-07:00</updated><title type='text'>BIRT Contest</title><content type='html'>Last week at the BIRT road show in Bangalore, Actuate announced a &lt;a href="http://www.actuate.com/birt-roadshow-india-contest/"&gt;BIRT contest&lt;/a&gt;.  The challenge is to extend BIRT by building plug-ins that implement key extension points, like emitters, ODA drivers, charts and report items.  The contest runs until October 15, 2011 and the details can be found on the &lt;a href="http://www.birt-exchange.org/org/wiki/index.php?title=Get_Started_with_BIRT_Contest_Details_and_Examples"&gt;Contest Wiki&lt;/a&gt; page. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-5711267868283621224?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.actuate.com/birt-roadshow-india-contest/' title='BIRT Contest'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/5711267868283621224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=5711267868283621224' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5711267868283621224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5711267868283621224'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/08/birt-contest.html' title='BIRT Contest'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-8369442218923763510</id><published>2011-08-26T10:49:00.001-07:00</published><updated>2011-08-26T10:57:56.533-07:00</updated><title type='text'>BIRT Viewer Export Data</title><content type='html'>When using the AJAX based BIRT Viewer, a user has the option to show the table of contents, re-run the report with different parameters, export report data, export the report to XLS, PDF, PPT, DOC, PS, ODS, ODP, ODT formats, Print from the client, or print on the server.  These options are available within the toolbar of the viewer.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-oaB0jjClAQ0/Tlfc0-HAqoI/AAAAAAAAAZg/M1OnhgcSejo/s1600/viewer.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 343px;" src="http://1.bp.blogspot.com/-oaB0jjClAQ0/Tlfc0-HAqoI/AAAAAAAAAZg/M1OnhgcSejo/s400/viewer.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5645223460515916418" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The export data function allows the report user to export all the columns in the data binding collection for all data bound items in the report.  To see the columns that will show up in the export, select the report item and choose the binding tab in the properties editor.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-thT4on7bPnI/Tlfc_HfPnbI/AAAAAAAAAZo/d_IRIEJcMPs/s1600/binding.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 125px;" src="http://1.bp.blogspot.com/-thT4on7bPnI/Tlfc_HfPnbI/AAAAAAAAAZo/d_IRIEJcMPs/s400/binding.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5645223634832170418" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Within the Export Data dialog, users can configure the output encoding and separator to use when creating the output.  Currently the separator supports comma, tab, semi-colon, colon, and vertical line separators.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-3XhcxvebH9Q/TlfdHyS0YFI/AAAAAAAAAZw/E6n-wldq5Ss/s1600/exportdata.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 343px;" src="http://1.bp.blogspot.com/-3XhcxvebH9Q/TlfdHyS0YFI/AAAAAAAAAZw/E6n-wldq5Ss/s400/exportdata.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5645223783761731666" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;By default BIRT will use the report element id to generate a name to populate the Available result sets drop down list.  This is generally not a user friendly name.  If the report designer names the report item in the general properties for a report item, this name will be used instead.  In the image above the table is named “mytable”.  By default all data bound items will be shown in the drop down list.  BIRT provides an advanced property called Allow Export that can be set to true or false.  If the value is true for a report item, the report items result set will be shown in the available result sets drop down.  If the value is false, the result set will not be shown.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-0YVUreNOHgY/Tlfdypu1mQI/AAAAAAAAAaA/ryX_zwhAFIE/s1600/advanced.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 239px;" src="http://1.bp.blogspot.com/-0YVUreNOHgY/Tlfdypu1mQI/AAAAAAAAAaA/ryX_zwhAFIE/s400/advanced.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5645224520197708034" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This property can also be set dynamically, using a beforeFactory script and the report elements name.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( params["ExportChartData"].value == false ){&lt;br /&gt;reportContext.getDesignHandle().findElement("mychart").setProperty("allowExport", false);&lt;br /&gt;}&lt;br /&gt;if( params["ExportTableData"].value == false ){&lt;br /&gt;reportContext.getDesignHandle().findElement("mytable").setProperty("allowExport", false);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;In this sample two Boolean report parameters are used to determine whether the allow export property should be set to false.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-Mgfy2VFHHSU/TlfddQvIGTI/AAAAAAAAAZ4/Ifvh6963XUI/s1600/output.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 301px;" src="http://3.bp.blogspot.com/-Mgfy2VFHHSU/TlfddQvIGTI/AAAAAAAAAZ4/Ifvh6963XUI/s400/output.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5645224152710781234" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Other conditions can be used to make the decision on whether to display a report item in the available result sets drop down list.  For example, from script you could call out to a Java object or access a session variable to make the decision.&lt;br /&gt;&lt;br /&gt;The sample report is available at &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1406-set-allow-export-dynamically/"&gt;BIRT-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-8369442218923763510?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/8369442218923763510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=8369442218923763510' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/8369442218923763510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/8369442218923763510'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/08/birt-viewer-export-data.html' title='BIRT Viewer Export Data'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-oaB0jjClAQ0/Tlfc0-HAqoI/AAAAAAAAAZg/M1OnhgcSejo/s72-c/viewer.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-3196597689350664528</id><published>2011-07-29T09:55:00.000-07:00</published><updated>2011-07-29T10:05:41.865-07:00</updated><title type='text'>BIRT Roadshow heads to India</title><content type='html'>If you are interested in some free BIRT training, some of the BIRT team will be in Bangalore on August 26th to do a workshop.  Ray Gans, the Community Manager for Birt-Exchange.org, has posted the agenda on his &lt;a href="http://www.birt-exchange.org/org/forum/index.php/blog/6/entry-266-birt-roadshow-india/"&gt;blog&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To register for the event, visit the &lt;a href="http://www.birt-exchange.com/be/info/birtroadshowbeorg/"&gt;BIRT Roadshow&lt;/a&gt; registration site.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-3196597689350664528?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/3196597689350664528/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=3196597689350664528' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3196597689350664528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3196597689350664528'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/07/birt-roadshow-heads-to-india.html' title='BIRT Roadshow heads to India'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-5871886596126071244</id><published>2011-07-26T14:09:00.000-07:00</published><updated>2011-07-26T14:16:42.277-07:00</updated><title type='text'>BIRT Developer Survey</title><content type='html'>Feedback from users is one of the key inputs into the BIRT planning process. By filling out this survey, you provide the BIRT team with valuable information on how you use BIRT and how you would like to see it evolve.&lt;br /&gt;&lt;br /&gt;Survey should take less than 3 minutes to fill out. &lt;br /&gt;&lt;a href="http://www.surveymonkey.com/s/5NV9XEC"&gt;BIRT Developer Survey&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-5871886596126071244?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.surveymonkey.com/s/5NV9XEC' title='BIRT Developer Survey'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/5871886596126071244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=5871886596126071244' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5871886596126071244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5871886596126071244'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/07/birt-developer-survey.html' title='BIRT Developer Survey'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-8592711357932617731</id><published>2011-07-21T10:27:00.000-07:00</published><updated>2011-07-21T10:43:50.777-07:00</updated><title type='text'>Replacing the default BIRT XLS Emitter</title><content type='html'>If you are using the BIRT 3.7 runtime, the BIRT engine is now in one JAR.  See the &lt;a href="http://www.eclipse.org/birt/phoenix/project/notable3.7.php#jump_2"&gt;BIRT 3.7 New and Notable&lt;/a&gt; for more details.  &lt;br /&gt;&lt;br /&gt;While this is optimal for a lot of reasons, it does make it a little more difficult to replace the default BIRT emitters.  We have seen this with many users wanting to use the &lt;a href="http://sourceforge.net/projects/tribix/"&gt;Tribix emitters&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;See this &lt;a href="http://www.birt-exchange.org/org/forum/index.php/topic/22708-tribix-emitters-in-birt-3-7/"&gt;thread&lt;/a&gt; and this &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=350662"&gt;bug&lt;/a&gt; for an example of the issues.  While replacing the emitter is achievable through the method described in the forum post, it is not very elegant.  BIRT supports having two emitters that emit the same output format.  When the engine processes a request for a specific output format the first emitter found by the runtime generally processes the request.  This may not be desirable.  To work around this a user can specify a specific emitter id to process the given output format.  So if you have both the Tribix XLS and the default BIRT XLS emitter deployed you can specify which emitter to use to process the report.  To illustrate how to do this, we will use the Tribix XLS emitter.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Deploy Tribix Emitter&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;First download the Tribix emitter and deploy it.  If you are using the WebViewer with Version 2.6.2 or earlier, just copy:&lt;br /&gt; &lt;br /&gt;org.uguess.birt.report.engine.emitter.xls_version.jar&lt;br /&gt;org.uguess.birt.report.engine.common_version.jar &lt;br /&gt;&lt;br /&gt;to the WebViewer/WEB-INF/platform/plugins directory.&lt;br /&gt;&lt;br /&gt;If you are using BIRT 3.7 or later extract the following jars from the org.uguess.birt.report.engine.emitter.xls_version.jar.&lt;br /&gt;&lt;br /&gt;xl-emitter.jar&lt;br /&gt;lib/poi-3.5..jar&lt;br /&gt;lib/commons-logging-version.jar&lt;br /&gt;lib/commons-jexl-version.jar&lt;br /&gt;&lt;br /&gt;Copy these jars to the WebViewer/WEB-INF/lib directory.  Make sure they are no longer in the org.uguess.birt.report.engine.emitter.xls_version.jar.  Finally, copy the modified org.uguess.birt.report.engine.emitter.xls_version.jar and the org.uguess.birt.report.engine.common_version.jar to the WebViewer/WEB-INF/lib folder.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Specifying Which Emitter To Use&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The WebViewer provides a URL parameter, named __emitterid that can be used to specify which emitter to use for the xls format.  For example:&lt;br /&gt;&lt;br /&gt;This URL will use the default BIRT XLS emitter&lt;br /&gt;&lt;br /&gt;http://localhost:8090/WebViewer/frameset?__report=test.rptdesign&amp;sample=my+parameter&amp;__emitterid=org.eclipse.birt.report.engine.emitter.prototype.excel&amp;__asattachment=true&amp;__format=xls&lt;br /&gt;&lt;br /&gt;This URL will use the Tribix XLS emitter&lt;br /&gt;&lt;br /&gt;http://localhost:8090/WebViewer/frameset?__report=test.rptdesign&amp;sample=my+parameter&amp;__emitterid=org.uguess.birt.report.engine.emitter.xls&amp;__asattachment=true&amp;__format=xls&lt;br /&gt;&lt;br /&gt;This does not address the case when you are using the export button in the web viewer.  In order to change which XLS emitter is used when the button is pressed, you will need to modify the &lt;br /&gt;BirtExportReportDialog.js file in the  WebViewer/ webcontent/birt/ajax/ui/dialog directory.  Modify the __exportAction function to add the emitter id parameter to the request.&lt;br /&gt;&lt;br /&gt;&lt;code font-size:10pt"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; __exportAction : function( )&lt;br /&gt; {&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;    else&lt;br /&gt;   {&lt;br /&gt;    action = action.replace( reg, "$1=false" );&lt;br /&gt;   }&lt;br /&gt;   if( format=="xls"){&lt;br /&gt;    //action = action + "&amp;__emitterid=org.eclipse.birt.report.engine.emitter.prototype.excel";&lt;br /&gt;    action = action + "&amp;__emitterid=org.uguess.birt.report.engine.emitter.xls"&lt;br /&gt;   }&lt;br /&gt;  &lt;br /&gt;   formObj.action = action;&lt;br /&gt;   formObj.method = "post";   &lt;br /&gt;   formObj.submit( );&lt;br /&gt;   &lt;br /&gt;   return true;&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If you are using the Report Engine API, there is a render option available for setting the emitter id.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;               EXCELRenderOption options = new EXCELRenderOption();  &lt;br /&gt;               options.setOutputFormat("xls");&lt;br /&gt;               options.setOutputFileName("output/resample/ps.xls");&lt;br /&gt;               options.setOption(IRenderOption.EMITTER_ID, "org.eclipse.birt.report.engine.emitter.prototype.excel");&lt;br /&gt;               IRenderTask task = engine.createRenderTask(document);   &lt;br /&gt;               task.setRenderOption(options);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;or&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;               EXCELRenderOption options = new EXCELRenderOption();  &lt;br /&gt;               options.setOutputFormat("xls");&lt;br /&gt;               options.setOutputFileName("output/resample/ps.xls");&lt;br /&gt;               options.setOption(IRenderOption.EMITTER_ID, "org.uguess.birt.report.engine.emitter.xls");&lt;br /&gt;               IRenderTask task = engine.createRenderTask(document);   &lt;br /&gt;               task.setRenderOption(options);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-8592711357932617731?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/8592711357932617731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=8592711357932617731' title='25 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/8592711357932617731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/8592711357932617731'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/07/replacing-default-birt-xls-emitter.html' title='Replacing the default BIRT XLS Emitter'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>25</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-746811783205136838</id><published>2011-06-21T21:11:00.001-07:00</published><updated>2011-06-22T06:53:34.032-07:00</updated><title type='text'>BIRT 3.7 Released</title><content type='html'>BIRT 3.7 is now available and with this release many improvements and new features are available. BIRT 3.7 now provides a new POJO based runtime for ease of deployment when using the BIRT Viewer or the Report Engine.  Open Document Text (ODT), Open Document Presentation (ODP), and Open Document Spreadsheet (ODS) outputs are also available with the addition of three new emitters. BIRT now provides support for Hadoop through a new Open Data Access Driver (ODA) that allows the developer to build queries using Hive Query Language (HQL) using the designer GUI.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-CsanOLH-bbI/TgFrj3q_XXI/AAAAAAAAAZY/csDdiK5-gJc/s1600/collauge2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 223px;" src="http://2.bp.blogspot.com/-CsanOLH-bbI/TgFrj3q_XXI/AAAAAAAAAZY/csDdiK5-gJc/s400/collauge2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5620892073918946674" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To read more about these and other new features for BIRT, see the &lt;a href="http://www.eclipse.org/birt/phoenix/project/notable3.7.php"&gt;BIRT 3.7 New and Notable&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-746811783205136838?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/746811783205136838/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=746811783205136838' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/746811783205136838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/746811783205136838'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/06/birt-37-released.html' title='BIRT 3.7 Released'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-CsanOLH-bbI/TgFrj3q_XXI/AAAAAAAAAZY/csDdiK5-gJc/s72-c/collauge2.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-5418699715313819684</id><published>2011-05-24T10:16:00.000-07:00</published><updated>2011-05-24T10:35:50.788-07:00</updated><title type='text'>BIRT:  Using XLS as a data source</title><content type='html'>BIRT currently supports many data sources, including XML, Web Services, JDBC and flat files.  This list can also be extended by implementing BIRT extension points.  Using this method is called implementing an ODA(Open Data Access) extension. &lt;br /&gt;&lt;br /&gt;An ODA allows the developer to add custom GUI elements to the BIRT designer to create and manipulate a data source.  This method is described in a set of articles located on &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/445-oda-primer-articles/"&gt;BIRT-Exchange&lt;/a&gt;.  BIRT also supplies a scripted data source that allows a developer to write code in a simplified interface to retrieve data using Java or JavaScript. This post explains how a scripted data source can be implemented to retrieve XLS data using the &lt;a href="http://jexcelapi.sourceforge.net/"&gt;Source Forge Java Excel API project&lt;/a&gt;.  For more information on using this API see this &lt;a href="http://www.vogella.de/articles/JavaExcel/article.html"&gt;blog post&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;br /&gt;Adding the JAR to the BIRT Project&lt;br /&gt;&lt;/h3&gt;&lt;br /&gt;First download the Java Excel API and extract the jxl.jar file from the download.  You can add this Jar to your BIRT project in several different ways.  See this post for designer &lt;a href="http://birtworld.blogspot.com/2009/12/birt-designer-classpath-changes.html.  "&gt;classpath options&lt;/a&gt;. One simple way to add the jar is to put the jar in your BIRT Project Resource folder and then add a reference to it in the report design.  You can set the resource folder in the BIRT Designer Preferences (Window-Preferences-Report Design-Resource).  The resource folder is also a web.xml setting in the deployed viewer.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-yN0fGQ0xf28/TdvpLPuqyMI/AAAAAAAAAYM/cYtkmSh6z1Y/s1600/resourcefolder.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 295px;" src="http://4.bp.blogspot.com/-yN0fGQ0xf28/TdvpLPuqyMI/AAAAAAAAAYM/cYtkmSh6z1Y/s400/resourcefolder.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5610334140230191298" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In the above screen shot we have a resources folder under the BIRT reports project.  Just import the jxl.jar into this folder.  To create the reference to the jar in a report design, select the properties view for the report and click on resources.   Click the add file button in the jar files section of the report resources and add the jar.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-0kH5SD0bQyU/TdvpYeWrrTI/AAAAAAAAAYU/_z_LPplxpqo/s1600/addjar.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 223px;" src="http://2.bp.blogspot.com/-0kH5SD0bQyU/TdvpYeWrrTI/AAAAAAAAAYU/_z_LPplxpqo/s400/addjar.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5610334367494417714" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The jar file should now be accessible in the designer from script or expressions.  When you deploy the report to the Viewer make sure to copy the jar to the resource folder of the deployed Viewer.&lt;br /&gt;&lt;br /&gt;If this method of adding the jar is not desirable you can always create a folder in the project containing the lib and add the jar to the project classpath entry (Window-Preferences-Report Design-Classpath).  This will allow the jar to be accessed at design time.  When deploying the report you can then just copy the jar to the WEB-ONF/lib folder of the deployed viewer.  &lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;br /&gt;Implementing the Scripted Data Source/Set&lt;br /&gt;&lt;/h3&gt;&lt;br /&gt;BIRT supports implementing a scripted data source in Java or JavaScript.  In this example we implement it using JavaScript.  Although the code is written in JavaScript we can still call Java code by using the importPackage method.  This example uses this approach.  &lt;br /&gt;&lt;br /&gt;Use the new data source wizard to add a scripted data source and use the new data set wizard to add a new scripted data set.  In this example we are reading a three column xls file, so we define 3 columns in our dataset.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-KyYTr3ynCwg/TdvpvORRbPI/AAAAAAAAAYc/GFEnnnMSTf8/s1600/newdatasource.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 307px;" src="http://3.bp.blogspot.com/-KyYTr3ynCwg/TdvpvORRbPI/AAAAAAAAAYc/GFEnnnMSTf8/s400/newdatasource.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5610334758313749746" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-8fSOacr-bVY/Tdvp3nRyKII/AAAAAAAAAYk/EtP_uRJEewk/s1600/newdataset.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 256px;" src="http://2.bp.blogspot.com/-8fSOacr-bVY/Tdvp3nRyKII/AAAAAAAAAYk/EtP_uRJEewk/s400/newdataset.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5610334902465734786" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The final portion of this example requires that we add code to the script events to call the Java Excel API.  Select the new data set and click on the script tab.  From the drop down menu select the open event.  Enter the following code.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;importPackage( Packages.java.io);&lt;br /&gt;importPackage( Packages.jxl );&lt;br /&gt;try{&lt;br /&gt; var inputWorkbook = new File(params["XLSLocation"].value);&lt;br /&gt; myworkbook = Workbook.getWorkbook(inputWorkbook);&lt;br /&gt; sheet = myworkbook.getSheet(0);&lt;br /&gt; numrows = sheet.getRows();&lt;br /&gt; curr = 0;&lt;br /&gt;}catch(e){&lt;br /&gt; curr=0;&lt;br /&gt; numrows=0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This code opens an xls file pointed to by the report parameter XLSLocation.  You can hard code the file but this example is a bit more dynamic.  The code then opens the first sheet in the workbook and sets a global JavaScript variable for the number of rows and initializes a current row counter to zero.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-USofWquEaHA/TdvqdCq7yrI/AAAAAAAAAYs/2yzsOQljKJ0/s1600/openevent.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 302px;" src="http://1.bp.blogspot.com/-USofWquEaHA/TdvqdCq7yrI/AAAAAAAAAYs/2yzsOQljKJ0/s400/openevent.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5610335545474140850" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Select the drop down menu and select the fetch event and enter the following code.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( curr &lt; numrows ){&lt;br /&gt;&lt;br /&gt;var cell1 = sheet.getCell(0, curr);&lt;br /&gt;row["col1"] = cell1.getContents();&lt;br /&gt;var cell2 = sheet.getCell(1, curr);&lt;br /&gt;row["col2"] = cell2.getContents();&lt;br /&gt;var cell3 = sheet.getCell(2, curr);&lt;br /&gt;row["col3"] = cell3.getContents();&lt;br /&gt;&lt;br /&gt;curr++&lt;br /&gt;return true;&lt;br /&gt;}else{&lt;br /&gt;return false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The fetch event is fired once per row of data and stops processing when the event returns false.  In this code we are just retrieving the first three columns of the xls sheet and assigning them to the dataset row columns.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-3UuznmAdXxE/TdvqumKWvCI/AAAAAAAAAY0/TzWUU7RoEVo/s1600/fetchevent.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 396px; height: 400px;" src="http://2.bp.blogspot.com/-3UuznmAdXxE/TdvqumKWvCI/AAAAAAAAAY0/TzWUU7RoEVo/s400/fetchevent.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5610335847058947106" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The final event to implement is the close event.  Select close from the drop down box and enter the following code.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( typeof myworkbook != 'undefined'  ){&lt;br /&gt;myworkbook.close();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This code closes the workbook.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-nZI_Ng5Msj0/TdvrHKa2RVI/AAAAAAAAAY8/m22cZohaCIQ/s1600/closeevent.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 351px; height: 400px;" src="http://4.bp.blogspot.com/-nZI_Ng5Msj0/TdvrHKa2RVI/AAAAAAAAAY8/m22cZohaCIQ/s400/closeevent.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5610336269108659538" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You should now be able to preview the dataset.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-AujBEzrXgCY/TdvrPhRAjII/AAAAAAAAAZE/Y9CqcWSrFY0/s1600/preview.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 234px;" src="http://4.bp.blogspot.com/-AujBEzrXgCY/TdvrPhRAjII/AAAAAAAAAZE/Y9CqcWSrFY0/s400/preview.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5610336412680359042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Remember to add the parameter that defines the location of the xls file.  Once the dataset is complete you can construct your BIRT report as usual.  This attached example produces the following report.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-tJXV7ptI1PY/TdvrbnMt_2I/AAAAAAAAAZM/gWJP5_mJK44/s1600/output.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 254px;" src="http://1.bp.blogspot.com/-tJXV7ptI1PY/TdvrbnMt_2I/AAAAAAAAAZM/gWJP5_mJK44/s400/output.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5610336620431408994" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This example is available at &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1366-use-xls-files-as-data-source/"&gt;BIRT-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-5418699715313819684?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/5418699715313819684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=5418699715313819684' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5418699715313819684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5418699715313819684'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/05/birt-using-xls-as-data-source.html' title='BIRT:  Using XLS as a data source'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-yN0fGQ0xf28/TdvpLPuqyMI/AAAAAAAAAYM/cYtkmSh6z1Y/s72-c/resourcefolder.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-6041207817352910438</id><published>2011-04-28T10:23:00.000-07:00</published><updated>2011-04-28T10:39:17.422-07:00</updated><title type='text'>BIRT - Reducing large queries and custom navigation controls</title><content type='html'>Often times when writing a report that requires large amounts of data, the query times become burdensome.  This will lead to dissatisfaction from customers of your report.  To get around this issue certain companies like Actuate implement progressive viewing in their products that start returning formatted data before the report generation process is complete.  This allows users of the report to start getting data long before the total report is completed.  &lt;br /&gt;&lt;br /&gt;Another option is to reduce the large queries into smaller queries and add navigation controls to your report to get the next smaller set of data.  For example, if you have a customer listing report, the first query may return all customers whose name starts with the letter A.  A set of navigation controls could have a next button that returns customers whose name starts with the letter B, etc.  This approach is very simple in BIRT and this post details one way of doing it.&lt;br /&gt;&lt;br /&gt;As an example we can use the classic models sample database that comes with BIRT.  It contains a customers table.  To return all customers starting with A we could use the query select * from customers where customername like ‘A%’.  We want the report to be dynamic, so we will need script to modify the query on the fly.   We can begin by just adding a new datasource that uses the classic models database.  Next we create a dataset with the following query:&lt;br /&gt;&lt;br /&gt;Select * from customers&lt;br /&gt;&lt;br /&gt;The next step is to add a hidden report parameter that we use in script to add a where clause to the query.  In this example the parameter is named “like”.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-0nEk5RL83Jk/TbmjA1FTgYI/AAAAAAAAAXc/BQ_jD85bemE/s1600/likeparameter.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 343px;" src="http://2.bp.blogspot.com/-0nEk5RL83Jk/TbmjA1FTgYI/AAAAAAAAAXc/BQ_jD85bemE/s400/likeparameter.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5600686846256578946" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The parameter is hidden and has a default value of A.  We can now use this parameter in the beforeOpen script of the data set we created earlier.  This script should look like the following:&lt;br /&gt;&lt;br /&gt;this.queryText = this.queryText + " where customername like '" + params["like"].value + "%'";&lt;br /&gt;&lt;br /&gt;This script will change the query every time the report runs and will append the where clause with the hidden report parameter.  The default value for the parameter is A which should list all customers starting with A.  Before adding navigation controls to the report we need to create and calculate some global variables that our controls will need.  Ideally we will add a previous and a next button to the report.  In addition it would also be nice to have a list A-Z that the user could click on to go directly to a set of customers.  So at the minimum when the report runs we need to get the parameter for the report and calculate what the previous and next customer names should start with.  For example if the parameter is C, previous should be B and next should be D.  This can be done with a simple beforeFactory script like:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;switch( params['like'].value ){&lt;br /&gt;case 'A':&lt;br /&gt;prev='Z';&lt;br /&gt;next='B';&lt;br /&gt;break;&lt;br /&gt;&lt;br /&gt;case 'B':&lt;br /&gt;prev='A';&lt;br /&gt;next='C';&lt;br /&gt;break;&lt;br /&gt;&lt;br /&gt;case 'C':&lt;br /&gt;prev='B';&lt;br /&gt;next='D';&lt;br /&gt;break;&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The beforeFactory script is used because it runs before data is retrieved and executes only once.  The BIRT initialize script can be executed multiple times so it is not ideal for this script.  The var keyword is also not used with the variables prev and next which will make them visible to downstream events.  You could also use the reportContext.setGlobalVariable method to do store the variables as well.&lt;br /&gt;&lt;br /&gt;After the table is added to the report you can then add a Text element that contains a script tag to implement your prev and next buttons.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-j_ilrIEIGLM/Tbmjka8HSRI/AAAAAAAAAXk/3Q_ufHnel4k/s1600/textelement.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 231px;" src="http://4.bp.blogspot.com/-j_ilrIEIGLM/Tbmjka8HSRI/AAAAAAAAAXk/3Q_ufHnel4k/s400/textelement.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5600687457713998098" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Remember to set the type to HTML.  The script tag contains a client side script that just reloads the report with a new value for the like parameter.  This function is called nextData and takes the new like value as a parameter.  The text element also contains two buttons that call the nextData function with the prev and next server side javascript variables we calculated in the beforeFactory.  Notice this is done with the VALUE-OF tag.  This tag allows us to combine server side scripting with client side scripting.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;function nextData( a ){&lt;br /&gt;var cl = new String(location.href);&lt;br /&gt;var targetURL = new String();&lt;br /&gt;var tst = cl.indexOf("&amp;like");&lt;br /&gt;if(  tst == -1 ){&lt;br /&gt; cl = cl + "&amp;like=" + a;&lt;br /&gt;}else{&lt;br /&gt; var ch = cl.indexOf("&amp;like=");&lt;br /&gt; cl = cl.substring(0, ch) + "&amp;like=" + a;&lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;window.location = cl;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;input type="button" value="Previous"&lt;br /&gt;onclick="nextData('&amp;lt;VALUE-OF&amp;gt;prev;&amp;lt;/VALUE-OF&amp;gt;')" &amp;gt;&lt;br /&gt;&amp;lt;input type="button" value="Next"&lt;br /&gt;onclick="nextData('&amp;lt;VALUE-OF&amp;gt;next;&amp;lt;/VALUE-OF&amp;gt;')" &amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The last thing we add to the Text element is an Alpha index for all letters of the alphabet.  &lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;br&amp;gt;&lt;br /&gt;&amp;lt;a href="#" onclick="nextData('A');return false"&amp;gt;A&amp;lt;/href&amp;gt;&lt;br /&gt;&amp;lt;a href="#" onclick="nextData('B');return false"&amp;gt;B&amp;lt;/href&amp;gt;&lt;br /&gt;&amp;lt;a href="#" onclick="nextData('C');return false"&amp;gt;C&amp;lt;/href&amp;gt;&lt;br /&gt;&amp;lt;a href="#" onclick="nextData('D');return false"&amp;gt;D&amp;lt;/href&amp;gt;&lt;br /&gt;&amp;lt;a href="#" onclick="nextData('E');return false"&amp;gt;E&amp;lt;/href&amp;gt;&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This allows the user to directly select a letter to use in the like clause.  The output for the report looks like the following.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-vDx27uUtcJI/TbmkeW90TkI/AAAAAAAAAXs/s9-jvDFXIpU/s1600/output.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 270px;" src="http://1.bp.blogspot.com/-vDx27uUtcJI/TbmkeW90TkI/AAAAAAAAAXs/s9-jvDFXIpU/s400/output.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5600688453079813698" /&gt;&lt;/a&gt;&lt;br /&gt;The report also handles the situation when no data is returned.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-h3w9Xqb578U/TbmkpFEtKfI/AAAAAAAAAX0/fH2Nwhtu6gw/s1600/nodata.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 270px;" src="http://1.bp.blogspot.com/-h3w9Xqb578U/TbmkpFEtKfI/AAAAAAAAAX0/fH2Nwhtu6gw/s400/nodata.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5600688637255428594" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The no data label is placed in a grid below the table.  The grid is bound to the table so it uses the same dataset.  The dataset contains an aggregate computed column that counts the number of rows.  This computed column is then used in the grid and the table visibility property.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-sqj58mepdik/Tbmk2PiMF-I/AAAAAAAAAX8/YeebriVoyoM/s1600/aggr.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 183px;" src="http://4.bp.blogspot.com/-sqj58mepdik/Tbmk2PiMF-I/AAAAAAAAAX8/YeebriVoyoM/s400/aggr.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5600688863401744354" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For example the grid visibility is shown below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-435TyAt7CLA/Tbmk9SgH0hI/AAAAAAAAAYE/3K_DvIVljJo/s1600/gridvis.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 215px;" src="http://4.bp.blogspot.com/-435TyAt7CLA/Tbmk9SgH0hI/AAAAAAAAAYE/3K_DvIVljJo/s400/gridvis.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5600688984457466386" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The expression is:&lt;br /&gt;(row["myrowcount"] &gt; 0)&lt;br /&gt;The expression returns true when rows exist.  This will then hide the grid and label.  The opposite condition is used on the table.  &lt;br /&gt;(row["myrowcount"] &lt; 1)&lt;br /&gt;This report is available at &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1359-reducing-large-queries-and-custom-navigation-controls/"&gt;Birt-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-6041207817352910438?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/6041207817352910438/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=6041207817352910438' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6041207817352910438'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6041207817352910438'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/04/birt-reducing-large-queries-and-custom.html' title='BIRT - Reducing large queries and custom navigation controls'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-0nEk5RL83Jk/TbmjA1FTgYI/AAAAAAAAAXc/BQ_jD85bemE/s72-c/likeparameter.png' height='72' width='72'/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-9148990231819489020</id><published>2011-03-30T14:11:00.000-07:00</published><updated>2011-03-30T14:22:40.502-07:00</updated><title type='text'>BIRT Roadshow coming to a city near you.</title><content type='html'>Actuate is continuing the very popular BIRT Road Shows that feature a free day of training on BIRT technologies.  If you are interested, the dates and cities for April and May are listed below.  Slots fill up fast so be sure to register quickly.  More information is available &lt;a href="http://www.birt-exchange.com/be/news-events/resources/?articleid=20190"&gt;here.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;April&lt;/b&gt;&lt;br /&gt;Seattle, WA Tuesday | 4/5&lt;br /&gt;Minneapolis, MN  Wednesday | 4/6 &lt;br /&gt;Indianapolis, IN  Thursday | 4/7    &lt;br /&gt;Philadelphia, PA  Wednesday | 4/13    &lt;br /&gt;&lt;b&gt;May&lt;/b&gt; &lt;br /&gt;Denver, CO Tuesday | 5/3 &lt;br /&gt;Toronto, ON  Wednesday | 5/4  &lt;br /&gt;Princeton, NJ  Tuesday | 5/10  &lt;br /&gt;Orlando, FL  Wednesday | 5/11  &lt;br /&gt;Dallas, TX  Thursday | 5/12  &lt;br /&gt;London, UK  Thursday | 5/19  &lt;br /&gt;Louisville, KY  Tuesday | 5/24   &lt;br /&gt;Washington, DC  Wednesday | 5/25&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-9148990231819489020?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/9148990231819489020/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=9148990231819489020' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/9148990231819489020'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/9148990231819489020'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/03/birt-roadshow-coming-to-city-near-you.html' title='BIRT Roadshow coming to a city near you.'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-6303728123879507596</id><published>2011-03-04T10:25:00.000-08:00</published><updated>2011-03-04T10:39:30.027-08:00</updated><title type='text'>BIRT 2.6.2 Enhancements</title><content type='html'>BIRT 2.6.2 is now available and is a maintenance release with a primary concern on bug fixes.  This generally means not many new features are introduced.  That said a couple of bug fixes merit special attention.  The full list of available fixes can be found &lt;a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced;classification=BIRT;product=BIRT;target_milestone=2.6.2"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;br /&gt;BIRT Pagination and Page Scripts&lt;br /&gt;&lt;/h4&gt;&lt;br /&gt;BIRT 2.5 introduced page variables and page scripts.  These features added the ability to repaginate based on things like a group change.  So in one report output you could add a page variable that showed the page count and current group page number within a group.  The full details for this feature are available in the &lt;a href="http://www.eclipse.org/birt/phoenix/project/notable2.5.php#jump_4"&gt;BIRT 2.5 new and notable&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;While using this feature is very nice, a particular bug caused the scripts not to fire when using a page break interval of 0.  The page break interval is one of the many ways in BIRT to introduce a page break in the output.  It essentially informs the engine to process a certain number of rows and then insert a page break.  If the interval for a table is set to 0, the engine inserts page breaks when all the master page available real-estate is used.  In BIRT 2.6.2 this bug is now fixed, allowing the designer to enter a page break interval of 0 in conjunction with page scripts.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-M9v3IQ9re6E/TXEvECciwjI/AAAAAAAAAW0/XU6KpXnV6Xc/s1600/multipagescripts.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 240px;" src="http://2.bp.blogspot.com/-M9v3IQ9re6E/TXEvECciwjI/AAAAAAAAAW0/XU6KpXnV6Xc/s400/multipagescripts.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5580293159711326770" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The above example can be downloaded from &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1331-page-by-group/"&gt;BIRT-Exchange&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To see some of the pagination bugs that were addressed in 2.6.2 see this &lt;a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced;short_desc=page;short_desc_type=allwordssubstr;target_milestone=2.6.2;classification=BIRT "&gt;bugzilla query&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;br /&gt;URL security bug&lt;br /&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;A security issue with the example Web Viewer was identified which posed a cross-site scripting vulnerability.  The issue has to do with the __report URL parameter.  This parameter specifies the report for the viewer to run.  In previous versions of BIRT a fully qualified URL could be used to specify the report, which allowed the report to reside on a completely different server.  Since BIRT reports can contain JavaScript which runs server side this poses a scripting risk.  The full details for the bug are located &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=336767"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;BIRT 2.6.2 fixes this issue by adding a web.xml entry that allows the developer to control what value can be used in the __report URL parameter.  The entry is named URL_REPORT_PATH_POLICY and has three valid values (all, domain, and none).  If the all value is specified no checks on the URL parameter are performed.  This value should only be used when access to the viewer is restricted to a known user base.  When the none option is used, only local reports to the viewer context for the server are allowed.  When the domain option is used the report can contain a fully qualified URL as long as the domain for the server is the same.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-DEkHw7kITFU/TXEvqc6nRjI/AAAAAAAAAW8/R6vUiKD2xe4/s1600/webxml.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 257px;" src="http://4.bp.blogspot.com/-DEkHw7kITFU/TXEvqc6nRjI/AAAAAAAAAW8/R6vUiKD2xe4/s400/webxml.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5580293819651802674" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you cannot upgrade the viewer, the patch details are available in the bugzilla entry.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;br /&gt;Formatter object&lt;br /&gt;&lt;/h4&gt;&lt;br /&gt;BIRT 2.6.2 now offers a formatter object in the expression builder to format dates, strings and numbers within a given expression.  This function is detailed in the &lt;a href="http://birtworld.blogspot.com/2011/02/birt-formatting-numbers-and-dates.html"&gt;following post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-vPmUqO6Fak0/TXEwCVImo8I/AAAAAAAAAXE/9JM52sOK0-U/s1600/formatter.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 313px;" src="http://3.bp.blogspot.com/-vPmUqO6Fak0/TXEwCVImo8I/AAAAAAAAAXE/9JM52sOK0-U/s400/formatter.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5580294229879858114" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;br /&gt;Radar Chart&lt;br /&gt;&lt;/h4&gt;&lt;br /&gt;The Radar Chart in BIRT was implemented in BIRT 2.6 to function as an example on how to implement your own chart types.  The source for this chart type is available in two of the BIRT plug-ins (org.eclipse.birt.chart.examples and org.eclipse.birt.chart.examples.core).  In BIRT 2.6.2 this chart type has been improved and it now supports rendering multiple series on the same radial within a radar chart.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/--gNvCTFa8E0/TXExKG9zTUI/AAAAAAAAAXM/Q9ji8LTgMWU/s1600/radar.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 336px;" src="http://3.bp.blogspot.com/--gNvCTFa8E0/TXExKG9zTUI/AAAAAAAAAXM/Q9ji8LTgMWU/s400/radar.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5580295463027035458" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The GUI for building the radar chart has also been improved to support a more optimal layout for configuring portions of the chart.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-zSlhnmJNuqo/TXExTM04hEI/AAAAAAAAAXU/43dArioz0aU/s1600/radardesigner.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 370px; height: 400px;" src="http://4.bp.blogspot.com/-zSlhnmJNuqo/TXExTM04hEI/AAAAAAAAAXU/43dArioz0aU/s400/radardesigner.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5580295619219063874" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-6303728123879507596?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/6303728123879507596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=6303728123879507596' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6303728123879507596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6303728123879507596'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/03/birt-262-enhancements.html' title='BIRT 2.6.2 Enhancements'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-M9v3IQ9re6E/TXEvECciwjI/AAAAAAAAAW0/XU6KpXnV6Xc/s72-c/multipagescripts.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-134367304156398577</id><published>2011-02-18T12:46:00.000-08:00</published><updated>2011-02-18T13:04:23.198-08:00</updated><title type='text'>BIRT Formatting numbers and dates</title><content type='html'>BIRT offers many options when formatting data is required.  This post discusses some of the common ways this can be done using the GUI, script and expressions.  &lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;br /&gt;Using the GUI to format data&lt;br /&gt;&lt;/h4&gt;&lt;br /&gt;When formatting the standard Data report item, customizing the format is very simple.  Located within the properties view for the data item are three tabs that allow formatting a number, date, or string.  Which format the data item uses will depend on the data type for the data item as specified in the binding.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-77PPGVRh6EM/TV7bPK2cAxI/AAAAAAAAAV0/XnBEBFbS89Q/s1600/guiformat.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 174px;" src="http://1.bp.blogspot.com/-77PPGVRh6EM/TV7bPK2cAxI/AAAAAAAAAV0/XnBEBFbS89Q/s400/guiformat.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5575134442388456210" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-lY_tjpmha8I/TV7bVh00KgI/AAAAAAAAAV8/9VyBm0eHU6s/s1600/databinding.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 274px;" src="http://3.bp.blogspot.com/-lY_tjpmha8I/TV7bVh00KgI/AAAAAAAAAV8/9VyBm0eHU6s/s400/databinding.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5575134551634881026" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Each of the format tabs provides a set of predefined patterns that can be applied to the data.  In addition, the pattern can be set to custom allowing the developer to define very specific formatting codes.  The formatting operation can be set to a specific locale or auto which will use the locale of the user running the report.  For example, entering ¤###,##0.00 as the pattern for a data item that is going to contain a currency  may produce  €131,44 for the French locale, and $131.44 for a US locale.  For an example of using positive:negative patterns you may want to have a look at this &lt;a href="http://birtworld.blogspot.com/2010/09/format-negative-numbers.html"&gt;post&lt;/a&gt;.  &lt;br /&gt;&lt;br /&gt;Report parameters selections can also be formatted in similar fashion to a Data report item.  Each parameter has a “Format As” selection within the Parameter Editor.  By selecting the change button a standard or custom format can be applied to parameter.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-MXg0tO18LcE/TV7b7_bhHCI/AAAAAAAAAWE/S9K4_0Fcu4s/s1600/parameters.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 384px;" src="http://1.bp.blogspot.com/-MXg0tO18LcE/TV7b7_bhHCI/AAAAAAAAAWE/S9K4_0Fcu4s/s400/parameters.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5575135212416867362" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Formatting labels within the chart builder is also possible.  Most items in a chart that display data have an associated format that can be customized by using the format button.  For example to format a date axis use the GUI as presented below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-ErNPxq9hkqM/TV7cK9p8OuI/AAAAAAAAAWM/ibMFM0o1RaA/s1600/chart.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 243px;" src="http://4.bp.blogspot.com/-ErNPxq9hkqM/TV7cK9p8OuI/AAAAAAAAAWM/ibMFM0o1RaA/s400/chart.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5575135469638531810" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;br /&gt;Formatting Data using the Expression builder or Script&lt;br /&gt;&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;The above formatting solutions work very well, but there are times when you want to mix formatted data within a string.  In this case you can write script, use and expression, or use a Text report item to format the data.  For example assume a report has two dates that are passed as parameters and you want to generate text within the report that shows “Start Date – End Date”.  This is not achievable using the GUI methods described above.  To do this you can use a text item and the value of syntax:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Start Date: &amp;lt;VALUE-OF format="MMM-dd-yy"&amp;gt;params["date1"].value;&amp;lt;/VALUE-OF&amp;gt;&lt;br /&gt;End Date: &amp;lt;VALUE-OF format="MMM-dd-yy"&amp;gt;params["date2"].value;&amp;lt;/VALUE-OF&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-tMpsXoiZlx8/TV7c1FwPRuI/AAAAAAAAAWU/wOFaOjOAnt4/s1600/valueof.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 216px;" src="http://4.bp.blogspot.com/-tMpsXoiZlx8/TV7c1FwPRuI/AAAAAAAAAWU/wOFaOjOAnt4/s400/valueof.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5575136193366935266" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In this example the VALUE-OF syntax is evaluated at runtime of the report and the format attribute is applied to the output.  This approach also works with numbers.  For example, &amp;lt;VALUE-OF format="$#,##0.00"&amp;gt;row[“MyData”];&amp;lt;/VALUE-OF&amp;gt;.  &lt;br /&gt;&lt;br /&gt;This same functionality could have been achieved by using a data item with the following expression.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var mydt1 =params["date1"].value&lt;br /&gt;var mydt2 =params["date2"].value&lt;br /&gt;&lt;br /&gt;importPackage( Packages.java.text );&lt;br /&gt;var sdf = new SimpleDateFormat("MMM d, yyyy", reportContext.getLocale());&lt;br /&gt;var mydtf1 = sdf.format( mydt1 );&lt;br /&gt;var mydtf2 = sdf.format( mydt2 );&lt;br /&gt;"Start Date: " + mydtf1 + " End Date:" + mydtf2&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-n9vaSGWFvQk/TV7dReUP3oI/AAAAAAAAAWc/yzoQPZuoqGs/s1600/importdata.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 356px;" src="http://1.bp.blogspot.com/-n9vaSGWFvQk/TV7dReUP3oI/AAAAAAAAAWc/yzoQPZuoqGs/s400/importdata.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5575136680996757122" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In this example we are just using the imported Java SimpleDateFormat class to do the formatting.&lt;br /&gt;&lt;br /&gt;If you are using BIRT 2.6.2 or higher, you can use the Formatter function within the expression builder to format localized numbers, dates and string as well.  The Formatter function is available within the BIRT Functions Category of the expression builder.  To build the example above, use the following expression in data item.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var mydtf1 = Formatter.format( params["date1"].value,  "MMM d, yyyy");&lt;br /&gt;var mydtf2 = Formatter.format( params["date2"].value,  "MMM d, yyyy");&lt;br /&gt;"Start Date: "+mydtf1 + " End Date " + mydtf2 + BirtDateTime.diffDay(params["date2"], params["date1"]) +" Days";&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/-LZEI0-57SsA/TV7dn5PRgaI/AAAAAAAAAWk/VqW_Mzz1ueY/s1600/formatterexpression.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 306px;" src="http://1.bp.blogspot.com/-LZEI0-57SsA/TV7dn5PRgaI/AAAAAAAAAWk/VqW_Mzz1ueY/s400/formatterexpression.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5575137066180772258" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In this example we have combined the start and end dates with the BirtDateTime.diffDay function to build a string that not only shows the start and end date, but shows the duration of days.&lt;br /&gt;&lt;br /&gt;The Formatter function takes the current locale into account when formatting the element.  If you want to test different locales, either set the preview locale in the preferences or use the __locale parameter in your report URL.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-PMYvtMUNuIw/TV7dxaugzfI/AAAAAAAAAWs/m-2Ru8p_QrY/s1600/preference.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 347px;" src="http://2.bp.blogspot.com/-PMYvtMUNuIw/TV7dxaugzfI/AAAAAAAAAWs/m-2Ru8p_QrY/s400/preference.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5575137229788990962" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As a side note, if you are interested in adding your own functions to the expression builder, see this &lt;a href="http://birtworld.blogspot.com/2008/09/birt-231-adding-functions-to-expression.html"&gt;post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can also import Java classes to manipulate data points within the BIRT or Chart event handlers.  For example to set your own format on an axis label the following script could be used on a chart.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeDrawAxisLabel( axis, label, context )&lt;br /&gt;{&lt;br /&gt; importPackage(Packages.org.eclipse.birt.chart.model.attribute);&lt;br /&gt; importPackage(Packages.java.lang);&lt;br /&gt; importPackage(Packages.java.text);&lt;br /&gt; if( context.getExternalContext().getScriptable().getParameterValue("MyParameter") == "date"){&lt;br /&gt;  if (axis.getType() == AxisType.TEXT_LITERAL)&lt;br /&gt;  {&lt;br /&gt;   value = label.getCaption().getValue();&lt;br /&gt;   var dtf = new SimpleDateFormat("MM/dd/yy");&lt;br /&gt;   var dt = new Date(value);&lt;br /&gt;   var fn = dtf.format(dt);&lt;br /&gt;   label.getCaption().setValue(fn); &lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;As another example, the code below could be placed in a report parameter’s getDefaultValueList event handler to return the current year.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;importPackage( Packages.java.util );&lt;br /&gt;cal = Calendar.getInstance(); &lt;br /&gt;tyear = cal.get(Calendar.YEAR); &lt;br /&gt;tyear;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-134367304156398577?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/134367304156398577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=134367304156398577' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/134367304156398577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/134367304156398577'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/02/birt-formatting-numbers-and-dates.html' title='BIRT Formatting numbers and dates'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-77PPGVRh6EM/TV7bPK2cAxI/AAAAAAAAAV0/XnBEBFbS89Q/s72-c/guiformat.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-3676114809620369558</id><published>2011-01-27T08:52:00.000-08:00</published><updated>2011-01-27T08:54:41.455-08:00</updated><title type='text'>Changing Eclipse BIRT Indigo Version Number to BIRT 3.7</title><content type='html'>For the BIRT project’s Indigo release in June of this year, our plan continues to be to match the BIRT version number with the Eclipse Platform version number used for Indigo. Going forward, this will make it easier for everyone to remember which version of BIRT is designed to work with which version of the Platform. And with Indigo being the 8th major release of the BIRT project, there is no downside with updating the release number to match the Platform release.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;At the outset of the Indigo project, it was an open question whether Indigo would be Eclipse 3.7 or 4.0 – so as a short term measure, we adopted BIRT 4.0 as the working release number for BIRT Indigo. Now that the Indigo release will be designated Eclipse 3.7, we plan to update BIRT Indigo to use the BIRT 3.7 designation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-3676114809620369558?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/3676114809620369558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=3676114809620369558' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3676114809620369558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3676114809620369558'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/01/changing-eclipse-birt-indigo-version.html' title='Changing Eclipse BIRT Indigo Version Number to BIRT 3.7'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-5231832124812329056</id><published>2011-01-14T07:35:00.000-08:00</published><updated>2011-01-14T08:11:43.851-08:00</updated><title type='text'>Building BIRT Based Dashboards</title><content type='html'>If you are using Actuate’s iServer technology, one of the new features for version 11 is the ability to build dashboards using nothing but the browser.  These dashboards can be constructed using open source BIRT reports, portions of a BIRT report, Flash Objects, Google Gadgets, and other web content.  Completed dashboards and gadgets can be shared with others and can be included in other web applications using the Actuate JSAPI.&lt;br /&gt;&lt;br /&gt;To start building a dashboard, select the new tab icon in the Actuate Information Console.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TTBtinluZoI/AAAAAAAAAS8/90I70FuYCZY/s1600/newtab.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 268px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TTBtinluZoI/AAAAAAAAAS8/90I70FuYCZY/s400/newtab.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562065981312755330" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This will create a dashboard canvas as shown below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TTBuAqTE9iI/AAAAAAAAATE/FJqKdfhYk9k/s1600/canvas.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 385px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TTBuAqTE9iI/AAAAAAAAATE/FJqKdfhYk9k/s400/canvas.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562066497435924002" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;By selecting the down arrow icon on the newly created tab, you can share the dashboard, rename it, set the layout or define data that will be used in the dashboard.  Using the Options field will also allow you to set the refresh time for a dashboard.  This can be used to present things like live charts or tables.  The layout option allows you to define how the dashboard is presented.  You can set a columnar option or freeform which allows you to place the gadgets anywhere on the canvas.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TTBuN9tjMFI/AAAAAAAAATM/clWQIZG_F7U/s1600/newtabdown.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 261px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TTBuN9tjMFI/AAAAAAAAATM/clWQIZG_F7U/s400/newtabdown.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562066725985529938" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Dashboard and Gadget Gallery menu items contain previously constructed items that have been shared.  The New Gadget menu contains the Gadgets that can be placed on the canvas.  There are four categories depending on what type of gadget you wish to use: Data Visualization, Data Selection, Report and Extras.&lt;br /&gt;&lt;h3&gt;&lt;br /&gt;Data Visualization Gadgets&lt;br /&gt;&lt;/h3&gt;&lt;br /&gt;The Data Visualization category contains a set of gadgets that can be used to analyze data.  These include a crosstab, a table, and a set of Flash charts.&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TTBv80vZK8I/AAAAAAAAATU/T82vMhjE4b0/s1600/DataVis.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 146px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TTBv80vZK8I/AAAAAAAAATU/T82vMhjE4b0/s400/DataVis.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562068630542822338" /&gt;&lt;/a&gt;&lt;br /&gt;To use one of these gadgets, simply drag it to the canvas below the menu.  For example, dragging the crosstab gadget onto the canvas will launch the Crosstab Builder.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBwLx5eUQI/AAAAAAAAATc/UM6PXVQHeLA/s1600/crosstabbuilder.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 256px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBwLx5eUQI/AAAAAAAAATc/UM6PXVQHeLA/s400/crosstabbuilder.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562068887477833986" /&gt;&lt;/a&gt;&lt;br /&gt;The gadget retrieves its data from a data object or from an on-demand data design.  The data design is essentially a set of BIRT data sources, data sets and data cubes.  This allows you to leverage existing open source BIRT Reports as content for your dashboard.  After assigning the design values for the crosstab you can move the gadget around the canvas to a suitable location.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBwr_jSkVI/AAAAAAAAATk/jE4UO708DMk/s1600/crosstabgadget.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 373px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBwr_jSkVI/AAAAAAAAATk/jE4UO708DMk/s400/crosstabgadget.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562069440898699602" /&gt;&lt;/a&gt;&lt;br /&gt;Placing one of the chart types will launch the Chart Builder, which allows specifying the chart data.&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TTBw98nRhzI/AAAAAAAAATs/e1592HCyJek/s1600/chartbuilder.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 323px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TTBw98nRhzI/AAAAAAAAATs/e1592HCyJek/s400/chartbuilder.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562069749347747634" /&gt;&lt;/a&gt;&lt;br /&gt;Most data visualization gadgets support further customization for filtering and formatting.  In addition the data can be further analyzed by drilling into the data by clicking on actionable fields or by using the Actuate Data Analyzer.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBxN8xiocI/AAAAAAAAAT0/V9p5G0fzBGg/s1600/dataviscomplete.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 212px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBxN8xiocI/AAAAAAAAAT0/V9p5G0fzBGg/s400/dataviscomplete.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562070024268718530" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBxVWuwOMI/AAAAAAAAAT8/tMR93ddV6gI/s1600/analyze.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 289px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBxVWuwOMI/AAAAAAAAAT8/tMR93ddV6gI/s400/analyze.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562070151495432386" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;br /&gt;Data Selection Gadgets&lt;br /&gt;&lt;/h3&gt;&lt;br /&gt;The Data Selection category contains a set of gadgets that present selection able data that can be used to drive other gadgets.  These gadgets include items like lists, combo boxes and calendar selectors.  To use these, just drag the gadget to the canvas and set the data similar to process used for Data Visualization gadgets.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBxqVZobYI/AAAAAAAAAUE/GXRLyPIEZeA/s1600/selectionmenu.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 214px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBxqVZobYI/AAAAAAAAAUE/GXRLyPIEZeA/s400/selectionmenu.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562070511915658626" /&gt;&lt;/a&gt;&lt;br /&gt;Once the gadget is placed you can link it to another gadget by selecting the target gadget and clicking on down arrow in the upper right corner of the gadget and select link.&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TTBx9xQMdsI/AAAAAAAAAUM/Jhrd--AX_7c/s1600/link.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 333px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TTBx9xQMdsI/AAAAAAAAAUM/Jhrd--AX_7c/s400/link.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562070845809784514" /&gt;&lt;/a&gt;&lt;br /&gt;This will launch the link editor where you can set field in the target you wish to link on.&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TTByHXCH3PI/AAAAAAAAAUU/9-3NkOqEKbs/s1600/linkbuilder.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 353px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TTByHXCH3PI/AAAAAAAAAUU/9-3NkOqEKbs/s400/linkbuilder.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562071010570132722" /&gt;&lt;/a&gt;&lt;br /&gt;In this particular example the selector updates the report parameter OrderDate for the Report Gadget.  Once the linking is complete any time the selector is updated the target gadget will get updated with the new value.  Selectors can be linked to multiple gadgets.  For example, in the following screenshot, the product line list selector updates an exploded pie chart and a detail report.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTByX36-lKI/AAAAAAAAAUc/Hl_1atsxP0s/s1600/multi-selector.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 231px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTByX36-lKI/AAAAAAAAAUc/Hl_1atsxP0s/s400/multi-selector.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562071294276441250" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;br /&gt;Report Gadgets&lt;br /&gt;&lt;/h3&gt;&lt;br /&gt;The Report category contains a set of gadgets that handle presenting BIRT report content.  This can include BIRT designs or generated documents, which allows for a cached or on demand design paradigm.  In addition the design or document can be further processed to only display a given object in a report or document.  Finally a parameter gadget allows the user to use a gadget that displays the parameters for a particular report.  This gadget can then be linked to a report gadget, which will be updated when the parameter gadget is changed.&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TTBynJZXM7I/AAAAAAAAAUk/VNuAVHj92hc/s1600/report.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 261px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TTBynJZXM7I/AAAAAAAAAUk/VNuAVHj92hc/s400/report.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562071556665324466" /&gt;&lt;/a&gt;&lt;br /&gt;When dragging these gadgets to the canvas a New Report Gadget dialog will be displayed, this allows you to configure the location and parameters for a given report.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBy8b1QjPI/AAAAAAAAAUs/9uGOqtuWZYg/s1600/reportgadgeteditor.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 241px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBy8b1QjPI/AAAAAAAAAUs/9uGOqtuWZYg/s400/reportgadgeteditor.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562071922391420146" /&gt;&lt;/a&gt;&lt;br /&gt;Using the refresh timer on the dashboard will also allow you to update how often the report is updated.&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TTBzIvlsh9I/AAAAAAAAAU0/foFqwFznBcM/s1600/reportgadetexample.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 395px; height: 400px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TTBzIvlsh9I/AAAAAAAAAU0/foFqwFznBcM/s400/reportgadetexample.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562072133853284306" /&gt;&lt;/a&gt;&lt;br /&gt;The Reportlet gadget allows the user to define a portion of a BIRT report or document to display.  When using these one extra field is available in the New Report Gadget dialog.  The field is the Bookmark field and corresponds with bookmark property for the report item in the BIRT report design.&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TTBzVxdHkJI/AAAAAAAAAU8/XxkSV3Bf0W8/s1600/reportleteditor.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 240px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TTBzVxdHkJI/AAAAAAAAAU8/XxkSV3Bf0W8/s400/reportleteditor.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562072357692477586" /&gt;&lt;/a&gt;&lt;br /&gt;In this example the bookmark Hist is located in the MasterSalesDashboard report design.  The Hist bookmark in the BIRT report design corresponds to a grid report item that contains historic sales data.&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TTBzhvLeNYI/AAAAAAAAAVE/NsBVRLQcNNc/s1600/reportletexample.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 374px; height: 400px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TTBzhvLeNYI/AAAAAAAAAVE/NsBVRLQcNNc/s400/reportletexample.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562072563240023426" /&gt;&lt;/a&gt;&lt;br /&gt;The Parameter gadget functions similarly to the Report and Reportlet gadgets, but only displays the parameter entry dialogs.  Once you have a Parameter gadget and a Report gadget on the same canvas you can link them by editing the Report gadget using the down arrow in the upper right corner of the gadget.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBzwT2QQcI/AAAAAAAAAVM/PEFo_ZtOnqE/s1600/parameteredit.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 358px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTBzwT2QQcI/AAAAAAAAAVM/PEFo_ZtOnqE/s400/parameteredit.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562072813601309122" /&gt;&lt;/a&gt;&lt;br /&gt;In the Edit Report Gadget dialog choose the Parameter Display Setting tab and in the first drop down select Link to Selectors.  For each report parameter use the succeeding drop down menus to link them to the parameter gadget.&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TTBz9jcZHtI/AAAAAAAAAVU/BtVlR-h-4MA/s1600/parameterlink.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 240px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TTBz9jcZHtI/AAAAAAAAAVU/BtVlR-h-4MA/s400/parameterlink.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562073041126104786" /&gt;&lt;/a&gt;&lt;br /&gt;Once this is complete updating the parameter in the Parameter gadget will update the report in the Report gadget.&lt;br /&gt;&lt;h3&gt;&lt;br /&gt;Extras Gadgets&lt;br /&gt;&lt;/h3&gt;&lt;br /&gt;The Extras category contains a set of gadgets that allow you to include images, HTML, customized text, video and Google gadgets in the dashboard.  &lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TTB0MukkViI/AAAAAAAAAVc/TmPI8YtWo54/s1600/extras.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 311px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TTB0MukkViI/AAAAAAAAAVc/TmPI8YtWo54/s400/extras.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562073301811222050" /&gt;&lt;/a&gt;&lt;br /&gt;Each gadget will have a custom dialog for configuring the gadget.  For example the Import Gadget item dialog allows you to specify the location for a Google Gadget.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTB0dcmc8UI/AAAAAAAAAVk/oNWcPz30iyw/s1600/googlegadgetdialog.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 378px; height: 400px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TTB0dcmc8UI/AAAAAAAAAVk/oNWcPz30iyw/s400/googlegadgetdialog.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5562073589045064002" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3&gt;&lt;br /&gt;Conclusion&lt;br /&gt;&lt;/h3&gt;&lt;br /&gt;This post is an overview of the building BIRT based dashboards using Actuate technology.  If you want more details see the &lt;a href="http://www.birt-exchange.com/be/documentation/R11/aic/help/wwhelp/wwhimpl/js/html/wwhelp.htm#href=dashboards/Dash-reports.4.01.html"&gt;help documentation&lt;/a&gt;.  If you want to try out this functionality download it from &lt;a href="http://www.birt-exchange.com/be/downloads/"&gt;BIRT-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-5231832124812329056?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/5231832124812329056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=5231832124812329056' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5231832124812329056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5231832124812329056'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2011/01/building-birt-based-dashboards.html' title='Building BIRT Based Dashboards'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GN1FyT5H8Kg/TTBtinluZoI/AAAAAAAAAS8/90I70FuYCZY/s72-c/newtab.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-4788684346015476703</id><published>2010-12-02T13:03:00.000-08:00</published><updated>2010-12-02T13:13:56.703-08:00</updated><title type='text'>BIRT Background/Watermark Images</title><content type='html'>Back in September I wrote a post about the &lt;a href="http://birtworld.blogspot.com/2010/09/birt-image-report-item.html"&gt;BIRT Image report item&lt;/a&gt;.  In that post I did not say much about creating background or watermarks for BIRT reports.  In this post I will cover a few ways this can be accomplished.&lt;br /&gt;&lt;br /&gt;One of the simplest approaches is to just add your watermark/background image to the resource folder that you have configured in the designer.  Note that you will also need to add the image to the resource folder of the deployed environment.  Once you have the image in the resource folder, select the style icon in the outline view and create a new style.  Set the background image for the new style to the image you added to the resource folder.  Next select the master page tab in the report editor and then right click on the canvas background and apply the new style.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TPgKcg-fjTI/AAAAAAAAASg/SjWTZowOw9c/s1600/backgroundstyle.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 222px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TPgKcg-fjTI/AAAAAAAAASg/SjWTZowOw9c/s400/backgroundstyle.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5546194426111429938" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The watermark can also be made to be dynamic.  For example assume you want one watermark for pdf output and one for html.  To do this you could add the second watermark to your resource folder and then use the following beforeFactory script to swap the image.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( reportContext.getHttpServletRequest().getParameter("__format") == "pdf" ){&lt;br /&gt;reportContext.getDesignHandle().findStyle("BackgroundStyle").backgroundImage = "watermarkpdf.png";&lt;br /&gt;}else{&lt;br /&gt;reportContext.getDesignHandle().findStyle("BackgroundStyle").backgroundImage = "watermarkhtml.png";&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;There is one drawback when using this approach.  Master page content is always created in the generation phase of the BIRT pipeline, which means if you use the BIRT Viewer and export the report to another format the above code will not work.  This is because the frameset mapping in the Viewer generates an rptdocument that can be rendered in additional formats without the need to re-execute the report.  If the report is not re-executed the master page background image cannot be changed.  &lt;br /&gt;&lt;br /&gt;Another option which will facilitate exporting the report is to use a grid item instead of the master page for the watermark.  For example assume there is one table in the report design.  You can add a grid to the report that has one column and one cell.  Set the height for the grid to be the size of your page (eg 11 in).  Drag the table into the cell.  Select the grid row and apply your background style.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TPgK7KMJlvI/AAAAAAAAASo/yytgFHsA1bk/s1600/gridrowbackgroundstyle.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 258px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TPgK7KMJlvI/AAAAAAAAASo/yytgFHsA1bk/s400/gridrowbackgroundstyle.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5546194952570640114" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Using the following onRender script of the grid row will allow you to change the style image at render time.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( reportContext.getHttpServletRequest().getParameter("__format") == "pdf" ){&lt;br /&gt;this.getStyle().backgroundImage = "watermarkpdf.png";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TPgLKr4PLKI/AAAAAAAAASw/o0hAZPmKNoM/s1600/exportpdf.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 222px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TPgLKr4PLKI/AAAAAAAAASw/o0hAZPmKNoM/s400/exportpdf.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5546195219311963298" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The examples used in this post are available on &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1292-watermark-examples/"&gt;Birt-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-4788684346015476703?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/4788684346015476703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=4788684346015476703' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/4788684346015476703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/4788684346015476703'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/12/birt-backgroundwatermark-images.html' title='BIRT Background/Watermark Images'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GN1FyT5H8Kg/TPgKcg-fjTI/AAAAAAAAASg/SjWTZowOw9c/s72-c/backgroundstyle.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-5930921369017306331</id><published>2010-11-29T20:35:00.000-08:00</published><updated>2010-11-29T20:35:45.959-08:00</updated><title type='text'>Last Day For EclipseCon Submissions</title><content type='html'>Tuesday is the last day for &lt;a href="http://www.eclipsecon.org/2011/submissions/"&gt;EclipseCon submissions&lt;/a&gt;. &amp;nbsp;This is a great time for all of you to share your experiences working with BIRT.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-5930921369017306331?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/5930921369017306331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=5930921369017306331' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5930921369017306331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5930921369017306331'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/11/last-day-for-eclipsecon-submissions.html' title='Last Day For EclipseCon Submissions'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-2948928985178920735</id><published>2010-10-21T12:45:00.001-07:00</published><updated>2010-10-21T13:02:38.178-07:00</updated><title type='text'>BIRT Duplicate Rows</title><content type='html'>Currently BIRT supports suppressing duplicate columns values.  To do this you can select the table column and in the general properties click the Suppress duplicates checkbox.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TMCYf8e1eJI/AAAAAAAAARg/2mh8S4Wm_5w/s1600/suppressduplicates.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 249px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TMCYf8e1eJI/AAAAAAAAARg/2mh8S4Wm_5w/s400/suppressduplicates.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5530588016989796498" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This will have an effect similar to the following image.&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TMCYn78dkpI/AAAAAAAAARo/yaEr4NC5kzI/s1600/effect1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 217px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TMCYn78dkpI/AAAAAAAAARo/yaEr4NC5kzI/s400/effect1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5530588154284577426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You will notice that the number of rows generated in the table has not changed, but no order number is repeated.  If your table does contain duplicate rows, meaning each column in the table has the same data as the row before and you suppress duplicates on each column, the number of rows displayed by BIRT will be reduced.  For example assume your table is tied to a dataset that has two columns and every row contains the same data.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TMCY3QpyAeI/AAAAAAAAARw/hSU1-uLjmd4/s1600/samedataset.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 250px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TMCY3QpyAeI/AAAAAAAAARw/hSU1-uLjmd4/s400/samedataset.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5530588417541407202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If this dataset is bound to a table and both columns are set to suppress duplicates the following will be displayed.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TMCZBJ75jFI/AAAAAAAAAR4/qTTWx0G-2es/s1600/samedatasetout.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 219px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TMCZBJ75jFI/AAAAAAAAAR4/qTTWx0G-2es/s400/samedatasetout.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5530588587537042514" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The actual number of rows is not reduced but the table only shows the value for one row.  In the generated HTML a TR element is created for each empty row with empty values.  If you use this approach make sure to set the padding on the table row, cell, and data items to 0 or you will get unwanted space for empty rows.  It is also important to realize that these empty rows are counted if you are use the page break interval property to handle page breaks.  As a side note, when dealing with duplicate rows it is often better to allow the database to handle culling repeated rows, but in some cases like flat file data sources this may not be an option.&lt;br /&gt;&lt;br /&gt;Another option that can be used to hide duplicate rows is scripting and a visibility expression.  &lt;br /&gt;&lt;br /&gt;Assume we have a table that shows order numbers.  If we only want a particular order number to be shown once, we obviously could use a distinct on the query.  If that is not an option you can use a script and a visibility expression to implement this requirement.  On the table row’s onCreate method you could enter a script like:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var rowLast = this.getRowData().getColumnValue("ORDERNUMBER");&lt;br /&gt;reportContext.setGlobalVariable("rl", rowLast);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;And a visibility expression like:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( row["ORDERNUMBER"] == reportContext.getGlobalVariable("rl") ){&lt;br /&gt;true;&lt;br /&gt;}else{&lt;br /&gt;false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This will cause the BIRT engine to only show the row if its current row order number is different from the previous row.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TMCZnb8-cEI/AAAAAAAAASA/uKuvo9y08hc/s1600/scriptsuppress.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 225px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TMCZnb8-cEI/AAAAAAAAASA/uKuvo9y08hc/s400/scriptsuppress.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5530589245208424514" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As with the previous examples and all visibility operations the underlying data is not altered.  It is just not displayed.  For example if you hide a table the dataset still executes.  If you want to alter the underlying data you will need to filter the data either on the table or the actual dataset.  This can be difficult when trying to get a rows previous value so I created a simple aggregate extension Plugin that will do this for you.  It is based on Scott’s post on &lt;a href="http://birtworld.blogspot.com/2006/09/optimistic-sums.html"&gt;Optimistic sums&lt;/a&gt;.  The extension point has been revised slightly since that post so take a look at the attached examples to see the source code.  The extension point adds a previous value aggregate function to BIRT.  To use it you can create a computed column on the dataset.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TMCZ57LYHtI/AAAAAAAAASI/r8Uxz0hvf3w/s1600/prevvalaggr.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 224px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TMCZ57LYHtI/AAAAAAAAASI/r8Uxz0hvf3w/s400/prevvalaggr.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5530589562827972306" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The function stores the last row value as entered in the Column expression.  Once the computed column is added to the dataset you can then select the filters tab and enter a filter like:&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TMCaCNzDs3I/AAAAAAAAASQ/HL7vIrNXVMc/s1600/prevalfilter.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 265px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TMCaCNzDs3I/AAAAAAAAASQ/HL7vIrNXVMc/s400/prevalfilter.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5530589705265197938" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This will filter the dataset as shown below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TMCaPhyT1lI/AAAAAAAAASY/NU0YGEvnIXI/s1600/previewdataset.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 170px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TMCaPhyT1lI/AAAAAAAAASY/NU0YGEvnIXI/s400/previewdataset.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5530589933969069650" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The source for this post is available at &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1271-birt-duplicate-rows/"&gt;Birt-Exchange&lt;/a&gt;.  The download contains two reports (one that uses the aggregate function and one that was demonstrated earlier in the post), the exported new aggregate plugin, and a source project for the plugin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-2948928985178920735?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/2948928985178920735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=2948928985178920735' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/2948928985178920735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/2948928985178920735'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/10/birt-duplicate-rows.html' title='BIRT Duplicate Rows'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GN1FyT5H8Kg/TMCYf8e1eJI/AAAAAAAAARg/2mh8S4Wm_5w/s72-c/suppressduplicates.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-1102303324358467556</id><published>2010-10-15T10:39:00.000-07:00</published><updated>2010-10-15T11:32:41.814-07:00</updated><title type='text'>BIRT Java Object Data Type</title><content type='html'>In addition to simple data types BIRT also supports a Java Object Data type.  This type can be useful when writing reports that use scripted data sources that consume POJOs that contain a member object.  For example assume you have an array of objects and each of these objects contains three member variables (a String, an Integer, and an Object).  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TLiSESkhD8I/AAAAAAAAAQg/VuXhTgrRo1s/s1600/example.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 373px; height: 400px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TLiSESkhD8I/AAAAAAAAAQg/VuXhTgrRo1s/s400/example.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5528329144999415746" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Before BIRT supported the Java Object data type you could write a scripted data source that iterated the array and assigned a row variable for the string member and another for the integer variable.  If you wanted to use the Object member you would need to call some method on the object that returned a BIRT primitive type.  While this is generally not a drawback with a simple table, if you wanted to nest tables and use the inner object in another dataset, scripting this became very complex.   Using the Java Object data type now makes this much easier.  The only caveat to using the Java Object data type is that the object must be serializable.  The reason for this is that BIRT caches datasets and the object will be cached just like any other column value.&lt;br /&gt;&lt;br /&gt;To illustrate using the Java Object type, consider the following classes.  The BIRTOuterJavaObject contains string, integer, and object member variables.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package test.birt.javaobject;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;&lt;br /&gt;public class BIRTOuterJavaObject implements Serializable {&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; private static final long serialVersionUID = 6530113212317618087L;&lt;br /&gt; private String outerstring;&lt;br /&gt; private int outerint;&lt;br /&gt; private BIRTInnerJavaObject innerobj;&lt;br /&gt;&lt;br /&gt; public String getOuterstring() {&lt;br /&gt;  return outerstring;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setOuterstring(String outerstring) {&lt;br /&gt;  this.outerstring = outerstring;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public int getOuterint() {&lt;br /&gt;  return outerint;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setOuterint(int outerint) {&lt;br /&gt;  this.outerint = outerint;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public BIRTInnerJavaObject getInnerobj() {&lt;br /&gt;  return innerobj;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setInnerobj(BIRTInnerJavaObject innerobj) {&lt;br /&gt;  this.innerobj = innerobj;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public BIRTOuterJavaObject() {&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The BIRTInnerJavaObject is just a sample object that stores information about an automobile.  It contains three member variables which are all strings.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package test.birt.javaobject;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;&lt;br /&gt;public class BIRTInnerJavaObject implements Serializable {&lt;br /&gt;&lt;br /&gt; private static final long serialVersionUID = -4509250036928470517L;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; private String make;&lt;br /&gt; private String model;&lt;br /&gt; private String year;&lt;br /&gt; public String getMake() {&lt;br /&gt;  return make;&lt;br /&gt; }&lt;br /&gt; public void setMake(String make) {&lt;br /&gt;  this.make = make;&lt;br /&gt; }&lt;br /&gt; public String getModel() {&lt;br /&gt;  return model;&lt;br /&gt; }&lt;br /&gt; public void setModel(String model) {&lt;br /&gt;  this.model = model;&lt;br /&gt; }&lt;br /&gt; public String getYear() {&lt;br /&gt;  return year;&lt;br /&gt; }&lt;br /&gt; public void setYear(String year) {&lt;br /&gt;  this.year = year;&lt;br /&gt; }&lt;br /&gt; public BIRTInnerJavaObject() {&lt;br /&gt; this.year = "2009";&lt;br /&gt; this.make = "Chevrolet";&lt;br /&gt; this.model = "Corvette";&lt;br /&gt; }&lt;br /&gt; public String toString(){&lt;br /&gt;  return "Make:--"+this.make+" Model:--"+this.model+" Year:--"+this.year;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The BIRTRow class sets up the array of objects that will be used in the report.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package test.birt.javaobject;&lt;br /&gt;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;&lt;br /&gt;public class BIRTRow {&lt;br /&gt; &lt;br /&gt; private ArrayList rows = null;&lt;br /&gt; &lt;br /&gt; public BIRTRow() {&lt;br /&gt;  rows = new ArrayList();&lt;br /&gt;  rows.clear();&lt;br /&gt; }&lt;br /&gt; public void setupRows(){&lt;br /&gt;  &lt;br /&gt;  BIRTOuterJavaObject row1o = new BIRTOuterJavaObject();&lt;br /&gt;  BIRTOuterJavaObject row2o = new BIRTOuterJavaObject();&lt;br /&gt;  BIRTOuterJavaObject row3o = new BIRTOuterJavaObject();&lt;br /&gt;  &lt;br /&gt;  BIRTInnerJavaObject row1i = new BIRTInnerJavaObject();&lt;br /&gt;  BIRTInnerJavaObject row2i = new BIRTInnerJavaObject();&lt;br /&gt;  BIRTInnerJavaObject row3i = new BIRTInnerJavaObject();&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  row1i.setMake("Toyota");&lt;br /&gt;  row1i.setModel("Land Cuiser");&lt;br /&gt;  row1i.setYear("2008");&lt;br /&gt;  row1o.setOuterint(1);&lt;br /&gt;  row1o.setOuterstring("Outer Row 1 String");&lt;br /&gt;  row1o.setInnerobj(row1i);&lt;br /&gt;  rows.add(row1o);&lt;br /&gt;  &lt;br /&gt;  row2i.setMake("Jeep");&lt;br /&gt;  row2i.setModel("Cherokee");&lt;br /&gt;  row2i.setYear("2002");&lt;br /&gt;  row2o.setOuterint(2);&lt;br /&gt;  row2o.setOuterstring("Outer Row 2 String");&lt;br /&gt;  row2o.setInnerobj(row2i);&lt;br /&gt;  rows.add(row2o);&lt;br /&gt;  &lt;br /&gt;  row3i.setMake("Land Rover");&lt;br /&gt;  row3i.setModel("LR3");&lt;br /&gt;  row3i.setYear("2006");&lt;br /&gt;  row3o.setOuterint(3);&lt;br /&gt;  row3o.setOuterstring("Outer Row 3 String");&lt;br /&gt;  row3o.setInnerobj(row3i);&lt;br /&gt;  rows.add(row3o);&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; public ArrayList getRows(){&lt;br /&gt;  return rows;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The primary goal of the example is to nest two tables.  The outer table will have three columns.  One column for each of the member variables of the outer object(BIRTOuterJavaObject).  The Inner BIRT table will contain three columns as well, one for each of the member variables of the inner object(BIRTInnerJavaObject).  Note that in this example the inner object could have contained a list of objects but for simplicity it only contains one object. Because the inner dataset will only return one row of data the example could have been completed using just one data set.   So the report will contain two datasets one for the outer object and one for the inner object.  The inner object dataset will be parameterized so that when we nest the inner table it can get the object from the outer dataset.  The inner dataset will only return one row of data.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TLiTDN6-cCI/AAAAAAAAAQo/FLAXyaiMXFg/s1600/tabledesign.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 123px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TLiTDN6-cCI/AAAAAAAAAQo/FLAXyaiMXFg/s400/tabledesign.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5528330226083196962" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The outer dataset scripted data set code is as follows:&lt;br /&gt;Open Method:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;importPackage(Packages.test.birt.javaobject);&lt;br /&gt;myrows = new BIRTRow();&lt;br /&gt;myrows.setupRows();&lt;br /&gt;rowsiter = myrows.getRows().iterator();&lt;br /&gt;icnt = 0;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The open method sets up the array of objects and gets an iterator for the list.&lt;br /&gt;Fetch Method:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( rowsiter.hasNext() )&lt;br /&gt;{&lt;br /&gt;var obj = rowsiter.next();&lt;br /&gt;row["OuterString"] = obj.getOuterstring();&lt;br /&gt;row["OuterInt"] = obj.getOuterint();&lt;br /&gt;row["InnerObj"] = obj.getInnerobj();&lt;br /&gt;icnt++;&lt;br /&gt;return true;&lt;br /&gt;} else {&lt;br /&gt;return false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The fetch method iterates over each of the outer objects and assigns the column values.  Note that the InnerObj column is of type Java Object and will be an instance of BIRTInnerJavaObject.&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TLiTlS-h4OI/AAAAAAAAAQw/i8w9WBEBmEQ/s1600/outercols.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 150px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TLiTlS-h4OI/AAAAAAAAAQw/i8w9WBEBmEQ/s400/outercols.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5528330811555832034" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The inner dataset has three string columns.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TLiTwWfekmI/AAAAAAAAAQ4/AsG5_D2HkGk/s1600/innercols.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 145px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TLiTwWfekmI/AAAAAAAAAQ4/AsG5_D2HkGk/s400/innercols.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5528331001477894754" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The inner dataset also has a parameter that we will set when the table is nested.  The parameter is named JavaObjectParam and its default value is set to null.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TLiT6A2Q-gI/AAAAAAAAARA/sUXsAKuwcAI/s1600/innerparam.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 145px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TLiT6A2Q-gI/AAAAAAAAARA/sUXsAKuwcAI/s400/innerparam.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5528331167466584578" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The inner data set code is as follows:&lt;br /&gt;&lt;br /&gt;Open method:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;importPackage(Packages.test.birt.javaobject);&lt;br /&gt;if( inputParams["JavaObjectParam"] == null ){&lt;br /&gt;icnt=1;&lt;br /&gt;}else{&lt;br /&gt;icnt=0;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The open method just checks to see if the dataset parameter is set.  If the parameter is null the dataset will not return any rows.  If the parameter is set the dataset will only return one row which is an instance of BIRTInnerJavaObject.&lt;br /&gt;&lt;br /&gt;Fetch Method:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( icnt &gt; 0 )return false&lt;br /&gt;var obj = inputParams["JavaObjectParam"];&lt;br /&gt;row["Make"] = obj.getMake();&lt;br /&gt;row["Model"] = obj.getModel();&lt;br /&gt;row["Year"] = obj.getYear();&lt;br /&gt;icnt++;&lt;br /&gt;return true;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In the fetch method we get the object from the parameter and call the getter methods for the object and assign them to the column values.&lt;br /&gt;&lt;br /&gt;Once both datasets are created, you can drag the outer dataset to the report canvas which will create the first table.  Next add a column to the first table and drag the second dataset to the new column which should create the second (nested) table.  To make the inner table work properly the dataset parameter has to be bound to the outer tables InnerObj column.  To do this select the inner table and click the binding tab in the properties view.  Click the data set parameter binding button and set the value of the dataset parameter to row[“InnerObj”].&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TLiUmSJu24I/AAAAAAAAARI/ABVLyosE5XQ/s1600/parmbinding.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 232px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TLiUmSJu24I/AAAAAAAAARI/ABVLyosE5XQ/s400/parmbinding.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5528331928025881474" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Java Object Data type can also be consumed by a chart.  Continuing with this example if you add a chart and bind it to the outer dataset you can specify getter methods for the series, categories, optional grouping, tooltip help, etc.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TLiUwJphSoI/AAAAAAAAARQ/29yfVdHYBlg/s1600/chartdesign.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 376px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TLiUwJphSoI/AAAAAAAAARQ/29yfVdHYBlg/s400/chartdesign.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5528332097541982850" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The completed report should have similar output to the following.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TLiU5m5aHII/AAAAAAAAARY/o7-6aZ7qZP0/s1600/output.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 235px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TLiU5m5aHII/AAAAAAAAARY/o7-6aZ7qZP0/s400/output.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5528332260012072066" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This example is available at &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1267-example-scripted-data-source-using-java-object-data-type/"&gt;BIRT-Exchange &lt;/a&gt;as two projects.  One Java project and one BIRT Report project.  To run the example import both projects to your workspace, open the BirtJavaObjectReport.rptdesign and preview the report.&lt;br /&gt;&lt;br /&gt;If you are using Actuate BIRT 11, The Java Object data type can be used in conjunction with the new POJO ODA data source that allows the Report Designer to access and report off of POJO’s using a GUI designer.   If you are interested in this approach take a look at this &lt;a href="http://www.birt-exchange.org/org/forum/index.php/blog/3/entry-173-still-using-scripted-data-source-for-your-pojos/"&gt;blog post&lt;/a&gt; and this &lt;a href="http://download.birt-exchange.com/products/demos/birt/PojoDataSource/PojoDataSource.html "&gt;video &lt;/a&gt;that show the driver in action.  An example of using this new data source is available on &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1268-birt-pojo-data-source-example/"&gt;BIRT-Exchange&lt;/a&gt; and you can try out Acutate BIRT 11 by downloading it &lt;a href="http://www.birt-exchange.com/be/downloads/"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-1102303324358467556?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/1102303324358467556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=1102303324358467556' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1102303324358467556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1102303324358467556'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/10/birt-java-object-data-type.html' title='BIRT Java Object Data Type'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GN1FyT5H8Kg/TLiSESkhD8I/AAAAAAAAAQg/VuXhTgrRo1s/s72-c/example.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-8264028827012951744</id><published>2010-09-22T13:57:00.000-07:00</published><updated>2010-09-22T13:58:31.702-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='format'/><title type='text'>Format Negative Numbers</title><content type='html'>Just a simple little tip this week.  I wanted to format numeric data with a custom format.  I wanted positive numbers to look like this relatively standard format&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;1,233.00&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But I also wanted negative numbers to show up like:&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;1,245.00 - &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;With the negative sign showing to the right of the number.&amp;nbsp; &lt;br /&gt;&lt;br /&gt;At first this was a &amp;nbsp;this is a bit of a problem. &amp;nbsp;I figured out a way to do it using OnRender script, but it was kind of ugly. &amp;nbsp;Turns out the solution is quite a bit more simple. BIRT is using the java &lt;a href="http://download-llnw.oracle.com/javase/1.5.0/docs/api/java/text/DecimalFormat.html"&gt;DecimalFormat&lt;/a&gt;&amp;nbsp;for numeric data in the CustomFormat. &amp;nbsp;One of the accepted patterns for DecimalFormat is in the form of&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;&lt;i&gt;PositivePattern&lt;/i&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt; ; &lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: monospace; white-space: pre;"&gt;&lt;i&gt;NegativePattern&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;So all you need to do is select Custom Format and enter the format as (see below)&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="white-space: normal;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;i&gt; &lt;/i&gt;#,##0.00; #,###.00 -&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;pre&gt;&lt;/pre&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_5bQPsXqbEM4/TJpsyHwkeKI/AAAAAAAAA2c/iF68FsUe-gA/s1600/number_format.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="396" src="http://2.bp.blogspot.com/_5bQPsXqbEM4/TJpsyHwkeKI/AAAAAAAAA2c/iF68FsUe-gA/s640/number_format.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-8264028827012951744?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/8264028827012951744/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=8264028827012951744' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/8264028827012951744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/8264028827012951744'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/09/format-negative-numbers.html' title='Format Negative Numbers'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_5bQPsXqbEM4/TJpsyHwkeKI/AAAAAAAAA2c/iF68FsUe-gA/s72-c/number_format.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-1734030328880392871</id><published>2010-09-13T18:20:00.000-07:00</published><updated>2010-09-13T18:20:49.344-07:00</updated><title type='text'>Open Source Reporting Comparison - BIRT vs. Pentaho vs. Jasper</title><content type='html'>&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;This is a post by Scott Rosenbaum of&amp;nbsp;&lt;/span&gt;&lt;a href="http://www.innoventsolutions.com/"&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Innovent Solutions&lt;/span&gt;&lt;/a&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;. It does not necessarily reflect the view of any of the other BIRT project members.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;One of the things that I often get asked is how does BIRT compare to&amp;nbsp;&lt;b&gt;BrandX&lt;/b&gt;? For the last six years, I have been&amp;nbsp;creating solutions using BIRT, so the easy answer would be &lt;i&gt;just use BIRT&lt;/i&gt;. Unfortunately it is not that simple. &lt;br /&gt;Innovent Solutions' corporate goal is &lt;b&gt;Enabling Intelligent Decisions&lt;/b&gt;&lt;sup&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;®&lt;/span&gt;&lt;/sup&gt;&amp;nbsp;and we use a variety of commercial and open source tools to achieve that goal. Over the last fifteen years, experience has taught us:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Analysis, communication, and project management are the keys to BI and reporting success&lt;/li&gt;&lt;li&gt;Any sufficiently mature technology can be successful in the right situation&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;So how does BIRT compare to&amp;nbsp;BrandX? requires a bit more than&amp;nbsp;&lt;i&gt;just use BIRT&lt;/i&gt;.  Most of the answer depends on the business issue that we are trying to solve. But we also have to evaluate if BrandX has reached the point of being sufficiently mature.&lt;/div&gt;&lt;div&gt;Over the last three years three open source business intelligence and reporting projects have emerged as leaders. BIRT, JasperReports, and Pentaho dominate the open source business intelligence and reporting space. In my opinion, BIRT reached the minimum maturity level with its 2.2 release in 2007, since then the product has continued to mature through three annual releases (2.3, 2.5, 2.6).&lt;/div&gt;&lt;div&gt;So what about Jasper and Pentaho, how do their features compare to BIRT, and are they sufficiently mature? In an effort to come up with a better answer, Innovent Solutions has conducted a &lt;a href="http://www.innoventsolutions.com/open-source-reporting-comparison.html"&gt;product comparison&lt;/a&gt;&amp;nbsp;of the open source report development tools from each project.&amp;nbsp;&lt;/div&gt;&lt;div&gt;The full evaluation is available on the&amp;nbsp;the Innovent Solutions web site (free, no registration). The starting point for the product comparison can be found at&amp;nbsp;&lt;a href="http://www.innoventsolutions.com/open-source-reporting-comparison.html"&gt;Product Comparison Overview&lt;/a&gt;. If you are interested in specific comparisons, we have one for&amp;nbsp;&lt;a href="http://www.innoventsolutions.com/birt-vs-jasper.html"&gt;BIRT versus Jasper&lt;/a&gt;&amp;nbsp;and another for&amp;nbsp;&lt;a href="http://www.innoventsolutions.com/birt-vs-pentaho.html"&gt;BIRT versus Pentaho&lt;/a&gt;. We also created a side by side feature comparison the&amp;nbsp;&lt;a href="http://www.innoventsolutions.com/birt-jasper-pentaho-comparison-matrix.html"&gt;Open Source Comparison Matrix (BIRT, Jasper, Pentaho)&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;div&gt;NOTE: I would love to hear what you think of the Innovent comparison, but I would like to keep the focus of this blog on BIRT. For this reason I have turned off comments for this post. Comments about the comparison should be made from the&amp;nbsp;&lt;a href="http://www.innoventsolutions.com/open-source-reporting-comparison.html"&gt;Product Comparison Overiew&lt;/a&gt;&amp;nbsp;page on the Innovent Solutions web site.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-1734030328880392871?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1734030328880392871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1734030328880392871'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/09/open-source-reporting-comparison-birt.html' title='Open Source Reporting Comparison - BIRT vs. Pentaho vs. Jasper'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-6111391226239927676</id><published>2010-09-08T09:31:00.000-07:00</published><updated>2010-09-08T09:44:52.503-07:00</updated><title type='text'>Beyond BIRT Basics - Roadshow</title><content type='html'>The advanced BIRT Roadshows will begin next week in Boston, New York and DC.&lt;br /&gt;These events feature a free day of training on advanced BIRT topics, like understanding the event model, chart and report item scripting, implementing high performance reports, and making BIRT mobile. &lt;br /&gt;&lt;br /&gt;The schedule for the month of September is listed below.&lt;br /&gt;&lt;br /&gt;Upcoming Accelerated BIRT Roadshows&lt;br /&gt;Boston – Tuesday, September 14&lt;br /&gt;New York – Wednesday, September 15&lt;br /&gt;DC – Thursday, September 16&lt;br /&gt;Bay Area – Tuesday, September 28&lt;br /&gt;&lt;br /&gt;If you are interested, &lt;a href="http://www.birt-exchange.com/be/news-events/resources/?articleid=20191"&gt;sign up quickly&lt;/a&gt;, as space is limited.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-6111391226239927676?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.birt-exchange.com/be/news-events/resources/?articleid=20191' title='Beyond BIRT Basics - Roadshow'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/6111391226239927676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=6111391226239927676' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6111391226239927676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6111391226239927676'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/09/beyond-birt-basics-roadshow.html' title='Beyond BIRT Basics - Roadshow'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-1124913252605750277</id><published>2010-09-02T07:10:00.000-07:00</published><updated>2010-09-02T07:38:13.394-07:00</updated><title type='text'>BIRT Image - Report Item</title><content type='html'>BIRT has many ways to include images within a report.  Images can be used in BIRT styles, as watermarks, in text elements, and placed within the report using an image report item.  In this post I will cover some of the details needed to work with images that are inserted using the Image report item. &lt;br /&gt; &lt;br /&gt;The image report item can retrieve images in four different ways.  1 -Through a URI, 2 – as an image in the resource folder, 3 – as an embedded image, 4 -or by using a dynamic image.  Each of these methods is described below with examples.  In addition some of the examples use onCreate scripts written in JavaScript.  While these examples use JavaScript, they could also have been written in Java.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TH-wusVg6aI/AAAAAAAAAP4/-hYccM6JXKI/s1600/palette.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 262px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TH-wusVg6aI/AAAAAAAAAP4/-hYccM6JXKI/s400/palette.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5512318785146644898" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;URI Images&lt;/em&gt;&lt;br /&gt;The first way is to retrieve an image with the image report item is to use a URI specification.  This method is pretty straight forward and the value can be entered as a constant or as a JavaScript expression.  Constants are processed faster by the engine but are harder to make dynamic.  An example of a constant expression for a URI image would be as follows:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;http://www.eclipse.org/eclipse.org-common/themes/Nova/images/eclipse.png  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Note: Do not put quotes around the expression unless JavaScript Syntax is selected.  An example of using a JavaScript expression is presented below.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( params["dynamicimage"].value == true ){&lt;br /&gt;"http://www.google.com/intl/en_ALL/images/srpr/logo1w.png";&lt;br /&gt;}else{&lt;br /&gt;"http://www.eclipse.org/eclipse.org-common/themes/Nova/images/eclipse.png";&lt;br /&gt;}&lt;br /&gt;This expression checks the value of the dynamicimage report parameter, and then based on its value, sets the value of the URI.&lt;br /&gt;The URI can also be set using an onCreate event handler for the image report item.  The syntax for this approach would look like:&lt;br /&gt;this.URI = "http://tomcat.apache.org/images/tomcat.gif";&lt;br /&gt;&lt;br /&gt;//for a local file use: &lt;br /&gt;//this.URI = "file://C:/test/birtlogo.png";  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;em&gt;Resource Folder Images&lt;/em&gt;&lt;br /&gt;BIRT uses a resource folder for storing report libraries, style sheets, images, jars, js files, properties files or virtually any file that you will need access to at runtime.  While in the design environment the resource folder location can be set using the Windows-&gt;Preferences-&gt;Report Design-&gt;Resource setting.  This can be set for the entire workspace or on a per project basis.  At runtime you can set the resource folder in the web.xml if you are using the viewer.  If you are using the engine API you can set the resource folder using the  EngineConfig class’ setResourcePath method.   When using a resource folder image, all that is needed is to specify the image name as it is defined in the resource folder.  You can also set a JavaScript expression for the image name.  For example:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( row["QUANTITYORDERED"] &gt; 30 ){&lt;br /&gt;"green.png";&lt;br /&gt;}else if( row["QUANTITYORDERED"] &gt; 25  &amp;&amp; row["QUANTITYORDERED"] &lt;= 30){&lt;br /&gt;"yellow.png";&lt;br /&gt;}else{&lt;br /&gt;"red.png";&lt;br /&gt;}  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This expression checks the row data to determine which resource folder image should be rendered.  The same type of checks can be made if you are using the onCreate script event for the image element.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var myqty = this.getRowData().getColumnValue("QUANTITYORDERED");&lt;br /&gt;if( myqty &gt; 30 ){&lt;br /&gt; this.file = "green.png";&lt;br /&gt;}else if( myqty &gt; 25  &amp;&amp; myqty &lt;= 30){&lt;br /&gt; this.file ="yellow.png";&lt;br /&gt;}else{&lt;br /&gt; this.file="red.png";&lt;br /&gt;}  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;One thing to note in the above is that the column value QUANTITYORDERED is the binding column name, not the dataset column name.  See the binding tab on the table in the attached example.  &lt;br /&gt;Images can also be placed in jar files within the resource folder.  If your image exists in a jar file, you can use a script expression similar to the following to specify the image to retrieve.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var jarfile = reportContext.getResource("birtimages.jar");&lt;br /&gt;myfulljarimage = "jar:"+jarfile.toString()+"!/green.png";&lt;br /&gt;myfulljarimage;  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The getResource method of the reportContext object is used to return the location of a file in the resource folder.   Using the location of the file and the jar protocol, the image can be specified.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Embedded Images&lt;/em&gt;&lt;br /&gt;BIRT allows images to be encoded directly into the xml report design.  Images can be added by right clicking on the embedded images icon in the outline view of the report and selecting “New Embedded Image”.  After selecting the image, the outline view is updated and the data for the image is encoded in to the design.  You can also add embedded images to the report using the add image button of the image report item editor.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TH-zLX55xpI/AAAAAAAAAQA/0SBiuSFbW-k/s1600/embedded.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 184px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TH-zLX55xpI/AAAAAAAAAQA/0SBiuSFbW-k/s400/embedded.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5512321476901586578" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Once the images are embedded into the report, you can add the image report item to the desired location, choose the embedded image radial, select the image name and click the insert button.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TH-zctpUkMI/AAAAAAAAAQI/8FQtShUyHis/s1600/embedded2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 314px; height: 400px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TH-zctpUkMI/AAAAAAAAAQI/8FQtShUyHis/s400/embedded2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5512321774795395266" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you wish to change the image dynamically, this can be done using an onCreate script.  In the onCreate script specify the image name using the imageName property.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;this.imageName = "eyellow.png";  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Dynamic Images&lt;/em&gt;&lt;br /&gt;Dynamic images allow Blob images to be inserted into the report.  Typically this type of image is tied to a data set column through either the image’s dataset bindings, or the container element’s bindings (eg Table).  The sample database, which is delivered as part of BIRT, contains a Blob type column in the PRODUCTLINES table.  The example report used in the post has an example of using this column in conjunction with the image report item.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TH-z2st0mFI/AAAAAAAAAQQ/S8IXYoqBBgI/s1600/blob.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 334px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TH-z2st0mFI/AAAAAAAAAQQ/S8IXYoqBBgI/s400/blob.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5512322221222434898" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A developer can also use an onCreate event script to set the image data.  When doing this, the image data should be in a byte[].  Presented below is an onCreate script that uses the ImageIO class to read a file, a URL, an image from the resource folder, or an image in a jar file in the resource folder.   Uncomment the section of the script for the desired image location. &lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;importPackage(Packages.java.io);&lt;br /&gt;importPackage(Packages.java.lang);&lt;br /&gt;importPackage(Packages.java.net);&lt;br /&gt;importPackage(Packages.javax.imageio);&lt;br /&gt;&lt;br /&gt;//File Based&lt;br /&gt;//var myfile = new Packages.java.io.File("c:/test/green.png");&lt;br /&gt;//var img = ImageIO.read(myfile);  &lt;br /&gt;&lt;br /&gt;//URL Based&lt;br /&gt;//Jar image in resource folder&lt;br /&gt;var jarfile = reportContext.getResource("birtimages.jar");&lt;br /&gt;var myfulljarimagestr = "jar:"+jarfile.toString()+"!/red.png";&lt;br /&gt;var myurl = new Packages.java.net.URL(myfulljarimagestr);&lt;br /&gt;&lt;br /&gt;//Image in resource folder&lt;br /&gt;//var myurl = reportContext.getResource("green.png");&lt;br /&gt;&lt;br /&gt;//Image at url&lt;br /&gt;//var myurl = new Packages.java.net.URL("http://www.eclipse.org/eclipse.org-common/themes/Nova/images/eclipse.png");&lt;br /&gt;&lt;br /&gt;var img = ImageIO.read(myurl);&lt;br /&gt;bas = new ByteArrayOutputStream();&lt;br /&gt;ImageIO.write(img, "png", bas);&lt;br /&gt;this.data = bas.toByteArray();&lt;br /&gt;  &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The example used for this post is available at &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1257-birt-image-examples/"&gt;Birt-Exchange&lt;/a&gt;.  To setup the example, copy the birtimages.jar and the three supplied images to your resource folder.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-1124913252605750277?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/1124913252605750277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=1124913252605750277' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1124913252605750277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1124913252605750277'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/09/birt-image-report-item.html' title='BIRT Image - Report Item'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GN1FyT5H8Kg/TH-wusVg6aI/AAAAAAAAAP4/-hYccM6JXKI/s72-c/palette.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-8207792429549444473</id><published>2010-08-20T08:52:00.000-07:00</published><updated>2010-08-20T11:29:21.838-07:00</updated><title type='text'>BIRT Flash and Gadget Scripting</title><content type='html'>In my last post I blogged about how &lt;a href="http://birtworld.blogspot.com/2010/08/birt-charting-scripting-overview.html"&gt;Chart Scripting&lt;/a&gt; works in BIRT. If you are using &lt;a href="http://www.birt-exchange.com/be/products/birt-report-designers/actuate-birt-report-designers/features/?articleid=17169"&gt;Actuate BIRT&lt;/a&gt;, you also will have access to Flash Charts and Gadgets. Scripting for these two report items is very similar to the standard Chart scripting model.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TG6k8uZZ9OI/AAAAAAAAAPA/Gz6ckW5hknI/s1600/image1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 388px; height: 241px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TG6k8uZZ9OI/AAAAAAAAAPA/Gz6ckW5hknI/s400/image1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5507520757474391266" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Flash Charts&lt;/strong&gt;&lt;br /&gt;Currently Flash charts support 14 script event triggers that can be hooked to make chart modifications.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TG6lZQFoM2I/AAAAAAAAAPI/00TM_FM3gzg/s1600/image2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 263px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TG6lZQFoM2I/AAAAAAAAAPI/00TM_FM3gzg/s400/image2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5507521247554581346" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The event firing order is shown below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TG6lkXz86sI/AAAAAAAAAPQ/3KXyehon3j4/s1600/flashchartorder.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 323px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TG6lkXz86sI/AAAAAAAAAPQ/3KXyehon3j4/s400/flashchartorder.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5507521438606486210" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As you can see the order is very similar to that of normal BIRT charts. The before and after dataset filled events are fired first for each dataset (category and value). Next the beforeRendering event is fired and then the before and after draw series events are fired for each series. Between the before and after draw series events the before and after draw data point events are fired for each point in the series. The before and after draw series events (and the events contained in them) are fired for each series in the chart. After all series are processed, the before and after draw effect events are fired for each effect in the chart. Effects can be used to alter the chart at runtime, allowing font manipulation, blurring, glowing, shadowing, beveling, and animation of different objects of the chart. Effects are added to the chart using the effects editor. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TG6l6_gX8gI/AAAAAAAAAPY/NWMx6vvkw_M/s1600/effects.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 249px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TG6l6_gX8gI/AAAAAAAAAPY/NWMx6vvkw_M/s400/effects.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5507521827218911746" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Using the beforeDrawEffect event script you can alter any of the effects added to the chart. For example to turn off the shadow effect in the above chart you could use the following script.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeDrawEffect( effect, fcsc )&lt;br /&gt;{&lt;br /&gt;var effectName = "MyTitleEffect";&lt;br /&gt;if ( effectName.equals( effect.getAction().getName() ) ){&lt;br /&gt;if( effect.getAction().getShadow() != null ){&lt;br /&gt;effect.getAction().getShadow().setEnabled(false);&lt;br /&gt;effect.getAction().getFont().setEnabled(false);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The getEffect().getAction().getName() call returns the name of the effect as defined in the effect editor. This can be used to determine which effect definition your script is operating on. The getAction allows access to the different effect features. Note that if the effect is not enabled the getter method for the effect will return null. In the above script we first check to see if the getShadow method returns null before turning it off. &lt;br /&gt;&lt;br /&gt;Finally the afterRendering event is triggered.&lt;br /&gt;&lt;br /&gt;These events function much the same way as described in my earlier post. You will notice that event function prototypes are just a little different. For example instead of a chart and icsc parameter you will get a flashChart and fcsc parameter in certain events. For practical purposes these are just extended chart and icsc objects and still provide most of the standard object features. For example to set the chart title to the value of a report parameter using the reportContext, you could use a script like the following. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeRendering( flashChart, fcsc )&lt;br /&gt;{&lt;br /&gt;var parmChartTitle = fcsc.getExternalContext().getScriptable().getParameterValue("MyChartTitle");&lt;br /&gt;flashChart.getChart().getTitle().getLabel().getCaption().setValue(parmChartTitle)&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Flash Gadgets&lt;/strong&gt;&lt;br /&gt;BIRT Flash Gadget report items are used to display data in a unique dynamic graphic. Currently Actuate BIRT supports thermometer, cylinder, bullet, spark line, meter gauge or linear gauge gadgets. These gadgets also support server side scripting.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TG6m092-PcI/AAAAAAAAAPg/qgDjuCURAa0/s1600/gadget1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 374px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TG6m092-PcI/AAAAAAAAAPg/qgDjuCURAa0/s400/gadget1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5507522823209237954" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Twelve event triggers are supported and can be used to alter how the gadget is displayed. The events that are triggered will depend on the gadget and which features the gadget is using. For example this meter gadget:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TG6nAxhkfmI/AAAAAAAAAPo/Tho9JkLLHac/s1600/examplegadget.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 206px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TG6nAxhkfmI/AAAAAAAAAPo/Tho9JkLLHac/s400/examplegadget.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5507523026056674914" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Produces the following event order.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TG6nODHAjRI/AAAAAAAAAPw/0KQjtRIHhIw/s1600/gadgeteventorder.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 211px; height: 400px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TG6nODHAjRI/AAAAAAAAAPw/0KQjtRIHhIw/s400/gadgeteventorder.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5507523254115405074" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The beforeRendering event is called first and can be used to modify the flash gadget before it is rendered. Next before and after draw region events are trigger for each of the three regions in the meter gadget. This gadget contains two thresholds, so the before and after threshold events are triggered next for each threshold. The gadget also contains two needles so the before and after draw needle events are fired. The threshold label contains a font effect and the threshold areas are animated. This produces before and after draw effect triggers for each. Finally the afterRendering event is triggered.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Retrieving Gadget Values&lt;/em&gt;&lt;br /&gt;BIRT Flash Gadgets use value definitions to link the gadget to a BIRT dataset.  The definitions are assigned in the Gadget Editor.  The runtime values for these definitions can be retrieved in script using the gadget object.  For example, in the beforeRendering you could use the following script:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeRendering( gadget, fgsc )&lt;br /&gt;{&lt;br /&gt; var vals=gadget.getResultValues();&lt;br /&gt; for( i = 0; i &lt; vals.size(); i++ ){&lt;br /&gt;  if( vals.get(i).getValue() &gt; 20 ){&lt;br /&gt;   //do something&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The number of result values will depend on the gadget.  For example, In a Spark Line gadget there will be multiple values.  In a meter gadget, there will be a result value for each needle value.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Region Events&lt;/em&gt;&lt;br /&gt;You can customize the colors, transparency, labels, and range values of any region using the beforeRendering or beforeDrawRegion scripts.  See the example below.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeDrawRegion( region, fgsc )&lt;br /&gt;{&lt;br /&gt; if( region.getLabel().equals("A") ){&lt;br /&gt;  region.setColor("00ff00");&lt;br /&gt; } &lt;br /&gt;   //Display value range of region.   &lt;br /&gt;     region.setLabel( "(" + region.getStartValue() + ", " + region.getEndValue() + ")" ); &lt;br /&gt;    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function beforeRendering( gadget, fgsc )&lt;br /&gt;{&lt;br /&gt; //First Region&lt;br /&gt; gadget.getRegion().get(0).setEndValue(25);&lt;br /&gt; //Second Region&lt;br /&gt; gadget.getRegion().get(1).setStartValue(25);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Threshold Events&lt;/em&gt;&lt;br /&gt;Thresholds, like regions can also be customized using script.  Virtually anything that is set in the designer can be changed in an event trigger.  For example:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeDrawThreshold( threshold, fgsc )&lt;br /&gt;{&lt;br /&gt;  if( threshold.getLabel().equals("MyThreshold") ){&lt;br /&gt;   threshold.setShowValueInside(true);&lt;br /&gt;   threshold.setShowValueOnTop(false);&lt;br /&gt;   threshold.setStartValue(10);&lt;br /&gt;   threshold.setColor("0000ee");&lt;br /&gt;  // Display the value range of threshold.&lt;br /&gt;   threshold.setLabel( "(" + threshold.getStartValue() + ", " + threshold.getEndValue() + ")" );&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function beforeRendering( gadget, fgsc )&lt;br /&gt;{&lt;br /&gt; gadget.getThresholds().get(0).setMarkerColor("ff0000");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;In these scripts, we change the starting value, color, label and label location in the beforeDrawThreshold.  The marker color is also changed in the beforeRendering script.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;AddOn Events&lt;/em&gt;&lt;br /&gt;BIRT Gadgets support the concept of an AddOn.  An AddOn allows the designer to place images, text, and various shapes on top of the gadget.  If the gadget contains an AddOn the before and afterDrawAddOn events will be triggered, allowing you to customize the AddOn at runtime.  For example, the following script customizes two AddOns.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeDrawAddOn( addOn, fgsc )&lt;br /&gt;{&lt;br /&gt; // Change add-on styles. &lt;br /&gt; if ( addOn.getName().equals("TitleAddOn") )&lt;br /&gt; {&lt;br /&gt;  addOn.setLabel( "Meter Gauge" );&lt;br /&gt;  addOn.setFontColor( "ff0000" );&lt;br /&gt;  addOn.setFontSize( 28 );&lt;br /&gt;  addOn.setY( 35 );&lt;br /&gt; }&lt;br /&gt; else if ( addOn.getName().equals( "ArcAddOn" ) )&lt;br /&gt; {&lt;br /&gt;  addOn.setFillColor( "ffff00" );&lt;br /&gt; }&lt;br /&gt;} &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;AddOns can even be created and placed on the gadget at runtime.  For example the following script adds a text AddOn to the gadget using the beforeRendering event.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeRendering( gadget, fgsc )&lt;br /&gt;{&lt;br /&gt;  importPackage( Packages.com.actuate.birt.flash.gadgets );&lt;br /&gt;  importPackage( Packages.com.actuate.birt.flash.gadgets.impl );&lt;br /&gt;  &lt;br /&gt;  // Add a text add-on.&lt;br /&gt;  var textAddOn = GadgetsFactory.eINSTANCE.createTextAddOn();&lt;br /&gt;  textAddOn.setAddOnType( AddOnType.TEXT );&lt;br /&gt;  textAddOn.setName("DescAddOn");&lt;br /&gt;  textAddOn.setShowAddOn(true);&lt;br /&gt;  gadget.getAddOns().add( textAddOn );&lt;br /&gt;  gadget.setZOrderPosition(1);&lt;br /&gt; &lt;br /&gt; textAddOn.setLabel("This sample demonstrates how to add an add-on by scripting.");&lt;br /&gt; textAddOn.setX(2);&lt;br /&gt; textAddOn.setY(20);&lt;br /&gt; textAddOn.setFontSize( 12 );&lt;br /&gt; textAddOn.setHorizontalAlignment( HorizontalAlignmentType.LEFT );&lt;br /&gt; textAddOn.setVerticalAlignment( VerticalAlignmentType.TOP );&lt;br /&gt; textAddOn.setWrap( true );&lt;br /&gt; textAddOn.setTextBoxBorderColor("000000"); //Black&lt;br /&gt; textAddOn.setTextBoxBackgroundColor("c0c0c0");&lt;br /&gt; textAddOn.setWrapMaxWidth( 30 );&lt;br /&gt; textAddOn.setWrapMaxHeight( 50 );&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;em&gt;Needle Events&lt;/em&gt;&lt;br /&gt;If your gadget contains a needle, the before and afterDrawNeedle events will be triggered.  Using script the needle can be customized.  The size, color, shape, and various other properties of the needle can be customized.  These events are passed a NeedleWrapper instance, which can be used to get the specific needle type.  For example the following two scripts differentiate between a normal gadget needle and a meter gadget needle.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function beforeDrawNeedle( needleWrapper, fgsc )&lt;br /&gt;{&lt;br /&gt;   importPackage( Packages.com.actuate.birt.flash.gadgets );&lt;br /&gt;   importPackage( Packages.com.actuate.birt.flash.gadgets.impl );&lt;br /&gt;   // Change needle styles.&lt;br /&gt;   needleWrapper.getNeedle().setShape( Shape.DIAMOND );&lt;br /&gt;   needleWrapper.getNeedle().setFillColor("2cf83a");&lt;br /&gt;   needleWrapper.getNeedle().setBorderColor("007f00");&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function beforeDrawNeedle( needleWrapper, fgsc )&lt;br /&gt;{  &lt;br /&gt;   //Set Needle size to 25%&lt;br /&gt;   needleWrapper.getMeterNeedle().setSize(25);&lt;br /&gt;   needleWrapper.getMeterNeedle().setBackgroundColor("ff0000");&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Effect Events&lt;/em&gt;&lt;br /&gt;The effect events were described above in the flash charting section.&lt;br /&gt;&lt;br /&gt;Several examples used in this post are available at &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1253-flash-chart-and-gadget-scripting/"&gt;BIRT-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-8207792429549444473?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/8207792429549444473/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=8207792429549444473' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/8207792429549444473'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/8207792429549444473'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/08/birt-flash-and-gadget-scripting.html' title='BIRT Flash and Gadget Scripting'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GN1FyT5H8Kg/TG6k8uZZ9OI/AAAAAAAAAPA/Gz6ckW5hknI/s72-c/image1.png' height='72' width='72'/><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-4596642243495761236</id><published>2010-08-16T15:48:00.000-07:00</published><updated>2010-08-16T15:48:19.053-07:00</updated><title type='text'>BIRT For Perforce</title><content type='html'>I recently stumbled across a project that has BIRT reports about Perforce. &amp;nbsp;It looks like if you are using Perforce for your version control, you can now use BIRT reports to gain insight into that system.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://public.perforce.com/wiki/BIRT_Reports"&gt;http://public.perforce.com/wiki/BIRT_Reports&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-4596642243495761236?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/4596642243495761236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=4596642243495761236' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/4596642243495761236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/4596642243495761236'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/08/birt-for-perforce.html' title='BIRT For Perforce'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7489011665210890224</id><published>2010-08-12T11:01:00.000-07:00</published><updated>2010-08-16T15:46:28.960-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='Charts'/><title type='text'>BIRT Charting – Scripting Overview</title><content type='html'>The BIRT Chart Engine currently supports building and running charts within the BIRT designer or externally.  The engine is fully extensible using the Eclipse extension mechanisms and supports client side interactivity and server side event scripting.  Fourteen main chart types, such as bar charts, line charts, and scatter charts are supported.  Additionally most chart types support many subtypes such as stacked bar charts, 2D with depth, or 3D charts.  When using the chart engine within BIRT the charts can be rendered as PNG, JPG, BMP, or SVG.&lt;br /&gt;&lt;br /&gt;The chart engine also supports a sophisticated server side event model that allows the developer to customize the charts dynamically.  This post is an overview of most of the chart scripting events available.  &lt;br /&gt;&lt;br /&gt;If you are interested in learning more about client side chart scripting, see these posts:&lt;br /&gt;ClientSide Script:&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2009/12/calling-client-side-javascript-from.html"&gt;Calling Client Side JavaScript from a BIRT Chart&lt;/a&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2010/05/more-on-chart-interactivity.html"&gt;More on Chart Interactivity&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;General BIRT Server Side Scripting&lt;/strong&gt;&lt;br /&gt;BIRT Chart event scripting is based on the standard BIRT report scripting model.  A primer for report scripting is available &lt;a href="http://www.eclipse.org/birt/phoenix/deploy/reportScripting.php"&gt;here&lt;/a&gt;.  When the BIRT report engine processes reports they are executed in two phases (Generation and Presentation).  The generation phase connects to data sources collects and processes the values and creates the report items.   The presentation phase renders the content to the particular output (HTML, paginated HTML, PDF, PPT, XLS, DOC, or PS).  These phases can be executed in one or two processes, depending on how you call the engine.&lt;br /&gt;&lt;br /&gt;If you use the Report Engine API (RE API), the RunAndRenderTask is one process.  To run it in two processes you would use a RunTask and then a RenderTask.  If you are using the BIRT Viewer, the /Run and /Preview mappings use one process and the /frameset mapping uses two processes.  This concept is very important to understand when scripting as it affects the order in which the events are triggered.  When using one process the event order for a data item would look something like:&lt;br /&gt;&lt;br /&gt;1st instance&lt;br /&gt;onPrepare&lt;br /&gt;onCreate&lt;br /&gt;onRender&lt;br /&gt;2nd instance&lt;br /&gt;onCreate&lt;br /&gt;onRender.&lt;br /&gt;&lt;br /&gt;The same data item with two processes would look like:&lt;br /&gt;&lt;br /&gt;1st instance&lt;br /&gt;onPrepare&lt;br /&gt;onCreate&lt;br /&gt;2nd instance&lt;br /&gt;onCreate&lt;br /&gt;&lt;br /&gt;onRender first instance&lt;br /&gt;onRender second instance&lt;br /&gt;&lt;br /&gt;Using two processes offers many advantages.  First a binary file called the report document (.rptdocument) is created which can be rendered many times at a later date without re-executing all the queries.   It is also required to support TOC bookmarks and paginated HTML.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Chart Server Side Scripting&lt;/strong&gt;&lt;br /&gt;When using charts in a BIRT report, the engine supports over thirty events.  These events can be used to change the data, interactivity, or presentation of the chart.  All of these events are fired in the presentation phase (at render time) of the report and can be written in Java or JavaScript.  &lt;br /&gt;&lt;br /&gt;It is possible to change chart properties at generation time, but these changes must be made in a report event that happens prior to the chart being created, like the beforeFactory event.  This approach is described &lt;a href="http://birtworld.blogspot.com/2009/08/using-script-to-modify-birt-chart.html"&gt;here&lt;/a&gt; and &lt;a href="http://birtworld.blogspot.com/2008/10/dynamically-adding-series-to-birt-chart.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It is vital to understand when chart events are fired, if you plan on making script changes to your chart.  Take for instance the following chart.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TGQ6FWlFUfI/AAAAAAAAAOg/J5uYfB0DOx0/s1600/ChartEventOrderChart.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 226px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TGQ6FWlFUfI/AAAAAAAAAOg/J5uYfB0DOx0/s400/ChartEventOrderChart.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5504588508188463602" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is a standard Bar chart with a marker line and curve fitting line.  If two processes are used to generate the report that contains this chart, the following event firing order will be used. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TGQ6Sjk9ldI/AAAAAAAAAOo/S7eg5xSUhfo/s1600/ChartEventOrder.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 364px; height: 400px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TGQ6Sjk9ldI/AAAAAAAAAOo/S7eg5xSUhfo/s400/ChartEventOrder.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5504588735015917010" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This diagram shows most of the available events, but not all events are fired for every chart type.  For example before and afterDrawMarker events are only fired for chart types that support makers and these events are usually fired in between the before and afterDrawDataPoint scripts.  The beforeDrawSeriesTitle event only fires for Pie charts.&lt;br /&gt;&lt;br /&gt;Notice the chart events do not start until after the beforeRender report level event. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Chart Script Context&lt;/strong&gt;&lt;br /&gt;Before getting into each of the events, a good understanding of the chart script context object will be helpful.  All BIRT Chart events are passed a chart script context object.  This object will be labeled icsc in the function definition.  You can use the chart script context object to get the current instance of the chart model by calling:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;icsc.getChartInstance();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You can also use it to get the reportContext that is associated with all other report scripting events.  See the scripting primer referenced above for more details.  This object can be used to get parameter values, resource values, locales, the current http request, global variables, page variables, etc.  To access these functions with a JavaScript event use the following:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;rpCtx = icsc.getExternalContext().getScriptable();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This is equivalent to the reportContext variable.  So to get a report parameter value, use:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;rpCtx.getParameterValue(“MyParameter”);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;or to access the http request use (this only works in the Viewer unless you put the http request object in the report engines App Context):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;rptCtx.getHttpServletRequest().getRequestURL();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;If you are using a Java Event handler use:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;IReportContext rpCtx = (IReportContext)icsc.getExternalContext().getObject();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;strong&gt;Data Set Filled Events&lt;/strong&gt;&lt;br /&gt;The first set of chart events that fire are the data set filled events.  These events are fired when data organizing and generation of runtime series is occurring for the chart.  In These events you can change many properties of the chart model, such as series expressions, grouping, labels, formatting, and series visibility.  These events are fired once for the category series and once for each runtime series that is generated based on how the chart is designed.  Generally you will get one runtime series per design time series and one additional one for the category series.  So if you define a bar chart with product code on the x-axis and quantity ordered on the y-axis, this would produce two runtime series.  Each series would contain an array of values.  For example ProdA, ProdB, and ProdC may be the category series and 55, 98, and 32 may be the value series.  If the chart also contained a line series then this would constitute on additional runtime series containing its values.  If you use the optional grouping feature this could generate many runtime series, depending on the number of groups the optional grouping expression produced.  In the above example, if the following expression was entered for the optional grouping.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( row["QUANTITYORDERED"] &gt; 50 ){&lt;br /&gt;"high";&lt;br /&gt;}else{&lt;br /&gt;"low";&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;This would produce a total of three runtime series. 1 (ProdA,ProdB,ProdC), 2 ( 55, 98, null) and 3 (null ,null, 32).&lt;br /&gt;&lt;br /&gt;Note that all series have to have the same number of points.  In the afterDataSetFilled script these values can be check and or modified. &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;beforeGeneration Event&lt;/strong&gt;&lt;br /&gt;The beforeGeneration event is executed before chart building begins and after all series data points have been created.  You can make changes to the chart model here and can even alter the datasets that the chart uses.  In the data set filled events, many runtime series may have been generated.  Every series in a chart will have a unique series identifier.  You can specify this on the third tab of the chart wizard.  If you use optional grouping and many runtime series are generated for each design time series, a new series identifier will be created for each runtime series.  To interrogate these series use code similar to the following (Chart With Axis Example):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var xAxis = chart.getAxes().get(0);&lt;br /&gt;var yAxis = xAxis.getAssociatedAxes().get(0);&lt;br /&gt;var xSeriesDef = xAxis.getSeriesDefinitions().get(0);&lt;br /&gt;var ySeriesDef = yAxis.getSeriesDefinitions().get(0);&lt;br /&gt;&lt;br /&gt;var ySeries = ySeriesDef.getRunTimeSeries();&lt;br /&gt;var numberofrunseries = ySeries.size();&lt;br /&gt;//get the first runtime series identifier&lt;br /&gt;ySeries.get(0).getSeriesIdentifier();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Computation Events&lt;/strong&gt;&lt;br /&gt;The before and afterComputations events are called next.  These events are called just before and right after all the calculations for the chart’s rendering properties are processed.  These computations include all bounds objects for the chart, the series rendering hints, and data point hints, which store the plot location and values for each series.  Using these scripts these values can be modified before the chart is actually rendered.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;afterGeneration/beforeRender Event&lt;/strong&gt;&lt;br /&gt;These events are fired after the chart is built but before it renders each part of the chart.  When the chart engine is building it stores all information in the GeneratedChartState object.  This object is passed to these methods and can be used to make changes before the chart is rendered.  You can use the following code to get the plotComputations object that was populated in the computations event:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;compu =gcs.getComputations();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;You can even change how the chart engine processes interactivity triggers.  For example assume you have a class that implements the IActionRenderer interface. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package my.action.handler;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;import org.eclipse.birt.chart.computation.DataPointHints;&lt;br /&gt;import org.eclipse.birt.chart.event.StructureSource;&lt;br /&gt;import org.eclipse.birt.chart.event.StructureType;&lt;br /&gt;import org.eclipse.birt.chart.model.attribute.ActionType;&lt;br /&gt;import org.eclipse.birt.chart.model.attribute.TooltipValue;&lt;br /&gt;import org.eclipse.birt.chart.model.data.Action;&lt;br /&gt;import org.eclipse.birt.chart.render.ActionRendererAdapter;&lt;br /&gt;public class MyActionHandler extends ActionRendererAdapter implements Serializable{&lt;br /&gt;&lt;br /&gt; private static final long serialVersionUID = 1169308658661902989L;&lt;br /&gt;&lt;br /&gt; public void processAction( Action action, StructureSource source )&lt;br /&gt; {&lt;br /&gt;  if ( ActionType.SHOW_TOOLTIP_LITERAL.equals( action.getType( ) ) )&lt;br /&gt;  {&lt;br /&gt;   TooltipValue tv = (TooltipValue) action.getValue( );&lt;br /&gt;   if ( StructureType.SERIES_DATA_POINT.equals( source.getType( ) ) )&lt;br /&gt;   {&lt;br /&gt;    final DataPointHints dph = (DataPointHints) source.getSource( );&lt;br /&gt;    String MyToolTip = "My Value is " + dph.getDisplayValue() + "--" +dph.getBaseDisplayValue();&lt;br /&gt;    tv.setText( MyToolTip );&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt; You could instantiate an instance of this class in the beforeFactory event of the report:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;importPackage(Packages.my.action.handler);&lt;br /&gt;MyActionRenderer = new MyActionHandler();&lt;br /&gt;reportContext.setPersistentGlobalVariable("myactionrenderer", MyActionRenderer);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;And then set it in the beforeRender event like:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mar = icsc.getExternalContext().getScriptable().getPersistentGlobalVariable("myactionrenderer");&lt;br /&gt;gcs.getRunTimeContext().setActionRenderer(mar);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;DrawBlock Events&lt;/strong&gt;&lt;br /&gt;Charts in BIRT are made up of rendering areas called blocks. Each block will have properties such as rendering bounds, anchor points, outline properties, background properties, and child blocks. The whole chart is the main chart block and within this block is the title block, the plot block and the legend block.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TGQ9JeayOrI/AAAAAAAAAOw/pRRSQ8hws9Q/s1600/blocks.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 217px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TGQ9JeayOrI/AAAAAAAAAOw/pRRSQ8hws9Q/s400/blocks.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5504591877547113138" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The before and afterDraw block events are called multiple times, once for each chart part that constitutes a block. &lt;br /&gt;&lt;br /&gt;The before and afterDraw block events are first called for the whole chart, the title block, plot block, and finally for the legend block.  Nested within the plot block and legend block other events will fire as illustrated in the event diagram.  The plot block events are fired once for each runtime series as well.  So if you have 3 runtime series, the before and afterDrawBlock event will be called three times for the plot block.&lt;br /&gt;&lt;br /&gt;To know which block the event is firing for you can use a script similar to:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; if ( block.isLegend( ) )&lt;br /&gt; {&lt;br /&gt;  block.getOutline( ).setVisible( true );&lt;br /&gt;  block.getOutline( ).getColor( ).set( 21,244,231 );&lt;br /&gt;  block.setBackground( ColorDefinitionImpl.YELLOW( ) );&lt;br /&gt;  block.setAnchor( Anchor.NORTH_LITERAL ); &lt;br /&gt; }&lt;br /&gt; else if ( block.isPlot( ) )&lt;br /&gt; {  &lt;br /&gt; }&lt;br /&gt; else if ( block.isTitle( ) )&lt;br /&gt; {  &lt;br /&gt; }&lt;br /&gt; else if ( block.isCustom( ) ) //Main Block&lt;br /&gt; {&lt;br /&gt; } &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;You can use these events to modify the calculated bounds of any block, but this may result in unattractive charts.  To change the location of the legend the following script could be used.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; if (block.isLegend())&lt;br /&gt; {&lt;br /&gt;  var wid = block.getBounds().getWidth();&lt;br /&gt;  var lft = block.getBounds().getLeft();&lt;br /&gt;  &lt;br /&gt;  block.getBounds().setLeft(lft-20.00);&lt;br /&gt;  block.getBounds().setWidth(wid+20.00);&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;strong&gt;Marker Range and Line Events&lt;/strong&gt;&lt;br /&gt;The before and afterDrawMarker range and line events are called before any of the series are drawn.  These events are only called for charts with axis that actually contain marker ranges (or lines).  Using these events the marker ranges (or lines) can be modified.  By default the location of the markers are set in the chart builder, but you can set the location using an index like:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;markerLine.setValue(NumberDataElementImpl.create(intcountformaker));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The index is associated with the runtime series data point index and not the data point value.  If the index is set to 0 the marker will be set to the first data point.  You can use this in combination with other events like the afterDataSetFilled event to make the marker dynamic.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Draw Series Events&lt;/strong&gt;&lt;br /&gt;For each runtime series that is generated, the before and afterDraw series events will be fired.  You can use the series identifier to determine which series is being processed.  You can also check the specific type that of series that is being rendered.  &lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; if( series.getClass() == LineSeriesImpl ){&lt;br /&gt;  series.getLineAttributes().setThickness(5);&lt;br /&gt; }&lt;br /&gt; if( series.getClass() == BarSeriesImpl ){&lt;br /&gt;  if( series.getSeriesIdentifier() == “Series 1”){&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Also note that this event is called for the category series.&lt;br /&gt;&lt;br /&gt;Within these events you can modify the series before it is rendered.  For example if you want to change a drill through hyperlink to point to a different report you could use the following script.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; triglen = series.getTriggers().size();&lt;br /&gt; if( triglen &gt;0 ){&lt;br /&gt;  mytarget = series.getTriggers().get(0).getAction().getValue().getURLValues( ).get(0).getBaseUrl();&lt;br /&gt;  newtarget = mytarget.replace("reporttarget1.rptdesign", "reporttarget2.rptdesign");&lt;br /&gt;         series.getTriggers().get(0).getAction().getValue().getURLValues( ).get(0).setBaseUrl(newtarget);&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;You can also get all the data points for the series by using script like the following:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; if( series.getClass() == BarSeriesImpl ){&lt;br /&gt;  var pts = isr.getSeriesRenderingHints().getDataPoints();&lt;br /&gt;  for( i=0; i&lt; pts.length; i++ ){&lt;br /&gt;   var mydp = pts[i];&lt;br /&gt;   if( mydp.getOrthogonalValue() &gt; 35 ){&lt;br /&gt;    //do something&lt;br /&gt;   }  &lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;strong&gt;DataPoint and Data Point Label Events&lt;/strong&gt;&lt;br /&gt;For each runtime series that is not a category series, the before and afterDrawDataPoint and before and afterDrawDataPointLabel events are fired.  These occur between the before and afterDrawSeries events.  These events can be used to modify how the data point and label are rendered.  &lt;br /&gt;&lt;br /&gt;The fill object passed to the before and afterDrawDataPoint events will be an instance of one of the following classes depending on how you have setup the palette.&lt;br /&gt;&lt;br /&gt;GradientImpl&lt;br /&gt;ColorDefinitionImpl&lt;br /&gt;ImageImpl (EmbeddedImageImpl and PatternImageImpl extend ImageImpl)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TGQ-3hXhPGI/AAAAAAAAAO4/aoCI4gc5O0E/s1600/palettefill.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 275px; height: 400px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TGQ-3hXhPGI/AAAAAAAAAO4/aoCI4gc5O0E/s400/palettefill.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5504593768124333154" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It is important to know which type you are dealing with if you plan on making changes to the fill object.  You can check the fill type with script similar to this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; if( fill.getClass().isAssignableFrom(GradientImpl)){&lt;br /&gt;        fill.setStartColor(ColorDefinitionImpl.create( 0, 0, 255 ));&lt;br /&gt;        fill.setEndColor(ColorDefinitionImpl.create(255,255,225 ));&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You can set the fill object based on the data point value by using a script like (Assumes  Color Fill):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;     val = dph.getOrthogonalValue();&lt;br /&gt;      if (val == 10){&lt;br /&gt;            fill.set(255, 0, 0);&lt;br /&gt;      }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Using the data point label scripts you can modify the label format and value.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var newlabel = label.getCaption().getValue().replace(",", "'");&lt;br /&gt;label.getCaption().setValue(newlabel);&lt;br /&gt;&lt;br /&gt; if( dph.getBaseDisplayValue() == 50 ){&lt;br /&gt;  label.setVisible(true);&lt;br /&gt;  &lt;br /&gt;  label.getCaption().getFont().setBold(true);&lt;br /&gt;  label.getCaption().getFont().setSize(14);&lt;br /&gt;  label.getCaption().getFont().setName("Arial");&lt;br /&gt;     }else{&lt;br /&gt;      label.setVisible(false);&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;strong&gt;Curve Fitting Events&lt;/strong&gt;&lt;br /&gt;If the series contains a visible curve fitting line, the before and afterDrawFittingCurve events will be trigged after all the data point and data point label scripts have fired.  You can use this event to modify the line attributes and label properties for the fitting curve.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Axis Title and Axis Label Events&lt;/strong&gt;&lt;br /&gt;After all series have been rendered the before and afterDrawAxisLabel events are fired for every label that appears on the axis.  The before and afterDrawAxisTitle events are then fired.  This process starts with the category axis and then proceeds for each value axis.  You can use these events to modify the labels that are rendered.  The axis type can be checked to determine which axis fired the event.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; //LINEAR_LITERAL&lt;br /&gt; //LOGARITHMIC_LITERAL&lt;br /&gt; //TEXT_LITERAL&lt;br /&gt; //DATE_TIME_LITERAL&lt;br /&gt; if( context.getExternalContext().getScriptable().getParameterValue("NewParameter") == "date"){&lt;br /&gt;  if (axis.getType() == AxisType.TEXT_LITERAL)&lt;br /&gt;  {&lt;br /&gt;   value = label.getCaption().getValue();&lt;br /&gt;   var dtf = new SimpleDateFormat("MM/dd/yy");&lt;br /&gt;   var dt = new Date(value);&lt;br /&gt;   var fn = dtf.format(dt);&lt;br /&gt;   label.getCaption().setValue(fn); &lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; You can also check the axis title to determine which axis fired the event.&lt;br /&gt; if( axis.getTitle( ).getCaption( ).getValue( ) ==&lt;br /&gt;  "myYaxisTitle" )&lt;br /&gt; {&lt;br /&gt;  label.getCaption( ).setColor( &lt;br /&gt;   ColorDefinitionImpl.BLUE( ) );&lt;br /&gt; }&lt;br /&gt; if ( axis.getType( ) == AxisType.DATE_TIME_LITERAL )&lt;br /&gt; {&lt;br /&gt;  label.getCaption( ).setColor( &lt;br /&gt;   ColorDefinitionImpl.RED( ) );&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;strong&gt;Legend Item Events&lt;/strong&gt;&lt;br /&gt;The final set of events that are fired that can affect the chart are the before and afterDrawLegendItem events.  These events can be used to customize the look of the chart legend.&lt;br /&gt;&lt;br /&gt;This event is passed the LegendEntryRenderingHints (lerh) object and the bounds for the specific entry. The bounds object is for legend item graphic and not the text.  Using these objects you can customize the legend.  You can hide an entry using the bounds object.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; if( lerh.getLabel().getCaption().getValue().compareToIgnoreCase("series3") == 0 ){&lt;br /&gt;  bounds.setHeight(0);&lt;br /&gt;  bounds.setWidth(0);&lt;br /&gt;  lerh.getLabel().setVisible(false);&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;You can modify the fill object using the lerh.getFill() function and modify the label using the lerh.getLabel() function.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; importPackage( Packages.org.eclipse.birt.chart.model.attribute.impl );&lt;br /&gt; label = lerh.getLabel();&lt;br /&gt; labelString = label.getCaption().getValue();&lt;br /&gt; if( labelString == "series2" ){&lt;br /&gt;  label.getCaption( ).getColor( ).set( 32, 168, 255 );&lt;br /&gt;  label.getCaption().getFont().setItalic(true);&lt;br /&gt;  label.getCaption().getFont().setRotation(5);&lt;br /&gt;  label.getCaption().getFont().setStrikethrough(true);&lt;br /&gt;  label.getCaption().getFont().setSize(12);&lt;br /&gt;  label.getCaption().getFont().setName("Arial");&lt;br /&gt;  label.getOutline().setVisible(true);&lt;br /&gt;  label.getOutline().setThickness(3); &lt;br /&gt;&lt;br /&gt;  var mycolor = ColorDefinitionImpl.BLUE();&lt;br /&gt;     r = mycolor.getRed();&lt;br /&gt;        g = mycolor.getGreen();&lt;br /&gt;        b = mycolor.getBlue();&lt;br /&gt;        lerh.getFill().set(r, g, b);&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;You can check the fill object type before modifying it as described in the &lt;strong&gt;DataPoint and Data Point Label Events&lt;/strong&gt; described earlier.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Chart Scripting Examples&lt;/strong&gt;&lt;br /&gt;Here are some example reports/posts that illustrate using the chart scripting model.&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2008/04/birt-resizing-charts.html"&gt;BIRT Resizing Charts&lt;/a&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2008/12/birt-reversing-chart-scale.html"&gt;BIRT - Reversing a Chart Scale&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1217-resize-pie-chart-based-on-optional-grouping-count/"&gt;Resize Pie Chart based on optional grouping count&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1219-add-spacing-to-stacked-bar-optional-grouped-chart/"&gt;Add spacing to stacked bar optional grouped chart&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1114-turning-a-chart-series-off-in-script/"&gt;Turning a Chart series off in script&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1117-set-chart-axis-label-interval-with-script/"&gt;Set Chart Axis Label Interval with Script&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1120-using-chart-script-to-define-a-specific-series-color/"&gt;Using Chart Script to Define a specific series color&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/826-chart-script-to-alter-palette-gradient-pie/"&gt;Chart Script to Alter Palette - Gradient Pie&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1005-adjust-bar-location-in-bar-chart/"&gt;Adjust BAR Location in Bar Chart&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7489011665210890224?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='BIRT Charting – Scripting Overview'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7489011665210890224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7489011665210890224' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7489011665210890224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7489011665210890224'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/08/birt-charting-scripting-overview.html' title='BIRT Charting – Scripting Overview'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GN1FyT5H8Kg/TGQ6FWlFUfI/AAAAAAAAAOg/J5uYfB0DOx0/s72-c/ChartEventOrderChart.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-1305792403492329427</id><published>2010-08-03T15:04:00.000-07:00</published><updated>2010-08-03T15:04:10.305-07:00</updated><title type='text'>Functions and Controls Moves to Eclipse Labs</title><content type='html'>Don't you love it when technology just works? &amp;nbsp;I recently had this experience when I moved a couple of BIRT projects to &lt;a href="http://code.google.com/a/eclipselabs.org/hosting/"&gt;Eclipse Labs&lt;/a&gt;. &amp;nbsp;I have moved all of my BIRT projects that were on Google Code over to the Eclipse Labs section of Google Code. &amp;nbsp;You can access them here:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/a/eclipselabs.org/p/birt-functions-lib/"&gt;BIRT Functions Library&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/a/eclipselabs.org/p/birt-controls-lib/"&gt;BIRT Controls Library&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/a/eclipselabs.org/p/birt-innovent-update/"&gt;BIRT Update Site&amp;nbsp;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The one question might be why create an update site that is separate from the project sites? &amp;nbsp;Well the short answer is that I want to make it easy for someone to get access to the projects we have created from a single site. &amp;nbsp;In addition, it is easy for me to add more content without having to modify the existing versions on the projects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the next couple of weeks, I hope to add a couple of new features to the update site that will make it easier to create team based reporting projects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-1305792403492329427?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/1305792403492329427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=1305792403492329427' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1305792403492329427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1305792403492329427'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/08/functions-and-controls-moves-to-eclipse.html' title='Functions and Controls Moves to Eclipse Labs'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7499064135659012183</id><published>2010-07-26T09:38:00.000-07:00</published><updated>2010-08-16T15:46:39.780-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>Whats the Difference Between dataSetRow["FIELD"] and row["FIELD"]</title><content type='html'>One of the most common questions for people that are new to BIRT is about how to ask data from the DataSet in the report. &amp;nbsp;The question is when building expressions should I use dataSetRow["FIELD"] or row["FIELD"]?&lt;br /&gt;&lt;br /&gt;So let me see if I can set the record straight. &amp;nbsp;When data is acquired, it is acquired by a DataSet, so the following query in a JDBC DataSet will create a three field resultset:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;select CITY, STATE, COUNTRY &lt;br /&gt;from CUSTOMERS&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;a href="http://4.bp.blogspot.com/_5bQPsXqbEM4/TEoGwq2zpSI/AAAAAAAAA1g/4oGG6QsV6o8/s1600/dataSet.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="228" src="http://4.bp.blogspot.com/_5bQPsXqbEM4/TEoGwq2zpSI/AAAAAAAAA1g/4oGG6QsV6o8/s400/dataSet.png" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Any script or expressions written on the DataSet will be written to use the format&lt;br /&gt;&lt;br /&gt;row["FIELD_NAME"];&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_5bQPsXqbEM4/TEoIIqzrb7I/AAAAAAAAA1k/CVrhOSRh87o/s1600/dataSetCompCol.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="120" src="http://4.bp.blogspot.com/_5bQPsXqbEM4/TEoIIqzrb7I/AAAAAAAAA1k/CVrhOSRh87o/s400/dataSetCompCol.png" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So if we add a computed column to the DataSet called compCityState, the expression would look like this.&lt;br /&gt;&lt;br /&gt;Once a computed column is created, you can reference that computed column using the same row syntax. &amp;nbsp;So in the OnFetch method you could add this message to log the value of the computed column.&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;Packages.java.lang.System.out.println(row["compCityState"]);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The other place that you can access variable on the DataSet is through ReportItem binding. &amp;nbsp;In most cases, this means Table Binding where you have attached a table to a DataSet. &amp;nbsp;In general, when you use BIRT you associate a Table with a DataSet. &amp;nbsp;We say that the Table is bound to the DataSet.&lt;br /&gt;&lt;br /&gt;When a DataSet is dragged to the Layout editor, BIRT automatically does the data binding and creates a bound column for each field and computed column in the DataSet. &amp;nbsp;The following shows a table and its Binding.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_5bQPsXqbEM4/TEoMfwYxSSI/AAAAAAAAA1s/97XpSrOBfy8/s1600/tableBinding.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="324" src="http://4.bp.blogspot.com/_5bQPsXqbEM4/TEoMfwYxSSI/AAAAAAAAA1s/97XpSrOBfy8/s640/tableBinding.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;You will notice that all of the expressions use the term dataSetRow, which means this value is pulled from the DataSet. &amp;nbsp;Now for the tricky bit, any field that is bound to a Table can be used in another table binding. &amp;nbsp;So if we wanted to create a field that has City, State and Country, we could either:&lt;br /&gt;a) go back to the DataSet&lt;br /&gt;b) add a new table binding&lt;br /&gt;&lt;br /&gt;When you add a binding to a table you are brought to the expression builder. &amp;nbsp;In this first example, I am creating a table binding that gathers data straight from the DataSet.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_5bQPsXqbEM4/TEoO7sbwwPI/AAAAAAAAA1w/C638LKAbr5E/s1600/dataSetBind.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="464" src="http://3.bp.blogspot.com/_5bQPsXqbEM4/TEoO7sbwwPI/AAAAAAAAA1w/C638LKAbr5E/s640/dataSetBind.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Because I am referencing the DataSet directly the expression uses the dataSetRow syntax.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;In the next example, I will use the previously established bindings to build the expression. &amp;nbsp;In the expression builder I will select Available Column Bindings and the Table and then select the fields. &amp;nbsp;You will also notice that the Table Binding has access to any of the previously bound fields and a special RowNumber field. &amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;The important thing is that the syntax to access those values is to use row["FIELD_NAME"]&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_5bQPsXqbEM4/TEoQgwRi8UI/AAAAAAAAA10/rOH-S73t9p0/s1600/dataSetBind_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="526" src="http://4.bp.blogspot.com/_5bQPsXqbEM4/TEoQgwRi8UI/AAAAAAAAA10/rOH-S73t9p0/s640/dataSetBind_2.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;So the short answer is, dataSetRow syntax references the original values from the DataSet, whereas the row syntax references the bound column values.&lt;br /&gt;&lt;br /&gt;Now for a quick test, this should be easy. &lt;br /&gt;&lt;br /&gt;Imagine that I change the expression of the CITY expression to look like this, and all else remains the same. &lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_5bQPsXqbEM4/TEoTE_eeU5I/AAAAAAAAA18/_SuELIa7rYw/s1600/test.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="128" src="http://4.bp.blogspot.com/_5bQPsXqbEM4/TEoTE_eeU5I/AAAAAAAAA18/_SuELIa7rYw/s640/test.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;If the values for the row are:&lt;br /&gt;City: Kalamazoo&lt;br /&gt;State: MI&lt;br /&gt;Country: USA&lt;br /&gt;&lt;br /&gt;What will a DataItem that is showing rowCityStateZip display?&lt;br /&gt;What will a DataItem that is showing tablCityStateCountry display?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The answers will be after a short shameless promotion of my companies BIRT training program. &amp;nbsp;We have designed a modular training program that is focused on teaching you how BIRT works. &amp;nbsp;You can take one module or all of them. &amp;nbsp;The focus of our training is on how BIRT works, so that when you finish you really understand what is going on in the product. &lt;br /&gt;&lt;br /&gt;Our training can be taken on-site, or through remote sessions of between two and four hours each. &amp;nbsp;We are also happy to work with your team to customize the training to match your companies needs. &amp;nbsp; If you are interested, please visit our web site and have a &lt;a href="http://draft.blogger.com/he%20answers%20will%20be%20after%20a%20short%20shameless%20promotion%20of%20my%20companies%20BIRT%20training%20program.%20%20We%20have%20designed%20a%20modular%20training%20program%20that%20is%20focused%20on%20teaching%20you%20how%20BIRT%20works.%20%20You%20can%20take%20one%20module%20or%20all%20of%20them.%20%20The%20focus%20of%20our%20training%20is%20on%20how%20BIRT%20works,%20so%20that%20when%20you%20finish%20you%20really%20understand%20what%20is%20going%20on%20in%20the%20product.%20%20%20%20Our%20training%20can%20be%20taken%20on-site,%20or%20through%20remote%20sessions%20of%20between%20two%20and%20four%20hours%20each.%20%20If%20you%20are%20interested,%20please%20visit%20our%20web%20site%20and%20have%20a%20look:%20http://www.innoventsolutions.com/birt-training.html"&gt;look&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Answers:&lt;br /&gt;rowCityStateZip: &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{ Kalamazoo }, MI USA&lt;br /&gt;tablCityStateCountry: &amp;nbsp;Kalamazoo, MI USA&lt;br /&gt;&lt;br /&gt;Remember, dataSetRow syntax (as used in tablCityStateCountry) goes back to the original data. &amp;nbsp;Row syntax use the table binding.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7499064135659012183?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7499064135659012183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7499064135659012183' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7499064135659012183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7499064135659012183'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/07/whats-difference-between.html' title='Whats the Difference Between dataSetRow[&quot;FIELD&quot;] and row[&quot;FIELD&quot;]'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_5bQPsXqbEM4/TEoGwq2zpSI/AAAAAAAAA1g/4oGG6QsV6o8/s72-c/dataSet.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-9052794956201522238</id><published>2010-07-19T12:02:00.000-07:00</published><updated>2010-08-16T15:46:46.409-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>Manipulating Chart Legends in Event Handlers</title><content type='html'>&lt;div style="text-align: left;"&gt;Recently I had the opportunity to figure out how to manipulate sizing, positioning and text wrapping of chart legends so I thought I'd share what I learned.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you have a chart with legend items that don't fit in the available space, BIRT will do one of two things, depending on the wrapping width option.   (Wrapping width is found on the legend layout dialog).  If the wrapping width is set to zero, BIRT will simply truncate the legend item text and optionally append an ellipsis.  (The ellipsis option is located on the legend entries dialog).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If the wrapping width is set to a positive value, BIRT will word-wrap the text.  Unfortunately when it does this, it doesn't check the vertical boundaries and long items can end up overlapping.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_IQZ2xtAZQyI/TESmg_5oVuI/AAAAAAAAAAc/l5IDC7kdV-o/s1600/overlap.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 253px;" src="http://2.bp.blogspot.com/_IQZ2xtAZQyI/TESmg_5oVuI/AAAAAAAAAAc/l5IDC7kdV-o/s320/overlap.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5495700531138025186" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/center&gt;Another downside is you have to specify a hard width within which to wrap.  It won't simply wrap based on the amount of space that's available.   On top of that, my client had some special requirements about how the Thai characters should be wrapped.  So I dug into the chart event handlers to see what I could do. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It turned out I could do a lot, but I had to pick the right event handler.   My first thought was to use beforeDrawLegendItem.  It looked perfect because of the Bounds parameter.  However, it turned out that was not the bounds of the text area, but of the colored rectangle, which didn't help me much.  Additionally I couldn't manipulate the size and position of the legend items within that handler and have it stick.  The horses had already left the barn so to speak.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The beforeRendering handler was much better.  In it I could manipulate the size, position and text of each legend item.   Following are the the technical details.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The first argument to the event handler function is a GeneratedChartState object (which I'll call gcs).    Using gcs.getRunTimeContext(), you can get the RunTimeContext object (rtc).  Then using rtc.getLegendLayoutHints()  you get the LegendLayoutHints object (llh) which tells you about the legend as a whole.   Particularly llh.getLegendSize() tells you how big BIRT wants to make the legend.   Finally llh.getLegendItemHints gets you an array of LegendItemHints (liha), which gives you access to each legend item.   The number of legend items is liha.length.  The text for each item is lih.getItemText().&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So how much height is available for the whole legend?   You can get that with gcs.getPlotComputations().getPlotBounds().getHeight().  The width of the legend is llh.getLegendSize().getWidth().  I didn't need to change the width so I didn't try to find out how to do that.  I'm not sure how BIRT allocates horizontal space to the legend vs the chart itself.  That may present itself as a future exercise.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For my project I had to wrap this text according to the space that was available, so I needed to be able to measure the pixel width of a string of characters.  To do this you need to instantiate BIRTChartComputation.  The constructor takes no arguments so it's simple.  I'll call my instance bcc.   Next you need the font height, which you can get from bcc.computeFontHeight.  This method needs an IDisplayServer and a Label.   You can get the IDisplayServer from gcs.getDisplayServer() and you can create a temporary Label with GObjectFactory.instance().createLabel().   The method with compute the font height based on the text in the label.    Finally, you get the overall size of a string of text with bcc.computeLabelSize, which you pass an IDisplayServer, a Label and a font height.   This is a fairly expensive operation so it's best to use a binary search to look for a wrap point.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once a new version of the text has been computed, you can simply insert it back into the LegendItemHint using lih.setItemText().   Also the item height can be set with lih.itemHeight().   Finally, if you want an ellipsis to be appended you need to set the valid item length with lih.validItemLen() to the character position where you want the ellipsis to go.  If you set it to zero or a value greater than the length of the label, no ellipsis will be appended. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Since I also needed to change the overall size of the legend, I wanted a setLegendSize method in LegendItemHints, but no such method exists.  In fact, the class is mostly immutable.   Fortunately it's possible to instantiate a new LegendItemHints with a new size and pass it to the RunTimeContext with rtc. setLegendLayoutHints().  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;An that's it.  Fun, huh?   Ok you can stop yawning.  Here's what my new legend looks like:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_IQZ2xtAZQyI/TETCiaccDnI/AAAAAAAAAAk/qm1rQk1whMc/s1600/final.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 238px;" src="http://4.bp.blogspot.com/_IQZ2xtAZQyI/TETCiaccDnI/AAAAAAAAAAk/qm1rQk1whMc/s320/final.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5495731341768789618" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/center&gt;I know you can't do everything in event handlers, but this is more than I thought I'd be able to do when I started.  I was pleasantly surprised.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-9052794956201522238?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/9052794956201522238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=9052794956201522238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/9052794956201522238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/9052794956201522238'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/07/manipulating-chart-legends-in-event.html' title='Manipulating Chart Legends in Event Handlers'/><author><name>Steve Schafer</name><uri>http://www.blogger.com/profile/11330471240264633246</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_IQZ2xtAZQyI/TESmg_5oVuI/AAAAAAAAAAc/l5IDC7kdV-o/s72-c/overlap.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-5451188382889499696</id><published>2010-07-14T08:56:00.000-07:00</published><updated>2010-07-14T09:21:35.815-07:00</updated><title type='text'>BIRT and OLAP</title><content type='html'>BIRT Introduced OLAP style data cubes and crosstabs in version 2.2 and while they have been around for some time we still get a lot of questions on how to use and manipulate them.  Below are just some of the resources that have been posted to BIRT Exchange that should help you with cubes and crosstabs.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Introduction Resources&lt;/strong&gt;&lt;br /&gt;To get an idea of what a BIRT cube is and how to tie it to a crosstab report item, take a look at &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1240-birt-crosstab-introduction-article/"&gt;this article&lt;/a&gt; which provides a detailed write-up of the technology and supplies some examples.&lt;br /&gt;&lt;br /&gt;To see a recorded demonstration of a crosstab style report being build see this &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/216-building-a-dynamic-crosstab-birt-2.2.1-tutorial-series/"&gt;tutorial video&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Event Based Scripting Resources&lt;/strong&gt;&lt;br /&gt;BIRT provides event based server side scripting for almost all report items, including crosstabs.  A detailed blog post is available &lt;a href="http://birtworld.blogspot.com/2010/02/birt-crosstab-scripting.html"&gt;here&lt;/a&gt; with an &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1156-crosstab-scripting-java-javascript/"&gt;example&lt;/a&gt; that demonstrates implementing a crosstab with event handler script. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TD3gUEja8II/AAAAAAAAANo/ardDoBRIgwY/s1600/serversidescript.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 294px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TD3gUEja8II/AAAAAAAAANo/ardDoBRIgwY/s400/serversidescript.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5493793755886186626" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Client Side Crosstab Scripting&lt;/strong&gt;&lt;br /&gt;BIRT supplies a Text report item that allows formatted HTML to be inserted into BIRT reports.  Text elements can also be used to insert client side script that will execute while viewing the report in HTML.  The Text element can be used in conjunction with a crosstab to add client side script to the crosstab.  As an example of this take a look at these on &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1085-client-side-script-on-crosstabs/"&gt;BIRT Exchange&lt;/a&gt;.   One of the examples animates the crosstab by iteratively changing the background color of a cell based on its value while the other inserts mouse over events to highlight specific cells.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TD3g_PJTU-I/AAAAAAAAANw/2tmTQE9pZqc/s1600/clientsidescript.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 217px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TD3g_PJTU-I/AAAAAAAAANw/2tmTQE9pZqc/s400/clientsidescript.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5493794497463800802" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Using the DE API in conjunction with a Crosstab&lt;/strong&gt;&lt;br /&gt;The BIRT Project provides the Design Engine (DE API) to construct report, template and library designs.  This API is used by the designer when building BIRT content.  Not only can this API be used in a Java project but can be called from a Java/Java Script event handler to modify a currently running report.  There are many examples of this on BIRT Exchange.  A couple of examples that are relevant to cubes and crosstabs are listed below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1201-add-sort-to-crosstab-using-de-api-in-script/"&gt;This example&lt;/a&gt; uses report parameters and a beforeFactory JavaScript event to change the sort order for a crosstab.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TD3h0oQ9aRI/AAAAAAAAAN4/axqyir8z0e0/s1600/desort.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 329px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TD3h0oQ9aRI/AAAAAAAAAN4/axqyir8z0e0/s400/desort.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5493795414739872018" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Another example of using this approach is located &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1181-dynamic-xtab-creation-using-script/"&gt;here&lt;/a&gt;.  This example contains a report with no graphical content, but does contain a datasource, dataset, and data cube.  It uses report parameters and a beforeFactory JavaScript event to construct a crosstab based on the parameters.&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TD3iKDCHPFI/AAAAAAAAAOA/b-4nakSYxPU/s1600/decrosstab.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 329px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TD3iKDCHPFI/AAAAAAAAAOA/b-4nakSYxPU/s400/decrosstab.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5493795782702611538" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Building a crosstab with the API&lt;/strong&gt;&lt;br /&gt;If you are using the DE API to create reports from your Java application and wish to add crosstabs to your reports &lt;a href="http://www.birt-exchange.org/org/devshare/deploying-birt-reports/1043-create-data-cube-amp-xtab-de-api-example/"&gt;this example&lt;/a&gt; illustrates building a data cube and adding a crosstab to a report using the API.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Extended Capabilities&lt;/strong&gt;&lt;br /&gt;If you are interested in further capabilities, Actuate 11 which will be released this fall, provides a new feature called the Actuate BIRT Data Analyzer.  This product is a zero footprint browser based BIRT cube analyzer.  It can be used with existing BIRT reports that contain cubes to add, modify, re-order, or remove dimensions and measures without having to re-execute the report.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TD3i813ghxI/AAAAAAAAAOI/64veGswLRZM/s1600/crosstab1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 290px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/TD3i813ghxI/AAAAAAAAAOI/64veGswLRZM/s400/crosstab1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5493796655341799186" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In addition to the above, the Data Analyzer can be used to pivot, filter, sort, and add computed measures and aggregates to the crosstab, all from within the browser without re-executing the report.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TD3jIv9SeJI/AAAAAAAAAOQ/bopfRvDbiZk/s1600/crosstab2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 290px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TD3jIv9SeJI/AAAAAAAAAOQ/bopfRvDbiZk/s400/crosstab2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5493796859913861266" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you are interested in trying out this feature download the latest milestone build of the Actuate BIRT Report Designer from the &lt;a href="http://www.birt-exchange.org/org/wiki/index.php?title=Actuate_11"&gt;milestone build page&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-5451188382889499696?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='BIRT and OLAP'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/5451188382889499696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=5451188382889499696' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5451188382889499696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5451188382889499696'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/07/birt-and-olap.html' title='BIRT and OLAP'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_GN1FyT5H8Kg/TD3gUEja8II/AAAAAAAAANo/ardDoBRIgwY/s72-c/serversidescript.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-1082823171751168456</id><published>2010-07-08T13:32:00.000-07:00</published><updated>2010-07-08T13:36:53.434-07:00</updated><title type='text'>BIRT 2.6 Webinar</title><content type='html'>Thanks to all those who attended the New BIRT 2.6 Features in Helios webinar.  The recording is available on &lt;a href="http://live.eclipse.org/node/910"&gt;Eclipse Live&lt;/a&gt;.  The examples used in the webinar are available at &lt;a href="http://www.birt-exchange.org/org/devshare/designing-birt-reports/1238-birt-2.6-webinar-examples/"&gt;BIRT-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-1082823171751168456?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/1082823171751168456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=1082823171751168456' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1082823171751168456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1082823171751168456'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/07/birt-26-webinar.html' title='BIRT 2.6 Webinar'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7378417490706680873</id><published>2010-06-23T06:26:00.000-07:00</published><updated>2010-06-23T06:29:32.180-07:00</updated><title type='text'>BIRT 2.6 Released</title><content type='html'>BIRT 2.6 is now available and with this release many improvements and new features are available. Charting with BIRT has been improved adding support for a Radar/Polar chart type, palette hash patterns, better JPG quality, and improved SVG to PDF support.  Changes have been made to the designer to support better per project classpath management, multiple resource files for localization, and support for locale and collation strength sorting properties. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TCIL0hXnevI/AAAAAAAAANg/ukLNS3NRwPU/s1600/snapshot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 215px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TCIL0hXnevI/AAAAAAAAANg/ukLNS3NRwPU/s400/snapshot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5485960293029214962" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To read more about the new BIRT 2.6 features see the &lt;a href="http://www.eclipse.org/birt/phoenix/project/notable2.6.php"&gt;BIRT New and Notable Features&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7378417490706680873?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7378417490706680873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7378417490706680873' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7378417490706680873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7378417490706680873'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/06/birt-26-released.html' title='BIRT 2.6 Released'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_GN1FyT5H8Kg/TCIL0hXnevI/AAAAAAAAANg/ukLNS3NRwPU/s72-c/snapshot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-2135697087467400763</id><published>2010-06-09T07:47:00.000-07:00</published><updated>2010-06-10T10:48:25.451-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>Conditional Table Filters</title><content type='html'>Just ran across this and it is a nice technique for those situations where you are limited to table based filtering of data. Typically, I focus on data filtering as far up stream as possible. It is better to filter data at the source (in the where clause for JDBC). Next, I use DataSet based filtering.&lt;br /&gt;&lt;br /&gt;But sometimes you can't filter at the Source or the DataSet, which is where table based filtering comes in. The issue with table based filters is that there is no good way in the UI to implement conditional filtering. For instance, imagine you have a data driven parameter multi-select parameter and you want to limit the choices to the values from that parameter.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_5bQPsXqbEM4/TA-ivCGsBPI/AAAAAAAAA1Q/T46K6aMWv3Q/s1600/filter_static.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="275" src="http://1.bp.blogspot.com/_5bQPsXqbEM4/TA-ivCGsBPI/AAAAAAAAA1Q/T46K6aMWv3Q/s320/filter_static.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;This is relatively simple to do, you just create a multi-select parameter and add a filter to a table.&lt;br /&gt;&lt;br /&gt;So what happens if your user wants to select all of the values in the list?  They need to select each of the values from the pick list that appears.  Unfortunately, with large pick lists this is a little tricky for the end user.  In addition, table based filtering on large pick list may create performance issues.  &lt;br /&gt;&lt;br /&gt;What you would like to do is make the parameter optional, and if the value for the parameter is not set, then just don't filter on that parameter value.  &lt;br /&gt;&lt;br /&gt;The UI does not support this type of behavior, but it is easy to do through a small amount of script on the table in the onPrepare method. &lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;importPackage( Packages.org.eclipse.birt.report.engine.api.script.element ); &lt;br /&gt;importPackage( Packages.org.eclipse.birt.report.model.api.simpleapi ); &lt;br /&gt;&lt;br /&gt;if(params["Region"].value!= null){&lt;br /&gt;    var filterCondition = StructureScriptAPIFactory.createFilterCondition(); &lt;br /&gt;    filterCondition.setExpr("row['COUNTRY']"); &lt;br /&gt;    filterCondition.setOperator("eq");&lt;br /&gt;    filterCondition.setValue1("params[\"Region\"]");&lt;br /&gt;    &lt;br /&gt;    var filterKey = filterCondition.getStructure();&lt;br /&gt;    var filterItem = SimpleElementFactory.getInstance().createFilterCondition( filterKey )&lt;br /&gt;    this.addFilterCondition( filterItem );&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Now how would you handle the situation if you had multiple filter conditions that you wanted to add? &amp;nbsp;A trivial re-factor and you can create a general purpose method add filter method.&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;// generic function to add a filter to a table&lt;br /&gt;function addFilterItem (table, rowExpr, paramExpr){&lt;br /&gt;  &lt;br /&gt;  var filterCondition = StructureScriptAPIFactory.createFilterCondition(); &lt;br /&gt;  filterCondition.setOperator("in");&lt;br /&gt;  filterCondition.setExpr(rowExpr); &lt;br /&gt;  filterCondition.setValue1(paramExpr);&lt;br /&gt;&lt;br /&gt;  // could do in one step, shows DEAPI creation steps&lt;br /&gt;  var filterKey = filterCondition.getStructure();&lt;br /&gt;  var filterItem = SimpleElementFactory.getInstance().createFilterCondition( filterKey );&lt;br /&gt;&lt;br /&gt;  table.addFilterCondition(filterItem);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This method can then be placed into a JavaScript file, a Script extension point, or a global location. &amp;nbsp;Calling the file from the table is equally easy. &lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;// add filters dynamically&lt;br /&gt;if (params["Country"].value != null )&lt;br /&gt;  addFilterItem (this, 'row["COUNTRY"]' , 'params["Country"].value' );&lt;br /&gt;&lt;br /&gt;if (params["City"].value != null)&lt;br /&gt;  addFilterItem (this, 'row["CITY"]' , 'params["City"].value' );&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;It is important to recognize that the second and third parameters that are being passed are expressions and not values. &amp;nbsp;So what is happening is we are creating a filter, and that filter will use the express row["COUNTRY"] to look up the appropriate country values. &amp;nbsp;That is why you need to pass the exact expression through in the function. &lt;br /&gt;&lt;br /&gt;If you are having trouble figuring out the appropriate expression, just build the expression that you want in the UI, and then search through the XML for the word filter.  You will see the expressions in the XML.  Just copy these expressions and pass them to your function.  Just delete the static filter and you are all set. &amp;nbsp;Yes, you can use different operators then the IN clause, but it seems the most appropriate for this type of filtering.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-2135697087467400763?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/2135697087467400763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=2135697087467400763' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/2135697087467400763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/2135697087467400763'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/06/conditional-table-filters.html' title='Conditional Table Filters'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_5bQPsXqbEM4/TA-ivCGsBPI/AAAAAAAAA1Q/T46K6aMWv3Q/s72-c/filter_static.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-3778969513265826037</id><published>2010-06-02T12:26:00.000-07:00</published><updated>2010-06-03T11:10:37.306-07:00</updated><title type='text'>BIRT Excel Output</title><content type='html'>BIRT 2.5.2 provides a variety of tools to construct reports to analyze data.  These include charts, aggregation elements, drill to detail capabilities, nested tables, data cubes and crosstabs.  These features are presented very well in the AJAX based viewer when deployed to the web, supporting pagination, table of contents, and exporting of data and contents to other formats.  Out of the box, BIRT supports exporting to HTML, paginated HTML, WORD, PDF, PostScript, PPT, and Excel.  BIRT also provides an extension point to implement your own emitters.  For an example of implementing an XML emitter see &lt;a href="http://www.developer.com/xml/article.php/10929_3732446_2/Developing-an-Eclipse-BIRT-XML-Report-Rendering-Extension.htm "&gt;Developing an Eclipse BIRT XML Report Rendering Extension&lt;/a&gt; or t&lt;a href="http://digiassn.blogspot.com/2007/08/birt-writing-emitter.html"&gt;BIRT: Writing an Emitter&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;As stated earlier BIRT supports exporting to Excel.  The BIRT Excel emitter creates a Microsoft Office XML XLS document that can be opened in Microsoft Office 2003 or greater.  To use this feature either add the __format=xls parameter to the BIRT viewer URL or use the AJAX export button.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TAaxDA8otFI/AAAAAAAAAMo/m_7djTHKOBA/s1600/opensourcexls.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 275px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TAaxDA8otFI/AAAAAAAAAMo/m_7djTHKOBA/s400/opensourcexls.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5478260662094836818" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;if you are using the Report Engine API, simply set up a render option for XLS.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;                //RunAndRender Task&lt;br /&gt;  IReportRunnable design = null;&lt;br /&gt;  design = engine.openReportDesign("Reports/myreport.rptdesign"); &lt;br /&gt;  IRunAndRenderTask task = engine.createRunAndRenderTask(design);   &lt;br /&gt;  EXCELRenderOption options = new EXCELRenderOption(); &lt;br /&gt;  options.setOutputFormat("xls");&lt;br /&gt;  options.setOutputFileName("output/resample/myxls.xls");&lt;br /&gt;  task.setRenderOption(options);&lt;br /&gt;  task.run();&lt;br /&gt;  task.close();&lt;br /&gt;&lt;br /&gt;                //or Render Task&lt;br /&gt;  IReportDocument document = null;&lt;br /&gt;  document = engine.openReportDocument("output/resample/myreport.rptdocument"); &lt;br /&gt;  EXCELRenderOption options = new EXCELRenderOption();&lt;br /&gt;  options.setOutputFormat("xls");&lt;br /&gt;  options.setOutputFileName("output/resample/xlsoutput.xls");&lt;br /&gt;  IRenderTask task = engine.createRenderTask(document);   &lt;br /&gt;  task.setRenderOption(options);&lt;br /&gt;  task.render();&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;While the XLS output is quite good, some features are not supported.  For example new worksheets on page breaks are not created and images and charts are not exported to the XLS.   While the team continues to improve the XLS emitter there are some other options for emitting XLS.  One of these options is to use the &lt;a href="http://sourceforge.net/projects/tribix/"&gt;Tribix emitter &lt;/a&gt;located on source forge.  The Tribix project offers emitters for RTF, PPT and XLS.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TAaxeqHn97I/AAAAAAAAAMw/DddnqMk4YwA/s1600/tribixdownload.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 374px; height: 400px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TAaxeqHn97I/AAAAAAAAAMw/DddnqMk4YwA/s400/tribixdownload.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5478261137003247538" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you wish to use just the XLS emitter, download the org.uguess.birt.report.engine.emitter.xls_version and org.uguess.birt.report.engine.common_version plugins and copy them to the plugins directory in your Eclipse install location.  You will also need to copy them to the runtime location as well.  For example, if you are using the WebViewer this will be the WebViewer/WEB-INF/Platform/plugins directory.  You will also need to remove org.eclipse.birt.report.engine.emitter.excel.config_version and org.eclipse.birt.report.engine.emitter.prototype.excel_version plugins from both locations to replace the out of the box XLS emitters.  Restart Eclipse with the –clean option and the Tribix emitter should work.  No API changes should be required if you are using the RE API.  New worksheets per page and image support should now work.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TAaxsnXP2xI/AAAAAAAAAM4/RuhATz-tch0/s1600/tribixcharts.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 283px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/TAaxsnXP2xI/AAAAAAAAAM4/RuhATz-tch0/s400/tribixcharts.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5478261376781638418" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you desire more XLS output options take a look at the Actuate XLS emitter that will be available in Actuate BIRT 11 which will be released this fall.  It allows exporting charts as either images or as native XLS charts.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TAax6eBaT1I/AAAAAAAAANA/-VciF0rEcIw/s1600/ActuateBIRTXLSChartoutput.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 212px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/TAax6eBaT1I/AAAAAAAAANA/-VciF0rEcIw/s400/ActuateBIRTXLSChartoutput.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5478261614792298322" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It also provides the capability to export formulas using a new scripting language called EasyScript, within the BIRT Expression Builder.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TAayFyN5S-I/AAAAAAAAANI/uV1DVAADbw0/s1600/ActuateEasyScript.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 255px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TAayFyN5S-I/AAAAAAAAANI/uV1DVAADbw0/s400/ActuateEasyScript.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5478261809191930850" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TAayMKhI8wI/AAAAAAAAANQ/lKlLwmWgh9I/s1600/ActuateFormulaExport.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 236px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TAayMKhI8wI/AAAAAAAAANQ/lKlLwmWgh9I/s400/ActuateFormulaExport.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5478261918794314498" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Actuate BIRT XLS emitter also offers the capability to export BIRT Crosstabs to native XLS Pivot Tables.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TAayWlbuNJI/AAAAAAAAANY/SbN_0HThDJ8/s1600/ActuateXLSPivotTable.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 257px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/TAayWlbuNJI/AAAAAAAAANY/SbN_0HThDJ8/s400/ActuateXLSPivotTable.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5478262097818039442" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you are interested in trying out the Actuate BIRT XLS emitter take a look at the Acutate 11 Milestone download page located on &lt;a href="http://www.birt-exchange.org/org/wiki/index.php?title=Actuate_11"&gt;BIRT-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-3778969513265826037?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/3778969513265826037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=3778969513265826037' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3778969513265826037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3778969513265826037'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/06/birt-excel-output.html' title='BIRT Excel Output'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GN1FyT5H8Kg/TAaxDA8otFI/AAAAAAAAAMo/m_7djTHKOBA/s72-c/opensourcexls.png' height='72' width='72'/><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7729014999280682496</id><published>2010-05-20T12:39:00.000-07:00</published><updated>2010-05-21T09:49:20.730-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Fonts'/><title type='text'>Adventures with Fonts</title><content type='html'>&lt;div&gt;One of the biggest problems facing report developers is how to efficiently support multiple languages using multiple output formats (HTML, PDF, Excel...)  BIRT provides support for multiple languages but the support is both OS and output format dependent.  Having gone through this process a couple of times, I have been asked to share my experiences, hopefully it will simplify the task if you run into similar issues.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;What I knew going in was that fonts are handled differently depending on the type of output. HTML fonts are rendered in the users browser, PDF fonts are rendered on the server by BIRT, and chart fonts are rendered on the server by Java AWT.  On top of all that, fonts in the development environment are rendered by SWT.   There are different ways to configure fonts for each of these situations.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;For HTML reports, the user must have the appropriate fonts installed on their machine.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;For PDF reports, BIRT renders the fonts on the server using information in the various fontsConfigXXX.xml files located in plugins/org.eclipse.birt.report.engine.fonts_XXX.  The base file is fontsConfig.xml and there are additional files to handle specific operating systems.   There are some useful comments in fontsConfig.xml that explain how this works.  I know these files are used for PDF generation and I think they are also used for rendering fonts in the development environment.  &lt;/div&gt;&lt;br /&gt;&lt;div&gt;From a previous font adventure, I knew that BIRT uses AWT to render charts, so font configuration is done in the lib folder of the JRE by manipulating various properties files.   Documentation on this seems to be a bit sketchy, but &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/fontconfig.html"&gt;this site&lt;/a&gt; has some information.  &lt;/div&gt;&lt;br /&gt;&lt;div&gt;My customer's problem, had to do with PDF output.  Thai characters were displaying as question marks in their 2.2.1.1 BIRT reports.   This was happening on all the OS's they ran, including Windows, Solaris and Linux.  The characters looked fine in HTML output, but the PDF rendered characters incorrectly. Their system administrator stated that they had full language packs installed on all of the machines.  &lt;/div&gt;&lt;br /&gt;&lt;div&gt;I started my investigations on their Windows box, running Windows Server 2003.  The first thing I looked at was the fontsConfig.xml file in plugins/org.eclipse.birt.report.engine.fonts_2.2.1.v20070823.  I noticed there was a block element for Thai in the commented out section:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&amp;lt;block name="Thai" start="e00" end="e7f" index="27" font-family="Font-Family"/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I realized this has the rather nice effect of dynamically switching fonts in mid-string whenever characters within this range are encountered.  There's no need to use a special font in the report design and that's particularly important in multi-lingual environments. &lt;/div&gt;&lt;br /&gt;&lt;div&gt;The only problem was the font family.   The sample element didn't tell me what it should be and I couldn't tell by looking looking at the font files in C:\windows\fonts.  I tried downloading several font viewers but none of them told me what I needed to know.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Then I had the good luck to check on my laptop, which runs Windows 7.  In Windows 7, the font listing in windows explorer shows lots more information about the fonts, including a column called "Designed For".  I found there were several fonts that were "designed for" Thai and Angsana New was one that also existed on their server.  I used Angsana New for the font family in the block element and restarted their web application and it fixed it!&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Next I had to preform this feat on their Solaris box.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Of course I tried Angsana New right off the bat, but it wasn't going to be that easy.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I started exploring the installed packages on my on Ubuntu box by searching for "font" in the synaptic package manager.  I found all kinds of programs and spent a good amount of time looking at the man pages for them and trying them out, but the only one I found that told me which fonts support which character ranges was gucharmap, the Gnome version of the character map program.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The left side has a list of "Scripts" and one of them was Thai.  Clicking on that showed the Thai character set (which is relatively small).  I found that holding the right mouse button down over a character would display its font name.  On my Ubuntu box the font was Waree, which worked for my machine but did not solve the client's issue.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Using gucharmap on the clients machine showed that their server was using AngsanaUPC.  A quick modification to the fontsConfigXXX.xml to use AngsanaUPC and the problem was resolved.  The main lesson I learned from this was how to find font families that support specific blocks of unicode characters.  &lt;/div&gt;&lt;br /&gt;&lt;div&gt;For windows, Windows 7 explorer works nicely.  I am unsure how to handle this if you are using XP.  For Linux gucharmap worked, but it was dependent on the particular distro of Linux.  The only downside to this approach was the need to have XWindows access.  I will continue looking for a good command line utility that can be used to research installed fonts on servers.  If anyone has found a utility like this, I would love to hear about it.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7729014999280682496?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7729014999280682496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7729014999280682496' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7729014999280682496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7729014999280682496'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/05/adventures-with-fonts.html' title='Adventures with Fonts'/><author><name>Steve Schafer</name><uri>http://www.blogger.com/profile/11330471240264633246</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7138858401335368573</id><published>2010-05-06T09:39:00.000-07:00</published><updated>2010-05-17T09:31:48.936-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Charts'/><title type='text'>More on Chart Interactivity</title><content type='html'>In an earlier post we examined chart interactivity with a focus on the Invoke Script Action, which allowed client side scripts to be called.  This post is available &lt;a href="http://birtworld.blogspot.com/2009/12/calling-client-side-javascript-from.html"&gt;here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;At the end of the post we mentioned predefined variables that are passed to the script that is invoked.  These variables are:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;evt &lt;/em&gt;– The Event Object.&lt;br /&gt;&lt;em&gt;categoryData &lt;/em&gt;– The Chart Category Value.&lt;br /&gt;&lt;em&gt;valueData &lt;/em&gt;– The Chart Orthogonal Value.&lt;br /&gt;&lt;em&gt;valueSeriesName &lt;/em&gt;– The specific Series Name.&lt;br /&gt;&lt;em&gt;legendItemText &lt;/em&gt;– The specific legend entry Text.&lt;br /&gt;&lt;em&gt;legendItemValue &lt;/em&gt;– The value of the specific legend entry. &lt;br /&gt;&lt;em&gt;axisLabel &lt;/em&gt;– The value of the specific axis label selected.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What these predefined variables contain depends on the chart type, how the chart is configured and what event is being fired.  For example if you define a Bar chart with legend interactivity and do not show the legend value, all the variables will be null with the exception of the evt Object and the legendItemText variable.  Generally these values will be populated like (evt object is always populated):&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Series Interactivity Invoke Script &lt;/em&gt;– categoryData, valueData, valueSeriesName populated, the rest are null. &lt;br /&gt;&lt;em&gt;Legend Interactivity Invoke Script&lt;/em&gt; – legendItemText and legendItemValue populated, the rest are null. &lt;br /&gt;&lt;em&gt;Axis Interactivity Invoke Script&lt;/em&gt; – axisLabel populated, the rest are null. &lt;br /&gt;&lt;em&gt;All other Interactivity Invoke Script&lt;/em&gt; – All are null.&lt;br /&gt;&lt;br /&gt;To see the values you can call an invoke script function to alert them.  For example, select a specific series on a chart within the third tab of the chart wizard and select interactivity.  For the event enter Mouse Click.  For the Action choose invoke script and enter the following script.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;ShowEventData(evt, categoryData, valueData, valueSeriesName, legendItemText, legendItemValue, axisLabel);&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S-LzBv19HNI/AAAAAAAAAMY/l733d-bX6gM/s1600/Interactivity1.png"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5468200108929391826" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S-LzBv19HNI/AAAAAAAAAMY/l733d-bX6gM/s400/Interactivity1.png" style="cursor: hand; cursor: pointer; display: block; height: 234px; margin: 0px auto 10px; text-align: center; width: 400px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Next add a text element to the report that has the following value.&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;&amp;lt;script language="JavaScript"&amp;gt;&lt;br /&gt;&lt;br /&gt;function ShowEventData(evt, categoryData, valueData, valueSeriesName, legendItemText, legendItemValue, axisLabel) {&lt;br /&gt;&lt;br /&gt;alert( "categoryData=" + categoryData + &lt;br /&gt;"\nvalueData=" + valueData + &lt;br /&gt;"\nvalueSeriesName=" + valueSeriesName + &lt;br /&gt;"\nlegendItemText=" + legendItemText + &lt;br /&gt;"\nlegendItemValue=" + legendItemValue + &lt;br /&gt;"\naxisLabel=" + axisLabel);&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Make sure you set the type to HTML for the text element.  The output when clicking on the series should look similar to:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S-Lz0U6T5AI/AAAAAAAAAMg/TKtHzy6i3xU/s1600/output.png"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5468200977873232898" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S-Lz0U6T5AI/AAAAAAAAAMg/TKtHzy6i3xU/s400/output.png" style="cursor: hand; cursor: pointer; display: block; height: 366px; margin: 0px auto 10px; text-align: center; width: 400px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;An example report that contains this event on all interactivity elements is available at &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/1206-chart-invoke-script-event-variables/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;An example that uses the predefined variables with client side script to toggle the visibly of a chart series is also available at &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/1207-toggle-visibility-of-series-based-on-client-side-script/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7138858401335368573?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='More on Chart Interactivity'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7138858401335368573/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7138858401335368573' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7138858401335368573'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7138858401335368573'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/05/more-on-chart-interactivity.html' title='More on Chart Interactivity'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GN1FyT5H8Kg/S-LzBv19HNI/AAAAAAAAAMY/l733d-bX6gM/s72-c/Interactivity1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-2618218586328434186</id><published>2010-04-22T09:26:00.000-07:00</published><updated>2010-05-17T09:29:51.797-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Charts'/><title type='text'>Multi-View Report Items</title><content type='html'>BIRT currently supports the concept of a multi-view report item.  What this means is that two report items share the same data bindings and physical space, but only one is displayed.  In the current version of BIRT only tables and crosstabs support this multi-view feature and the second view must be a chart.  Generally the view that is displayed is chosen at design time, but this can be altered using some script and a report parameter.  &lt;br /&gt;&lt;br /&gt;To create a multi-view report item, first create a table or crosstab.  Next right click on the report item and select Create Chart View.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S9B5K90GjTI/AAAAAAAAALo/_SlPN8Rw8lg/s1600/createchartview.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 294px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S9B5K90GjTI/AAAAAAAAALo/_SlPN8Rw8lg/s400/createchartview.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5462999577299160370" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This will launch t he Chart Builder.  Construct the chart as usual.  After creating the chart a second tab will appear at the bottom of the report item.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/S9B5VKfETYI/AAAAAAAAALw/gYgx2EYu43Q/s1600/multitab.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 199px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/S9B5VKfETYI/AAAAAAAAALw/gYgx2EYu43Q/s400/multitab.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5462999752499285378" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The tab selected currently determines which view will be displayed.  The selected view can also be changed with script and a report parameter.  First select the table tab and name the table.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/S9B5ot_yz5I/AAAAAAAAAL4/sFov38HzJP4/s1600/nametable.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 202px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/S9B5ot_yz5I/AAAAAAAAAL4/sFov38HzJP4/s400/nametable.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5463000088449306514" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In this case I have named the table “mytable”.  Next add a report parameter to use in the script.  The parameter should allow two choices, show as chart or show as table.  In this example I have named the report parameter ShowAs and the parameter has chartview or tableview as possible values.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S9B51xJnU3I/AAAAAAAAAMA/Pis3m5UsdME/s1600/parm.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 340px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S9B51xJnU3I/AAAAAAAAAMA/Pis3m5UsdME/s400/parm.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5463000312634102642" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Finally enter the following script in the beforeFactory event.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var th = reportContext.getDesignHandle().findElement("mytable");&lt;br /&gt;var mvh = th.getProperty("multiViews");&lt;br /&gt;&lt;br /&gt;if( params["ShowAs"].value == "chartview" ){&lt;br /&gt; mvh.setProperty("index", "0" );&lt;br /&gt;}else{&lt;br /&gt; mvh.setProperty("index", "-1" );&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The first line retrieves a handle to the table and the second retrieves a handle to the multiviews property for the table.  The parameter is then used to set the index for the multiview item.&lt;br /&gt;&lt;br /&gt;The output will look similar to:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S9B6OeBhrYI/AAAAAAAAAMI/FUTiRJ-DuMI/s1600/outputtable.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 363px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S9B6OeBhrYI/AAAAAAAAAMI/FUTiRJ-DuMI/s400/outputtable.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5463000736996633986" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/S9B6ZW0uYHI/AAAAAAAAAMQ/BPaSA4GGY8o/s1600/outputchart.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 326px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/S9B6ZW0uYHI/AAAAAAAAAMQ/BPaSA4GGY8o/s400/outputchart.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5463000924042453106" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This example is available at &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/1202-multi-view-table-chart-select-using-parameter/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-2618218586328434186?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='Multi-View Report Items'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/2618218586328434186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=2618218586328434186' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/2618218586328434186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/2618218586328434186'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/04/multi-view-report-items.html' title='Multi-View Report Items'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GN1FyT5H8Kg/S9B5K90GjTI/AAAAAAAAALo/_SlPN8Rw8lg/s72-c/createchartview.PNG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7953053627177598214</id><published>2010-03-28T14:30:00.000-07:00</published><updated>2010-03-28T15:07:02.397-07:00</updated><title type='text'>BIRT Roadshow Series Continues – Help decide the content!</title><content type='html'>In the past year Actuate has been running free one day BIRT training events, where users are introduced to BIRT technology by a series of talks followed by some hands on training exercises.  This road show series, which was conducted in major cities around the globe, has been heavily attended. &lt;br /&gt;&lt;br /&gt;Actuate is currently planning a new series that focuses on some of the more advanced topics of BIRT and is looking for feedback on what the community would like to see in the agenda.  Are you interested in learning more about Charting, Advanced Scripting, or Custom data sources? To provide input simply follow this &lt;a href="http://www.surveymonkey.com/s/57MBQRZ"&gt;link&lt;/a&gt;, which provides a form for your input.  It should take less than five minutes to complete.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7953053627177598214?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='BIRT Roadshow Series Continues – Help decide the content!'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7953053627177598214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7953053627177598214' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7953053627177598214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7953053627177598214'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/03/birt-roadshow-series-continues-help.html' title='BIRT Roadshow Series Continues – Help decide the content!'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-49694784302848995</id><published>2010-03-09T13:00:00.000-08:00</published><updated>2010-03-09T13:11:43.673-08:00</updated><title type='text'>BIRT 2.5.2 Enhancements</title><content type='html'>As BIRT 2.5.2 was released recently, I wanted to post on some of the new features available in the release.  BIRT 2.5.2 represents a maintenance release, which is generally dominated with bug fixes and not new enhancements, but this release does have a few that are worth noting.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;SQL Query Builder&lt;/strong&gt;&lt;br /&gt;The SQL Query Builder is now directly available without creating a connection profile.  When adding a new data source, the query builder is listed as one of the data sources available.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S5a3wKCfpsI/AAAAAAAAAK4/t0b51IHrX7k/s1600-h/newdatasource.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 390px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S5a3wKCfpsI/AAAAAAAAAK4/t0b51IHrX7k/s400/newdatasource.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5446742837307614914" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;After selecting the Query Builder data source you are prompted with a list of available databases.  Once you select the type of database you can then specify the specific driver and connection properties that will be used.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S5a37UgXUkI/AAAAAAAAALA/9aWLklO1kn4/s1600-h/driver.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 270px; height: 400px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S5a37UgXUkI/AAAAAAAAALA/9aWLklO1kn4/s400/driver.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5446743029095813698" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;One of the advantages to using this driver is that the jar location of the driver is a data source property and can be changed using Property Binding or an Event Handler Script.&lt;br /&gt;&lt;br /&gt;&amp;ltproperty name="jarList"&amp;gtC:\birt\mysql\mysql-connector-java-5.0.4-bin.jar&amp;lt/property&amp;gt&lt;br /&gt;&lt;br /&gt;After the data source is created, you create a dataset just like you would with any other BIRT data source.  The editor allows graphic query creation as shown in the following image.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/S5a4UFfmNoI/AAAAAAAAALI/p5VcP3htyGs/s1600-h/newdataset.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 358px; height: 400px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/S5a4UFfmNoI/AAAAAAAAALI/p5VcP3htyGs/s400/newdataset.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5446743454562793090" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Designer Classpath Configuration&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In prior releases of BIRT, the classloader while in the designer would search all projects within the workspace to locate a class that was used within the design.  This would happen for classes invoked used in expressions or JavaScript event handlers.  Event handlers written in Java where located in this fashion as well.  In BIRT 2.5.2 you can now configure the classpath for the workspace or for the individual project that BIRT will use.  To set this preference select the window-&gt;preferences-&gt;Report Design-&gt;Classpath entry.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/S5a4jYo1frI/AAAAAAAAALQ/kcYxJdH1yYs/s1600-h/classpath.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 334px; height: 400px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/S5a4jYo1frI/AAAAAAAAALQ/kcYxJdH1yYs/s400/classpath.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5446743717399854770" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Sorting Enhancement&lt;/strong&gt;&lt;br /&gt;BIRT provides sorting on many report items, such as tables, group sections, and crosstabs.  New for BIRT 2.5.2 is ability to set the collation strength and locale for the sorter.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S5a4uzt4gwI/AAAAAAAAALY/8Qp-us__5fI/s1600-h/sort.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 311px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S5a4uzt4gwI/AAAAAAAAALY/8Qp-us__5fI/s400/sort.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5446743913647342338" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Crosstab Cheat Sheet and Template&lt;/strong&gt;&lt;br /&gt;A new Report Template and Cheat Sheet are available for creating a cross tab style report.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S5a5GUO3rHI/AAAAAAAAALg/xdSBPDveOs0/s1600-h/xtab.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 397px; height: 400px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S5a5GUO3rHI/AAAAAAAAALg/xdSBPDveOs0/s400/xtab.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5446744317512625266" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Other enhancements are also in BIRT 2.5.2 and these can be viewed in &lt;a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced;bug_severity=enhancement;classification=BIRT;product=BIRT;target_milestone=2.5.2;target_milestone=2.5.2%20RC2;target_milestone=2.5.2%20RC3;target_milestone=2.5.2%20RC4"&gt;bugzilla&lt;/a&gt;.  The full list of bug fixes is also available with this &lt;a href="https://bugs.eclipse.org/bugs/buglist.cgi?query_format=advanced;target_milestone=2.5.2%20RC1;target_milestone=2.5.2;target_milestone=2.5.2%20RC2;target_milestone=2.5.2%20RC3;target_milestone=2.5.2%20RC4;product=BIRT;classification=BIRT"&gt;query&lt;/a&gt;.  You can download BIRT 2.5.2 &lt;a href="http://download.eclipse.org/birt/downloads/"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-49694784302848995?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='BIRT 2.5.2 Enhancements'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/49694784302848995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=49694784302848995' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/49694784302848995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/49694784302848995'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/03/birt-252-enhancements.html' title='BIRT 2.5.2 Enhancements'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GN1FyT5H8Kg/S5a3wKCfpsI/AAAAAAAAAK4/t0b51IHrX7k/s72-c/newdatasource.PNG' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-8859452173907933122</id><published>2010-02-22T14:04:00.000-08:00</published><updated>2010-02-22T14:27:57.573-08:00</updated><title type='text'>BIRT and Struts 2</title><content type='html'>BIRT offers several ways reports can be deployed. The AJAX based BIRT viewer can be deployed to your application server, the BIRT tag libraries can be used or you can deploy the Report Engine in your application.  You can also modify any of the above options, given that the source is available for download.  Several commercial options are also available.  This post explains deploying the BIRT engine as an Action component within Struts2.  It also discusses using Actuate’s JSAPI with Struts 2’s Bean tag.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;BIRT Engine Deployed to Struts 2&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;The BIRT report engine can be deployed as a Servlet and the process for doing this is described in the &lt;a href="http://wiki.eclipse.org/Servlet_Example_%28BIRT%29_2.1"&gt;BIRT wiki&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;If you happen to be using Struts 2 as your application framework you can deploy the Report Engine as an Action component.  The process for doing this is not much different than the Servlet approach described in the above link.  First you have to implement the ActionSupport class.  &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package org.birt.struts2;&lt;br /&gt;import java.io.InputStream;&lt;br /&gt;import java.io.OutputStream;&lt;br /&gt;import java.io.ByteArrayOutputStream;&lt;br /&gt;import java.io.ByteArrayInputStream;&lt;br /&gt;import org.apache.struts2.util.ServletContextAware;&lt;br /&gt;import org.apache.struts2.interceptor.ServletRequestAware; &lt;br /&gt;import javax.servlet.ServletContext;&lt;br /&gt;import javax.servlet.http.HttpServletRequest;&lt;br /&gt;&lt;br /&gt;import com.opensymphony.xwork2.ActionSupport;&lt;br /&gt;public class BirtStruts2 extends ActionSupport implements ServletContextAware, ServletRequestAware {&lt;br /&gt;&lt;br /&gt; private ByteArrayInputStream inputStream;&lt;br /&gt;&lt;br /&gt; public ByteArrayInputStream getInputStream() {&lt;br /&gt;  return inputStream;&lt;br /&gt; }&lt;br /&gt; private HttpServletRequest request;&lt;br /&gt; public void setServletRequest(HttpServletRequest request) {&lt;br /&gt;  this.request = request;&lt;br /&gt; }   &lt;br /&gt; private ServletContext context;  &lt;br /&gt; public void setServletContext(ServletContext context) {  &lt;br /&gt;  this.context = context;  &lt;br /&gt; }  &lt;br /&gt; public String execute() throws Exception {&lt;br /&gt;&lt;br /&gt;  RunBirt rb = new RunBirt();&lt;br /&gt;  inputStream = new ByteArrayInputStream(rb.runReport(this.context, this.request));&lt;br /&gt;&lt;br /&gt;  return SUCCESS;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;In this example we are going to create a RunBirt class that will return the report in a byte array.  The above BirtStruts2 class extends the ActionSupport class and implements ServletContextAware and ServletRequestAware.  The reason we implement the two extra interfaces is that the RunBirt class will need the ServletContext and the Request object.  The BirtStruts2 class also has an inputStream member that is used by the Struts 2 framework to handle the returned report.  The struts.config file is as follows:&lt;br /&gt;&lt;br /&gt;&amp;lt;!DOCTYPE struts PUBLIC&lt;br /&gt;    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"&lt;br /&gt;    "http://struts.apache.org/dtds/struts-2.0.dtd"&amp;gt;&lt;br /&gt;&amp;lt;struts&amp;gt;&lt;br /&gt;    &amp;lt;package name="BirtStruts2" extends="struts-default"&amp;gt;&lt;br /&gt;  &amp;lt;action name="BirtStruts2" class="org.birt.struts2.BirtStruts2"&amp;gt;&lt;br /&gt;  &amp;lt;result type="stream"&amp;gt;&lt;br /&gt;   &amp;lt;param name="contentType"&amp;gt;text/html&amp;lt;/param&amp;gt;&lt;br /&gt;   &amp;lt;param name="inputName"&amp;gt;inputStream&amp;lt;/param&amp;gt;&lt;br /&gt;  &amp;lt;/result&amp;gt;&lt;br /&gt;  &amp;lt;/action&amp;gt;  &lt;br /&gt;    &amp;lt;/package&amp;gt;&lt;br /&gt;&amp;lt;/struts&amp;gt;&lt;br /&gt;&lt;br /&gt;The result for the BirtStruts2 action is set to stream, the content type is set to html, and the inputStream  variable from our BirtStruts2 class is set as the inputName stream result parameter.  You will need to change the contentType if you plan on altering the example to return PDF, XLS, or Word.&lt;br /&gt;&lt;br /&gt;The RunBirt class is similar to the WebReport class described in the Wiki example.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public byte[] runReport(ServletContext sc, HttpServletRequest req) throws ServletException{&lt;br /&gt;&lt;br /&gt;  this.birtReportEngine = BirtEngine.getBirtEngine(sc);&lt;br /&gt;  &lt;br /&gt;  IReportRunnable design;&lt;br /&gt;  try&lt;br /&gt;  {&lt;br /&gt;   //Open report design&lt;br /&gt;   design = birtReportEngine.openReportDesign( sc.getRealPath("/Reports/TopNPercent.rptdesign") );&lt;br /&gt;   //create task to run and render report&lt;br /&gt;   IRunAndRenderTask task = birtReportEngine.createRunAndRenderTask( design );  &lt;br /&gt;   task.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY, RunBirt.class.getClassLoader()); &lt;br /&gt;   //task.getAppContext().put("BIRT_VIEWER_HTTPSERVLET_REQUEST", req );   &lt;br /&gt;   if( req.getParameter("TopCount") != null ){&lt;br /&gt;    task.setParameterValue("Top Count", Integer.valueOf(req.getParameter("TopCount")));&lt;br /&gt;   }&lt;br /&gt;   if( req.getParameter("TopPercentage") != null ){&lt;br /&gt;    task.setParameterValue("Top Percentage", Float.valueOf(req.getParameter("TopPercentage")));&lt;br /&gt;   }&lt;br /&gt;   //set output options&lt;br /&gt;   HTMLRenderOption options = new HTMLRenderOption();&lt;br /&gt;   options.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_HTML);&lt;br /&gt;   ByteArrayOutputStream oStream = new ByteArrayOutputStream(); &lt;br /&gt;   options.setOutputStream(oStream);&lt;br /&gt;   options.setImageHandler(new HTMLServerImageHandler());&lt;br /&gt;   options.setBaseImageURL(req.getContextPath()+"/images");&lt;br /&gt;   options.setImageDirectory(sc.getRealPath("/images"));   &lt;br /&gt;   task.setRenderOption(options);&lt;br /&gt;      &lt;br /&gt;   &lt;br /&gt;   //run report&lt;br /&gt;   task.run();&lt;br /&gt;   task.close();&lt;br /&gt;   return oStream.toByteArray();&lt;br /&gt;   &lt;br /&gt;  }catch (Exception e){&lt;br /&gt;   &lt;br /&gt;   e.printStackTrace();&lt;br /&gt;   throw new ServletException( e );&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you have used the BIRT Report Engine API there is nothing unique in this example for Struts 2.   The report name is hard-coded but could easily be changed to be set as a parameter.  The HTML render options are setup to write to a ByteArrayOutputStream which is then converted to a byte array and returned the BirtStruts2 class.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;HTMLRenderOption options = new HTMLRenderOption();&lt;br /&gt;options.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_HTML);&lt;br /&gt;ByteArrayOutputStream oStream = new ByteArrayOutputStream(); &lt;br /&gt;options.setOutputStream(oStream);&lt;br /&gt;options.setImageHandler(new HTMLServerImageHandler());&lt;br /&gt;options.setBaseImageURL(req.getContextPath()+"/images");&lt;br /&gt;options.setImageDirectory(sc.getRealPath("/images"));   &lt;br /&gt;task.setRenderOption(options);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The images directory and base URL (pre-pended to the img src tag in the output) are also set based on the passed in ServletContext and Request objects.  The only other class is the BirtEngine class which is desribed in the Wiki example but is shown here for completeness.  This class provides static synchronized method to return the ReportEngine.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package org.birt.struts2;&lt;br /&gt;import javax.servlet.ServletContext;&lt;br /&gt;import javax.servlet.ServletConfig;&lt;br /&gt;import javax.servlet.ServletException;&lt;br /&gt;import javax.servlet.http.HttpServlet;&lt;br /&gt;import javax.servlet.http.HttpServletRequest;&lt;br /&gt;import javax.servlet.http.HttpServletResponse;&lt;br /&gt;&lt;br /&gt;import org.eclipse.birt.report.engine.api.EngineConstants;&lt;br /&gt;import org.eclipse.birt.report.engine.api.HTMLRenderOption;&lt;br /&gt;import org.eclipse.birt.report.engine.api.IReportRunnable;&lt;br /&gt;import org.eclipse.birt.report.engine.api.IRunAndRenderTask;&lt;br /&gt;import org.eclipse.birt.report.engine.api.IReportEngine;&lt;br /&gt;import org.eclipse.birt.report.engine.api.HTMLServerImageHandler;&lt;br /&gt;import org.eclipse.birt.report.engine.api.PDFRenderOption;&lt;br /&gt;import org.eclipse.birt.report.engine.api.RenderOption;&lt;br /&gt;import java.io.ByteArrayOutputStream;&lt;br /&gt;&lt;br /&gt;public class RunBirt{&lt;br /&gt;private IReportEngine birtReportEngine = null;&lt;br /&gt;&lt;br /&gt;package org.birt.struts2;&lt;br /&gt;&lt;br /&gt;import java.io.InputStream;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.util.Properties;&lt;br /&gt;import java.util.logging.Level;&lt;br /&gt;&lt;br /&gt;import org.eclipse.birt.report.engine.api.EngineConfig;&lt;br /&gt;import org.eclipse.birt.report.engine.api.IReportEngine;&lt;br /&gt;import javax.servlet.*;&lt;br /&gt;import org.eclipse.birt.core.framework.PlatformServletContext;&lt;br /&gt;import org.eclipse.birt.core.framework.IPlatformContext;&lt;br /&gt;import org.eclipse.birt.core.framework.Platform;&lt;br /&gt;import org.eclipse.birt.core.exception.BirtException;&lt;br /&gt;import org.eclipse.birt.report.engine.api.IReportEngineFactory;&lt;br /&gt;import org.eclipse.birt.report.engine.api.ReportEngine;&lt;br /&gt;import javax.servlet.http.HttpServletRequest;&lt;br /&gt;&lt;br /&gt;public class BirtEngine {&lt;br /&gt;&lt;br /&gt; private static IReportEngine birtEngine = null;&lt;br /&gt;&lt;br /&gt; private static Properties configProps = new Properties();&lt;br /&gt;&lt;br /&gt; private final static String configFile = "BirtConfig.properties";&lt;br /&gt;&lt;br /&gt; public static synchronized void initBirtConfig() {&lt;br /&gt;  loadEngineProps();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static synchronized IReportEngine getBirtEngine(ServletContext sc) {&lt;br /&gt;  if (birtEngine == null) &lt;br /&gt;  {&lt;br /&gt;   EngineConfig config = new EngineConfig();&lt;br /&gt;   if( configProps != null){&lt;br /&gt;    String logLevel = configProps.getProperty("logLevel");&lt;br /&gt;    Level level = Level.OFF;&lt;br /&gt;    if ("SEVERE".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.SEVERE;&lt;br /&gt;    } else if ("WARNING".equalsIgnoreCase(logLevel))&lt;br /&gt;    {&lt;br /&gt;     level = Level.WARNING;&lt;br /&gt;    } else if ("INFO".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.INFO;&lt;br /&gt;    } else if ("CONFIG".equalsIgnoreCase(logLevel))&lt;br /&gt;    {&lt;br /&gt;     level = Level.CONFIG;&lt;br /&gt;    } else if ("FINE".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.FINE;&lt;br /&gt;    } else if ("FINER".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.FINER;&lt;br /&gt;    } else if ("FINEST".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.FINEST;&lt;br /&gt;    } else if ("OFF".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.OFF;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    config.setLogConfig(configProps.getProperty("logDirectory"), level);&lt;br /&gt;   }&lt;br /&gt;config.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY, BirtEngine.class.getClassLoader());&lt;br /&gt;   config.setEngineHome("");&lt;br /&gt;   &lt;br /&gt;   IPlatformContext context = new PlatformServletContext( sc );&lt;br /&gt;   config.setPlatformContext( context );&lt;br /&gt;   &lt;br /&gt;   try&lt;br /&gt;   {&lt;br /&gt;    Platform.startup( config );&lt;br /&gt;   }&lt;br /&gt;   catch ( BirtException e )&lt;br /&gt;   {&lt;br /&gt;    e.printStackTrace( );&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   IReportEngineFactory factory = (IReportEngineFactory) Platform&lt;br /&gt;   .createFactoryObject( IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY );&lt;br /&gt;   birtEngine = factory.createReportEngine( config );&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;  return birtEngine;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public static synchronized void destroyBirtEngine() {&lt;br /&gt;  if (birtEngine == null) {&lt;br /&gt;   return;&lt;br /&gt;  }  &lt;br /&gt;  birtEngine.destroy();&lt;br /&gt;  Platform.shutdown();&lt;br /&gt;  birtEngine = null;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;To call this code you can implement a page similar to the following:&lt;br /&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;    &amp;lt;head&amp;gt;&lt;br /&gt;  &amp;lt;/head&amp;gt;&lt;br /&gt;    &amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;s:form action="/BirtStruts2.action" method="POST"&amp;gt;&lt;br /&gt;      &amp;lt;s:textfield name="TopCount" label="Top Count"/&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;      &amp;lt;s:textfield name="TopPercentage" label="Top Percentage"/&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;         &amp;lt;s:submit value="Run Report" align="center"/&amp;gt;&lt;br /&gt;    &amp;lt;/s:form&amp;gt;&lt;br /&gt;  &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;This example has very little error checking for brevity.  Also note that the report engine should be shutdown using a context listener, but should not be shutdown while the context is up and running as starting the engine is resource intensive.  Finally no code is provided in the example to remove image files that are generated by the engine in the images directory.&lt;br /&gt;&lt;br /&gt;The complete example with ant build and a readme that describes where to put the BIRT plugins and libs is available at &lt;a href="http://www.birt-exchange.org/devshare/deploying-birt-reports/1162-birt-engine-deployed-to-struts-2/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Example Output:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S4MDRa4aeoI/AAAAAAAAAKo/JTSCzYxKuqI/s1600-h/birtstruts2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 320px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S4MDRa4aeoI/AAAAAAAAAKo/JTSCzYxKuqI/s320/birtstruts2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5441196372602288770" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Using Actuate’s JSAPI with Struts 2&lt;/strong&gt;&lt;br /&gt;If you are using Actuate’s JSAPI, integration with Struts 2 is very easy as the API is AJAX based and can be included in virtually any front-end.  One interesting way the two technologies can be deployed together is to use the Struts 2 Bean tag to pass parameters to the JSAPI.  For example assume we have the following bean class.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package com.actuate.jsapi.struts2;&lt;br /&gt;&lt;br /&gt;public class MyRegionBean  {&lt;br /&gt;&lt;br /&gt; private String region;&lt;br /&gt; private String rep;&lt;br /&gt;&lt;br /&gt; public String getRegion(){&lt;br /&gt;  //expecting rep passed in and region lookup in db&lt;br /&gt;  //based on the rep.  Hard coded for example purposes&lt;br /&gt;  this.region = "EMEA";&lt;br /&gt;  return region;&lt;br /&gt; }&lt;br /&gt; public void setRegion(String nRegion ){&lt;br /&gt;  this.region = nRegion;&lt;br /&gt; }&lt;br /&gt; public String getRep(){&lt;br /&gt;  return rep;&lt;br /&gt; }&lt;br /&gt; public void setRep(String nRep ){&lt;br /&gt;  this.rep = nRep;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This bean can be used in conjunction with the JSAPI to pass report parameters to the Report Engine.&lt;br /&gt;&lt;br /&gt;&amp;lt;%@ taglib prefix="s" uri="/struts-tags" %&amp;gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;JSAPI Struts 2&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div id="acviewer" /&amp;gt;&lt;br /&gt;&amp;lt;div id="jsapi_example_container"&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&lt;br /&gt; src="http://localhost:8080/ActuateJavaComponent/jsapi"&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;  actuate.load("viewer");&lt;br /&gt;  actuate.initialize("http://localhost:8080/ActuateJavaComponent/",&lt;br /&gt;  null,&lt;br /&gt;  null,&lt;br /&gt;  null,&lt;br /&gt;  initViewer);&lt;br /&gt;  var viewer;&lt;br /&gt;  function initViewer()&lt;br /&gt;  {&lt;br /&gt;   viewer = new actuate.Viewer("acviewer");&lt;br /&gt;   var viewerwidth = 800;&lt;br /&gt;   var viewerheight = 620; &lt;br /&gt;   viewer.setWidth(viewerwidth);&lt;br /&gt;   viewer.setHeight(viewerheight);&lt;br /&gt;   runInitial();&lt;br /&gt;  }&lt;br /&gt;  function runInitial()&lt;br /&gt;  { &lt;br /&gt;   &amp;lt;s:bean name="com.actuate.jsapi.struts2.MyRegionBean"&amp;gt;&lt;br /&gt;   &amp;lt;s:param name="rep" value="John Smith" /&amp;gt;&lt;br /&gt;   viewer.setParameters({"Territory":"&amp;lt;s:property value="region" /&amp;gt;"});&lt;br /&gt;   &amp;lt;/s:bean&amp;gt;  &lt;br /&gt;   viewer.setReportName("/Public/BIRT and BIRT Report Studio Examples/Sales by Territory.rptdesign");&lt;br /&gt;   viewer.submit();&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt; &lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;In the runInitial JavaScript function the viewer components setParameters method is called passing the value of the bean’s region member variable as the value for the Territory report parameter.&lt;br /&gt;&lt;br /&gt;More information is available on the JSAPI &lt;a href="http://www.birt-exchange.org/wiki/GSG:Getting_Started_with_BIRT_JavaScript_API/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The example is available at &lt;a href="http://www.birt-exchange.org/devshare/deploying-birt-reports/1163-actuate-jsapi-with-struts-2/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Output for this example is as follows:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/S4MEaurjxwI/AAAAAAAAAKw/TQgUHzBf7sE/s1600-h/jsapistruts2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 251px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/S4MEaurjxwI/AAAAAAAAAKw/TQgUHzBf7sE/s320/jsapistruts2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5441197632047531778" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-8859452173907933122?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='BIRT and Struts 2'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/8859452173907933122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=8859452173907933122' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/8859452173907933122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/8859452173907933122'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/02/birt-and-struts-2.html' title='BIRT and Struts 2'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GN1FyT5H8Kg/S4MDRa4aeoI/AAAAAAAAAKo/JTSCzYxKuqI/s72-c/birtstruts2.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7700416754011254743</id><published>2010-02-18T14:27:00.000-08:00</published><updated>2010-06-02T12:15:53.768-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>BIRT Controls and Functions - Update</title><content type='html'>We have updated the BIRT Functions and BIRT Controls libraries today to support versions 2.3.2 and 2.5.1. &amp;nbsp;Turns out that there were some minor changes that needed to be addressed. &amp;nbsp;In addition, we did a bit of work to make the naming and version numbering more consistent.&lt;br /&gt;&lt;br /&gt;The biggest question I faced was how to do the version numbering for these plugins. &amp;nbsp;As they stand, they are sub components to BIRT, which as a very specific version scheme. &amp;nbsp;We thought about using version numbers that did not track BIRT versions at all. &amp;nbsp;But then I started writing the documentation. &lt;br /&gt;&lt;blockquote&gt;If you are using BIRT 2.3.2 then you should use 1.0.1 of the BIRT Controls...&lt;/blockquote&gt;Started to feel more like &lt;i&gt;"you put your left foot in, ...". &amp;nbsp;&lt;/i&gt;I think that there is a lot of value in making developers write the documentation. &amp;nbsp;When you write your own docs, you quickly figure out when things that you have come to accept are really more difficult then they should be. &lt;br /&gt;&lt;br /&gt;Rather than write a bunch of hokey pokey build instructions, we decided to generate the components one more time using version numbers that will be easy for the component consumers. &amp;nbsp;So it may not follow the &lt;a href="http://wiki.eclipse.org/index.php/Version_Numbering"&gt;Eclipse version number guidelines&lt;/a&gt;, but it is easy for our clients. &lt;br /&gt;&lt;br /&gt;And easy for our clients is my number one goal.&lt;br /&gt;BIRT Controls and BIRT Functions version guidelines.&lt;br /&gt;&lt;b&gt;If you are using BIRT 2.3.2, then use version 2.3.2.X of our components. &lt;/b&gt;&lt;br /&gt;&lt;b&gt;If you are using BIRT 2.5.1, then use version 2.5.1.X of our components. &amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Also along the easy = good theme. &amp;nbsp;I wanted to share how much I enjoy working with Google Code. &amp;nbsp;I know that the Eclipse foundation is talking about doing some form of easy to use Eclipse Foundry type site, but in the absence of details on what is going on there, I went with Google. &amp;nbsp;It has been very easy to create a project, with all the trappings a small project needs.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Home Page check&lt;/li&gt;&lt;li&gt;Wiki check&lt;/li&gt;&lt;li&gt;Issue Tracking check&lt;/li&gt;&lt;li&gt;Version Control (SVN or Hg) check&lt;/li&gt;&lt;li&gt;Downloads check&lt;/li&gt;&lt;li&gt;Update Site check (right out of the the SVN repository)&lt;/li&gt;&lt;li&gt;Administration and Security check&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Makes me wonder if the foundation really needs to create our own infrastructure to manage a foundry. Perhaps there is a way to leverage an existing code foundry and focus on creating a great migration path from the foundry to the Eclipse infrastructure. &lt;br /&gt;&lt;br /&gt;The other thing that I really love are the market places that I can use to get the word out about these controls. As a small company, we don't have a huge marketing staff (any marketing). &amp;nbsp;So having not one but two great outlets that help us get the word out about our component is super helpful. &amp;nbsp;Thanks again to&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.birt-exchange.com/be/marketplace/hub/"&gt;BIRT Exchange Market Place&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://marketplace.eclipse.org/"&gt;Eclipse Market Place&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Enough rambling, I have to go write some docs...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7700416754011254743?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7700416754011254743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7700416754011254743' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7700416754011254743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7700416754011254743'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/02/birt-controls-and-functions-update.html' title='BIRT Controls and Functions - Update'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-467722829672168653</id><published>2010-02-11T11:09:00.000-08:00</published><updated>2010-06-02T12:15:53.768-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>BIRT Crosstab scripting</title><content type='html'>BIRT supplies scripting hooks for just about every report element in the palette.  You can generally implement an onPrepare, onCreate, and onRender event handler for each of these report items.  The onPrepare event fires before data is retrieved and allows you to change the design for a specific report item.  The onCreate event fires when the report item is being created by the report engine’s generation task.  The onRender event fires when the report item is being rendered by the report engine’s render task.  These events and example are described on the &lt;a href="http://www.eclipse.org/birt/phoenix/deploy/reportScripting.php"&gt;BIRT website&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Some report items offer more event hooks.  For example a chart item actually has over thirty event hooks that allow total customization of the chart generation and presentation phases.  As a side note, all chart scripts fire during the report engine’s render task.  This does not mean the database is hit at render time though.  The report engine will cache the data for a chart in memory or in a report document, depending on what task type is being used to run and render the report.&lt;br /&gt;&lt;br /&gt;The BIRT crosstab element offers onPrepare, onCreate and onRender hooks as well.  These events are fired both for the crosstab as a whole and for each individual cell in the crosstab.  When firing events for cells, these are processed top to bottom and left to right.  Handlers can be written using the script tab at the bottom of the report design view.  BIRT also supplies an event adapter to allow you to write these events in Java as well.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/S3RWaEDT4UI/AAAAAAAAAKA/jpRYi8DXK50/s1600-h/xtabevents.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 92px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/S3RWaEDT4UI/AAAAAAAAAKA/jpRYi8DXK50/s320/xtabevents.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5437065655907246402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As an example script, you can modify the crosstab in the onPrepare like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function onPrepareCrosstab( crosstab, reportContext )&lt;br /&gt;{&lt;br /&gt; var coldim = crosstab.getColumnLevels().get(0);&lt;br /&gt; coldim.removeAllFilterConditions(); &lt;br /&gt; crosstab.getStyle().setFontFamily("Arial");&lt;br /&gt; crosstab.getStyle().setFontSize("8");&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This script removes filters from the first column level and sets some font information.  Some of the more interesting capabilities are available when using the onCreateCell event hook.  For example consider the following script.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function onCreateCell( cellInst, reportContext )&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; //Can reference cells by type or id - valid types "header" or "aggregation"&lt;br /&gt; if(  cellInst.getCellType() == "header" ) {&lt;br /&gt;  //Get data values see binding tab on crosstab&lt;br /&gt;  //if( cellInst.getDataValue("PRODUCTLINE") == "Planes" ){&lt;br /&gt;  if( reportContext.evaluate("dimension['ProductGroup']['PRODUCTLINE']") == "Planes" ){&lt;br /&gt;   cellInst.getStyle().setBackgroundColor("#FF0000");&lt;br /&gt;   cellInst.getStyle().setFontSize("12");&lt;br /&gt;  }else{&lt;br /&gt;   //Set the rest to yellow&lt;br /&gt;   cellInst.getStyle().setBackgroundColor("#FFFF00");&lt;br /&gt;   cellInst.getStyle().setFontSize("12");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt; //refer to crosstab header&lt;br /&gt; if( cellInst.getCellID() == 167){&lt;br /&gt;  cellInst.getStyle().setBackgroundColor("Orange");&lt;br /&gt; } &lt;br /&gt; if( cellInst.getCellType() == "aggregation"){&lt;br /&gt;  //Can refernce value using getDataValue or &lt;br /&gt;  if( cellInst.getDataValue("PRODUCTLINE") == "Planes" ){&lt;br /&gt;   //set color to bluegray&lt;br /&gt;   cellInst.getStyle().setBackgroundColor("RGB(169,170,226)");&lt;br /&gt;  }&lt;br /&gt;  //by using reportContext.evaluate&lt;br /&gt;  //if( reportContext.evaluate("measure['amount']") &gt; 50000 ){&lt;br /&gt;  if( cellInst.getDataValue("amount_DateGroup/quarter_ProductGroup/PRODUCTLINE") &gt; 50000 ){&lt;br /&gt;   cellInst.getStyle().setBackgroundColor("Green");&lt;br /&gt;   cellInst.getStyle().setColor("White");&lt;br /&gt;  }&lt;br /&gt; } &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The onCreateCell script is passed the reportContext and an instance of the cell.  The cellInst object has several methods that can be used to determine which cell is currently being processed. You can call getCellType() which will return header or aggregation.  In the following image all cells in the red box will return aggregation and all others will return header.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S3RW93OKgyI/AAAAAAAAAKI/vQ_6MA94kfg/s1600-h/getcelltype.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 51px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S3RW93OKgyI/AAAAAAAAAKI/vQ_6MA94kfg/s320/getcelltype.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5437066270938399522" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can also call getCellID() which will return the specific element id that your crosstab uses for that cell.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S3RXLXPVh6I/AAAAAAAAAKQ/sII6KaO82vA/s1600-h/getcellid.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 118px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S3RXLXPVh6I/AAAAAAAAAKQ/sII6KaO82vA/s320/getcellid.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5437066502871549858" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In this example the getCellID call will return 160 every time this cell is created.  This can be useful when you are trying to determine if you have a new row or column in your crosstab.  If this is the innermost header element then this cell will be created for every new row/column.  The only drawback to this approach is that if the crosstab is in a library or you copy and paste it, the cell ids will change.  &lt;br /&gt;&lt;br /&gt;Once you know the cell you are currently processing you generally want to access the data, to make some script decision.  To do this you have a couple of choices.  You can call the getDataValue method on the cell instance or use the reportContext.evaluate method.  When using the getDataValue method, the value you need to refer to is the data binding column name set on the crosstab item.  For example:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cellInst.getDataValue("PRODUCTLINE") == "Planes"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;refers to the PRODUCTLINE data binding.  Also note that this is the value of the column as this particular cell is being processed.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S3RXg5taBgI/AAAAAAAAAKY/F3ieZP_qlg0/s1600-h/getdatavalue.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 113px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S3RXg5taBgI/AAAAAAAAAKY/F3ieZP_qlg0/s320/getdatavalue.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5437066872901731842" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You can also use the reportContext.evaluate method, which allows you to build an expression and bypass the binding.  For example:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;if( reportContext.evaluate("dimension['ProductGroup']['PRODUCTLINE']") == "Planes" )&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Essentially returns the same value as the previous getDataValue(“PRODUCTLINE”) method.  This is because the PRODUCTLINE data binding has:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;dimension['ProductGroup']['PRODUCTLINE']&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;As it’s expression.  This example references a particular dimension of the cube.  You can reference cube measures as well.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;reportContext.evaluate("measure['amount']")&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;As with the column binding this will return the value for the specific cell you are currently processing.  &lt;br /&gt;&lt;br /&gt;In the script posted at the top of this post, we use the cell instance object to set specific styling based on the values of various column bindings.  This is done using the getStyle method.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;cellInst.getStyle().setBackgroundColor("Green");&lt;br /&gt;cellInst.getStyle().setColor("White");&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Using this method is no different than other BIRT report items. &lt;br /&gt;&lt;br /&gt;Using these methods and the reportContext you can write some very sophisticated scripts.  For example you can store all the quantities ordered where the product line is ships to a global variable using a script similar to this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; if( cellInst.getCellType() == "aggregation" &amp;&amp; cellInst.getCellID() == 151){&lt;br /&gt;  if( cellInst.getDataValue("PRODUCTLINE") == "Ships" ){&lt;br /&gt;   importPackage(Packages.java.lang );&lt;br /&gt;   var cur = cellInst.getDataValue("amount_DateGroup/quarter_ProductGroup/PRODUCTLINE");&lt;br /&gt;   if( reportContext.getGlobalVariable("totalplanes")==null){&lt;br /&gt;    reportContext.setGlobalVariable("totalplanes", new Double(Double.parseDouble(cur)) );   &lt;br /&gt;   }else{&lt;br /&gt;    var oldcnt = reportContext.getGlobalVariable("totalplanes");&lt;br /&gt;    reportContext.setGlobalVariable("totalplanes", new Double(Double.parseDouble(oldcnt) + Double.parseDouble(cur)));  &lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This value can then be referenced within the same crosstab or later in the report.  For example the following expression for a text item can be used.&lt;br /&gt;&lt;br /&gt;&amp;lt;VALUE-OF format="#,##0.00"&amp;gt;reportContext.getGlobalVariable("totalplanes");&amp;lt;/VALUE-OF&amp;gt;&lt;br /&gt;&lt;br /&gt;This example can also be implemented in Java.  In the attached link the report will contain two crosstabs.  One where the code is done in JavaScript and the other uses an event handler written in Java, which is also attached.&lt;br /&gt;&lt;br /&gt;The example report output is presented below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S3RY_ZF9uQI/AAAAAAAAAKg/urTd2a2evNc/s1600-h/reportout.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 286px; height: 320px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/S3RY_ZF9uQI/AAAAAAAAAKg/urTd2a2evNc/s320/reportout.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5437068496233937154" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The examples are available at &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/1156-crosstab-scripting-java-javascript/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-467722829672168653?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='BIRT Crosstab scripting'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/467722829672168653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=467722829672168653' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/467722829672168653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/467722829672168653'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/02/birt-crosstab-scripting.html' title='BIRT Crosstab scripting'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_GN1FyT5H8Kg/S3RWaEDT4UI/AAAAAAAAAKA/jpRYi8DXK50/s72-c/xtabevents.PNG' height='72' width='72'/><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-1470980849788807826</id><published>2010-02-02T14:49:00.000-08:00</published><updated>2010-02-02T14:49:24.194-08:00</updated><title type='text'>Remus Uses BIRT</title><content type='html'>I read about the &lt;a href="http://eclipse.org/proposals/remus/"&gt;Remus &lt;/a&gt;project on &lt;a href="http://www.richclient2.eu/2010_02_02/building-datacentric-rcprap-applications-with-remus-proposed-as-eclipse-project/"&gt;Planet Eclipse&lt;/a&gt; today and was intrigued. &amp;nbsp; Looking at the draft project proposal:&lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: small;"&gt;With today's information technologies, the amount of information we consume daily is enormous. Efficient management and fast access to frequently used information has become more important than ever. The fact that we use a wide range of applications and digital mediums makes the aggregation of information, search and retrieval even more difficult. Managing a huge amount of information successfully requires an intelligent tool that enables users to file, categorize and visualize such diverse types of data as information units in a single application.&lt;/span&gt;&lt;/blockquote&gt;And now I am very intrigued, my company Innovent Solutions works in this very space. &amp;nbsp;Naturally, I wondered about how BIRT could interact with Remus. &amp;nbsp;Turns out that they have &lt;a href="http://www.richclient2.eu/2009_11_23/building-reports-of-your-local-information-pool-with-birt-and-remus/"&gt;created an ODA for BIRT&lt;/a&gt; and have bundled some reports. &amp;nbsp;&lt;br /&gt;&lt;br /&gt;Looks like another nice use of BIRT.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-1470980849788807826?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/1470980849788807826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=1470980849788807826' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1470980849788807826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1470980849788807826'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/02/remus-uses-birt.html' title='Remus Uses BIRT'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7318270866043692795</id><published>2010-01-28T10:48:00.000-08:00</published><updated>2010-01-28T10:51:02.102-08:00</updated><title type='text'>BIRT 2.5 Integration Webinar</title><content type='html'>For those who attended the Webinar we did this week, I am attaching the slides and examples.  They are available at &lt;a href="http://www.birt-exchange.org/devshare/deploying-birt-reports/1145-birt-2-5-integration-webinar/#description"&gt;BIRT Exchange&lt;/a&gt;.  If you did not get a chance to participate, the recording is available at &lt;a href="http://live.eclipse.org/node/856"&gt;Eclipse Live&lt;/a&gt;.  The examples illustrate different deployment and use cases and were built using BIRT 2.5.&lt;br /&gt;&lt;br /&gt;Thanks Lynn for putting this together.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7318270866043692795?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='BIRT 2.5 Integration Webinar'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7318270866043692795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7318270866043692795' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7318270866043692795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7318270866043692795'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/01/birt-25-integration-webinar.html' title='BIRT 2.5 Integration Webinar'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-1521830653432768332</id><published>2010-01-15T09:29:00.000-08:00</published><updated>2010-01-27T14:27:25.715-08:00</updated><title type='text'>Using Actuate’s JSAPI with a JBoss SEAM component</title><content type='html'>If you are using Actuate’s JSAPI to run BIRT reports and you wish to pass parameters from a SEAM component this can be done very easily.  In addition you can combine SEAM remoting with the JSAPI to do some interesting things.  For example assume we create a SEAM component that retrieves report parameters that we want to use with the JSAPI.  The component would look similar to this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package com.actuate.seam.example;&lt;br /&gt;&lt;br /&gt;import org.jboss.seam.annotations.*;&lt;br /&gt;import org.jboss.seam.*;&lt;br /&gt;import org.jboss.seam.annotations.remoting.WebRemote;&lt;br /&gt;&lt;br /&gt;@Name("reportParameters")&lt;br /&gt;@Scope(ScopeType.SESSION)&lt;br /&gt;public class ReportParameters {&lt;br /&gt;    private String parmName = "";&lt;br /&gt;    private String parmValue = "";&lt;br /&gt;    public String getParmName() {&lt;br /&gt;        return parmName;&lt;br /&gt;    }&lt;br /&gt;    public void setParmName(String pn) {&lt;br /&gt;        this.parmName = pn;&lt;br /&gt;    }&lt;br /&gt;    public String getParmValue() {&lt;br /&gt;        return parmValue;&lt;br /&gt;    }&lt;br /&gt;    public void setParmValue(String pv) {&lt;br /&gt;        this.parmValue = pv;&lt;br /&gt;    } &lt;br /&gt;    @Create&lt;br /&gt;    public void initData() {&lt;br /&gt;  setParmName("customer");&lt;br /&gt;  setParmValue("CAF Imports");&lt;br /&gt;    }&lt;br /&gt; @WebRemote&lt;br /&gt; public String getAlternateReport() {&lt;br /&gt;      return "/Public/BIRT and BIRT Report Studio Examples/Top 5 Sales Performers.rptdesign";&lt;br /&gt; }           &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;All we have in this class is a report parameter name and value.  Obviously the values would not be hard coded but for simplicity they are in this example.  We also have one web remote method to retrieve the path of a specific report.  We will use this to change the report being rendered via SEAM remoting.  The XHTML page would look like the following:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;br /&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&lt;br /&gt; xmlns:ui="http://java.sun.com/jsf/facelets"&lt;br /&gt; xmlns:h="http://java.sun.com/jsf/html"&lt;br /&gt; xmlns:s="http://jboss.com/products/seam/taglib"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Seam Remoting - Actuate JSAPI Example&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;h1&amp;gt;Seam Remoting -Actuate JSAPI Example&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;s:remote include="reportParameters" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;button onclick="javascript:changeReport()"&amp;gt;Change Report&amp;lt;/button&amp;gt;&lt;br /&gt;&amp;lt;div id="acviewer" /&amp;gt;&lt;br /&gt;&amp;lt;div id="jsapi_example_container"&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&lt;br /&gt; src="http://localhost:8080/ActuateJavaComponent/jsapi"&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;  actuate.load("viewer");&lt;br /&gt;  actuate.initialize("http://localhost:8080/ActuateJavaComponent/",&lt;br /&gt;  null,&lt;br /&gt;  null,&lt;br /&gt;  null,&lt;br /&gt;  initViewer);&lt;br /&gt;  var viewer;&lt;br /&gt;  function initViewer()&lt;br /&gt;  {&lt;br /&gt;   viewer = new actuate.Viewer("acviewer");&lt;br /&gt;   var viewerwidth = 800;&lt;br /&gt;   var viewerheight = 620; &lt;br /&gt;   viewer.setWidth(viewerwidth);&lt;br /&gt;   viewer.setHeight(viewerheight);&lt;br /&gt;   runInitial();&lt;br /&gt;  }&lt;br /&gt;  function runAlternate(newReport)&lt;br /&gt;  {&lt;br /&gt;   viewer.setReportName(newReport);&lt;br /&gt;   viewer.submit();&lt;br /&gt;  }&lt;br /&gt;  function runInitial()&lt;br /&gt;  { &lt;br /&gt;   viewer.setParameters({"#{reportParameters.parmName}":"#{reportParameters.parmValue}"});&lt;br /&gt;   viewer.setReportName("/Public/BIRT and BIRT Report Studio Examples/Customer Order History.rptdesign");&lt;br /&gt;   viewer.submit();&lt;br /&gt;  }&lt;br /&gt;     function changeReport() {&lt;br /&gt;         var callback = function(newReport) { runAlternate(newReport); };&lt;br /&gt;        Seam.Component.getInstance("reportParameters").getAlternateReport(callback);&lt;br /&gt;     }&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;We use the standard JSAPI viewer tag to run the report, with the EL-Bindings to retrieve the report parameter name and value when the page is loaded.  The page also has a button to change the report.  This button uses SEAM remoting to call the getAlternateReport method which returns the path to the new report.  The callback function then calls the runAlternate JavaScript method which in turn calls the JSAPI to run the new report.  When the page is first loaded the following is displayed.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S1Cnxr_3LdI/AAAAAAAAAJw/WYw-bn5dybc/s1600-h/report1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 314px; height: 320px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S1Cnxr_3LdI/AAAAAAAAAJw/WYw-bn5dybc/s320/report1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5427022023047458258" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Notice that the report is executed for CAF Imports, which is the parameter retrieved from the ReportParameters class.  Clicking on the change report button will display the following.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S1CoAusb8EI/AAAAAAAAAJ4/kCG-8AYw2aA/s1600-h/report2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 314px; height: 320px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/S1CoAusb8EI/AAAAAAAAAJ4/kCG-8AYw2aA/s320/report2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5427022281469325378" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This example is based on the SEAM remoting helloworld example.  It was tested with JBoss AS 5.1.0 and SEAM 2.2.0.  The source for it is available &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/1143-seam-and-jsapi/#description"&gt;here&lt;/a&gt;.  To run this example download and extract it to the jboss-seam-2.2.0.GA\examples\remoting directory.  If you have already set the application server settings in the SEAM build.properties file, all you should have to do to build  the example is type:&lt;br /&gt;Ant explode in the example directory.&lt;br /&gt;&lt;br /&gt;If you have downloaded Actuate’s Java Component technology and wish to deploy it to JBoss 5.1.0 GA, you will need to extract the war and remove xercesImpl.jar from the ActuateJavaComponent/WEB-INF/lib directory.  Rebuild the WAR and deploy to your JBoss AS.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-1521830653432768332?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='Using Actuate’s JSAPI with a JBoss SEAM component'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/1521830653432768332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=1521830653432768332' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1521830653432768332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1521830653432768332'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/01/using-acutates-jsapi-with-jboss-seam.html' title='Using Actuate’s JSAPI with a JBoss SEAM component'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GN1FyT5H8Kg/S1Cnxr_3LdI/AAAAAAAAAJw/WYw-bn5dybc/s72-c/report1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-2063119775131233504</id><published>2010-01-13T12:02:00.000-08:00</published><updated>2010-06-02T12:15:53.768-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>Quick and Dirty Logging</title><content type='html'>One of the best ways to debug your BIRT Expressions and JavaScript is logging. &amp;nbsp;I have worked with a number of different techniques for logging, and finally settled on using the script functions to create a logging utility. &amp;nbsp;This approach can be seen in the &lt;a href="http://code.google.com/p/birt-functions-lib/"&gt;birt-functions-lib&lt;/a&gt; project.&lt;br /&gt;&lt;br /&gt;But I frequently don't have the functions library, and I just want examine a value or an object. &amp;nbsp;I need quick and dirty logging, not a logging infrastructure. &lt;br /&gt;&lt;br /&gt;As you probably know, BIRT JavaScript can interact with Java objects natively. &amp;nbsp;So I should be able to invoke &lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;java.lang.System.out.println("message");&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;and see an output message. &amp;nbsp;There are just two tiny 'tricks' you need to know about to make this work.&lt;br /&gt;&lt;br /&gt;First,&amp;nbsp;the Eclipse application that BIRT runs under has a console mode. &amp;nbsp;To run eclipse in console mode run &lt;span style="color: #666666;"&gt;eclipse&lt;/span&gt;&lt;b&gt;c&lt;/b&gt;&lt;span style="color: #666666;"&gt;.exe &lt;/span&gt;instead of &lt;span style="color: #666666;"&gt;eclipse.exe. &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #666666;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Second, in order to access the java.lang package you need to preface your method call with the keyword Packages, as in:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;Packages.java.lang.System.out.println("message");&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;As you can see, your message will appear in the console window, quick and dirty.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_5bQPsXqbEM4/S04jvhcFDoI/AAAAAAAAA1I/FnD8eW0TI_o/s1600-h/c_is_for_console.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_5bQPsXqbEM4/S04jvhcFDoI/AAAAAAAAA1I/FnD8eW0TI_o/s640/c_is_for_console.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;If you are going to be doing a lot of quick and dirty logging, you can use the importPackage method to clean things up:&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;importPackage(Packages.java.lang);&lt;br /&gt;System.out.println("message with import package");&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;You can even create a global function that will wrap off the message generation if you are feeling motivated.&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;importPackage(Packages.java.lang);&lt;br /&gt;function log(msg){&lt;br /&gt;    System.out.println(msg);&lt;br /&gt;}&lt;br /&gt;reportContext.setGlobalVariable("log", log);&lt;br /&gt;&lt;br /&gt;log("Test global function");&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;But my feeling is that once you have reached that level, it would be just easier to use a script function and allow people to select the function through the UI. &amp;nbsp;Did I mention that there is an &lt;a href="http://code.google.com/p/birt-functions-lib/"&gt;open source functions library&lt;/a&gt; that will do this for you?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-2063119775131233504?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/2063119775131233504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=2063119775131233504' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/2063119775131233504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/2063119775131233504'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2010/01/quick-and-dirty-logging.html' title='Quick and Dirty Logging'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_5bQPsXqbEM4/S04jvhcFDoI/AAAAAAAAA1I/FnD8eW0TI_o/s72-c/c_is_for_console.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-1168201154165787019</id><published>2009-12-18T08:45:00.000-08:00</published><updated>2009-12-18T08:45:13.379-08:00</updated><title type='text'>EclipseCon Submissions - Last Chance to Propose a Talk</title><content type='html'>Oisín Hurley is one of the smartest, funniest and best looking people in the Eclipse community* &amp;nbsp;So when he says &lt;a href="http://oisinh.wordpress.com/2009/12/18/eclipsecon-submissions-pendant-le-deluge/?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed:+oisin+(Ois%C3%ADn+Hurley's+Weblog)"&gt;jump&lt;/a&gt;, I &lt;a href="https://www.eclipsecon.org/submissions/2010/view_talk.php?id=1416&amp;amp;search=john+ward"&gt;jump&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;That's right it is the last day to get your EclipseCon submission for a talk in. &amp;nbsp;If you have been doing anything interesting with BIRT that you would like to share with the Eclipse community, we would love to hear about it. &amp;nbsp;There are lots of opportunities to present at different lengths. &lt;br /&gt;&lt;br /&gt;Head on over to the&lt;a href="http://www.eclipsecon.org/2010/submissions/"&gt; EclipseCon submission site&lt;/a&gt; and make a proposal about how you are using BIRT. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;*And totally immune to blatant attempts at flattery.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-1168201154165787019?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/1168201154165787019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=1168201154165787019' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1168201154165787019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/1168201154165787019'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/12/eclipsecon-submissions-last-chance-to.html' title='EclipseCon Submissions - Last Chance to Propose a Talk'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-6345318964643525839</id><published>2009-12-14T10:18:00.000-08:00</published><updated>2009-12-16T15:05:36.249-08:00</updated><title type='text'>BIRT Plugins at Google Code</title><content type='html'>&lt;a href="http://www.blackboard.com/" rel="nofollow"&gt;&lt;span style="font-family: inherit;"&gt;Blackboard, Inc.&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family: inherit;"&gt;&amp;nbsp;develops solutions for the K-12 school, college campus, workplace, and community that increase the impact of education by transforming the experience of education. Blackboard has chosen BIRT as its reporting and business intelligence tool. &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Over the last two years I have been lucky to work with Blackboard on their BIRT integration. &amp;nbsp;Working with their product and developers we have been able to enhance their core product with reports. &amp;nbsp;Each Blackboard report tells a story that can help their clients better perform their jobs. &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;One of BIRT's features that was extremely helpful was the ability to customize and extend BIRT to meet Blackboards requirements. &amp;nbsp;Using the BIRT extension points we added functions and controls to BIRT that improved both the developer and users experience when interacting with BIRT.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;Blackboard has agreed to release some of the generic portions of this work back to the BIRT community as open source contributions. &amp;nbsp;Rather than rolling these contributions into the core product (where it would quickly get lost amidst all the other code) we have created two small open source projects that can be used by the community. &amp;nbsp;These projects can be used either as fully functional products or as best practice sample code. &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;   &lt;td&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/birt-functions-lib/"&gt;&lt;br /&gt;&lt;img height="96px" src="http://birt-functions-lib.googlecode.com/svn/wiki/home.attach/be_icon_function.png" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td&gt;&lt;a href="http://code.google.com/p/birt-functions-lib/"&gt;BIRT Functions&lt;/a&gt;&lt;br /&gt;&lt;/td&gt; &lt;td&gt;Uses the Aggregate and Script Function extension point to add new functions to the BIRT product.&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr&gt;  &lt;td&gt;&lt;a href="http://code.google.com/p/birt-controls-lib/"&gt;&lt;br /&gt;&lt;img height="96px" src="http://birt-controls-lib.googlecode.com/svn/wiki/home.attach/be_icon_controls.png" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td&gt;&lt;a href="http://code.google.com/p/birt-controls-lib/"&gt;BIRT Controls&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td&gt;Uses the ReportItem extension point to create new elements that show up on BIRT reports.&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr&gt;   &lt;td&gt;&lt;a href="http://code.google.com/p/innovent/"&gt; &lt;br /&gt;&lt;img height="96px" src="http://innovent.googlecode.com/svn/wiki/home.attach/birt_solo_transparent_no_spell.png" /&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td&gt;&lt;a href="http://code.google.com/p/innovent/"&gt;Innovent Update Site&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;  &lt;td&gt;Hosts an Eclipse Update site for both projects. We will be adding new projects to this site as we finish up the code.&lt;br /&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;If you are a BIRT developer that just wants to get started you can use the following update link:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span style="font-family: monospace; font-size: 12px; white-space: pre;"&gt;&lt;span style="color: black;"&gt;http&lt;/span&gt;&lt;span style="color: #666600;"&gt;:&lt;/span&gt;&lt;span style="color: #880000;"&gt;//innovent.googlecode.com/svn/trunk/update&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you would like to find out a bit more about the projects, please visit the project sites.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/birt-functions-lib/"&gt;BIRT Functions Plugin&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/birt-controls-lib/"&gt;BIRT Controls Plugin&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Thanks go out to thank both&amp;nbsp;&lt;a href="http://www.birt-exchange.com/be/marketplace/hub/"&gt;BIRT Exchange&lt;/a&gt; and the brand spanking new &lt;a href="http://marketplace.eclipse.org/"&gt;Eclipse Marketplace&lt;/a&gt; for providing access to our projects. &amp;nbsp;It is really great to have a couple of quality channels to publicize our work to the BIRT community. &lt;br /&gt;&lt;br /&gt;Also, I want to mention the team that helped to build and get this code open sourced. &amp;nbsp;Steve Schafer from Innovent Solutions wrote a lot of the code and figured out the inner workings of the ReportItem exension point. &amp;nbsp;Blackboard had a whole team of people working on reports, in particular thanks to Heather, JoAnna, Michelle, Dan, Joe, Joel, and Manpreet. &lt;br /&gt;&lt;span style="font-family: 'Times New Roman', serif; font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;span style="font-family: 'Times New Roman';"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-6345318964643525839?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://code.google.com/p/birt-functions-lib/' title='BIRT Plugins at Google Code'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/6345318964643525839/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=6345318964643525839' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6345318964643525839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6345318964643525839'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/12/birt-plugins-at-google-code.html' title='BIRT Plugins at Google Code'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-297763476646420444</id><published>2009-12-11T17:07:00.000-08:00</published><updated>2010-06-02T12:15:53.768-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='Charts'/><title type='text'>Calling Client Side JavaScript from a BIRT Chart</title><content type='html'>A couple of months ago I detailed a new feature for BIRT charts that allows multiple hyperlinks to be attached to one the supported events.  That post is available &lt;a href="http://birtworld.blogspot.com/2009/10/multiple-hyperlinks-on-birt-charts.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In this post I will discuss using a BIRT Text element that contains script which executes within the client browser and contains functions that are called from rendered charts.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;General Information&lt;/strong&gt;&lt;br /&gt;BIRT currently supports interactivity on many chart components like chart series, title, axis, and the legend.  The components that support interactivity will depend on the type of chart being used.  The events are client based events like mouse click, mouse over, key down, etc.  Multiple events can be hooked and each is associated with an action.  Actions define the behavior that should occur when a specific event happens. The actions available depend on what component the action is defined for and what chart output type is being used.  Currently BIRT supports the following Actions.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Hyperlink &lt;/em&gt;– Supports multiple hyperlinks, drill through, and linking to bookmarks.&lt;br /&gt;&lt;em&gt;Show Toolip&lt;/em&gt; – Supports displaying tooltips.  Data available for use in the tooltip will depend on the component.&lt;br /&gt;&lt;em&gt;Highlight&lt;/em&gt; – Highlights the selected component.  Most often used to highlight specific series or data point.&lt;br /&gt;&lt;em&gt;Toggle Visibility&lt;/em&gt; – Toggles the visibility of the selected component.  Most often used to change the visibility of a series or data point.&lt;br /&gt;&lt;em&gt;Toggle DataPoint Visibility&lt;/em&gt; – Toggles the data point label visibility.&lt;br /&gt;&lt;em&gt;Invoke Script&lt;/em&gt; – Invokes client side script.&lt;br /&gt;&lt;br /&gt;Additionally if you are using the Chart engine within an SWT, SVG, or Swing based application the engine supports adding a callback action that your code can use to interpret chart events.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLtqyj530I/AAAAAAAAAIw/kgYfRt25bjg/s1600-h/interactivitymenu.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 299px; height: 320px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLtqyj530I/AAAAAAAAAIw/kgYfRt25bjg/s320/interactivitymenu.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5414151021435412290" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Highlight, Toggle Visibility, and Toggle DataPoint Visibility actions are only available when using an SVG output setting.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLuJgTS5FI/AAAAAAAAAJA/M8-YG75LGNM/s1600-h/outputtype.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 317px; height: 320px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLuJgTS5FI/AAAAAAAAAJA/M8-YG75LGNM/s320/outputtype.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5414151549109855314" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you use SVG, and you wish to test the report in the designer remember to set the Enable SVG chart in the Preview preferences for the Report Design Preference entry.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SyLt5YxhAaI/AAAAAAAAAI4/vyLFMh4EuEs/s1600-h/svgenable.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 278px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SyLt5YxhAaI/AAAAAAAAAI4/vyLFMh4EuEs/s320/svgenable.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5414151272211218850" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;More information on Chart Interactivity is available &lt;a href="http://wiki.eclipse.org/BPS37  "&gt;here&lt;/a&gt;.  Also see the &lt;a href="http://wiki.eclipse.org/BIRT/FAQ/Charts2.2"&gt;Chart FAQ&lt;/a&gt; for more details.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;InvokeScript Example&lt;/strong&gt;&lt;br /&gt;The follow section details an example of using the invokeScript action on multiple Chart events.  &lt;br /&gt;&lt;br /&gt;Assume that you have a Chart that displays a set of customers with a series value for each equal to the customer's credit limit.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLu82iV9JI/AAAAAAAAAJI/E8uPnxU41BM/s1600-h/plainchart.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 146px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLu82iV9JI/AAAAAAAAAJI/E8uPnxU41BM/s320/plainchart.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5414152431251879058" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Suppose you want to display the customer details right below the chart when the mouse is moved over a specific data point.  This can be done using the invokeScript action on the mouse over event for the chart series.  To do this first create a table below the chart that is bound to the same dataset that the chart is using.  You can then nest a table that calls another data set to retrieve customer information.  In the attached example this will be the ChartData and CustomerInformation datasets respectively.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLvIs26giI/AAAAAAAAAJQ/1Z9RWn0KAM8/s1600-h/tabledefs.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 223px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLvIs26giI/AAAAAAAAAJQ/1Z9RWn0KAM8/s320/tabledefs.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5414152634812236322" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;By default this will generate a inner table that contains customer information for every customer represented in the chart.  Obviously you do not want to display all of these at once, so create a new style in the style editor with only one property overridden – Text Block:Display set to no Display.  Apply this new style to both the inner and outer tables.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLvYfijeaI/AAAAAAAAAJY/xUlRb-KWmKg/s1600-h/nodisplay.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 266px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLvYfijeaI/AAAAAAAAAJY/xUlRb-KWmKg/s320/nodisplay.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5414152906115086754" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you run the report after completing this step all the tables will be generated in the output but none will be displayed.  This is different than using the visibility property which will not put the tables in the output.  Enter the following bookmarks for the outer and inner tables.&lt;br /&gt;&lt;br /&gt;Outer table bookmark expression:  "myoutertable";&lt;br /&gt;Inner table bookmark expression: "mytable"+row["CUSTOMERNUMBER"]&lt;br /&gt;&lt;br /&gt;This will assign the outer table id to myoutertable and a unique id for each inner table starting with mytable and the customer number for the given inner table appended to it.  We can now use these with some client script to turn them on or off.&lt;br /&gt;&lt;br /&gt;Add a Text element below the two tables with the following value.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;function clearSel(){&lt;br /&gt;   var ot=document.getElementById("myoutertable");&lt;br /&gt;   ot.style.display="none";&lt;br /&gt;   var intbls=ot.getElementsByTagName("TABLE");&lt;br /&gt;   for( jj=0; jj&amp;lt;intbls.length; jj++ ){&lt;br /&gt;    intbls[jj].style.display = "none";&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;function DisplayCustomer(cat) {&lt;br /&gt; clearSel();&lt;br /&gt; //alert(cat);&lt;br /&gt; document.getElementById("myoutertable").style.display="block"&lt;br /&gt; document.getElementById("mytable"+cat).style.display="block"&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&amp;lt;/script&amp;gt; &lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Make sure to set the Text type to HTML.&lt;br /&gt;&lt;br /&gt;The clearSel function first finds the outer table and then locates every nested table and sets the display style for each to none.  The outer table’s display style is also set to none.  This will effectively hide both tables.&lt;br /&gt;&lt;br /&gt;The DisplayCustomer function first clears all current displayed tables.  Next it uses a category passed in from the Chart to find the specific customer inner table and sets its display style to block.  It also sets the outer table to be visible.&lt;br /&gt;&lt;br /&gt;To link these two functions to the Chart use the Interactivity button on the Value (Y) Series as shown in the picture below.  Note that we use a mouse over event to call the DisplayCustomer function and a mouse click function to clear the tables.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLwzkzy79I/AAAAAAAAAJg/iUXJrXGDkCQ/s1600-h/idef.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 250px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLwzkzy79I/AAAAAAAAAJg/iUXJrXGDkCQ/s320/idef.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5414154470897676242" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This produces the following output.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLxBZdHagI/AAAAAAAAAJo/0rWouP4SIuU/s1600-h/output.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 237px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLxBZdHagI/AAAAAAAAAJo/0rWouP4SIuU/s320/output.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5414154708367927810" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As the mouse is moved over the different tubes the table below the chart will update.  To clear the tables click on one of the tubes.  You will notice that we passed categoryData to the DisplayCustomer JavaScript function.  This is a predefined variable available to the invokeScript function that contains the category value for a specific datapoint.  The example report lists the predefined variables and in what action they are available using label elements at the top of the report.  These labels are hidden at run time.&lt;br /&gt;&lt;br /&gt;The example is available at &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/1116-mouse-over-details-for-a-chart/#description"&gt;BIRT Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-297763476646420444?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='Calling Client Side JavaScript from a BIRT Chart'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/297763476646420444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=297763476646420444' title='23 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/297763476646420444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/297763476646420444'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/12/calling-client-side-javascript-from.html' title='Calling Client Side JavaScript from a BIRT Chart'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GN1FyT5H8Kg/SyLtqyj530I/AAAAAAAAAIw/kgYfRt25bjg/s72-c/interactivitymenu.PNG' height='72' width='72'/><thr:total>23</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7884030183659369631</id><published>2009-12-01T14:01:00.000-08:00</published><updated>2009-12-01T14:13:06.180-08:00</updated><title type='text'>BIRT Designer Classpath Changes</title><content type='html'>Starting with the 2.5.2 branch of BIRT (Release date February 2010), configuring the classpath for the designer has been improved.  This classpath setting is used by the BIRT engine when processing reports that use Java event handlers or make calls to external classes while in the designer.  In previous releases of BIRT, the engine would add all Java projects within the same workspace to the classpath automatically.  With BIRT 2.5.2 you will now be able configure the BIRT classpath globally or project specific.  This setting is available in the preferences.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/SxWUokoEuVI/AAAAAAAAAIo/OyRXMc6k8k8/s1600/cpconfig.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 242px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/SxWUokoEuVI/AAAAAAAAAIo/OyRXMc6k8k8/s320/cpconfig.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5410393952102955346" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In this example I have configured a project (BIRT Reports) to add the BirtEventHandlers Java project to the classpath that the BIRT engine uses when previewing the reports in the designer.  Note these changes only affect the designer and you should deploy your event handler classes to the scriptlib directory in the deployed environment.  More details are available in the &lt;a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=258574"&gt;bugzilla entry&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7884030183659369631?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='BIRT Designer Classpath Changes'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7884030183659369631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7884030183659369631' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7884030183659369631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7884030183659369631'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/12/birt-designer-classpath-changes.html' title='BIRT Designer Classpath Changes'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_GN1FyT5H8Kg/SxWUokoEuVI/AAAAAAAAAIo/OyRXMc6k8k8/s72-c/cpconfig.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-3462683361680323868</id><published>2009-11-20T16:00:00.000-08:00</published><updated>2010-06-02T12:15:53.769-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>Accessing Spring Beans from the BIRT Designer</title><content type='html'>Recently I have described methods that can be used to access Spring Beans from the BIRT Engine.  These examples are intended to be illustrative and not comprehensive.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2009/11/more-on-birt-and-spring.html"&gt;More on BIRT and Spring&lt;/a&gt;&lt;br&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2009/11/calling-spring-objects-from-birt.html"&gt;Calling Spring Objects from BIRT Expressions and Event Handlers&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In both of these examples I used the BIRT engine to retrieve Spring objects within the scripting environment.  In this post I am supplying an example that illustrates how to implement your own menu in the expression builder, so Spring objects can be called within the BIRT Designer.  This will allow you to test your report prior to deployment.&lt;br /&gt;&lt;br /&gt;In this post:&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2008/09/birt-231-adding-functions-to-expression.html"&gt;BIRT 2.3.1 - Adding Functions to the Expression Builder&lt;/a&gt;&lt;br /&gt;I described how to implement the org.eclipse.birt.core.ScriptFunctionService.  The attached example is an implementation of this extension point.  When using this example the expression builder will appear as follows.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SwcumA2v_RI/AAAAAAAAAIQ/o0LXyHwFY6Q/s1600/expressionbuilder.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 278px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SwcumA2v_RI/AAAAAAAAAIQ/o0LXyHwFY6Q/s320/expressionbuilder.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5406341108281113874" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Notice that there is now a SpringFunctions sub-category, which provides one method callBean.  This method takes a bean name and a method name and expects a returned string.  To keep the example simple no arguments are supported and the method must return a string.  The plugin.xml looks like the following:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/Swcuu7yL_CI/AAAAAAAAAIY/2xUFGCB5rVU/s1600/ScriptFunctionService.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 238px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/Swcuu7yL_CI/AAAAAAAAAIY/2xUFGCB5rVU/s320/ScriptFunctionService.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5406341261538622498" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Provided with the example is a deployable J2EE application and the plugin that implements the ScriptFunctionService.  See the readme for details on setting up the example.  Also note that the deployable plugin is also attached in the example.  You will need to add this to your designer and your runtime.  This example works with both the Open Source BIRT designer and the Actuate BIRT designer.&lt;br /&gt;&lt;br /&gt;Also included is an example report with the following output.&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/Swcu57rt_1I/AAAAAAAAAIg/FOh08jmnF8I/s1600/output.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 128px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/Swcu57rt_1I/AAAAAAAAAIg/FOh08jmnF8I/s320/output.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5406341450490052434" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This example is available at &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/1100-calling-spring-objects-from-the-expression-builder/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-3462683361680323868?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='Accessing Spring Beans from the BIRT Designer'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/3462683361680323868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=3462683361680323868' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3462683361680323868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3462683361680323868'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/11/accessing-spring-beans-from-birt.html' title='Accessing Spring Beans from the BIRT Designer'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GN1FyT5H8Kg/SwcumA2v_RI/AAAAAAAAAIQ/o0LXyHwFY6Q/s72-c/expressionbuilder.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-518475541905446927</id><published>2009-11-13T20:13:00.000-08:00</published><updated>2009-11-13T20:13:21.176-08:00</updated><title type='text'>It's Movember</title><content type='html'>Movember, that time of year when the days grow shorter, the weather grows colder and the family gathers today for the holidays. &amp;nbsp;Of course in my family the kids are looking at me and laughing, and I am getting 'that' look from Gretchen my wife. &lt;br /&gt;&lt;br /&gt;Yes I am growing in a mustache in an effort to change the face of men's health. &amp;nbsp;To quote my team lead (I am a part of &lt;a href="http://www.fatcyclist.com/2009/11/04/movember-with-team-fatty/"&gt;Team Fat Cyclist&lt;/a&gt;). &lt;br /&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="color: #020100; font-family: Verdana, Helvetica, sans-serif; font-size: 12px; line-height: 16px;"&gt;"Movember is the month formerly known as November. During this month, men — manly men — grow mos as a way to call attention to themselves (hey, I’m just being honest here).&lt;span class="Apple-style-span" style="color: black; font-family: 'Times New Roman'; font-size: medium; line-height: normal;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="color: #020100; font-family: Verdana, Helvetica, sans-serif; font-size: 12px; line-height: 16px;"&gt;Then, when people ask you “Why are you growing a moustache?” — and they will ask you this question — you tell them about the cancers affecting men, and ask them to donate to your Mo donation page (the money will be channeled to the Prostate Cancer Foundation and to LiveStrong).&lt;span class="Apple-style-span" style="color: black; font-family: 'Times New Roman'; font-size: medium; line-height: normal;"&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="color: #020100; font-family: Verdana, Helvetica, sans-serif; font-size: 12px; line-height: 16px;"&gt;So really, a mo is kinda like wearing a pink ribbon for breast cancer awareness. But a lot more personal. And harder to remove. And it’s displayed a lot higher."&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div style="text-align: right;"&gt;-The Fat Cyclist (Elden Nelson)&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;If you are interested in supporting me and helping to raise money for men's health issues, please visit my &lt;a href="http://us.movember.com/mospace/422764/"&gt;mo page&lt;/a&gt; and donate. &lt;br /&gt;&lt;br /&gt;If not me, please visit another great team, the&amp;nbsp;&lt;a href="http://ca.movember.com/mospace/466229"&gt;Eclipse Momitters&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-518475541905446927?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://www.movember.com/us/donate/your-details/member_id/422764/' title='It&apos;s Movember'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/518475541905446927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=518475541905446927' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/518475541905446927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/518475541905446927'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/11/its-movember.html' title='It&apos;s Movember'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7648196583825427954</id><published>2009-11-12T11:23:00.000-08:00</published><updated>2009-11-12T11:32:25.109-08:00</updated><title type='text'>More on BIRT and Spring</title><content type='html'>In my &lt;a href="http://birtworld.blogspot.com/2009/11/calling-spring-objects-from-birt.html"&gt;previous post&lt;/a&gt; I discussed calling Spring objects within a BIRT report.  That example used an architecture similar to the simplified diagram below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/SvxhHIIfMeI/AAAAAAAAAHY/wVdFD_v54GQ/s1600-h/engineint.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 307px; height: 320px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/SvxhHIIfMeI/AAAAAAAAAHY/wVdFD_v54GQ/s320/engineint.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5403300428007813602" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Spring Context was injected in the BIRT app context and this gave the BIRT scripting environment access to the Spring Beans.  This example could have been expanded further to the Open Source BIRT Viewer by adding a similar object to the Application Context for the BIRT Viewer.  See &lt;a href="http://wiki.eclipse.org/Adding_an_Object_to_the_Application_Context_for_the_Viewer_%28BIRT%29"&gt;this wiki page&lt;/a&gt; for more details.  If you use the method described in the wiki page, you may prefer to implement this with a Spring RequestContextFilter.&lt;br /&gt;&lt;br /&gt;The simplified architecture for this setup is presented below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/Svxhih7CsVI/AAAAAAAAAHg/DlYMaxdLE0c/s1600-h/osviewerint.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 318px; height: 320px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/Svxhih7CsVI/AAAAAAAAAHg/DlYMaxdLE0c/s320/osviewerint.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5403300898787209554" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Another option is to use Spring Remoting and the Open Source BIRT Viewer tag libraries or standard URL integration.  In this case you add the Spring jars to the WEB-INF/lib of the viewer and write a wrapper class for the Spring remote client.  The wrapper class and Spring configuration file can then be added to the WEB-INF/lib directory of the Viewer to access your remote beans.  The architecture for this setup would be as follows.  Attached to this post is an example of this method.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/Svxh1ZenylI/AAAAAAAAAHo/2s825BJUOZ0/s1600-h/osviewerremoteint.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 195px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/Svxh1ZenylI/AAAAAAAAAHo/2s825BJUOZ0/s320/osviewerremoteint.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5403301222938036818" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you are using the Actuate Java Components technology, you can use the JSAPI within a standard HTML page or generate it in a Spring View which will include the BIRT report.  This approach allows Flash charts to be populated by Spring Beans and report interactivity like dynamically grouping, sorting and filtering all without re-executing the report.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/SvxiAU0ymBI/AAAAAAAAAHw/YN4_zOseDr0/s1600-h/interactremoteint.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 209px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/SvxiAU0ymBI/AAAAAAAAAHw/YN4_zOseDr0/s320/interactremoteint.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5403301410667403282" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The example, that is attached to this post, is a very simple Spring Remoting example.  It contains two ANT projects, one for the server application and one that acts as the remote client wrapper.  Once you download the example, build the server application and deploy it.  Instructions are in a readme file.  Then build the client wrapper jar and deploy it as described in the readme.  The readme illustrates deploying to the Open Source BIRT Viewer or the Actuate Interactive Viewer.  The example uses Spring HTTP Remoting, but any of the Spring Remoting technologies should work.  An example report is provided for both deployed environments.  Whether you are using the Open Source BIRT Report designer or the Actuate BIRT Designer, the expression to access the Spring Bean will be similar to the following.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/SvxiKAJ_cnI/AAAAAAAAAH4/1j9lRNTxH0Q/s1600-h/expression.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 278px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/SvxiKAJ_cnI/AAAAAAAAAH4/1j9lRNTxH0Q/s320/expression.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5403301576917873266" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Output for the example is as follows.&lt;br /&gt;&lt;br /&gt;Open Source Viewer&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SvxiWzTlNuI/AAAAAAAAAIA/EkJ6Q746XNs/s1600-h/viewerremoteexample.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 166px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SvxiWzTlNuI/AAAAAAAAAIA/EkJ6Q746XNs/s320/viewerremoteexample.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5403301796806735586" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Actuate Interactive Viewer&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SvxigsJGujI/AAAAAAAAAII/qIsT5e064A0/s1600-h/AJCExample.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 271px; height: 320px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SvxigsJGujI/AAAAAAAAAII/qIsT5e064A0/s320/AJCExample.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5403301966682438194" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Example is available at &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/1096-remote-spring-beans-from-birt/#description"&gt;BIRT Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7648196583825427954?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='More on BIRT and Spring'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7648196583825427954/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7648196583825427954' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7648196583825427954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7648196583825427954'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/11/more-on-birt-and-spring.html' title='More on BIRT and Spring'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_GN1FyT5H8Kg/SvxhHIIfMeI/AAAAAAAAAHY/wVdFD_v54GQ/s72-c/engineint.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7932873220674159902</id><published>2009-11-05T07:38:00.000-08:00</published><updated>2010-06-02T12:15:53.769-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>Calling Spring Objects from BIRT Expressions and Event Handlers</title><content type='html'>Several examples are already available on the web, which demonstrate calling the BIRT engine from a Spring MVC application.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://internna.blogspot.com/2007/03/integrating-birt-with-spring-in-web.html"&gt;Integrating BIRT with Spring in a Web application&lt;/a&gt;&lt;br /&gt;and &lt;br /&gt;&lt;a href="http://blog.xebia.com/2006/08/29/reporting-the-eclipse-way/"&gt;Eclipse BIRT in Spring web applications&lt;/a&gt;&lt;br /&gt;are a couple of examples.&lt;br /&gt;&lt;br /&gt;There is not much information on how to include Spring Beans within a report design.  This post details an example of injecting the Spring ApplicationContext into BIRT’s AppContext object which will allow you to call your Spring Beans in BIRT expressions or event handlers.  A link for the source is listed at the bottom.  A readme file containing instructions for building the example is included in the download.&lt;br /&gt;&lt;br /&gt;You can include the BIRT runtime by following the post above or examining the download.  The Example implements a Spring Controller with the following code.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;package org.eclipse.birt.spring;&lt;br /&gt;&lt;br /&gt;import javax.servlet.ServletContext;&lt;br /&gt;import javax.servlet.http.HttpServletRequest;&lt;br /&gt;import javax.servlet.http.HttpServletResponse;&lt;br /&gt;&lt;br /&gt;import org.eclipse.birt.report.engine.api.HTMLRenderOption;&lt;br /&gt;import org.eclipse.birt.report.engine.api.HTMLServerImageHandler;&lt;br /&gt;import org.eclipse.birt.report.engine.api.IReportEngine;&lt;br /&gt;import org.eclipse.birt.report.engine.api.IReportRunnable;&lt;br /&gt;import org.eclipse.birt.report.engine.api.IRunAndRenderTask;&lt;br /&gt;import org.springframework.web.servlet.ModelAndView;&lt;br /&gt;import org.springframework.web.servlet.mvc.AbstractController;&lt;br /&gt;&lt;br /&gt;public class BirtController extends AbstractController {&lt;br /&gt;&lt;br /&gt;  private IReportEngine reportEngine;&lt;br /&gt;&lt;br /&gt;  protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {&lt;br /&gt;&lt;br /&gt; String reportName = request.getParameter("ReportName");&lt;br /&gt; ServletContext sc = request.getSession().getServletContext();&lt;br /&gt; reportEngine = BirtEngine.getBirtEngine(sc);&lt;br /&gt; IReportRunnable runnable = null;&lt;br /&gt; runnable = reportEngine.openReportDesign( sc.getRealPath("/Reports")+"/"+reportName );&lt;br /&gt;    IRunAndRenderTask runAndRenderTask = reportEngine.createRunAndRenderTask(runnable);&lt;br /&gt;&lt;br /&gt;    HTMLRenderOption options = new HTMLRenderOption();&lt;br /&gt;    options.setOutputFormat("html");&lt;br /&gt;    options.setOutputStream(response.getOutputStream());&lt;br /&gt; options.setImageHandler(new HTMLServerImageHandler());&lt;br /&gt; options.setBaseImageURL(request.getContextPath()+"/images");&lt;br /&gt; options.setImageDirectory(sc.getRealPath("/images"));&lt;br /&gt;    runAndRenderTask.setRenderOption(options);&lt;br /&gt;    runAndRenderTask.run();&lt;br /&gt;&lt;br /&gt;    return null;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Note that no error checking is implemented in this example.  This controller class just extends the Spring AbstractController class passes the response object to the BIRT engine to output the report.  The report name is retrieved from the request.  Before running the report the BirtEngine class is used to retrieve the BIRT engine.  This is virtually the same BirtEngine class used in the servlet example available in the &lt;a href="http://wiki.eclipse.org/Servlet_Example_%28BIRT%29_2.1"&gt;BIRT wiki&lt;/a&gt; with some exceptions that are noted here.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;package org.eclipse.birt.spring;&lt;br /&gt;&lt;br /&gt;import java.io.InputStream;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import java.util.Properties;&lt;br /&gt;import java.util.logging.Level;&lt;br /&gt;&lt;br /&gt;import org.eclipse.birt.report.engine.api.EngineConfig;&lt;br /&gt;import org.eclipse.birt.report.engine.api.IReportEngine;&lt;br /&gt;import javax.servlet.*;&lt;br /&gt;import org.eclipse.birt.core.framework.PlatformServletContext;&lt;br /&gt;import org.eclipse.birt.core.framework.IPlatformContext;&lt;br /&gt;import org.eclipse.birt.core.framework.Platform;&lt;br /&gt;import org.eclipse.birt.core.exception.BirtException;&lt;br /&gt;import org.eclipse.birt.report.engine.api.IReportEngineFactory;&lt;br /&gt;import org.springframework.context.ApplicationContext; &lt;br /&gt;&lt;br /&gt;public class BirtEngine {&lt;br /&gt;&lt;br /&gt; private static IReportEngine birtEngine = null;&lt;br /&gt;&lt;br /&gt; private static Properties configProps = new Properties();&lt;br /&gt;&lt;br /&gt; private final static String configFile = "BirtConfig.properties";&lt;br /&gt;&lt;br /&gt; public static synchronized void initBirtConfig() {&lt;br /&gt;  loadEngineProps();&lt;br /&gt; }&lt;br /&gt; public static synchronized IReportEngine getBirtEngine(ServletContext sc) {&lt;br /&gt;  if (birtEngine == null) &lt;br /&gt;  {&lt;br /&gt;   //optionally load engine props&lt;br /&gt;   //loadEngineProps();&lt;br /&gt;   EngineConfig config = new EngineConfig();&lt;br /&gt;   if( configProps != null){&lt;br /&gt;    String logLevel = configProps.getProperty("logLevel");&lt;br /&gt;    Level level = Level.OFF;&lt;br /&gt;    if ("SEVERE".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.SEVERE;&lt;br /&gt;    } else if ("WARNING".equalsIgnoreCase(logLevel))&lt;br /&gt;    {&lt;br /&gt;     level = Level.WARNING;&lt;br /&gt;    } else if ("INFO".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.INFO;&lt;br /&gt;    } else if ("CONFIG".equalsIgnoreCase(logLevel))&lt;br /&gt;    {&lt;br /&gt;     level = Level.CONFIG;&lt;br /&gt;    } else if ("FINE".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.FINE;&lt;br /&gt;    } else if ("FINER".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.FINER;&lt;br /&gt;    } else if ("FINEST".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.FINEST;&lt;br /&gt;    } else if ("OFF".equalsIgnoreCase(logLevel)) &lt;br /&gt;    {&lt;br /&gt;     level = Level.OFF;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    config.setLogConfig(configProps.getProperty("logDirectory"), level);&lt;br /&gt;   }&lt;br /&gt;   config.setEngineHome("");&lt;br /&gt;   &lt;br /&gt;   IPlatformContext context = new PlatformServletContext( sc );&lt;br /&gt;   config.setPlatformContext( context );&lt;br /&gt;   config.getAppContext().put("PARENT_CLASSLOADER", BirtEngine.class.getClassLoader());&lt;br /&gt;   ApplicationContext sprCtx = ContextAccess.getApplicationContext();&lt;br /&gt;   config.getAppContext().put("spring",sprCtx);   &lt;br /&gt;   try&lt;br /&gt;   {&lt;br /&gt;    Platform.startup( config );&lt;br /&gt;   }&lt;br /&gt;   catch ( BirtException e )&lt;br /&gt;   {&lt;br /&gt;    e.printStackTrace( );&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   IReportEngineFactory factory = (IReportEngineFactory) Platform&lt;br /&gt;   .createFactoryObject( IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY );&lt;br /&gt;   birtEngine = factory.createReportEngine( config );&lt;br /&gt;  }&lt;br /&gt;  return birtEngine;&lt;br /&gt; }&lt;br /&gt; public static synchronized void destroyBirtEngine() {&lt;br /&gt;  if (birtEngine == null) {&lt;br /&gt;   return;&lt;br /&gt;  }  &lt;br /&gt;  birtEngine.destroy();&lt;br /&gt;  Platform.shutdown();&lt;br /&gt;  birtEngine = null;&lt;br /&gt; }&lt;br /&gt; public Object clone() throws CloneNotSupportedException {&lt;br /&gt;  throw new CloneNotSupportedException();&lt;br /&gt; }&lt;br /&gt; private static void loadEngineProps() {&lt;br /&gt;  try {&lt;br /&gt;   //Config File must be in classpath&lt;br /&gt;   ClassLoader cl = Thread.currentThread ().getContextClassLoader();&lt;br /&gt;   InputStream in = null;&lt;br /&gt;   in = cl.getResourceAsStream (configFile);&lt;br /&gt;   configProps.load(in);&lt;br /&gt;   in.close();&lt;br /&gt;  } catch (IOException e) {&lt;br /&gt;   e.printStackTrace();&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt; &lt;br /&gt;This class just wraps access to the BIRT engine in a singleton.&lt;br /&gt;The notable changes are in these lines of code deal with the EngineConfig class.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;   config.setEngineHome("");&lt;br /&gt;   &lt;br /&gt;   IPlatformContext context = new PlatformServletContext( sc );&lt;br /&gt;   config.setPlatformContext( context );&lt;br /&gt;   config.getAppContext().put("PARENT_CLASSLOADER", BirtEngine.class.getClassLoader());&lt;br /&gt;   ApplicationContext sprCtx = ContextAccess.getApplicationContext();&lt;br /&gt;   config.getAppContext().put("spring",sprCtx);  &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The setEngineHome is passed a blank value and setting the PlatformContext to use a PlatformServletContext class will by default look for the BIRT plugins in the WEB-INF/Platform/plugins directory.  Next we set the parent classloader for the report engine plugin so that classes available to the project will also be available to the BIRT engine.  The final line gets the Spring ApplicationContext instance and loads it into the BIRT AppContext object and names it “spring”.  The method used for retrieving the Spring context is described in a great post &lt;a href="http://blog.jdevelop.eu/2008/07/06/access-the-spring-applicationcontext-from-everywhere-in-your-application/"&gt;here&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;The ContextAccess class is defined as follows.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;package org.eclipse.birt.spring;&lt;br /&gt;import org.springframework.context.ApplicationContext; &lt;br /&gt;public class ContextAccess {&lt;br /&gt; private static ApplicationContext ctx;&lt;br /&gt; public static void setApplicationContext(ApplicationContext applicationContext) {   &lt;br /&gt;  ctx = applicationContext;   &lt;br /&gt; }&lt;br /&gt; public static ApplicationContext getApplicationContext() {&lt;br /&gt;  return ctx;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This Class just contains methods to set and get the static variable ctx, which will contain the Spring ApplicationContext with the addition of one more class.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;package org.eclipse.birt.spring;&lt;br /&gt;&lt;br /&gt;import org.springframework.beans.BeansException;&lt;br /&gt;import org.springframework.context.ApplicationContext;&lt;br /&gt;import org.springframework.context.ApplicationContextAware; &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class SpringContextProvider implements ApplicationContextAware {&lt;br /&gt; public void setApplicationContext(ApplicationContext ctx) throws BeansException {&lt;br /&gt;  ContextAccess.setApplicationContext(ctx);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This Class implements the ApplicationContextAware interface which causes the Spring framework to callback this class with the Spring context, when it is created.  The Spring configuration file for this example looks like the following.&lt;br /&gt;&lt;br /&gt;&amp;lt;beans&amp;gt;&lt;br /&gt; &amp;lt;bean id="springContextProvider" class="org.eclipse.birt.spring.SpringContextProvider"&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;     &lt;br /&gt; &amp;lt;bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"&amp;gt;&lt;br /&gt;  &amp;lt;property name="mappings"&amp;gt;&lt;br /&gt;   &amp;lt;props&amp;gt;                &lt;br /&gt;    &amp;lt;prop key="/runbirt.htm"&amp;gt;birtController&amp;lt;/prop&amp;gt;&lt;br /&gt;   &amp;lt;/props&amp;gt;        &lt;br /&gt;  &amp;lt;/property&amp;gt;    &lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt; &amp;lt;bean id="birtEngine"&lt;br /&gt;  class="org.eclipse.birt.spring.BirtEngine"&lt;br /&gt;  destroy-method="destroyBirtEngine"&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt; &amp;lt;bean id="birtController"&lt;br /&gt;  class="org.eclipse.birt.spring.BirtController"&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt;&lt;br /&gt; &amp;lt;bean id="carPojo"&lt;br /&gt;  class="org.eclipse.birt.spring.CarPojo"&amp;gt;&lt;br /&gt; &amp;lt;/bean&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;br /&gt;&lt;br /&gt;We have a carPojo bean that is available.  To access this from a BIRT expression, all we have to do is use the following syntax.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var mypojo = spring.getBean("carPojo");&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;You can then call the methods on the object. Eg &lt;code&gt;mypojo.getYear();&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/SvLzpcdiV7I/AAAAAAAAAHI/0Vmh-WCz_OQ/s1600-h/expression.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 274px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/SvLzpcdiV7I/AAAAAAAAAHI/0Vmh-WCz_OQ/s320/expression.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5400646796510910386" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Output for the example is presented below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SvLz0-FxYpI/AAAAAAAAAHQ/BPdwDwyyUQ4/s1600-h/example.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 230px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SvLz0-FxYpI/AAAAAAAAAHQ/BPdwDwyyUQ4/s320/example.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5400646994516599442" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Caveats&lt;/em&gt;&lt;br /&gt;If you preview the report in the designer the report will not work.  This is because the Spring context is not available to the designer.  The report has to be deployed to test it.  There are many ways this example could be extended to circumvent this issue.  BIRT provides an extension point to enhance the expression builder which could be used with Spring Remoting to access the Spring context.  BIRT also provides an extension to implement a BIRT application context object within the designer that could be used in this same fashion.  I will try to implement one of these methods in the future to illustrate this concept.&lt;br /&gt;&lt;br /&gt;The example can be downloaded from &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/1082-accessing-spring-beans-from-birt-reports/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7932873220674159902?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='Calling Spring Objects from BIRT Expressions and Event Handlers'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7932873220674159902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7932873220674159902' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7932873220674159902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7932873220674159902'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/11/calling-spring-objects-from-birt.html' title='Calling Spring Objects from BIRT Expressions and Event Handlers'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GN1FyT5H8Kg/SvLzpcdiV7I/AAAAAAAAAHI/0Vmh-WCz_OQ/s72-c/expression.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-982679717359004673</id><published>2009-10-20T11:51:00.000-07:00</published><updated>2010-05-17T09:31:48.937-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Charts'/><title type='text'>Multiple Hyperlinks on BIRT Charts</title><content type='html'>BIRT 2.5.1 was released a couple of weeks ago and with its release BIRT Charts now support multiple hyperlinks.  To use this feature select any of the interactivity locations within the chart builder.  Next select the add button under the hyperlinks list box.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/St4G_c0sMlI/AAAAAAAAAGY/5AvaT49sYGI/s1600-h/builder.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 284px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/St4G_c0sMlI/AAAAAAAAAGY/5AvaT49sYGI/s320/builder.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5394757090775151186" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This will launch the hyperlink editor.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/St4HIfpDV6I/AAAAAAAAAGg/3YYfN_woIXk/s1600-h/hyperlinkeditor.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 207px; height: 320px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/St4HIfpDV6I/AAAAAAAAAGg/3YYfN_woIXk/s320/hyperlinkeditor.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5394757246150465442" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enter the name you wish to appear in the context menu.  Next select the edit base URL button, which will display the Hyperlink Options editor.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/St4HSqdzWDI/AAAAAAAAAGo/_TkdB0KP7zc/s1600-h/hyperlinkoptions.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 284px; height: 320px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/St4HSqdzWDI/AAAAAAAAAGo/_TkdB0KP7zc/s320/hyperlinkoptions.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5394757420854761522" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here you have the option to link to a URI, a bookmark within the same report or to a bookmark in another report.  Values from the current chart can be passed through to the target.  For example the value of a slice could be passed to a google query.  To do this select the URI radial and enter an expression similar to the one shown in the image below.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/St4IH5vSU2I/AAAAAAAAAG4/v8_16reQ6TY/s1600-h/hyperlink.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 320px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/St4IH5vSU2I/AAAAAAAAAG4/v8_16reQ6TY/s320/hyperlink.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5394758335487693666" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When running the report containing the chart, the multiple hyperlinks menu will popup on whatever event you defined in the editor.  In the above example this was defined on a mouse click event.  So clicking on a slice of the pie will cause the multiple hyperlinks context menu to appear.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/St4IUcxpQTI/AAAAAAAAAHA/WvyNekn5YpM/s1600-h/execute.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 287px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/St4IUcxpQTI/AAAAAAAAAHA/WvyNekn5YpM/s320/execute.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5394758551051256114" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This sample report is available at &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/1074-mult-hyperlink-chart-sample/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-982679717359004673?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='Multiple Hyperlinks on BIRT Charts'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/982679717359004673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=982679717359004673' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/982679717359004673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/982679717359004673'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/10/multiple-hyperlinks-on-birt-charts.html' title='Multiple Hyperlinks on BIRT Charts'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_GN1FyT5H8Kg/St4G_c0sMlI/AAAAAAAAAGY/5AvaT49sYGI/s72-c/builder.PNG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7237980129408940288</id><published>2009-09-28T18:47:00.000-07:00</published><updated>2009-09-28T19:09:12.126-07:00</updated><title type='text'>Calling BIRT reports from Wicket using Actuate’s JSAPI</title><content type='html'>I have written several posts on how to use the Actuate JSAPI to integrate with various frameworks.  In this post I will detail integrating with Wicket.  For more information on the JSAPI see this post:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2008/11/showing-birt-reports-using-actuate.html"&gt;Showing BIRT Reports using the Actuate JSAPI&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Wicket can call BIRT reports with the JSAPI in a similar fashion as other front end frameworks that allow AJAX based APIs, where JavaScript is just embedded into the HTML.  An HTML file based on the Hello World Wicket example may look similar to the following.&lt;br /&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Actuate JSAPI Wicket Example&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"&amp;gt;&lt;br /&gt;&amp;lt;title&amp;gt;Viewer creation example&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;b&amp;gt;&lt;br /&gt;&amp;lt;span wicket:id="message"&amp;gt;message will be here&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/b&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div id="acviewer" /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;div id="jsapi_example_container"&amp;gt;&amp;lt;script type="text/javascript"&lt;br /&gt; src="http://localhost:8080/ActuateJavaComponent/jsapi"&amp;gt;&amp;lt;/script&amp;gt; &amp;lt;script&lt;br /&gt; type="text/javascript" language="JavaScript"&amp;gt;&lt;br /&gt;&lt;br /&gt; actuate.load("viewer");&lt;br /&gt; actuate.initialize("http://localhost:8080/ActuateJavaComponent/",&lt;br /&gt; null,&lt;br /&gt; null,&lt;br /&gt; null,&lt;br /&gt; initViewer);&lt;br /&gt; var viewer;&lt;br /&gt; function initViewer()&lt;br /&gt; {&lt;br /&gt;  viewer = new actuate.Viewer("acviewer");&lt;br /&gt;  var viewerwidth = 800;&lt;br /&gt;  var viewerheight = 620; &lt;br /&gt;  viewer.setWidth(viewerwidth);&lt;br /&gt;  viewer.setHeight(viewerheight);&lt;br /&gt;  run();&lt;br /&gt; }&lt;br /&gt; Using a Wicket Behavior to write out this code&lt;br /&gt; function run()&lt;br /&gt; { &lt;br /&gt;  viewer.setParameters({"Customer":"CAF Imports"});&lt;br /&gt;  viewer.setReportName("/Public/BIRT and BIRT Report Studio Examples/Customer Order History.rptdesign");&lt;br /&gt;  viewer.submit();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &amp;lt;/script&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt; &lt;br /&gt;&lt;br /&gt;This example will look very familiar to other examples in the JSAPI overview post.  The only real difference is the addition of the wicket message, which is generated by my instance of the Wicket Web Page class.  You will notice that the run JavaScript function is hard coding the report name and parameters.  This may be something you want to handle in the Java code, to make it more dynamic.  One way of handling this is to use Wicket Behaviors to create custom components.  You could use a Behavior to write out all the above JavaScript, but we will keep it simple and just write out the run script.  So the first thing to do is to create a class that extends the AbstractBehavior class.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;package jsapi.wicket.sample;&lt;br /&gt;&lt;br /&gt;import org.apache.wicket.Component;&lt;br /&gt;import org.apache.wicket.Response;&lt;br /&gt;import org.apache.wicket.behavior.AbstractBehavior;&lt;br /&gt;import org.apache.wicket.util.string.JavascriptUtils;&lt;br /&gt;&lt;br /&gt;public class ReportComponent extends AbstractBehavior{&lt;br /&gt;&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt; public void onRendered(Component component) {&lt;br /&gt;        Response response = component.getResponse(); &lt;br /&gt;        response.write(JavascriptUtils.SCRIPT_OPEN_TAG);&lt;br /&gt;        response.write("function run(){");&lt;br /&gt;        response.write("viewer.setParameters({\"Customer\":\"CAF Imports\"});");&lt;br /&gt;        response.write("viewer.setReportName(\"/Public/BIRT and BIRT Report Studio Examples/Customer Order History.rptdesign\");");&lt;br /&gt;     response.write("viewer.submit();}");&lt;br /&gt;        response.write(JavascriptUtils.SCRIPT_CLOSE_TAG);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This class overides the onRendered method to write out the entire run script from the HTML above.   I can now modify my extended WebPage class to add an instance of the ReportComponent class.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;package jsapi.wicket.sample;&lt;br /&gt;&lt;br /&gt;import org.apache.wicket.PageParameters;&lt;br /&gt;import org.apache.wicket.markup.html.WebPage;&lt;br /&gt;import org.apache.wicket.markup.html.basic.Label;&lt;br /&gt;&lt;br /&gt;public class ReportParameter extends WebPage {&lt;br /&gt;&lt;br /&gt; private static final long serialVersionUID = 1L;&lt;br /&gt;&lt;br /&gt; public ReportParameter(final PageParameters parameters) {&lt;br /&gt;&lt;br /&gt;  // Add the simplest type of label&lt;br /&gt;  Label myLabel = new Label("message", "Actuate JSAPI Wicket Example");&lt;br /&gt;  add(myLabel);&lt;br /&gt;  ReportComponent rc = new ReportComponent();&lt;br /&gt;  myLabel.add(rc);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The script is written below the Label component.&lt;br /&gt;Finally the HTML should have the run JavaScript function commented out.  The output from this example is as follows.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/SsFqBZ3zFeI/AAAAAAAAAGA/_A3efwmRunk/s1600-h/WicketExample1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 260px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/SsFqBZ3zFeI/AAAAAAAAAGA/_A3efwmRunk/s320/WicketExample1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5386703201669158370" /&gt;&lt;/a&gt;&lt;br /&gt;The generated HTML looks like:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SsFqwFrv6jI/AAAAAAAAAGI/LnLoyqguAe8/s1600-h/source.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 190px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SsFqwFrv6jI/AAAAAAAAAGI/LnLoyqguAe8/s320/source.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5386704003703761458" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note that you can use the built in view time functions like selecting new parameters and rerunning the report without any additional code.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/SsFq_kWC8BI/AAAAAAAAAGQ/ZNG-WgnuSMM/s1600-h/WicketExample2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 320px; height: 260px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/SsFq_kWC8BI/AAAAAAAAAGQ/ZNG-WgnuSMM/s320/WicketExample2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5386704269632270354" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The example files can be downloaded from &lt;a href="http://www.birt-exchange.org/devshare/deploying-birt-reports/1045-calling-birt-reports-from-wicket-using-the-jsapi/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7237980129408940288?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='Calling BIRT reports from Wicket using Actuate’s JSAPI'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7237980129408940288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7237980129408940288' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7237980129408940288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7237980129408940288'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/09/calling-birt-reports-from-wicket-using.html' title='Calling BIRT reports from Wicket using Actuate’s JSAPI'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GN1FyT5H8Kg/SsFqBZ3zFeI/AAAAAAAAAGA/_A3efwmRunk/s72-c/WicketExample1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-7316682967108926409</id><published>2009-09-03T11:43:00.000-07:00</published><updated>2009-09-03T12:11:48.674-07:00</updated><title type='text'>Calling BIRT reports from Flex using Actuate’s JSAPI</title><content type='html'>Continuing on a series of posts I have written around Acuate’s JSAPI, this post details integrating BIRT reports with Flex.   Previous posts detailed:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2008/11/showing-birt-reports-using-actuate.html"&gt;Showing BIRT Reports using the Actuate JSAPI&lt;/a&gt;&lt;br /&gt;See this link for more details on what is available in the JSAPI.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2009/08/calling-birt-reports-from-php-using.html"&gt;Calling BIRT Reports from PHP using Actuate’s JSAPI&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2009/06/calling-birt-reports-from-aspnet-using.html"&gt;Calling BIRT Reports from ASP.NET using Actuate’s JSAPI&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;BIRT Reports can contain Flash components using the Text element.  Actuate has also extended the BIRT report designer to include Flash charts.  As stated in previous post the JSAPI can be used to include BIRT content in just about any front end.  BIRT currently does not support a Flash emitter, but a Flex component can call the JSAPI to include and modify BIRT content within the same HTML page.  This post details how this can be achieved.&lt;br /&gt;&lt;br /&gt;The Flex SDK provides a Flex Ajax bridge that allows a Flex application to call and interact with Ajax based APIs.  To illustrate how this can be used with Actuate’s JSAPI, I am going to build a Flex application that list a couple of reports.  The application will also contain a button to execute the report.  The output for the report will be written to another DIV element within the HTML wrapper.  &lt;br /&gt;&lt;br /&gt;The mxml file is pretty simple and contains a DataGrid that calls an action script to load the names and paths of two reports. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;br /&gt;&amp;lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" &lt;br /&gt;   width="640" height="300" layout="vertical"  backgroundColor="white"&amp;gt;&lt;br /&gt;   &amp;lt;fab:FABridge xmlns:fab="bridge.*" /&amp;gt;&lt;br /&gt;   &lt;br /&gt;   &amp;lt;mx:Panel id="pnlMain" x="10" y="10" width="560" height="260" &lt;br /&gt;   layout="absolute" title="BIRT Reports From Flex"&amp;gt;&lt;br /&gt;  &amp;lt;mx:DataGrid id="dgReports" x="10" y="10" initialize="initReports()" width="530" height="130"&amp;gt;&lt;br /&gt;    &amp;lt;mx:columns&amp;gt;&lt;br /&gt;      &amp;lt;mx:DataGridColumn headerText="Report Name" width="160" dataField="name"/&amp;gt;&lt;br /&gt;      &amp;lt;mx:DataGridColumn headerText="Report Path" dataField="path"/&amp;gt;&lt;br /&gt;    &amp;lt;/mx:columns&amp;gt;&lt;br /&gt;  &amp;lt;/mx:DataGrid&amp;gt;&lt;br /&gt;  &amp;lt;mx:Button x="10" y="156" label="Run Report From Flex" id="flashButton" /&amp;gt;&lt;br /&gt;&amp;lt;/mx:Panel&amp;gt;  &lt;br /&gt;&amp;lt;mx:Script&amp;gt;&lt;br /&gt; &amp;lt;![CDATA[&lt;br /&gt;   import mx.collections.ArrayCollection;&lt;br /&gt;   &lt;br /&gt;   public function initReports():void&lt;br /&gt;   {&lt;br /&gt;     var reports:Array = new Array();&lt;br /&gt;     reports.push({name: "Monthly Revenue Analysis", path: "/Public/BIRT and BIRT Report Studio Examples/Monthly Revenue Analysis.rptdesign"});&lt;br /&gt;     reports.push({name: "Sales by Territory", path: "/Public/BIRT and BIRT Report Studio Examples/Sales by Territory.rptdesign"});&lt;br /&gt;     var reportCollection:ArrayCollection = new ArrayCollection(reports);&lt;br /&gt;     dgReports.dataProvider = reportCollection;&lt;br /&gt;     dgReports.selectedIndex = 0;&lt;br /&gt;   }&lt;br /&gt; ]]&amp;gt;&lt;br /&gt;&amp;lt;/mx:Script&amp;gt;&lt;br /&gt;&amp;lt;/mx:Application&amp;gt; &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The fab:FABridge xmlns:fab=”bridge.*” tag includes the Flex Ajax bridge library.  In this example I just added a bridge directory to my application, which contained the FABridge.as and FABridge.js files that handle the bridge.  These files are available in the Flex SDK.  This application also contains a button (flashButton) that will be used by JavaScript later in the example.&lt;br /&gt;&lt;br /&gt;My wrapper HTML file contains a div element to display the application which is named BirtFlex.  The flashvars parameter is used to set a unique bridge name for this application.  The bridge name is used by JavaScript to get/set values within the Flex application.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  &amp;lt;div id="fply"&amp;gt;&lt;br /&gt;  &amp;lt;script language='javascript' charset='utf-8'&amp;gt;&lt;br /&gt;   document.write("&amp;lt;object id='flexApp' classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,5,0,0' type='application/x-shockwave-flash' height='300' width='640'&amp;gt;");&lt;br /&gt;   document.write("&amp;lt;param name='flashvars' value='bridgeName=birtexample'/&amp;gt;");&lt;br /&gt;   document.write("&amp;lt;param name='src' value='BirtFlex.swf'/&amp;gt;");&lt;br /&gt;   document.write("&amp;lt;embed name='BirtFlexDemo' pluginspage='http://www.macromedia.com/go/getflashplayer' src='BirtFlex.swf' height='300' width='640' flashvars='bridgeName=birtexample'/&amp;gt;");&lt;br /&gt;   document.write("&amp;lt;/object&amp;gt;");&lt;br /&gt;  &amp;lt;/script&amp;gt;&lt;br /&gt;  &amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;For brevity, I have foregone error checking and player checks.&lt;br /&gt;To use the JSAPI the following code is added to the wrapper HTML file.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  &amp;lt;div id="jsapi_example_container"&amp;gt;&lt;br /&gt;   &amp;lt;script type="text/javascript" src="http://localhost:8080/ActuateJavaComponent/jsapi"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;   &amp;lt;script type="text/javascript" language="JavaScript"&amp;gt;&lt;br /&gt;&lt;br /&gt;    actuate.load("viewer");&lt;br /&gt;    actuate.initialize("http://localhost:8080/ActuateJavaComponent/",&lt;br /&gt;         null,&lt;br /&gt;         null,&lt;br /&gt;         null,&lt;br /&gt;         initViewer);&lt;br /&gt;    var viewer;&lt;br /&gt;    function initViewer()&lt;br /&gt;    {&lt;br /&gt;     document.getElementById("run").disabled = true;&lt;br /&gt;     viewer = new actuate.Viewer("acviewer");&lt;br /&gt;     var viewerwidth = 500;&lt;br /&gt;     var viewerheight = 620;     &lt;br /&gt;     viewer.setWidth(viewerwidth);&lt;br /&gt;     viewer.setHeight(viewerheight);&lt;br /&gt;     setupFlashCallBack();&lt;br /&gt;    }&lt;br /&gt;    function run()&lt;br /&gt;    { &lt;br /&gt;     var flexApp = FABridge.birtexample.root();&lt;br /&gt;     var appValue = flexApp.getDgReports().getSelectedItem().path;&lt;br /&gt;     viewer.setReportName(appValue);&lt;br /&gt;     viewer.submit();&lt;br /&gt;    }&lt;br /&gt;    function setupFlashCallBack()&lt;br /&gt;    {&lt;br /&gt;     var initCallback = function()&lt;br /&gt;     {&lt;br /&gt;      //alert("Enabling");&lt;br /&gt;      document.getElementById("run").disabled = false;&lt;br /&gt;     }&lt;br /&gt;     var btnCallback = function()&lt;br /&gt;     {&lt;br /&gt;      var flexApp = FABridge.birtexample.root();&lt;br /&gt;      flexApp.getFlashButton().addEventListener("click",flashButtonClicked);&lt;br /&gt;     }&lt;br /&gt;     FABridge.addInitializationCallback("birtexample",initCallback);&lt;br /&gt;     FABridge.addInitializationCallback("birtexample",btnCallback);&lt;br /&gt;    }    &lt;br /&gt;    function flashButtonClicked(event)&lt;br /&gt;    {&lt;br /&gt;     run();&lt;br /&gt;    }&lt;br /&gt;   &amp;lt;/script&amp;gt;&lt;br /&gt;  &amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This code is very similar to previous examples with a few notable exceptions.  When the JSAPI is initialized the call back function initViewer is set.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt; actuate.initialize("http://localhost:8080/ActuateJavaComponent/",&lt;br /&gt;         null,&lt;br /&gt;         null,&lt;br /&gt;         null,&lt;br /&gt;         initViewer);&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Once the API is initialized, the initViewer JavaScript function is called.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    function initViewer()&lt;br /&gt;    {&lt;br /&gt;     document.getElementById("run").disabled = true;&lt;br /&gt;     viewer = new actuate.Viewer("acviewer");&lt;br /&gt;     var viewerwidth = 500;&lt;br /&gt;     var viewerheight = 620;     &lt;br /&gt;     viewer.setWidth(viewerwidth);&lt;br /&gt;     viewer.setHeight(viewerheight);&lt;br /&gt;     setupFlashCallBack();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In addition to a button in the Flex application, the HTML wrapper also contains one to run the report.  Not that two buttons are needed, but for illustrative purposes, this example contains two.  In this example we disable the button until both the JSAPI and the Flex component are initialized.  The Viewer JSAPI component is created as usual and then the setupFlashCallBack() function is called.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    function setupFlashCallBack()&lt;br /&gt;    {&lt;br /&gt;     var initCallback = function()&lt;br /&gt;     {&lt;br /&gt;      document.getElementById("run").disabled = false;&lt;br /&gt;     }&lt;br /&gt;     var btnCallback = function()&lt;br /&gt;     {&lt;br /&gt;      var flexApp = FABridge.birtexample.root();&lt;br /&gt;      flexApp.getFlashButton().addEventListener("click",flashButtonClicked);&lt;br /&gt;     }&lt;br /&gt;     FABridge.addInitializationCallback("birtexample",initCallback);&lt;br /&gt;     FABridge.addInitializationCallback("birtexample",btnCallback);&lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In this function two call back functions are registered.  The first one (initCallback) is setup to let us know when the Flex application is loaded, which then enables the run button.  The second one (btnCallback) registers an event handler that the bridge will call when the Flex button is pressed.  This event handler JavaScript function simply calls the run JavaScript function.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    function flashButtonClicked(event)&lt;br /&gt;    {&lt;br /&gt;     run();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The JavaScript button has the run function setup on the onclick event.&lt;br /&gt;&lt;code&gt;&lt;br /&gt; &amp;lt;input type="button" id="run" value="Run Report From JavaScript" onclick="run()" &amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;So the report can be run from either button.  The run function sets the report name and executes the API to run the report.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    function run()&lt;br /&gt;    { &lt;br /&gt;     var flexApp = FABridge.birtexample.root();&lt;br /&gt;     var appValue = flexApp.getDgReports().getSelectedItem().path;&lt;br /&gt;     viewer.setReportName(appValue);&lt;br /&gt;     viewer.submit();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/code&gt; &lt;br /&gt;&lt;br /&gt;The report path is retrieved using the getDgReports().getSelectedItem().path command.  The DataGrid in the mxml file is named dgReports&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;mx:DataGrid id="dgReports" x="10" y="10" initialize="initReports()" width="530" height="130"&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The bridge provides getter and setter methods for the items in the Flex application.  The DataGrid contains two columns (name and path).  The path contains the location of the report, so this is the field that is retrieved from the Flex application.  See the Flex developers guide for more details on the bridge calls.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SqATjLG2eSI/AAAAAAAAAF4/japaf8GFcV0/s1600-h/flexbirt.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 230px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SqATjLG2eSI/AAAAAAAAAF4/japaf8GFcV0/s320/flexbirt.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5377319450078247202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This example can be downloaded at &lt;a href="http://www.birt-exchange.org/devshare/deploying-birt-reports/1007-calling-jsapi-from-flex-application/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-7316682967108926409?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='Calling BIRT reports from Flex using Actuate’s JSAPI'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/7316682967108926409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=7316682967108926409' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7316682967108926409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/7316682967108926409'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/09/calling-birt-reports-from-flex-using.html' title='Calling BIRT reports from Flex using Actuate’s JSAPI'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GN1FyT5H8Kg/SqATjLG2eSI/AAAAAAAAAF4/japaf8GFcV0/s72-c/flexbirt.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-6490199676281634089</id><published>2009-08-26T13:23:00.000-07:00</published><updated>2010-06-02T12:15:53.769-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><category scheme='http://www.blogger.com/atom/ns#' term='Charts'/><title type='text'>Using Script to Modify a BIRT Chart</title><content type='html'>When designing BIRT reports that contain charts, the developer has many ways a chart can be customized.  One way is to implement a script event handler either in JavaScript or Java.  The chart engine currently supports over thirty hooks for implementing an event handler.  These events are fired during the generation and rendering of the chart.  Many items can be customized.  For example, the data for a chart can be changed in the afterDatasetFilled script, or the entire chart model can be changed in the beforeGeneration script.  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In addition to changing the chart using the chart scripting hooks, the chart model can also be changed using the primary BIRT report script hooks.  When making changes to the report, most developers will use the beforeFactory event script.  This event is fired prior to running the report and offers a location to make simple or complex changes to the report.  This includes modifying any charts that exist within the report.  Simple chart properties can be changed using the Chart Simple API.  An example of this approach is described &lt;a href="http://birtworld.blogspot.com/2008/04/birt-resizing-charts.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;For more complex changes, the Chart API can be called within the script.  As an example, changing a specific chart series type is possible.  BIRT 2.5 provides study charts which allow multiple Y-axes to be stacked, each with a different series type.  Turning this feature on or off can also be done using script.  These two changes can be done with the following script:&lt;br /&gt;&lt;br /&gt;First import the API packages that will be needed.&lt;br /&gt;&lt;code&gt;&lt;br /&gt; importPackage(Packages.org.eclipse.birt.chart.model.data.impl);&lt;br /&gt; importPackage(Packages.org.eclipse.birt.chart.model.type.impl);&lt;br /&gt; importPackage(Packages.org.eclipse.birt.chart.model.attribute.impl); &lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Retrieve the report design handle and find the chart.  Note that the chart needs to be named.  This can be done in the general properties for the chart.&lt;br /&gt;&lt;code&gt;&lt;br /&gt; //Chart must be named&lt;br /&gt; cht = reportContext.getDesignHandle().findElement("MyChart");&lt;br /&gt; //get the chart model;&lt;br /&gt; mychart = cht.getReportItem().getProperty( "chart.instance" );&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Next retrieve the axes.  In this example the chart has two Y-Axes.  The second one contains the series to be modified.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  xAxis =mychart.getAxes().get(0);&lt;br /&gt;  yAxis2 = xAxis.getAssociatedAxes().get(1);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Clear all series definitions defined for the second Y-axis.&lt;br /&gt;&lt;code&gt;&lt;br /&gt; yAxis2.getSeriesDefinitions().clear();&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The example report contains a combo parameter that allows the user to select the series type for the second Y-Axis.  The parameter is checked and an appropriate series is created.  Note that if an area series is created, the background is set to translucent.&lt;br /&gt;&lt;code&gt;&lt;br /&gt; if( params["SeriesType"].value == "Line"){&lt;br /&gt;  var ns = LineSeriesImpl.create();&lt;br /&gt; }else if( params["SeriesType"].value == "Bar"){&lt;br /&gt;  var ns = BarSeriesImpl.create();&lt;br /&gt; }else if( params["SeriesType"].value == "Area"){&lt;br /&gt;  var ns = AreaSeriesImpl.create();&lt;br /&gt;  ns.setTranslucent(true);&lt;br /&gt;  ns.getLineAttributes().setColor(ColorDefinitionImpl.TRANSPARENT())&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Create a new series definition and set the appropriate query and series type.&lt;br /&gt;&lt;code&gt;&lt;br /&gt; var sdNew = SeriesDefinitionImpl.create();&lt;br /&gt;  sdNew.getSeriesPalette( ).shift( 0 );&lt;br /&gt; ns.getLabel().setVisible(true);&lt;br /&gt; var qry = QueryImpl.create("row[\"QUANTITYORDERED\"]" );&lt;br /&gt; ns.getDataDefinition().add(qry)&lt;br /&gt; sdNew.getSeries().add( ns );&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Assign the new series definition to the second Y-Axis.&lt;br /&gt;&lt;code&gt;&lt;br /&gt; yAxis2.getSeriesDefinitions().add( sdNew );&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The example report also has a Boolean parameter that determines if the chart should be displayed as a study chart.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt; if( params["StudyChart"].value == true ){&lt;br /&gt;  mychart.setStudyLayout(true);&lt;br /&gt; }else{&lt;br /&gt;  mychart.setStudyLayout(false);&lt;br /&gt; }&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Some of the output options for this example report are displayed below.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/SpWbiOgcSRI/AAAAAAAAAFw/nqci4es2iHQ/s1600-h/example.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 258px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/SpWbiOgcSRI/AAAAAAAAAFw/nqci4es2iHQ/s320/example.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5374372742648580370" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This report is available at &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/992-change-chart-series-type-with-script/#description"&gt;Birt-Exchange&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-6490199676281634089?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/6490199676281634089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=6490199676281634089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6490199676281634089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6490199676281634089'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/08/using-script-to-modify-birt-chart.html' title='Using Script to Modify a BIRT Chart'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GN1FyT5H8Kg/SpWbiOgcSRI/AAAAAAAAAFw/nqci4es2iHQ/s72-c/example.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-9105665135627604830</id><published>2009-08-13T14:30:00.000-07:00</published><updated>2009-08-13T16:10:46.522-07:00</updated><title type='text'>Calling BIRT reports from PHP using Actuate’s JSAPI</title><content type='html'>I have written a couple of post on using Actuate’s JSAPI to include BIRT content within your system.  This API is AJAX based and allows content to be embedded within most web applications.&lt;br /&gt;&lt;br /&gt;These post can read here:&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2009/06/calling-birt-reports-from-aspnet-using.html"&gt;Calling BIRT Reports from ASP.NET&lt;/a&gt;&lt;br /&gt;and&lt;br /&gt;&lt;a href="http://birtworld.blogspot.com/2008/11/showing-birt-reports-using-actuate.html"&gt;Actuate's JSAPI&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In addition take a look at calling the &lt;a href="http://birtworld.blogspot.com/2009/03/using-birt-with-php.html"&gt;BIRT Engine from PHP&lt;/a&gt;, which I blogged about a while back.&lt;br /&gt;&lt;br /&gt;Calling the JSAPI from PHP is not much different than any other front end.  For example, including the interactive viewer can be done using the following code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;&lt;b&gt;$JSAPI_Location='http://localhost:8080/ActuateJavaComponent/jsapi';&lt;/b&gt;&lt;br /&gt;&lt;b&gt;$ReportFile='/Public/BIRT and BIRT Report Studio Examples/Customer Dashboard.rptdesign';&lt;/b&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&amp;lt;HTML&amp;gt;&lt;br /&gt; &amp;lt;head&amp;gt;&lt;br /&gt; &amp;lt;/head&amp;gt;&lt;br /&gt; &amp;lt;body&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;div id="jsapi_example_container"&amp;gt;&lt;br /&gt;   &lt;b&gt;&amp;lt;script type="text/javascript" src="&amp;lt;?php echo $JSAPI_Location ?&amp;gt;"&amp;gt;&amp;lt;/script&amp;gt;&lt;/b&gt;&lt;br /&gt;   &amp;lt;script type="text/javascript" language="JavaScript"&amp;gt;&lt;br /&gt;    &amp;lt;!-- Load the viewer component of the Actuate object --&amp;gt;&lt;br /&gt;    actuate.load("viewer");    &lt;br /&gt;    &lt;b&gt;actuate.initialize("&amp;lt;?php echo substr($JSAPI_Location, 0, -5) ?&amp;gt;",&lt;/b&gt;&lt;br /&gt;         null,&lt;br /&gt;         null,&lt;br /&gt;         null,&lt;br /&gt;         initViewer);&lt;br /&gt;    var viewer;&lt;br /&gt;    function initViewer()&lt;br /&gt;    {&lt;br /&gt;     viewer = new actuate.Viewer("acviewer");&lt;br /&gt;     &amp;lt;!-- register an event handler to catch exceptions --&amp;gt;     &lt;br /&gt;     viewer.registerEventHandler(actuate.viewer.EventConstants.ON_EXCEPTION, errorHandler);&lt;br /&gt;     run();&lt;br /&gt;    }&lt;br /&gt;    function run()&lt;br /&gt;    { &lt;br /&gt;&lt;br /&gt;     &lt;b&gt;viewer.setReportName("&amp;lt;?php echo $ReportFile ?&amp;gt;");&lt;/b&gt;&lt;br /&gt;     viewer.submit();&lt;br /&gt;    }&lt;br /&gt;    function errorHandler(viewInstance, exception)&lt;br /&gt;    {&lt;br /&gt;     alert(exception.getMessage());&lt;br /&gt;    }&lt;br /&gt;   &amp;lt;/script&amp;gt;&lt;br /&gt;   &amp;lt;div id="acviewer"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;/div&amp;gt;&lt;br /&gt; &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/HTML&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;In this example I am setting the JSAPI location and report file to run using a couple of PHP variables.  The JSAPI is initialized and the callback function initViewer is called which creates the viewer within the acviewer div element.   The initViewer function then calls the run method which sets the report to run and executes it.  The report is then displayed within the acviewer div element.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SoSQL6gHzZI/AAAAAAAAAFQ/MFtegV4-S-0/s1600-h/viewerphp.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 298px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SoSQL6gHzZI/AAAAAAAAAFQ/MFtegV4-S-0/s320/viewerphp.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5369575190089420178" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If the report has parameters you can use the parameter component of the JSAPI or set them using PHP variables.&lt;br /&gt;&lt;br /&gt;Change the code above to add the parameter values.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?PHP&lt;br /&gt;$JSAPI_Location='http://localhost:8080/ActuateJavaComponent/jsapi';&lt;br /&gt;$ReportFile='/Public/BIRT and BIRT Report Studio Examples/Sales By Territory.rptdesign';&lt;br /&gt;$reportTerritory='NA';&lt;br /&gt;$reportYear=2004;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Next, within the run method set the parameters using code similar to the following.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    function run()&lt;br /&gt;    { &lt;br /&gt;                     viewer.setParameters(&lt;br /&gt;                                  {&lt;br /&gt;"Territory": "&amp;lt;?php echo $reportTerritory ?&amp;gt;",&lt;br /&gt;"currentYear": &amp;lt;?php echo $reportYear ?&amp;gt;&lt;br /&gt;                                  }&lt;br /&gt;                     );&lt;br /&gt;     viewer.setReportName("&amp;lt;?php echo $ReportFile ?&amp;gt;");&lt;br /&gt;     viewer.submit();&lt;br /&gt;    }&lt;br /&gt;&lt;/code&gt;    &lt;br /&gt;To use the parameter component use code similar to the following.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt; $JSAPI_Location='http://localhost:8080/ActuateJavaComponent/jsapi';&lt;br /&gt; $ReportFile='/Public/BIRT and BIRT Report Studio Examples/DateTest.rptdesign'; &lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &amp;lt;div id="jsapi_example_container"&amp;gt;&lt;br /&gt;  &amp;lt;script type="text/javascript" src="&amp;lt;?php echo $JSAPI_Location ?&amp;gt;"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;  &amp;lt;script type="text/javascript" language="JavaScript"&amp;gt;&lt;br /&gt;   var paramObj;&lt;br /&gt;   var viewer;&lt;br /&gt;   actuate.load("viewer");&lt;br /&gt;   actuate.initialize("&amp;lt;?php echo substr($JSAPI_Location, 0, -5) ?&amp;gt;",&lt;br /&gt;            null,&lt;br /&gt;            null,&lt;br /&gt;            null,&lt;br /&gt;            init);&lt;br /&gt;&lt;br /&gt;   function init()&lt;br /&gt;   {&lt;br /&gt;    &amp;lt;!-- parameter --&amp;gt;&lt;br /&gt;    paramObj = new actuate.Parameter("parampane");&lt;br /&gt;    &amp;lt;!-- register an event handler to catch exceptions --&amp;gt;&lt;br /&gt;    paramObj.registerEventHandler(actuate.parameter.EventConstants.ON_EXCEPTION, parameterErrorHandler);&lt;br /&gt;    &amp;lt;!-- viewer --&amp;gt;&lt;br /&gt;    viewer = new actuate.Viewer("viewerpane");&lt;br /&gt;    var viewerwidth = 800;&lt;br /&gt;    var viewerheight = 600;&lt;br /&gt;    &amp;lt;!-- register an event handler to catch exceptions --&amp;gt;&lt;br /&gt;    viewer.registerEventHandler(actuate.viewer.EventConstants.ON_EXCEPTION, errorHandler);    &lt;br /&gt;    viewer.setWidth(viewerwidth);&lt;br /&gt;    viewer.setHeight(viewerheight);&lt;br /&gt;    runParam();&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   function runParam()&lt;br /&gt;   {&lt;br /&gt;    paramObj.setReportName("&amp;lt;?php echo $ReportFile ?&amp;gt;");&lt;br /&gt;    paramObj.submit(function () {document.getElementById("run").style.visibility = 'visible';});   &lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   function run()&lt;br /&gt;   {&lt;br /&gt;    paramObj.downloadParameterValues(runNext);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   function runNext( pvs )&lt;br /&gt;   {&lt;br /&gt;    &lt;b&gt;viewer.setParameterValues(pvs);&lt;/b&gt;&lt;br /&gt;    viewer.setReportName("&amp;lt;?php echo $ReportFile ?&amp;gt;");&lt;br /&gt;    viewer.submit();&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   function errorHandler(viewInstance, exception)&lt;br /&gt;   {&lt;br /&gt;    alert(exception.getMessage());&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;   function parameterErrorHandler(exception)&lt;br /&gt;   {&lt;br /&gt;    alert(exception.getMessage());&lt;br /&gt;   }&lt;br /&gt;   &lt;br /&gt;  &amp;lt;/script&amp;gt;&lt;br /&gt;   &amp;lt;table border=1&amp;gt;&lt;br /&gt;    &amp;lt;tr&amp;gt; &lt;br /&gt;     &amp;lt;td&amp;gt;&amp;lt;div id="parampane"&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;     &amp;lt;td&amp;gt;&amp;lt;input type="button" class="btn" id="run" value="Run Report" onclick="run()" style="visibility: hidden"&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;/tr&amp;gt;&lt;br /&gt;   &amp;lt;/table&amp;gt;&lt;br /&gt;   &amp;lt;div id="viewerpane"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The run function downloads the parameters that were set using the parameter component.  Next the setParameterValues method is used to set the parameter values for the run of the report.  Notice this example has a date parameter, and the JSAPI provides a date picker for this type of parameter.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SoSXoAvsmYI/AAAAAAAAAFY/XA3aquIw17o/s1600-h/date1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 241px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SoSXoAvsmYI/AAAAAAAAAFY/XA3aquIw17o/s320/date1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5369583369383090562" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SoSXsgjENhI/AAAAAAAAAFg/7Ith_uV-bZs/s1600-h/date2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 271px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SoSXsgjENhI/AAAAAAAAAFg/7Ith_uV-bZs/s320/date2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5369583446639523346" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you are already using some PHP class to implement a date picker, such as the one available at the &lt;a href=" http://stefangabos.blogspot.com"&gt;Zebra PHP Components Framework blog&lt;/a&gt;, you can modify your code to retrieve the date from the id of the element the date is stored in.  The above example would have the following modifications:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;    // include the class&lt;br /&gt;    &lt;b&gt;require "class.datepicker.php";&lt;br /&gt;    // instantiate the object&lt;br /&gt;    $dp=new datepicker();&lt;br /&gt; $dp-&gt;dateFormat="m/d/Y";&lt;/b&gt;&lt;br /&gt; $JSAPI_Location='http://localhost:8080/ActuateJavaComponent/jsapi';&lt;br /&gt; $ReportFile='/Public/BIRT and BIRT Report Studio Examples/DateTest.rptdesign'; &lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;br /&gt;   function runNext( pvs )&lt;br /&gt;   {&lt;br /&gt;    &lt;b&gt;//viewer.setParameterValues(pvs);&lt;br /&gt;    viewer.setParameters({"currentYear":2003, "currentMonth":12, "DateParameter":document.getElementById("date").value});&lt;/b&gt;    &lt;br /&gt;    viewer.setReportName("&lt;?php echo $ReportFile ?&gt;");&lt;br /&gt;    viewer.submit();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   &amp;lt;table border=1&amp;gt;&lt;br /&gt;    &lt;b&gt;&amp;lt;tr&amp;gt;&lt;br /&gt;     &amp;lt;td&amp;gt;&amp;lt;input type="text" id="date"&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;     &amp;lt;td&amp;gt;&amp;lt;input type="button" value="Select Date" onclick="&amp;lt;?=$dp-&amp;gt;show("date")?&amp;gt;"&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;/tr&amp;gt;&lt;/b&gt;&lt;br /&gt;    &amp;lt;tr&amp;gt;&lt;br /&gt;     &amp;lt;td&amp;gt;&amp;lt;div id="parampane"&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;     &amp;lt;td&amp;gt;&amp;lt;input type="button" class="btn" id="run" value="Run Report" onclick="run()" style="visibility: hidden"&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;    &amp;lt;/tr&amp;gt;&lt;br /&gt;   &amp;lt;/table&amp;gt;&lt;br /&gt;   &amp;lt;div id="viewerpane"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt; &lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SoSbaWuHouI/AAAAAAAAAFo/w1-m-GN5v-g/s1600-h/datepick3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 272px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SoSbaWuHouI/AAAAAAAAAFo/w1-m-GN5v-g/s320/datepick3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5369587532810396386" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-9105665135627604830?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='Calling BIRT reports from PHP using Actuate’s JSAPI'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/9105665135627604830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=9105665135627604830' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/9105665135627604830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/9105665135627604830'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/08/calling-birt-reports-from-php-using.html' title='Calling BIRT reports from PHP using Actuate’s JSAPI'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GN1FyT5H8Kg/SoSQL6gHzZI/AAAAAAAAAFQ/MFtegV4-S-0/s72-c/viewerphp.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-6927679127765353007</id><published>2009-07-09T09:49:00.000-07:00</published><updated>2009-07-09T09:50:57.375-07:00</updated><title type='text'>The Heavy Hand</title><content type='html'>Today I received a foundation email with this little nugget in it:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Pursuant to the Eclipse Foundation Bylaws, the Eclipse Foundation recently amended the Eclipse Foundation Bylaws and Membership Agreement. As required by the Eclipse Foundation Membership Agreement, we require your formal acceptance of these changes which became effective July 23, 2008 and are more fully described at: http://www.eclipse.org/membership/vote2008/. &lt;br /&gt;&lt;br /&gt;Formal acceptance is &lt;b&gt;required&lt;/b&gt; by virtue of the Membership Agreement. It should be noted that these changes are &lt;b&gt;not optional&lt;/b&gt; and apply to all Eclipse Members upon Membership renewal from July 23, 2008 onwards.&amp;nbsp; (emphasis added)&lt;/blockquote&gt;Now I have no problem with the changes to the by laws.&amp;nbsp; In fact, they are great for my small company.&amp;nbsp; What I don't understand is why I need to agree in writing to these non-optional requirements?&lt;br /&gt;&lt;br /&gt;If the decision has all ready been made, why do I need to agree in writing?&amp;nbsp; Maybe it is just me, but it feels heavy handed (and pointless) to insist that I validate a decision after it has all ready been made.&lt;br /&gt;&lt;br /&gt;After all, if I don't like the decision I can just choose not to renew.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-6927679127765353007?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/6927679127765353007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=6927679127765353007' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6927679127765353007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/6927679127765353007'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/07/heavy-hand.html' title='The Heavy Hand'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-2724664458505703675</id><published>2009-06-26T09:54:00.001-07:00</published><updated>2010-06-02T12:15:53.769-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>Passing JDBC ResultSet to a report</title><content type='html'>Nice article on how to pass a JDBC resultset to a report at &lt;br /&gt;&lt;br /&gt;&lt;a href="http://techieocean.blogspot.com/2009/06/how-to-pass-resultset-to-birt-report.html"&gt;Techie.Ocean&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-2724664458505703675?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/2724664458505703675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=2724664458505703675' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/2724664458505703675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/2724664458505703675'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/06/passing-jdbc-resultset-to-report.html' title='Passing JDBC ResultSet to a report'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-3992652681893182888</id><published>2009-06-12T13:30:00.000-07:00</published><updated>2009-06-12T13:42:40.561-07:00</updated><title type='text'>Calling BIRT reports from ASP.NET using Actuate’s JSAPI</title><content type='html'>A while back I wrote a &lt;a href="http://birtworld.blogspot.com/2008/11/showing-birt-reports-using-actuate.html"&gt;blog entry &lt;/a&gt;about Actuate’s new JSAPI.  This API is AJAX based and allows BIRT reports to be displayed using virtually any front end.  The previous post points to an article on Birt-Exchange that describes the capabilities of the API.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SjK7fo2em9I/AAAAAAAAAE4/QmW-n4uxrnk/s1600-h/JSAPIArch.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/SjK7fo2em9I/AAAAAAAAAE4/QmW-n4uxrnk/s320/JSAPIArch.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5346541859858455506" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To include the API within an ASP.NET page is very simple.  All that is needed is to add a script tag within the head tag and point it to the location you have installed the Actuate Java Component package. &lt;br /&gt;&lt;br /&gt;&amp;lt;head runat="server"&gt;&lt;br /&gt;    &amp;lt;script type="text/javascript" language="JavaScript" src="http://localhost:8080/ActuateJavaComponent/jsapi"&gt;&amp;lt;/script&gt;&lt;br /&gt;&amp;lt;/head&gt;&lt;br /&gt;&lt;br /&gt;The viewer can now be created within any div statement in the page by using code similar to the following.&lt;br /&gt;&lt;br /&gt;  &amp;lt;div id="viewer1" style="width: 800px; height: 600px; border-width: 1px; border-style: solid;"&gt;&lt;br /&gt;         &amp;lt;script type="text/javascript" language="JavaScript"&gt;&lt;br /&gt;            function createViewer() {&lt;br /&gt;                var viewer1 = new actuate.Viewer("viewer1");                &lt;br /&gt;                viewer1.setReportName("/Public/BIRT and BIRT Report Studio Examples/" + "&amp;lt;%=DropDownList1.Text%&gt;");&lt;br /&gt;                viewer1.setWidth(600);&lt;br /&gt;                viewer1.setHeight(450);&lt;br /&gt;                viewer1.submit();&lt;br /&gt;&lt;br /&gt;            }&lt;br /&gt;            actuate.load("viewer");&lt;br /&gt;            actuate.initialize("http://localhost:8080/ActuateJavaComponent/", null, null, null, createViewer);&lt;br /&gt;        &amp;lt;/script&amp;lt;/div&gt;&lt;br /&gt;&lt;br /&gt;In the above example we are setting the report name based on a drop down list that is populated with the following code.&lt;br /&gt;&lt;br /&gt;    &amp;lt;asp:DropDownList ID="DropDownList2" runat="server" AutoPostBack="True"&gt;&lt;br /&gt;        &amp;lt;asp:ListItem&gt;Customer Order History.rptdesign&amp;lt;/asp:ListItem&gt;&lt;br /&gt;        &amp;lt;asp:ListItem&gt;Sales by Territory.rptdesign&amp;lt;/asp:ListItem&gt;&lt;br /&gt;        &amp;lt;asp:ListItem&gt;Customer Dashboard.rptdesign&amp;lt;/asp:ListItem&gt;&lt;br /&gt;    &amp;lt;/asp:DropDownList&gt;&lt;br /&gt;&lt;br /&gt;The viewer is created within the “viewer1” div tag.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SjK8aGnCwRI/AAAAAAAAAFA/kxG3Y4P4MXE/s1600-h/asp.netexample1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 288px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SjK8aGnCwRI/AAAAAAAAAFA/kxG3Y4P4MXE/s320/asp.netexample1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5346542864279191826" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The API also supplies a component for presenting parameters.  This component can be created in a similar method to the viewer component.&lt;br /&gt;&lt;br /&gt;            function createParameter() {&lt;br /&gt;                myParam = new actuate.Parameter("myDivContainer");&lt;br /&gt;                myParam.setReportName("/Public/BIRT and BIRT Report Studio Examples/Sales By Territory.rptdesign");&lt;br /&gt;                myParam.submit();&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;This will present a parameter page that is based on the parameter designs within the report.  The Parameter component can be used in conjunction with the Viewer component to display both the parameters and the report within one page.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;button onclick="runReport()"&gt;&lt;br /&gt;        Run Report&lt;br /&gt;    &amp;lt;/button&gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;div id="myDivContainer" style="border-width: 1px; border-style: solid;"&gt;&lt;br /&gt;    &amp;lt;/div&gt;&lt;br /&gt;    &amp;lt;div id="myViewerDivContainer" style="border-width: 1px; border-style: solid;"&gt;&lt;br /&gt;    &amp;lt;/div&gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;script type="text/javascript" language="JavaScript"&gt;&lt;br /&gt;            var myViewer = null;&lt;br /&gt;            var myParam = null;&lt;br /&gt;            function createParameter() {&lt;br /&gt;                myParam = new actuate.Parameter("myDivContainer");&lt;br /&gt;                myParam.setReportName("/Public/BIRT and BIRT Report Studio Examples/Sales By Territory.rptdesign");&lt;br /&gt;                myParam.submit();&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            function runReport() {&lt;br /&gt;                myViewer = new actuate.Viewer("myViewerDivContainer");&lt;br /&gt;                myViewer.setReportName("/Public/BIRT and BIRT Report Studio Examples/Sales By Territory.rptdesign");&lt;br /&gt;                myViewer.setParameters(myParam.getParameterMap();&lt;br /&gt;                myViewer.submit();&lt;br /&gt;            }&lt;br /&gt;            actuate.load("parameter");&lt;br /&gt;            actuate.load("viewer");&lt;br /&gt;            actuate.initialize("http://localhost:8080/ActuateJavaComponent/", null, null, null, createParameter);&lt;br /&gt;        &amp;lt;/script&gt;&lt;br /&gt;&lt;br /&gt;This line:&lt;br /&gt;                myViewer.setParameters(myParam.getParameterMap();&lt;br /&gt;&lt;br /&gt;Sets the parameters entered in the parameter component to the viewer component.  If you decide to create your own parameter controls, the values can be passed to viewer component using name value pairs.&lt;br /&gt;&lt;br /&gt;    &amp;lt;form id="form1" runat="server"&gt;&lt;br /&gt;    &amp;lt;asp:DropDownList ID="DropDownList1" runat="server"&gt;&lt;br /&gt;        &amp;lt;asp:ListItem&gt;NA&amp;lt;/asp:ListItem&gt;&lt;br /&gt;        &amp;lt;asp:ListItem&gt;Japan&amp;lt;/asp:ListItem&gt;&lt;br /&gt;        &amp;lt;asp:ListItem&gt;EMEA&amp;lt;/asp:ListItem&gt;&lt;br /&gt;    &amp;lt;/asp:DropDownList&gt;&lt;br /&gt;    &amp;lt;/form&gt;&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;myViewer.setParameters({ "Territory": document.getElementById("DropDownList1").value });&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_GN1FyT5H8Kg/SjK9DxRSCKI/AAAAAAAAAFI/mQ2DJV9U7aQ/s1600-h/asp.netexample2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 288px;" src="http://2.bp.blogspot.com/_GN1FyT5H8Kg/SjK9DxRSCKI/AAAAAAAAAFI/mQ2DJV9U7aQ/s320/asp.netexample2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5346543580105279650" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The examples are available &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/896-call-jaspi-from-asp-net-pages/#description"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-3992652681893182888?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='Calling BIRT reports from ASP.NET using Actuate’s JSAPI'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/3992652681893182888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=3992652681893182888' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3992652681893182888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3992652681893182888'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/06/calling-birt-reports-from-aspnet-using.html' title='Calling BIRT reports from ASP.NET using Actuate’s JSAPI'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GN1FyT5H8Kg/SjK7fo2em9I/AAAAAAAAAE4/QmW-n4uxrnk/s72-c/JSAPIArch.PNG' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-4398897108206829127</id><published>2009-05-27T09:15:00.000-07:00</published><updated>2009-05-27T09:15:17.424-07:00</updated><title type='text'>Change Page Layout</title><content type='html'>Been busy writing reports lately, but I thought that I would try to publish a few quick tips that I have turned up.  &lt;br /&gt;&lt;br /&gt;One of the issues I have faced is that when a report is being formatted for PDF layout, I want it to be constrained to the page dimensions and to have it in portrait style.  At the same time, when it is displayed for HTML, I want to have it in Landscape mode since the rendering seems to be better for HTML.  &lt;br /&gt;&lt;br /&gt;This little section of script placed in the beforeFactory method of the ReportItem will do that for you.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;var renderO = reportContext.getRenderOption().getOutputFormat();&lt;br /&gt;// change layout&lt;br /&gt;if (renderO == &amp;quot;pdf&amp;quot;){&lt;br /&gt;    reportContext.getDesignHandle().getMasterPages().get(0).setProperty(&amp;quot;orientation&amp;quot;,&amp;quot;portrait&amp;quot;);&lt;br /&gt;} else if (renderO == &amp;quot;html&amp;quot;)&lt;br /&gt;    reportContext.getDesignHandle().getMasterPages().get(0).setProperty(&amp;quot;orientation&amp;quot;,&amp;quot;landscape&amp;quot;);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-4398897108206829127?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/4398897108206829127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=4398897108206829127' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/4398897108206829127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/4398897108206829127'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/05/change-page-layout.html' title='Change Page Layout'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-3938457827815677420</id><published>2009-05-18T07:36:00.000-07:00</published><updated>2009-05-18T07:40:59.729-07:00</updated><title type='text'>BIRT 2.5 M7 New and Notable</title><content type='html'>BIRT 2.5 M7 was released earlier this month.  This milestone adds features like, default parameter value scripting, the ability to paste HTML and RTF directly into a Text element, and independent Locale formatting.  Crosstabs have also been improved to support dragging attributes directly from the data cube into the crosstab, independent visibility for a measure and its totals, and improved support for empty values associated with a time dimension.  In addition a new interface is provided that allows your Java programs to track the progress of a BIRT report.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_GN1FyT5H8Kg/ShFzDDF5kdI/AAAAAAAAAEw/TqJBbJ_7yLk/s1600-h/collagsmall.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 229px; height: 320px;" src="http://1.bp.blogspot.com/_GN1FyT5H8Kg/ShFzDDF5kdI/AAAAAAAAAEw/TqJBbJ_7yLk/s320/collagsmall.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5337173529617600978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To read more about the new features, go &lt;a href="http://www.eclipse.org/birt/phoenix/project/notable2.5M7.php"&gt;here&lt;/a&gt;.  As always we appreciate feedback on the new features.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-3938457827815677420?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='BIRT 2.5 M7 New and Notable'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/3938457827815677420/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=3938457827815677420' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3938457827815677420'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3938457827815677420'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/05/birt-25-m7-new-and-notable.html' title='BIRT 2.5 M7 New and Notable'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_GN1FyT5H8Kg/ShFzDDF5kdI/AAAAAAAAAEw/TqJBbJ_7yLk/s72-c/collagsmall.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-3144281245859653598</id><published>2009-04-30T14:30:00.000-07:00</published><updated>2010-06-02T12:15:53.770-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>BIRT Cascaded Parameters</title><content type='html'>BIRT provides the capability to use dynamic parameters to present the end user with a list of choices that are populated from a dataset.  This is very useful but can cause issues when the dataset returns many rows of data.  To reduce the number of items in any parameter, the developer can use a cascaded parameter, which allows multiple levels and multiple datasets.  When the user selects the first level parameter in a cascaded parameter group the second level in the group is automatically re-queried.  &lt;br /&gt;&lt;br /&gt;For example, if you have a customer detail report that allows the end user to select a particular customer, you could create a dynamic parameter that retrieves all the customer names from your database.  The user would then select the one they are interested in, and a detail report would be generated on the selected customer.  If you have thousands of customers this task becomes more difficult for the end user to navigate.  To remedy this, you could create a cascaded parameter that has as its first level, the country and once that value is selected, all customers for the specific country would be listed.  This assumes you have a field like country to that can be used to reduce the number of entries.  If you do not have a field like this, it may be possible to create your own using script.  &lt;br /&gt;&lt;br /&gt;If we take the customer list example, one way to reduce the number of items in any of the parameter list box, would be to sort the first level of the cascade alphabetically.  So the first level of the cascade could be tied to a scripted datasource that returns the letters of the alphabet.  Another option is to do a distinct query on the customers within the database that retrieves only the first letter like:&lt;br /&gt;&lt;br /&gt;select distinct SUBSTR( CUSTOMERNAME, 1, 1)&lt;br /&gt;from customers&lt;br /&gt;&lt;br /&gt;The second level in the cascade would then be defined with the following query.&lt;br /&gt;&lt;br /&gt;select customername&lt;br /&gt;from customers&lt;br /&gt;where customername like ?&lt;br /&gt;&lt;br /&gt;The question mark represents a data set input parameter, which is not the same as a report parameter.  The dataset parameter can be linked to a report parameter or set programmatically using script. In this example we need to use script to add a wildcard to the query.  So in the beforeOpen script of the second level query, we could do this:&lt;br /&gt;&lt;br /&gt;inputParams["alpha"] = params["FirstLetter"]+"%";&lt;br /&gt;&lt;br /&gt;In this example, alpha is the dataset parameter and the FirstLetter is the first level report parameter in the cascade group.  In this case we are only adding the wildcard to the query.&lt;br /&gt;&lt;br /&gt;The resultant parameter entry screen would look like:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SfoZNh7wPzI/AAAAAAAAAEo/D77btCuj7MU/s1600-h/cascade.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 267px;" src="http://3.bp.blogspot.com/_GN1FyT5H8Kg/SfoZNh7wPzI/AAAAAAAAAEo/D77btCuj7MU/s320/cascade.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5330600829184393010" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This report is available &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/833-cacade-report-parameter-list-culling/#description"&gt;here&lt;/a&gt;.  Another example using a scripted data source is available &lt;a href="http://www.birt-exchange.org/devshare/designing-birt-reports/834-cacade-parameter-list-culling-using-a-scripted-datasource/#description"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-3144281245859653598?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='BIRT Cascaded Parameters'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/3144281245859653598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=3144281245859653598' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3144281245859653598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/3144281245859653598'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/04/birt-cascaded-parameters.html' title='BIRT Cascaded Parameters'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_GN1FyT5H8Kg/SfoZNh7wPzI/AAAAAAAAAEo/D77btCuj7MU/s72-c/cascade.PNG' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-234873044976542338</id><published>2009-04-14T12:58:00.001-07:00</published><updated>2010-06-02T12:15:53.770-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>Multi-Select Parameters - Part 2</title><content type='html'>&amp;nbsp;In a &lt;a href="http://birtworld.blogspot.com/2009/03/birt-multi-select-statements.html"&gt;previous post&lt;/a&gt;&amp;nbsp;I described how you could create a simple method to use multi-select parameters with a SQL IN clause in a generic fashion. &amp;nbsp;In that post I referenced that the right way to do this is to use Java Bind variables&lt;br /&gt;&lt;blockquote&gt;&lt;span style="color: #333333; font-family: Verdana; font-size: 16px; line-height: 20px;"&gt;There is a way that this can be done using Java Bind variables, but it is significantly more difficult.&lt;/span&gt;&lt;/blockquote&gt;But I did not explain how that is done. &amp;nbsp;Today I gave a webinar on how you can use the Design Engine API and the BIRT Script Function extension point to dynamically add parameter binding to your report designs. &lt;br /&gt;&lt;br /&gt;The DEAPI code is a bit tricky to use, but thanks to the ScriptFunction extension, any one can use the function quickly and easily.&lt;br /&gt;&lt;br /&gt;All of the code and the slides for the project are available on the Innovent Subversion server &lt;a href="http://longlake.minnovent.com/repos/birt_example/innovent.birt.functions/"&gt;here&lt;/a&gt;. &amp;nbsp;You can use the &lt;a href="http://subclipse.tigris.org/"&gt;subclipse&lt;/a&gt;&amp;nbsp;plugin to download this code as an Eclipse project.&lt;br /&gt;&lt;br /&gt;The slides for the presentation are included here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.scribd.com/doc/14342488/BIRT-Multi-Select-Parameters" style="-x-system-font: none; display: block; font-family: Helvetica,Arial,Sans-serif; font-size-adjust: none; font-size: 14px; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; margin: 12px auto 6px auto; text-decoration: underline;" title="View BIRT Multi Select Parameters on Scribd"&gt;BIRT Multi Select Parameters&lt;/a&gt; &lt;object align="middle" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" height="500" id="doc_229110567097178" name="doc_229110567097178" width="100%"&gt;  &lt;param name="movie" value="http://d.scribd.com/ScribdViewer.swf?document_id=14342488&amp;access_key=key-1i5grcxtvfe5k5bow3uq&amp;page=1&amp;version=1&amp;viewMode="&gt;&lt;param name="quality" value="high"&gt;&lt;param name="play" value="true"&gt;&lt;param name="loop" value="true"&gt;&lt;param name="scale" value="showall"&gt;&lt;param name="wmode" value="opaque"&gt;&lt;param name="devicefont" value="false"&gt;&lt;param name="bgcolor" value="#ffffff"&gt;&lt;param name="menu" value="true"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;param name="salign" value=""&gt;&lt;embed src="http://d.scribd.com/ScribdViewer.swf?document_id=14342488&amp;access_key=key-1i5grcxtvfe5k5bow3uq&amp;page=1&amp;version=1&amp;viewMode=" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" play="true" loop="true" scale="showall" wmode="opaque" devicefont="false" bgcolor="#ffffff" name="doc_229110567097178_object" menu="true" allowfullscreen="true" allowscriptaccess="always" salign="" type="application/x-shockwave-flash" align="middle"  height="500" width="100%"&gt;&lt;/embed&gt;   &lt;/object&gt; &lt;br /&gt;&lt;div style="-x-system-font: none; display: block; font-family: Helvetica,Arial,Sans-serif; font-size-adjust: none; font-size: 12px; font-stretch: normal; font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; margin: 6px auto 3px auto;"&gt;&lt;a href="http://www.scribd.com/upload" style="text-decoration: underline;"&gt;Publish at Scribd&lt;/a&gt; or &lt;a href="http://www.scribd.com/browse" style="text-decoration: underline;"&gt;explore&lt;/a&gt; others:            &lt;a href="http://www.scribd.com/browse/HowtoGuides-Manuals/" style="text-decoration: underline;"&gt;How-to-Guides &amp;amp; Manu&lt;/a&gt;                  &lt;a href="http://www.scribd.com/tag/multiselect" style="text-decoration: underline;"&gt;multiselect&lt;/a&gt;              &lt;a href="http://www.scribd.com/tag/script%20function" style="text-decoration: underline;"&gt;script function&lt;/a&gt;       &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-234873044976542338?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/234873044976542338/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=234873044976542338' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/234873044976542338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/234873044976542338'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/04/multi-select-parameters-part-2.html' title='Multi-Select Parameters - Part 2'/><author><name>Scott Rosenbaum</name><uri>http://www.blogger.com/profile/17441053019711310813</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://4.bp.blogspot.com/_5bQPsXqbEM4/Sv4qUlI1adI/AAAAAAAAAyw/GRJ0epDRi18/S220/IMG_0093.JPG'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-5505873450449560464</id><published>2009-04-01T10:28:00.000-07:00</published><updated>2009-04-01T10:32:07.130-07:00</updated><title type='text'>BIRT 2.5 M6 New and Notable</title><content type='html'>Just wanted to drop a note to say the new and notable for BIRT 2.5 M6 is now available.  Some great features are making their way into BIRT 2.5, like z ordering for combination charts, improved 508 compliance,  project configuration changes, and better image marker support. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_GN1FyT5H8Kg/SdOkmLGy0FI/AAAAAAAAAEg/EzZZgm_V5Es/s1600-h/2.5m6.PNG"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 296px; height: 320px;" src="http://4.bp.blogspot.com/_GN1FyT5H8Kg/SdOkmLGy0FI/AAAAAAAAAEg/EzZZgm_V5Es/s320/2.5m6.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5319776560577957970" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To read more about the new features, go &lt;a href="http://www.eclipse.org/birt/phoenix/project/notable2.5M6.php"&gt;here&lt;/a&gt;.  As always we appreciate feedback on the new features.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/14521551-5505873450449560464?l=birtworld.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.eclipse.org/birt' title='BIRT 2.5 M6 New and Notable'/><link rel='replies' type='application/atom+xml' href='http://birtworld.blogspot.com/feeds/5505873450449560464/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=14521551&amp;postID=5505873450449560464' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5505873450449560464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/14521551/posts/default/5505873450449560464'/><link rel='alternate' type='text/html' href='http://birtworld.blogspot.com/2009/04/birt-25-m6-new-and-notable.html' title='BIRT 2.5 M6 New and Notable'/><author><name>Jason Weathersby</name><uri>http://www.blogger.com/profile/13114050439576571984</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_GN1FyT5H8Kg/SdOkmLGy0FI/AAAAAAAAAEg/EzZZgm_V5Es/s72-c/2.5m6.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-14521551.post-2901865078397403900</id><published>2009-03-08T20:46:00.000-07:00</published><updated>2010-06-02T12:15:53.770-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scripts'/><title type='text'>BIRT Multi-Select Statements</title><content type='html'>Note: re-published to fix typos in the opening paragraph. &amp;nbsp;Oh the perils of late night posting.&lt;br /&gt;&lt;br /&gt;In BIRT 2.3.1 a new extension point was added to support the creation of user defined functions. &amp;nbsp;Jason has all ready blogged about the ScriptFunctionExecutor&amp;nbsp;&lt;a href="http://birtworld.blogspot.com/2008/09/birt-231-adding-functions-to-expression.html"&gt;here&lt;/a&gt;&amp;nbsp;. &amp;nbsp;In this post, I would like to show how this extension point can be used to automate handling Multi-Select input parameters in SQL statements.&lt;br /&gt;&lt;br /&gt;BIRT 2.3 added support for Multi-Select parameters. &amp;nbsp;The most typical application of this technology is to support using an IN statement within a SQL where clause. &amp;nbsp;Imagine having the following SQL:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;select status   &lt;br /&gt;from orders&lt;br /&gt;where state in (?)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;What you would like to be able to do is have a user select multiple parameters from a drop down list, and then have them work in the query. &amp;nbsp;At this time, BIRT does not support this, mostly because of the way JDBC property binding works. &amp;nbsp;JDBC would require a new parameter binding (?) to be added for each parameter value that was passed, e.g.&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border-bottom-color: rgb(153, 153, 153); border-bottom-style: dashed; border-bottom-width: 1px; border-left-color: rgb(153, 153, 153); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(153, 153, 153); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(153, 153, 153); border-top-style: dashed; border-top-width: 1px; color: black; font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 12px; line-height: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 100%;"&gt;&lt;code&gt;where state in (?, ?, ?)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;span style="font-family: '-webkit-monospace'; font-size: 12px; line-height: 14px; white-space: pre;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: '-webkit-monospace'; font-size: 12px; line-height: 14px; white-space: pre;"&gt;&lt;span style="font-family: 'Times New Roman'; font-size: 18px; line-height: normal; white-space: normal;"&gt;The problem is that you don't know how many parameters are passed when you design the report. &amp;nbsp;The work around that most people use is to write an event handler that will insert SQL into the query in the BeforeOpen method of the DataSet. &amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: '-webkit-monospace'; font-size: 12px; line-height: 14px; white-space: pre;"&gt;&lt;span style="font-family: 'Times New Roman'; font-size: 18px; line-height: normal; white-space: normal;"&gt;There are two problems with this approach is that you leave yourself wide open for a SQL Injection attack. &amp;nbsp;First, you have SQL in the DataSet editor and in the BeforeOpen method, &amp;nbsp;this makes the code more brittle and difficult to maintain. &amp;nbsp;The second is that you leave yourself wide open to a &lt;a href="http://en.wikipedia.org/wiki/SQL_injection"&gt;SQL Injection&lt;/a&gt; attack. &amp;nbsp;(If you don't know, please follow the link). &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;What I wanted to do was figure out a way that I could simplify using multi-select statements that would have some safe guards against a SQL injection attack. &amp;nbsp;The ScriptFunctionExtension is a great way to do just that. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;First, we want to modify our SQL so that the parameters are defined within the SQL. &amp;nbsp;To use my function your SQL will look like this:&lt;/div&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;select status   &lt;br /&gt;from orders&lt;br /&gt;where status in ('MS:pStatus') and&lt;br /&gt;state in ('MS:pState')&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;In this scenario you have two parameters pStatus and pState that are defined in the report parameters. &amp;nbsp;Then you modify the BeforeOpen method of your DataSet to have the following code:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;this.queryText = BlackboardFunctions&lt;br /&gt;            .MultiSelectSql(this.queryText, reportContext);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;That's is all you have to do. &amp;nbsp;All of the SQL modification and checks for injection strings are done for you in the ScriptFunction. &amp;nbsp; Now the caveats: I realize that there are still SQL Injection issues here. &amp;nbsp;I welcome your suggestions on how to reduce the risk. &amp;nbsp;There is a way that this can be done using Java Bind variables, but it is significantly more difficult. &lt;br /&gt;&lt;br /&gt;If you would like to download the full source to the plugin, I have it on my Subversion server &lt;a href="http://longlake.minnovent.com/repos/birt_example/com.innoventsolutions.birt.functions/"&gt;here&lt;/a&gt;. &amp;nbsp;For the curious, the remainder of this article will talk about how it was done. &lt;br /&gt;&lt;br /&gt;First, let's look at the ScriptFunctionFactory. &amp;nbsp;I absolutely hate having to keep code coordinated in more than one place. &amp;nbsp;The ScriptFunction requires that you define the Script in the plugin.xml and in the FunctionFactory. &amp;nbsp;In addition, you will have the actual ScriptFunctionExecutor classes.&lt;br /&gt;&lt;br /&gt;What I did was came up with a simple rule, the name of the Function (in plugin.xml), is the name of the ScriptFunctionExecutor class. &amp;nbsp;This simplifies my FunctionFactory to just use the name passed in to find the appropriate class:&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;    public IScriptFunctionExecutor getFunctionExecutor(String functionName )&lt;br /&gt;        throws BirtException {&lt;br /&gt;        String fullClassName = plugin_id + "." + functionName;&lt;br /&gt;        try {&lt;br /&gt;            Class&amp;lt;? extends IScriptFunctionExecutor&amp;gt; functionClass = Class&lt;br /&gt;                    .forName( fullClassName )&lt;br /&gt;                    .asSubclass( IScriptFunctionExecutor.class );&lt;br /&gt;            IScriptFunctionExecutor scriptFunction = functionClass&lt;br /&gt;                    .newInstance();&lt;br /&gt;            return scriptFunction;&lt;br /&gt;        }&lt;br /&gt;        catch ( Exception e ) {&lt;br /&gt;            e.printStackTrace();&lt;br /&gt;            throw new BirtException( plugin_id, "Unable to find class: "&lt;br /&gt;                                                            + fullClassName,&lt;br /&gt;                                                getResourceBundle(), e );&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Next we need to have the ScriptFunction code that walks through the queryText replacing the messages with the appropriate parameter values&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;public Object execute( Object[] args, IScriptFunctionContext context ) throws BirtException {&lt;br /&gt;    final String sqlText = args[ 0 ].toString();&lt;br /&gt;    IReportContext reportContext = super.getReportContext( args[ 1 ] );&lt;br /&gt;&lt;br /&gt;    // find the Multi-Select replacement string&lt;br /&gt;    List&amp;lt;String&amp;gt; matchList = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;    try {&lt;br /&gt;        Pattern regex = Pattern.compile( "\\('MS:[A-Za-z0-9]+'\\)" );&lt;br /&gt;        Matcher regexMatcher = regex.matcher( sqlText );&lt;br /&gt;        while ( regexMatcher.find() ) {&lt;br /&gt;            matchList.add( regexMatcher.group() );&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    catch ( PatternSyntaxException ex ) {&lt;br /&gt;        // Syntax error in the regular expression&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    String rtnStr = sqlText;&lt;br /&gt;    // iterate through each multi-select parameter&lt;br /&gt;    // in the sql and replace with appropriate parameter values&lt;br /&gt;    for ( final String matchStr : matchList ) {&lt;br /&gt;        String searchFor = matchStr.substring( 2, matchStr.length() - 2 );&lt;br /&gt;        String paramName = searchFor.substring( 3 );&lt;br /&gt;        Object obj = reportContext.getParameterValue( paramName );&lt;br /&gt;        if ( obj == null )&lt;br /&gt;            removeLine( matchStr, rtnStr );&lt;br /&gt;        if ( obj instanceof Object[] ) {&lt;br /&gt;            StringBuffer sb = new StringBuffer();&lt;br /&gt;            Object[] pVals = (Object[]) obj;&lt;br /&gt;            for ( int i = 0; i &amp;lt; pVals.length; i++ ) {&lt;br /&gt;                super.testSqlInjection( pVals[ i ].toString() );&lt;br /&gt;                sb.append( pVals[ i ].toString() );&lt;br /&gt;                if ( i &amp;lt; pVals.length - 1 ) {&lt;br /&gt;                    sb.append( "', '" );&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;            rtnStr = rtnStr.replaceAll( searchFor, sb.toString() );&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;    return rtnStr;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;There are two sub-functions that are lurking in that text. &amp;nbsp;First, a common task for ScriptFunctions will be getting the ReportContext from the EventHandler, while not difficult, it makes sense to have appropriate error handling and testing, so I put that in an abstract super class. &lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;protected IReportContext getReportContext( final Object rcArgument )&lt;br /&gt;    throws BirtException {&lt;br /&gt;    if ( rcArgument == null ) {&lt;br /&gt;        throw new BirtException( InnoventFunctionFactory.plugin_id,&lt;br /&gt;                                            "ReportContext object is null in "&lt;br /&gt;                                                    + this.getClass()&lt;br /&gt;                                                            .getSimpleName(),&lt;br /&gt;                                            InnoventFunctionFactory&lt;br /&gt;                                                    .getResourceBundle() );&lt;br /&gt;    }&lt;br /&gt;    if ( ( rcArgument instanceof IReportContext ) != true ) {&lt;br /&gt;        throw new BirtException( InnoventFunctionFactory.plugin_id,&lt;br /&gt;                                            "ReportCtxt is not instance of IReportContext in "&lt;br /&gt;                                                    + this.getClass()&lt;br /&gt;                                                            .getSimpleName(),&lt;br /&gt;                                            InnoventFunctionFactory&lt;br /&gt;                                                    .getResourceBundle() );&lt;br /&gt;    }&lt;br /&gt;    return (IReportContext) rcArgument;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Not completely tricky, but who wants to write that code over and over again?&lt;br /&gt;&lt;br /&gt;The other statement is the call to test for likely SQL Injection tokens. &amp;nbsp;I know the list is not complete, but what do you expect when you have free advice. &lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"&gt;&lt;code&gt;    protected void testSqlInjection( String paramValue )&lt;br /&gt;        throws BirtException {&lt;br /&gt;        List&amp;lt;String&amp;gt; errList = new ArrayList&amp;lt;String&amp;gt;();&lt;br /&gt;        try {&lt;br /&gt;            Pattern regex = Pattern.compile( "[%]|[']|[;]|[(]|[)]|[=]" );&lt;br /&gt;            Matcher regexMatcher = regex.matcher( paramValue );&lt;br /&gt;            while ( regexMatcher.find() ) {&lt;br /&gt;                errList.add( regexMatcher.group() );&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        catch ( PatternSyntaxException ex ) {&lt;br /&gt;            // Syntax error in the regular expression&lt;br /&gt;        }&lt;br /&gt;        if ( errList == null || errList.size() == 0 ) {&lt;br /&gt;            return;&lt;br /&gt;        }&lt;br /&gt;        // Uh oh, something is fishy in this parameter&lt;br /&gt;        StringBuffer sb = new StringBuffer();&lt;br /&gt;        sb.append( "Failure to add parameter value :\n" );&lt;br /&gt;        sb.append( paramValue );&lt;br /&gt;        sb&lt;br /&gt;                .append( "The following values are not allowed in parameters \n{ " );&lt;br /&gt;        for ( String err : errList ) {&lt;br /&gt;            sb.append( err );&lt;br /&gt;            sb.append( " " );&lt;br /&gt;        }&lt;br /&gt;        sb.append( " }" );&lt;br /&gt;        throw new BirtException( InnoventFunctionFactory.plugin_id, sb&lt;br /&gt;                .toString(), InnoventFunctionFactory.getResourceBundle() );&lt;br /&gt;    }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Well that is about it. &amp;nbsp;It is probably a lot easier to just download the code and have a look. &lt;br /&gt;&lt;br /&gt;I hope to see you all at EclipseCon in two weeks. &amp;nbsp;We have a &lt;a href="http://www.eclipsecon.org/2009/sessions?category=Frameworks%20-%20Reporting"&gt;number&lt;/a&gt; of really great tal
