Discussions
Categories
Groups
Community Home
Categories
INTERNAL ENABLEMENT
POPULAR
THRUST SERVICES & TOOLS
CLOUD EDITIONS
Quick Links
MY LINKS
HELPFUL TIPS
Back to website
Home
Intelligence (Analytics)
JSP, JSF, Facelets and Chart Engine API
cgswtsu78
Hello,
I've looked over this forum, imported some of the examples and I've yet to find a working use of a jsp page that dynamically loads a chart. Can anyone help point me in the direction of a full tutorial?
I'm looking at both dynamically creating a chart using the chart engine api and then loading than into a web page. At first I will try JPS then move onto JSF/Facelets. I know several topics have pointed towards using a servlet to load the chart as an image, but each time I download an example there are runtime issues with the servlet and or servlet config.
any help would be greatly appreciated!
Thanks,
Colin
Find more posts tagged with
Comments
JasonW
I just ran this and it worked fine:
package org.eclipse.chart.birt.servlet.example;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.eclipse.birt.chart.api.ChartEngine;
import org.eclipse.birt.chart.device.IDeviceRenderer;
import org.eclipse.birt.chart.exception.ChartException;
import org.eclipse.birt.chart.factory.GeneratedChartState;
import org.eclipse.birt.chart.factory.Generator;
import org.eclipse.birt.chart.factory.IGenerator;
import org.eclipse.birt.chart.factory.RunTimeContext;
import org.eclipse.birt.chart.model.Chart;
import org.eclipse.birt.chart.model.ChartWithAxes;
import org.eclipse.birt.chart.model.attribute.ActionType;
import org.eclipse.birt.chart.model.attribute.AxisType;
import org.eclipse.birt.chart.model.attribute.Bounds;
import org.eclipse.birt.chart.model.attribute.IntersectionType;
import org.eclipse.birt.chart.model.attribute.LegendItemType;
import org.eclipse.birt.chart.model.attribute.Position;
import org.eclipse.birt.chart.model.attribute.TickStyle;
import org.eclipse.birt.chart.model.attribute.TriggerCondition;
import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;
import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl;
import org.eclipse.birt.chart.model.attribute.impl.TooltipValueImpl;
import org.eclipse.birt.chart.model.attribute.impl.URLValueImpl;
import org.eclipse.birt.chart.model.component.Axis;
import org.eclipse.birt.chart.model.component.Series;
import org.eclipse.birt.chart.model.component.impl.SeriesImpl;
import org.eclipse.birt.chart.model.data.BaseSampleData;
import org.eclipse.birt.chart.model.data.DataFactory;
import org.eclipse.birt.chart.model.data.NumberDataSet;
import org.eclipse.birt.chart.model.data.OrthogonalSampleData;
import org.eclipse.birt.chart.model.data.SampleData;
import org.eclipse.birt.chart.model.data.SeriesDefinition;
import org.eclipse.birt.chart.model.data.TextDataSet;
import org.eclipse.birt.chart.model.data.Trigger;
import org.eclipse.birt.chart.model.data.impl.ActionImpl;
import org.eclipse.birt.chart.model.data.impl.NumberDataSetImpl;
import org.eclipse.birt.chart.model.data.impl.SeriesDefinitionImpl;
import org.eclipse.birt.chart.model.data.impl.TextDataSetImpl;
import org.eclipse.birt.chart.model.data.impl.TriggerImpl;
import org.eclipse.birt.chart.model.impl.ChartWithAxesImpl;
import org.eclipse.birt.chart.model.layout.Legend;
import org.eclipse.birt.chart.model.layout.Plot;
import org.eclipse.birt.chart.model.type.BarSeries;
import org.eclipse.birt.chart.model.type.impl.BarSeriesImpl;
import org.eclipse.birt.core.framework.PlatformConfig;
import com.ibm.icu.util.ULocale;
public class ChartServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private IDeviceRenderer idr = null;
private ChartEngine ce = null;
private Chart chart = null;
public ChartServlet( )
{
PlatformConfig pf = new PlatformConfig();
pf.setProperty("STANDALONE", true);
ce = ChartEngine.instance( pf);
try
{
idr = ce.getRenderer( "dv.SWING" );//$NON-NLS-1$
}
catch ( ChartException ex )
{
ex.printStackTrace( );
}
}
public void init() throws ServletException {
}
public void destroy() {
super.destroy();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
chart = ChartServlet.createStackedBar();
response.setHeader( "Cache-Control", "no-store" );
response.setDateHeader( "Expires", 0 ); response.setContentType( "image/png" );
try {
createImage((OutputStream) response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
super.doPost(request, response);
}
private void createImage( OutputStream out )
{
// Create a buffered image
BufferedImage image = new BufferedImage( 600,
400,
BufferedImage.TYPE_INT_RGB );
// Draw the chart in the buffered image
Graphics2D g2d = (Graphics2D) image.getGraphics( );
idr.setProperty( IDeviceRenderer.GRAPHICS_CONTEXT, g2d );
Bounds bo = BoundsImpl.create( 0, 0, 600, 400 );
bo.scale( 72d / idr.getDisplayServer( ).getDpiResolution( ) );
IGenerator gr = ce.getGenerator();
try
{
GeneratedChartState gcs =
gr.build( idr.getDisplayServer( ),
chart,
bo,
null,
null,
null );
gr.render( idr, gcs ); // Style processor
}
catch ( ChartException ex )
{
ex.printStackTrace( );
}
g2d.dispose( );
try
{
ImageIO.write( image, "PNG", out );
}
catch ( IOException io )
{
io.printStackTrace( );
}
}
public static final Chart createStackedBar()
{
ChartWithAxes cwaBar = ChartWithAxesImpl.create();
cwaBar.setType("Bar Chart");
cwaBar.setSubType("Stacked");
cwaBar.getBlock().setBackground(ColorDefinitionImpl.WHITE());
cwaBar.getBlock().getOutline().setVisible(true);
Plot p = cwaBar.getPlot();
p.getClientArea().setBackground(ColorDefinitionImpl.create(255,
255,
225));
cwaBar.getTitle()
.getLabel()
.getCaption()
.setValue("Stacked Bar Chart");
Legend lg = cwaBar.getLegend();
lg.setItemType(LegendItemType.CATEGORIES_LITERAL);
cwaBar
.setScript("function beforeGeneration( cm, icsc )"
+ "{importPackage(Packages.org.eclipse.birt.chart.model.attribute); "
+ " importPackage(Packages.org.eclipse.birt.chart.model.attribute.impl); "
+ " cm.getLegend().getOutline( ).setStyle( LineStyle.DASH_DOTTED_LITERAL );"
+ " cm.getLegend().getOutline( ).setColor( ColorDefinitionImpl.GREEN() );"
+ " cm.getLegend().getOutline( ).setVisible( true );} ");
Axis xAxisPrimary = cwaBar.getPrimaryBaseAxes()[0];
xAxisPrimary.setType(AxisType.TEXT_LITERAL);
xAxisPrimary.getMajorGrid().setTickStyle(TickStyle.BELOW_LITERAL);
xAxisPrimary.getOrigin().setType(IntersectionType.MIN_LITERAL);
Axis yAxisPrimary = cwaBar.getPrimaryOrthogonalAxis(xAxisPrimary);
yAxisPrimary.getMajorGrid().setTickStyle(TickStyle.LEFT_LITERAL);
yAxisPrimary.setType(AxisType.LINEAR_LITERAL);
yAxisPrimary.setLabelPosition(Position.RIGHT_LITERAL);
yAxisPrimary.getLabel().getCaption().getFont().setRotation(45);
TextDataSet categoryValues = TextDataSetImpl.create(new String[] {
"Item 1a", "Item 2", "Item 3", "Item 4", "Item 5" });
NumberDataSet orthoValues1 = NumberDataSetImpl.create(new double[] {
25, 35, 15, 5, 20
});
NumberDataSet orthoValues2 = NumberDataSetImpl.create(new double[] {
5, 10, 25, 10, 5
});
SampleData sd = DataFactory.eINSTANCE.createSampleData();
BaseSampleData sdBase = DataFactory.eINSTANCE.createBaseSampleData();
sdBase.setDataSetRepresentation("");
sd.getBaseSampleData().add(sdBase);
OrthogonalSampleData sdOrthogonal1 = DataFactory.eINSTANCE
.createOrthogonalSampleData();
sdOrthogonal1.setDataSetRepresentation("");
sdOrthogonal1.setSeriesDefinitionIndex(0);
sd.getOrthogonalSampleData().add(sdOrthogonal1);
OrthogonalSampleData sdOrthogonal2 = DataFactory.eINSTANCE
.createOrthogonalSampleData();
sdOrthogonal2.setDataSetRepresentation("");
sdOrthogonal2.setSeriesDefinitionIndex(1);
sd.getOrthogonalSampleData().add(sdOrthogonal2);
cwaBar.setSampleData(sd);
Series seCategory = SeriesImpl.create();
seCategory.setDataSet(categoryValues);
SeriesDefinition sdX = SeriesDefinitionImpl.create();
xAxisPrimary.getSeriesDefinitions().add(sdX);
sdX.getSeries().add(seCategory);
sdX.getSeriesPalette().shift(0);
BarSeries bs1 = (BarSeries) BarSeriesImpl.create();
bs1.setDataSet(orthoValues1);
bs1.setStacked(true);
bs1.getLabel().setVisible(true);
bs1.setLabelPosition(Position.INSIDE_LITERAL);
bs1.setRiserOutline(ColorDefinitionImpl.TRANSPARENT());
BarSeries bs2 = (BarSeries) BarSeriesImpl.create();
bs2.setDataSet(orthoValues2);
bs2.setStacked(true);
bs2.setRiserOutline(ColorDefinitionImpl.TRANSPARENT());
bs2.getLabel().setVisible(true);
bs2.setLabelPosition(Position.INSIDE_LITERAL);
Trigger tr1 = TriggerImpl.create(TriggerCondition.ONMOUSEOVER_LITERAL,
ActionImpl.create(ActionType.SHOW_TOOLTIP_LITERAL,
TooltipValueImpl.create(200, "test + dph.getDisplayValue()")));
Trigger tr2 = TriggerImpl.create(TriggerCondition.ONCLICK_LITERAL,
ActionImpl.create(ActionType.URL_REDIRECT_LITERAL, URLValueImpl
.create("
https://www.google.com"
, null, "component",
"value", "")));
bs1.getTriggers().add(tr1);
bs1.getTriggers().add(tr2);
//bs2.getTriggers().add(tr3);
//bs2.getTriggers().add(tr4);
SeriesDefinition sdY = SeriesDefinitionImpl.create();
sdY.getSeriesPalette().shift(0);
yAxisPrimary.getSeriesDefinitions().add(sdY);
sdY.getSeries().add(bs1);
sdY.getSeries().add(bs2);
return cwaBar;
}
}
Jason
cgswtsu78
I've copied the entire servlet and ran it and i just get a black image. One thing I notice in the console is a warning, see below. Can you zip up your project and put it somewhere I can grab it?
Nov 4, 2009 8:10:39 AM org.eclipse.birt.chart.computation.withaxes.AutoScale getPrecision
WARNING: Autoscale precision not found for 1.0
cgswtsu78
Jason,
I'm trying to use the Birt Chart Engine API to dynamically create a pie chart and I'm running into an issue when assigning the NumberDataSet for the chart. I get the below runtime exception when trying to render the chart instance into an image. Other chart types (bar, line, area) all accept a List of BigDecimal values for their NumberDataSet. I can only get the pie chart type to work with an array of double values, why is this?
List<BigDecimal> test = new ArrayList<BigDecimal>();
test.add(new BigDecimal(400));
test.add(new BigDecimal(200));
test.add(new BigDecimal(100));
NumberDataSet seriesOneValues = NumberDataSetImpl.create(test);
Exception:
org.eclipse.birt.chart.exception.ChartException: Unexpected non-numerical data type 400 found in data set; cannot convert to numeric value.
at org.eclipse.birt.chart.computation.withoutaxes.SeriesRenderingHints.asPrimitiveDoubleValues(SeriesRenderingHints.java:136)
at org.eclipse.birt.chart.render.Pie.compute(Pie.java:93)
at org.eclipse.birt.chart.factory.Generator.build(Generator.java:1106)
at com.proofpoint.resources.chartsvcs.impl.DynamicChart.buildChart(DynamicChart.java:65)
at com.proofpoint.resources.chartsvcs.impl.ChartSvcsImpl.getChart(ChartSvcsImpl.java:156)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:136)
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:82)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:109)
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:63)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:56)
at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:92)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:220)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:78)
at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:92)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:285)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:131)
at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:175)
at org.apache.cxf.transport.servlet.AbstractCXFServlet.doGet(AbstractCXFServlet.java:157)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
at java.lang.Thread.run(Unknown Source)
Nov 10, 2009 3:55:42 PM org.apache.cxf.phase.PhaseInterceptorChain doIntercept
INFO: Application has thrown exception, unwinding now: org.eclipse.birt.chart.exception.ChartException: Unexpected non-numerical data type 400 found in data set; cannot convert to numeric value.
JasonW
This appears to be a bug. Can you log a bugzilla entry for it?
A pie chart only handles doubles currently.
cgswtsu78
bug opened, <a class='bbc_url' href='
https://bugs.eclipse.org/bugs/show_bug.cgi?id=294903'>https://bugs.eclipse.org/bugs/show_bug.cgi?id=294903</a>
;
cgswtsu78
Jason,
Is there a maven repository for the Chart Engine API and it's dependencies? Maybe an example maven pom.xml?
Thanks,
Colin
cgswtsu78
Jason,
In your example, are the below statements the only thing needed in order to render a literal and make it clickable or does an image map have to be configured as well? I wasn't able to take the Trigger examples from your dynamic bar graph example and apply them to a pie chart, are there differences in defining roll over literals and clickable pieces of the pie chart?
Trigger tr1 = TriggerImpl.create(TriggerCondition.ONMOUSEOVER_LITERAL,
ActionImpl.create(ActionType.SHOW_TOOLTIP_LITERAL,
TooltipValueImpl.create(200, "test + dph.getDisplayValue()")));
Trigger tr2 = TriggerImpl.create(TriggerCondition.ONCLICK_LITERAL,
ActionImpl.create(ActionType.URL_REDIRECT_LITERAL, URLValueImpl
.create("
https://www.google.com"
, null, "component",
"value", "")));
JasonW
You have to define a map unless you are using svg.
cgswtsu78
Do you have an example of using an SVG to produce a rollover tooltip and that is also defines a clickable area in order to redirect to another graph or url?
JasonW
I dont but you should be able to modify the current example to change the renderer to dv.SVG.
Jason