Skip to content

Commit 8d79a33

Browse files
Add hitTolerance option to all annotations (#902)
* Add hitTolerance option to all annotations * add test cases for line, box and ellipse annotations * add option to polygon annotation * add option to point annotation * add types * add documentation * code improving * Update src/helpers/helpers.core.js Co-authored-by: Jacco van den Berg <[email protected]> * increase tolerance for a fixture --------- Co-authored-by: Jacco van den Berg <[email protected]>
1 parent e94475c commit 8d79a33

24 files changed

+583
-50
lines changed

docs/guide/types/_commonInnerLabel.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ All of these options can be [Scriptable](../options.md#scriptable-options)
1212
| `drawTime` | `string` | `options.drawTime` | See [drawTime](../options#draw-time). Defaults to the annotation draw time if unset
1313
| [`font`](#fonts-and-colors) | [`Font`\|`Font[]`](../options#font) | `{ weight: 'bold' }` | Label font
1414
| `height` | `number`\|`string` | `undefined` | Overrides the height of the image or canvas element. Could be set in pixel by a number, or in percentage of current height of image or canvas element by a string. If undefined, uses the height of the image or canvas element. It is used only when the content is an image or canvas element.
15+
| `hitTolerance` | `number` | `undefined` | Amount of pixels to interact with annotations within some distance of the mouse point.
1516
| `opacity` | `number` | `undefined` | Overrides the opacity of the image or canvas element. Could be set a number in the range 0.0 to 1.0, inclusive. If undefined, uses the opacity of the image or canvas element. It is used only when the content is an image or canvas element.
1617
| `padding` | [`Padding`](../options.md#padding) | `6` | The padding to add around the text label.
1718
| [`position`](#position) | `string`\|`{x: string, y: string}` | `'center'` | Anchor position of label in the annotation.

docs/guide/types/_commonOptions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ The following options are available for all annotations.
1212
| [`borderShadowColor`](#styling) | [`Color`](../options.md#color) | Yes | `'transparent'`
1313
| [`display`](#general) | `boolean` | Yes | `true`
1414
| [`drawTime`](#general) | `string` | Yes | `'afterDatasetsDraw'`
15+
| [`hitTolerance`](#general) | `number` | Yes | `0`
1516
| [`init`](../configuration.html#common) | `boolean` | [See initial animation](../configuration.html#initial-animation) | `undefined`
1617
| [`id`](#general) | `string` | No | `undefined`
1718
| [`shadowBlur`](#styling) | `number` | Yes | `0`

docs/guide/types/box.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ If one of the axes does not match an axis in the chart, the box will take the en
7171
| `adjustScaleRange` | Should the scale range be adjusted if this annotation is out of range.
7272
| `display` | Whether or not this annotation is visible.
7373
| `drawTime` | See [drawTime](../options.md#draw-time).
74+
| `hitTolerance` | Amount of pixels to interact with annotations within some distance of the mouse point.
7475
| `id` | Identifies a unique id for the annotation and it will be stored in the element context. When the annotations are defined by an object, the id is automatically set using the key used to store the annotations in the object. When the annotations are configured by an array, the id, passed by this option in the annotation, will be used.
7576
| `rotation` | Rotation of the box in degrees.
7677
| `xMax` | Right edge of the box in units along the x axis.

docs/guide/types/ellipse.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ If one of the axes does not match an axis in the chart, the ellipse will take th
6868
| `adjustScaleRange` | Should the scale range be adjusted if this annotation is out of range.
6969
| `display` | Whether or not this annotation is visible.
7070
| `drawTime` | See [drawTime](../options.md#draw-time).
71+
| `hitTolerance` | Amount of pixels to interact with annotations within some distance of the mouse point.
7172
| `id` | Identifies a unique id for the annotation and it will be stored in the element context. When the annotations are defined by an object, the id is automatically set using the key used to store the annotations in the object. When the annotations are configured by an array, the id, passed by this option in the annotation, will be used.
7273
| `rotation` | Rotation of the ellipse in degrees, default is 0.
7374
| `xMax` | Right edge of the ellipse in units along the x axis.

docs/guide/types/label.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ The 4 coordinates, xMin, xMax, yMin, yMax are optional. If not specified, the bo
9292
| `display` | Whether or not this annotation is visible.
9393
| `drawTime` | See [drawTime](../options.md#draw-time).
9494
| `height` | Overrides the height of the image or canvas element. Could be set in pixel by a number, or in percentage of current height of image or canvas element by a string. If undefined, uses the height of the image or canvas element. It is used only when the content is an image or canvas element.
95+
| `hitTolerance` | Amount of pixels to interact with annotations within some distance of the mouse point.
9596
| `id` | Identifies a unique id for the annotation and it will be stored in the element context. When the annotations are defined by an object, the id is automatically set using the key used to store the annotations in the object. When the annotations are configured by an array, the id, passed by this option in the annotation, will be used.
9697
| `padding` | The padding to add around the text label.
9798
| `rotation` | Rotation of the label in degrees.

docs/guide/types/line.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ If `scaleID` is unset, then `xScaleID` and `yScaleID` are used to draw a line fr
8989
| `display` | Whether or not this annotation is visible.
9090
| `drawTime` | See [drawTime](../options.md#draw-time).
9191
| `endValue` | End two of the line when a single scale is specified.
92+
| `hitTolerance` | Amount of pixels to interact with annotations within some distance of the mouse point.
93+
| `id` | Identifies a unique id for the annotation and it will be stored in the element context. When the annotations are defined by an object, the id is automatically set using the key used to store the annotations in the object. When the annotations are configured by an array, the id, passed by this option in the annotation, will be used.
9294
| `scaleID` | ID of the scale in single scale mode. If unset, `xScaleID` and `yScaleID` are used.
9395
| `value` | End one of the line when a single scale is specified.
9496
| `xMax` | X coordinate of end two of the line in units along the x axis.
@@ -137,6 +139,7 @@ All of these options can be [Scriptable](../options.md#scriptable-options)
137139
| `drawTime` | `string` | `options.drawTime` | See [drawTime](../options#draw-time). Defaults to the line annotation draw time if unset.
138140
| [`font`](#fonts-and-colors) | [`Font`\|`Font[]`](../options#font) | `{ weight: 'bold' }` | Label font.
139141
| `height` | `number`\|`string` | `undefined` | Overrides the height of the image or canvas element. Could be set in pixel by a number, or in percentage of current height of image or canvas element by a string. If undefined, uses the height of the image or canvas element. It is used only when the content is an image or canvas element.
142+
| `hitTolerance` | `number` | `undefined` | Amount of pixels to interact with annotations within some distance of the mouse point.
140143
| `opacity` | `number` | `undefined` | Overrides the opacity of the image or canvas element. Could be set a number in the range 0.0 to 1.0, inclusive. If undefined, uses the opacity of the image or canvas element. It is used only when the content is an image or canvas element.
141144
| `padding` | [`Padding`](../options.md#padding) | `6` | The padding to add around the text label.
142145
| `position` | `string` | `'center'` | Anchor position of label on line. Possible options are: `'start'`, `'center'`, `'end'`. It can be set by a string in percentage format `'number%'` which are representing the percentage on the width of the line where the label will be located.

docs/guide/types/point.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ The 4 coordinates, xMin, xMax, yMin, yMax are optional. If not specified, the bo
7373
| `adjustScaleRange` | Should the scale range be adjusted if this annotation is out of range.
7474
| `display` | Whether or not this annotation is visible.
7575
| `drawTime` | See [drawTime](../options.md#draw-time).
76+
| `hitTolerance` | Amount of pixels to interact with annotations within some distance of the mouse point.
7677
| `id` | Identifies a unique id for the annotation and it will be stored in the element context. When the annotations are defined by an object, the id is automatically set using the key used to store the annotations in the object. When the annotations are configured by an array, the id, passed by this option in the annotation, will be used.
7778
| `radius` | Size of the point in pixels.
7879
| `rotation` | Rotation of point, in degrees.

docs/guide/types/polygon.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ The 4 coordinates, xMin, xMax, yMin, yMax are optional. If not specified, the bo
7878
| `adjustScaleRange` | Should the scale range be adjusted if this annotation is out of range.
7979
| `display` | Whether or not this annotation is visible.
8080
| `drawTime` | See [drawTime](../options.md#draw-time).
81+
| `hitTolerance` | Amount of pixels to interact with annotations within some distance of the mouse point.
8182
| `id` | Identifies a unique id for the annotation and it will be stored in the element context. When the annotations are defined by an object, the id is automatically set using the key used to store the annotations in the object. When the annotations are configured by an array, the id, passed by this option in the annotation, will be used.
8283
| `radius` | Size of the polygon in pixels.
8384
| `rotation` | Rotation of polygon, in degrees.

src/helpers/helpers.core.js

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ const isOlderPart = (act, req) => req > act || (act.length > req.length && act.s
99
export const EPSILON = 0.001;
1010
export const clamp = (x, from, to) => Math.min(to, Math.max(from, x));
1111

12+
/**
13+
* @param {{value: number, start: number, end: number}} limit
14+
* @param {number} hitSize
15+
* @returns {boolean}
16+
*/
17+
export const inLimit = (limit, hitSize) => limit.value >= limit.start - hitSize && limit.value <= limit.end + hitSize;
18+
1219
/**
1320
* @param {Object} obj
1421
* @param {number} from
@@ -26,28 +33,27 @@ export function clampAll(obj, from, to) {
2633
* @param {Point} point
2734
* @param {Point} center
2835
* @param {number} radius
29-
* @param {number} borderWidth
36+
* @param {number} hitSize
3037
* @returns {boolean}
3138
*/
32-
export function inPointRange(point, center, radius, borderWidth) {
39+
export function inPointRange(point, center, radius, hitSize) {
3340
if (!point || !center || radius <= 0) {
3441
return false;
3542
}
36-
const hBorderWidth = borderWidth / 2;
37-
return (Math.pow(point.x - center.x, 2) + Math.pow(point.y - center.y, 2)) <= Math.pow(radius + hBorderWidth, 2);
43+
return (Math.pow(point.x - center.x, 2) + Math.pow(point.y - center.y, 2)) <= Math.pow(radius + hitSize, 2);
3844
}
3945

4046
/**
4147
* @param {Point} point
4248
* @param {{x: number, y: number, x2: number, y2: number}} rect
4349
* @param {InteractionAxis} axis
44-
* @param {number} borderWidth
50+
* @param {{borderWidth: number, hitTolerance: number}} hitsize
4551
* @returns {boolean}
4652
*/
47-
export function inBoxRange(point, {x, y, x2, y2}, axis, borderWidth) {
48-
const hBorderWidth = borderWidth / 2;
49-
const inRangeX = point.x >= x - hBorderWidth - EPSILON && point.x <= x2 + hBorderWidth + EPSILON;
50-
const inRangeY = point.y >= y - hBorderWidth - EPSILON && point.y <= y2 + hBorderWidth + EPSILON;
53+
export function inBoxRange(point, {x, y, x2, y2}, axis, {borderWidth, hitTolerance}) {
54+
const hitSize = (borderWidth + hitTolerance) / 2;
55+
const inRangeX = point.x >= x - hitSize - EPSILON && point.x <= x2 + hitSize + EPSILON;
56+
const inRangeY = point.y >= y - hitSize - EPSILON && point.y <= y2 + hitSize + EPSILON;
5157
if (axis === 'x') {
5258
return inRangeX;
5359
} else if (axis === 'y') {

src/types/box.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export default class BoxAnnotation extends Element {
66

77
inRange(mouseX, mouseY, axis, useFinalPosition) {
88
const {x, y} = rotated({x: mouseX, y: mouseY}, this.getCenterPoint(useFinalPosition), toRadians(-this.options.rotation));
9-
return inBoxRange({x, y}, this.getProps(['x', 'y', 'x2', 'y2'], useFinalPosition), axis, this.options.borderWidth);
9+
return inBoxRange({x, y}, this.getProps(['x', 'y', 'x2', 'y2'], useFinalPosition), axis, this.options);
1010
}
1111

1212
getCenterPoint(useFinalPosition) {
@@ -43,6 +43,7 @@ BoxAnnotation.defaults = {
4343
borderWidth: 1,
4444
display: true,
4545
init: undefined,
46+
hitTolerance: 0,
4647
label: {
4748
backgroundColor: 'transparent',
4849
borderWidth: 0,
@@ -61,6 +62,7 @@ BoxAnnotation.defaults = {
6162
weight: 'bold'
6263
},
6364
height: undefined,
65+
hitTolerance: undefined,
6466
opacity: undefined,
6567
padding: 6,
6668
position: 'center',

0 commit comments

Comments
 (0)