Skip to content

JSON ViewModel Specification

Mark Hughes (happybeing) edited this page Mar 6, 2020 · 5 revisions

VisLab JSON ViewModel

Here you will find the set of data structures used by Visualisation Lab (VisLab) to simplify the creation of visualisations whether using existing libraries, components or custom code.

Discovering what form to get data into for visualisation is work, so I'm sharing to help others avoid re-inventing this wheel, save people time documenting what they use, and improve interoperability and code maintenance.

Adopting these data structures will simplify the process of constructing a visualisation using common JavaScript visualisation libraries such as Vega, Vega-Lite and D3 or your own custom visualisation component. It should also improve interoperability between systems and libraries, as well as saving time on documentation.

To summarise the benefits of using the VisLab JSON model:

  • no need to invent your own structure, find the appropriate model and adopt that
  • visualise by following an example for your favourite library (examples wanted!)
  • no data structures to document
  • easy code re-use and maintenance

Consider this a potential de-facto standard for visualisation of data using JavaScript, or by all means go your own way! But if you use these structures you should be able to get your data into one of a large range of visualisations with minimum time and effort.

Interactivity

An important goal for VisLab is the ability to interact with data through the visualisations, and to make this as intuitive as possible. While the data structures described here don't go into that, you will see how they can be applied to support interactivity within VisLab itself.

Background

When trying to decide on suitable data structures for use in VisLab I couldn't find an official standard or any comprehensive documentation of the structures used or recommended in various visualisation libraries. There seemed to be some coherence across different libraries but nothing definitive.

Here I try to identify a reasonable set of JSON data structures for use in visualisation, and to document them for use by anyone.

I chose to base these structures around conventions I found in use with Vega and Vega-Lite, D3 and so on, and to make it trivial to take data using the models described below and feed it to one of these libraries to create any one of a large number of visualisations.

For example, if you want to use something supported by Vega-Lite you'll be able to plug a VisualModel described here directly into a Vega-Lite schema by assigning it to the 'values' property of the schema. On the other hand it is easy to use these same models with any other library, or your own visualisation components. VisLab uses a combination of custom visualisations including some built with D3, as well as some provided by Vega and Vega-Lite using the Vega-Lite runtime.

Relationship to Vega and Vega-Lite

You are not tied to using Vega or Vega-Lite if you adopt these structures but I warn you, it might just be too easy not to do so!

If you know Vega or Vega-Lite, you will appreciate how easy it is to combine these models with a Vega/Vega-Lite schema to create one of many different styles of visualisation. The 'values' object (typically an array) in those schemas holds the data to be visualised in a fairly raw form, for example after loading from a source such as a CSV file.

The Vega/Vega-Lite schemas don't tie down the 'values' object to a specific structure - if they did all that is needed would be to document them. Instead the schemas are designed to make it easy to get data from standard sources into manageable JSON format that can then be processed using Vega transforms and other features to cope with variations and fine tune the visual represetnation.

The structures here provide a rigorous definition for the data prior to visualisation, which makes it possible to just insert them into one of a library of ready made schemas, rather than rolling your own. For some this will work best, for other it may be better to roll your own schema to save getting the data into one of these models first - although in most cases that is likely to be straighforward and may be worth doing anyway, just so everyone working with the code knows what the data should look like.

Feedback

Feedback is very welcome so if you have comments or suggestions please use this issue

Use within VisLab

Visualisation Lab makes use of these standards and so provides a set of examples (in Svelte) of how they can help build a set of components for that allow for transformation, filtering, selection of data for visualisation with an interactive user interface. If you don't know Svelte, don't worry because it is very easy to understand the structure and operation of Svelte code.

This 'specification' and VisLab are a work in progress, which means that feedback and suggestions, and contributions (!) are welcome in all areas (see 'Feedback' above).

Within VisLab I envisage using a set of ViewModel classes to generate each model type (e.g. VMGraph) and then to add transform ViewModel Transform (VMT) class to adapt each for a particular view component schema. For example: SourceResult -> VMGraph -> VMGraphToVega -> ViewVegaForceGraph

The latest deployed demo of VisLab is live at vlab.happybeing.com.


JSON ViewModel Definitions

The JSON structures defined below are in many cases based on those suggested for the 'values' object of the Vega/Vega-Lite schemas, taken from the official documentation. This makes them very easy to use with the Vega-Lite runtime, to generate one of the many Vega/Vega-Lite visualisations, which can later be customised through your Vega/Vega-Lite schema or replaced by a completely new visualisation (e.g. using custom rendering or a library such as D3).

JSON ViewModel types so far include:

  • vm-tabular-json for tables (e.g. from a spreadsheet in CSV format)
  • vm-graph-json for graphs (nodes and links)
  • vm-tree for a hierarchy of nodes with an optional value property
  • vm-series-json for a series of values

The following is not intended as a ViewModel, but an input which can be transformed into a ViewModel such as vm-graph-json. It is included because it is part of the full set of models used to represent data by VisLab, but can be ignored for most applications.

  • raw-graph-rdfdataset for RDF graphs loaded using RDF/JS

Each of these is defined below.

Note that in the following the 'VisLab class' is not part of this specification, but referenced as an example of code which implements the model as a JavaScript class.


ViewModel: vm-tabular-json

viewModel.values: [
  { [v1, v2, v3 ...]  },	// Row 1, normally the column headings (see 'header' property)
  { [v1, v2, v3 ...]  },	// Row 2
  { [v1, v2, v3 ...]  },	// Row 3
]
viewModel.header: [h1, h2, h3 ...]	// Only present if row 1 does NOT contain column headings

VisLab code example: class VMTable

Examples:

  • TODO

ViewModel: raw-graph-rdfdataset

viewModel.data: Object	// RDF/JS Dataset

VisLab code example: class VMGraph

Examples:

  • TODO

ViewModel: vm-graph-json

	viewModel.values: { nodes: [], links: [] }

Where:

	node { id, ...properties }		// Optional properties can affect visualisation, such as 'label'
	link { source, target, ...properties }	// source = source node id, target = target node id

VisLab code example: class VMGraph

Examples:

  • TODO

ViewModel: vm-tree-json

	viewModel.values: []
	viewModel.quantityField	// [optional] the name of the field on a node which contains a numeric quantity

where values is an array of node objects:

{
	index: Number, 	// Index of this node
	parent: Number, // Index of parent node. The root node uses its own index as parent
	<quantity>: Number,	// [optional] a numeric quantity associated with the node (see vievModel.quantityField)
}

☐ how does this compare to D3 tree (e.g.d3-hierarchy)?

VisLab code example: class VMTree

Examples:

  • TODO

Note: For Vega, a tree will be generated from the above 'raw' values as follows. It may be useful for other View implementations to follow this convention, but there's no need to do this unless you want to maintain compatibity with VisLab (e.g. by making use of one of the components that will be published as VisLab is developed).

values: [{
  index: Number, 
  parent: Number,
  x: Number,
  y: Number,
  depth: Number,
  children: Number
}]

ViewModel: vm-series-json

	viewModel.values: []  // TODO

Where:

VisLab code example: class VMSeries

Examples:

  • TODO

ViewModel: vm-timeline-json

TODO is this needed?

	viewModel.values: []  // TODO

Where: ???

VisLab code example: class VMTimeline

Examples:

  • TODO

TODO

More possibilities to think about!

Chart - Line


Chart - Pie


ViewModel: vm-geo-json

See GeoJSON on Wikipedia

Clone this wiki locally