2015-02-22
Data Analysis and Visualization with JSXGraph

I want to explore D3 and JSXGraph as potentially useful ways to embed data visualization into web pages. I’m going to start with JSXGraph in this post, and follow up with D3 and perhaps other techs in later posts.

I’m also going to be playing with conditional Hugo templates so that only those pages that need a particular resource (e.g., ReactJS, AngularJS, JSXGraph or D3) will end up loading those files. For this page, I’m defining usejsxgraph: true in the metadata for this post. I’ve extended header.html to include the required JSXGraph when the usejsxgraph parameter is true for a post or page.

In order to see how easy or difficult JSXGraph is to embed, I’ve adapted the example from Infinity to fit nicely into the page. Overall, I’m impressed with how easy it is to embed JSXGraph with a few lines of code.


The code for the above example is very small and easy to understand:

<div id='infinitybox' class='jxgbox' style='width:450px;height:400px;'>
</div>

<script>
var brd = JXG.JSXGraph.initBoard('infinitybox', {boundingbox: [-6, 6, 10, -8]});
brd.suspendUpdate();
var S = brd.create('slider', [[-5,-6],[5,-6],[0,0.95,1]], {name:'S'});
var hue = brd.create('slider', [[-5,-7],[5,-7],[0,8,36]], {name:'color'});
var points = new Array();
points[0] = brd.create('point',[5, 5], {name:' '});
points[1] = brd.create('point',[-5, 5], {name:' '});
points[2] = brd.create('point',[-5, -5], {name:' '});
points[3] = brd.create('point',[5, -5], {name:' '});

function quadrangle(pt, n) {
    var col;
    var arr = new Array();
    for(var i = 0; i < 4; i++) {
        arr[i] = brd.create('point',
            [function(t) {
                return function () {var x = pt[t].X();
                                var x1 = pt[(t+1)%4].X();
                                var s = S.Value();
                                return x+(x1-x)*s;
                         }}(i),
             function(t) {
                return function () {var y = pt[t].Y();
                                var y1 = pt[(t+1)%4].Y();
                                var s = S.Value();
                                return y+(y1-y)*s;
                         }}(i)
            ],
            {size:1, name:"",withLabel:false,visible:false});
    }
    col =  function(){return JXG.hsv2rgb(hue.Value()*n,0.7,0.9);};
    brd.create('polygon',pt, {fillColor:col});
    if(n>0)
        quadrangle(arr, --n);
   }
quadrangle(points,30);
brd.unsuspendUpdate();
</script>

PieChart Example

One of the useful things to do with a graphics library is to draw meaningful charts. Let’s try it with JSXGraph. I’m going to begin with one of their examples, and then try to morph it into something more original. I’m using the Pie Chart example. I’ve adjusted the original example and code for better placement in this post.


And the code for the above is:

<div id='piechartbox' class='jxgbox' style='width:450px;height:350px;'>
</div>

<script>
  var dataArr = [
                  30, 16, 14, 10, 10,
                  8, 6, 6];
  var board = JXG.JSXGraph.initBoard('piechartbox', {showNavigation:false, showCopyright:true, boundingbox: [-2.4, 8, 13.6, -4]});
  board.containerObj.style.backgroundColor = 'darkslateblue';
  board.options.label.strokeColor = 'lightblue';
  board.options.label.fontSize = 12;
  board.suspendUpdate();

  var a = board.create('chart', dataArr,
      { chartStyle:'pie',
        colors:[
            '#0F408D','#6F1B75','#CA147A','#DA2228','#E8801B',
            '#FCF302','#8DC922','#15993C','#87CCEE','#0092CE'],
        fillOpacity:0.8,
        center:[5,2],
        strokeColor:'darkblue', highlightStrokeColor:'darkblue', strokeWidth:4,
        labels:[
            'War games','Sport games', 'Old games', 'Strategy games', '3D games',
            'Puzzle games','Board games', 'I do not play games'],
        highlightColors:[
            '#E46F6A','#F9DF82','#F7FA7B','#B0D990', '#69BF8E',
            '#BDDDE4','#92C2DF','#637CB0', '#AB91BC','#EB8EBF'],
       highlightOnSector:true,
       highlightBySize:true,
       gradient:'linear'
      }
  );
  board.unsuspendUpdate();
</script>
Data-driven Chart

I’m going to extend the above example to see if I can create a parameterizable component, rather than having a bunch of code. So I’m going to want to build a function that takes a table looking like:

Category Name Category Percentage Category Color
War games 30 #0F408D
Sport games 16 #6F1B75

But instead of the game data from the original example, I’m going to use this blog itself as the data. For example, I should be able to build a PieChart with all of the tags and their frequency percentage. I modified the default Hugo template so that it builds a Javascript variable window.blogTaxonomies that has a map of tag name to Posts containing that tag. To verify I can incorporate this variable, I’ll try to generate a table from this data.

CategoryCountPosts
{[ catKey ]} {[ catVal.length ]}
  • {[ catPost ]}

Now let’s try hardcoding a PieChart using this data:

Argh Gotta do some real work right now. To be continued…