Skip to content

Commit 206eb34

Browse files
committed
Clamp drag rectangle to chart area
I believe this is a better UI, and it also fixes some issues with incorrect zoom ranges when dragging the rectangle outside of the chart area. To help implement this, I copied the clamp helper function from chartjs-plugin-annotation. Fixes #895
1 parent 2b76ccc commit 206eb34

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

src/handlers.js

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ import {zoom, zoomRect} from './core';
33
import {callback as call, getRelativePosition, _isPointInArea} from 'chart.js/helpers';
44
import {getState} from './state';
55

6+
/**
7+
* @param {number} x
8+
* @param {number} from
9+
* @param {number} to
10+
* @returns {number}
11+
*/
12+
const clamp = (x, from, to) => Math.min(to, Math.max(from, x));
13+
614
function removeHandler(chart, type) {
715
const {handlers} = getState(chart);
816
const handler = handlers[type];
@@ -111,12 +119,12 @@ function applyAspectRatio(endPoint, beginPoint, aspectRatio) {
111119
endPoint.y = beginPoint.y + height;
112120
}
113121

114-
function applyMinMaxProps(rect, beginPoint, endPoint, {min, max, prop}) {
115-
rect[min] = Math.max(0, Math.min(beginPoint[prop], endPoint[prop]));
116-
rect[max] = Math.max(beginPoint[prop], endPoint[prop]);
122+
function applyMinMaxProps(rect, chartArea, beginPoint, endPoint, {min, max, prop}) {
123+
rect[min] = clamp(Math.min(beginPoint[prop], endPoint[prop]), chartArea[min], chartArea[max]);
124+
rect[max] = clamp(Math.max(beginPoint[prop], endPoint[prop]), chartArea[min], chartArea[max]);
117125
}
118126

119-
function getReplativePoints(chart, points, maintainAspectRatio) {
127+
function getRelativePoints(chart, points, maintainAspectRatio) {
120128
const beginPoint = getPointPosition(points.dragStart, chart);
121129
const endPoint = getPointPosition(points.dragEnd, chart);
122130

@@ -134,14 +142,14 @@ export function computeDragRect(chart, mode, points, maintainAspectRatio) {
134142
const {top, left, right, bottom, width: chartWidth, height: chartHeight} = chart.chartArea;
135143
const rect = {top, left, right, bottom};
136144

137-
const {beginPoint, endPoint} = getReplativePoints(chart, points, maintainAspectRatio && xEnabled && yEnabled);
145+
const {beginPoint, endPoint} = getRelativePoints(chart, points, maintainAspectRatio && xEnabled && yEnabled);
138146

139147
if (xEnabled) {
140-
applyMinMaxProps(rect, beginPoint, endPoint, {min: 'left', max: 'right', prop: 'x'});
148+
applyMinMaxProps(rect, chart.chartArea, beginPoint, endPoint, {min: 'left', max: 'right', prop: 'x'});
141149
}
142150

143151
if (yEnabled) {
144-
applyMinMaxProps(rect, beginPoint, endPoint, {min: 'top', max: 'bottom', prop: 'y'});
152+
applyMinMaxProps(rect, chart.chartArea, beginPoint, endPoint, {min: 'top', max: 'bottom', prop: 'y'});
145153
}
146154

147155
const width = rect.right - rect.left;

0 commit comments

Comments
 (0)