From 83b020607f52dd99a2cbe32b7d36f50ec0cb6654 Mon Sep 17 00:00:00 2001 From: Jae Sung Park Date: Wed, 18 Oct 2023 16:30:58 +0900 Subject: [PATCH] fix(point): Fix data.onclick not called when point.senstivity is radius when point.senstivity='radius' is set, the conditional checking distance not work. When the value is 'radius' make conditional to work with node's radius value instead. Fix #3466 --- src/ChartInternal/interactions/eventrect.ts | 3 ++- src/ChartInternal/shape/point.ts | 6 ++++-- test/interactions/interaction-spec.ts | 20 +++++++++++++++++ test/shape/point-spec.ts | 24 +++++++++++++++++---- 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/ChartInternal/interactions/eventrect.ts b/src/ChartInternal/interactions/eventrect.ts index e76cce546..d1cfd24d5 100644 --- a/src/ChartInternal/interactions/eventrect.ts +++ b/src/ChartInternal/interactions/eventrect.ts @@ -619,13 +619,14 @@ export default { const mouse = getPointer(state.event, this); const closest = $$.findClosestFromTargets(targetsToShow, mouse); + const sensitivity = config.point_sensitivity === "radius" ? closest.r : config.point_sensitivity; if (!closest) { return; } // select if selection enabled - if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) { + if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < sensitivity) { $$.$el.main.selectAll(`.${$SHAPE.shapes}${$$.getTargetSelectorSuffix(closest.id)}`) .selectAll(`.${$SHAPE.shape}-${closest.index}`) .each(function() { diff --git a/src/ChartInternal/shape/point.ts b/src/ChartInternal/shape/point.ts index 6e074624e..b038f287e 100644 --- a/src/ChartInternal/shape/point.ts +++ b/src/ChartInternal/shape/point.ts @@ -371,9 +371,11 @@ export default { }, isWithinCircle(node: SVGElement, r?: number): boolean { - const mouse = getPointer(this.state.event, node); + const {config, state} = this; + const mouse = getPointer(state.event, node); const element = d3Select(node); const prefix = this.isCirclePoint(node) ? "c" : ""; + const sensitivity = config.point_sensitivity === "radius" ? node.getAttribute("r") : config.point_sensitivity; let cx = +element.attr(`${prefix}x`); let cy = +element.attr(`${prefix}y`); @@ -387,7 +389,7 @@ export default { return Math.sqrt( Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2) - ) < (r || this.config.point_sensitivity); + ) < (r || sensitivity); }, /** diff --git a/test/interactions/interaction-spec.ts b/test/interactions/interaction-spec.ts index ee77095d1..ff8edd6ea 100644 --- a/test/interactions/interaction-spec.ts +++ b/test/interactions/interaction-spec.ts @@ -632,6 +632,26 @@ describe("INTERACTION", () => { expect(clicked).to.be.true; expect(data.value).to.be.equal(10); }); + + it("set option point.sensitivity='radius'", () => { + args.point.sensitivity = "radius"; + }); + + it("check for data click for line: when point.senstivity='radius'", () => { + const main = chart.$.main; + const {eventRect} = chart.internal.$el; + const circle = util.getBBox(main.select(`.${$CIRCLE.circles}-data1 circle`)); + + util.fireEvent(eventRect.node(), "click", { + clientX: circle.x, + clientY: circle.y + }, chart); + + expect(clicked).to.be.true; + expect(data.value).to.be.equal(10); + + delete args.point.sensitivity; + }); it("set option point.type='rectangle'", () => { args.point.pattern = ["rectangle"]; diff --git a/test/shape/point-spec.ts b/test/shape/point-spec.ts index 308f6bcd4..fa5b97507 100644 --- a/test/shape/point-spec.ts +++ b/test/shape/point-spec.ts @@ -4,10 +4,11 @@ */ /* eslint-disable */ /* global describe, beforeEach, it, expect */ +import sinon from "sinon"; import {expect} from "chai"; -import {window} from "../../src/module/browser" import util from "../assets/util"; import {$CIRCLE} from "../../src/config/classes"; +import {fireEvent} from "../assets/helper"; describe("SHAPE POINT", () => { let chart; @@ -228,21 +229,35 @@ describe("SHAPE POINT", () => { }); describe("point sensitivity", () => { + const spy = sinon.spy(); + function checkHover({circle, eventRect}, values, index, sensitivity = 0) { const node = circle.nodes()[index]; const x = +node.getAttribute("cx"); const y = +node.getAttribute("cy"); const r = +node.getAttribute("r"); + const clientX = x + (sensitivity || r); + const clientY = y; + util.hoverChart(chart, "mousemove", { - clientX: x + (sensitivity || r), - clientY: y + clientX, clientY }); expect(+chart.$.tooltip.select(".value").text()) .to.be.equal(values[index]); expect(eventRect.style("cursor")).to.be.equal("pointer"); + + if (chart.config("point.sensitivity") === "radius") { + fireEvent(eventRect.node(), "click", { + clientX, clientY + }, chart); + + expect(spy.calledOnce).to.be.true; + + spy.resetHistory(); + } } before(() => { @@ -293,7 +308,8 @@ describe("SHAPE POINT", () => { columns: [ ["data1", 10, 100, 300] ], - type: "bubble" + type: "bubble", + onclick: spy }, point: { sensitivity: "radius"