SVG Chart Libraries (NVD3, Rickshaw, Highcharts, Morris.js) - Battle Royale!

JavaScript performance comparison

Revision 12 of this test case created

Info

Libraries:

SVG - nvd3 v0.0.1 (D3.js) (https://rawgithub.com/novus/nvd3/master/nv.d3.min.js) SVG - Rickshaw (D3.js) (https://rawgithub.com/shutterstock/rickshaw/master/rickshaw.min.js) SVG - Highcharts v2.2.5 (http://code.highcharts.com/highcharts.js) SVG - Morris.js v0.2.10 (jQuery, Raphael.js) (https://raw2.github.com/morrisjs/morris.js/master/morris.min.js)

Preparation code

<style>
/********************
* TOOLTIP CSS
*/

.nvtooltip {
        position: absolute;
        background-color: rgba(255,255,255,1);
        padding: 10px;
        border: 1px solid #ddd;
        z-index: 10000;

        font-family: Arial;
        font-size: 13px;

        transition: opacity 500ms linear;
        -moz-transition: opacity 500ms linear;
        -webkit-transition: opacity 500ms linear;

        transition-delay: 500ms;
        -moz-transition-delay: 500ms;
        -webkit-transition-delay: 500ms;

        -moz-box-shadow: 4px 4px 8px rgba(0,0,0,.5);
        -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,.5);
        box-shadow: 4px 4px 8px rgba(0,0,0,.5);

        -moz-border-radius: 10px;
        border-radius: 10px;

        pointer-events: none;

        -webkit-touch-callout: none;
        -webkit-user-select: none;
        -khtml-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
}

.nvtooltip h3 {
        margin: 0;
        padding: 0;
        text-align: center;
}

.nvtooltip p {
        margin: 0;
        padding: 0;
        text-align: center;
}

.nvtooltip span {
        display: inline-block;
        margin: 2px 0;
}

/**********
*  Axes
*/

.nvd3 .axis path {
        fill: none;
        stroke: #000;
        stroke-opacity: .75;
        shape-rendering: crispEdges;
}

.nvd3 .axis path.domain {
        stroke-opacity: .75;
}

.nvd3 .axis line {
        fill: none;
        stroke: #000;
        stroke-opacity: .25;
        shape-rendering: crispEdges;
}

.nvd3 .axis line.zero {
        stroke-opacity: .75;
}

.nvd3 .axis .axisMaxMin text {
        font-weight: bold;
}

/**********
* Lines
*/

.nvd3 .groups path.line {
        fill: none;
        stroke-width: 2.5px;
        stroke-linecap: round;
        shape-rendering: geometricPrecision;
}

.nvd3 .line.hover path {
        stroke-width: 6px;
}

.nvd3.line .nvd3.scatter .groups .point {
        fill-opacity: 0;
        stroke-opacity: 0;
}

.nvd3 .groups .point {
        transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
        -moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
        -webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
}

.nvd3.scatter .groups .point.hover,
.nvd3 .groups .point.hover {
        stroke-width: 20px;
        fill-opacity: .5 !important;
        stroke-opacity: .5 !important;
}

.nvd3 .point-paths path {
        stroke: #aaa;
        stroke-opacity: 0;
        fill: #eee;
        fill-opacity: 0;
}

.nvd3 .indexLine {
        cursor: ew-resize;
}
</style>
<style>
        .rickshaw_graph .detail{pointer-events:none;position:absolute;top:0;z-index:2;background:rgba(0,0,0,.1);bottom:0;width:1px;transition:opacity .25s linear;-moz-transition:opacity .25s linear;-o-transition:opacity .25s linear;-webkit-transition:opacity .25s linear}.rickshaw_graph .detail.inactive{opacity:0}.rickshaw_graph .detail .item.active{opacity:1}.rickshaw_graph .detail .x_label{font-family:Arial,sans-serif;border-radius:3px;padding:6px;opacity:.5;border:1px solid #e0e0e0;font-size:12px;position:absolute;background:#fff;white-space:nowrap}.rickshaw_graph .detail .item{position:absolute;z-index:2;border-radius:3px;padding:.25em;font-size:12px;font-family:Arial,sans-serif;opacity:0;background:rgba(0,0,0,.4);color:#fff;border:1px solid rgba(0,0,0,.4);margin-left:1em;margin-top:-1em;white-space:nowrap}.rickshaw_graph .detail .item.active{opacity:1;background:rgba(0,0,0,.8)}.rickshaw_graph .detail .item:before{content:"\25c2";position:absolute;left:-.5em;color:rgba(0,0,0,.7);width:0}.rickshaw_graph .detail .dot{width:4px;height:4px;margin-left:-4px;margin-top:-3px;border-radius:5px;position:absolute;box-shadow:0 0 2px rgba(0,0,0,.6);background:#fff;border-width:2px;border-style:solid;display:none;background-clip:padding-box}.rickshaw_graph .detail .dot.active{display:block}.rickshaw_graph{position:relative}.rickshaw_graph svg{display:block;overflow:hidden}.rickshaw_graph .x_tick{position:absolute;top:0;bottom:0;width:0;border-left:1px dotted rgba(0,0,0,.2);pointer-events:none}.rickshaw_graph .x_tick .title{position:absolute;font-size:12px;font-family:Arial,sans-serif;opacity:.5;white-space:nowrap;margin-left:3px;bottom:1px}.rickshaw_annotation_timeline{height:1px;border-top:1px solid #e0e0e0;margin-top:10px;position:relative}.rickshaw_annotation_timeline .annotation{position:absolute;height:6px;width:6px;margin-left:-2px;top:-3px;border-radius:5px;background-color:rgba(0,0,0,.25)}.rickshaw_graph .annotation_line{position:absolute;top:0;bottom:-6px;width:0;border-left:2px solid rgba(0,0,0,.3);display:none}.rickshaw_graph .annotation_line.active{display:block}.rickshaw_annotation_timeline .annotation .content{background:#fff;color:#000;opacity:.9;padding:5px 5px;box-shadow:0 0 2px rgba(0,0,0,.8);border-radius:3px;position:relative;z-index:20;font-size:12px;padding:6px 8px 8px;top:18px;left:-11px;width:160px;display:none;cursor:pointer}.rickshaw_annotation_timeline .annotation .content:before{content:"\25b2";position:absolute;top:-11px;color:#fff;text-shadow:0 -1px 1px rgba(0,0,0,.8)}.rickshaw_annotation_timeline .annotation.active,.rickshaw_annotation_timeline .annotation:hover{background-color:rgba(0,0,0,.8);cursor:none}.rickshaw_annotation_timeline .annotation .content:hover{z-index:50}.rickshaw_annotation_timeline .annotation.active .content{display:block}.rickshaw_annotation_timeline .annotation:hover .content{display:block;z-index:50}.rickshaw_graph .y_axis{fill:none}.rickshaw_graph .y_ticks .tick{stroke:rgba(0,0,0,.16);stroke-width:2px;shape-rendering:crisp-edges;pointer-events:none}.rickshaw_graph .y_grid .tick{z-index:-1;stroke:rgba(0,0,0,.20);stroke-width:1px;stroke-dasharray:1 1}.rickshaw_graph .y_grid path{fill:none;stroke:none}.rickshaw_graph .y_ticks path{fill:none;stroke:#808080}.rickshaw_graph .y_ticks text{opacity:.5;font-size:12px;pointer-events:none}.rickshaw_graph .x_tick.glow .title,.rickshaw_graph .y_ticks.glow text{fill:black;color:#000;text-shadow:-1px 1px 0 rgba(255,255,255,.1),1px -1px 0 rgba(255,255,255,.1),1px 1px 0 rgba(255,255,255,.1),0px 1px 0 rgba(255,255,255,.1),0px -1px 0 rgba(255,255,255,.1),1px 0 0 rgba(255,255,255,.1),-1px 0 0 rgba(255,255,255,.1),-1px -1px 0 rgba(255,255,255,.1)}.rickshaw_graph .x_tick.inverse .title,.rickshaw_graph .y_ticks.inverse text{fill:white;color:#fff;text-shadow:-1px 1px 0 rgba(0,0,0,.8),1px -1px 0 rgba(0,0,0,.8),1px 1px 0 rgba(0,0,0,.8),0px 1px 0 rgba(0,0,0,.8),0px -1px 0 rgba(0,0,0,.8),1px 0 0 rgba(0,0,0,.8),-1px 0 0 rgba(0,0,0,.8),-1px -1px 0 rgba(0,0,0,.8)}.rickshaw_legend{font-family:Arial;font-size:12px;color:#fff;background:#404040;display:inline-block;padding:12px 5px;border-radius:2px;position:relative}.rickshaw_legend:hover{z-index:10}.rickshaw_legend .swatch{width:10px;height:10px;border:1px solid rgba(0,0,0,.2)}.rickshaw_legend .line{clear:both;line-height:140%;padding-right:15px}.rickshaw_legend .line .swatch{display:inline-block;margin-right:3px;border-radius:2px}.rickshaw_legend .label{white-space:nowrap;display:inline}.rickshaw_legend .action:hover{opacity:.6}.rickshaw_legend .action{margin-right:.2em;font-size:10px;opacity:.2;cursor:pointer;font-size:14px}.rickshaw_legend .line.disabled{opacity:.4}.rickshaw_legend ul{list-style-type:none;margin:0;padding:0;margin:2px;cursor:pointer}.rickshaw_legend li{padding:0 0 0 2px;min-width:80px;white-space:nowrap}.rickshaw_legend li:hover{background:rgba(255,255,255,.08);border-radius:3px}.rickshaw_legend li:active{background:rgba(255,255,255,.2);border-radius:3px}
</style>
<style>
#legend {
        top: 20px;
}

#test, #svgtest {
        width: 500px;
        height: 300px;
        background-color: #EEE;
}
</style>
<div id="test"></div>
<div id="legend"></div>
<svg id="svgtest"></svg>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="//code.highcharts.com/highcharts.js"></script>
<script src="//rawgithub.com/morrisjs/morris.js/master/morris.min.js"></script>
<script src="//rawgithub.com/DmitryBaranovskiy/raphael/52bff469f60988f1391e8b3d7cb5349163df8ba1/raphael-min.js"></script>
<script src="//rawgithub.com/mbostock/d3/master/d3.min.js"></script>
<script src="//rawgithub.com/shutterstock/rickshaw/master/rickshaw.min.js"></script>
<script src="//rawgithub.com/novus/nvd3/master/nv.d3.min.js"></script>
<script>
/* Highcharts */

var sin = [], cos = [];

for (var i = 0; i < 100; i++) {
    sin.push({
        name: 'Sine',
        x: i,
        y: Math.sin(i/10)
    });
    cos.push({
        name: 'Cosine',
        x: i,
        y: .5 * Math.cos(i/10)
    });
}

var highcharts_data = [{
    data: sin
}, {
    data: cos
}];

/* Morris.js */

var morris_data = [];

for (var i = 0; i < 100; i++) {
    morris_data.push({
        x: i,
        sin: Math.sin(i/10),
        cos: .5 * Math.cos(i/10)
    });
}

/* Rickshaw */

var sin = [], cos = [];

for (var i = 0; i < 100; i++) {
    sin.push({x: i, y: 1 + (Math.sin(i/10))});
    cos.push({x: i, y: 1 + (.5 * Math.cos(i/10))});
}

var rickshaw_data = [{
    data: sin,
    name: 'Sine',
    color: '#FF0000'
}, {
    name: 'Cosine',
    data: cos,
    color: '#0000FF'
}];

/* NVD3 */

var sin = [], cos = [];

for (var i = 0; i < 100; i++) {
    sin.push({x: i, y: Math.sin(i/10)});
    cos.push({x: i, y: .5 * Math.cos(i/10)});
}

var nvd3_data = [{
    values: sin,
    key: 'Sine',
    color: '#FF0000'
}, {
    values: cos,
    key: 'Cosine',
    color: '#0000FF'
}];
</script>

Preparation code output

Test runner

Warning! For accurate results, please disable Firebug before running the tests. (Why?)

Java applet disabled.

Testing in unknown unknown
Test Ops/sec
NVD3
nv.addGraph(function() {
    d3.select('#svgtest')
        .datum(nvd3_data)
        .call(nv.models.lineChart());
});
pending…
Rickshaw
var graph = new Rickshaw.Graph({
    element: document.getElementById('test'),
    renderer: 'line',
    series: rickshaw_data
});

new Rickshaw.Graph.Axis.Y({
    graph: graph
});

new Rickshaw.Graph.Axis.Time({
    graph: graph
});

new Rickshaw.Graph.HoverDetail({
    graph: graph
});

new Rickshaw.Graph.Legend({
    graph: graph,
    element: document.getElementById('legend')
});

graph.render();
pending…
Highcharts
new Highcharts.Chart({
    chart: {
        renderTo: 'test',
        backgroundColor: '#EEE'
    },
    plotOptions: {
        series: {
        animation: false
    }
    },
    xAxis: {
        tickPixelInterval: 20
    },
    yAxis: {
        tickPixelInterval: 20
    },
    series: highcharts_data,
    title: {text: null}
});
pending…
Morris.js
Morris.Line({
    element: 'test',
    data: morris_data,
    xkey: 'x',
    ykeys: ['sin', 'cos'],
    labels: ['Sine', 'Cosine'],
    lineColors: ['#FF0000','#0000FF'],
    parseTime: false,
    ymin: -1.0,
    ymax: 1.0
});
pending…

Compare results of other browsers

Revisions

You can edit these tests or add even more tests to this page by appending /edit to the URL. Here’s a list of current revisions for this page:

0 comments

Add a comment