gatsby-theme-dashbored

0.2.0 • Public • Published

Dashbored

Version Download Bundle size Top Language License

Dashbored is a Gasby plugin that creates boring* data dashboards using simple configuration. It's quick and painless and allows you to focus on the data fetching and queries rather than UI.

* Static.

  • Built on Gatsby, so use any other plugins
  • It's static, run gatsby build to refetch the data and build a new version of the dashbored, means its super fast.
  • Easily connect to your SQL database via Knex, or just call an API as your datasource.
  • Powerful and beautiful data visualisation using Nivo.
  • Building in configuration and simple queries means anyone who knows SQL can contribute to your dashbored.

View the demo

Install

For new projects you can either use the gatsby cli or just initialise a new project with yarn/npm:

yarn init -y
yarn add gatsby gatsby-theme-dashbored

For existing gatsby projects, you can simply install the Gatsby dashbored theme:

yarn add gatsby-theme-dashbored

Getting Started

Step 1.

If you haven’t got a gatsby-config.js file already, create an empty one and add the dashbored's theme:

// gatsby-config.js
module.exports = {
  siteMetadata: {
    title: `Gatsby`,
    siteUrl: `https://www.gatsbyjs.org`,
    description: `Blazing fast modern site generator for React`,
  },
  __experimentalThemes: [
    {
      resolve: 'gatsby-theme-dashbored',
      options: { queryFile: './queries.js' },
    },
  ],
}

Step 2.

Then create the file queries.js at the root of your project:

// queries.js
const fetch = require('node-fetch')

module.exports = [
  {
    title: 'Knowledge of the Beers',
    default: true,
    queries: [
      {
        name: 'Number of beers',
        type: 'number',
        query: () =>
          fetch('https://api.punkapi.com/v2/beers')
            .then(res => res.json())
            .then(json => json.length)
            .then(l => ({ value: l })),
      },
    ],
  },
]

Your first Dashbored is ready to go!

Note: For the above example to work you'll need to add node-fetch as a dependency in your project:

yarn add node-fetch

Step 3.

Add the following script in your package.json:

// package.json
{
  "scripts": {
    "develop": "gatsby develop"
  }
}

Step 4.

Now you can launch your dashbored, enter the command below and it should be available at http://localhost:8000:

yarn develop

Querying data

The example above is nice and easy but in the real world you'll probably want to run your queries on a Database. There are 2 options for that.

SQL queries with knex

If you are using an SQL based DB (PostgresSQL, MySQL, ...), you can connect by passing a knexConfig object into the theme's config.

This opens 2 ways of querying data:

  • You can simply pass a query as a simple string
  • You can pass a function that receives a knex instance as a parameter

As a simple string

// queries.js
{
  [...],
  queries: [{
    name: 'Number of users',
    type: 'number',
    query: `SELECT COUNT(users.id) FROM users`
  }]
}

As a function

// queries.js
{
  [...],
  queries: [{
    name: 'Number of users',
    type: 'number',
    query: db => db('users').count('*')
  }]
}

Passing the data as a function

If you are not using an SQL database or simply prefer to handle the connection on your end, you can pass the data as a function:

// queries.js
{
  [...],
  queries: [{
    name: 'Number of users',
    type: 'number',
    query: () => Users.count()
  }]
}

The shape of the queryFile


Your query file should be a js file that exports an array of objects. Each object represents a page in your dashbored.

// queries.js
module.exports = [
  {
    title: 'Page 1',
    default: true,
    queries: [
      /*your queries*/
    ],
  },
  {
    title: 'Page 2',
    queries: [
      /*your queries*/
    ],
  },
]

In the example above, Page 1 will be your index/homepage (/). If multiple pages with default: true are present, the last one will overwrite the previous pages.

queries field

This field will contain all of the queries for the page. It's an array of objects, each object being a widget.

There is for now 4 type of widgets:

  • Simple number
  • Pie chart
  • Bar chart
  • Line chart
  • Scatter Plot

Mandatory fields

Every widget object should contains this fields:

name

  • type: string
  • description: Name of the widget

type

  • type: ["number", "pie", "bar", "line", "scatter"]
  • description: Type of the widget

query

  • type: string/function
  • parameter
    • db: knex instance
  • description: query/data of your widget

The nivoConfig allows you to customize the library we are using for data visualization nivo, you can find their amazing docs on their website.

Each type of widget has optional fields and expects a specific structure for your query data:

Widgets

Number

  • options: none

structure of the data expected:

const data = {
  value: number,
}
// OR
const data = [
  {
    value: number,
  },
]

Example

// queries.js
module.exports = [
  {
    title: 'Unicorns',
    default: true,
    queries: [
      {
        name: 'Number of unicorns',
        type: 'number',
        query: () => [{ value: 42 }],
      },
    ],
  },
]

Pie

nivo doc

Structure of the data expected:

const data = [
  {
    id: string | number,
    label: string | number,
    value: number,
  },
]

Example

// queries.js
module.exports = [
  {
    title: 'Unicorns',
    default: true,
    queries: [
      {
        name: 'Species of unicorns',
        type: 'pie',
        query: () => [
          { id: 'gingercorn', label: 'Gingercorn', value: 1 },
          { id: 'blondecorn', label: 'Blondecorn', value: 1 },
          { id: 'invisiblecorn', label: 'Invisiblecorn', value: 1 },
          { id: 'flycorn', label: 'Flycorn', value: 1 },
          { id: 'popcorn', label: 'Popcorn', value: 1 },
        ],
      },
    ],
  },
]

Bar

nivo doc

Structure of the data expected:

const data = [
  {
    id: string | number,
    label: string | number,
    value: number,
  },
]

Example

// queries.js
module.exports = [
  {
    title: 'Unicorns',
    default: true,
    queries: [
      {
        name: 'Average lifespan of each species',
        type: 'bar',
        query: () => [
          { index: 'Gingercorn', value: 100 },
          { index: 'Blondecorn', value: 63 },
          { index: 'Invisiblecorn', value: 13 },
          { index: 'Flycorn', value: 45.5 },
          { index: 'Popcorn', value: 42 },
        ],
      },
    ],
  },
]

Line

nivo doc

Structure of the data expected:

const data = [
  {
    id: string | number,
    data: [{ x: number | string | Date, y: number | string | Date }],
  },
]

In the case of Line and Scatter, you can pass the data with two different structures. You can directly send the correctly formatted data in one query or send multiple queries in Tuples(see line example below). [id: string, data: fn]

If you send the array of Tuples, Dashbored will convert this into the expected data structure for you.

Example

// queries.js
module.exports = [
  {
    title: 'Unicorns',
    default: true,
    queries: [
      {
        name: 'Average population by species over the month',
        type: 'line',
        query: [
          [
            'Gingercorn',
            () => [
              { x: '2019-12-01', y: '12' },
              { x: '2019-12-06', y: '23' },
              { x: '2019-12-12', y: '76' },
              { x: '2019-12-18', y: '62' },
              { x: '2019-12-24', y: '22' },
              { x: '2019-12-30', y: '42' },
            ],
          ],
          [
            'Blondecorn',
            () => [
              { x: '2019-12-01', y: '4' },
              { x: '2019-12-06', y: '2' },
              { x: '2019-12-12', y: '12' },
              { x: '2019-12-18', y: '54' },
              { x: '2019-12-24', y: '90' },
              { x: '2019-12-30', y: '42' },
            ],
          ],
          [
            'Invisiblecorn',
            () => [
              { x: '2019-12-01', y: '45' },
              { x: '2019-12-06', y: '65' },
              { x: '2019-12-12', y: '32' },
              { x: '2019-12-18', y: '23' },
              { x: '2019-12-24', y: '67' },
              { x: '2019-12-30', y: '42' },
            ],
          ],
          [
            'Flycorn',
            () => [
              { x: '2019-12-01', y: '4' },
              { x: '2019-12-06', y: '7' },
              { x: '2019-12-12', y: '52' },
              { x: '2019-12-18', y: '22' },
              { x: '2019-12-24', y: '22' },
              { x: '2019-12-30', y: '42' },
            ],
          ],
          [
            'Popcorn',
            () => [
              { x: '2019-12-01', y: '42' },
              { x: '2019-12-06', y: '42' },
              { x: '2019-12-12', y: '42' },
              { x: '2019-12-18', y: '42' },
              { x: '2019-12-24', y: '42' },
              { x: '2019-12-30', y: '42' },
            ],
          ],
        ],
      },
    ],
  },
]

Scatter

nivo doc

Structure of the data expected:

const data = [
  {
    id: string | number,
    data: [{ x: number | string | Date, y: number | string | Date }],
  },
]

In the case of Line and Scatter, you can pass the data with two different structures. You can directly send the correctly formatted data in one query or send multiple queries in Tuples(see line example above). [id: string, data: fn]

If you send the array of Tuples, Dashbored will convert this into the expected data structure for you.

Example

// queries.js
module.exports = [
  {
    title: 'Unicorns',
    default: true,
    queries: [
      {
        name: 'Earthquakes in time',
        type: 'scatter',
        nivoConfig: {
          yScale: {
            type: 'linear',
            min: 5.5,
            max: 'auto',
          },
          xScale: {
            type: 'time',
            format: '%m/%d/%Y',
            precision: 'day',
          },
        },
        query: () => [
          { id: 'Pompei disaster', data: [{ x: '12-31-2019', y: 6 }] },
          { id: 'Pompei disaster, The return of the ash', data: [{ x: '12-12-2012', y: 10 }] },
          { id: 'Pompei disaster, A new ash', data: [{ x: '09-12-2015', y: 6.4 }] },
        ],
      },
    ],
  },
]

Generic options

nivoConfig

allow you to change the default nivo config use for each nivo component (every component except number)

columns

Allow you to change the number of column used by the widget based on screen's width. Dashbored is responsive, it means that the number of columns is based on breaking points.

mobile (1 column): < 737px tablet (4 columns): <= 1025px desktop (6 columns): > 1025px

To let you customize the size of the widget you can send an object looking like this:

{
  mobile: 1,
  tablet: 4,
  desktop: 6
}

This is the default value for each breakpoints and widgets:

Tables Number Pie Bar Line Scatter
mobile 1 1 1 1 1
tablet 1 2 2 2 2
desktop 1 3 6 6 6

rows

Allow you to change the number of rows used by the widget. Dashbored creates as many row as needed. A row is 225px. The behavior is the same as columns.

This is the default value for each breakpoints and widgets:

Tables Number Pie Bar Line Scatter
mobile 1 3 4 4 4
tablet 1 2 3 3 3
desktop 1 2 2 2 2

shortLabel

Allow to show a shorter version of your label.

{
  shortLabel: 4 // will substring your label to the first 4 characters.
}

If you overwrite the nivoConfig, this property might have no effect. For each widget that use shortLabel, this is the property affecte by shortLabel:

  • number: none
  • pie: radialLabel
  • bar: axisBottom
  • line: axisBottom
  • scatter: axisBottom

Caveats

Dev Mode watch

Right now the dev mode of gatsby doesn't rebuild when your changing your query file. In the future we'll try to create a Gatsby plugin to add the file in the watchlist.

Nivo labels

Gatsby-config doesn't pass function to the templates (the reason is because the config is stringified). For Dashbored, it means you won't be able to pass functions for the label's format of your widget. tooltips, legends, ...

Running the Examples

Installation

This repo uses yarn workspaces to handle dependencies, so run yarn at the root of the repo.

yarn

Run the example (/packages/dash)

To run scripts in a workspace, use the yarn workspace command.

yarn workspace dash develop

Package Sidebar

Install

npm i gatsby-theme-dashbored

Weekly Downloads

0

Version

0.2.0

License

MIT

Unpacked Size

29.9 kB

Total Files

18

Last publish

Collaborators

  • wcastand