# Make a custom chart interactive > Add cross-filtering, drill-through, and highlight effects to custom charts using Vega-Lite point and interval selections, with copy-ready code examples. Custom charts can have the same interactions as Holistics's built-in charts, such as: - [Cross-filtering](/docs/cross-filtering) - [Drill-through](/docs/interactions/drill-through) - [Date drills](/docs/interactions/date-drills) You enable this in two steps. First, you declare the interactions your chart accepts. Then you wire those interactions to Holistics features. This guide walks you through both. ## How interactions work Interactions come from two parts of the chart template: - **Selections** declare what a user can do, such as clicking a data point or dragging to select a range. You define them with Vega-Lite [`params`](/reference/aml/custom-chart#params). Vega-Lite calls a selection a *signal*. - **`holisticsConfig`** wires those selections to Holistics features. Two fields matter: - `crossFilterSignals`: selections that trigger [Cross Filter](/docs/cross-filtering) on **click**. - `contextMenuSignals`: selections that open the context menu (Date-drill, Drill-through) on **right-click**. Use a **hover** selection here so the menu targets the point under the cursor. For the full property reference, see [`holisticsConfig`](/reference/aml/custom-chart#holisticsconfig) and [`params`](/reference/aml/custom-chart#params). If you are new to chart templates, start with [Understand Custom Chart](/docs/charts/understand-custom-chart). ### Selection types A selection is either point-based or interval-based. **Point selection (click).** A point selection fires when a user clicks a single value (left click), or selects several values (hold Shift and left click). To deselect, the user clicks a selected value again. Read more in the [Vega-Lite selection docs](https://vega.github.io/vega-lite/docs/parameter.html#select). **Interval selection (drag).** An interval selection fires when a user holds left click and drags across a range of values. To deselect, the user double-clicks anywhere on the chart. ## Interaction examples Each example below starts from a working chart and adds one interaction. The full, copy-ready code for each one lives in the [Custom Chart Library](https://github.com/holistics/custom-chart-library/tree/main/interactive_features). ### Highlight selected columns on point selection **Outcome.** When a user selects one or more columns, those columns stay fully visible while the rest fade out. On hover, a stroke outlines the column. 1. In your template, declare two point selections in `params`: one that fires on click, and one that fires on hover. ```aml template: @vgl { ... "params": [ // effective only while the user hovers { "name": "pointSelectionOnMouseOver", "select": {"type": "point", "on": "mouseover"} }, // effective when the user clicks { "name": "normalPointSelection", "select": "point" } ] ... } ``` 2. Add a `fillOpacity` rule so selected columns keep full opacity while the rest fade. ```aml template: @vgl { ... "mark": { "fill": "#484848" // base color of the columns }, "encoding": { "fillOpacity": { // selected columns stay fully visible "condition": {"param": "normalPointSelection", "value": 1}, // unselected columns fade to 30% "value": 0.3 } } ... } ``` 3. Try it. Click a single column, then select a range by holding Shift and clicking. The selected columns should stay highlighted. 4. Add a `strokeWidth` rule so hovered columns get a light stroke and selected columns get a bolder one. ```aml template: @vgl { ... "mark": { "fill": "#484848", "stroke": "black" // stroke color }, "encoding": { "strokeWidth": { "condition": [ // bolder stroke (2) on selected columns { "param": "normalPointSelection", "empty": false, "value": 2 }, // light stroke (1) on hovered columns { "param": "pointSelectionOnMouseOver", "empty": false, "value": 1 } ], "value": 0 // no stroke by default } } ... } ``` 5. Try selecting and hovering again. You should see a light stroke on hovered columns and a bolder stroke on selected ones. **Full code example:** [Highlight stroke effect on point selection](https://github.com/holistics/custom-chart-library/blob/main/interactive_features/highlight_stroke_effect_on_point_selection.md). ### Cross-filter on point selection :::info What is Cross Filter? Cross Filter creates shared filters that apply to all report widgets in your dashboard. To learn more, see [Cross Filter](/docs/cross-filtering). ::: **Outcome.** When a user selects data on your chart, a cross filter for that selection is applied to every widget in the dashboard. **Prerequisite:** a chart with a point selection declared. The [highlight example](#highlight-selected-columns-on-point-selection) above is a good starting point. 1. In your template, declare a point selection in `params`. ```aml template: @vgl { ... "params": [ // effective when the user clicks { "name": "normalPointSelection", "select": "point" } ] ... } ``` 2. Add a `holisticsConfig` field with `crossFilterSignals`, and list the point selection from step 1. ```aml template: @vgl { ... "holisticsConfig": { "crossFilterSignals": ["normalPointSelection"] } ... } ``` 3. Try it. Click a single column, or select a range with Shift and click. A cross filter should be created and applied to the other reports in your dashboard. **Full code example:** [Cross Filter on point selection](https://github.com/holistics/custom-chart-library/blob/main/interactive_features/cross_filter_on_point_selection.md). ### Cross-filter on interval selection **Outcome.** When a user drags to select an interval on your chart, a cross filter for that range is applied to every widget in the dashboard. **Prerequisite:** a working custom chart you can add a selection to. 1. In your template, declare an interval selection in `params`. ```aml template: @vgl { ... "params": [ { "name": "intervalSelection", "select": {"type": "interval", "encodings": ["x"]} } ] ... } ``` 2. Add a `holisticsConfig` field with `crossFilterSignals`, and list the interval selection from step 1. ```aml template: @vgl { ... "holisticsConfig": { "crossFilterSignals": ["intervalSelection"] } ... } ``` 3. Try it. Hold left click and drag across a range of values. A cross filter should be created and applied to the other reports in your dashboard. **Full code example:** [Cross Filter on interval selection](https://github.com/holistics/custom-chart-library/blob/main/interactive_features/cross_filter_on_interval_selection.md). ### Cross-filter all sub-charts in a combo chart **Outcome.** A selection on a combo (mixed) chart applies the cross filter to every sub-chart in the layer, not just the one the user interacted with. **Prerequisite:** a combo chart built with a Vega-Lite `layer`. See [Cross Filter on sub-charts in a combo chart](https://github.com/holistics/custom-chart-library/blob/main/interactive_features/cross_filter_on_subcharts_combo_chart.md) for how to build one. 1. In your template, find the sub-chart in the `layer` array that the cross filter should also apply to. ```aml template: @vgl { ... "layer": [ // your bar chart definition { ... }, // your line chart definition (the one we'll filter) { ... } ] ... } ``` 2. Add a `transform` to that sub-chart with a `filter` that takes the user's selection as its `param`. ```aml template: @vgl { ... "layer": [ { ... }, // your bar chart definition { "transform": [ // filter this sub-chart by the user's interval selection { "filter": {"param": "intervalSelection"} } ] // ...the rest of the sub-chart definition } ] ... } ``` 3. Create a cross filter on your dashboard and confirm the sub-chart updates along with the rest. **Full code example:** [Cross Filter on sub-charts in a combo chart](https://github.com/holistics/custom-chart-library/blob/main/interactive_features/cross_filter_on_subcharts_combo_chart.md). ### Drill-through on point selection **Outcome.** When a user hovers a data point and right-clicks, the Holistics context menu opens so they can Date-drill or Drill-through, just like on a built-in chart. **Prerequisite:** a chart you can add a selection to (see the [cross-filter example](#cross-filter-on-point-selection)). The context menu opens on **right-click**, so it must read the point currently under the cursor. That means it needs a **hover** selection, not the click selection you use for Cross Filter. (A click selection has no target on right-click unless the user left-clicks the point first, which would also cross-filter.) 1. In your template, declare a **hover** point selection in `params`. The `"on": "mouseover"` trigger makes it track whichever point the cursor is over. ```aml template: @vgl { ... "params": [ { "name": "hoverPointSelection", "select": {"type": "point", "on": "mouseover", "clear": "mouseout"} } ] ... } ``` 2. Add a `holisticsConfig` field with `contextMenuSignals`, and list the hover selection from step 1. ```aml template: @vgl { ... "holisticsConfig": { "contextMenuSignals": ["hoverPointSelection"] } ... } ``` 3. Try it. Hover a data point and right-click; the context menu appears, with options to Date-drill and Drill-through. Cross Filter and the context menu use different triggers, so wire them to different selections: a **click** selection for `crossFilterSignals` (left-click cross-filters the dashboard) and a **hover** selection for `contextMenuSignals` (hover, then right-click opens the menu on that point). For the full property reference, see [`holisticsConfig`](/reference/aml/custom-chart#holisticsconfig).