NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.
To learn about what's going on, see About the Archive Site.
Hello everybody, I'm using VisAD to display a 2D time series plot with lots of points (>1000) and above it moving 'timer bar' that advances from left to right in time. I found at least 3 possibilities to do this so far, but none of them is doing it well. Problem is that I need this 'timer bar' to advance smoothly and accurate even in sub-second resolution. This is ok for let's say around 500 points but if there more than 1000, the update rate of the display drops to around 1 per second and less. To make it clear: I'm not moving the 1000 points, they're fixed, I'm just moving a timer bar consisting of 2 points connected by a line above the bunch of points. The first solution I found updates the timer data via a call to setSamples. Far too slow. The second one, which I currently use, updates not the data, but the ScalarMap attached to the timer (via ScalarMap.setRange()). This is much faster than the first one, but still too slow for lots of underlying points. It seems the DataRenderer has to redraw all the points, not only the few (2!) that changed. The third one uses the animation feature of VisAD. I don't know about the speed yet, because I faced unexpected 'out of memory' errors. If you can't help me with the speed issue, maybe you can help me with this. The attached file is a slightly modified P5_02 example. In the current version it works fine, but if you change the value for ticksPerSecond in line 92 (e.g. to 20 instead of 10), you'll get (or at least I'll get) a Exception occurred during event dispatching: java.lang.OutOfMemoryError <<no stack trace available>> Alternatively you can leave the ticksPerSecond at 10 and resize the application window. Big sizes lead to the same error. Regards & thanks in advance, Timo -- __.__________ |lmo |homas
/* VisAD Tutorial Copyright (C) 2000 Ugo Taddei */ // Import needed classes import visad.*; import visad.java2d.DisplayImplJ2D; import java.rmi.RemoteException; import java.awt.*; import javax.swing.*; /** VisAD Tutorial example 5_02 A simple sine curve, but this time animated and with a different MathType. Use a FieldImpl and Display.Animation Run program with java P5_02 * */ public class TimerTest{ // Declare variables // The quantities to be displayed in x- and y-axes private RealType minute, length, amplitude; // The function amplitude = f(length) // as ( length -> amplitude ) private FunctionType func_len_amp; // The ( time -> range ) private FunctionType func_t_range; // Our Data values for length are represented by the set private Set lengthSet; // Time values are given by the set by the set private Set timeSet; // The Data class FlatField, which will hold data. private FlatField amp_len_ff; // A FieldImpl, which will hold all data. private FieldImpl timeField; // The DataReference from the data to display private DataReferenceImpl data_ref; // The 2D display, and its the maps private DisplayImpl display; private ScalarMap timeAnimMap, timeZMap, lenXMap, ampYMap, ampRGBMap; public TimerTest (String[] args) throws RemoteException, VisADException { // Create the quantities length = new RealType("some_unit", SI.meter, null); amplitude = new RealType("time", SI.meter, null); minute = new RealType("minute", SI.second, null); // Create the functions func_len_amp = new FunctionType(length,amplitude); func_t_range = new FunctionType(minute, func_len_amp ); // Create the sets: one for length and the other for time int nSamples = 2; lengthSet = new Linear1DSet(length, -1.0, 1.0, nSamples); // Time set int numSeconds = 10; int ticksPerSecond = 10; int tSamples = numSeconds * ticksPerSecond; timeSet = new Integer1DSet(minute, tSamples); // Values for amplitude are in an array like float[ rangeDim ][ nSamples] float[][] ampVals = new float[1][nSamples]; // Get the lengthtime values in the domain set to help with the calculations // "flase" means we don't get a copy from the samples float[][] lenVals = lengthSet.getSamples( false ); // Create some amplitude values: // Create a FlatField amp_len_ff = new FlatField( func_len_amp, lengthSet); // ...and a FieldImpl timeField = new FieldImpl( func_t_range, timeSet); // loop once for all time steps for(int t=0;t<tSamples;t++){ ampVals[0][0] = (float) t * (1.0f / ticksPerSecond); ampVals[0][1] = (float) t * (1.0f / ticksPerSecond); // and initialize it with the samples array amp_len_ff.setSamples( ampVals ); // set amp_len_ff as the t-th component of the Field timeField.setSample( t, amp_len_ff ); } // Create Display and its maps // A 2D display display = new DisplayImplJ2D("display1"); // Get display's graphics mode control draw scales GraphicsModeControl dispGMC = (GraphicsModeControl) display.getGraphicsModeControl(); dispGMC.setScaleEnable(true); // Create the ScalarMaps lenXMap = new ScalarMap( length, Display.YAxis ); ampYMap = new ScalarMap( amplitude, Display.XAxis ); // ampRGBMap = new ScalarMap( amplitude, Display.RGB ); timeAnimMap = new ScalarMap( minute, Display.Animation ); // Add maps to display display.addMap( lenXMap ); display.addMap( ampYMap ); // display.addMap( ampRGBMap ); display.addMap( timeAnimMap ); // Create a data reference and set the FieldImpl as our data data_ref = new DataReferenceImpl("amp_len_ref"); data_ref.setData( timeField ); // Add reference to display display.addReference( data_ref ); // Get AnimationControl from the Animation ScalarMap AnimationControl ac = (AnimationControl) timeAnimMap.getControl(); // and start animation ac.setStep(1000 / ticksPerSecond); ac.setOn( true ); // Create application window, put display into it JFrame jframe = new JFrame("VisAD Tutorial example 5_02"); jframe.getContentPane().add(display.getComponent()); // Set window size and make it visible jframe.setSize(300, 300); jframe.setVisible(true); } public static void main(String[] args) throws RemoteException, VisADException { new TimerTest(args); } } //end of Visad Tutorial Program 5_02
visad
archives: