Skip to content

Widgets' specification

Clément Prod'homme edited this page Feb 15, 2021 · 4 revisions

Widgets created through the widget-editor are of two kinds: charts (that are built with the Vega library) and maps. In addition, the widget-editor can be used in two modes:

  • interactive: in this mode, the user creates/edits a widget through the interface
  • advanced: in this one, the user will write a “Vega JSON” to create their widget (charts only)

When used in its interactive mode to create charts, the editor outputs a JSON that mostly follows the Vega specification. Some custom formats are used for the legend and tooltip though.

When used in its advanced mode, the user may create a widget from scratch or start with the output of the editor. That's the reason why it is important to understand these custom formats.

Table of content

Why custom formats?

On one side, there is the legend. Vega is perfectly able to render a legend, as many examples can demonstrate. The catch though is that its styles are very limited. For this reason, we decided it would be preferable to part from Vega's way of doing it, and create our own format instead.

On the other side, the tooltip is not supported by default by Vega. Still, alongside the main library, the authors also provided another library to manage tooltips. In the more recent versions of this library, tooltips can be natively triggered via signals. Unfortunately, a large collection of widgets has already been created, using a custom format we created when tooltips couldn't be managed otherwise. For this reason, we still use this custom format today.

Legend specification

Before anything, if you wish to use Vega's native legend, please refer to this document. Below, we will assume you want to create a legend based on the widget-editor's legend format.

The widget-editor's legend is represented by the top-level legend property. It's signature is the following:

type legend = Array<{
  // `type` defines whether the color or size of the items vary
  // This property is not used anymore and can be omitted
  // Only legends where the color varies can be built
  type: "color"|"size",
  // `label` is not used anymore and can be omitted
  label: null,
  // `shape` represents the shape of the symbol next to each of the legend items
  // This property is not used anymore and can be omitted
  // Only circle symbols are currently rendered
  shape: "circle"|"square",
  // `values` contain each of the legend items
  values: Array<{
    // `label` represents the label of the legend item
    label: string|number,
    // `value` contains the color of the legend item (any valid CSS color)
    value: string,
    // `type` contains the type of the label
    type: "string"|"number"|"date"
  }>
}>;

Even though legend must be an array, only its first item is interpreted. The array nature of the property has been inherited from previous versions of the widget-editor, as most of the inner properties that are not used anymore.

As an example, here is the minimal configuration of a legend:

[
  {
    "values": [
      { "label": "Item A", "value": "blue", "type": "string" },
      { "label": "Item B", "value": "white", "type": "string" },
      { "label": "Item C", "value": "red", "type": "string" }
    ]
  }
]

Tooltip specification

The tooltip is represented by the top-level property interaction_config. Here is its type definition:

type interaction_config = Array<{
  // `name` must be set to "tooltip" to be interpreted
  name: "tooltip",
  config: {
    // `fields` is an array so you can display multiple items in the tooltip
    fields: Array<{
      // `column` is the name of the data property to get the value from
      column: "string",
      // `property` represents the label shown in the tooltip
      property: "string",
      // `type` is the type of the value
      type: "string"|"number"|"date",
      // `format` contains the format applied to the value
      // For items of type "number", these formats are available: https://github.com/d3/d3-format
      // For items of type "date", these are available: https://github.com/d3/d3-time-format
      // For items of type "string", this property is ignored but still required
      format: "string"
    }>
  }
}>;

interaction_config must be an array, but only the item for which the name property is set to "name" is taken into account.

If the data passed to Vega would contain the properties power_plant and capacity, here is an example of legend you could build:

[
  {
    "name": "tooltip",
    "config": {
      "fields": [
        {
          "column": "power_plant",
          "property": "Power plant name",
          "type": "string",
          "format": ".2s"
        },
        {
          "column": "capacity",
          "property": "Capacity (MW)",
          "type": "number",
          "format": "s"
        }
      ]
    }
  }
]

Other custom properties

In addition to the legend and tooltip, the widget-editor adds other custom properties to the Vega specification.

config property

The top-level config property is not using a custom format per se. It is defined in the Vega specification and allows you to modify the visual appearance of the widget.

One specificity though, is that we require all the widgets to have a name property inside config. This name is used to determine which color scheme is applied to the widget, when opened in the widget-editor.

Color schemes are a feature of the interactive mode that allow the user to quickly change the visual appearance of the widget, choosing from a selection of color schemes provided by the host app (e.g. Resource Watch) or by customizing/creating their own one.

To provide this functionality, the color schemes must use unique names. For this reason, if the user starts customizing a scheme, or uses the advanced mode, we require this scheme to be named "user-custom".

All the advanced widgets that define a config property must have config.name set to "user-custom".

we_meta property

The top-level we_meta property is used internally by the widget-editor to register which of its versions was used to create or last edit the widget. This property is added for debugging and widget migration purposes.

This property must not be set by the user themselves. Users cannot add this property to the Vega JSON in the advanced mode.

paramsConfig property

The top-level paramsConfig property is also used internally by the widget-editor. It allows the editor to edit existing widgets by storing information about how they were created.

This property must not be set by the user themselves. Users cannot add this property to the Vega JSON in the advanced mode.