Wednesday, December 7, 2011

Introducing Add-Ins in CTools

We just added Add-Ins support in CDF / CDE. This will have a great impact in both the development of the ctools but also in the usage




AddIns reference 
 
AddIns are CDF's extension points. Can be used in any component to be able to fine-control that component and extend it in a very simple way
The use case for this concept is TableComponent's colType. Tables are a fundamental piece of dashboards / visualizations and there needs to be simple ways to extend the ways they are rendered
AddIn Implementation
In order to implement an AddIn, you need to create an object like the following:
  var sparkline = {
    name: "sparkline",
    label: "Sparkline",
    defaults: {
      type: 'line'
    },
    init: function(){

      // Register this for datatables sort
      var myself = this;
      $.fn.dataTableExt.oSort[this.name+'-asc'] = function(a,b){
        return myself.sort(a,b)
      };
      $.fn.dataTableExt.oSort[this.name+'-desc'] = function(a,b){
        return myself.sort(b,a)
      };
        
    },
    
    sort: function(a,b){
      return this.sumStrArray(a) - this.sumStrArray(b);
    },
    
    sumStrArray: function(arr){
      return arr.split(',').reduce(function(prev, curr, index, array){  
        console.log("Current " + curr +"; prev " +  prev); 
        return parseFloat(curr) + (typeof(prev)==='number'?prev:parseFloat(prev));
      });
    },
    implementation: function (tgt, st, opt) {
      var t = $(tgt);
      t.sparkline(st.value.split(/,/),opt);
      t.removeClass("sparkline");
    }
  };

Dashboards.registerAddIn("Table", "colType", new AddIn(sparkline));
name, label, defaults, init and implementation are the important bits here. This specific code is an implementation of a sparkline using the jquery plugin.


Setting options
Options are passed on a per component basis, usually in the component's preExecution function. It can either be a static list of options that will be merged with the defaults or a function where the options change according to the state
function f(){
 
    // Option 1 :Static list

    this.setAddInOptions("colType","sparkline",{barColor: "red"});
 
    // option 2: function
    this.setAddInOptions("colType","sparkline",function(state){
        // Let's turn the second sparkline into a bar
        if(state.colIdx == "2"){
            return { type:'bar'};
        }
    });
}
Setting defaults
It's also possible to ser a site-wide / dashboard wide defaults, and like the previous option, can either be a static list or a function
Dashboards.setAddInDefaults("Table","colType","sparkline",{fillColor:"#aaa"});

Dashboards.setAddInDefaults("Table","colType","sparkline",function(state){ 
    return state.rowIdx%2?{fillColor:"#aaa"}:{fillColor:"#fff"};
});


Implementation arguments
implementation function has the following arguments:
    implementation: function (tgt, st, opt) {}
tgt
target - Target for the action. eg: On a cellType, it will be the td cell
state
state - Information about the specific addin call. On a cellType will be an object with: {rawData, tableData, colIdx, rowIdx, series, category, value, colFormat}
opt
options passed to this addIn
Calling AddIns from components
When developing a component, it's very easy to define a new AddIn type. Here's the example that TableComponent uses:
    var addIn = myself.getAddIn("colType",colType);
    addIn.call(td,state,myself.getAddInOptions("colType",addIn.getName()));
From this point on, there will be a new colType available to register.

 Implemented AddIns:

  • sparkline
  • pvSparkline
  • dataBar
  • trendArrow
  • hyperlink

Here's some screenshots for the implemented addins. More details under cde_samples in the solution repository after installing ctools:

  All credits to Brandon Jackson for sponsoring this huge develpment!  /bow!

No comments:

Post a Comment