diff --git a/demo/plugins/select.html b/demo/plugins/select.html index cadcef0..cf337c4 100644 --- a/demo/plugins/select.html +++ b/demo/plugins/select.html @@ -16,6 +16,12 @@

Select & Zoom with Mouse

+ + + + + + @@ -54,9 +60,11 @@

Select & Zoom with Mouse

const form = document.querySelector('form'); function syncSelectZoom() { - const { x, y } = form; + const { x, y, thresholdX, thresholdY } = form; chart.plugins.selectZoom.options.enableX = x.checked; chart.plugins.selectZoom.options.enableY = y.checked; + chart.plugins.selectZoom.options.thresholdX = thresholdX.value; + chart.plugins.selectZoom.options.thresholdY = thresholdY.value; } form.addEventListener('change', syncSelectZoom); syncSelectZoom(); diff --git a/src/plugins_extra/selectZoom.ts b/src/plugins_extra/selectZoom.ts index dcfcf8e..27c24e4 100644 --- a/src/plugins_extra/selectZoom.ts +++ b/src/plugins_extra/selectZoom.ts @@ -5,6 +5,8 @@ export interface SelectZoomOptions { mouseButtons: number; enableX: boolean; enableY: boolean; + thresholdX: number; + thresholdY: number; cancelOnSecondPointer: boolean; } @@ -12,6 +14,8 @@ const defaultOptions = { mouseButtons: 1, enableX: true, enableY: true, + thresholdX: 0, + thresholdY: 0, cancelOnSecondPointer: false, } as const; @@ -50,6 +54,8 @@ export class SelectZoom { } private start: {p: Point, id: number} | null = null; + private selectX: boolean = false; + private selectY: boolean = false; private reset() { if (this.start === null) @@ -95,21 +101,26 @@ export class SelectZoom { return; const p = this.getPoint(ev); - if (this.options.enableX) { - const x = Math.min(this.start.p.x, p.x); - const w = Math.abs(this.start.p.x - p.x); + const x = Math.min(this.start.p.x, p.x); + const y = Math.min(this.start.p.y, p.y); + const width = Math.abs(this.start.p.x - p.x); + const height = Math.abs(this.start.p.y - p.y); + const minWidth = Math.min(height, this.options.thresholdX); + const minHeight = Math.min(width, this.options.thresholdY); + this.selectX = width >= minWidth || !this.options.enableY; + this.selectY = height > minHeight || !this.options.enableX; + + if (this.options.enableX && this.selectX) { this.visual.x.baseVal.value = x; - this.visual.width.baseVal.value = w; + this.visual.width.baseVal.value = width; } else { this.visual.setAttribute('x', '0'); this.visual.setAttribute('width', '100%'); } - if (this.options.enableY) { - const y = Math.min(this.start.p.y, p.y); - const h = Math.abs(this.start.p.y - p.y); + if (this.options.enableY && this.selectY) { this.visual.y.baseVal.value = y; - this.visual.height.baseVal.value = h; + this.visual.height.baseVal.value = height; } else { this.visual.setAttribute('y', '0'); this.visual.setAttribute('height', '100%'); @@ -121,33 +132,29 @@ export class SelectZoom { return; const p = this.getPoint(ev); + const x1 = Math.min(this.start.p.x, p.x); + const x2 = Math.max(this.start.p.x, p.x); + const y1 = Math.max(this.start.p.y, p.y); + const y2 = Math.min(this.start.p.y, p.y); let changed = false; - if (this.options.enableX) { - const x1 = Math.min(this.start.p.x, p.x); - const x2 = Math.max(this.start.p.x, p.x); - if (x2 - x1 > 0) { - const newDomain = [ - this.chart.model.xScale.invert(x1), - this.chart.model.xScale.invert(x2), - ]; - this.chart.model.xScale.domain(newDomain); - this.chart.options.xRange = null; - changed = true; - } + if (this.options.enableX && this.selectX && x2 != x1) { + const newDomain = [ + this.chart.model.xScale.invert(x1), + this.chart.model.xScale.invert(x2), + ]; + this.chart.model.xScale.domain(newDomain); + this.chart.options.xRange = null; + changed = true; } - if (this.options.enableY) { - const y1 = Math.max(this.start.p.y, p.y); - const y2 = Math.min(this.start.p.y, p.y); - if (y1 - y2 > 0) { - const newDomain = [ - this.chart.model.yScale.invert(y1), - this.chart.model.yScale.invert(y2), - ]; - this.chart.model.yScale.domain(newDomain); - this.chart.options.yRange = null; - changed = true; - } + if (this.options.enableY && this.selectY && y2 != y1) { + const newDomain = [ + this.chart.model.yScale.invert(y1), + this.chart.model.yScale.invert(y2), + ]; + this.chart.model.yScale.domain(newDomain); + this.chart.options.yRange = null; + changed = true; } if (changed) this.chart.model.requestRedraw();