For Developers

Table of contents

Introduction

It's easy to build real-time data-driven visualisations, or add analytics to your existing applications. We provide a hosted back-end with analytics capabilities, into which you can load your data via a RESTful API.

If you want to modify your visualisation's appearance beyond what our UI allows, you can clone the dataseed-visualisation repo on Github - it's written entirely in js and provided as open source under the GPL2 license.

Benefits

  • Powerful cloud-hosted OLAP analytics engine

  • Support for real-time data streams

  • RESTful JSON API for importing and querying data

  • Open-source javascript front-end, built with backbone.js, gulp, bootstrap - all the good stuff

  • SVG charts build with d3.js and dc.js

  • Versatile multi-dimensional data model

  • Statistical operations including mean, min, max, variance, sum of squares and standard deviation

  • Responsive and ready for desktop / tablet / mobile

  • Paid support plans, custom development, training, and consultancy are available - just ask

Getting Started

Glossary

  • Dataset - like a table. Each column in the table is a field and each row an observation
  • Field - A "column" in the Dataset
  • Observation - A "row" in the Dataset
  • Measure - A type of Field used in a chart as a numeric value, optionally aggregated (e.g. distance driven by a vehicle)
  • Dimension - A type of Field used in a chart as a non-numeric dimension (e.g. a vehicle's model or make)
  • Visualisation - A set of Elements using the Measures and Dimensions from the Visualisation's Dataset
  • Element - A component of a Visualisation such as a chart or aggregate summary
  • Chart - A graphical representation of a Measure and a Dimension (e.g. Number of miles driven by vehicle model)

Embedding visualisations

The simplest way to embed a visualisation is to use the "Export" button on your visualisation's toolbar. You will be provided with a snippet of HTML that you can copy-and-paste into your site.

For help on more advanced embedding, providing full control of the visualisation's appearance, have a look at the Javascript Library.

Importing data through the API

The easiest way to add data through the API is by providing the URL of a dataset file to the Dataseed Import API

Another option is to create a dataset then add observations (rows). To create a dataset, you can either use the UI to import a spreadsheet, or use the POST /dataset API call. To add observations, use the POST or PUT /observations API call.

For full details please see the Dataseed API documentation

Drupal

For easy Drupal integration check out the Dataseed module on drupal.org

Javascript Library

The Dataseed-visualisation Javascript Library allows visualisations to be integrated with existing Javascript applications. A working knowledge of Javascript is necessary to use the library, for a simpler method of including visualisations on your site see Basic Embedding.

The library consists of models and views for fetching and rendering visualisations built on the Backbone.js framework with RequireJS used for module and dependency handling.

Dependencies

The library uses the Node.js platform for building the JS and related tasks. You can install Node.js using the packages on the download page or through your OS's package manager.

Setup & Build

The README on Github contains the latest instructions for setting up and building the project. The build process is managed by Gulp and includes Javascript aggregation and minification, LESS compilation, and jasmine tests. To run the build use:

gulp

Modifying code

Only modify js or css code in the "src" directory. In order to view your changes in a browser immediately without having to build, you will need to run a web server. We have provided one using the gulp-connect plugin, just run the below command and load http://localhost:8080/index-src.html in your browser.

gulp serve

Example

The following example demonstrates a simple web application that renders a visualisation when a user clicks a button:

<!doctype html>
<html dir="ltr" lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>Dataseed Interactive Data Visualization</title>
    <meta name="viewport" content="width=device-width" />
    <link href="src/less/dataseed.less" rel="stylesheet/less" type="text/css" />
    <script src="src/js/components/less/dist/less-1.7.5.js"></script>
  </head>
  <body>
    <button id="start">Show me the visualisation!</button>
    <div id="vis"></div>
    <script src="src/js/components/requirejs/require.js"></script>
    <script>
        require(['src/js/config'], function() {
            require(['jquery', './views/dataset', 'app'], function($, DatasetEmbedView) {
                $('#start').click(function() {
                    new DatasetEmbedView({
                        'el': $('#vis'),
                        'id': 'mortality',
                        'visualisation_id': '1'
                    });
                });
            });
        });
    </script>
  </body>
</html>

Architecture

Dataseed uses a standard Model/Collection/View backbone architecture where each model has an associated view for rendering and groups of models are stored together in collections. The most important components of Dataseed are listed below along with brief explanations. For more information please see the full code on Github or get in touch.

Dataset Model src/js/models/dataset.js The dataset model owns the visualisation model and handles filtering of data.
View src/js/views/dataset.js The dataset view owns the visualisation view and initiates rendering.
Visualisation Model src/js/models/visualisation.js The visualisation model owns the collection of elements (i.e. charts) and handles filtering events (addCut and removeCut) by passing them on to the dataset model.
View src/js/views/visualisation.js The visualisation view handles add, removing, re-ordering and rendering of the visualisation elements. For each element model in the elements collection a corresponding element view is created.
Elements Collection src/js/collections/elements.js The elements collection owns all the element models in a visualisation. It uses the polymorphic models pattern to keep both DimensionalElements (charts with a dimension and measure) and MeasureElements (charts with only a measure).
Element Model src/js/models/visualisation/element.js The element model fetches visualisation data through the ConnectionPool collection. It is also responsible for building chart labels/tooltips, sending filter events and providing methods to help charts interrogate the data, for example, but checking if a particular dimension is currently being filtered.
View src/js/views/element.js The element view is used to create the actual chart views and delegates all rendering to them.
Chart View src/js/views/element/d3/chart.js The base chart view is inherited by the various chart types (e.g. the bubble chart). It provides basic rendering of the chart container (title, margins, etc) as well as methods to help with filtering and styling individual charts.

Authentication

To allow embedding of private visualisations without revealing your username and password a separate HMAC-based authentication method is available. To use this authentication method you will need a way to sign messages for your users, i.e. the ability to run code server-side.

Before you start you'll need your user_token and user_key values, which can be found on your profile page. WARNING: Your user_key should never be revealed (e.g. by including it in your HTML or javascript). Anyone with access to your user_key can use it to see your private data!

The process for authenticating a user's request to an embedded visualisation is as follows:

  1. The user's browser makes a request to your site
  2. Your site calculates an auth message and HMAC and returns these to the user, along with the embedded visualisation
  3. When the dataseed javascript executes in the user's browser it will request data from dataseed using the credentials provided
  4. Dataseed will return the requested data to the user, as long as the following conditions are met:
    • The auth message is in the correct format
    • The requested dataset_id is owned by your dataseed account
    • The auth message hasn't expired
    • The HMAC is valid

The authentication message is a base64 encoded JSON object with the following keys:

  • user - Your user_token
  • dataset - Your dataset's ID
  • filters - An object containing mandatory filters on your data
  • timestamp - A unix timestamp (in UTC) indicating when the message was created

An example authentication message, before base64ing:

{
    "user": "xxx",
    "dataset": "xxx",
    "filters": {},
    "timestamp": 471484800
}

After you've calculated the auth message and HMAC (see the PHP and Python examples below) they should be included in the page after the dataseed javascript but before initialising the embedded visualisation:

require.config({
    'config': {
        'models/authSingleton': {
            'AUTH': {
                'msg': 'TGFzdCBDaHJpc3RtYXMgSSBnYXZlIHlvdSBteSBoZWFydCBCdXQgdGhlIHZlcnkgbmV4dCBkYXkgeW91IGdhdmUgaXQgYXdheS4gVGhpcyB5ZWFyIFRvIHNhdmUgbWUgZnJvbSB0ZWFycyBJJ2xsIGdpdmUgaXQgdG8gc29tZW9uZSBzcGVjaWFsCg==',
                'hmac': 'TWF5YmUgbmV4dCB5ZWFyIEknbGwgZ2l2ZSBpdCB0byBzb21lb25lIEknbGwgZ2l2ZSBpdCB0byBzb21lb25lIHNwZWNpYWwK'
            }
        }
    }
});

PHP

<?php

// Set your own values here
$user_token = 'xxx';
$user_key = 'xxx';
$dataset_id = 'xxx';

// Check hash extension is available
if (!function_exists('hash_algos') || !function_exists('hash_hmac') || !in_array('sha512', hash_algos())) {
    die('Please install the PHP hash extension ensuring the SHA512 hash function is enabled: http://php.net/manual/en/book.hash.php');
}

// Build authentication message
$msg = new StdClass();
$msg->user = $user_token;
$msg->dataset = $dataset_id;
$msg->filters = new StdClass();

// Get message timestamp in UTC
$tz = date_default_timezone_get();
date_default_timezone_set('UTC');
$msg->timestamp = time();
date_default_timezone_set($tz);

// Encode message for transport and hashing
$msg = base64_encode(json_encode($msg));

// Calculate HMAC and encode for transport
$msg_hmac = base64_encode(hash_hmac('sha512', $msg, $user_key, TRUE));

// Print config JSON
$config = json_encode(array(
    'config' => array(
        'models/authSingleton' => array(
            'AUTH' => array(
                'msg' => $msg,
                'hmac' => $msg_hmac
            ),
        ),
    ),
));
print "<script>require.config($config);</script>";

Python

import json
import hashlib
import hmac
from time import time
from binascii import b2a_base64
from base64 import b64encode

# Set your own values here
user_token = 'xxx'
user_key = 'xxx'
dataset_id = 'xxx'

# Build authentication message
msg = {
    'user': user_token,
    'dataset': dataset_id,
    'filters': {},
    'timestamp': time(),
}

# Encode message for transport and hashing
msg = b64encode(json.dumps(msg)).encode('utf-8')

# Calculate HMAC and encode for transport
hashed = hmac.new(user_key.encode('utf-8'), msg, hashlib.sha512)
msg_hmac = b2a_base64(hashed.digest())[:-1]

# Print config JSON
config = json.dumps({
    'config': {
        'models/authSingleton': {
            'AUTH': {
                'msg': msg,
                'hmac': msg_hmac,
            },
        },
    },
})
print '<script>require.config(%s);</script>' % config

Styles

To change text and background colours in the visualisation model an array of styles is used. Each style is represented in the array as an object with a style ID and value.

For example, to set the colour for the heading text of every chart in a visualisation the model should contain:

{
    "id": "1",
    "label": "My Visualisation",
    "elements": [
        // ...
    ],
    "styles": [
        {
            "id": "heading",
            "value": "#f00"
        }
    ]
}

The full list of styles is shown in the table below. To style the visualisation in other ways (e.g. changing the font) the required elements can be targeted by your own CSS in the usual way.

ID Default Description
visualisationBackground #fff Background colour for the visualisation
background #f5f6f9 Background colour for the charts
heading #566573 Chart heading text colour
featureFill #72bd49 Chart feature (e.g. bars or lines) colour
featureFillActive #88939d Colour for inactive features when a chart is cut (i.e. features without a cut)
featureStroke #fff Chart feature outline colour
featureStrokeActive #fff Chart inactive feature outline colour
label #2c3e50 Chart label text colour
scaleFeature #2c3e50 Scale/axis line colour
scaleLabel #2c3e50 Scale label text colour
measureLabel #2c3e50 Measure label text colour
choroplethMin #fff Map feature (e.g. a country or a state) start colour
choroplethMax #000 Map feature end colour
choroplethStroke #000 Map feature outline colour
choroplethStrokeWidth 1 Map feature outline width

Add New Chart

When using the embedded JS you can create new chart types as well as using the standard chart types. The process to create a new chart type is:

  1. Create a Backbone view that implements a render method. Whenever data is received (during the initial page load or when a cut is applied) the render method will be called to output the HTML/SVG for the chart.
  2. Add your new view class to the ElementView chart types object in ElementView.prototype.chartTypes
  3. Set the chart type in your element's model

In your chart view's render method you have access to its associated model which has a number of useful methods:

  • getObservations - Returns an array of all observations
  • hasCutId - Check if the visualisation is cut on the supplied dimension member ID
  • featureClick - Cut the visualisation on the supplied value

When creating new chart types it can be useful to extend the ChartView class as it contains a number of useful methods for dealing with cuts and styles.

The example below shows how to create a basic "list" type chart. Each observation is rendered as a link that can be clicked to cut on it.

<!doctype html>
<html dir="ltr" lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>Dataseed List Chart Example</title>
    <meta name="viewport" content="width=device-width" />
    <link href="src/less/dataseed.less" rel="stylesheet/less" type="text/css" />
    <script src="src/js/components/less/dist/less-1.7.5.js"></script>
    <style type="text/css">
        /* Highlight the currently cut dimension in our chart */
        .mylistElement .cut {
            font-weight: bold;
        }
    </style>
  </head>
  <body>
    <div id="vis"></div>
    <script src="src/js/components/requirejs/require.js"></script>
    <script>
      /**
       * Define a basic visualisation model consisting of
       * a summary element as well as our new chart type
       */
      require.config({
       "config": {
           "models/datasetSingleton": {
               "DATASET": {
                   "id": "mortality",
                   "label": "Mortality",
                   "fields": [
                        {"id": "year", "label": "Year", "type": "string"},
                        {"id": "value", "label": "Value", "type": "integer"}
                    ],
                    "visualisations": [
                        {
                            "id": "1",
                            "label": "Mortality in England and Wales",
                            "description": "Explore and compare the number of deaths by disease, sex, area and year",
                            "elements": [
                                {
                                    "id": "sum0",
                                    "type": "summary",
                                    "label": "Total",
                                    "measure_label": "Number of deaths",
                                    "aggregation": "sum",
                                    "measure": {"id": "value"},
                                    "dimensions": [{"field": {"id": "year", "type": "string"}}],
                                    "width": 4,
                                    "height": 1
                                },
                                {
                                    "id": "chart0",
                                    "type": "mylist",
                                    "label": "My List Chart",
                                    "measure_label": "Number of deaths",
                                    "aggregation": "sum",
                                    "measure": {"id": "value"},
                                    "dimensions": [{"field": {"id": "year", "type": "string"}}],
                                    "width": 4,
                                    "height": 6
                                }
                            ]
                        }
                    ]
                } // end "DATASET"
            }
        } // end "config"
    });

    require(['src/js/config'], function() {
        require(['backbone', 'underscore', 'jquery', './views/element', './views/dataset', 'app'],
            function(Backbone, _, $, ElementView, DatasetEmbedView) {

            /**
             * Create new chart type
             */
            var MyListView = Backbone.View.extend({

                // Chart HTML template
                chartTemplate: _.template('<h2><%- label %></h2><ul></ul>'),

                // Chart item HTML template
                itemTemplate: _.template(
                    '<li class="<%= (cut) ? "cut" : "" %>">' +
                    '   <a href="#" data-id="<%- id %>">' +
                    '       <%- id %>: <%- total %>' +
                    '   </a>' +
                    '</li>'
                ),

                // Chart events
                events: {
                    'click a': 'click'
                },

                /**
                 * Render the chart
                 */
                render: function() {
                    // Render chart heading and populate list with observations
                    this.$el
                        .html(this.chartTemplate(this.model.attributes))
                        .find('ul')
                        .append(_.map(this.model.getObservations(), this.renderItem, this));
                },

                /**
                 * Render chart item
                 */
                renderItem: function(d) {
                    var settings = _.extend({cut: this.model.hasCutId(d.id)}, d);
                    return this.itemTemplate(settings);
                },

                /**
                 * Handle chart click
                 */
                click: function(e) {
                    e.preventDefault();
                    this.model.featureClick({
                        id: $(e.currentTarget).data('id').toString()
                    });
                }

            });

            // Add our chart type to the available types
            ElementView.prototype.chartTypes.mylist = MyListView;

            /**
             * Render the visualisation
             */
            new DatasetEmbedView({el: $('#vis')});
        });
    });
    </script>
  </body>
</html>

REST API

Introduction

The API for Dataseed is implemented as a set of JSON resources (e.g. a Visualisation), each with their own URL. The resources may be read or altered using the standard HTTP verbs. We have tried to follow RESTful principles in the design of the API wherever possible.

The examples in this documentation use the cURL command line tool to interact with the API. If you have cURL installed (Linux and OS X users should have it by default) you can copy and paste the commands into a terminal to see them in action! For authenticated commands you'll need to replace the example account details with your own (see Authentication).

Requests

Requests to the API must always specify an Accept header with the JSON MIME type (i.e. "application/json"). So you could fetch a public dataset using:

curl -H'Accept: application/json' https://dataseedapp.com/api/datasets/mortality

When sending data to the API you must also specify the MIME type of your request using the Content-Type header header. The following example shows how to add an observation to an existing dataset:

curl -u'dataseed@example.com:password' -H'Accept: application/json' -H'Content-type: application/json' https://dataseedapp.com/api/datasets/my-dataset/observations -d'{ "observations": [ { "id": "o1234", "age": "26", "gender": "M" } ] }'

You can also get HTML responses to GET requests made in a browser, e.g. https://dataseedapp.com/api/datasets/mortality

Responses

The are two classes of response returned by the API, indicated by the HTTP status code:

200/300: Success

The request succeeded. When creating or updating resources a 303 code will be returned. The URL the resource should be fetched from is specified in the Location header.

{
    "status": 200,
    "message": "Created"
}
400: Bad Request

The request failed because it was invalid. A general error message will be provided in the returned JSON as well as more specific errors when applicable.

{
    "status": 400,
    "message": "Invalid",
    "errors": {
        "label": "Required",
        "public": "Required"
    }
}

Authentication

All requests must be authenticated except when reading Datasets or Visualisations that are public. Currently, the only supported authentication method is HTTP Basic Authentication. The username and password should be the same ones you use to login with (if you haven't already got an account sign-up for one now).

So, for example, to fetch a private dataset you would do the following:

curl -u'dataseed@example.com:password' -H'Accept: application/json' https://dataseedapp.com/api/datasets/my-dataset

Import

Create

Request
curl -XPOST -u'dataseed@example.com:password' -H'Accept: application/json' -H'Content-type: application/json' https://dataseedapp.com/api/imports/ -d' {"files": [{"key": "http://example.com/example.csv"}], "data": {"label": "remote file example", "public": "true"}}'

The dataset field types can also be set (must be one of "StringType, IntegerType, DecimalType, DateType, DateYearType"). Otherwise they will be guessed.

curl -XPOST -u'dataseed@example.com:password' -H'Accept: application/json' -H'Content-type: application/json' https://dataseedapp.com/api/imports/ -d' {"files": [{"type": "external", "key": "http://example.com/example.csv"}], "data": {"label": "remote file example", "public": "true", "columns": {"0": "StringType", "1": "StringType", "2": "StringType", "3": "IntegerType"}}}'
Response
{
   "status": 303,
   "href": "/api/imports/252b529188c2bdee4c16570a133a329d"
}

Read

By making a GET request to the URL returned in the previous call we can get the status and all the other info related to our import.

Request
curl -u'dataseed@example.com:password' -H'Accept: application/json' -H'Content-type: application/json' https://dataseedapp.com/api/imports/252b529188c2bdee4c16570a133a329d'
Response
{
    "created": "2015-02-04T18:23:05.532800",
      "data": {
        "columns": {
          "0": "DateType",
          "1": "DecimalType"
        },
        "data_row": 2,
        "description": "",
        "header_labels": {
          "0": "Date",
          "1": "Value"
        },
        "header_row": 1,
        "headers": [
          "Date",
          "Value"
        ],
        "label": "label",
        "measure": "rows",
        "numeric_columns": {
          "1": "Value"
        },
        "public": "true",
        "table_set_type": "CSV"
      },
      "files": [
        {
          "key": "http://example.com/example.csv",
          "type": "external"
        }
      ],
      "id": "252b529188c2bdee4c16570a133a329d",
      "status": "completed"

}

Dataset

Read

Request
curl -H'Accept: application/json' https://dataseedapp.com/api/datasets/mortality
Response
{
    "id": "mortality",
    "label": "Mortality",
    "public": true,
    "imports": [],
    "fields": [
        {"id": "year", "label": "Year", "type": "string"},
        {"id": "gender", "label": "Gender", "type": "string"},
        {"id": "value", "label": "Value", "type": "integer"}
    ],
    "visualisations": [
        {
            "id": "1",
            "label": "Mortality in England and Wales",
            "description": "Explore and compare the number of deaths by disease, sex, area and year",
            "public": true,
            "elements": [
                {
                    "id": "year",
                    "label": "Year",
                    "measure_label": "Number of deaths",
                    "type": "bar",
                    "aggregation": "sum",
                    "measure": {"id": "value"},
                    "dimensions": [{"field": {"id": "year", "type": "string"}}],
                    "width": 1,
                    "height": 6,
                    "y": 1,
                    "x": 1
                },
                {
                    "id": "gender",
                    "label": "Gender",
                    "measure_label": "Number of deaths",
                    "type": "bar",
                    "aggregation": "sum",
                    "measure": {"id": "value"},
                    "dimensions": [{"field": {"id": "gender", "type": "string"}}],
                    "width": 1,
                    "height": 6,
                    "y": 1,
                    "x": 2
                }
            ],
            "styles": []
        }
    ],
    "modified": "2013-09-06T10:33:39.789859",
    "created": "2013-09-06T10:33:39.789859"
}

Create

Request
curl -XPOST -u'dataseed@example.com:password' -H'Accept: application/json' -H'Content-type: application/json' https://dataseedapp.com/api/datasets/ -d'
{
    "label": "My Vehicle Dataset",
    "public": false,
    "fields": [
        {
            "id": "vehicle",
            "label": "Vehicle",
            "type": "string"
        },
        {
            "id": "miles",
            "label": "Miles",
            "type": "float"
        }
    ]
}'
Response
{
    "status": 303,
    "href": "/api/datasets/252b529188c2bdee4c16570a133a329d"
}

Update

By making a PUT request to the URL returned in the previous call we can make changes to our new dataset.

Request
curl -XPUT -u'dataseed@example.com:password' -H'Accept: application/json' -H'Content-type: application/json' https://dataseedapp.com/api/datasets/252b529188c2bdee4c16570a133a329d -d'
{
    "label": "My Awesome Vehicle Dataset",
    "public": false
}'
Response
{
    "status": 303,
    "href": "/api/datasets/252b529188c2bdee4c16570a133a329d"
}

Delete

Request
curl -XDELETE -u'dataseed@example.com:password' -H'Accept: application/json' https://dataseedapp.com/api/datasets/252b529188c2bdee4c16570a133a329d
Response
{
    "status": 200,
    "message": "Deleted"
}

Visualisation

In the example above we have shown how to use the Dataseed Javascript Library to embed a visualisation within an existing Javascript application. Starting from that example, the following shows how to define a visualisation directly in the context of the consumer application instead of fetching it from Dataseed.

<!doctype html>
<html dir="ltr" lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>Dataseed Interactive Data Visualization</title>
    <meta name="viewport" content="width=device-width" />
    <link href="src/less/dataseed.less" rel="stylesheet/less" type="text/css" />
    <script src="src/js/components/less/dist/less-1.7.5.js"></script>
  </head>
  <body>
    <button id="start">Show me the visualisation!</button>
    <div id="vis"></div>
    <script src="src/js/components/requirejs/require.js"></script>
    <script>
      require.config({
       "config": {
           "models/datasetSingleton": {
               "DATASET": {
                   "id": "mortality",
                   "label": "Mortality",
                   "public": true,
                   "imports": [],
                   "fields": [
                        {"id": "year", "label": "Year", "type": "string"},
                        {"id": "gender", "label": "Gender", "type": "string"},
                        {"id": "value", "label": "Value", "type": "integer"}
                    ],
                    "visualisations": [
                        {
                            "id": "1",
                            "label": "Mortality in England and Wales",
                            "description": "Explore and compare the number of deaths by disease, sex, area and year",
                            "elements": [
                                {
                                    "id": "year",
                                    "label": "Year",
                                    "measure_label": "Number of deaths",
                                    "type": "bar",
                                    "aggregation": "sum",
                                    "measure": {"id": "value"},
                                    "dimensions": [{"field": {"id": "year", "type": "string"}}],
                                    "width": 1,
                                    "height": 6,
                                    "y": 1,
                                    "x": 1
                                },
                                {
                                    "id": "gender",
                                    "label": "Gender",
                                    "measure_label": "Number of deaths",
                                    "type": "bar",
                                    "aggregation": "sum",
                                    "measure": {"id": "value"},
                                    "dimensions": [{"field": {"id": "gender", "type": "string"}}],
                                    "width": 1,
                                    "height": 6,
                                    "y": 1,
                                    "x": 2
                                }
                            ],
                            "styles": []
                        }
                    ],
                    "modified": "2013-09-06T10:33:39.789859",
                    "created": "2013-09-06T10:33:39.789859"
                } // end "DATASET"
            }
        } // end "config"
    });

    require(['src/js/config'], function() {
        require(['jquery', './views/dataset', 'app'], function($, DatasetEmbedView) {
            $('#start').click(function() {
                new DatasetEmbedView({
                    'el': $('#vis'),
                    'id': 'mortality',
                    'visualisation_id': '1'
                });
            });
        });
    });
    </script>
  </body>
</html>

Elements

This section shows the available visualisation elements and how to use them in a visualisation defined in the context of a consumer application.

To be concise, we won't show the whole dataset model in the following examples: we will just provide snippets that can be added to the elements attribute list of the Dataseed visualisation model example above.

Summary

Displays a summary text of the current dataset cut.

{
    "aggregation":"sum",
    // Each dimension will be related to a component of the summary text.
    // The first component is always the aggregated totals.
    "dimensions":[
        {
            "bucket":null,
            "field":{
                "id":"gender",
                "type":"string"
            },

            // Component value. $ is a placeholder for the current dimension cut value
            // (in this case we have suffixed it with 's' in order to make plurals)
            "text_format":"<strong>$s died</strong>",

            // Default summary text component value (displayed when a cut is not
            // set on this dimension)
            "text_default":"people died",

            "weight":1
        },
        {
            "bucket":null,
            "field":{
                "id":"year",
                "type":"string"
            },
            "text_default":"between 2002 and 2011",
            "text_format":"in <strong>$</strong>",
            "weight":4
        }
    ],
    "id":"summary",
    "label":"Number of deaths",
    "measure":{
        "id":"value"
    },
    "measure_label":"Number of deaths",
    "type":"summary",
    "width":4,
    "height":1
}
Filter

Filters let the user add a dimension cut on the visualised dataset through links or drop down selects.

Navigation

The navigation element displays all the dimensions' values as links.

{
    "aggregation":"sum",
    // The links will be displayed within an accordion. Each dimension will be a header.
    "dimensions":[
        {
            "bucket":null,
            "field":{
                "id":"gender",
                "type":"string"
            },
            "weight":1
        },
        {
            "bucket":null,
            "field":{
                "id":"year",
                "type":"string"
            },
            "weight":4
        }
    ],
    "id":"filter",
    "label":"Filter",
    "measure":{
        "id":"value"
    },
    "measure_label":"Number of deaths",
    "type":"navigation",
    "width":4,
    "height":6
}
Chart

Dataseed supports the following chart types:

  • Bar
  • Bubble (Available only on D3)
  • Line

A generic chart visualisation element can be defined by:

{
    "id": "year",
    "label": "Year",
    "measure_label": "Number of deaths",

    // The attribute that defines the chart type to display
    "type": "<CHART_TYPE_HERE>",
    "aggregation": "sum",
    "measure": {"id": "value"},
    "dimensions": [{"field": {"id": "year", "type": "string"}}],
    "width": 1,
    "height": 6
}

where the type attribute can assume one of the following values:

  • bar
  • bubble
  • line
Table

Rather than charting a dimension we might just want to show all its related observations in a sortable table. This is what the Table element is meant to be used for.

{
    "id": "year",
    "label": "Year",
    "measure_label": "Number of deaths",
    "type": "table",
    "aggregation": "sum",
    "measure": {"id": "value"},
    "dimensions": [{"field": {"id": "year", "type": "string"}}],
    "width": 1,
    "height": 6
}

Optional attributes

This section shows all the optional Dataset model attributes that can be defined in a visualisation model.

Dataset
cut

The cut dataset attribute allows to define a cut on the dataset dimensions that has to be applied by default when the visualisation is rendered.

<script>
require.config({
    "config": {
        "models/datasetSingleton": {
            "DATASET": {
                "id": "mortality",
                "label": "Mortality",
                "fields": [
                    {
                        "id": "gender",
                        "label": "Gender",
                        "type": "string"
                    },
                    // Other Dataset fields here ...

                ],
                "cut": {
                    "gender": "F",
                },
                // Other Dataset attributes here ...
            }
        }
    }
});
</script>
Dataset Fields
update_dimension

Related to a dataset's field, this attribute is set to true if the values for the dimensions related to the field need to be fetched every time a cut is applied to the dataset. Otherwise dimension's values are fetched only once, i.e. when DatasetEmbedView() is instantiated.

Default value: False

<script>
require.config({
    "config": {
        "models/datasetSingleton": {
            "DATASET": {
                "id": "mortality",
                "label": "Mortality",
                "fields": [
                    {
                        "id": "year",
                        "label": "Year",
                        "type": "string",
                        "update_dimension": true
                    },
                    // Other Dataset fields here ...

                ],
                // Other Dataset attributes here ...
            }
        }
    }
});
</script>
Visualisation Elements
Charts
interactive

By default a click on a chart element feature (bar/point/etc.) makes a new cut to be added to the dataset. Set this attribute to false in order to make the chart not reacting on the feature click event.

Default value: true

<script>
require.config({
    "config": {
        "models/datasetSingleton": {
            "DATASET": {
                // Dataset attributes here (e.g. fields) ...
                "visualisations": [
                    {
                        "id": "1",
                        "label": "Mortality in England and Wales",
                        // Other visualisation attributes here ...
                        "public": true,
                        "elements": [
                            {
                                "id": "year",
                                "label": "Year",
                                "measure_label": "Number of deaths",
                                "type": "bar",
                                "interactive": false,
                                //Other element attributess here ...
                            },
                            // Other elements here ...
                        ],

                    }
                ]
                // Other dataset attributes here ...
            }
        }
    }
});
</script>
Filters
required

At the moment this attribute is taken into account only by the Filter Form element. It is related to an element's dimension: if it is set to true the element won't let the user unset the cut on the dimension the attribute refers to. This also means that a default cut needs to be defined for a required element dimensions.

Default value: false

<script>
require.config({
    "config": {
        "models/datasetSingleton": {
            "DATASET": {
                // Dataset attributes here (e.g. fields) ...
                "visualisations": [
                    {
                        "id": "1",
                        "label": "Mortality in England and Wales",
                        "public": true,
                        // Other visualisation attributes here ...
                        "elements": [
                            {
                                "id": "year",
                                "label": "Year",
                                "measure_label": "Number of deaths",
                                "type": "navigation",
                                "required": true,
                                //Other element attributes here ...
                            },
                            // Other elements here ...
                        ],

                    }
                ]
                // Other dataset attributes here ...
            }
        }
    }
});
</script>
sort

Defines the order in which the filter options have to be displayed. The value for this attribute is an object in the format {"[attribute]": "[direction]"} where:

  • [attribute] is either "total" or "label"
  • [direction] is either "asc" or "desc"

Default value: {"total": "desc"}

<script>
require.config({
    "config": {
        "models/datasetSingleton": {
            "DATASET": {
                // Dataset attributes here (e.g. fields) ...
                "visualisations": [
                    {
                        "id": "1",
                        "label": "Mortality in England and Wales",
                        "public": true,
                        // Other visualisation attributes here ...
                        "elements": [
                            {
                                "id": "year",
                                "label": "Year",
                                "measure_label": "Number of deaths",
                                "type": "navigation",
                                "sort": {
                                    "label": "asc"
                                },
                                //Other element attributes here ...
                            },
                            // Other elements here ...
                        ],

                    }
                ]
                // Other dataset attributes here ...
            }
        }
    }
});
</script>

Dimensions

Dimensions allow us to store additional meta-data for dimension field values (dimension members). For example your dataset may contain a field "gender" that has values "M" and "F". We can use the Dimension model to associate the labels "Male" and "Female" which will then used by charts in the visualisation automatically.

Read

Request
curl -H'Accept: application/json' 'https://dataseedapp.com/api/datasets/mortality/dimensions/gender'
Response
{
    "gender": {
        "F": {
            "id": "F",
            "label": "Female"
        },
        "M": {
            "id": "M",
            "label": "Male"
        }
    }
}

Create

Creating (POSTing) dimension values will delete any existing dimension values. To append dimension values use PUT.

Request
curl -XPOST -u'dataseed@example.com:password' -H'Accept: application/json' -H'Content-type: application/json' 'https://dataseedapp.com/api/datasets/mortality/dimensions/gender' -d'
{
    "values": [
        {
            "id": "F",
            "label": "Female"
        },
        {
            "id": "M",
            "label": "Male"
        }
    ]
}'
Response
{
    "status": 200,
    "message": "Created"
}

Update

Request
curl -XPUT -u'dataseed@example.com:password' -H'Accept: application/json' -H'Content-type: application/json' 'https://dataseedapp.com/api/datasets/mortality/dimensions/gender' -d'
{
    "values": [
        {
            "id": "F",
            "label": "Female"
        }
    ]
}'
Response
{
    "status": 200,
    "message": "Updated"
}

Delete

Request
curl -XDELETE -u'dataseed@example.com:password' -H'Accept: application/json' 'https://dataseedapp.com/api/datasets/mortality/dimensions/gender'
Response
{
    "status": 200,
    "message": "Deleted"
}

Observations

Read

When requesting observations they are returned aggregated on a particular measure for a particular dimension. The dimension is specified in the URL and the measure with the following GET parameters:

  • measure - The field that contains the measure. This parameter is required unless the aggregation is specified as "rows".
  • aggregation - The aggregation type ("sum", "mean", "min", "max" or "rows"). This parameter is always required.

In the example below we are requesting a "sum" aggregation of the "value" measure for the "gender" dimension.

Request
curl -H'Accept: application/json' 'https://dataseedapp.com/api/datasets/mortality/observations/gender?aggregation=sum&measure=value'
Response
{
    "gender": [
        {
            "id": "F",
            "total": 2645375.0
        },
        {
            "id": "M",
            "total": 2412236.0
        }
    ]
}

To get "unfaceted" aggregations, that is, aggregations that are not related to a dimension's facets, we just have to omit the dimension name from the observations Read URL. For example, if we want to get a sum of the "value" measure across all the dataset's observations and dimensions:

Request
curl -H'Accept: application/json' 'https://dataseedapp.com/api/datasets/mortality/observations/?aggregation=sum&measure=value'
Response
{"total": 5057611.0}

Create

Creating (POSTing) observations will delete all existing entries, to append observations use PUT.

Request
curl -XPOST -u'dataseed@example.com:password' -H'Accept: application/json' -H'Content-type: application/json' 'https://dataseedapp.com/api/datasets/mortality/observations/' -d'
{
    "observations": [
        {
            "id": 0,
            "gender": "M",
            "year": 2008,
            "chapter": "IX",
            "value": 12
        },
        {
            "id": 1,
            "gender": "F",
            "year": 2008,
            "chapter": "IX",
            "value": 18
        }
    ]
}'
Response
{
    "status": 200,
    "message": "Created"
}

Update

To replace existing observations use the same id value. If no id is passed or if the id doesn't exist in the dataset the observation will be added instead.

Request
curl -XPUT -u'dataseed@example.com:password' -H'Accept: application/json' -H'Content-type: application/json' 'https://dataseedapp.com/api/datasets/mortality/observations' -d'
{
    "observations": [
        {
            "id": 0,
            "gender": "M",
            "year": 2008,
            "chapter": "IX",
            "value": 13
        },
        {
            "id": 2,
            "gender": "F",
            "year": 2004,
            "chapter": "IV",
            "value": 31
        }
    ]
}'
Response
{
    "status": 200,
    "message": "Updated"
}

Delete

The request to delete all observations in a dataset is shown below. To delete an individual observation within a dataset make the same request but with the observations's id value appended to the URL (e.g. /api/datasets/mortality/observations/1234).

Request
curl -XDELETE -u'dataseed@example.com:password' -H'Accept: application/json' 'https://dataseedapp.com/api/datasets/mortality/observations'
Response
{
    "status": 200,
    "message": "Deleted"
}
Success tick

Use Dataseed to build your own stunning visualisations

Sign up now to be one of the first to participate in the dataseed beta launch