In-Depth Analysis of API Features in Web and Node Charting Libraries

Table of Contents

Background

We want to review the API available for the web and Node with current charting libraries.

  • determine what the configuration would need to to render the standard dataframes for any of the charting packages

In order to perform this review we need to look at the base scaffolding for each of the libraries.

Assume we just want to plot a basic line chart with some of the heading information but will significant control over the rendering of the application so the same dataset could be be applied to a different chart with a slight modification to the configuration

The default data for the chart should just be something like the following:

  {
    "labels": [],
    "datasets": []
  }

Anything else required for the chart display or rendering should be able to be external.

Nomenclature

We want to have a standard nomenclature for the ways that most of the libraries deal with the base case of rendering two or more sets of data on a line chart.

Labels String[]

  • labels
  • header
  • metadata (colName)

DataSets: Object[]

Swagger

  swagger: '2.0'
  info:
    version: 0.0.1
    title: Charting support
    description: Charting, D3, C3, Charts.js
  x-host: 'localhost:8080'
  schemes:
    - https
  consumes:
    - application/json
  produces:
    - application/json

  paths:
    /:
      get:
        summary: Scaffolding for Data
        responses:
          '200':
            description: Successful Operation
            schema:
              $ref: '#/definitions/Data'

  definitions:
    Data:
      title: Data
      description: Transformable, non-library specific, data used by all implementations
      type: object
      required:
        - labels
        - datasets
      properties:
        labels:
          type: array
          items:
            type: string
        datasets:
          type: array
          items:
            type: object


Input

Some of these are likely available elsewhere but value could be obtained by packaging up the dependencies and ensuring that all the libraries work well together.

  • JSON
  • readTsv
  • readCSV
  • readResultSet

Libraries

Chart.js (datasets)

Can consume a base structure like the following

  var ctx = document.getElementById("myChart").getContext('2d');
  var myChart = new Chart(, {
    type: 'line',
    data: {
      datasets: [
        {
          data: source.map(e => e)
        }
      ],
      labels: source.map(e => `e${e}`)
    }
  });


Google (addRows())

This isn't seriously being considered but the APIs from Google generally have fairly broad coverage.

        var chart = new google.visualization.LineChart(document.getElementById('chart_div'));

  let data = new google.visualization.DataTable();
  data.addColumn('string', 'date');
  data.addRows([
    [
        "2016-10-03"

    ]
  ]);
  chart.draw(data, {});


C3 (columnsz)

This doesn't seem like obvious syntax for either the x or the axis. The specs for the library have a fair number of tests around axis-spec.js .

  {
    data: {
      x : 'date',
      columns: [
        ['date', '2013-01-01', '2013-01-02', '2013-01-03'],
        ['data1', 30, 200, 100],
        ['data2', 130, 300, 200]
      ]
    },
    axis : {
      x : {
        type : 'timeseries'
      }
    }
  }

Frappé (datasets)

This seems like a reasonable implementation where data is explicitly not part of the core

  let data = {
    labels: ["12am-3am", "3am-6am", "6am-9am", "9am-12pm",
      "12pm-3pm", "3pm-6pm", "6pm-9pm", "9pm-12am"],

    datasets: [
      {
        title: "Some Data",
        values: [25, 40, 30, 35, 8, 52, 17, -4]
      },
      {
        title: "Another Set",
        values: [25, 50, -10, 15, 18, 32, 27, 14]
      },
      {
        title: "Yet Another",
        values: [15, 20, -3, -15, 58, 12, -17, 37]
      }
    ]
  };

echarts (series)

Uses multiple invocations to push data or to set options against the chart using series as the core holder of a second data element.

  chart.setOption({
    title: {},
    legend: {},
    xAxis: {
      data: ['']
    },
    series: [
      null,  // xAxis.data?
      {
        name: 'line',
        type: 'line',
        stack: 'all',
        symbol: 'circle',
        data: [12345], // data
      }
    ]
  });


Plotly (traces)

The Node.js version is useful for generating static rendering of the data. The imported version wasn't tested thoughly.

Data is given as an sequence of traces that include some metadata about their rendering.

This is invoked simply with something like the following.

  const traces = [ // qua data
    {
      name: '',
      x: [],
      y: []
    }
  ];
  const options = {};
  const cb = (err, msg) => {};
  plotly.plot(traces, options, cb)

Features

Ignoring some of the charts that don't seem relevant to primary use cases (i.e., not considering area, bubble, guage, heatmap, polar, radar).

Feature Chart.js C3 Frappé
Chart: Line      
Chart: Bar      
Chart: Stacked      
Chart: Pie      
Chart: Doughnut      
Chart: Scatter      
Zoom      
Axis      
Line: Fill      
Events      
Grids      

Author: Jason Walsh

j@wal.sh

Last Updated: 2025-07-30 13:45:27

build: 2025-12-23 09:12 | sha: e32f33e