diff --git a/src/component/axisPointer/AxisPointerModel.ts b/src/component/axisPointer/AxisPointerModel.ts index 9ff16f84f1..a7421461e3 100644 --- a/src/component/axisPointer/AxisPointerModel.ts +++ b/src/component/axisPointer/AxisPointerModel.ts @@ -90,6 +90,8 @@ class AxisPointerModel extends ComponentModel { snap: false, triggerTooltip: true, triggerEmphasis: true, + triggerOnNoData: false, + findPointOnConnectedCharts: true, value: null, status: null, // Init value depends on whether handle is used. diff --git a/src/component/axisPointer/axisTrigger.ts b/src/component/axisPointer/axisTrigger.ts index af1a232fd2..4e4028c98d 100644 --- a/src/component/axisPointer/axisTrigger.ts +++ b/src/component/axisPointer/axisTrigger.ts @@ -115,12 +115,12 @@ export default function axisTrigger( ecModel: GlobalModel, api: ExtensionAPI ) { + const axisPointerComponent = ecModel.getComponent('axisPointer') as AxisPointerModel; const currTrigger = payload.currTrigger; let point = [payload.x, payload.y]; const finder = payload; const dispatchAction = payload.dispatchAction || bind(api.dispatchAction, api); - const coordSysAxesInfo = (ecModel.getComponent('axisPointer') as AxisPointerModel) - .coordSysAxesInfo as CollectedCoordInfo; + const coordSysAxesInfo = axisPointerComponent.coordSysAxesInfo as CollectedCoordInfo; // Pending // See #6121. But we are not able to reproduce it yet. @@ -128,7 +128,10 @@ export default function axisTrigger( return; } - if (illegalPoint(point)) { + // Chart-wide option. See `CommonAxisPointerOption.findPointOnConnectedCharts`. + const findPointOnConnectedCharts = axisPointerComponent.get('findPointOnConnectedCharts'); + + if (illegalPoint(point) && findPointOnConnectedCharts) { // Used in the default behavior of `connection`: use the sample seriesIndex // and dataIndex. And also used in the tooltipView trigger. point = findPointFromSeries({ @@ -168,8 +171,13 @@ export default function axisTrigger( each(coordSysAxesInfo.coordSysAxesInfo[coordSysKey], function (axisInfo, key) { const axis = axisInfo.axis; const inputAxisInfo = findInputAxisInfo(inputAxesInfo, axisInfo); + // When `triggerOnNoData` is enabled, still trigger this axis even if the point + // is illegal (e.g. on a connected chart with no data at the hovered location), + // as long as a value is available from the input (the linked value). This is + // not applied on `leave`, so the pointer is still hidden when the cursor leaves. + const triggerOnNoData = axisInfo.triggerOnNoData && currTrigger !== 'leave' && !!inputAxisInfo; // If no inputAxesInfo, no axis is restricted. - if (!shouldHide && coordSysContainsPoint && (!inputAxesInfo || inputAxisInfo)) { + if ((!shouldHide || triggerOnNoData) && coordSysContainsPoint && (!inputAxesInfo || inputAxisInfo)) { let val = inputAxisInfo && inputAxisInfo.value; if (val == null && !isIllegalPoint) { val = axis.pointToData(point); diff --git a/src/component/axisPointer/modelHelper.ts b/src/component/axisPointer/modelHelper.ts index 2a600d526a..5c46d14f47 100644 --- a/src/component/axisPointer/modelHelper.ts +++ b/src/component/axisPointer/modelHelper.ts @@ -50,6 +50,7 @@ interface AxisInfo { axisPointerModel: Model triggerTooltip: boolean triggerEmphasis: boolean + triggerOnNoData: boolean involveSeries: boolean snap: boolean useHandle: boolean @@ -89,6 +90,7 @@ export function collect(ecModel: GlobalModel, api: ExtensionAPI) { * axisPointerModel, * triggerTooltip, * triggerEmphasis, + * triggerOnNoData, * involveSeries, * snap, * seriesModels, @@ -197,6 +199,7 @@ function collectAxesInfo(result: CollectionResult, ecModel: GlobalModel, api: Ex const snap = axisPointerModel.get('snap'); const triggerEmphasis = axisPointerModel.get('triggerEmphasis'); + const triggerOnNoData = axisPointerModel.get('triggerOnNoData'); const axisKey = makeKey(axis.model); const involveSeries = triggerTooltip || snap || axis.type === 'category'; @@ -208,6 +211,7 @@ function collectAxesInfo(result: CollectionResult, ecModel: GlobalModel, api: Ex axisPointerModel: axisPointerModel, triggerTooltip: triggerTooltip, triggerEmphasis: triggerEmphasis, + triggerOnNoData: triggerOnNoData, involveSeries: involveSeries, snap: snap, useHandle: isHandleTrigger(axisPointerModel), diff --git a/src/util/types.ts b/src/util/types.ts index 3496f5eacc..c7a5c020d3 100644 --- a/src/util/types.ts +++ b/src/util/types.ts @@ -1782,6 +1782,33 @@ export interface CommonAxisPointerOption { triggerEmphasis?: boolean + /** + * By default the axisPointer is only displayed when the triggered point maps to + * an actual value (i.e. there is data at that location). When set to `true`, the + * axisPointer is still displayed even if there is no data at the location, as long + * as an axis value is available (e.g. the value linked from a connected chart). + * + * This is mainly useful for `echarts.connect`-ed charts that have different data: + * hovering over one chart at a position where another chart has no data will still + * show the axisPointer on the other chart at the linked value. + * + * Configured per axis (e.g. `xAxis.axisPointer.triggerOnNoData`). Default `false`. + */ + triggerOnNoData?: boolean + + /** + * Used by the default behavior of `echarts.connect`. When an action is replayed on + * a connected chart, the original pixel point is meaningless on that chart, so by + * default a sample point is looked up from the chart's own series (using the sample + * `seriesIndex`/`dataIndex`) to position the axisPointer/tooltip. + * + * Set to `false` to skip this lookup, so the axisPointer is positioned solely by the + * linked axis value (see {@link triggerOnNoData}) rather than snapped to a sample data + * point. This is a chart-wide option; configure it on the top-level `axisPointer` + * component. Default `true` (keeps the legacy behavior). + */ + findPointOnConnectedCharts?: boolean + /** * current value. When using axisPointer.handle, value can be set to define the initial position of axisPointer. */ diff --git a/test/axisPointer-triggerOnNoData.html b/test/axisPointer-triggerOnNoData.html new file mode 100644 index 0000000000..2a78277676 --- /dev/null +++ b/test/axisPointer-triggerOnNoData.html @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + +
+
+ + + +