Home » Archived » BIRT » Can't Refresh Chart rather than Re-Build and Render
Can't Refresh Chart rather than Re-Build and Render [message #538227] |
Sun, 06 June 2010 20:21 |
Mark Leone Messages: 123 Registered: July 2009 |
Senior Member |
|
|
I have a chart rendered in an RCP View that will be refreshed very fast over a period of several seconds, and I want to minimize the flicker effect. I saw in some BIRT documentation found online that I could do a refresh rather than build and render on the Generator. But if I call refresh() on the Generator, I get a SWTException with the message "Graphic is disposed".
I've pasted my code below, adapted from an example I found online. It's a test case that plots a sine wave and changes the period of the wave every 500 msec. The code works, but there is some flicker with each update. If you un-comment the line in paintControl() that sets firstRender to false, it will attempt to refresh rather than build and render after the first paint operation. Then the SWTException I mentioned earlier will be thrown on gr.refresh(state). The exception is thrown in class Generator, when computing the chart; and I can't even find a sufficient guard to avoid calling refresh() when the Exception will be thrown.
public class SampleChartView extends ViewPart {
public static final String ID = "net.midnightjava.charttest.views.SampleChartView";
private static float p = 5;
private static GeneratedChartState state;
private static final class MyPaintListener implements PaintListener
{
boolean firstRender = true;
public void paintControl(PaintEvent e)
{
IDeviceRenderer deviceRenderer = null;
try {
deviceRenderer = PluginSettings.instance().getDevice("dv.SWT");
} catch (ChartException e1) {
e1.printStackTrace();
}
deviceRenderer
.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, e.gc);
Rectangle rect = ((Composite) e.widget).getClientArea();
Bounds bounds = BoundsImpl.create(rect.x + 2,
rect.y + 2,
rect.width - 4,
rect.height - 4);
bounds.scale(72d /
deviceRenderer.getDisplayServer().getDpiResolution());
Chart chart = null;
if (firstRender) {
chart = createSimpleLineChart();
}
Generator gr = Generator.instance();
try
{
if (firstRender) {
state = gr.build(deviceRenderer.getDisplayServer(),
chart,
bounds,
new RunTimeContext());
gr.render(deviceRenderer, state);
} else {
gr.refresh(state);
}
//firstRender = false;
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
private Canvas canvas;
public SampleChartView() {
Job animator = new Job("Animator Job") {
@Override
protected IStatus run(IProgressMonitor monitor) {
if (p == 10) {
p = 5;
} else {
p++;
}
if (!PlatformUI.getWorkbench().getDisplay().isDisposed()) {
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
if (canvas != null && !canvas.isDisposed()) {
canvas.redraw();
}
}
});
}
schedule(500);
return Status.OK_STATUS;
}
};
animator.setSystem(true);
animator.schedule();
}
public void createPartControl(final Composite parent) {
canvas = new Canvas(parent, SWT.NONE);
canvas.addPaintListener(new MyPaintListener());
}
public static final Chart createSimpleLineChart()
{
ChartWithAxes cwaBar = ChartWithAxesImpl.create();
cwaBar.getBlock().setBackground(ColorDefinitionImpl.BLACK());
Plot plot = cwaBar.getPlot();
plot.getOutline().setVisible(false);
cwaBar.getTitle().getLabel().setVisible(false);
Legend lg = cwaBar.getLegend();
LineAttributes lia = lg.getOutline();
lg.getText().getFont().setSize(16);
lia.setStyle(LineStyle.SOLID_LITERAL);
lg.getInsets().set(10, 5, 0, 0);
lg.getOutline().setVisible(false);
lg.setAnchor(Anchor.NORTH_LITERAL);
lg.setVisible(false);
AxisImpl xAxisPrimary = (AxisImpl) cwaBar.getPrimaryBaseAxes()[0];
xAxisPrimary.setType(AxisType.LINEAR_LITERAL);
xAxisPrimary.getMajorGrid().getTickAttributes().setVisible(false);
xAxisPrimary.getOrigin().setType(IntersectionType.MIN_LITERAL);
xAxisPrimary.getTitle().setVisible(false);
xAxisPrimary.getLabel().setVisible(false);
xAxisPrimary.getLineAttributes().setVisible(false);
AxisImpl yAxisPrimary = (AxisImpl) cwaBar.getPrimaryOrthogonalAxis(xAxisPrimary);
yAxisPrimary.getMajorGrid().getTickAttributes().setVisible(false);
yAxisPrimary.getTitle().setVisible(false);
yAxisPrimary.setPercent(false);
yAxisPrimary.getLabel().setVisible(false);
yAxisPrimary.getLineAttributes().setVisible(false);
Vector<Integer> vs = new Vector<Integer>();
for (int i = 1; i <= 512; i++) {
vs.add(i);
}
ArrayList<Double> vn1 = new ArrayList<Double>();
for (float i = 1; i <= 512; i++) {
vn1.add(40 * Math.sin(i / p) + 40);
}
NumberDataSet categoryValues = NumberDataSetImpl.create(vs);
NumberDataSet orthoValues1 = NumberDataSetImpl.create(vn1);
Series seCategory = SeriesImpl.create();
seCategory.setDataSet(categoryValues);
seCategory.setVisible(false);
LineSeries ls = (LineSeries) LineSeriesImpl.create();
ls.setDataSet(orthoValues1);
ls.getLineAttributes().setColor(ColorDefinitionImpl.GREEN());
ls.getMarkers().get(0).setVisible(false);
SeriesDefinition sdX = SeriesDefinitionImpl.create();
sdX.getSeriesPalette().shift(0);
xAxisPrimary.getSeriesDefinitions().add(sdX);
SeriesDefinition sdY = SeriesDefinitionImpl.create();
sdY.getSeriesPalette().shift(0);
yAxisPrimary.getSeriesDefinitions().add(sdY);
sdX.getSeries().add(seCategory);
sdY.getSeries().add(ls);
return cwaBar;
}
@Override
public void setFocus() {
// TODO Auto-generated method stub
}
}
|
|
|
Re: Can't Refresh Chart rather than Re-Build and Render [message #538728 is a reply to message #538227] |
Tue, 08 June 2010 13:44 |
|
Mark,
Have you looked at the SWTChartViewer Example? You need to call build
every time. I am attaching the example.
Jason
/*********************************************************** ************
* Copyright (c) 2004, 2007 Actuate Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Actuate Corporation - initial API and implementation
************************************************************ ***********/
package org.eclipse.birt.chart.examples.api.viewer;
import org.eclipse.birt.chart.api.ChartEngine;
import org.eclipse.birt.chart.device.IDeviceRenderer;
import org.eclipse.birt.chart.examples.api.script.JavaScriptViewer;
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.log.ILogger;
import org.eclipse.birt.chart.log.Logger;
import org.eclipse.birt.chart.model.Chart;
import org.eclipse.birt.chart.model.ChartWithAxes;
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.LineAttributes;
import org.eclipse.birt.chart.model.attribute.LineStyle;
import org.eclipse.birt.chart.model.attribute.Marker;
import org.eclipse.birt.chart.model.attribute.MarkerType;
import org.eclipse.birt.chart.model.attribute.Position;
import org.eclipse.birt.chart.model.attribute.RiserType;
import org.eclipse.birt.chart.model.attribute.TickStyle;
import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;
import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionI mpl;
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.NumberDataSet;
import org.eclipse.birt.chart.model.data.SeriesDefinition;
import org.eclipse.birt.chart.model.data.TextDataSet;
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.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.LineSeries;
import org.eclipse.birt.chart.model.type.impl.BarSeriesImpl;
import org.eclipse.birt.chart.model.type.impl.LineSeriesImpl;
import org.eclipse.birt.core.framework.PlatformConfig;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class SwtLiveChartViewer extends Composite implements PaintListener
{
private IDeviceRenderer idr = null;
private Chart cm = null;
private GeneratedChartState gcs = null;
private static SwtLiveChartViewer c3dViewer;
/**
* Used in building the chart for the first time
*/
private boolean bFirstPaint = true;
private static ILogger logger = Logger.getLogger(
JavaScriptViewer.class.getName( ) );
/**
* execute application
*
* @param args
*/
public static void main( String[] args )
{
Display display = Display.getDefault( );
Shell shell = new Shell( display, SWT.CLOSE );
shell.setSize( 600, 400 );
shell.setLayout( new GridLayout( ) );
c3dViewer = new SwtLiveChartViewer( shell, SWT.NO_BACKGROUND );
c3dViewer.setLayoutData( new GridData( GridData.FILL_BOTH ) );
c3dViewer.addPaintListener( c3dViewer );
shell.open( );
while ( !shell.isDisposed( ) )
{
if ( !display.readAndDispatch( ) )
display.sleep( );
}
display.dispose( );
}
/**
* Constructor
*/
SwtLiveChartViewer( Composite parent, int style )
{
super( parent, style );
try
{
PlatformConfig config = new PlatformConfig( );
config.setProperty( "STANDALONE", "true" ); //$NON-NLS-1$ //$NON-NLS-2$
idr = ChartEngine.instance( config ).getRenderer( "dv.SWT"
);//$NON-NLS-1$
}
catch ( ChartException pex )
{
logger.log( pex );
}
cm = createLiveChart( );
}
public static final Chart createLiveChart( )
{
ChartWithAxes cwaBar = ChartWithAxesImpl.create( );
// Plot
cwaBar.getBlock( ).setBackground( ColorDefinitionImpl.WHITE( ) );
Plot p = cwaBar.getPlot( );
p.getClientArea( ).setBackground( ColorDefinitionImpl.create( 255,
255,
225 ) );
// Legend
Legend lg = cwaBar.getLegend( );
LineAttributes lia = lg.getOutline( );
lg.getText( ).getFont( ).setSize( 16 );
lia.setStyle( LineStyle.SOLID_LITERAL );
lg.getInsets( ).setLeft( 10 );
lg.getInsets( ).setRight( 10 );
// Title
cwaBar.getTitle( )
.getLabel( )
.getCaption( )
.setValue( "Live Chart Demo" );//$NON-NLS-1$
// X-Axis
Axis xAxisPrimary = cwaBar.getPrimaryBaseAxes( )[0];
xAxisPrimary.setType( AxisType.TEXT_LITERAL );
xAxisPrimary.getOrigin( ).setType( IntersectionType.VALUE_LITERAL );
xAxisPrimary.getOrigin( ).setType( IntersectionType.MIN_LITERAL );
xAxisPrimary.getTitle( )
.getCaption( )
.setValue( "Category Text X-Axis" );//$NON-NLS-1$
xAxisPrimary.setTitlePosition( Position.BELOW_LITERAL );
xAxisPrimary.getLabel( ).getCaption( ).getFont( ).setRotation( 75 );
xAxisPrimary.setLabelPosition( Position.BELOW_LITERAL );
xAxisPrimary.getMajorGrid( ).setTickStyle( TickStyle.BELOW_LITERAL );
xAxisPrimary.getMajorGrid( )
.getLineAttributes( )
.setStyle( LineStyle.DOTTED_LITERAL );
xAxisPrimary.getMajorGrid( )
.getLineAttributes( )
.setColor( ColorDefinitionImpl.create( 64, 64, 64 ) );
xAxisPrimary.getMajorGrid( ).getLineAttributes( ).setVisible( true );
// Y-Axis
Axis yAxisPrimary = cwaBar.getPrimaryOrthogonalAxis( xAxisPrimary );
yAxisPrimary.getLabel( ).getCaption( ).setValue( "Price Axis"
);//$NON-NLS-1$
yAxisPrimary.getLabel( ).getCaption( ).getFont( ).setRotation( 37 );
yAxisPrimary.setLabelPosition( Position.LEFT_LITERAL );
yAxisPrimary.setTitlePosition( Position.LEFT_LITERAL );
yAxisPrimary.getTitle( ).getCaption( ).setValue( "Linear Value Y-Axis"
);//$NON-NLS-1$
yAxisPrimary.setType( AxisType.LINEAR_LITERAL );
yAxisPrimary.getMajorGrid( ).setTickStyle( TickStyle.LEFT_LITERAL );
yAxisPrimary.getMajorGrid( )
.getLineAttributes( )
.setStyle( LineStyle.DOTTED_LITERAL );
yAxisPrimary.getMajorGrid( )
.getLineAttributes( )
.setColor( ColorDefinitionImpl.RED( ) );
yAxisPrimary.getMajorGrid( ).getLineAttributes( ).setVisible( true );
// X-Series
Series seCategory = SeriesImpl.create( );
SeriesDefinition sdX = SeriesDefinitionImpl.create( );
xAxisPrimary.getSeriesDefinitions( ).add( sdX );
sdX.getSeries( ).add( seCategory );
// Y-Series (1)
BarSeries bs1 = (BarSeries) BarSeriesImpl.create( );
bs1.setSeriesIdentifier( "Unit Price" );//$NON-NLS-1$
bs1.setRiserOutline( null );
bs1.setRiser( RiserType.RECTANGLE_LITERAL );
// Y-Series (2)
LineSeries ls1 = (LineSeries) LineSeriesImpl.create( );
ls1.setSeriesIdentifier( "Quantity" );//$NON-NLS-1$
ls1.getLineAttributes( ).setColor( ColorDefinitionImpl.GREEN( ) );
for ( int i = 0; i < ls1.getMarkers( ).size( ); i++ )
{
( (Marker) ls1.getMarkers( ).get( i ) ).setType(
MarkerType.BOX_LITERAL );
}
ls1.setCurve( true );
SeriesDefinition sdY = SeriesDefinitionImpl.create( );
yAxisPrimary.getSeriesDefinitions( ).add( sdY );
sdY.getSeriesPalette( ).shift( -1 );
sdY.getSeries( ).add( bs1 );
sdY.getSeries( ).add( ls1 );
// Update data
updateDataSet( cwaBar );
return cwaBar;
}
static final void updateDataSet( ChartWithAxes cwaBar )
{
// Associate with Data Set
TextDataSet categoryValues = TextDataSetImpl.create( sa );
NumberDataSet seriesOneValues = NumberDataSetImpl.create( da1 );
NumberDataSet seriesTwoValues = NumberDataSetImpl.create( da2 );
// X-Axis
Axis xAxisPrimary = cwaBar.getPrimaryBaseAxes( )[0];
SeriesDefinition sdX = (SeriesDefinition)
xAxisPrimary.getSeriesDefinitions( )
.get( 0 );
( (Series) sdX.getSeries( ).get( 0 ) ).setDataSet( categoryValues );
// Y-Axis
Axis yAxisPrimary = cwaBar.getPrimaryOrthogonalAxis( xAxisPrimary );
SeriesDefinition sdY = (SeriesDefinition)
yAxisPrimary.getSeriesDefinitions( )
.get( 0 );
( (Series) sdY.getSeries( ).get( 0 ) ).setDataSet( seriesOneValues );
( (Series) sdY.getSeries( ).get( 1 ) ).setDataSet( seriesTwoValues );
}
// Live Date Set
private static final String[] sa = {
"One", "Two", "Three", "Four",
"Five" ,//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON- NLS-5$
"Six", "Seven", "Eight", "Nine",
"Ten" };//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON -NLS-5$
private static final double[] da1 = {
56.99,
352.95,
-201.95,
299.95,
-95.95,
25.45,
129.33,
-26.5,
43.5,
122
};
private static final double[] da2 = {
20, 35, 59, 105, 150, -37, -65, -99, -145, -185
};
private Image imgChart;
private GC gcImage;
private Bounds bo;
static final void scrollData( ChartWithAxes cwa )
{
// Scroll the bar (Y) series
double dTemp = da1[0];
for ( int i = 0; i < da1.length - 1; i++ )
{
da1[i] = da1[i + 1];
}
da1[da1.length - 1] = dTemp;
// Scroll the line (Y) series
dTemp = da2[0];
for ( int i = 0; i < da2.length - 1; i++ )
{
da2[i] = da2[i + 1];
}
da2[da2.length - 1] = dTemp;
// Scroll X series
String sTemp = sa[0];
for ( int i = 0; i < sa.length - 1; i++ )
{
sa[i] = sa[i + 1];
}
sa[sa.length - 1] = sTemp;
updateDataSet( cwa );
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.swt.events.PaintListener#paintControl(org.eclips e.swt.events
* .PaintEvent)
*/
public final void paintControl( PaintEvent e )
{
Rectangle d = this.getClientArea( );
if ( bFirstPaint )
{
imgChart = new Image( this.getDisplay( ), d );
gcImage = new GC( imgChart );
idr.setProperty( IDeviceRenderer.GRAPHICS_CONTEXT, gcImage );
bo = BoundsImpl.create( 0, 0, d.width, d.height );
bo.scale( 72d / idr.getDisplayServer( ).getDpiResolution( ) );
}
Generator gr = Generator.instance( );
try
{
gcs = gr.build( idr.getDisplayServer( ), cm, bo, null, null, null );
gr.render( idr, gcs );
GC gc = e.gc;
gc.drawImage( imgChart, d.x, d.y );
}
catch ( ChartException ce )
{
ce.printStackTrace( );
}
bFirstPaint = false;
Display.getDefault( ).timerExec( 100, new Runnable( ) {
public void run( )
{
chartRefresh( );
}
} );
}
/*
* (non-Javadoc)
*
* @see
*
org.eclipse.swt.events.SelectionListener#widgetDefaultSelect ed(org.eclipse
* .swt.events.SelectionEvent)
*/
private void chartRefresh( )
{
if ( !isDisposed( ) )
{
final Generator gr = Generator.instance( );
scrollData( (ChartWithAxes) cm );
// Refresh
try
{
gr.refresh( gcs );
}
catch ( ChartException ex )
{
ex.printStackTrace( );
}
redraw( );
}
}
}
On 6/6/2010 4:21 PM, Mark Leone wrote:
> I have a chart rendered in an RCP View that will be refreshed very fast
> over a period of several seconds, and I want to minimize the flicker
> effect. I saw in some BIRT documentation found online that I could do a
> refresh rather than build and render on the Generator. But if I call
> refresh() on the Generator, I get a SWTException with the message
> "Graphic is disposed".
>
> I've pasted my code below, adapted from an example I found online. It's
> a test case that plots a sine wave and changes the period of the wave
> every 500 msec. The code works, but there is some flicker with each
> update. If you un-comment the line in paintControl() that sets
> firstRender to false, it will attempt to refresh rather than build and
> render after the first paint operation. Then the SWTException I
> mentioned earlier will be thrown on gr.refresh(state). The exception is
> thrown in class Generator, when computing the chart; and I can't even
> find a sufficient guard to avoid calling refresh() when the Exception
> will be thrown.
>
> public class SampleChartView extends ViewPart {
>
> public static final String ID =
> "net.midnightjava.charttest.views.SampleChartView";
>
> private static float p = 5;
>
> private static GeneratedChartState state;
>
> private static final class MyPaintListener implements PaintListener
> {
>
> boolean firstRender = true;
>
> public void paintControl(PaintEvent e)
> {
> IDeviceRenderer deviceRenderer = null;
> try {
> deviceRenderer = PluginSettings.instance().getDevice("dv.SWT");
> } catch (ChartException e1) {
> e1.printStackTrace();
> }
> deviceRenderer
> .setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, e.gc);
>
> Rectangle rect = ((Composite) e.widget).getClientArea();
> Bounds bounds = BoundsImpl.create(rect.x + 2,
> rect.y + 2,
> rect.width - 4,
> rect.height - 4);
> bounds.scale(72d /
> deviceRenderer.getDisplayServer().getDpiResolution());
>
> Chart chart = null;
> if (firstRender) {
> chart = createSimpleLineChart(); }
>
> Generator gr = Generator.instance();
> try
> {
> if (firstRender) {
> state = gr.build(deviceRenderer.getDisplayServer(),
> chart,
> bounds,
> new RunTimeContext());
>
> gr.render(deviceRenderer, state);
> } else {
> gr.refresh(state);
> }
> //firstRender = false;
> }
> catch (Exception ex)
> {
> ex.printStackTrace();
> }
> }
> }
>
> private Canvas canvas;
>
> public SampleChartView() {
> Job animator = new Job("Animator Job") {
>
> @Override
> protected IStatus run(IProgressMonitor monitor) {
> if (p == 10) {
> p = 5;
> } else {
> p++;
> }
> if (!PlatformUI.getWorkbench().getDisplay().isDisposed()) {
> PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
>
> @Override
> public void run() {
> if (canvas != null && !canvas.isDisposed()) {
> canvas.redraw();
> }
> }
>
> });
> }
> schedule(500);
> return Status.OK_STATUS;
> }
>
> };
> animator.setSystem(true);
> animator.schedule();
> }
>
> public void createPartControl(final Composite parent) {
> canvas = new Canvas(parent, SWT.NONE);
> canvas.addPaintListener(new MyPaintListener());
> }
>
> public static final Chart createSimpleLineChart()
> {
> ChartWithAxes cwaBar = ChartWithAxesImpl.create();
> cwaBar.getBlock().setBackground(ColorDefinitionImpl.BLACK()) ;
> Plot plot = cwaBar.getPlot();
> plot.getOutline().setVisible(false);
> cwaBar.getTitle().getLabel().setVisible(false);
>
> Legend lg = cwaBar.getLegend();
> LineAttributes lia = lg.getOutline();
> lg.getText().getFont().setSize(16);
> lia.setStyle(LineStyle.SOLID_LITERAL);
> lg.getInsets().set(10, 5, 0, 0);
> lg.getOutline().setVisible(false);
> lg.setAnchor(Anchor.NORTH_LITERAL);
> lg.setVisible(false);
>
> AxisImpl xAxisPrimary = (AxisImpl) cwaBar.getPrimaryBaseAxes()[0];
> xAxisPrimary.setType(AxisType.LINEAR_LITERAL);
> xAxisPrimary.getMajorGrid().getTickAttributes().setVisible(f alse);
> xAxisPrimary.getOrigin().setType(IntersectionType.MIN_LITERA L);
> xAxisPrimary.getTitle().setVisible(false);
> xAxisPrimary.getLabel().setVisible(false);
> xAxisPrimary.getLineAttributes().setVisible(false);
>
> AxisImpl yAxisPrimary = (AxisImpl)
> cwaBar.getPrimaryOrthogonalAxis(xAxisPrimary);
> yAxisPrimary.getMajorGrid().getTickAttributes().setVisible(f alse);
> yAxisPrimary.getTitle().setVisible(false);
> yAxisPrimary.setPercent(false);
> yAxisPrimary.getLabel().setVisible(false);
> yAxisPrimary.getLineAttributes().setVisible(false);
>
> Vector<Integer> vs = new Vector<Integer>();
> for (int i = 1; i <= 512; i++) {
> vs.add(i);
> }
>
> ArrayList<Double> vn1 = new ArrayList<Double>();
> for (float i = 1; i <= 512; i++) {
> vn1.add(40 * Math.sin(i / p) + 40);
> }
>
> NumberDataSet categoryValues = NumberDataSetImpl.create(vs);
> NumberDataSet orthoValues1 = NumberDataSetImpl.create(vn1);
>
> Series seCategory = SeriesImpl.create();
> seCategory.setDataSet(categoryValues);
> seCategory.setVisible(false);
>
> LineSeries ls = (LineSeries) LineSeriesImpl.create();
> ls.setDataSet(orthoValues1);
> ls.getLineAttributes().setColor(ColorDefinitionImpl.GREEN()) ;
> ls.getMarkers().get(0).setVisible(false);
>
> SeriesDefinition sdX = SeriesDefinitionImpl.create();
> sdX.getSeriesPalette().shift(0);
> xAxisPrimary.getSeriesDefinitions().add(sdX);
>
> SeriesDefinition sdY = SeriesDefinitionImpl.create();
> sdY.getSeriesPalette().shift(0);
> yAxisPrimary.getSeriesDefinitions().add(sdY);
>
> sdX.getSeries().add(seCategory);
> sdY.getSeries().add(ls);
>
> return cwaBar;
> }
>
> @Override
> public void setFocus() {
> // TODO Auto-generated method stub
>
> }
> }
|
|
|
Re: Can't Refresh Chart rather than Re-Build and Render [message #543906 is a reply to message #538728] |
Thu, 01 July 2010 04:20 |
Mark Leone Messages: 123 Registered: July 2009 |
Senior Member |
|
|
Jason,
I'm just now able to get back to this problem. Thanks for posting the code. I tried it and found that it has the same deficiency of the example code I posted, which is that calling redraw() in the PaintListener produces a pronounced flicker. At the update rate used in the example, the chart is unreadable.
I found a way to update the chart directly with a backgrouond job, apart from the PaintListener. This works well with respect to the flicker problem, but since I'm not using a PaintListener, the chart doesn't adjust its size when the window is re-sized. I tried various permutations of code in PaintListener.paintControl(), using the code you posted for ideas, but everything I tried throws some version of org.eclipse.birt.YouDontKnowWhatYoureDoingException.
Can anyone tell me how to avoid the flicker in the code Jason posted? Or can someone tell me how to implement paintControl() in my example below to handle re-sizing of the parent Composite?
My code runs in an RCP app, so what I've posted is an instance of IViewPart that draws a sample chart in the view. It's a modulated sine wave, with the frequency of the modulated signal cycling through a range of discrete values. I'm not sure how to translate this to a standalone SWT application, as I can't figure out how to resolve the birt dependencies other than within the OSGI runtime. I ran the code Jason posted in an RCP view, and saw the flickering I mentioned. Perhaps that doesn't occur when run as a standalone SWT app.
import java.util.ArrayList;
import java.util.Vector;
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.RunTimeContext;
import org.eclipse.birt.chart.model.Chart;
import org.eclipse.birt.chart.model.ChartWithAxes;
import org.eclipse.birt.chart.model.attribute.Anchor;
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.LineAttributes;
import org.eclipse.birt.chart.model.attribute.LineStyle;
import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;
import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl;
import org.eclipse.birt.chart.model.component.Series;
import org.eclipse.birt.chart.model.component.impl.AxisImpl;
import org.eclipse.birt.chart.model.component.impl.SeriesImpl;
import org.eclipse.birt.chart.model.data.NumberDataSet;
import org.eclipse.birt.chart.model.data.SeriesDefinition;
import org.eclipse.birt.chart.model.data.impl.NumberDataSetImpl;
import org.eclipse.birt.chart.model.data.impl.SeriesDefinitionImpl;
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.LineSeries;
import org.eclipse.birt.chart.model.type.impl.LineSeriesImpl;
import org.eclipse.birt.chart.util.PluginSettings;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
public class SampleSinePlotView extends ViewPart implements PaintListener {
/**
* The ID of the view as specified by the extension.
*/
public static final String ID = "net.midnightjava.charttest.views.SampleSinePlotView";
private static final long REDRAW_PERIOD = 100;
private static float p = 10f;
private Canvas canvas;
private Job startPlotJob = new Job("Start Plot Job") {
@Override
protected IStatus run(IProgressMonitor monitor) {
if (canvas != null) {
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
startPlotting();
}
});
} else {
schedule(50);
}
return Status.OK_STATUS;
}
};
private IDeviceRenderer deviceRenderer;
private Bounds bounds;
protected Chart chart;
public SampleSinePlotView() {
}
public void createPartControl(final Composite parent) {
GridLayoutFactory glf = GridLayoutFactory.fillDefaults();
glf.applyTo(parent);
canvas = new Canvas(parent, SWT.NONE);
canvas.addPaintListener(this);
GridDataFactory gdf = GridDataFactory.fillDefaults();
gdf.grab(true, true).applyTo(canvas);
startPlotJob.setSystem(true);
startPlotJob.schedule();
}
private void startPlotting() {
final Generator gr = Generator.instance();
try {
deviceRenderer = PluginSettings.instance().getDevice("dv.SWT");
deviceRenderer.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, new GC(canvas));
Rectangle rect = canvas.getClientArea();
bounds = BoundsImpl.create(rect.x + 2,
rect.y + 2,
rect.width - 4,
rect.height - 4);
bounds.scale(72d /
deviceRenderer.getDisplayServer().getDpiResolution());
final Job plotJob = new Job("Plot Job") {
private GeneratedChartState state;
@Override
protected IStatus run(IProgressMonitor monitor) {
scrollData();
chart = createSimpleLineChart();
try
{
if (!PlatformUI.getWorkbench().getDisplay().isDisposed()) {
state = gr.build(deviceRenderer.getDisplayServer(),
chart,
bounds,
new RunTimeContext());
gr.render(deviceRenderer, state);
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
schedule(REDRAW_PERIOD);
return Status.OK_STATUS;
}
};
plotJob.setSystem(true);
plotJob.schedule();
} catch (ChartException e1) {
e1.printStackTrace();
}
}
protected void scrollData() {
if (p >= 20f) {
p = 10f;
} else {
p++;
}
}
public static final Chart createSimpleLineChart()
{
ChartWithAxes cwaBar = ChartWithAxesImpl.create();
cwaBar.getBlock().setBackground(ColorDefinitionImpl.BLACK());
Plot plot = cwaBar.getPlot();
plot.getOutline().setVisible(false);
cwaBar.getTitle().getLabel().setVisible(false);
Legend lg = cwaBar.getLegend();
LineAttributes lia = lg.getOutline();
lg.getText().getFont().setSize(16);
lia.setStyle(LineStyle.SOLID_LITERAL);
lg.getInsets().set(10, 5, 0, 0);
lg.getOutline().setVisible(false);
lg.setAnchor(Anchor.NORTH_LITERAL);
lg.setVisible(false);
AxisImpl xAxisPrimary = (AxisImpl) cwaBar.getPrimaryBaseAxes()[0];
xAxisPrimary.setType(AxisType.LINEAR_LITERAL);
xAxisPrimary.getMajorGrid().getTickAttributes().setVisible(false);
xAxisPrimary.getOrigin().setType(IntersectionType.MIN_LITERAL);
xAxisPrimary.getTitle().setVisible(false);
xAxisPrimary.getLabel().setVisible(false);
xAxisPrimary.getLineAttributes().setVisible(false);
AxisImpl yAxisPrimary = (AxisImpl) cwaBar.getPrimaryOrthogonalAxis(xAxisPrimary);
yAxisPrimary.getMajorGrid().getTickAttributes().setVisible(false);
yAxisPrimary.getTitle().setVisible(false);
yAxisPrimary.setPercent(false);
yAxisPrimary.getLabel().setVisible(false);
yAxisPrimary.getLineAttributes().setVisible(false);
Vector<Integer> vs = new Vector<Integer>();
for (int i = 1; i <= 512; i++) {
vs.add(i);
}
ArrayList<Double> vn1 = new ArrayList<Double>();
for (float i = 1; i <= 512; i++) {
vn1.add(40 * Math.sin(i / 0.1) + 40 + 40 * Math.sin(i / p) + 40);
}
NumberDataSet categoryValues = NumberDataSetImpl.create(vs);
NumberDataSet orthoValues1 = NumberDataSetImpl.create(vn1);
Series seCategory = SeriesImpl.create();
seCategory.setDataSet(categoryValues);
seCategory.setVisible(false);
LineSeries ls = (LineSeries) LineSeriesImpl.create();
ls.setDataSet(orthoValues1);
ls.getLineAttributes().setColor(ColorDefinitionImpl.GREEN());
ls.getMarkers().get(0).setVisible(false);
SeriesDefinition sdX = SeriesDefinitionImpl.create();
sdX.getSeriesPalette().shift(0);
xAxisPrimary.getSeriesDefinitions().add(sdX);
SeriesDefinition sdY = SeriesDefinitionImpl.create();
sdY.getSeriesPalette().shift(0);
yAxisPrimary.getSeriesDefinitions().add(sdY);
sdX.getSeries().add(seCategory);
sdY.getSeries().add(ls);
return cwaBar;
}
@Override
public void setFocus() {
// TODO Auto-generated method stub
}
public void paintControl(PaintEvent e) {
//??
}
}
|
|
|
Re: Can't Refresh Chart rather than Re-Build and Render [message #543907 is a reply to message #543906] |
Thu, 01 July 2010 04:26 |
Mark Leone Messages: 123 Registered: July 2009 |
Senior Member |
|
|
After posting, I thought of a way to run the code Jason provided as a standalone SWT app. I just create a separate Shell in createPartControl() and pass it to the SwtLiveChartViewer constructor, which then runs in a Shell outside the RCP runtime workbench.
When I did it this way, the flicker did not occur. Then I discovered that I was missing the SWT.NO_BACKGROUND style setting in the SwtLiveChartViewer constructor for the RCP app version. When I use that, the flicker does not occur, even when run in the RCP app.
However, I'm still not any better off than with the code I came up with, as this implementation does not handle re-sizing of the window either. In fact, it's worse than with my code, because instead of just re-drawing the plot at the same size in a larger window, it re-draws it elsewhere and leaves parts of the original plot behind, garbling the image. This happens in the RCP app and also as a stand-alone SWT app (tested by adding SWT.RESIZE as a style bit to the Shell constructor).
So the question remains, how can I handle window re-sizing for a dynamically updating chart?
[Updated on: Thu, 01 July 2010 04:45] Report message to a moderator
|
|
|
Re: Can't Refresh Chart rather than Re-Build and Render [message #544075 is a reply to message #543907] |
Thu, 01 July 2010 13:58 |
|
Mark,
Can you open a bug entry for this?
Jason
On 7/1/2010 12:26 AM, Mark Leone wrote:
> After posting, I thought of a way to run the code Jason provided as a
> standalone SWT app. I just create a separate Shell in
> createPartControl() and pass it to the SwtLiveChartViewer constructor,
> whch then runs in a Shell outside the RCP runtime workbench.
>
> When I do it that way, the flicker does not occur. So it's an artifact
> of running this code within an RCP app.
|
|
| |
Re: Can't Refresh Chart rather than Re-Build and Render [message #544131 is a reply to message #544124] |
Thu, 01 July 2010 16:46 |
|
Mark,
Can you download these examples:
http://www.birt-exchange.org/org/devshare/deploying-birt-rep orts/1187-eclipsecon-2010-birt-metal-ppt/
In the workspace there is a project called
org.eclipse.birt.examples.rcpchartengine which updates a chart and
renders it in an rcp app with re-sizable window. When I resize I do not
get any flicker but can you give it a try?
Jason
On 7/1/2010 12:35 PM, Mark Leone wrote:
> Jason,
>
> I edited my last response shortly after posting, and you seem to have
> responded to the earlier version (per the text you quoted). So to be
> clear, there's no issue with flicker when running as an RCP app. My only
> remaining question is how to handle window re-sizing. The example code
> was written with a shell that can't be re-sized, so I'm wondering if the
> behavior I observed is a known issue or a feature.
>
> So with this clarification, do you still think a bug is in order for the
> re-size behavior?
>
>
|
|
| |
Re: Can't Refresh Chart rather than Re-Build and Render [message #544447 is a reply to message #544429] |
Fri, 02 July 2010 16:45 |
|
Mark,
It is used for event handling when you have triggers on the chart. For
example with images that produce maps:
gcs = gr.build(
dServer,
cm,
bo,
null,
null,
null );
dRenderer.setProperty(IDeviceRenderer.UPDATE_NOTIFIER, new
EmptyUpdateNotifier( cm, gcs.getChartModel()));
gr.render( dRenderer, gcs );
String im = ((IImageMapEmitter)dRenderer).getImageMap();
BufferedWriter out = new BufferedWriter( new FileWriter(OUTPUT_HTML));
out.write("<html>");
out.newLine();
out.write("<body>");
out.newLine();
out.write("<div>");
out.newLine();
out.write("<map name='testmap'>");
out.write(im);
out.write("</map>");
out.newLine();
out.write( "<img id=myimage src='standalone.png'
usemap='#testmap'></img>");
out.newLine();
out.write("</div>");
out.newLine();
out.write("</body>");
out.newLine();
out.write("</html>");
out.newLine();
out.close();
If you comment out the update notifier the Image Map will not be created.
Jason
On 7/2/2010 12:00 PM, Mark Leone wrote:
> Thanks, Jason. I see now how the control listener is used to handle
> re-sizing behavior. The example worked fine for me, including re-sizing
> and detaching the view.
>
> Can you clarify what the update notifier does? I tried running without
> that property set on the display renderer, and I didn't see any
> different behavior.
|
|
|
Goto Forum:
Current Time: Thu May 02 22:53:50 GMT 2024
Powered by FUDForum. Page generated in 0.02731 seconds
|