Protovis compatibility in Internet Explorer

Tutorial: Protovis compatibility in Internet Explorer

Introduction

internet-explorer-11-logo

Protovis is a terrific tool, but it does have some compatibility problems with some browsers (yes, we’re looking at you Internet Explorer 6-8. Protovis draws images in the Scalable Vector Graphic format (SVG). This format was developed in 1998-1999 but languished for years until the recent push toward HTML 5 Standards. Practically every modern and mobile browser, including IE 9, can render the format.

Your web team can find out if your site gets a lot of traffic from IE browsers. If you get less than five percent, This tutorial is probably not for you. But if many of your users do rely on IE, we’re going to look at some methods to make your Protovis graphics compatible with them while retaining functionality in modern browsers.

Modernizr

The simplest method is to use Modernizr, a very small JavaScript library similar to Protovis. Modernizr runs a test to see if a browser is able to render SVG. This is better than the blunt tool that is simple browser detection.

If the browser can render svg, the Protovis code renders. If it doesn’t, you can replace the Protovis chart with a fallback. In this case, we’ll us an image.

Download Modernizr and upload it to your server.

Now, load the Modernizr library by calling your script between the head tags.

Go to the Protovis script in the body of your page. Add the following Modernizr code directly after the opening script tag so that it looks like this:

Now go to the bottom of the script and add the following after the render command but before the closing script tag. It should look like this:

Download the example files if you want to see it in action.

ChromeFrame plugin

Google has an excellent product to help IE render Protovis. When an IE user arrives on a page with the appropriate code, a window opens and asks the user if they want to install ChromeFrame to view the content. If they choose yes, it will install the plugin and and refresh the page and renders the svg image. If the user chooses no, the window disappears and the content is not loaded.

This follows the same model that made Flash ubiquitous. It works fairly well but the IE warning message can be bit jarring.

The following meta tag must be added to the head area of your page. This will tell a browser that already has ChromeFrame installed to activate it when it views the page. It's best if you do this site wide if possible.

Next we have to include the code that does the browser detection. There are three blocks that we care about. It's best to include them in the head of your page because code included in the head area can be used by items anywhere on the page. But not everyone has that kind of access to their Content Management System (CMS). As an alternative, this will work if you include the code in the body just above your Protovis code.

This first block gives you access to the Google API:

See the code that says YOUR_KEY_HERE? Go get a Google API key for your site and copy and replace that text. It's free and takes less than a minute.

This second block loads a JavaScript library that can install Chrome Frame.

The third block does the actual browser detection. Notice the code destination: "". When there is nothing in the quotes, ChromeFrame will refresh the existing page once it's installed. You can also put a URL inside the quotes if you want to direct the user to another page.

Download the example files to see different ways to implement ChromeFrame.

Protovis+SVGweb

A third way to render in IE is to use a branch of Protovis that was altered to use Google's SVGWeb. Jamie Love has done a terrific job of making sure it works well with Protovis and stays up to date with the latest developments. But it is not for the faint of heart. You will have to write some code a little differently and it takes a little work.

The great advantage of this technique is that Protovis graphics are converted into Flash 10 objects and animations are retained. The disadvantage is that Flash is not viewable on iPhones and iPads.

Here is Love's directions for using SVGWeb

Protovis Tests, Partially Applying SVGWeb

This protovis pre-3.2 includes a small number of changes over
the top of protovis 3.2 that allow it to work with SVGWeb.

You can find a fork of the official Protovis source code
with these changes at
gitorious
(http://gitorious.org/~jlove/protovis/jloves-protovis).

Downloads

Or you can download the necessary files here:

How-To

To make protovis work using SVGWeb, you need to alter your coding
style slightly, basically because you need to make it work under IE.
Namely:

  • Conditionally include the SVGWeb svg.js file. You
    probably don't want to use SVGWeb for non-IE browsers (at least yet).
    You can do this, by, at the top of your HTML file:
    Make sure to you include 'svg.js' first - it MUST be the first
    javascript file you include. The 'data-path' attribute must reference
    the directory svg.swf is in.
  • Unless using a script type of text+protovis,
    don't use function expressions like function () a.b ,
    instead you have to write long form: function () { return a.b; } .
    This is an IE limitation.

Bugs using SVGWeb

This SVGWeb implementation is not perfect. There are a few bugs
and what-not to work out still:

  • Resizing the Protovis root panel does not also resize the flash <object>
    container containing the SVG. To do so, you need to identify and resize the <object>
    DOM element manually.
  • The title property does not work via SVGWeb.
    Use a label instead if possible.
  • Completely re-rendering a graph may not work. It
    seems a little flaky. That is - calling vis.render()
    on a visualisation previously rendered may or may not work.
    I'm sure this is fairly simple to fix.upate: This works
    fine on the polar clock example.
  • Creating a whole new visualistion (by going var vis = new pv.Panel()
    and rendering to the same div as a previous render may not work.
    This is to do with the underlying flash object not cleaning up correctly.
  • Text labels with a text size different to the default
    will have their vertical text-alignment be a little wrong. This is because
    the flash SVG renderer doesn't understand the concept of 'em' for text
    offsets.
  • The flash renderer is slower than native rendering, so
    frequent re-rendering of a graph will easily bog the browser
    down, and probably won't work (so don't try sub-1s re-rendering).
    This can be alleviated by only re-rendering child marks on the
    graph, and longer term we can probably find some performance
    improvements for it.
  • In SVGWeb, when nodes are rerendered, the re-render
    can cause SVGWeb to trigger a mouseover event for the
    newly renderer node. As many graphs re-render the same
    node, changing color etc, this causes an infinite
    stream of mouseover events.Therefore, be very careful on how you trigger color/graphical
    changes on mouseover. Ensure you don't re-render if on mouseover you
    get the same index. Also, try and avoid having a mouseout event
    on the same mark as the mouseover - instead try and add mouseout to
    your base panel, and mouseover to your mark (bar chart whatever).
  • The flash renderer doesn't seem to get circle's correct -
    see the polar clock for an example. This also occurs in other
    situations - e.g. see the antibiotics example.
  • Rotated text does not work with SVGWeb. This is due to a known
    limitation with the Flash SVG rendering. See

    this SVGWeb bug report
    for details. Sadly, SVGWeb also does not
    support SVG fonts referenced via a font-face definition
    (see this
    SVGWeb issue
    ).

Download the example files.

About this Tutorial

This tutorial was made to support the Interactive Census Workshop held by the Knight Digital Media Center at U.C. Berkeley in December, 2010.

Republishing Policy

This content may not be republished in print or digital form without express written permission from KDMC. Please see our Content Redistribution Policy at kdmc.berkeley.edu/license.