BIRT - RCP and memory allocation [message #368143] |
Wed, 06 May 2009 10:33 |
Jan Pannecoeck Messages: 21 Registered: July 2009 |
Junior Member |
|
|
Hi all,
I'm using BIRT Chart Engine in an RCP Application to draw multiple
charts (each chart has its own View and own devRenderer). Now I have
some issues with the memory allocation and used Sleak to monitor the SWT
graphics resources.
I found out that each time I redraw a chart, a new Font object is
created and even if I dispose the devRenderer, this Font object isn't
released. I'll put some code here so maybe I'm doing something wrong...
Creating the chart:
> private void createChart(){
> chart = ChartWithAxesImpl.create();
> chart.getBlock().setBackground(ColorDefinitionImpl.WHITE());
> Plot chartPlot = chart.getPlot();
> chartPlot.setBackground(ColorDefinitionImpl.WHITE());
> chartPlot.getClientArea().setBackground(ColorDefinitionImpl. WHITE());
> chart.getTitle().getLabel().getCaption().setValue("Title");
> chart.getTitle().setVisible(false);
> Legend lg = chart.getLegend();
> lg.setVisible(true);
> lg.setPosition(Position.BELOW_LITERAL);
> lg.setOrientation(Orientation.HORIZONTAL_LITERAL);
>
> AxisImpl xAxis = (AxisImpl) chart.getPrimaryBaseAxes()[0];
> xAxis.setType(AxisType.DATE_TIME_LITERAL);
> xAxis.setFormatSpecifier(JavaDateFormatSpecifierImpl.create( "YYYY/MM/dd HH:mm"));
> xAxis.getScale().setUnit(ScaleUnitType.MINUTES_LITERAL);
> xAxis.getMajorGrid().setTickStyle(TickStyle.BELOW_LITERAL);
> xAxis.getOrigin().setType(IntersectionType.VALUE_LITERAL);
> xAxis.getTitle().setVisible(false);
> xAxis.getLabel().getCaption().getFont().setSize(8);
> AxisImpl yAxis = (AxisImpl) chart.getPrimaryOrthogonalAxis(xAxis);
> yAxis.getMajorGrid().setTickStyle(TickStyle.LEFT_LITERAL);
> yAxis.getMinorGrid().setTickStyle(TickStyle.LEFT_LITERAL);
> yAxis.getLabel().setVisible(true);
> yAxis.getLabel().getCaption().getFont().setSize(8);
> yAxis.setFormatSpecifier(JavaNumberFormatSpecifierImpl.creat e( "00.00"));
>
> yAxis.getMajorGrid().getLineAttributes().setVisible(true);
> yAxis.getMajorGrid().getLineAttributes().setColor(ColorDefin itionImpl.GREY());
> yAxis.getMajorGrid().getLineAttributes().setStyle(LineStyle. DASHED_LITERAL);
> yAxis.getMajorGrid().setTickStyle(TickStyle.LEFT_LITERAL);
> yAxis.setType(AxisType.LINEAR_LITERAL);
> }
Redrawing the chart each time I have new data:
> // Generate X and Y values
> // X-value: dates
> // y-values: measurement
> com.ibm.icu.util.Calendar[] dates = new com.ibm.icu.util.Calendar[xSerie.size()];
> dates = xSerie.toArray(dates);
> DateTimeDataSet xAxisValues = DateTimeDataSetImpl.create(dates);
>
> Series xCategory = SeriesImpl.create();
> xCategory.setDataSet(xAxisValues);
> xCategory.setStacked(false);
>
> SeriesDefinition sdX = SeriesDefinitionImpl.create();
> sdX.getSeriesPalette().shift(0);
> sdX.getSeries().add(xCategory);
>
> SeriesDefinition sdY = SeriesDefinitionImpl.create();
> Palette colorPalette = sdY.getSeriesPalette();
> colorPalette.shift(0);
>
> AxisImpl xAxis = (AxisImpl) chart.getPrimaryBaseAxes()[0];
> xAxis.getSeriesDefinitions().clear();
> xAxis.getSeriesDefinitions().add(sdX);>
>
> AxisImpl yAxis = (AxisImpl) chart.getPrimaryOrthogonalAxis(xAxis);
> yAxis.getSeriesDefinitions().clear();
> yAxis.getSeriesDefinitions().add(sdY);
>
int[] counters = new int[xSeries.size()];
> for(int i = 0; i < counters.length;i++)
> counters[i] = 0;
> Double[][] ySeriesValues = new Double[ySeries.size()][xSerie.size()];
> // X and Y axis should both have the same amount of items
> // Each Y-serie should have same amount of items
> // item in Y-serie can be NULL
> for(int h = 0; h < xSerie.size(); h++){
> com.ibm.icu.util.Calendar date = xSerie.get(h);
> for(int i = 0; i < xSeries.size(); i++){
> int counterIndex = counters[i];
> if(counterIndex < xSeries.get(i).length){
> com.ibm.icu.util.Calendar current = xSeries.get(i)[counterIndex];
> if(current.equals(date)){
> if(counterIndex < ySeries.get(i).length){
> ySeriesValues[i][h] = ySeries.get(i)[counterIndex];
> counters[i]++;
> }
> break;
> }
> }
> }
> }
> for(int h = 0; h < ySeriesValues.length; h++){
> NumberDataSet yAxisValues = NumberDataSetImpl.create(ySeriesValues[h]);
> LineSeries yCategory =(LineSeries) LineSeriesImpl.create();
> yCategory.setDataSet(yAxisValues);
> yCategory.setStacked(false);
> ITideStation station = (ITideStation)mapYSerieTideStation.get(h);
> yCategory.setSeriesIdentifier(station.getProjectName() + " - " + station.getName());
> for(Object marker : yCategory.getMarkers()){
> if(marker instanceof Marker){
> Marker m = (Marker) marker;
> m.setType(MarkerType.CIRCLE_LITERAL);
> m.setSize(2);
> }
> }
> yCategory.setPaletteLineColor(true);
> // Add trigger
> yCategory.getTriggers().add(TriggerImpl.create(
> TriggerCondition.ONMOUSEOVER_LITERAL, ActionImpl.create(
> ActionType.SHOW_TOOLTIP_LITERAL, TooltipValueImpl.create(500, null))));
>
> sdY.getSeries().add(yCategory);
> }
And drawing the chart to an image:
> private void drawChartToCachedImage(final PaintEvent e) {
> Rectangle d = canvas.getClientArea();
> if(cachedImage != null)
> cachedImage.dispose();
>
> cachedImage = new Image(canvas.getDisplay(), d);
> GC gcImage = new GC(cachedImage);
> devRenderer.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, gcImage);
> final Bounds bo = BoundsImpl.create(0,0, d.width, d.height);
> bo.scale(72d/devRenderer.getDisplayServer().getDpiResolution ());
>
> Generator gr = Generator.instance();
>
> try{
> Thread drawChartThread = new Thread(){
> public void run(){
> try {
> drawChart();
> } catch (ChartException ex) {
> createChart();
> try {
> drawChart();
> } catch (ChartException e) {
>
> }
> }
> }
>
> private void drawChart() throws ChartException {
> Generator gr = Generator.instance();
> state = gr.build(devRenderer.getDisplayServer(), chart, bo, null, null, null);
> state.getRunTimeContext().setActionRenderer(new ToolTipActionRenderer());
> gr.render(devRenderer, state);
> }
> };
> drawChartThread.start();
> while(drawChartThread != null && drawChartThread.isAlive()){
> Thread.sleep(100);
> }
> GC gc = e.gc;
> gc.drawImage(cachedImage, d.x, d.y);
> gc.dispose();
> } catch (InterruptedException ex) {
> // TODO Auto-generated catch block
> ex.printStackTrace();
> }
> finally{
> if(gcImage != null)
> gcImage.dispose();
> }
> }
I hope this is somehow clear to someone who has any idea what the
problam could be!!
Thanks in advance!!
Jan Pannecoeck
|
|
|
Re: BIRT - RCP and memory allocation [message #368145 is a reply to message #368143] |
Wed, 06 May 2009 12:02 |
Jan Pannecoeck Messages: 21 Registered: July 2009 |
Junior Member |
|
|
Seems this problem is fixed in releases after 2.3.1 (the one I'm using)
So I'm going to try to upgrate now to 2.3.2 and see if that solves my
problem...
Jan
Jan Pannecoeck wrote:
> Hi all,
>
> I'm using BIRT Chart Engine in an RCP Application to draw multiple
> charts (each chart has its own View and own devRenderer). Now I have
> some issues with the memory allocation and used Sleak to monitor the SWT
> graphics resources.
>
> I found out that each time I redraw a chart, a new Font object is
> created and even if I dispose the devRenderer, this Font object isn't
> released. I'll put some code here so maybe I'm doing something wrong...
>
> Creating the chart:
>
>> private void createChart(){
>> chart = ChartWithAxesImpl.create();
>> chart.getBlock().setBackground(ColorDefinitionImpl.WHITE());
>> Plot chartPlot = chart.getPlot();
>> chartPlot.setBackground(ColorDefinitionImpl.WHITE());
>>
>> chartPlot.getClientArea().setBackground(ColorDefinitionImpl. WHITE());
>> chart.getTitle().getLabel().getCaption().setValue("Title");
>> chart.getTitle().setVisible(false);
>> Legend lg = chart.getLegend();
>> lg.setVisible(true);
>> lg.setPosition(Position.BELOW_LITERAL);
>> lg.setOrientation(Orientation.HORIZONTAL_LITERAL);
>>
>> AxisImpl xAxis = (AxisImpl) chart.getPrimaryBaseAxes()[0];
>> xAxis.setType(AxisType.DATE_TIME_LITERAL);
>>
>> xAxis.setFormatSpecifier(JavaDateFormatSpecifierImpl.create( "YYYY/MM/dd
>> HH:mm"));
>> xAxis.getScale().setUnit(ScaleUnitType.MINUTES_LITERAL);
>> xAxis.getMajorGrid().setTickStyle(TickStyle.BELOW_LITERAL);
>> xAxis.getOrigin().setType(IntersectionType.VALUE_LITERAL);
>> xAxis.getTitle().setVisible(false);
>> xAxis.getLabel().getCaption().getFont().setSize(8);
>> AxisImpl yAxis = (AxisImpl)
>> chart.getPrimaryOrthogonalAxis(xAxis);
>> yAxis.getMajorGrid().setTickStyle(TickStyle.LEFT_LITERAL);
>> yAxis.getMinorGrid().setTickStyle(TickStyle.LEFT_LITERAL);
>> yAxis.getLabel().setVisible(true);
>> yAxis.getLabel().getCaption().getFont().setSize(8);
>>
>> yAxis.setFormatSpecifier(JavaNumberFormatSpecifierImpl.creat e( "00.00"));
>>
>> yAxis.getMajorGrid().getLineAttributes().setVisible(true);
>>
>> yAxis.getMajorGrid().getLineAttributes().setColor(ColorDefin itionImpl.GREY());
>>
>>
>> yAxis.getMajorGrid().getLineAttributes().setStyle(LineStyle. DASHED_LITERAL);
>>
>> yAxis.getMajorGrid().setTickStyle(TickStyle.LEFT_LITERAL);
>> yAxis.setType(AxisType.LINEAR_LITERAL);
>> }
>
> Redrawing the chart each time I have new data:
>
>> // Generate X and Y values
>> // X-value: dates
>> // y-values: measurement
>> com.ibm.icu.util.Calendar[] dates = new
>> com.ibm.icu.util.Calendar[xSerie.size()];
>> dates = xSerie.toArray(dates);
>> DateTimeDataSet xAxisValues = DateTimeDataSetImpl.create(dates);
>>
>> Series xCategory = SeriesImpl.create();
>> xCategory.setDataSet(xAxisValues);
>> xCategory.setStacked(false);
>>
>> SeriesDefinition sdX = SeriesDefinitionImpl.create();
>> sdX.getSeriesPalette().shift(0);
>> sdX.getSeries().add(xCategory);
>>
>> SeriesDefinition sdY = SeriesDefinitionImpl.create();
>> Palette colorPalette = sdY.getSeriesPalette();
>> colorPalette.shift(0);
>>
>> AxisImpl xAxis = (AxisImpl) chart.getPrimaryBaseAxes()[0];
>> xAxis.getSeriesDefinitions().clear();
>> xAxis.getSeriesDefinitions().add(sdX);>
>>
>> AxisImpl yAxis = (AxisImpl)
>> chart.getPrimaryOrthogonalAxis(xAxis);
>> yAxis.getSeriesDefinitions().clear();
>> yAxis.getSeriesDefinitions().add(sdY);
>>
> int[] counters = new int[xSeries.size()];
>> for(int i = 0; i < counters.length;i++)
>> counters[i] = 0;
>> Double[][] ySeriesValues = new
>> Double[ySeries.size()][xSerie.size()];
>> // X and Y axis should both have the same amount of items
>> // Each Y-serie should have same amount of items
>> // item in Y-serie can be NULL
>> for(int h = 0; h < xSerie.size(); h++){
>> com.ibm.icu.util.Calendar date = xSerie.get(h);
>> for(int i = 0; i < xSeries.size(); i++){
>> int counterIndex = counters[i];
>> if(counterIndex < xSeries.get(i).length){
>> com.ibm.icu.util.Calendar current =
>> xSeries.get(i)[counterIndex];
>> if(current.equals(date)){
>> if(counterIndex < ySeries.get(i).length){
>> ySeriesValues[i][h] =
>> ySeries.get(i)[counterIndex];
>> counters[i]++;
>> }
>> break;
>> }
>> }
>> }
>> }
>
>> for(int h = 0; h < ySeriesValues.length; h++){
>> NumberDataSet yAxisValues =
>> NumberDataSetImpl.create(ySeriesValues[h]);
>> LineSeries yCategory =(LineSeries) LineSeriesImpl.create();
>> yCategory.setDataSet(yAxisValues);
>> yCategory.setStacked(false);
>> ITideStation station =
>> (ITideStation)mapYSerieTideStation.get(h);
>> yCategory.setSeriesIdentifier(station.getProjectName() + "
>> - " + station.getName());
>> for(Object marker : yCategory.getMarkers()){
>> if(marker instanceof Marker){
>> Marker m = (Marker) marker;
>> m.setType(MarkerType.CIRCLE_LITERAL);
>> m.setSize(2);
>> }
>> }
>> yCategory.setPaletteLineColor(true);
>> // Add trigger
>> yCategory.getTriggers().add(TriggerImpl.create(
>> TriggerCondition.ONMOUSEOVER_LITERAL,
>> ActionImpl.create(
>> ActionType.SHOW_TOOLTIP_LITERAL,
>> TooltipValueImpl.create(500, null))));
>>
>> sdY.getSeries().add(yCategory);
>> }
>
> And drawing the chart to an image:
>
>> private void drawChartToCachedImage(final PaintEvent e) {
>> Rectangle d = canvas.getClientArea();
>> if(cachedImage != null)
>> cachedImage.dispose();
>>
>> cachedImage = new Image(canvas.getDisplay(), d);
>> GC gcImage = new GC(cachedImage);
>> devRenderer.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT,
>> gcImage);
>> final Bounds bo = BoundsImpl.create(0,0, d.width, d.height);
>> bo.scale(72d/devRenderer.getDisplayServer().getDpiResolution ());
>>
>> Generator gr = Generator.instance();
>>
>> try{
>> Thread drawChartThread = new Thread(){
>> public void run(){
>> try {
>> drawChart();
>> } catch (ChartException ex) {
>> createChart();
>> try {
>> drawChart();
>> } catch (ChartException e) {
>>
>> }
>> }
>> }
>>
>> private void drawChart() throws ChartException {
>> Generator gr = Generator.instance();
>> state = gr.build(devRenderer.getDisplayServer(),
>> chart, bo, null, null, null);
>> state.getRunTimeContext().setActionRenderer(new
>> ToolTipActionRenderer());
>> gr.render(devRenderer, state);
>> }
>> };
>> drawChartThread.start();
>> while(drawChartThread != null && drawChartThread.isAlive()){
>> Thread.sleep(100);
>> }
>> GC gc = e.gc;
>> gc.drawImage(cachedImage, d.x, d.y);
>> gc.dispose();
>> } catch (InterruptedException ex) {
>> // TODO Auto-generated catch block
>> ex.printStackTrace();
>> }
>> finally{
>> if(gcImage != null)
>> gcImage.dispose();
>> }
>> }
>
> I hope this is somehow clear to someone who has any idea what the
> problam could be!!
>
> Thanks in advance!!
>
> Jan Pannecoeck
|
|
|
Powered by
FUDForum. Page generated in 0.03659 seconds