PivotViewer with JIT collections

I’ve spent the last week further extending our PivotViwer platform to allow for Just In Time (JIT) collections. Now creating JIT collections is nothing new or exiting, Microsoft even has a sample application for creating them. While the sample application is great there were some limitations which meant that I had to roll my own. If you’re interested in the first JIT collection I’ve created then have a look at our Flickr browser – http://pivot.lobsterpot.com.au/flickr each photo with a tag can be further drilled-through to allow for further exploration – check it out!

In creating my own JIT collection generator I had certain goals in mind, some of them were successful, others were not. But in creating my own Pivot and DeepZoom handlers I got a fantastic insight into how the PivotViewer control and DeepZoom works.

ASP.NET MVC

One of the goals was to keep the existing MVC application that is currently serving up our static collections (See my last post for more details). The Microsoft example uses HttpHandlers to intercept collection requests and output the required xml. This could have been integrated into the existing application, but in order to achieve some of my goals I decided instead to use MVC’s MapRoute feature to capture the collection requests and then render them using custom ActionResults. The required routes were:

//PivotViewer collection request
routes.MapRoute(
    "CXML",
    "{controller}/{action}/pivot.cxml",
    new { controller = "Collection", action = "Index" }
);
//DeepZoom collection request
routes.MapRoute(
    "DeepZoomDzc",
    "DZ/{action}/{cacheKey}.dzc",
    new { controller = "DeepZoom", action = "Dzc", cacheKey = UrlParameter.Optional, itemId = UrlParameter.Optional }
);
//DeepZoom image definition request
routes.MapRoute(
    "DeepZoomDzi",
    "DZ/Dzc/{cacheKey}/{itemId}.dzi",
    new { controller = "DeepZoom", action = "Dzi", cacheKey = UrlParameter.Optional, itemId = UrlParameter.Optional }
);
//DeepZoom tile request
routes.MapRoute(
    "DeepZoomTile",
    "DZ/Dzc/{cacheKey}_files/{level}/{x}_{y}.jpg",
    new { controller = "DeepZoom", action = "ImageTile", cacheKey = UrlParameter.Optional }
);
//DeepZoom image request
routes.MapRoute(
    "DeepZoomImage",
    "DZ/Dzc/{cacheKey}/{itemId}_files/{level}/{x}_{y}.jpg",
    new { controller = "DeepZoom", action = "Image", cacheKey = UrlParameter.Optional }
);

As you can see each of the DeepZoom routes was mapped to a DeepZoom controller. The DeepZoom controller was then tasked with returning the appropriate ActionResult.

Dynamic Image Selection

My second goal was to implement dynamic image selection. The plan was to leverage the different image sizes available in flickr photos, and at run time decide which image to download. I had decided to pick Thumbnail, Medium and Large/Original sizes. When a DeepZoom image is requested it first requests the *.dzi definition which contains the image size. It then requests the image using the following formatted url:

<http://address>/<itemaddress>/<level>/<x-coordinate>_<y-coordinate>.jpg

The level being an integer associated with the size of the image. My plan was to get the level and then map that to the image sizes: 0 – 2 = Thumbnail, 3 – 5 = Medium and 6+ = Large/Original. Unfortunately for me part of the image definition xml also contains the size of the image. This means that if the size of the image is different from the expected size then the rendering is thrown completely off. So if the Large size is 640 x 426 and the thumbnail is 100 x 67 then things go horribly wrong! The solution would be to then try and dynamically resize the images, but I’m not convinced it’s worth the CPU power. In the end I dropped this feature and stuck with the Thumbnail size to improve performance.

Drill-through collections

The final feature was to include drill-through functionality that allowed for filters/tags to be passed to the CXML controller and generate a new collection to be consumed. Using a method of prefacing links with “drillthrough:” I was that able to use e.Link.Scheme on the PivotViewers OnLinkClicked event to determine if the link was a drill-through action. If it was I was then able to reload to collection – a big thanks to Mike Taulty’s post on PivotViewer collections for the idea.

While there is still so much to be done, the flickr JIT collection is a great example of how the PivotViewer can be leveraged to provide more than just static collections.

3 Responses to “PivotViewer with JIT collections”


  1. 1 Anonymous July 2, 2012 at 8:08 am

    Hello Roger Nobel:

    Our project uses Silverlight 4 and Microsoft Pivot Viewer which is a Data Presentation tool that works in Silverlight.

    Microsoft Pivot Viewer makes it easier to interact with massive amounts of data in ways that are powerful, informative, and fun. Microsoft Live Labs tried to step back and design an interaction model that accommodates the complexity and scale of information rather than the traditional structure of the Web.

    Moreover, I am using the Pivot just-in-time collection (JIT) which is a collection that is dynamically generated for each view. Specifically, in JIT collections, the CXML and corresponding Deep Zoom image collection are generated by a web server at request time.

    The Module within our application that uses Siliverlight and Microsoft Pivot Viewer dynamically retrieves images at runtime so that it present the images to the user in Siliverlight and Microsoft Pivot Viewer.

    Just a refresher on the PivotViewer technology. When we install the PivotViewer.en-us.msi executable, the PivotViewer will also install the following DLL assemblies:

    System.Windows.Pivot
    System.Windows.Pivot.Model
    System.Windows.Pivot.SharedUI
    System.Windows.Pivot.StringResources
    System.Windows.Pivot.Utilities

    In the Pivot just-in-time collection (JIT), the Silverlight component only References:

    System.Windows.Pivot

    The Silverlight component of the Pivot just-in-time collection (JIT) throws JScript runtime error if I add any or all of the following Pivot DLL assemblies to the References:

    System.Windows.Pivot.Model
    System.Windows.Pivot.SharedUI
    System.Windows.Pivot.StringResources
    System.Windows.Pivot.Utilities

    Here is the Error:

    Microsoft JScript runtime error: Unhandled Error in Silverlight Application Set property ‘System.Windows.FrameworkElement.Style’ threw an exception. [Line: 23 Position: 46] at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
    at SilverlightPivotViewer.MainPage.InitializeComponent()
    at SilverlightPivotViewer.MainPage..ctor()
    at SilverlightPivotViewer.App.Application_Startup(Object sender, StartupEventArgs e)
    at MS.Internal.CoreInvokeHandler.InvokeEventHandler(UInt32 typeIndex, Delegate handlerDelegate, Object sender, Object args)
    at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs

    Could someone please help me resolve this error?

    • 2 Roger July 2, 2012 at 7:18 pm

      Not sure – I haven’t seen that error before. Are you able to send me your code?
      Roger

      • 3 Anonymous July 4, 2012 at 5:38 am

        All:

        Thank you for responding to my post.

        I found a workaround by looking at PivotViewer CustomActions feature in the code that I downloaded from the following webpage:

        http://pivotviewerlessons.codeplex.com/

        However, I have one more question.

        The PivotViewer display in our project will be using Custom Actions.
        I figured out a way to add custom action buttons on top of each item image in PivotViewer.

        My intention is to have “Add to cart” and “Remove” custom action buttons on top of each item image in PivotViewer.

        Obviously, “Add to cart” custom action button will ultimately trigger some kind of method of a Web Service or WCF service that will add the item image to a personal account Shopping Cart ( i.e. basically my application will be accessing the database ).

        Obviously, “Remove” custom action button will ultimately trigger some kind of method of a Web Service or WCF service that will remove the item image to a personal account Shopping Cart ( i.e. basically my application will be accessing the database ).

        However, I vaguely remember that someone posted a comment on a blog stating that the custom actions associated with Pivot Viewer displays should be very light weight.

        I’m just worried whether invoking a web service method when the custom action of a PivotViewer is invoked will be heavy weight.

        Is this something I should be concerned about?

        Thanks,


Leave a Reply