Telerik blogs

Like it or not, Android version fragmentation is creating the new class of "IE6" browser for mobile development. With the broad majority (94%) of Android users still using a 2.x version of the platform (according to Google's own stats), Google has created a huge population of mobile users that have a crippled HTML5 browser.

The default Android 2.x browser lacks device orientation events. It lacks XHR2. It lacks Web Workers. HTML5 forms. Oh, and everything SVG!

Newer versions of Android (3+) improve the situation, but even in those cases the default Android browser leaves something to be desired. Google seems to know this, and they are actively developing Chrome for Android (yay!), but so far that's an Android 4+ exclusive.

As a developer targeting mobile HTML5 devices, you have two options for dealing with this Android situation:

  1. Target Android 3+ devices (and less than 5% of the Android market)
  2. Workaround the limits of Android 2.x

Google may be able to make the hard sell and only support Android 4+, but most developers probably prefer to include the 94% of Android 2.x users in their target user base. That means we need to work around the problems.

Kendo UI DataViz and SVG

When we set-out to build our data visualization tools for HTML5, we picked a combination of SVG and VML to power the Kendo UI DataViz rendering. SVG is a vector-based standard, broadly supported on all modern browsers, especially suited for interactive 2D rendering, and VML is a similar Microsoft technology that we use to support older versions of IE. Together, we can deliver richly interactive data viz that works just about everywhere.

Except Android 2.x.

As with most things in the modern web, though, there are always creative solutions for older browsers. By the end of this post, I'll show you how you can easily use Kendo UI DataViz (and SVG) on any version of Android, all the way back to Eclair (Android 2.1).

Solutions for SVG on Android 2.x

There are probably many creative ways you could technically solve the problem of SVG on old Android, but for the sake of this post, our available options are:

  1. Install a better Android browser
  2. Use a SVG JavaScript polyfill

Installing a Better Browser

Unlike Apple's iOS, there are many different browsers (with different HTML/JS engines) available on Android. By simply installing one of these more capable mobile browsers, Android 2.x users can quickly gain native access to more HTML5 features (including SVG). Two popular choices to consider if you want native SVG support on Android 2.x:

Opera Mobile for Android (11.5.5)
Firefox for Android (10.0.1)

Both of these browsers are free, and both natively support SVG. Firefox will deliver the best native SVG experience (including animations), whereas Opera Mobile will properly render SVG, but won't preserve SVG scripting or animation.

So, solving the SVG problem on Android 2.x can be as easy as installing a new browser. Done and done.

BUT…you don't have control over your users' browsers, so let's look at another option.

Polyfilling SVG on Android

Android's native browser may lack SVG, but it does support the HTML5 canvas element. That's good news. With the help of some crafty JavaScript, we can take any SVG, parse it, and then render the results to a canvas. The process may sacrifice some fidelity and interactivity that native SVG provides, but it will deliver a functional result.

There are (at least) two popular polyfills that I found to make the process of converting SVG to a Canvas surprisingly trivial:

These libraries are open source MIT (which means you can use them anywhere), and both can take SVG and spit-out a canvas rendering. By simply adding one of these JavaScript files to your project, you can easily swap-out the SVG with an identical canvas rendering when a browser lacking SVG visits your page.

Here's a basic example using the canvg polyfill that renders an SVG string on a HTML5 canvas (note: I've configured this demo to always replace SVG with canvas even if your browser natively supports SVG):

These polyfills are not "automatically" converting SVG to Canvas (though canvg can be used as a passive polyfill). Two or three lines of code is required for this approach. But that's a small price to pay to be able to support SVG-less browsers, like Android 2.x.

Rendering Kendo UI Charts on Android 2.x

Now that we have a polyfill that can convert SVG to canvas, we have a way of making the Kendo UI DataViz charts work on all versions of Android. Here's the basic approach:

  1. Check if the current browser supports SVG (using something like Modernizr). If it does, we don't need to do anything. If it doesn't…
  2. Use the Kendo UI DataViz chart API to get the SVG markup for your chart (yeah, there's an API method for that!)
  3. Create a new canvas in memory using JavaScript
  4. Pass the chart SVG to your polyfill and let it render the results
  5. Finally, remove the original SVG from your page (otherwise the browser might try to display it as a blank area on your page) and insert your new canvas rendering in to the DOM

The code is dead simple. Assuming you have added a Kendo UI chart to your page and you're using the canvg polyfill, we can do this in less than 10 lines of code:

//Handle Android (or any non SVG browser, except old IE where we want to use VML)
if (!Modernizr.svg && !supportsVML()) {
    //Get chart object and SVG
    var chartEle = $("#chart"),
        chart = chartEle.data("kendoChart"),
        svg = chart.svg();
    
    //Create a canvas
    var canvas = document.createElement("canvas");
    canvas.setAttribute("style", "height:" + chartEle.height() + ";width:" + chartEle.width() + ";");

    //Convert the SVG to canvas
    canvg(canvas, svg);

    //Remove the SVG/VML and show the canvas rendering
    chartEle.empty();
    chartEle.append(canvas);
}

BOOM! Presto. Do this, and your Kendo UI charts will be automatically converted from SVG to canvas on Eclair (2.1), Froyo (2.2), and Gingerbread (2.3). You can try this for yourself with the complete jsFiddle, where I've also added some code to let you toggle between different chart types (just so you can see the complete support for rendering different chart types). For those without Android devices handy, here are some "money shots":

Android 2.3.3 (Gingerbread - 59% of Android Market)
android_2-3-3kendoChartOnAndroid2-3

Android 2.2 (Froyo - 28% of Android Market)
android_2-2kendoChartOnAndroid2-2

Android 2.1 (Eclair - 7.6% of Android Market)
android_2-1kendoChartOnAndroid2-1

If you do have an Android 2.x device and want to test this outside of jsFiddle, I've also hosted this demo on htmlui.com via an easy to type Bitly link: http://bit.ly/KendoAndroidSVG (case sensitive!).

Known Issues (it's not all rainbows and unicorns)

Of course, while this cool SVG polyfill gives us the ability to functionally support older versions of Android, we do lose some richness that native SVG offers:

  • Animations won't work (in fact, you should disable animations when targeting Anroid 2.x)
  • Interactive features, like series tooltips, won't work

That makes sense. We're rendering the SVG to a static Canvas bitmap, so without more custom code we only have a static view of the chart. But we do have a view of the chart! On Android 2.x, where native SVG is otherwise absent.

Finally, Android 2.1 seems to be a bit more temperamental than 2.2 and 2.3, producing inconsistent results in my tests. Fortunately, it's the oldest and least used 2.x version, so be sure to do some extra testing if 2.1 is an essential target for your app.

Wrapping-up

If you are using Kendo UI DataViz and you need to support Android 2.x, this simple technique can instantly extend the reach of your solution. By using a simple JavaScript polyfill and a few lines of code, you can render SVG-based charts (or any other SVG, for that matter) using the HTML5 canvas on browsers that lack native SVG support.

Of course, we hope the world moves beyond Android 2.x. Only 4.5% of today's Android users are on versions 3+, and just 1% use Google's latest Ice Cream Sandwich release. If Google fails to fix this problem, we may all soon be looking at Android 2.x with the same ire we've assigned to IE6 for years.


ToddAnglin_164
About the Author

Todd Anglin

Todd Anglin is Vice President of Product at Progress. Todd is responsible for leading the teams at Progress focused on NativeScript, a modern cross-platform solution for building native mobile apps with JavaScript. Todd is an author and frequent speaker on web and mobile app development. Follow Todd @toddanglin for his latest writings and industry insights.

Comments

Comments are disabled in preview mode.