Custom Chart Properties
Overview
Below is a listing of all basic properties in a Custom Chart definition
CustomChart {
fields {
field (multiple) {
label (optional): String
type: 'dimension' | 'measure'
sort (optional) {
apply_order (optional): Number
direction: 'asc' | 'desc'
}
data_type (optional): 'string' | 'number' | 'boolean' | 'date'
}
}
options (optional) {
option (multiple) {
label (optional): String
type: 'input' | 'number-input' | 'toggle' | 'radio' | 'select' | 'color-picker'
options (optional): Any
default_value (optional): String | Number | Boolean
}
}
template: @vgl {
// Vega Lite JSON Specifications
};;
}
Runtime data
Runtime data is the data generated while the code is running. It is not possible to pre-define any value for this type of data. You can use runtime data in the Template definition of Custom Chart.
field <name>
name
Refer to the current field with all of its pre-defined properties.
format
Refer to the current field’s format
type
Refer to the current field’s data type
option <name>
value
Refer to the current option with all of its pre-defined properties
Suppose we have a Custom Chart definition as below:
CustomChart {
fields {
field a { // "a" is the field name
type: "dimension"
label: "field a" // displayed in Visualization Settings
sort {
apply_order: 1 // this field will be sorted first
direction: "asc" // sort direction: ascending
}
}
field b {
type: "measure" // any field dragged here will be aggregated
label: "field b"
sort {
apply_order: 2 // this field will be sorted second
direction: "desc"
}
}
}
options {
option tooltip {
type: 'toggle'
label: 'Show tooltip'
default_value: true
}
}
template: @vgl {
"data": {
"values": @{values}
},
"mark": {
"type": "bar",
"tooltip": @{options.tooltip.value},
},
"encoding": {
"x": {
"field": @{fields.a.name},
"type": "nominal",
},
"y": {
"field": @{fields.b.name},
"type": "quantitative"
}
}
};;
}
Suppose the user drags Created_at
field into field a
and Revenue
field into field b
. During runtime, the data is returned as below:
{
"data": {
"values": [
{"a": "01/01/2022", "b": 28},
{"a": "01/02/2022", "b": 55},
{"a": "01/03/2022", "b": 43},
]
},
fields: {
a: {
name: "Created_at" // see @{fields.a.name} in the definition
type: "date" // data type of the field user drags in field a
format: "mm/dd/yyyy" // format of the field user drags in field a
}
b: {
name: "Sum of Revenue" // because the field is aggregated
type: "number"
format: "Number (rounded)"
}
},
options: {
tooltip: {
value: true // see @{options.tooltip.value} in the definition
},
}
}
Field definition properties
Syntax: field <field_name>
type
(string)
Description: Specify if the field is a dimension or measure. If you set “measure”, any field dragged in this section will be aggregated.
This is a required field.
All valid values for type
are: “dimension” || “measure”.
Note: Example charts from Vega-Lite library usually define aggregation within their codes, therefore you do not need to aggregate once more in Holistics. If you reuse those codes, it’s recommended to use the type
“dimension” for all fields.
###label
(string)
Description: The field name, displayed in visualization settings to help users understand what it means.
This is an optional field.
sort
(field)
Description: sort
has two properties:
direction
: Specify the direction that the field should be sorted. All valid values fordirection
are: "asc" || "desc".apply_order
: Specify the order that the field should be sorted relative to other fields. Accepts a numeric value.
This is an optional field.
data_type
(string)
Description: Limit the type of data that users can drag into in the exploration screen.
This is an optional field.
All valid values for type
are: “string” || ”number” || “boolean” || “date”.
Option definition properties
Syntax: option <option_name>
type
(string) (required)
Description: This property determines how the option will be displayed in the STYLES tab.
All valid values for types
are: "input" || "number-input" || "toggle" || "radio" || "select" || "color-picker".
"input" type
Description: This type of option renders a text input in the Settings section, and will accept a text input from users.
Sample code:
option my_text_input_option{
type: 'input',
default_value: 'Some default value here'
}
Notes:
After defining this option, you can access its value using this syntax:
@{{ options.my_text_input_option.value }}
"number-input" type
Description: Similar to "input" option, but only renders/accepts a numeric value.
Sample code:
option my_number_input_option{
type: 'number-input',
default_value: 1
}
Notes:
- After defining this option, you can access its value using this syntax:
@{{ options.my_number_input_option.value }}
"option" type
Description: This option type renders a toggle element, and accepts a Boolean value (true/false).
Sample code:
option my_toggle_option{
type: 'toggle',
default_value: false
}
Notes:
- After defining this option, you can access its value using this syntax:
@{{ options.my_toggle_option.value }}
"radio" type
Description: This option type renders a radio list, and accepts a value from a predefined list.
Sample code:
option my_radio_option{
type: 'radio',
options: ['option 1', 'option 2', 'option 3', 'option 4'] // list all your options here
default_value: 'option 1'
}
Notes:
- After defining this option, you can access its value using this syntax:
@{{ options.my_radio_option.value }}
"select" type
Description: Similar to radio option, but renders a select box instead.
Sample code:
option my_select_option{
type: 'select',
options: ['option 1', 'option 2', 'option 3', 'option 4'] // list all your options here
default_value: 'option 1'
}
Notes:
- After defining this option, you can access its value using this syntax:
@{{ options.my_select_option.value }}
"color-picker" type
Description: This option type renders a color picker, and resolves the selected color hex code.
Sample code:
option bar_color {
type: 'color-picker'
label: 'Bar color'
default_value: 'cyan'
}
Then to reference it in the Vega Lite JSON encoding. Sample as below:
"mark": {
"type": "bar",
"width": 20,
"tooltip": @{options.tooltip.value},
"color": @{options.bar_color.value}
}
options
(string)
If you set type
as “select” or "radio", you are required to specify the option values users can choose from by this property. Otherwise, this property is optional.
label
(string)
Description: It specifies the label to be displayed in Visualization settings for the Option.
This is an optional field.
default_value
(string/number/boolean)
Description: This defines the value the option will take by default.
This is an optional field.
Vega-lite properties
For a full list of Vega-lite's properties, we highly recommend going through the official Vega-lite’s documentation.
This section only serves as a quick introduction, or a refresher if you are already familiar with Vega-lite.
data
property
In a normal Vega-lite chart, a data source can be anything from a hard-coded dataframe to an URL to a JSON file. However in Holistics, this must always be specified as:
"data": {
"values": @{values}
}
The placeholder @{values}
is used by Holistics to pass in the data coming from dataset fields that the users drag in.
mark
property
Here you specify the shapes to be used (bar, line, point...) and the style of those shapes (like bar width, line thickness, color...). For example:
"mark": {
"type": "bar",
"width": 20,
"tooltip": @{options.tooltip.value},
"color": @{options.bar_color.value}
}
encoding
property
Here you specify which field you declared will map to which dimension of the chart. For example, in the Field definition seciton we have declared two fields: a
and b
. You will map them to the x and y axes of the chart like so:
"encoding": {
"x": {
"field": @{fields.a.name},
"type": "temporal"
},
"y": {
"field": @{fields.b.name},
"type": "quantitative"
}
}
params
property
💡 params
is a part of Vega-lite official syntax. You can read more about it here: https://vega.github.io/vega-lite/docs/parameter.html
Use params
to declare user interactions that your chart accepts. It takes in an Array of user interaction declarations.
A valid user interaction declaration consists of:
"name":
This field accepts a String. This is the name of your user interaction declaration."select":
This field accepts a String. Optionally, you can pass more options into it. This is the type of your user interaction.
A valid params declaration may look like this:
template: @vgl {
"params:" [
// Different types of user interaction declaration
// 1. A simple Point selection declaration. The name of the selection is "pointSelection",
// and the type of select is "point".
{ "name": "pointSelection", "select": "point" },
// 2. More advanced Point selection declaration. The name of the selection is
// "hightlight" and the select is "point" only on when user hovers over the chart.
{ "name": "highlight", "select": {"type": "point", "on": "mouseover"} }
]
}
On its own, params
declaration does not do much, but it lays the foundation so that you can create interesting interactive effects with your chart.
Head over to Tutorial: Create Interactive Custom Charts to learn more.
Holistics's additional properties
holisticsConfig
property
Use holisticsConfig
to enable interactive chart features like Cross Filter or Drill-through to be triggered on user’s interactions.
params
and holisticsConfig
To make Vega-lite and Holistics's interactive features work together, we recommend the following mappings:
- Vega-lite's point selection maps to
crossFilterSignals
. - Vega-lite's point-on-hover-selection maps to
contextMenuSignals
.
Please refer to Custom chart's selection types for more information.
crossFilterSignals
Takes in an Array of valid user selections as input. This configuration enables your chart to listen for declared user selections, and trigger Cross Filter on those interactions.
If you are not sure on how to declare a user selection for your chart, head over to params.
When a user creates a selection whose type matches the input declaration, Cross Filtering feature is automatically triggered.
template: @vgl {
...
"params": [
// 1. Point selection is declared here
{"name": "myPointSelection", "select": "point"}
],
...
"holisticsConfig": {
// 2. Point selection now triggers cross filter on your chart
"crossFilterSignals": ["myPointSelection"],
}
}
contextMenuSignals
Context Menu contains several interactive features in Holistics, including Explore, Date-drill, Drill-through, etc. The menu will be shown when you right-click on the chart inside a widget/report.
If you enable Context Menu, Explore and Date drill will be ready to use without further configurations.
Drill-through feature, however, requires users to select a data point(s) from the chart. Therefore, to enable Drill-through for your Custom Chart, it is necessary to declare user selections so that your chart can listen for them.
Accepts an Array of valid user selections as input. This configuration enables your chart to listen for declared user selections, and trigger Context Menu on those interactions.
If you are not sure on how to declare a user selection for your chart, head over to params.
When a user creates a selection whose type matches the input declaration, the selected data will become the input params for the Drill-through feature.
template: @vgl {
...
"params": [
// 1. Point-hover selection is declared here
{ "name": "myHoverSelection",
"select": { "type": "point", "on": "mouseover" }
},
],
...
"holisticsConfig": {
// 2. You can trigger Context Menu on hover selection
"contextMenuSignals": ["myHoverSelection"],
}
}
With the code above, your Custom Chart now listens for hover interactions. On a hover then right click, user can open the Context Menu. If they select Drill-through functionality, the input data would be the data point that they are hovering on.
holisticsFormat
To render your Custom Chart with the format settings specified by Data Explorers in the Exploration UI, you need to add the 2 properties below to your fields of encoding
property in the Template definition:
"format": @{fields.field_name.format}
"formatType": "holisticsFormat"
(a custom format type Holistics registered with Vega-Lite)
For example, to apply Holistics format to the fields' axis labels:
"encoding": {
"x":{
"field": @{fields.a.name},
"type": "nominal",
"axis": {
"format": @{fields.a.format},
"formatType": "holisticsFormat"
}
},
"y":{
"field": @{fields.b.name},
"type": "quantitative",
"axis": {
"format": @{fields.b.format},
"formatType": "holisticsFormat"
}
}
}
You can also apply it to Legend, Header, Tooltips, etc. in the same way. Please refer to Format | Vega-lite’s documentation for more details.