Monday, December 11, 2006

Custom Bindows View Port

I was surfing for UI design patterns besides those offered by the great Bill Scott and his team at Yahoo and found Jenifer Tidwell's Designing Interfaces . Her book describes a number of design patterns one which we all use a lot -- "Overview Plus Detail."

You might not have known the name, but if you've used Google or Yahoo! Maps, you're using this pattern.

The way that the pattern works is that the map is the detail part and the little view port located at the lower right or the upper left is the overview part of the pattern. You use this pattern when there is a large amount of spatial information, but you can't see it all. So, thru the view port, you navigate to specific parts of the data.

Jenifer has a great description of it here.

As of this writing (I am using Bindows 2.5), Bindows doesn't have a BiViewPort, but we can easily create one. We'll use it to navigate a randomly generated graph created from the Bindows graphical API.

Let's look at the design details.

First, let's decide how large we want our virtual view area to be. The virtual area is the place where we'll put the graph. Let's make it 5000x5000 pixels. Obviously, we won't be able to see the graph in its entirety (at least with any meaning; besides, how many people have monitors capable of displaying a graph that size!), but we'll be able to see a portion of the graph as wide and as high as the screen.

Then, we'll need a way to navigate the virtual area. This is where the overview window comes in.
We'll need an overview window and then a little viewport to navigate the virtual area.

Basically, the overview window is the virtual area in miniature. Likewise, the viewport is a little miniature "screen." Because they're miniatures, we have to properly scale them so they look and react proportionally just like the real thing.

The overview window and the viewport are pretty simple. They're just BiComponents. The viewport is added to the overview window. Here's the code --


Notice that we've hardcoded a size to the overview window (ex. overview.setSize(200, 200)). This is fine as long as the viewport is properly scaled based on the overview and the graph size. This is what we're doing with the function getMultiple() --


The function returns the number of times that the graph is bigger than the overview. We use the multiple to scale down the viewport like this --


Now, here comes the really important part. We need to take care of navigation. This means that we need to move the viewport and once we're done moving the view port, we move the graph.

For the first part, the viewport listens for the dragstart event. Once that event fires, a number of things happen --

- The viewport is made movable (i.e. added as BiMoveHandle)
- The movable component listens for the moveend event

When the move ends, we take the location of the viewport and then scale up to match the position of the virtual area so that the screen can display the same nodes found in the viewport. Here's what all this looks like --


The linkMgr is the BiLinkManager. In other words, it's the graph container. We're moving this entire component which contains all the elements that make up a graph (nodes and edges).

We're done!

One thing you'll notice is that I didn't talk about creating graphs. The folks at Bindows have some terrific tutorials, examples and documentation on that. You can also review my source.

When you do, you'll also note that I use two additional components which I didn't mention -- originalPos and navWinInfo. The first one is just a BiComponent which marks the position that the viewport was at (that's the gray box which you'll see in the prototype). The second one is just a BiLabel which displays current xy coordinates.

You can find the prototype here (be sure and maximize your browser - F11). Feel free to study and use the source. If you do, let them know where you got it.

Enjoy and have fun!

2 comments:

Yoram said...

Great job Oliver,
Yoram Meriaz

skypoet said...

Thanks Yoram! I thought you might like it!