# Custom Chart Properties > A reference of available Custom Chart properties ## Overview Below is a listing of all basic properties in a Custom Chart definition ```json 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`** 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 ` - **`value`** Refer to the current option with all of its pre-defined properties Suppose we have a Custom Chart definition as below: ```json 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: ```js { 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 ` ### `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 for `direction` 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 ` ### `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 :::info Note For a full list of Vega-lite's properties, we highly recommend going through the [official Vega-lite’s documentation](https://vega.github.io/vega-lite/docs/). 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: ```json "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: ```json "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](#field-definition-properties) section we have declared two fields: `a` and `b`. You will map them to the x and y axes of the chart like so: ```json "encoding": { "x": { "field": @{fields.a.name}, "type": "temporal" }, "y": { "field": @{fields.b.name}, "type": "quantitative" } } ``` ### `params` property :::info 💡 `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](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: ```json 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](/guides/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. :::tip combine Vega-lite's `params` and `holisticsConfig` To make Vega-lite and Holistics's interactive features work together, we recommend the following mappings: - [Vega-lite's point selection](https://vega.github.io/vega-lite/docs/selection.html#type) maps to [`crossFilterSignals`](#crossfiltersignals). - [Vega-lite's point-on-hover-selection](https://vega.github.io/vega-lite/docs/selection.html#type) maps to [`contextMenuSignals`](#contextmenusignals). Please refer to [Custom chart's selection types](/guides/create-interactive-custom-charts#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](#params-property). When a user creates a selection whose type matches the input declaration, [Cross Filtering](/docs/cross-filtering) feature is automatically triggered. ```json 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 :::info What is Context Menu? **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](/docs/data-exploration) and [Date drill](/docs/interactions/date-drills) will be ready to use without further configurations. [Drill-through](/docs/interactions/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](#params-property). 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. ```json 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](#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: ```json "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](https://vega.github.io/vega-lite/docs/format.html#formatting-axis-legend-and-header-labels) for more details.