Section 15.9. Virtual Workspace


15.9. Virtual Workspace

Camera, Desktop, Illusion, Infinite, InfiniteScrollbar, Lens, Move, Pan, Portal, Scroll, Solipsism, Viewport, Virtual, Visible, Window, Zoom

Figure 15-23. Virtual Workspace


15.9.1. Goal Story

Bill is using a meta-search engine to receive insurance quotes. The browser can't retrieve all 500 results at once, but Bill sees a table containing what looks like all the results. He can scroll up and down as if it were a regular table, and the newly appearing rows are populated on demand.

15.9.2. Problem

How can the user navigate through a large workspace?

15.9.3. Forces

  • Ajax Apps often require data from the server.

  • On the server side, data storage is virtually unlimitedsearch engines, for example, store billions of web pages. Even on corporate intranets, query results are often huge; try searching for every retail transaction on a given day.

  • The application should respond to data requests as quickly as possible.

  • Bandwidth constraints mean it's not feasible for an interactive application to download the entire search result. Yet users should be free to explore the whole thing.

15.9.4. Solution

Provide a browser-side view into a server-side workspace, allowing users to navigate the entire workspace as if it were held locally. The illusion is that the entire workspace is already in the browser, but the reality is that the server actually provides content on demand. At any time, the user is looking at an "opening" or "portal" into the entire workspace. He can pan across, jump to a different region, and zoom in and out. Each of these actions requires a view change, so the browser transparently fetches the data for the new portion of the workspace and renders it accordingly.

Here are some examples of navigable workspaces:


Lists

These include search results and user preferences.


Tables

These include Data Grids and spreadsheets.


Physical images

These include diagrams, photos and maps.


Documents

These include web content.


3D Models

These include computer-rendered landscapes and visualizations of virtual models such as chemical molecules.


Time-dependent artifacts

These include any artifact that changes with timeworld population, for instanceand can be "navigated" by moving across time.

Users move through the space in different ways. Often they use a combination of the tools described next.


Scrollbars

Users can make the content scroll incrementally or jump to a completely different region.


Dragging tool

Gives the user the impression of dragging the document around while keeping the view fixed.


Keyboard shortcuts

Users can scroll incrementally using directional keys. Page Up and Page Down are often used to completely replenish the current view with an adjacent region. Home and End are often used to jump to the start and end.


Direct command

Users can use a separate control to specify an exact regionfor example, typing in the dimensions they want to view. Or, for an image, placing a bounding box on a thumbnail view of the entire document.

There are also different zooming techniques:


Zoom slider

This is an adjustable Slider that represents the current zoom level.


Keyboard shortcuts

A common choice for zooming in and out is - and + (or =, since + usually requires pressing Shift-=).


Selecting a region

This is used to zoom further into a region within the current view.

Depending on the mechanisms you're supporting, you'll need to add different types of event handlers. So, for keyboard shortcuts, watch for events like keydown; for dragging and selecting a region, watch for mousedown, mousemove, and mouseup. In some cases, you'll need a control separate from the view itself, as is the case with a zoom slider or a thumbnail sketch of the entire workspace.

Whatever the event mechanism, the upshot is that the browser script will sometimes receive notifications that there is a new desired region or zoom level, if that's applicable. At that point, a Web Remoting (Chapter 6) call must occur, passing the server the details of the new region. Upon reply, the old data is either replaced or shifted along and the new data is rendered.

This pattern is often very bandwidth-intensive, considering that the entire workspace can be massive and the interaction complex. For that reason, there are several important performance optimizationsfor more details, see "Related Patterns" later in this chapter.

15.9.5. Decisions

15.9.5.1. How will you handle panning?

Panning, as opposed to jumping straight from one position to another, provides some unique design challenges. Unlike a complete jump, the user will expect a smooth transition from one position to another. Fortunately though, you already have most of the workspace loaded. Thus, a Browser-Side Cache (Chapter 13) is very important if you wish to achieve smooth scrolling. With this, you need only to load the new portion of the workspace instead of the whole thing. This leads to a few more specific questions:

  • How much of the workspace will you cache? A standard caching trade-off between memory and speed.

  • How will you track changes? Again, this should be the responsibility of the cache. At one level, the script will ask for the whole workspace, but the cache will decide which portion of that actually requires server content.

15.9.5.2. How will the view appear initially?

There has to be a default view position and zoom level within the overall workspace. A typical choice for the view is at the logical start or center. Zoom level should usually be quite high to let the user quickly drill down from the starting point.

15.9.5.3. What do you display while a region is being repopulated?

Most of the time, users are navigating to areas that are partly or completely unpopulated, requiring a result from the server to render them. What do you show in the interim? Here are a few options:

  • Whatever was there previously, possibly with a change of appearance.

  • Nothingclear it while waiting.

  • A Progress Indicator (Chapter 14).

  • A Popup (see earlier in this chapter)perhaps with just a single wordindicating what content will be placed there.

  • A Guesstimate (Chapter 13) of the content, perhaps made by extrapolating neighboring data held in the cache.

15.9.5.4. How will you handle changes to the existing view?

Sometimes the workspace changes while the user is watching it. For example, a user might introduce a filter to a result set. A change to the workspace means the view must change too. The easiest approach is to abandon the previous view location and revert to the default. However, there is often a more logical solution. Following are some examples:

  • You could keep the proportions the same as beforee.g., if the user was looking at rows one-third of the way down a table, then show the new rows that appear one-third of the way down the reduced table.

  • You could fix on certain contente.g., keep the top row in the same spot and show the remaining rows that are now directly below it. If the top row no longer exists, continue working downward until one of the rows does exist.

15.9.6. Real-World Examples

15.9.6.1. map.search.ch

http://map.search.ch is a Swiss Ajax map. Like Google Maps (http://maps.google.com) (which it predates) and similar products, the map constitutes a huge Virtual Workspace, and the user only views a tiny portion of it at any point in time. The map can be panned by dragging the workspace, clicking on arrow icons just outside its boundaries, and pressing the arrow keys. Zooming is controlled by clicking on a horizontal imagemap, clicking on Zoom In and Zoom Out buttons, or pressing Page Up and Page Down.

15.9.6.2. OpenRico Search Demo

The OpenRico Search Demo (http://openrico.org/rico/yahooSearch.page) is a Cross-Domain Proxy (Chapter 10) providing an Ajax interface to Yahoo! Search (Figure 15-24). Its philosophy was best summed up by OpenRico developer Bill Scott as "Death to Paging!" (http://looksgoodworkswell.blogspot.com/2005/06/death-to-paging-rico-livegrid-released.html). Instead of wading through a sequence of pages, you're presented with a single table containing all results. The results are a Virtual Workspace, and the table is a view into that space. Each time you navigate within the table, new results are pulled down from the server.

Figure 15-24. OpenRico Search Demo


15.9.6.3. Giant-Ass Image Viewer (GSV) library

Michael Magurski's GSV (http://mike.teczno.com/giant/pan/) is a library that lets web developers show an image of any size and allow the user to pan and zoom within it. The homepage contains a working demo.

15.9.6.4. Dunstan Orchard's blog

Dunstan Orchard's blog (http://www.1976design.com/blog/colophon) presents a slick panoramic, cartoonish view from his home. When the mouse rolls anywhere on the image, a couple of transparent Popups (see earlier in this chapter) appear on each side of the panorama. Rolling onto either of those and keeping the mouse there causes the banner to pan in that direction. Note that this is a different form of Virtual Workspace, since the whole workspace is local.

15.9.7. Code Refactoring: AjaxPatterns OpenRico Search

The OpenRico Search Demo is based on the OpenRico's LiveGrid API. In Data Grid (Chapter 14), the code example shows how to use the API. This example covers some of the API internals, specifically regarding the inclusion of a Virtual Workspace. Note that OpenRico uses Prototype (http://prototype.conio.net/) to allow for a more object-oriented coding style.

In OpenRico, the user's view is a GridViewPort object, which has a fixed row height and also tracks the view's starting position, i.e., the index that the top row of the GridViewPort corresponds to.

   Rico.GridViewPort.prototype = {     initialize: function(table, rowHeight, visibleRows, buffer, liveGrid) {       ...       this.rowHeight = rowHeight;       this.div.style.height = this.rowHeight * visibleRows;       ...       this.startPos = 0;     }, 

The results might include thousands of virtual rows, but the table itself is only about 20 rows (as determined by visibleRows). How, then, is the scrollbar created to make it appear as if there were thousands of rows? OpenRico creates a custom scrollbar. The trick is to create a 1-pixel-wide div whose height matches the height of the Virtual Workspace. The virtual height can be calculated since the scrollbar has access to the visible table height (visibleHeight), the number of virtual rows (metaData.getTotalRows( )), and the number of rows in the view (metaData.getPageSize( )). The scrollbar div's height is set to this virtual height, so the browser will render a scrollbar that appears to scroll across the entire virtual table:

     createScrollBar: function( ) {       var visibleHeight = this.liveGrid.viewPort.visibleHeight( );       // create the outer div...       this.scrollerDiv  = document.createElement("div");       ...       // create the inner div...       this.heightDiv = document.createElement("div");       this.heightDiv.style.width  = "1px";       this.heightDiv.style.height = parseInt(visibleHeight *           this.metaData.getTotalRows()/this.metaData.getPageSize( )) + "px" ;       this.scrollerDiv.appendChild(this.heightDiv);       this.scrollerDiv.onscroll = this.handleScroll.bindAsEventListener(this);       var table = this.liveGrid.table;       table.parentNode.parentNode.insertBefore(         this.scrollerDiv, table.parentNode.nextSibling);     }, 

Events on the scrollbar are dispatched to handleScroll. After any scrolling behavior has occurred, this function calculates the portion of virtual space being viewed. The algorithm determines the new virtual row that should appear on top of the viewport. For instance, if the row height is 10 pixels, and the user has scrolled to 50 pixels from the top, then the virtual row is 5; the viewport will need to be refreshed such that the new top row is the fifth virtual row.

   handleScroll: function( ) {     ...     var contentOffset = parseInt(this.scrollerDiv.scrollTop / this.viewPort.rowHeight);     this.liveGrid.requestContentRefresh(contentOffset);     this.viewPort.scrollTo(this.scrollerDiv.scrollTop);     ...   }, 

requestContentRefresh fetches the required content into a Browser-Side Cache known as Buffer. With the buffer in place, you can smoothly scroll back to previously seen results without any call required:

   fetchBuffer: function(offset) {     ...     var bufferStartPos = this.buffer.getFetchOffset(offset);     this.processingRequest = new Rico.LiveGridRequest(offset);     this.processingRequest.bufferOffset = bufferStartPos;     ...     callParms.push('id='        + this.tableId);     callParms.push('page_size=' + fetchSize);     callParms.push('offset='    + bufferStartPos);     ...     ajaxEngine.sendRequest.apply( ajaxEngine, callParms );     ...   }, 

Eventually, the viewport table is populated with the new set of rows:

   refreshContents: function(startPos) {       ...       for (var i=0; i < rows.length; i++) {//initialize what we have         this.populateRow(this.table.rows[i + contentOffset], rows[i]);       }       ...   }, 

15.9.8. Alternatives

15.9.8.1. Virtual Magnifying Glass

Instead of showing a partial view, you could present the entire thing in low detail and offer a "Virtual Magnifying Glass" or "Virtual Fish-Eye Lens" to zoom in on the detail. This might sound like it could only be applied to an image, but it is also applicable to tables and other interfaces.

15.9.9. Related Patterns

15.9.9.1. Browser-Side Cache

Browser-Side Cache (Chapter 13) is very important with respect to the Virtual Workspace if the user moves 1 percent down, you don't want to download the entire view again.

15.9.9.2. Predictive Fetch

It's useful to perform a Predictive Fetch (Chapter 13) on regions of the Virtual Workspace that the user is likely to navigate to next. Panning is a common task, so it's worthwhile caching the regions neighboring the current view. You might also cache at the next and previous zoom levels.

15.9.9.3. Guesstimate

Sometimes you might be able to quickly satisfy a navigation action with a Guesstimate (Chapter 13) while waiting for the real data to return.

15.9.9.4. Multi-Stage Download

If the response is large, break it into more than one part; download the most important information first, then follow up with more refined content.

15.9.9.5. Drag-And-Drop

Drag-And-Drop (see earlier) is often used to let the user pan by enabling her to drag the entire workspace across the view.

15.9.9.6. Slider

The zoom control is often a Slider (Chapter 14).

15.9.9.7. Unique URLs

Views need to be associated with Unique URLs (Chapter 17) so that the user can highlight a particular part of the workspace rather than the entire thing. That way, the user can easily bookmark the view or mail it to a friend.

15.9.10. Metaphor

Did you see The Truman Show (http://www.imdb.com/title/tt0120382/)? It's the story of a man who has no idea his whole world is fake, completely architected for the purposes of a reality TV show. As he walks around town, props are adjusted and the "townspeople" are directed a few seconds ahead of his arrival. There's a similar type of perception management going in Virtual Workspace; the illusion is that there's a whole world of content beyond the view, but the reality is that it's all constructed on demand.

15.9.11. Want to Know More?

Death to PagingBill Scott's LiveGrid Announcement (http://looksgoodworkswell.blogspot.com/2005/06/death-to-paging-rico-livegrid-released.html).

15.9.12. Acknowledgments

Thanks to Bill Scott for pointing out this example and keeping me updated on the progress of OpenRico and the LiveGrid functionality. Bill and fellow OpenRico developer Richard Cowin helped explain some of the implementation.




Ajax Design Patterns
Ajax Design Patterns
ISBN: 0596101805
EAN: 2147483647
Year: 2007
Pages: 169

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net