Speeding up line drawing

I’m programming a parallel coordinates visualization tool (sure, it’s not a game by most people’s standards, but it is interactive and colorful), and I’m experiencing speed problems with large datasets (i.e., drawing many, many lines). Handling the data and doing calculations is not the bottleneck; the drawing is. An example of a parallel coordinates visualization in Java can be found here: http://home.subnet.at/flo/mv/parvis/ if you have never heard of “parallel coordinates”.

Of course, the poor performance is to be expected, because for each record in the dataset I am analyzing I need to check whether the user has highlighted the record, then for each record draw a line between each column on the visualization. Basically, with a dataset with about 2000 records, each with 7 dimensions, I’ll be drawing 6 * 2000 or 12,000 lines (if they are all selected). At times, the tool performs sluggishly, making it sometimes difficult for the user to be precise with selections. The tool has to be cross-platform, and I haven’t tested OpenGL acceleration since I only have onboard video on my machine. I have already optimized for() loops, etc., so is there any faster way to draw lines in Java than using drawLine onto BufferedImage objects?

if you are not afraid of the effort, you can convert an image to an int[] array and use the Bresenham algorithm to draw the lines.
That should be much faster if you draw 10000+ lines, but its slower when drawing only a few lines (with java api) because of the converting overhead

Hm… someone mentioned that he got a nice speed increase by combining several lines in one Area and drawing that instead. Unfortunately I can’t remember the details nor find the thread. However, I do remember that he (who?) said that there was a sweet spot with somewhat like 30-50 lines in one Area object.

You might just give that a try… it’s rather easy to implement and you can easily find out the sweet spot by trial’n’error.

[quote]Hm… someone mentioned that he got a nice speed increase by combining several lines in one Area and drawing that instead. Unfortunately I can’t remember the details nor find the thread. However, I do remember that he (who?) said that there was a sweet spot with somewhat like 30-50 lines in one Area object.

You might just give that a try… it’s rather easy to implement and you can easily find out the sweet spot by trial’n’error.
[/quote]
What do you mean by “combining several lines in one Area”? Do you mean drawing the lines to the Area and then drawing the area on the BufferedImage? I’m a Java2D n00b…is there a method for drawing lines to an Area object?

[quote]Hm… someone mentioned that he got a nice speed increase by combining several lines in one Area and drawing that instead. Unfortunately I can’t remember the details nor find the thread. However, I do remember that he (who?) said that there was a sweet spot with somewhat like 30-50 lines in one Area object.
[/quote]
GeneralPath, not Area.

http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=2D;action=display;num=1081955210

Oops :-[

Well, I’ve never used that stuff :wink:

I really don’t see drawing 12,000 lines being a problem, (edit I’m sure the profiler doesn’t lie, but do you need to draw all the lines all the time?);

  1. load the dataset, draw the lines
  2. mouse hovers over a line, redraw in hilite color
  3. mouse hovers a different line || mouse leaves line pane then redraw previous line dark && 2.

or

  1. load the dataset, draw the lines
  2. mouse hovers over a datapoint, redraw all connected lines in hilite color
  3. mouse hovers a different datapoint || mouse leaves line pane then redraw previous lines dark && 2.

Should be a fraction of 12,000 lines connected to a node?

I’m probably way off though, I usually am…

Slight detail. screenshots show that he is using antialiased lines, thus the overwriting would give crappy results.
Nevertheless, he can still draw an ORed line for the good result.

The best way top speed this up is to not draw so many lines each time! Create an extra BufferedImage and draw everything in to it in the unselected state. Now to paint with a line selected, first copy this image to the output surface and the draw any selected lines on top.
Now each refresh only does bitmap copy plus drawing just the selected lines. Provided the number of lines selected is much less than the total, the code will be much faster.
I do something like this with road maps containing 10s (or even 100s) of thousands of antialiased ‘wide’ lines. I cache the background map images and just draw interesting (highlighted) routes on top.

[quote]I do something like this with road maps containing 10s (or even 100s) of thousands of antialiased ‘wide’ lines. I cache the background map images and just draw interesting (highlighted) routes on top.
[/quote]
Lol. I do the same thing. I suppose there aren’t too many different ways to go about it, is there? :slight_smile:

God bless,
-Toby Reyelts