• .NET Developer Tools DevTools

    UI controls for ASP.NET AJAX, MVC, WPF,
    Silverlight, Windows 8 and Windows Phone

  • Hybrid Mobile Development Icenium

    Cross-platform Mobile Development Tool
    with cloud-based architecture

  • HTML5 / JavaScript Development Kendo UI

    Everything you need to build sites and
    mobile apps with JavaScript and HTML5

  • Testing Tools TestStudio

    One easy tool for Functional, Performance,
    Load and Mobile software testing

  • Web Presence Platform Sitefinity CMS

    Everything for your online business - content
    management, ecommerce, emarketing

  • Agile Project Management TeamPulse

    Simple and intuitive project management
    and collaboration software

Contact us

We are here for you.
  • usa+1‒888‒365‒2779
  • uk+44‒20‒7291‒0580
  • bg+359‒2‒8099850
  • de+49‒89‒2441642‒70
  • au+61‒2‒8090‒1465
  • emailsales@telerik.com
Your account Access to your products, updates and support
Telerik Product Families
  • Your Account
    Your Account
    Log in
  • ABOUT US

    About Telerik

    • Company
    • Press Center
    • Customers
    • Community
    • Careers
    • Contacts
Kendo UI - The way of HTML5
Products ▼
Kendo UI Web Kendo UI Mobile Kendo UI DataViz Server Side Wrappers
Demos Purchase Download
Blogs Documentation
Support ▼
Premium Forums StackOverflow Forums
Resources ▼

Featured Resource

Kendo UI Dojo


Blogs Code Library Demos Documentation FAQ Testing
Premium Forums Roadmap User Voice Videos Webinars More Resources
Contact Us Search
 

Blogs

Using SVG on Android 2.x (and Kendo UI DataViz)

Friday, February 17, 2012 by Kendo UI Team Blog | Comments 15

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:

  • canvg.js (~13KB minified, compressed)
  • Fabric.js (~37KB minified, compressed)

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.

About the Author
Todd Anglin is an avid HTML5, CSS3, and JavaScript advocate, and geek about all things web development. He is an active speaker and author, helping developers around the world learn and adopt HTML5. Todd works for Telerik as VP of HTML5 Web & Mobile Tools, where his current technical focus is on Kendo UI. Todd is @toddanglin on Twitter.

15 Comments

  1. 1 Vesselin Obreshkov 17 Feb 2012
    Man the Android browser has been quite the disappointment, hasn't it? Hope Chrome for Android does better (broke my phone so using iCraphone 3G and haven't been able to try out the new Chrome).

    That being said, wonder how things look on Windows Phone, lol ;)
  2. 2 Todd 17 Feb 2012
    @Vesselin It is unfortunate. If Google could just do for Android what it already does for Chrome (auto updates, help move people to new versions quickly), the entire industry would benefit.

    But alas...Android 2.x rules the roost.

    Things should actually look fine on Windows Phone thanks to our use of SVG/VML (technologies that work all the way back to IE6).
  3. 3 Rick Bullotta 03 Mar 2012
    The Android browser most definitely *is* the "internet explorer of mobile", and that, of course, is not a flattering commentary...
  4. 4 Adam 26 Apr 2012
    Cool article, any idea of how many Android users use javascript? Is it as high as the normal rates.. 96-8%?
  5. 5 S 28 Jun 2012
    Installing firefox on android does not cause the WebView to magically use firefox webkit, so it does not actually bring support for SVG to android 2.x apps as this article claims...
  6. 6 Peter Bulloch 24 Aug 2012
    Nice!

    I made my font sizes larger for phone use but the android version renders the initial, almost unreadable, small font. Any thoughts?
  7. 7 Peter Bulloch 24 Aug 2012
    Ah... I think this will help twig fonts (3 and 4 line within your demo code)...

    var canvas = document.createElement("canvas");
    canvas.setAttribute("style", "height:" + chartEle.height() + ";width:" + chartEle.width() + ";");

    var textObj = new fabric.Text("CanvasText", { fontSize: 50 });
    canvas.add(textObj);

    canvg(canvas, svg);
  8. 8 Peter Bulloch 24 Aug 2012
    Oops, ignore my solution. That needs yet another framework (fabric.js). Still would like some help on managing font sizes when converting SVG to Canvas for the Android turd.
  9. 9 Peter Bulloch 24 Aug 2012
    I would be forever in your debt if you can create an example using fabric.js.
  10. 10 Damian C. 18 Sep 2012
    Ive the same problem that Peter Bulloch… i would like to know how to resize labels font size.
  11. 11 Alex 25 Oct 2012
    I am having trouble using the recommended solution.
    This simple chart renders blank on Android 2.3.4 (emulator and real device as well)

    What could be causing the problem_

    <!DOCTYPE html>
    <html>
    <head>
    <title>Spending by Category</title>


    <link href="styles/examples-offline.css" rel="stylesheet">
    <link href="styles/kendo.dataviz.min.css" rel="stylesheet">


    <script src="js/jquery.min.js"></script>
    <script src="js/kendo.dataviz.min.js"></script>
    <script src="js/console.js"></script>
    <script src="js/canvg.js"></script>
    </head>
    <body>
    <div id="example" class="k-content" style="width: 100%; height: 800px">
    <div class="chart-wrapper">
    <div id="chart1"></div>
    </div>
    <script>
    var internetUsers = [ {
    "ID" : 2,
    "Name" : "Groceries",
    "Amount" : 800
    }, {
    "ID" : 4,
    "Name" : "Clothes",
    "Amount" : 320
    }, {
    "ID" : 5,
    "Name" : "Automobile",
    "Amount" : 490
    }, {
    "ID" : 8,
    "Name" : "Insurance",
    "Amount" : 160,
    "explode" : true
    }, {
    "ID" : 9,
    "Name" : "Pet care",
    "Amount" : 50
    } ];


    function createChart(transitionEnabled) {


    $("#chart1").kendoChart({
    theme : $(document).data("kendoSkin") || "default",
    dataSource : {
    data : internetUsers
    },
    title : {
    text : "Spending by Category"
    },
    legend : {
    position : "bottom"
    },
    seriesDefaults : {
    type : "area",
    labels : {
    visible : true,
    format : "{0}%"
    }
    },
    series : [ {
    type : "pie",
    field : "Amount",
    categoryField : "Name",
    explodeField : "explode"
    } ],
    tooltip : {
    visible : true,
    template : "${ category } - ${ value }%"
    },
    seriesClick : MainChartSeriesClick,
    transitions : transitionEnabled
    });
    }


    MainChartSeriesClick = function(e) {
    $(e.sender.dataSource.options.data).each(function(i, item) {
    if (item.Name != e.category) {
    item.explode = false;
    } else {
    item.explode = true;
    }
    });
    rendercharts();
    }


    function testSvg() {
    return !!document.createElementNS
    && !!document.createElementNS(
    'http://www.w3.org/2000/svg', 'svg').createSVGRect;
    }


    function rendercharts() {


    //Handle Android (or any non SVG browser, except old IE where we want to use VML)
    if (!testSvg()) {
    createChart(false);


    // Gauge 1
    var chartEle1 = $("#chart1"), chart1 = chartEle1
    .data("kendoChart"), svg1 = chart1.svg();


    //Create a canvas
    var canvas1 = document.createElement("canvas");
    canvas1.setAttribute("style", "height:"
    + chartEle1.height() + ";width:"
    + chartEle1.width() + ";");


    //Convert the SVG to canvas
    canvg(canvas1, svg1);


    //Remove the SVG/VML and show the canvas rendering
    chartEle1.empty();
    chartEle1.append(canvas1);


    } else
    createChart(true);
    }


    $(document).ready(function() {
    rendercharts();


    $(document).bind("kendo:skinChange", function(e) {
    rendercharts();
    });
    });
    </script>
    </div>
    </body>
    </html>

  12. 12 Alex 25 Oct 2012
    I figured it out, canvg is dependent on rgbcolor library
    Adding this line fixed it
    <script src="js/rgbcolor.js"></script>
  13. 13 Jose 28 Nov 2012
    The exact same example does not work under jQuery mobile.

    Android v 2.3.6
    It converts the svg chart to HTML5 canvas, but the bars in the chart are solid black instead of being orange and green.

    Anybody have an example to use fabric.js instead of canvg.js?

    Thanks,

  14. 14 natishu 17 Mar 2013
    i get 
    ERROR: Element 'html' not yet implemented.
  15. 15 Anup 30 Dec 2012
    @Jose I tried the same code with fabric.js but I can't get it to work. I've forced it to draw canvas from svg. fabric.js just renders the axes labels and chart title. Nothing else. Have a look: http://jsfiddle.net/qwjeu/

Comment

  1. Click to add

  2. Click to add

  3. Click to add

  4.    
     
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
    •  
     
      
       
Blogs feed
Categories

  • Tutorials (26)
  • Release (33)
  • Browsers (7)
  • Extensions (3)
  • Tip of the Week (10)
  • Videos (5)
  • Concepts and Theory (13)
  • Misc. (25)
  • Framework Constructs (6)
  • Mobile (6)
  • UI Widgets (5)
  • Blogs (1)
Archive
  • 2013 May (6)
  • 2013 April (10)
  • 2013 March (9)
  • 2013 February (12)
  • 2013 January (10)
  • 2012 December (9)
  • 2012 November (11)
  • 2012 October (6)
  • 2012 September (7)
  • 2012 August (8)
  • 2012 July (10)
  • 2012 June (8)
  • 2012 May (10)
  • 2012 April (7)
  • 2012 March (13)
  • 2012 February (10)
  • 2012 January (6)
  • 2011 December (10)
  • 2011 November (4)
  • 2011 October (6)
  • 2011 September (5)
  • 2011 August (9)
Home Web Mobile DataViz Server Wrappers Whitepapers Surveys Chrome Icenium Contact Us

Kendo UI framework is developed by Telerik - a leading provider of UI components for web, desktop and mobile applications. Trusted by over 100,000 customers worldwide for our devotion to quality and industry-best technical support, Telerik helps professionals maximize their productivity and "deliver more than expected" every day.

kendoui - powered by html5, css3 & jquery
get social
  • Twitter
  • Facebook
  • Google plus
  • RSS
Privacy Policy | Branding Guidelines
Powered by Sitefinity CMS

Copyright © 2011 - 2013 Telerik Inc. All rights reserved.