diff --git a/src/ChartInternal/data/data.ts b/src/ChartInternal/data/data.ts
index 8534f6b6f..dc4aa4e89 100644
--- a/src/ChartInternal/data/data.ts
+++ b/src/ChartInternal/data/data.ts
@@ -743,20 +743,23 @@ export default {
let minDist = config.point_sensitivity;
let closest;
- // find mouseovering bar
+ // find mouseovering bar/candlestick
+ // https://github.com/naver/billboard.js/issues/2434
data
- .filter(v => $$.isBarType(v.id))
+ .filter(v => $$.isBarType(v.id) || $$.isCandlestickType(v.id))
.forEach(v => {
- const shape = main.select(`.${CLASS.bars}${$$.getTargetSelectorSuffix(v.id)} .${CLASS.bar}-${v.index}`).node();
+ const selector = $$.isBarType(v.id) ?
+ `.${CLASS.chartBar}.${CLASS.target}${$$.getTargetSelectorSuffix(v.id)} .${CLASS.bar}-${v.index}` :
+ `.${CLASS.chartCandlestick}.${CLASS.target}${$$.getTargetSelectorSuffix(v.id)} .${CLASS.candlestick}-${v.index} path`;
- if (!closest && $$.isWithinBar(shape)) {
+ if (!closest && $$.isWithinBar(main.select(selector).node())) {
closest = v;
}
});
- // find closest point from non-bar
+ // find closest point from non-bar/candlestick
data
- .filter(v => !$$.isBarType(v.id))
+ .filter(v => !$$.isBarType(v.id) && !$$.isCandlestickType(v.id))
.forEach(v => {
const d = $$.dist(v, pos);
diff --git a/src/ChartInternal/shape/bar.ts b/src/ChartInternal/shape/bar.ts
index 6f04a1f6a..8c1274fd2 100644
--- a/src/ChartInternal/shape/bar.ts
+++ b/src/ChartInternal/shape/bar.ts
@@ -3,7 +3,7 @@
* billboard.js project is licensed under the MIT license
*/
import CLASS from "../../config/classes";
-import {getPointer, getRandom, getRectSegList, isNumber} from "../../module/util";
+import {getRandom, isNumber} from "../../module/util";
export default {
initBar(): void {
@@ -191,26 +191,5 @@ export default {
[startPosX, offset]
];
};
- },
-
- isWithinBar(that): boolean {
- const mouse = getPointer(this.state.event, that);
- const list = getRectSegList(that);
- const [seg0, seg1] = list;
- const x = Math.min(seg0.x, seg1.x);
- const y = Math.min(seg0.y, seg1.y);
- const offset = this.config.bar_sensitivity;
- const {width, height} = that.getBBox();
- const sx = x - offset;
- const ex = x + width + offset;
- const sy = y + height + offset;
- const ey = y - offset;
-
- const isWithin = sx < mouse[0] &&
- mouse[0] < ex &&
- ey < mouse[1] &&
- mouse[1] < sy;
-
- return isWithin;
}
};
diff --git a/src/ChartInternal/shape/shape.ts b/src/ChartInternal/shape/shape.ts
index 5c7c2c90b..6c0aaa574 100644
--- a/src/ChartInternal/shape/shape.ts
+++ b/src/ChartInternal/shape/shape.ts
@@ -23,9 +23,9 @@ import {
curveStep as d3CurveStep
} from "d3-shape";
import {select as d3Select} from "d3-selection";
-import {d3Selection} from "types/types";
+import {d3Selection} from "../../../types/types";
import CLASS from "../../config/classes";
-import {capitalize, getUnique, isObjectType, isNumber, isValue, isUndefined, notEmpty} from "../../module/util";
+import {capitalize, getPointer, getRectSegList, getUnique, isObjectType, isNumber, isValue, isUndefined, notEmpty} from "../../module/util";
export default {
/**
@@ -424,5 +424,26 @@ export default {
$$.isStepType(d) ?
config.line_step_type : "linear"
);
+ },
+
+ isWithinBar(that): boolean {
+ const mouse = getPointer(this.state.event, that);
+ const list = getRectSegList(that);
+ const [seg0, seg1] = list;
+ const x = Math.min(seg0.x, seg1.x);
+ const y = Math.min(seg0.y, seg1.y);
+ const offset = this.config.bar_sensitivity;
+ const {width, height} = that.getBBox();
+ const sx = x - offset;
+ const ex = x + width + offset;
+ const sy = y + height + offset;
+ const ey = y - offset;
+
+ const isWithin = sx < mouse[0] &&
+ mouse[0] < ex &&
+ ey < mouse[1] &&
+ mouse[1] < sy;
+
+ return isWithin;
}
};
diff --git a/test/internals/tooltip-spec.ts b/test/internals/tooltip-spec.ts
index 405d64057..c0aff6fe2 100644
--- a/test/internals/tooltip-spec.ts
+++ b/test/internals/tooltip-spec.ts
@@ -1409,4 +1409,37 @@ describe("TOOLTIP", function() {
chart.$.chart.style("margin-left", null);
});
});
+
+ describe("tooltip: candlestick type with xs option", () => {
+ before(() => {
+ args = {
+ data: {
+ xs: {
+ data1: "x"
+ },
+ columns: [
+ ["x", "2021-02-20"],
+ ["data1", { open: 1300, high: 1369, low: 1200, close: 1339, volume: 100 }]
+ ],
+ type: "candlestick",
+ labels: true,
+ },
+ axis: {
+ x: {
+ type: "timeseries",
+ tick: {
+ format: "%Y-%m-%d",
+ }
+ }
+ }
+ };
+ });
+
+ it("should display tooltip", () => {
+ util.hoverChart(chart, "mousemove", {clientX: 180, clientY: 130});
+
+ expect(chart.$.tooltip.select(".value").html())
+ .to.be.equal(`Open: 1300 High: 1369 Low: 1200 Close: 1339 Volume: 100`);
+ });
+ });
});