Overview

All components that extend the Base Component, including the Dashboard Component can receive data in three ways, depending on how the component (or the dashboard) is configured:

Raw Data

Raw data is passed via the data prop. If the data is in the correct format, as specified by the component specification, it will be rendered as is.

example:

{
  type: 'chart',
  settings: {
    x: 'val',
    y: 'key'
    // ...
  },
  data: [
    [{key: 'a', val: 1}, {key:'a', val: 2}, {key: 'a', val: 3}]
  ]
}

Here data is a an array containing a single series which represents variable a as a linear progression. Note that the series is contained as an array, as expected by most of our components. See Data Format.

Backends

example:

{
  // ... other component configuration
  data: {
    type: 'backend',
    backend: 'CSV',
    url: '/path/to/your.csv'
    // delimeter: '\t' // optionally specify a 
  }
}

Data can fetched using one of the existing data backends. Currently, react dashboard supports the following backends:

Custom Data Handlers

Data handlers allow you to write custom code to determine how to generate component data or dashboard data.

An example of a component that uses a data handler to generate its data:

in settings.js:

{
  // ...other component configuration
  dataHandlers: [
    {
      name: getCustomData,
      fields: ['field1', 'field2']
    }
  ]
}

in customDatahanders.js

getCustomData: function (componentData, dashboardData, handler, e, appliedFilters, pipelineData) {
  let _data = dashboardData;
  let fields = handler.fields;
  return  _.data.map(row => {
    let newRow = {};
    fields.forEach(field => {
        newRow[field] = row[field];
    });
    return newRow;
  });
}

In this example, we tell our component to use a custom datahandler called getCustomData. We use an array of field names to select a subset of the dashboard’s global data. See datahandler settings object amd datahandler paramaters below:

datahandler settings object

Datahandlers are defined in settings.js as an object with a unique name paramter. Dot notation can be used in the name to provide structure to your library of datahandlers, if needed.

All paramters except for name will be passed to the datahandler function as paramaters to the handler argument, and can be used example:

// in settings.js
{
  type: 'metricComponent'
  dataHandlers: [
    {
      name: 'anotherCustomeHandler',
      arg1: {foo: 'bar', bar: 'baz'},
      arg2: [1,2,3],
      // etc - any valid javascript/json data can be passed to the data handler
    }
  ]
}

These attributes can now be used within anotherCustomHandler by accessing handler.arg1, handler.arg2, etc.

datahandler paramaters

Data handler functions receive the following paramaters:

  • componentData - any data set on the calling component
  • dashboardData - also known as globalData, data set at the top level of the dashboard
  • handler - the handler object as defined in settings.js. All paramaters, except the required name paramter will be properties of this object, accessible inside the handler’s scope
  • e - if the datahandler is called after an action, the jevascript event which fired the action. Useful for handling filter events and user interactions which update data. See Actions
  • appliedFilters - Any filters which have been applied on the dashboard. See Actions
  • pipelineData - If the component has defined an array of datahandlers, subsequent datahandlers will be passed the return value from the previous handler, otherwise undefined. See chaining

chaining

Data handlers can be chained, in which case the return value from each handler is passed to the following handler in the chain as pipelineData. A trivial example follows:

// assume that globalData is as follows:
{
    seriesOne: [{key: 1, val: 1}, {key: 1, val: 2}, {key: 2, val:2 }],
    seriesTwo: [{key: a, val: 11}, {key: b, val: 2}, {key: c, val:6 }]
    // ...
}

// settings.js
{
  type: 'Metric',
  dataHandlers: [
    {
      name: 'getSeriesByIndex',
      index: 'seriesOne'
    },
    {
      name: 'addOne',
      x: 'val'
    },
    {
      name: 'double',
      x: 'val'
    }
  ]
}

// customDatahandlers.js
/**
 * returns keyed data from globalData
 **/
function getSeriesByIndex(componentData, dashboardData, handler, e, appliedFilters, pipelineData) {
  return [globalData[handler.index]]
}

/**
 * Adds one to all values
 **/
function addOne(componentData, dashboardData, handler, e, appliedFilters, pipelineData) {
  // check for pipeline data first, or use componentData if exists
  let _data = pipelineData || componentData || [];
  _data.map(series => {
    series.forEach(row => {
      row[handler.x] = row[handler.x]*2
    });
    return series;
  }) 
}

I’ll leave it as an excercise for you to implement the double dataHandler :)

registering data handlers

In order for everything to work, data handlers must be registered as follows:

// customDatahandlers.js
import DataHandler from 'react-dash';

function exampleHandler(componentData, dashboardData, handler, e, appliedFilters, pipelineData) {
  // ... your handler code
}

DataHandler.set('exampleHandler', exampleHandler);

// OR:
let handlers = {
  handler1: function(componentData, dashboardData, handler, e, appliedFilters, pipelineData) {
    // ... your code
  },

  handler2: function (componentData, dashboardData, handler, e, appliedFilters, pipelineData) {
    // ... your code
  },

  // ...
}

for (let k in handlers) {
  DataHandler.set(k, customDataHandlers[k]);
}

@@TODO Provided Data Handlers