diff --git a/src/ChartInternal/interactions/eventrect.ts b/src/ChartInternal/interactions/eventrect.ts
index 20702a019..59aaee101 100644
--- a/src/ChartInternal/interactions/eventrect.ts
+++ b/src/ChartInternal/interactions/eventrect.ts
@@ -388,7 +388,7 @@ export default {
return $$.isWithinShape(this, d);
});
- if (shapeAtIndex.empty() && !isTooltipGrouped) {
+ if (shapeAtIndex.empty() && !isTooltipGrouped && config.interaction_onout) {
$$.hideGridFocus?.();
$$.hideTooltip();
@@ -591,7 +591,10 @@ export default {
state.event = event;
// chart is destroyed
- if (!config || $$.hasArcType() || eventReceiver.currentIdx === -1) {
+ if (
+ !config || $$.hasArcType() || eventReceiver.currentIdx === -1 ||
+ !config.interaction_onout
+ ) {
return;
}
@@ -637,7 +640,7 @@ export default {
*/
generateEventRectsForMultipleXs(eventRectEnter): void {
const $$ = this;
- const {state} = $$;
+ const {config, state} = $$;
eventRectEnter
.on("click", function(event) {
@@ -656,7 +659,7 @@ export default {
state.event = event;
// chart is destroyed
- if (!$$.config || $$.hasArcType()) {
+ if (!$$.config || $$.hasArcType() || !config.interaction_onout) {
return;
}
diff --git a/src/ChartInternal/shape/arc.ts b/src/ChartInternal/shape/arc.ts
index af3a014de..23d107d39 100644
--- a/src/ChartInternal/shape/arc.ts
+++ b/src/ChartInternal/shape/arc.ts
@@ -1124,7 +1124,7 @@ export default {
$$.setOverOut(true, arcData);
})
.on("mouseout", (event, d) => {
- if (state.transiting) { // skip while transiting
+ if (state.transiting || !config.interaction_onout) { // skip while transiting
return;
}
diff --git a/src/ChartInternal/shape/funnel.ts b/src/ChartInternal/shape/funnel.ts
index 49c1bce29..2df6318ab 100644
--- a/src/ChartInternal/shape/funnel.ts
+++ b/src/ChartInternal/shape/funnel.ts
@@ -236,8 +236,10 @@ export default {
.on(isTouch ? "touchend" : "mouseout", event => {
const data = getTarget(event);
- $$.hideTooltip();
- $$.setOverOut(false, data);
+ if (config.interaction_onout) {
+ $$.hideTooltip();
+ $$.setOverOut(false, data);
+ }
});
}
},
diff --git a/src/ChartInternal/shape/radar.ts b/src/ChartInternal/shape/radar.ts
index 6efd2cab3..eadae1dd8 100644
--- a/src/ChartInternal/shape/radar.ts
+++ b/src/ChartInternal/shape/radar.ts
@@ -331,7 +331,7 @@ export default {
bindRadarEvent(): void {
const $$ = this;
- const {state, $el: {radar, svg}} = $$;
+ const {config, state, $el: {radar, svg}} = $$;
const focusOnly = $$.isPointFocusOnly();
const {inputType, transiting} = state;
const isMouse = inputType === "mouse";
@@ -339,6 +339,10 @@ export default {
const hide = event => {
state.event = event;
+ if (!config.interaction_onout) {
+ return;
+ }
+
// const index = getIndex(event);
const index = $$.getDataIndexFromEvent(event);
diff --git a/src/ChartInternal/shape/treemap.ts b/src/ChartInternal/shape/treemap.ts
index aa0377893..cefcebd4c 100644
--- a/src/ChartInternal/shape/treemap.ts
+++ b/src/ChartInternal/shape/treemap.ts
@@ -147,8 +147,10 @@ export default {
.on(isTouch ? "touchend" : "mouseout", event => {
const data = getTarget(event);
- $$.hideTooltip();
- $$.setOverOut(false, data);
+ if (config.interaction_onout) {
+ $$.hideTooltip();
+ $$.setOverOut(false, data);
+ }
});
}
},
diff --git a/src/config/Options/interaction/interaction.ts b/src/config/Options/interaction/interaction.ts
index 9cd5d1d8b..4170e8524 100644
--- a/src/config/Options/interaction/interaction.ts
+++ b/src/config/Options/interaction/interaction.ts
@@ -18,6 +18,8 @@ export default {
* @property {boolean} [interaction.inputType.mouse=true] enable or disable mouse interaction
* @property {boolean} [interaction.inputType.touch=true] enable or disable touch interaction
* @property {boolean|number} [interaction.inputType.touch.preventDefault=false] enable or disable to call event.preventDefault on touchstart & touchmove event. It's usually used to prevent document scrolling.
+ * @property {boolean} [interaction.onout=true] Enable or disable "onout" event.
+ * When is disabled, defocus(hiding tooltip, focused gridline, etc.) event won't work.
* @see [Demo: touch.preventDefault](https://naver.github.io/billboard.js/demo/#Interaction.PreventScrollOnTouch)
* @example
* interaction: {
@@ -35,11 +37,15 @@ export default {
* // or threshold pixel value (pixel moved from touchstart to touchmove)
* preventDefault: 5
* }
- * }
+ * },
+ *
+ * // disable "onout" event
+ * onout: false
* }
*/
interaction_enabled: true,
interaction_brighten: true,
interaction_inputType_mouse: true,
- interaction_inputType_touch: {}
+ interaction_inputType_touch: {},
+ interaction_onout: true
};
diff --git a/test/interactions/interaction-spec.ts b/test/interactions/interaction-spec.ts
index 50f5964e2..12b0079bd 100644
--- a/test/interactions/interaction-spec.ts
+++ b/test/interactions/interaction-spec.ts
@@ -1454,4 +1454,31 @@ describe("INTERACTION", () => {
expect(+point.attr("r")).to.be.above(r);
});
});
+
+ describe("interaction.onover", () => {
+ const spy = sinon.spy();
+
+ beforeAll(() => {
+ args = {
+ data: {
+ columns: [
+ ["data1", 300, 350, 300, 0, 0, 0],
+ ["data2", 130, 100, 140, 200, 150, 50]
+ ],
+ onout: spy
+ },
+ interaction: {
+ onout: false
+ }
+ }
+ });
+
+ it("should maintain 'selected' state", () => {
+ util.hoverChart(chart, "mousemove", {clientX: 250, clientY: 311});
+ util.hoverChart(chart, "mouseout", {clientX: -100, clientY: -100});
+
+ expect(chart.$.tooltip.style("display")).to.be.equal("block");
+ expect(spy.called).to.be.false;
+ });
+ });
});
diff --git a/types/options.d.ts b/types/options.d.ts
index 2f145af1a..f87c99e93 100644
--- a/types/options.d.ts
+++ b/types/options.d.ts
@@ -245,7 +245,13 @@ export interface ChartOptions {
*/
preventDefault?: boolean | number;
};
- }
+ },
+
+ /**
+ * Enable or disable "onout" event.
+ * When is disabled, defocus(hiding tooltip, focused gridline, etc.) event won't work.
+ */
+ onout?: boolean;
};
transition?: {