Discuss this template on the forums.

    Introduction

    This template provides a nice DekiScript wrapper for the Bluff graphing package.  Bluff is free under the MIT license, so it is not limited like Google charts or Visifire, and it is not dependent on a plugin like Visifire.  It has better axis control than the Google charts extension.  While it cannot do everything, it does produce very nice looking graphs.

    This is a preliminary beta version that I'm playing around with right now; it is plenty useful in its current state.

    Version history

    • 0.5.1 (26-Aug-2010 by neilw) - Fixed a graph rendering problem with IE8... works on my wiki but not MCP... ARGH!
    • 0.5.0 (20-Nov-2009 by neilw) - First beta version

    Todo

    Lots and lots.  For starters:

    • Control over tooltips (right now they're always enabled in their default mode)
    • Custom themes
    • More flexibility on data format
    • access to more options (x axis name!)
    • add support for remaining graph types (once I figure out how they work)
    • etc.

    Usage

    See the Bluff API Reference to understand the overall functioning of the package.  Only a subset of options are supported for now, but I think they are the most useful ones in typical usage.

    At present the template supports only the following graph types (note these names are case sensitive: enter them exactly!):

    • Area

    • Bar

    • Dot

    • Line

    • Mini.Bar

    • Mini.Pie

    • Mini.SideBar

    • Pie

    • SideBar

    • SideStackedBar

    • StackedArea

    • StackedBar

    Examples

    These self-documenting (?) examples will serve to explain the usage of the template until I can write some better docs.

    Line chart

    bluff {
        type: "Line",        // one of the above chart types (default = Line)
        size: 500,           // size may either be a list of two numbers [width,height] or just a number, in which case it's width, and
                             // height will be auto-calculated as .75 * width (default = [400,300])
        title: "Example 1",  // default = no title
        theme: "37signals",  // default = "37signals"
        labels: { 0: "start", 2: "middle", 4: "end" },    // labels for x-axis, aligned with the given data index (could also be a list)  Default: no labels
        y: { inc: 10, min: 0, max: 50 }, // Y axis controls: inc = label increment, min and max are self explanatory.  Defaults are to auto-set everything
        data: [              // data is a list of maps, each with one series
            { name:"series 1", data:[ 10,2,9,40,20 ] },                    // use default color
            { name:"series 2", data:[ 5,45,35,25,10], color:"#FF0000" }    // set color explicitly
        ]
    } 
    

    Bar Chart

    bluff {
        type: "Bar",
        size: [400,400],
        title: "Example 2",
        theme: "keynote",
    //    labels: { 0: "start", 2: "middle", 4: "end" },   // Let's try no labels for this one
    //    y: { inc: 10, min: 0, max: 50 },                 // Let's try auto-axis
        data: [              // data is a list of maps, each with one series
            { name:"series 1", data:[ 10,2,9,40,20 ] },   // use default color for both series
            { name:"series 2", data:[ 5,45,35,25,10] }
        ]
    } 

    Pie Chart

    Pie chart is maybe not quite working right (only displays integers for each pie slice?).  Don't love this one in general, compared to Google Charts.

    bluff {
        type: "Pie",
        size: [500,500],
        title: "Global Smartphone Sales, 2Q2009",
        theme: "pastel",
    //    labels: { 0: "start", 2: "middle", 4: "end" },   // Not relevant for pie chart (I think)
    //    y: { inc: 10, min: 0, max: 50 },                 // ditto
        data: [
            { name:"Symbian",    data:50.3 },   // For pie chart, data is a single value
            { name:"Blackberry", data:20.9 },
            { name:"iPhone",     data:13.7 },
            { name:"WinMo",      data:9.0  },
            { name:"Android",    data:2.8  },
            { name:"Other",      data:3.3  }
        ]
    }
    

    Template Source Code

    var errors = [];
    var id = @id;
    
    //*****************
    // Process options
    //*****************
    
    // type
    var type = $0 ?? $type;
    var allowed_types = [
        /* "AccumulatorBar", */ "Area", "Bar", "Dot", "Line", "Mini.Bar", "Mini.Pie", "Mini.SideBar",
        /* "Net",*/ "Pie", "SideBar", "SideStackedBar", /* "Spider",*/ "StackedArea", "StackedBar"
    ];
    if (type is not str || !list.contains(allowed_types,type)) {
        if (type is not nil)
            let errors ..= [ "invalid graph type '"..type.."'; allowed types are "..string.join(allowed_types,", ") ];
        let type = "Line";
    }
    // types which require single datum per series: Pie, Mini.Pie
    
    // size
    var size = $1 ?? $size;
    if (size is num) let size = [ size, size*.75 ];
    if (size is not list || #size != 2 || size[0] is not num || size[1] is not num || size[0] <= 0 || size[1] <= 0) {
        if (size is not nil) let errors ..= [ "size must be a list of positive numbers" ];
        let size = [ 400, 300];
    }
    
    // theme
    var theme = $2 ?? $theme;
    var allowed_themes = [ "keynote", "37signals", "rails_keynote", "odeo", "pastel", "greyscale" ];
    if (theme is not str || !list.contains(allowed_themes, theme)) {
        if (theme is not nil)
            let errors ..= [ "invalid theme '"..theme.."'; allowed themes are "..string.join(allowed_themes,", ") ];
        let theme = "37signals";
    }
    
    // data
    var data = $3 ?? $data;
    if (data is not list) {
        if (data is not nil) let errors ..= [ "data must be a list of maps" ];
        let data = [];
    }
    
    // title
    var title = $4 ?? $title;
    if (title is not str) {
        if (title is not nil) let errors ..= [ "title must be a string" ];
        let title = "";
    }
    
    // labels
    var labels = $5 ?? $labels;
    if (labels is not list && labels is not map) {
        if (labels is not nil) let errors ..= [ "labels must be a list or map" ];
        let labels = {};
    }
    if (labels is list)
        let labels = { (i):labels[i] foreach var i in num.series(0,#labels-1) where labels[i] is not nil };
    
    // y
    var y = $6 ?? $y;
    if (y is not map) {
        if (y is not nil) let errors ..= [ "y must be a map" ];
        let y = {};
    }
    <html>
    <head>
    <script type="text/javascript" src="http://developer.mindtouch.com/@api/deki/files/4949/=js-class.js" ></script>;
    <script type="text/javascript" src="http://developer.mindtouch.com/@api/deki/files/4947/=bluff-src.js" ></script>;
    <script type="text/javascript" src="http://developer.mindtouch.com/@api/deki/files/4948/=excanvas.js" ></script>;
    
    <script type="text/javascript"> "
    Deki.$(document).ready(function($) {
        var g = new Bluff."..type.."('"..id.."','"..string.join(size,"x").."');
        g.theme_"..theme.."();
        g.title = '"..title.."';
    ";
    // output the data
    foreach (var d in data)
        "    g.data("..json.emit(d.name??"")..","..json.emit(d.data)..(d.color ? ","..json.emit(d.color):"")..");\n";
    // y axis parameters
    if (y.inc is not nil) "    g.y_axis_increment = ".. y.inc .. ";\n";
    if (y.min is not nil) "    g.minimum_value = "   .. y.min .. ";\n";
    if (y.max is not nil) "    g.maximum_value = "   .. y.max .. ";\n";
    // resume script
    "
        g.labels = " .. json.emit(labels) .. ";
        g.tooltips = true;
        g.draw();
    });
    " </script>
    </head>;
    <body>
    if (#errors) <div style="color:red">
        <strong> "ERRORS:" </strong>;
        <ul> foreach (var e in errors) <li> e </li>; </ul>;
    </div>;
    <canvas id=(id) width=(size[0] /*.. "px"*/) height=(size[1] /* .. "px"*/)> </canvas>;
    </body>
    </html>
    

    Tag page
    Viewing 5 of 5 comments: view all
    Great work neilw!!
    I don't know exactly why..., but i need to replace "size*.75" by "size*(3/4)" expression to avoid an error.
    Posted 04:51, 21 Apr 2010
    @himikel
    That is super weird about the .75, since it works fine on this site. What version are you running?
    Posted 06:16, 21 Apr 2010
    @neilw the version is MindTouch Core v.9.08.1
    I've tested some decimal expressions in the same wiki, and i've obtained the following weird result:
    http://www.gureweb.net/User:himikel/roles/SoftDeveloper/SandBox/Expression_testing
    Seems that the decimal point is not recognized..., the site language is ES and the page language EN, any idea?
    Posted 10:32, 21 Apr 2010
    @himikel
    Very weird. I wonder if it's a language bug, though I can't reproduce it. One thing to try: 0.75 instead of simply .75; let me know if that works. And either way, please file a bug on this.
    Posted 10:42, 21 Apr 2010
    @neilw you can see in Test2: 5*0.5 = 25 ... the decimal part is not recognized as such
    but in Test3: 5*(5/10) = 2,5 ... i can see the correct result but shown with Spanish (ES) localization
    Can i configure this localization somewhere: system, php, site or page settings...?
    Posted 12:06, 21 Apr 2010
    Viewing 5 of 5 comments: view all
    You must login to post a comment.

    Copyright © 2011 MindTouch, Inc. Powered by