Skip to content

Commit

Permalink
fix(point): Fix point sensitivity pointe
Browse files Browse the repository at this point in the history
- Fix closest data point to work with point.sensitivity option
- Split getSensitivity inner function to getPointSensitivity

Fix #3293
  • Loading branch information
netil authored Jul 17, 2023
1 parent cfec99f commit a47e091
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 29 deletions.
14 changes: 2 additions & 12 deletions src/ChartInternal/data/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -740,19 +740,9 @@ export default {

findClosest(values, pos: [number, number]): IDataRow | undefined {
const $$ = this;
const {config, $el: {main}} = $$;
const {$el: {main}} = $$;
const data = values.filter(v => v && isValue(v.value));
const getSensitivity = (d: IDataPoint) => {
let sensitivity = config.point_sensitivity;

if (isFunction(sensitivity)) {
sensitivity = sensitivity.call($$.api, d);
} else if (sensitivity === "radius") {
sensitivity = d.r;
}

return sensitivity;
};
let minDist;
let closest;

Expand All @@ -776,7 +766,7 @@ export default {
.forEach((v: IDataPoint) => {
const d = $$.dist(v, pos);

minDist = getSensitivity(v);
minDist = $$.getPointSensitivity(v);

if (d < minDist) {
minDist = d;
Expand Down
4 changes: 3 additions & 1 deletion src/ChartInternal/interactions/eventrect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -351,8 +351,10 @@ export default {
// Show xgrid focus line
$$.showGridFocus(selectedData);

const dist = $$.dist(closest, mouse);

// Show cursor as pointer if point is close to mouse position
if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) {
if ($$.isBarType(closest.id) || dist < $$.getPointSensitivity(closest)) {
$$.$el.svg.select(`.${$EVENT.eventRect}`).style("cursor", "pointer");

if (!state.mouseover) {
Expand Down
22 changes: 20 additions & 2 deletions src/ChartInternal/shape/point.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import type {d3Selection} from "../../../types/types";
import {$CIRCLE, $COMMON, $SELECT} from "../../config/classes";
import {document} from "../../module/browser";
import type {IDataRow} from "../data/IData";
import type {IDataPoint, IDataRow} from "../data/IData";
import {getBoundingRect, getPointer, getRandom, isFunction, isObject, isObjectType, isUndefined, isValue, toArray, notEmpty} from "../../module/util";

const getTransitionName = () => getRandom();
Expand Down Expand Up @@ -342,7 +342,7 @@ export default {
selectR(d) : (selectR || $$.pointR(d) * 4);
},

isWithinCircle(node, r?: number): boolean {
isWithinCircle(node: SVGElement, r?: number): boolean {
const mouse = getPointer(this.state.event, node);
const element = d3Select(node);
const prefix = this.isCirclePoint(node) ? "c" : "";
Expand All @@ -362,6 +362,24 @@ export default {
) < (r || this.config.point_sensitivity);
},

/**
* Get data point sensitivity radius
* @param {object} d Data point object
* @returns {number} return the sensitivity value
*/
getPointSensitivity(d: IDataPoint) {
const $$ = this;
let sensitivity = $$.config.point_sensitivity;

if (isFunction(sensitivity)) {
sensitivity = sensitivity.call($$.api, d);
} else if (sensitivity === "radius") {
sensitivity = d.r;
}

return sensitivity;
},

insertPointInfoDefs(point, id: string): void {
const $$ = this;
const copyAttr = (from, target) => {
Expand Down
27 changes: 13 additions & 14 deletions test/shape/point-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import {expect} from "chai";
import util from "../assets/util";
import {$CIRCLE} from "../../src/config/classes";
import {fireEvent} from "../assets/helper";

describe("SHAPE POINT", () => {
let chart;
Expand Down Expand Up @@ -190,8 +189,8 @@ describe("SHAPE POINT", () => {
});

describe("point sensitivity", () => {
function checkHover(nodes, values, index, sensitivity = 0) {
const node = nodes[index];
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");
Expand All @@ -200,9 +199,11 @@ describe("SHAPE POINT", () => {
clientX: x + (sensitivity || r),
clientY: y
});

expect(+chart.$.tooltip.select(".value").text())
.to.be.equal(values[index]);

expect(eventRect.style("cursor")).to.be.equal("pointer");
}

before(() => {
Expand Down Expand Up @@ -267,23 +268,22 @@ describe("SHAPE POINT", () => {
});

it("check when point.sensitivity='radius'", done => {
const {circles} = chart.$;
const nodes = circles.nodes();
const {$el} = chart.internal;
const values = chart.data.values("data1");

new Promise((resolve, reject) => {
checkHover(nodes, values, 0);
checkHover($el, values, 0);

setTimeout(resolve, 300);
}).then(() => {
return new Promise((resolve, reject) => {
checkHover(nodes, values, 1);
checkHover($el, values, 1);

setTimeout(resolve, 300);
});
}).then(() => {
return new Promise((resolve, reject) => {
checkHover(nodes, values, 2);
checkHover($el, values, 2);

setTimeout(resolve, 300);
});
Expand All @@ -310,23 +310,22 @@ describe("SHAPE POINT", () => {
});

it("check when point.sensitivity=Function", done => {
const {circles} = chart.$;
const nodes = circles.nodes();
const {$el} = chart.internal;
const values = chart.data.values("data1");

new Promise((resolve, reject) => {
checkHover(nodes, values, 0);
checkHover($el, values, 0);

setTimeout(resolve, 300);
}).then(() => {
return new Promise((resolve, reject) => {
checkHover(nodes, values, 1, 5);
checkHover($el, values, 1, 5);

setTimeout(resolve, 300);
});
}).then(() => {
return new Promise((resolve, reject) => {
checkHover(nodes, values, 2, 15);
checkHover($el, values, 2, 15);

setTimeout(resolve, 300);
});
Expand Down

0 comments on commit a47e091

Please sign in to comment.