Hi Timo,
> 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.
You are getting the OutOfMemoryError because DisplayImplJ2D stores
a BufferedImage for each step in the animation (that's the only
way to get fast animation with the "software rendering" that it
uses). With ticksPerSecond = 20 you get 200 BufferedImages.
You should be able to do what you want with something like your
first solution:
DisplayImplJ2D display = ...
display.addMap(...)
...
DataReferenceImpl ref = new DataReferenceImpl("timer");
Linear1DSet lengthSet = new Linear1DSet(length, -1.0, 1.0, nSamples);
FlatField amp_len_ff = new FlatField( func_len_amp, lengthSet);
int t = 0; // initial time
ampVals[0][0] = (float) t * (1.0f / ticksPerSecond);
ampVals[0][1] = (float) t * (1.0f / ticksPerSecond);
amp_len_ff.setSamples( ampVals );
ref.setData(amp_len_ff);
display.addReference(ref);
...
// now every time you want to go to a new time step
t = ... // new time step
ampVals[0][0] = (float) t * (1.0f / ticksPerSecond);
ampVals[0][1] = (float) t * (1.0f / ticksPerSecond);
amp_len_ff.setSamples( ampVals );
This should update quickly, since the your amp_len_ff contains
only two samples. In particular, as you increase the number of
time steps, the size of amp_len_ff does not increase.
Is this the same as your first solution? If it is, and is slow
then the explanation is that the DisplayImplJ2D needs to redraw
the graphics for the other data it is linked to (not retransform,
but simply redraw which will get slow for large enough data).
DisplayImplJ2D redraws all the graphics because when the graphics
for one data object change it may cover and uncover different
parts of the graphics for other data objects.
A DisplayImplJ3D will redraw much faster for your first solution,
and avoid the extra memory for your third solution. Is there a
reason why you cannot use a DisplayImplJ3D with a
TwoDDisplayRendererJ3D? If you can use Java3D, I recommend it.
Cheers,
Bill
----------------------------------------------------------
Bill Hibbard, SSEC, 1225 W. Dayton St., Madison, WI 53706
hibbard@xxxxxxxxxxxxxxxxx 608-263-4427 fax: 608-263-6738
http://www.ssec.wisc.edu/~billh/vis.html