@thewhitehaven04/chartjs-plugin-zoom 2.2.8 → 2.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/@thewhitehaven04/chartjs-plugin-zoom.esm.js +1172 -0
- package/dist/@thewhitehaven04/chartjs-plugin-zoom.esm.js.map +1 -0
- package/dist/@thewhitehaven04/chartjs-plugin-zoom.js +3 -3
- package/dist/@thewhitehaven04/chartjs-plugin-zoom.js.map +1 -0
- package/dist/@thewhitehaven04/chartjs-plugin-zoom.min.js +8 -0
- package/dist/@thewhitehaven04/chartjs-plugin-zoom.min.js.map +1 -0
- package/dist/src/core.d.ts +24 -0
- package/dist/src/defaults.d.ts +3 -0
- package/dist/src/hammer.d.ts +6 -0
- package/dist/src/handlers.d.ts +24 -0
- package/dist/src/index.d.ts +31 -0
- package/dist/src/index.umd.d.ts +3 -0
- package/dist/src/options.d.ts +196 -0
- package/dist/src/plugin.d.ts +25 -0
- package/dist/src/scale.types.d.ts +12 -0
- package/dist/src/scale.types.test.d.ts +2 -0
- package/dist/src/state.d.ts +53 -0
- package/dist/src/types.d.ts +11 -0
- package/dist/src/utils.d.ts +14 -0
- package/dist/src/utils.test.d.ts +2 -0
- package/package.json +9 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chartjs-plugin-zoom.min.js","sources":["../../src/utils.ts","../../src/state.ts","../../src/scale.types.ts","../../src/core.ts","../../src/handlers.ts","../../src/hammer.ts","../../src/plugin.ts","../../src/defaults.ts","../../src/index.umd.ts"],"sourcesContent":["import type { Chart, Point, Scale } from 'chart.js'\nimport type { DragOptions, ModeOption, ModifierKey, PanOptions } from './options'\n\nconst eventKey = (key: ModifierKey): 'altKey' | 'ctrlKey' | 'metaKey' | 'shiftKey' => `${key}Key`\n\nexport const getModifierKey = (opts?: DragOptions | PanOptions): ModifierKey | undefined =>\n opts?.enabled && opts.modifierKey ? opts.modifierKey : undefined\nexport const keyPressed = (key: ModifierKey | undefined, event: TouchEvent | MouseEvent | PointerEvent) =>\n key && event[eventKey(key)]\nexport const keyNotPressed = (key: ModifierKey | undefined, event: TouchEvent | MouseEvent | PointerEvent) =>\n key && !event[eventKey(key)]\n\nexport function directionEnabled(mode: ModeOption | undefined, dir: 'x' | 'y', chart: Chart): boolean {\n if (mode === undefined) {\n return true\n } else if (typeof mode === 'string') {\n return mode.indexOf(dir) !== -1\n } else if (typeof mode === 'function') {\n return mode({ chart }).indexOf(dir) !== -1\n }\n\n return false\n}\n\nfunction directionsEnabled(mode: ModeOption | undefined, chart: Chart) {\n if (typeof mode === 'function') {\n mode = mode({ chart })\n }\n if (typeof mode === 'string') {\n return { x: mode.indexOf('x') !== -1, y: mode.indexOf('y') !== -1 }\n }\n\n return { x: false, y: false }\n}\n\nexport function debounce(fn: () => void, delay: number | undefined) {\n let timeout: number | NodeJS.Timeout\n return function () {\n clearTimeout(timeout)\n timeout = setTimeout(fn, delay)\n return delay\n }\n}\n\nfunction getScaleUnderPoint({ x, y }: Point, chart: Chart): Scale | null {\n const scales = chart.scales\n const scaleIds = Object.keys(scales)\n for (let i = 0; i < scaleIds.length; i++) {\n const scale = scales[scaleIds[i]]\n if (y >= scale.top && y <= scale.bottom && x >= scale.left && x <= scale.right) {\n return scale\n }\n }\n return null\n}\n\ntype EnabledDirections = { x: boolean; y: boolean }\n\nconst convertOverScaleMode = (\n chart: Chart,\n overScaleMode: ModeOption | undefined,\n scaleEnabled: EnabledDirections,\n enabled: EnabledDirections\n) => {\n if (!overScaleMode) {\n return\n }\n\n const overScaleEnabled = directionsEnabled(overScaleMode, chart)\n for (const axis of ['x', 'y'] as const) {\n if (overScaleEnabled[axis]) {\n scaleEnabled[axis] = enabled[axis]\n enabled[axis] = false\n }\n }\n}\n\nconst getEnabledScales = (chart: Chart, enabled: EnabledDirections): Scale[] => {\n const enabledScales: Scale[] = []\n\n for (const scaleItem of Object.values(chart.scales)) {\n if (enabled[scaleItem.axis as 'x' | 'y']) {\n enabledScales.push(scaleItem)\n }\n }\n\n return enabledScales || Object.values(chart.scales)\n}\n\n/**\n * Evaluate the chart's mode, scaleMode, and overScaleMode properties to\n * determine which axes are eligible for scaling.\n * options.overScaleMode can be a function if user want zoom only one scale of many for example.\n */\nexport function getEnabledScalesByPoint(options: PanOptions | undefined, point: Point, chart: Chart): Scale[] {\n const { mode = 'xy', scaleMode, overScaleMode } = options || {}\n const scale = getScaleUnderPoint(point, chart)\n\n const enabled = directionsEnabled(mode, chart)\n const scaleEnabled = directionsEnabled(scaleMode, chart)\n\n // Convert deprecated overScaleEnabled to new scaleEnabled.\n convertOverScaleMode(chart, overScaleMode, scaleEnabled, enabled)\n\n if (scale && scaleEnabled[scale.axis as 'x' | 'y']) {\n return [scale]\n }\n\n return getEnabledScales(chart, enabled)\n}\n","import { Chart, type Point } from 'chart.js'\nimport type { ZoomPluginOptions } from './options'\n\nexport type ScaleRange = { min: number; max: number }\nexport type OriginalLimits = { min: { scale?: number; options?: unknown }; max: { scale?: number; options?: unknown } }\nexport type OriginalScaleLimits = Record<string, OriginalLimits>\nexport type UpdatedScaleLimits = Record<string, ScaleRange>\n\nexport type HandlerFunctions = {\n click: (chart: Chart, event: MouseEvent, options: ZoomPluginOptions) => void\n keydown: (chart: Chart, event: KeyboardEvent) => void\n mousedown: (chart: Chart, event: MouseEvent, options: ZoomPluginOptions) => void\n mousemove: (chart: Chart, event: MouseEvent, options: ZoomPluginOptions) => void\n mouseup: (chart: Chart, event: MouseEvent, options: ZoomPluginOptions) => void\n onZoomComplete: ({ chart }: { chart: Chart }) => void\n wheel: (chart: Chart, event: WheelEvent) => void\n}\nexport type HandlerName = keyof HandlerFunctions\nexport type HandlerFunction = HandlerFunctions[HandlerName]\nexport type Handler = EventListener\nexport type Handlers = Partial<Record<HandlerName, Handler>>\n\nexport type HandlerTarget = Partial<Record<HandlerName, HTMLCanvasElement | Document>>\n\nexport interface State {\n originalScaleLimits: OriginalScaleLimits\n updatedScaleLimits: UpdatedScaleLimits\n handlers: Handlers\n targets: HandlerTarget\n panDelta: Record<string, number>\n dragging: boolean\n panning: boolean\n options: ZoomPluginOptions\n dragStart?: MouseEvent\n dragEnd?: MouseEvent\n filterNextClick?: boolean\n scale?: number | null\n delta?: Point | null\n panScales?: string[]\n}\n\nconst chartStates = new WeakMap<Chart, State>()\n\nexport function getState(chart: Chart): State {\n let state = chartStates.get(chart)\n if (!state) {\n state = {\n originalScaleLimits: {},\n updatedScaleLimits: {},\n handlers: {},\n options: {},\n targets: {},\n panDelta: {},\n dragging: false,\n panning: false,\n }\n chartStates.set(chart, state)\n }\n return state\n}\n\nexport function removeState(chart: Chart) {\n chartStates.delete(chart)\n}\n","import { almostEquals, isNullOrUndef, isNumber, valueOrDefault } from 'chart.js/helpers'\nimport { getState, type ScaleRange, type State } from './state'\nimport type { Point, Scale, TimeScale, TimeUnit } from 'chart.js'\nimport type { LimitOptions, ScaleLimits } from './options'\n\nexport type ZoomFunction = (scale: Scale, zoom: number, center: Point, limits: LimitOptions) => boolean\nexport type ZoomRectFunction = (scale: Scale, from: number, to: number, limits: LimitOptions) => boolean\nexport type PanFunction = (scale: Scale, delta: number, limits: LimitOptions) => boolean\n\nconst isTimeScale = (scale: Scale): scale is TimeScale => scale.type === 'time'\n\nconst isNotNumber = (value?: number): value is undefined => value === undefined || isNaN(value)\n\nexport function zoomDelta(\n val: number | undefined,\n min: number | undefined,\n range: number,\n newRange: number\n): ScaleRange {\n const minPercent = range && isNumber(val) && isNumber(min) ? Math.max(0, Math.min(1, (val - min) / range)) : 0\n const maxPercent = 1 - minPercent\n\n return {\n min: newRange * minPercent,\n max: newRange * maxPercent,\n }\n}\n\nfunction getValueAtPoint(scale: Scale, point: Point): number | undefined {\n const pixel = scale.isHorizontal() ? point.x : point.y\n\n return scale.getValueForPixel(pixel)\n}\n\nfunction linearZoomDelta(scale: Scale, zoom: number, center: Point): ScaleRange {\n const range = scale.max - scale.min\n const newRange = range * (zoom - 1)\n const centerValue = getValueAtPoint(scale, center)\n\n return zoomDelta(centerValue, scale.min, range, newRange)\n}\n\nfunction logarithmicZoomRange(scale: Scale, zoom: number, center: Point) {\n const centerValue = getValueAtPoint(scale, center)\n\n // Return the original range, if value could not be determined.\n if (centerValue === undefined) {\n return { min: scale.min, max: scale.max }\n }\n\n const logMin = Math.log10(scale.min)\n const logMax = Math.log10(scale.max)\n const logCenter = Math.log10(centerValue)\n const logRange = logMax - logMin\n const newLogRange = logRange * (zoom - 1)\n const delta = zoomDelta(logCenter, logMin, logRange, newLogRange)\n\n return {\n min: Math.pow(10, logMin + delta.min),\n max: Math.pow(10, logMax - delta.max),\n }\n}\n\nfunction getScaleLimits(scale: Scale, limits?: LimitOptions): ScaleLimits {\n return limits?.[scale.id] || limits?.[scale.axis] || {}\n}\n\nfunction getLimit(state: State, scale: Scale, scaleLimits: ScaleLimits, prop: 'min' | 'max', fallback: number): number {\n let limit = scaleLimits[prop]\n if (limit === 'original') {\n const original = state.originalScaleLimits[scale.id][prop]\n if (isNumber(original.options)) {\n return original.options\n }\n\n if (!isNullOrUndef(original.options)) {\n const parsed = scale.parse(original.options)\n if (isNumber(parsed)) {\n return parsed\n }\n }\n\n limit = original.scale\n }\n return valueOrDefault(limit, fallback)\n}\n\nfunction linearRange(scale: Scale, pixel0: number, pixel1: number): ScaleRange {\n const v0 = scale.getValueForPixel(pixel0) ?? scale.min\n const v1 = scale.getValueForPixel(pixel1) ?? scale.max\n return {\n min: Math.min(v0, v1),\n max: Math.max(v0, v1),\n }\n}\n\nfunction fixRange(\n range: number,\n { min, max, minLimit, maxLimit }: { min: number; max: number; minLimit: number; maxLimit: number },\n state: State,\n scale: Scale\n) {\n const offset = (range - max + min) / 2\n min -= offset\n max += offset\n\n // In case the values are really close to the original values, use the original values.\n const origLimits: ScaleLimits = { min: 'original', max: 'original' }\n const origMin = getLimit(state, scale, origLimits, 'min', -Infinity)\n const origMax = getLimit(state, scale, origLimits, 'max', Infinity)\n\n const epsilon = range / 1e6\n if (almostEquals(min, origMin, epsilon)) {\n min = origMin\n }\n if (almostEquals(max, origMax, epsilon)) {\n max = origMax\n }\n\n // Apply limits\n if (min < minLimit) {\n min = minLimit\n max = Math.min(minLimit + range, maxLimit)\n } else if (max > maxLimit) {\n max = maxLimit\n min = Math.max(maxLimit - range, minLimit)\n }\n\n return { min, max }\n}\n\nexport function updateRange(\n scale: Scale,\n { min, max }: ScaleRange,\n limits?: LimitOptions,\n zoom = false,\n pan = false\n): boolean {\n const state = getState(scale.chart)\n const { options: scaleOpts } = scale\n\n const scaleLimits = getScaleLimits(scale, limits)\n const { minRange = 0 } = scaleLimits\n const minLimit = getLimit(state, scale, scaleLimits, 'min', -Infinity)\n const maxLimit = getLimit(state, scale, scaleLimits, 'max', Infinity)\n\n if (pan && (min < minLimit || max > maxLimit)) {\n // At limit: No change but return true to indicate no need to store the delta.\n return true\n }\n\n const scaleRange = scale.max - scale.min\n const range = zoom ? Math.max(max - min, minRange) : scaleRange\n\n if (zoom && range === minRange && scaleRange <= minRange) {\n // At range limit: No change but return true to indicate no need to store the delta.\n return true\n }\n\n const newRange = fixRange(range, { min, max, minLimit, maxLimit }, state, scale)\n\n scaleOpts.min = newRange.min\n scaleOpts.max = newRange.max\n\n state.updatedScaleLimits[scale.id] = newRange\n\n // return true if the scale range is changed\n return scale.parse(newRange.min) !== scale.min || scale.parse(newRange.max) !== scale.max\n}\n\nfunction zoomNumericalScale(scale: Scale, zoom: number, center: Point, limits: LimitOptions) {\n const delta = linearZoomDelta(scale, zoom, center)\n const newRange = { min: scale.min + delta.min, max: scale.max - delta.max }\n return updateRange(scale, newRange, limits, true)\n}\n\nfunction zoomLogarithmicScale(scale: Scale, zoom: number, center: Point, limits: LimitOptions) {\n const newRange = logarithmicZoomRange(scale, zoom, center)\n return updateRange(scale, newRange, limits, true)\n}\n\nfunction zoomRectNumericalScale(scale: Scale, from: number, to: number, limits: LimitOptions) {\n return updateRange(scale, linearRange(scale, from, to), limits, true)\n}\n\nconst integerChange = (v: number) =>\n v === 0 || isNaN(v) ? 0 : v < 0 ? Math.min(Math.round(v), -1) : Math.max(Math.round(v), 1)\n\nfunction existCategoryFromMaxZoom(scale: Scale) {\n const labels = scale.getLabels()\n const maxIndex = labels.length - 1\n\n if (scale.min > 0) {\n scale.min -= 1\n }\n if (scale.max < maxIndex) {\n scale.max += 1\n }\n}\n\nfunction zoomCategoryScale(scale: Scale, zoom: number, center: Point, limits: LimitOptions) {\n const delta = linearZoomDelta(scale, zoom, center)\n if (scale.min === scale.max && zoom < 1) {\n existCategoryFromMaxZoom(scale)\n }\n const newRange = { min: scale.min + integerChange(delta.min), max: scale.max - integerChange(delta.max) }\n\n return updateRange(scale, newRange, limits, true)\n}\n\nfunction scaleLength(scale: Scale) {\n return scale.isHorizontal() ? scale.width : scale.height\n}\n\nfunction panCategoryScale(scale: Scale, delta: number, limits: LimitOptions) {\n const labels = scale.getLabels()\n const lastLabelIndex = labels.length - 1\n let { min, max } = scale\n // The visible range. Ticks can be skipped, and thus not reliable.\n const range = Math.max(max - min, 1)\n // How many pixels of delta is required before making a step. stepSize, but limited to max 1/10 of the scale length.\n const stepDelta = Math.round(scaleLength(scale) / Math.max(range, 10))\n const stepSize = Math.round(Math.abs(delta / stepDelta))\n let applied\n if (delta < -stepDelta) {\n max = Math.min(max + stepSize, lastLabelIndex)\n min = range === 1 ? max : max - range\n applied = max === lastLabelIndex\n } else if (delta > stepDelta) {\n min = Math.max(0, min - stepSize)\n max = range === 1 ? min : min + range\n applied = min === 0\n }\n\n return updateRange(scale, { min, max }, limits) || Boolean(applied)\n}\n\nconst OFFSETS: Record<TimeUnit, number> = {\n millisecond: 0,\n second: 500, // 500 ms\n minute: 30 * 1000, // 30 s\n hour: 30 * 60 * 1000, // 30 m\n day: 12 * 60 * 60 * 1000, // 12 h\n week: 3.5 * 24 * 60 * 60 * 1000, // 3.5 d\n month: 15 * 24 * 60 * 60 * 1000, // 15 d\n quarter: 60 * 24 * 60 * 60 * 1000, // 60 d\n year: 182 * 24 * 60 * 60 * 1000, // 182 d\n}\n\nfunction panNumericalScale(scale: Scale, delta: number, limits: LimitOptions, canZoom = false) {\n const { min: prevStart, max: prevEnd } = scale\n let offset = 0\n if (isTimeScale(scale)) {\n const round = scale.options.time?.round\n offset = round ? OFFSETS[round] : 0\n }\n const newMin = scale.getValueForPixel(scale.getPixelForValue(prevStart + offset) - delta)\n const newMax = scale.getValueForPixel(scale.getPixelForValue(prevEnd + offset) - delta)\n if (isNotNumber(newMin) || isNotNumber(newMax)) {\n // NaN can happen for 0-dimension scales (either because they were configured\n // with min === max or because the chart has 0 plottable area).\n return true\n }\n return updateRange(scale, { min: newMin, max: newMax }, limits, canZoom, true)\n}\n\nfunction panNonLinearScale(scale: Scale, delta: number, limits: LimitOptions) {\n return panNumericalScale(scale, delta, limits, true)\n}\n\nexport const zoomFunctions: Record<string, ZoomFunction> = {\n category: zoomCategoryScale,\n default: zoomNumericalScale,\n logarithmic: zoomLogarithmicScale,\n}\n\nexport const zoomRectFunctions: Record<string, ZoomRectFunction> = {\n default: zoomRectNumericalScale,\n}\n\nexport const panFunctions: Record<string, PanFunction> = {\n category: panCategoryScale,\n default: panNumericalScale,\n logarithmic: panNonLinearScale,\n timeseries: panNonLinearScale,\n}\n","import { isNumber, sign } from 'chart.js/helpers'\nimport { panFunctions, updateRange, zoomFunctions, zoomRectFunctions } from './scale.types.js'\nimport { getState, type OriginalScaleLimits, type ScaleRange, type State, type UpdatedScaleLimits } from './state.js'\nimport { directionEnabled, getEnabledScalesByPoint } from './utils.js'\nimport type { Chart, Point, Scale, UpdateMode } from 'chart.js'\nimport type { LimitOptions, PanTrigger, ZoomTrigger } from './options.js'\nimport type { ZoomAmount } from './types.js'\n\nfunction shouldUpdateScaleLimits(\n scale: Scale,\n originalScaleLimits: OriginalScaleLimits,\n updatedScaleLimits: UpdatedScaleLimits\n) {\n const {\n id,\n options: { min, max },\n } = scale\n if (!originalScaleLimits[id] || !updatedScaleLimits[id]) {\n return true\n }\n const previous = updatedScaleLimits[id]\n return previous.min !== min || previous.max !== max\n}\n\nfunction removeMissingScales(limits: OriginalScaleLimits | UpdatedScaleLimits, scales: Record<string, Scale>) {\n for (const key of Object.keys(limits)) {\n if (!scales[key]) {\n delete limits[key]\n }\n }\n}\n\nfunction storeOriginalScaleLimits(chart: Chart, state: State) {\n const { scales } = chart\n const { originalScaleLimits, updatedScaleLimits } = state\n\n for (const scale of Object.values(scales)) {\n if (shouldUpdateScaleLimits(scale, originalScaleLimits, updatedScaleLimits)) {\n originalScaleLimits[scale.id] = {\n min: { scale: scale.min, options: scale.options.min },\n max: { scale: scale.max, options: scale.options.max },\n }\n }\n }\n\n removeMissingScales(originalScaleLimits, scales)\n removeMissingScales(updatedScaleLimits, scales)\n return originalScaleLimits\n}\n\nfunction doZoom(scale: Scale, amount: number, center: Point, limits: LimitOptions) {\n const fn = zoomFunctions[scale.type] || zoomFunctions.default\n fn?.(scale, amount, center, limits)\n}\n\nfunction doZoomRect(scale: Scale, from: number, to: number, limits: LimitOptions) {\n const fn = zoomRectFunctions[scale.type] || zoomRectFunctions.default\n fn?.(scale, from, to, limits)\n}\n\nfunction getCenter(chart: Chart) {\n const ca = chart.chartArea\n return {\n x: (ca.left + ca.right) / 2,\n y: (ca.top + ca.bottom) / 2,\n }\n}\n\nexport function zoom(chart: Chart, amount: ZoomAmount, transition: UpdateMode = 'none', trigger: ZoomTrigger = 'api') {\n const { x = 1, y = 1, focalPoint = getCenter(chart) } = typeof amount === 'number' ? { x: amount, y: amount } : amount\n const state = getState(chart)\n const {\n options: { limits = {}, zoom: zoomOptions },\n } = state\n\n storeOriginalScaleLimits(chart, state)\n\n const xEnabled = x !== 1\n const yEnabled = y !== 1\n const enabledScales = getEnabledScalesByPoint(zoomOptions, focalPoint, chart)\n\n for (const scale of enabledScales) {\n if (scale.isHorizontal() && xEnabled) {\n doZoom(scale, x, focalPoint, limits)\n } else if (!scale.isHorizontal() && yEnabled) {\n doZoom(scale, y, focalPoint, limits)\n }\n }\n\n chart.update(transition)\n\n zoomOptions?.onZoom?.({ chart, trigger, amount: { x, y, focalPoint } })\n}\n\nexport function zoomRect(\n chart: Chart,\n p0: Point,\n p1: Point,\n transition: UpdateMode = 'none',\n trigger: ZoomTrigger = 'api'\n) {\n const state = getState(chart)\n const {\n options: { limits = {}, zoom: zoomOptions = {} },\n } = state\n const { mode = 'xy' } = zoomOptions\n\n storeOriginalScaleLimits(chart, state)\n const xEnabled = directionEnabled(mode, 'x', chart)\n const yEnabled = directionEnabled(mode, 'y', chart)\n\n for (const scale of Object.values(chart.scales)) {\n if (scale.isHorizontal() && xEnabled) {\n doZoomRect(scale, p0.x, p1.x, limits)\n } else if (!scale.isHorizontal() && yEnabled) {\n doZoomRect(scale, p0.y, p1.y, limits)\n }\n }\n\n chart.update(transition)\n\n zoomOptions.onZoom?.({ chart, trigger })\n}\n\nexport function zoomScale(\n chart: Chart,\n scaleId: string,\n range: ScaleRange,\n transition: UpdateMode = 'none',\n trigger: ZoomTrigger = 'api'\n) {\n const state = getState(chart)\n storeOriginalScaleLimits(chart, state)\n const scale = chart.scales[scaleId]\n updateRange(scale, range, undefined, true)\n chart.update(transition)\n\n state.options.zoom?.onZoom?.({ chart, trigger })\n}\n\nexport function resetZoom(chart: Chart, transition: UpdateMode = 'default') {\n const state = getState(chart)\n const originalScaleLimits = storeOriginalScaleLimits(chart, state)\n\n for (const scale of Object.values(chart.scales)) {\n const scaleOptions = scale.options\n if (originalScaleLimits[scale.id]) {\n scaleOptions.min = originalScaleLimits[scale.id].min.options\n scaleOptions.max = originalScaleLimits[scale.id].max.options\n } else {\n delete scaleOptions.min\n delete scaleOptions.max\n }\n delete state.updatedScaleLimits[scale.id]\n }\n chart.update(transition)\n\n state.options.zoom?.onZoomComplete?.({ chart })\n}\n\nfunction getOriginalRange(state: State, scaleId: string): number | undefined {\n const original = state.originalScaleLimits[scaleId]\n if (!original) {\n return undefined\n }\n const { min, max } = original\n if (isNumber(max.options) && isNumber(min.options)) {\n return max.options - min.options\n }\n if (isNumber(max.scale) && isNumber(min.scale)) {\n return max.scale - min.scale\n }\n return undefined\n}\n\nexport function getZoomLevel(chart: Chart) {\n const state = getState(chart)\n let min = 1\n let max = 1\n for (const scale of Object.values(chart.scales)) {\n const origRange = getOriginalRange(state, scale.id)\n if (origRange) {\n const level = Math.round((origRange / (scale.max - scale.min)) * 100) / 100\n min = Math.min(min, level)\n max = Math.max(max, level)\n }\n }\n return min < 1 ? min : max\n}\n\nfunction panScale(scale: Scale, delta: number, limits: LimitOptions, state: State) {\n const { panDelta } = state\n // Add possible cumulative delta from previous pan attempts where scale did not change\n const storedDelta = panDelta[scale.id] || 0\n if (sign(storedDelta) === sign(delta)) {\n delta += storedDelta\n }\n const fn = panFunctions[scale.type] || panFunctions.default\n if (fn?.(scale, delta, limits)) {\n // The scale changed, reset cumulative delta\n panDelta[scale.id] = 0\n } else {\n // The scale did not change, store cumulative delta\n panDelta[scale.id] = delta\n }\n}\n\ntype PanAmount = number | Partial<Point>\n\nexport function pan(\n chart: Chart,\n delta: PanAmount,\n enabledScales?: Scale[],\n transition: UpdateMode = 'none',\n trigger: PanTrigger = 'other'\n) {\n const { x = 0, y = 0 } = typeof delta === 'number' ? { x: delta, y: delta } : delta\n const state = getState(chart)\n const {\n options: { pan: panOptions, limits = {} },\n } = state\n const { onPan } = panOptions || {}\n\n storeOriginalScaleLimits(chart, state)\n\n const xEnabled = x !== 0\n const yEnabled = y !== 0\n\n const scales = enabledScales || Object.values(chart.scales)\n\n for (const scale of scales) {\n if (scale.isHorizontal() && xEnabled) {\n panScale(scale, x, limits, state)\n } else if (!scale.isHorizontal() && yEnabled) {\n panScale(scale, y, limits, state)\n }\n }\n\n chart.update(transition)\n\n onPan?.({ chart, trigger, delta: { x, y } })\n}\n\nexport function getInitialScaleBounds(chart: Chart) {\n const state = getState(chart)\n storeOriginalScaleLimits(chart, state)\n const scaleBounds: Record<string, { min?: number; max?: number }> = {}\n for (const scaleId of Object.keys(chart.scales)) {\n const { min, max } = state.originalScaleLimits[scaleId] || { min: {}, max: {} }\n scaleBounds[scaleId] = { min: min.scale, max: max.scale }\n }\n\n return scaleBounds\n}\n\nexport function getZoomedScaleBounds(chart: Chart) {\n const state = getState(chart)\n const scaleBounds: Record<string, { min?: number; max?: number }> = {}\n for (const scaleId of Object.keys(chart.scales)) {\n scaleBounds[scaleId] = state.updatedScaleLimits[scaleId]\n }\n\n return scaleBounds\n}\n\nexport function isZoomedOrPanned(chart: Chart) {\n const scaleBounds = getInitialScaleBounds(chart)\n for (const scaleId of Object.keys(chart.scales)) {\n const { min: originalMin, max: originalMax } = scaleBounds[scaleId]\n\n if (originalMin !== undefined && chart.scales[scaleId].min !== originalMin) {\n return true\n }\n\n if (originalMax !== undefined && chart.scales[scaleId].max !== originalMax) {\n return true\n }\n }\n\n return false\n}\n\nexport function isZoomingOrPanningState(state: State) {\n return state.panning || state.dragging\n}\n\nexport function isZoomingOrPanning(chart: Chart) {\n const state = getState(chart)\n // From the perspective of outside callers, zooming and panning are still\n // active if we haven't yet cleared the next click.\n return !!(isZoomingOrPanningState(state) || state.filterNextClick)\n}\n","import { directionEnabled, debounce, keyNotPressed, getModifierKey, keyPressed } from './utils'\nimport { zoom, zoomRect } from './core'\nimport { getRelativePosition, _isPointInArea } from 'chart.js/helpers'\nimport { getState, type HandlerFunctions, type HandlerName } from './state'\nimport type { Chart, ChartArea, Point } from 'chart.js'\nimport type { ModeOption, ZoomOptions, ZoomPluginOptions } from './options'\n\nconst clamp = (x: number, from: number, to: number): number => Math.min(to, Math.max(from, x))\n\nfunction removeHandler(chart: Chart, type: HandlerName) {\n const { handlers, targets } = getState(chart)\n const handler = handlers[type]\n const target = targets[type]\n if (handler && target) {\n target.removeEventListener(type, handler)\n delete handlers[type]\n }\n}\n\ntype EventHandler<T extends Event> = (chart: Chart, event: T, options: ZoomPluginOptions) => void\n\nfunction addHandler<T extends Event>(\n chart: Chart,\n target: HTMLCanvasElement | Document,\n type: HandlerName,\n handler: EventHandler<T>\n) {\n const { handlers, options, targets } = getState(chart)\n const oldHandler = handlers[type]\n if (oldHandler && targets[type] === target) {\n // already attached\n return\n }\n removeHandler(chart, type)\n const listener = (handlers[type] = (event) => handler(chart, event as T, options))\n targets[type] = target\n\n // `passive: false` for wheel events, to prevent chrome warnings. Use default value for other events.\n const passive = type === 'wheel' ? false : undefined\n target.addEventListener(type, listener, { passive })\n}\n\nexport function mouseMove(chart: Chart, event: MouseEvent) {\n const state = getState(chart)\n if (state.dragStart) {\n state.dragging = true\n state.dragEnd = event\n chart.draw()\n }\n}\n\nfunction keyDown(chart: Chart, event: KeyboardEvent) {\n const state = getState(chart)\n if (!state.dragStart || event.key !== 'Escape') {\n return\n }\n\n removeHandler(chart, 'keydown')\n state.dragging = false\n state.dragStart = state.dragEnd = undefined\n chart.draw()\n}\n\nfunction getPointPosition(event: MouseEvent, chart: Chart) {\n if (event.target !== chart.canvas) {\n const canvasArea = chart.canvas.getBoundingClientRect()\n return {\n x: event.clientX - canvasArea.left,\n y: event.clientY - canvasArea.top,\n }\n }\n return getRelativePosition(event, chart as any) // TODO: would expect Chart type to be valid for getRelativePosition\n}\n\nfunction zoomStart(chart: Chart, event: MouseEvent, zoomOptions: ZoomOptions): boolean | void {\n const { onZoomStart, onZoomRejected } = zoomOptions\n if (onZoomStart) {\n const point = getPointPosition(event, chart)\n if (onZoomStart?.({ chart, event, point }) === false) {\n onZoomRejected?.({ chart, event })\n return false\n }\n }\n}\n\nexport function mouseDown(chart: Chart, event: MouseEvent): void {\n if (chart.legend) {\n const point = getRelativePosition(event, chart as any) // TODO: would expect Chart type to be valid for getRelativePosition\n if (_isPointInArea(point, chart.legend)) {\n return\n }\n }\n const state = getState(chart)\n const { pan: panOptions, zoom: zoomOptions = {} } = state.options\n if (\n event.button !== 0 ||\n keyPressed(getModifierKey(panOptions), event) ||\n keyNotPressed(getModifierKey(zoomOptions.drag), event)\n ) {\n return zoomOptions.onZoomRejected?.({ chart, event })\n }\n\n if (zoomStart(chart, event, zoomOptions) === false) {\n return\n }\n state.dragStart = event\n\n addHandler(chart, chart.canvas.ownerDocument, 'mousemove', mouseMove)\n addHandler(chart, window.document, 'keydown', keyDown)\n}\n\nfunction applyAspectRatio(\n { begin, end }: { begin: { x: number; y: number }; end: { x: number; y: number } },\n aspectRatio: number\n) {\n let width = end.x - begin.x\n let height = end.y - begin.y\n const ratio = Math.abs(width / height)\n\n if (ratio > aspectRatio) {\n width = Math.sign(width) * Math.abs(height * aspectRatio)\n } else if (ratio < aspectRatio) {\n height = Math.sign(height) * Math.abs(width / aspectRatio)\n }\n\n end.x = begin.x + width\n end.y = begin.y + height\n}\n\ntype Rect = { top?: number; left?: number; right?: number; bottom?: number }\nfunction applyMinMaxProps(\n rect: Rect,\n chartArea: ChartArea,\n points: { begin: Point; end: Point },\n { min, max, prop }: { min: keyof Rect; max: keyof Rect; prop: 'x' | 'y' }\n) {\n rect[min] = clamp(Math.min(points.begin[prop], points.end[prop]), chartArea[min], chartArea[max])\n rect[max] = clamp(Math.max(points.begin[prop], points.end[prop]), chartArea[min], chartArea[max])\n}\n\nfunction getRelativePoints(\n chart: Chart,\n pointEvents: { dragStart: MouseEvent; dragEnd: MouseEvent },\n maintainAspectRatio?: boolean\n) {\n const points = {\n begin: getPointPosition(pointEvents.dragStart, chart),\n end: getPointPosition(pointEvents.dragEnd, chart),\n }\n\n if (maintainAspectRatio) {\n const aspectRatio = chart.chartArea.width / chart.chartArea.height\n applyAspectRatio(points, aspectRatio)\n }\n\n return points\n}\n\nexport function computeDragRect(\n chart: Chart,\n mode: ModeOption | undefined,\n pointEvents: { dragStart: MouseEvent; dragEnd: MouseEvent },\n maintainAspectRatio: boolean | undefined\n) {\n const xEnabled = directionEnabled(mode, 'x', chart)\n const yEnabled = directionEnabled(mode, 'y', chart)\n const { top, left, right, bottom, width: chartWidth, height: chartHeight } = chart.chartArea\n const rect = { top, left, right, bottom }\n\n const points = getRelativePoints(chart, pointEvents, maintainAspectRatio && xEnabled && yEnabled)\n\n if (xEnabled) {\n applyMinMaxProps(rect, chart.chartArea, points, { min: 'left', max: 'right', prop: 'x' })\n }\n\n if (yEnabled) {\n applyMinMaxProps(rect, chart.chartArea, points, { min: 'top', max: 'bottom', prop: 'y' })\n }\n\n const width = rect.right - rect.left\n const height = rect.bottom - rect.top\n\n return {\n ...rect,\n width,\n height,\n zoomX: xEnabled && width ? 1 + (chartWidth - width) / chartWidth : 1,\n zoomY: yEnabled && height ? 1 + (chartHeight - height) / chartHeight : 1,\n }\n}\n\nexport function mouseUp(chart: Chart, event: MouseEvent) {\n const state = getState(chart)\n if (!state.dragStart) {\n return\n }\n\n removeHandler(chart, 'mousemove')\n const { mode, onZoomComplete, drag } = state.options.zoom ?? {}\n const { threshold = 0, maintainAspectRatio } = drag ?? {}\n const rect = computeDragRect(chart, mode, { dragStart: state.dragStart, dragEnd: event }, maintainAspectRatio)\n const distanceX = directionEnabled(mode, 'x', chart) ? rect.width : 0\n const distanceY = directionEnabled(mode, 'y', chart) ? rect.height : 0\n const distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY)\n\n // Remove drag start and end before chart render to stop drawing selected area\n state.dragStart = state.dragEnd = undefined\n\n if (distance <= threshold) {\n state.dragging = false\n chart.draw()\n return\n }\n\n zoomRect(chart, { x: rect.left, y: rect.top }, { x: rect.right, y: rect.bottom }, 'zoom', 'drag')\n\n state.dragging = false\n state.filterNextClick = true\n onZoomComplete?.({ chart })\n}\n\nfunction wheelPreconditions(chart: Chart, event: WheelEvent, zoomOptions: ZoomOptions): true | void {\n // Before preventDefault, check if the modifier key required and pressed\n if (keyNotPressed(getModifierKey(zoomOptions.wheel), event)) {\n zoomOptions.onZoomRejected?.({ chart, event })\n return\n }\n\n if (zoomStart(chart, event, zoomOptions) === false) {\n return\n }\n\n // Prevent the event from triggering the default behavior (e.g. content scrolling).\n if (event.cancelable) {\n event.preventDefault()\n }\n\n // Firefox always fires the wheel event twice:\n // First without the delta and right after that once with the delta properties.\n if (event.deltaY === undefined) {\n return\n }\n return true\n}\n\nexport function wheel(chart: Chart, event: WheelEvent & { target?: HTMLCanvasElement }) {\n const {\n handlers: { onZoomComplete },\n options: { zoom: zoomOptions = {} },\n } = getState(chart)\n\n if (!wheelPreconditions(chart, event, zoomOptions)) {\n return\n }\n\n const rect = event.target?.getBoundingClientRect()\n const speed = zoomOptions?.wheel?.speed ?? 0.1\n const percentage = event.deltaY >= 0 ? 2 - 1 / (1 - speed) : 1 + speed\n const amount = {\n x: percentage,\n y: percentage,\n focalPoint: {\n x: event.clientX - rect.left,\n y: event.clientY - rect.top,\n },\n }\n\n zoom(chart, amount, 'zoom', 'wheel')\n\n onZoomComplete?.(event)\n}\n\nfunction addDebouncedHandler(\n chart: Chart,\n name: HandlerName,\n handler: HandlerFunctions['onZoomComplete'] | undefined,\n delay: number\n) {\n if (handler) {\n getState(chart).handlers[name] = debounce(() => handler?.({ chart }), delay)\n }\n}\n\nexport function addListeners(chart: Chart, options: ZoomPluginOptions) {\n const canvas = chart.canvas\n const { wheel: wheelOptions, drag: dragOptions, onZoomComplete } = options.zoom ?? {}\n\n // Install listeners. Do this dynamically based on options so that we can turn zoom on and off\n // We also want to make sure listeners aren't always on. E.g. if you're scrolling down a page\n // and the mouse goes over a chart you don't want it intercepted unless the plugin is enabled\n if (wheelOptions?.enabled) {\n addHandler(chart, canvas, 'wheel', wheel)\n addDebouncedHandler(chart, 'onZoomComplete', onZoomComplete, 250)\n } else {\n removeHandler(chart, 'wheel')\n }\n if (dragOptions?.enabled) {\n addHandler(chart, canvas, 'mousedown', mouseDown)\n addHandler(chart, canvas.ownerDocument, 'mouseup', mouseUp)\n } else {\n removeHandler(chart, 'mousedown')\n removeHandler(chart, 'mousemove')\n removeHandler(chart, 'mouseup')\n removeHandler(chart, 'keydown')\n }\n}\n\nexport function removeListeners(chart: Chart) {\n removeHandler(chart, 'mousedown')\n removeHandler(chart, 'mousemove')\n removeHandler(chart, 'mouseup')\n removeHandler(chart, 'wheel')\n removeHandler(chart, 'click')\n removeHandler(chart, 'keydown')\n}\n","import { getRelativePosition } from 'chart.js/helpers'\nimport Hammer from 'hammerjs'\nimport { pan, zoom } from './core'\nimport { getState, type State } from './state'\nimport { directionEnabled, getEnabledScalesByPoint, getModifierKey, keyNotPressed, keyPressed } from './utils'\nimport type { Chart } from 'chart.js'\nimport type { ZoomPluginOptions } from './options'\n\nfunction createEnabler(chart: Chart, state: State) {\n return function (_recognizer: any, event: HammerInput) {\n const { pan: panOptions, zoom: zoomOptions = {} } = state.options\n if (!panOptions || !panOptions.enabled) {\n return false\n }\n const srcEvent = event && event.srcEvent\n if (!srcEvent) {\n // Sometimes Hammer queries this with a null event.\n return true\n }\n if (\n !state.panning &&\n event.pointerType === 'mouse' &&\n (keyNotPressed(getModifierKey(panOptions), srcEvent) || keyPressed(getModifierKey(zoomOptions.drag), srcEvent))\n ) {\n panOptions.onPanRejected?.({ chart, event })\n return false\n }\n return true\n }\n}\n\nfunction pinchAxes(p0: { clientX: number; clientY: number }, p1: { clientX: number; clientY: number }) {\n // fingers position difference\n const pinchX = Math.abs(p0.clientX - p1.clientX)\n const pinchY = Math.abs(p0.clientY - p1.clientY)\n\n // diagonal fingers will change both (xy) axes\n const p = pinchX / pinchY\n let x, y\n if (p > 0.3 && p < 1.7) {\n x = y = true\n } else if (pinchX > pinchY) {\n x = true\n } else {\n y = true\n }\n return { x, y }\n}\n\nfunction handlePinch(chart: Chart, state: State, e: HammerInput) {\n if (state.scale) {\n const { center, pointers } = e\n // Hammer reports the total scaling. We need the incremental amount\n const zoomPercent = (1 / state.scale) * e.scale\n const rect = e.target.getBoundingClientRect()\n const pinch = pinchAxes(pointers[0], pointers[1])\n const mode = state.options.zoom?.mode\n const amount = {\n x: pinch.x && directionEnabled(mode, 'x', chart) ? zoomPercent : 1,\n y: pinch.y && directionEnabled(mode, 'y', chart) ? zoomPercent : 1,\n focalPoint: {\n x: center.x - rect.left,\n y: center.y - rect.top,\n },\n }\n\n zoom(chart, amount, 'zoom', 'pinch')\n\n // Keep track of overall scale\n state.scale = e.scale\n }\n}\n\nfunction startPinch(chart: Chart, state: State, e: HammerInput) {\n if (state.options.zoom?.pinch?.enabled) {\n const point = getRelativePosition(e.srcEvent, chart as any) // TODO: would expect Chart type to be valid for getRelativePosition\n if (state.options.zoom?.onZoomStart?.({ chart, event: e.srcEvent, point }) === false) {\n state.scale = null\n state.options.zoom?.onZoomRejected?.({ chart, event: e.srcEvent })\n } else {\n state.scale = 1\n }\n }\n}\n\nfunction endPinch(chart: Chart, state: State, e: HammerInput) {\n if (state.scale) {\n handlePinch(chart, state, e)\n state.scale = null // reset\n state.options.zoom?.onZoomComplete?.({ chart })\n }\n}\n\nfunction handlePan(chart: Chart, state: State, e: HammerInput) {\n const delta = state.delta\n if (delta) {\n state.panning = true\n pan(\n chart,\n { x: e.deltaX - delta.x, y: e.deltaY - delta.y },\n state.panScales && state.panScales.map((i) => chart.scales[i]).filter(Boolean)\n )\n state.delta = { x: e.deltaX, y: e.deltaY }\n }\n}\n\nfunction startPan(chart: Chart, state: State, event: HammerInput) {\n const { enabled, onPanStart, onPanRejected } = state.options.pan ?? {}\n if (!enabled) {\n return\n }\n const rect = event.target.getBoundingClientRect()\n const point = {\n x: event.center.x - rect.left,\n y: event.center.y - rect.top,\n }\n\n if (onPanStart?.({ chart, event, point }) === false) {\n return onPanRejected?.({ chart, event })\n }\n\n state.panScales = getEnabledScalesByPoint(state.options.pan, point, chart).map((i) => i.id)\n state.delta = { x: 0, y: 0 }\n handlePan(chart, state, event)\n}\n\nfunction endPan(chart: Chart, state: State) {\n state.delta = null\n if (state.panning) {\n state.panning = false\n state.filterNextClick = true\n state.options.pan?.onPanComplete?.({ chart })\n }\n}\n\nconst hammers = new WeakMap()\nexport function startHammer(chart: Chart, options: ZoomPluginOptions) {\n const state = getState(chart)\n const canvas = chart.canvas\n const { pan: panOptions, zoom: zoomOptions } = options\n\n const mc = new Hammer.Manager(canvas)\n if (zoomOptions?.pinch?.enabled) {\n mc.add(new Hammer.Pinch())\n mc.on('pinchstart', (e) => startPinch(chart, state, e))\n mc.on('pinch', (e) => handlePinch(chart, state, e))\n mc.on('pinchend', (e) => endPinch(chart, state, e))\n }\n\n if (panOptions && panOptions.enabled) {\n mc.add(\n new Hammer.Pan({\n threshold: panOptions.threshold,\n enable: createEnabler(chart, state),\n })\n )\n mc.on('panstart', (e) => startPan(chart, state, e))\n mc.on('panmove', (e) => handlePan(chart, state, e))\n mc.on('panend', () => endPan(chart, state))\n }\n\n hammers.set(chart, mc)\n}\n\nexport function stopHammer(chart: Chart) {\n const mc = hammers.get(chart)\n if (mc) {\n mc.remove('pinchstart')\n mc.remove('pinch')\n mc.remove('pinchend')\n mc.remove('panstart')\n mc.remove('pan')\n mc.remove('panend')\n mc.destroy()\n hammers.delete(chart)\n }\n}\n\nexport function hammerOptionsChanged(oldOptions: ZoomPluginOptions, newOptions: ZoomPluginOptions) {\n const { pan: oldPan, zoom: oldZoom } = oldOptions\n const { pan: newPan, zoom: newZoom } = newOptions\n\n if (oldZoom?.pinch?.enabled !== newZoom?.pinch?.enabled) {\n return true\n }\n if (oldPan?.enabled !== newPan?.enabled) {\n return true\n }\n if (oldPan?.threshold !== newPan?.threshold) {\n return true\n }\n\n return false\n}\n","import Hammer from 'hammerjs'\nimport { addListeners, computeDragRect, removeListeners } from './handlers'\nimport { hammerOptionsChanged, startHammer, stopHammer } from './hammer'\nimport {\n pan,\n zoom,\n resetZoom,\n zoomScale,\n getZoomLevel,\n getInitialScaleBounds,\n getZoomedScaleBounds,\n isZoomedOrPanned,\n isZoomingOrPanning,\n isZoomingOrPanningState,\n zoomRect,\n} from './core'\nimport { panFunctions, zoomFunctions, zoomRectFunctions } from './scale.types'\nimport { getState, removeState } from './state'\nimport { version } from '../package.json'\nimport type { Chart, ChartEvent } from 'chart.js'\nimport type { ZoomPluginOptions } from './options'\nimport { defaults } from './defaults'\n\nfunction draw(chart: Chart, caller: string, options: ZoomPluginOptions) {\n const dragOptions = options.zoom?.drag\n const { dragStart, dragEnd } = getState(chart)\n\n if (dragOptions?.drawTime !== caller || !dragStart || !dragEnd) {\n return\n }\n const { left, top, width, height } = computeDragRect(\n chart,\n options.zoom?.mode,\n { dragStart, dragEnd },\n dragOptions.maintainAspectRatio\n )\n const ctx = chart.ctx\n\n ctx.save()\n ctx.beginPath()\n ctx.fillStyle = dragOptions.backgroundColor || 'rgba(225,225,225,0.3)'\n ctx.fillRect(left, top, width, height)\n\n if (dragOptions.borderWidth) {\n ctx.lineWidth = dragOptions.borderWidth\n ctx.strokeStyle = dragOptions.borderColor || 'rgba(225,225,225)'\n ctx.strokeRect(left, top, width, height)\n }\n ctx.restore()\n}\n\nconst bindApi = (chart: Chart) => {\n chart.pan = (delta, panScales, transition) => pan(chart, delta, panScales, transition, 'api')\n chart.zoom = (args, transition) => zoom(chart, args, transition)\n chart.zoomRect = (p0, p1, transition) => zoomRect(chart, p0, p1, transition)\n chart.zoomScale = (id, range, transition) => zoomScale(chart, id, range, transition)\n chart.resetZoom = (transition) => resetZoom(chart, transition)\n chart.getZoomLevel = () => getZoomLevel(chart)\n chart.getInitialScaleBounds = () => getInitialScaleBounds(chart)\n chart.getZoomedScaleBounds = () => getZoomedScaleBounds(chart)\n chart.isZoomedOrPanned = () => isZoomedOrPanned(chart)\n chart.isZoomingOrPanning = () => isZoomingOrPanning(chart)\n}\n\nexport default {\n id: 'zoom',\n\n version,\n\n defaults,\n\n start(chart: Chart, _args: unknown, options: ZoomPluginOptions) {\n const state = getState(chart)\n state.options = options\n\n if (Object.prototype.hasOwnProperty.call(options.zoom, 'enabled')) {\n console.warn(\n 'The option `zoom.enabled` is no longer supported. Please use `zoom.wheel.enabled`, `zoom.drag.enabled`, or `zoom.pinch.enabled`.'\n )\n }\n if (\n Object.prototype.hasOwnProperty.call(options.zoom, 'overScaleMode') ||\n Object.prototype.hasOwnProperty.call(options.pan, 'overScaleMode')\n ) {\n console.warn(\n 'The option `overScaleMode` is deprecated. Please use `scaleMode` instead (and update `mode` as desired).'\n )\n }\n\n if (Hammer) {\n startHammer(chart, options)\n }\n\n bindApi(chart)\n },\n\n beforeEvent(\n chart: Chart,\n { event }: { event: ChartEvent; replay: boolean; cancelable: true; inChartArea: boolean }\n ): boolean | void {\n const state = getState(chart)\n if (isZoomingOrPanningState(state)) {\n // cancel any event handling while panning or dragging\n return false\n }\n // cancel the next click or mouseup after drag or pan\n if (event.type === 'click' || event.type === 'mouseup') {\n if (state.filterNextClick) {\n state.filterNextClick = false\n return false\n }\n }\n },\n\n beforeUpdate(chart: Chart, _args: unknown, options: ZoomPluginOptions) {\n const state = getState(chart)\n const previousOptions = state.options\n state.options = options\n\n // Hammer needs to be restarted when certain options change.\n if (hammerOptionsChanged(previousOptions, options)) {\n stopHammer(chart)\n startHammer(chart, options)\n }\n\n addListeners(chart, options)\n },\n\n beforeDatasetsDraw(chart: Chart, _args: unknown, options: ZoomPluginOptions) {\n draw(chart, 'beforeDatasetsDraw', options)\n },\n\n afterDatasetsDraw(chart: Chart, _args: unknown, options: ZoomPluginOptions) {\n draw(chart, 'afterDatasetsDraw', options)\n },\n\n beforeDraw(chart: Chart, _args: unknown, options: ZoomPluginOptions) {\n draw(chart, 'beforeDraw', options)\n },\n\n afterDraw(chart: Chart, _args: unknown, options: ZoomPluginOptions) {\n draw(chart, 'afterDraw', options)\n },\n\n stop(chart: Chart) {\n removeListeners(chart)\n\n if (Hammer) {\n stopHammer(chart)\n }\n removeState(chart)\n },\n\n panFunctions,\n zoomFunctions,\n zoomRectFunctions,\n}\n","import type { ZoomPluginOptions } from './options'\n\nexport const defaults: ZoomPluginOptions = {\n pan: {\n enabled: false,\n mode: 'xy',\n threshold: 10,\n modifierKey: null,\n },\n zoom: {\n wheel: {\n enabled: false,\n speed: 0.1,\n modifierKey: null,\n },\n drag: {\n enabled: false,\n drawTime: 'beforeDatasetsDraw',\n modifierKey: null,\n },\n pinch: {\n enabled: false,\n },\n mode: 'xy',\n },\n}\n","import { Chart } from 'chart.js'\nimport Zoom from './plugin'\n\nChart.register(Zoom)\n\nexport default Zoom\n"],"names":["eventKey","key","getModifierKey","opts","enabled","modifierKey","undefined","keyPressed","event","keyNotPressed","directionEnabled","mode","dir","chart","indexOf","directionsEnabled","x","y","getEnabledScalesByPoint","options","point","scaleMode","overScaleMode","scale","scales","scaleIds","Object","keys","i","length","top","bottom","left","right","getScaleUnderPoint","scaleEnabled","overScaleEnabled","axis","convertOverScaleMode","enabledScales","scaleItem","values","push","getEnabledScales","chartStates","WeakMap","getState","state","get","originalScaleLimits","updatedScaleLimits","handlers","targets","panDelta","dragging","panning","set","isNotNumber","value","isNaN","zoomDelta","val","min","range","newRange","minPercent","isNumber","Math","max","getValueAtPoint","pixel","isHorizontal","getValueForPixel","linearZoomDelta","zoom","center","getLimit","scaleLimits","prop","fallback","limit","original","id","isNullOrUndef","parsed","parse","valueOrDefault","updateRange","limits","pan","scaleOpts","getScaleLimits","minRange","minLimit","Infinity","maxLimit","scaleRange","offset","origLimits","origMin","origMax","epsilon","almostEquals","fixRange","integerChange","v","round","OFFSETS","millisecond","second","minute","hour","day","week","month","quarter","year","panNumericalScale","delta","canZoom","prevStart","prevEnd","type","isTimeScale","time","newMin","getPixelForValue","newMax","panNonLinearScale","zoomFunctions","category","maxIndex","getLabels","existCategoryFromMaxZoom","default","logarithmic","centerValue","logMin","log10","logMax","logRange","pow","logarithmicZoomRange","zoomRectFunctions","from","to","pixel0","pixel1","v0","v1","linearRange","panFunctions","lastLabelIndex","stepDelta","width","height","scaleLength","stepSize","abs","applied","Boolean","timeseries","shouldUpdateScaleLimits","previous","removeMissingScales","storeOriginalScaleLimits","doZoom","amount","fn","doZoomRect","getCenter","ca","chartArea","transition","trigger","focalPoint","zoomOptions","xEnabled","yEnabled","update","onZoom","zoomRect","p0","p1","getOriginalRange","scaleId","panScale","storedDelta","sign","panOptions","onPan","getInitialScaleBounds","scaleBounds","isZoomingOrPanningState","clamp","removeHandler","handler","target","removeEventListener","addHandler","listener","passive","addEventListener","mouseMove","dragStart","dragEnd","draw","keyDown","getPointPosition","canvas","canvasArea","getBoundingClientRect","clientX","clientY","getRelativePosition","zoomStart","onZoomStart","onZoomRejected","mouseDown","legend","_isPointInArea","button","drag","ownerDocument","window","document","applyMinMaxProps","rect","points","begin","end","getRelativePoints","pointEvents","maintainAspectRatio","aspectRatio","ratio","applyAspectRatio","computeDragRect","chartWidth","chartHeight","zoomX","zoomY","mouseUp","onZoomComplete","threshold","distanceX","distanceY","distance","sqrt","filterNextClick","wheel","cancelable","preventDefault","deltaY","wheelPreconditions","speed","percentage","addDebouncedHandler","name","delay","timeout","clearTimeout","setTimeout","debounce","createEnabler","_recognizer","srcEvent","pointerType","onPanRejected","handlePinch","e","pointers","zoomPercent","pinch","pinchX","pinchY","p","pinchAxes","handlePan","deltaX","panScales","map","filter","hammers","startHammer","mc","Hammer","Manager","add","Pinch","on","startPinch","endPinch","Pan","enable","onPanStart","startPan","onPanComplete","endPan","stopHammer","remove","destroy","delete","caller","dragOptions","drawTime","ctx","save","beginPath","fillStyle","backgroundColor","fillRect","borderWidth","lineWidth","strokeStyle","borderColor","strokeRect","restore","bindApi","args","zoomScale","resetZoom","scaleOptions","getZoomLevel","origRange","level","getZoomedScaleBounds","isZoomedOrPanned","originalMin","originalMax","isZoomingOrPanning","Zoom","version","defaults","start","_args","prototype","hasOwnProperty","call","console","warn","beforeEvent","beforeUpdate","previousOptions","oldOptions","newOptions","oldPan","oldZoom","newPan","newZoom","hammerOptionsChanged","wheelOptions","addListeners","beforeDatasetsDraw","afterDatasetsDraw","beforeDraw","afterDraw","stop","removeListeners","removeState","Chart","register"],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ScaleRange, type State } from './state.js';
|
|
2
|
+
import type { Chart, Point, Scale, UpdateMode } from 'chart.js';
|
|
3
|
+
import type { PanTrigger, ZoomTrigger } from './options.js';
|
|
4
|
+
import type { ZoomAmount } from './types.js';
|
|
5
|
+
export declare function zoom(chart: Chart, amount: ZoomAmount, transition?: UpdateMode, trigger?: ZoomTrigger): void;
|
|
6
|
+
export declare function zoomRect(chart: Chart, p0: Point, p1: Point, transition?: UpdateMode, trigger?: ZoomTrigger): void;
|
|
7
|
+
export declare function zoomScale(chart: Chart, scaleId: string, range: ScaleRange, transition?: UpdateMode, trigger?: ZoomTrigger): void;
|
|
8
|
+
export declare function resetZoom(chart: Chart, transition?: UpdateMode): void;
|
|
9
|
+
export declare function getZoomLevel(chart: Chart): number;
|
|
10
|
+
type PanAmount = number | Partial<Point>;
|
|
11
|
+
export declare function pan(chart: Chart, delta: PanAmount, enabledScales?: Scale[], transition?: UpdateMode, trigger?: PanTrigger): void;
|
|
12
|
+
export declare function getInitialScaleBounds(chart: Chart): Record<string, {
|
|
13
|
+
min?: number | undefined;
|
|
14
|
+
max?: number | undefined;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function getZoomedScaleBounds(chart: Chart): Record<string, {
|
|
17
|
+
min?: number | undefined;
|
|
18
|
+
max?: number | undefined;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function isZoomedOrPanned(chart: Chart): boolean;
|
|
21
|
+
export declare function isZoomingOrPanningState(state: State): boolean;
|
|
22
|
+
export declare function isZoomingOrPanning(chart: Chart): boolean;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Chart } from 'chart.js';
|
|
2
|
+
import type { ZoomPluginOptions } from './options';
|
|
3
|
+
export declare function startHammer(chart: Chart, options: ZoomPluginOptions): void;
|
|
4
|
+
export declare function stopHammer(chart: Chart): void;
|
|
5
|
+
export declare function hammerOptionsChanged(oldOptions: ZoomPluginOptions, newOptions: ZoomPluginOptions): boolean;
|
|
6
|
+
//# sourceMappingURL=hammer.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Chart } from 'chart.js';
|
|
2
|
+
import type { ModeOption, ZoomPluginOptions } from './options';
|
|
3
|
+
export declare function mouseMove(chart: Chart, event: MouseEvent): void;
|
|
4
|
+
export declare function mouseDown(chart: Chart, event: MouseEvent): void;
|
|
5
|
+
export declare function computeDragRect(chart: Chart, mode: ModeOption | undefined, pointEvents: {
|
|
6
|
+
dragStart: MouseEvent;
|
|
7
|
+
dragEnd: MouseEvent;
|
|
8
|
+
}, maintainAspectRatio: boolean | undefined): {
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
zoomX: number;
|
|
12
|
+
zoomY: number;
|
|
13
|
+
top: number;
|
|
14
|
+
left: number;
|
|
15
|
+
right: number;
|
|
16
|
+
bottom: number;
|
|
17
|
+
};
|
|
18
|
+
export declare function mouseUp(chart: Chart, event: MouseEvent): void;
|
|
19
|
+
export declare function wheel(chart: Chart, event: WheelEvent & {
|
|
20
|
+
target?: HTMLCanvasElement;
|
|
21
|
+
}): void;
|
|
22
|
+
export declare function addListeners(chart: Chart, options: ZoomPluginOptions): void;
|
|
23
|
+
export declare function removeListeners(chart: Chart): void;
|
|
24
|
+
//# sourceMappingURL=handlers.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import plugin from './plugin';
|
|
2
|
+
import type { ZoomPluginOptions } from './options';
|
|
3
|
+
import type { ScaleRange } from './state';
|
|
4
|
+
import type { DistributiveArray, PanAmount, ZoomAmount } from './types.js';
|
|
5
|
+
import type { ChartType, ChartTypeRegistry, Point, Scale, UpdateMode } from 'chart.js';
|
|
6
|
+
declare module 'chart.js' {
|
|
7
|
+
interface PluginOptionsByType<TType extends ChartType> {
|
|
8
|
+
zoom: ZoomPluginOptions;
|
|
9
|
+
}
|
|
10
|
+
enum UpdateModeEnum {
|
|
11
|
+
zoom = "zoom"
|
|
12
|
+
}
|
|
13
|
+
interface Chart<TType extends ChartType = keyof ChartTypeRegistry, TData = DistributiveArray<ChartTypeRegistry[TType]['defaultDataPoint']>, TLabel = unknown> {
|
|
14
|
+
pan(pan: PanAmount, scales?: Scale[], mode?: UpdateMode): void;
|
|
15
|
+
zoom(zoom: ZoomAmount, mode?: UpdateMode): void;
|
|
16
|
+
zoomRect(p0: Point, p1: Point, mode?: UpdateMode): void;
|
|
17
|
+
zoomScale(id: string, range: ScaleRange, mode?: UpdateMode): void;
|
|
18
|
+
resetZoom(mode?: UpdateMode): void;
|
|
19
|
+
getZoomLevel(): number;
|
|
20
|
+
getInitialScaleBounds(): Record<string, {
|
|
21
|
+
min?: number;
|
|
22
|
+
max?: number;
|
|
23
|
+
}>;
|
|
24
|
+
getZoomedScaleBounds(): Record<string, Partial<ScaleRange>>;
|
|
25
|
+
isZoomedOrPanned(): boolean;
|
|
26
|
+
isZoomingOrPanning(): boolean;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export default plugin;
|
|
30
|
+
export { pan, zoom, zoomRect, zoomScale, resetZoom } from './core';
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/// <reference types="hammerjs" />
|
|
2
|
+
import type { Chart, Color, Point } from 'chart.js';
|
|
3
|
+
export type Mode = 'x' | 'y' | 'xy';
|
|
4
|
+
export type ModeFn = (context: {
|
|
5
|
+
chart: Chart;
|
|
6
|
+
}) => Mode;
|
|
7
|
+
export type ModeOption = Mode | ModeFn;
|
|
8
|
+
export type ModifierKey = 'ctrl' | 'alt' | 'shift' | 'meta';
|
|
9
|
+
export type DrawTime = 'afterDraw' | 'afterDatasetsDraw' | 'beforeDraw' | 'beforeDatasetsDraw';
|
|
10
|
+
export type ZoomTrigger = 'api' | 'drag' | 'wheel' | 'pinch';
|
|
11
|
+
export type PanTrigger = 'api' | 'drag' | 'wheel' | 'other';
|
|
12
|
+
type RejectableStartEvent<T = Event | HammerInput> = (context: {
|
|
13
|
+
chart: Chart;
|
|
14
|
+
event: T;
|
|
15
|
+
point: Point;
|
|
16
|
+
}) => boolean | undefined;
|
|
17
|
+
type RejectEvent<T = Event | HammerInput> = (context: {
|
|
18
|
+
chart: Chart;
|
|
19
|
+
event: T;
|
|
20
|
+
}) => void;
|
|
21
|
+
type GenericEvent = (context: {
|
|
22
|
+
chart: Chart;
|
|
23
|
+
}) => void;
|
|
24
|
+
export interface WheelOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Enable the zoom via mouse wheel
|
|
27
|
+
*/
|
|
28
|
+
enabled?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Speed of zoom via mouse wheel
|
|
31
|
+
* (percentage of zoom on a wheel event)
|
|
32
|
+
*/
|
|
33
|
+
speed?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Modifier key required for zooming with mouse
|
|
36
|
+
*/
|
|
37
|
+
modifierKey?: ModifierKey | null;
|
|
38
|
+
}
|
|
39
|
+
export interface DragOptions {
|
|
40
|
+
/**
|
|
41
|
+
* Enable the zoom via drag
|
|
42
|
+
*/
|
|
43
|
+
enabled?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Minimal zoom distance required before actually applying zoom
|
|
46
|
+
*/
|
|
47
|
+
threshold?: number;
|
|
48
|
+
/**
|
|
49
|
+
* Border color of the drag area
|
|
50
|
+
*/
|
|
51
|
+
borderColor?: Color;
|
|
52
|
+
/**
|
|
53
|
+
* Border width of the drag area
|
|
54
|
+
*/
|
|
55
|
+
borderWidth?: number;
|
|
56
|
+
/**
|
|
57
|
+
* Background color of the drag area
|
|
58
|
+
*/
|
|
59
|
+
backgroundColor?: Color;
|
|
60
|
+
/**
|
|
61
|
+
* Modifier key required for drag-to-zoom
|
|
62
|
+
*/
|
|
63
|
+
modifierKey?: ModifierKey | null;
|
|
64
|
+
/**
|
|
65
|
+
* Draw time required for drag-to-zoom
|
|
66
|
+
*/
|
|
67
|
+
drawTime?: DrawTime;
|
|
68
|
+
/**
|
|
69
|
+
* Maintain aspect ratio of the drag rectangle
|
|
70
|
+
*/
|
|
71
|
+
maintainAspectRatio?: boolean;
|
|
72
|
+
}
|
|
73
|
+
export interface PinchOptions {
|
|
74
|
+
/**
|
|
75
|
+
* Enable the zoom via pinch
|
|
76
|
+
*/
|
|
77
|
+
enabled?: boolean;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Container for zoom options
|
|
81
|
+
*/
|
|
82
|
+
export interface ZoomOptions {
|
|
83
|
+
/**
|
|
84
|
+
* Zooming directions. Remove the appropriate direction to disable
|
|
85
|
+
* E.g. 'y' would only allow zooming in the y direction
|
|
86
|
+
* A function that is called as the user is zooming and returns the
|
|
87
|
+
* available directions can also be used:
|
|
88
|
+
* mode: function({ chart }) {
|
|
89
|
+
* return 'xy';
|
|
90
|
+
* },
|
|
91
|
+
*/
|
|
92
|
+
mode?: ModeOption;
|
|
93
|
+
/**
|
|
94
|
+
* Options of the mouse wheel mode
|
|
95
|
+
*/
|
|
96
|
+
wheel?: WheelOptions;
|
|
97
|
+
/**
|
|
98
|
+
* Options of the drag-to-zoom mode
|
|
99
|
+
*/
|
|
100
|
+
drag?: DragOptions;
|
|
101
|
+
/**
|
|
102
|
+
* Options of the pinch mode
|
|
103
|
+
*/
|
|
104
|
+
pinch?: PinchOptions;
|
|
105
|
+
scaleMode?: ModeOption;
|
|
106
|
+
/** @deprecated Use scaleMode instead */
|
|
107
|
+
overScaleMode?: ModeOption;
|
|
108
|
+
/**
|
|
109
|
+
* Function called while the user is zooming
|
|
110
|
+
*/
|
|
111
|
+
onZoom?: (context: {
|
|
112
|
+
chart: Chart;
|
|
113
|
+
trigger: ZoomTrigger;
|
|
114
|
+
amount?: {
|
|
115
|
+
x: number;
|
|
116
|
+
y: number;
|
|
117
|
+
} & {
|
|
118
|
+
focalPoint: Point;
|
|
119
|
+
};
|
|
120
|
+
}) => void;
|
|
121
|
+
/**
|
|
122
|
+
* Function called once zooming is completed
|
|
123
|
+
*/
|
|
124
|
+
onZoomComplete?: GenericEvent;
|
|
125
|
+
/**
|
|
126
|
+
* Function called when wheel input occurs without modifier key
|
|
127
|
+
*/
|
|
128
|
+
onZoomRejected?: RejectEvent<Event>;
|
|
129
|
+
onZoomStart?: RejectableStartEvent<Event>;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Container for pan options
|
|
133
|
+
*/
|
|
134
|
+
export interface PanOptions {
|
|
135
|
+
/**
|
|
136
|
+
* Boolean to enable panning
|
|
137
|
+
*/
|
|
138
|
+
enabled?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Panning directions. Remove the appropriate direction to disable
|
|
141
|
+
* E.g. 'y' would only allow panning in the y direction
|
|
142
|
+
* A function that is called as the user is panning and returns the
|
|
143
|
+
* available directions can also be used:
|
|
144
|
+
* mode: function({ chart }) {
|
|
145
|
+
* return 'xy';
|
|
146
|
+
* },
|
|
147
|
+
*/
|
|
148
|
+
mode?: ModeOption;
|
|
149
|
+
/**
|
|
150
|
+
* Modifier key required for panning with mouse
|
|
151
|
+
*/
|
|
152
|
+
modifierKey?: ModifierKey | null;
|
|
153
|
+
scaleMode?: ModeOption;
|
|
154
|
+
/** @deprecated Use scaleMode instead */
|
|
155
|
+
overScaleMode?: ModeOption;
|
|
156
|
+
/**
|
|
157
|
+
* Minimal pan distance required before actually applying pan
|
|
158
|
+
*/
|
|
159
|
+
threshold?: number;
|
|
160
|
+
/**
|
|
161
|
+
* Function called while the user is panning
|
|
162
|
+
*/
|
|
163
|
+
onPan?: (context: {
|
|
164
|
+
chart: Chart;
|
|
165
|
+
trigger: PanTrigger;
|
|
166
|
+
delta: {
|
|
167
|
+
x: number;
|
|
168
|
+
y: number;
|
|
169
|
+
};
|
|
170
|
+
}) => void;
|
|
171
|
+
/**
|
|
172
|
+
* Function called once panning is completed
|
|
173
|
+
*/
|
|
174
|
+
onPanComplete?: GenericEvent;
|
|
175
|
+
/**
|
|
176
|
+
* Function called when pan fails because modifier key was not detected.
|
|
177
|
+
* event is the Hammer event that failed - see https://hammerjs.github.io/api#event-object
|
|
178
|
+
*/
|
|
179
|
+
onPanRejected?: RejectEvent<HammerInput>;
|
|
180
|
+
onPanStart?: RejectableStartEvent<HammerInput>;
|
|
181
|
+
}
|
|
182
|
+
export interface ScaleLimits {
|
|
183
|
+
min?: number | 'original';
|
|
184
|
+
max?: number | 'original';
|
|
185
|
+
minRange?: number;
|
|
186
|
+
}
|
|
187
|
+
export interface LimitOptions {
|
|
188
|
+
[axisId: string]: ScaleLimits;
|
|
189
|
+
}
|
|
190
|
+
export interface ZoomPluginOptions {
|
|
191
|
+
pan?: PanOptions;
|
|
192
|
+
limits?: LimitOptions;
|
|
193
|
+
zoom?: ZoomOptions;
|
|
194
|
+
}
|
|
195
|
+
export {};
|
|
196
|
+
//# sourceMappingURL=options.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Chart, ChartEvent } from 'chart.js';
|
|
2
|
+
import type { ZoomPluginOptions } from './options';
|
|
3
|
+
declare const _default: {
|
|
4
|
+
id: string;
|
|
5
|
+
version: string;
|
|
6
|
+
defaults: ZoomPluginOptions;
|
|
7
|
+
start(chart: Chart, _args: unknown, options: ZoomPluginOptions): void;
|
|
8
|
+
beforeEvent(chart: Chart, { event }: {
|
|
9
|
+
event: ChartEvent;
|
|
10
|
+
replay: boolean;
|
|
11
|
+
cancelable: true;
|
|
12
|
+
inChartArea: boolean;
|
|
13
|
+
}): boolean | void;
|
|
14
|
+
beforeUpdate(chart: Chart, _args: unknown, options: ZoomPluginOptions): void;
|
|
15
|
+
beforeDatasetsDraw(chart: Chart, _args: unknown, options: ZoomPluginOptions): void;
|
|
16
|
+
afterDatasetsDraw(chart: Chart, _args: unknown, options: ZoomPluginOptions): void;
|
|
17
|
+
beforeDraw(chart: Chart, _args: unknown, options: ZoomPluginOptions): void;
|
|
18
|
+
afterDraw(chart: Chart, _args: unknown, options: ZoomPluginOptions): void;
|
|
19
|
+
stop(chart: Chart): void;
|
|
20
|
+
panFunctions: Record<string, import("./scale.types").PanFunction>;
|
|
21
|
+
zoomFunctions: Record<string, import("./scale.types").ZoomFunction>;
|
|
22
|
+
zoomRectFunctions: Record<string, import("./scale.types").ZoomRectFunction>;
|
|
23
|
+
};
|
|
24
|
+
export default _default;
|
|
25
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ScaleRange } from './state';
|
|
2
|
+
import type { Point, Scale } from 'chart.js';
|
|
3
|
+
import type { LimitOptions } from './options';
|
|
4
|
+
export type ZoomFunction = (scale: Scale, zoom: number, center: Point, limits: LimitOptions) => boolean;
|
|
5
|
+
export type ZoomRectFunction = (scale: Scale, from: number, to: number, limits: LimitOptions) => boolean;
|
|
6
|
+
export type PanFunction = (scale: Scale, delta: number, limits: LimitOptions) => boolean;
|
|
7
|
+
export declare function zoomDelta(val: number | undefined, min: number | undefined, range: number, newRange: number): ScaleRange;
|
|
8
|
+
export declare function updateRange(scale: Scale, { min, max }: ScaleRange, limits?: LimitOptions, zoom?: boolean, pan?: boolean): boolean;
|
|
9
|
+
export declare const zoomFunctions: Record<string, ZoomFunction>;
|
|
10
|
+
export declare const zoomRectFunctions: Record<string, ZoomRectFunction>;
|
|
11
|
+
export declare const panFunctions: Record<string, PanFunction>;
|
|
12
|
+
//# sourceMappingURL=scale.types.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Chart, type Point } from 'chart.js';
|
|
2
|
+
import type { ZoomPluginOptions } from './options';
|
|
3
|
+
export type ScaleRange = {
|
|
4
|
+
min: number;
|
|
5
|
+
max: number;
|
|
6
|
+
};
|
|
7
|
+
export type OriginalLimits = {
|
|
8
|
+
min: {
|
|
9
|
+
scale?: number;
|
|
10
|
+
options?: unknown;
|
|
11
|
+
};
|
|
12
|
+
max: {
|
|
13
|
+
scale?: number;
|
|
14
|
+
options?: unknown;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
export type OriginalScaleLimits = Record<string, OriginalLimits>;
|
|
18
|
+
export type UpdatedScaleLimits = Record<string, ScaleRange>;
|
|
19
|
+
export type HandlerFunctions = {
|
|
20
|
+
click: (chart: Chart, event: MouseEvent, options: ZoomPluginOptions) => void;
|
|
21
|
+
keydown: (chart: Chart, event: KeyboardEvent) => void;
|
|
22
|
+
mousedown: (chart: Chart, event: MouseEvent, options: ZoomPluginOptions) => void;
|
|
23
|
+
mousemove: (chart: Chart, event: MouseEvent, options: ZoomPluginOptions) => void;
|
|
24
|
+
mouseup: (chart: Chart, event: MouseEvent, options: ZoomPluginOptions) => void;
|
|
25
|
+
onZoomComplete: ({ chart }: {
|
|
26
|
+
chart: Chart;
|
|
27
|
+
}) => void;
|
|
28
|
+
wheel: (chart: Chart, event: WheelEvent) => void;
|
|
29
|
+
};
|
|
30
|
+
export type HandlerName = keyof HandlerFunctions;
|
|
31
|
+
export type HandlerFunction = HandlerFunctions[HandlerName];
|
|
32
|
+
export type Handler = EventListener;
|
|
33
|
+
export type Handlers = Partial<Record<HandlerName, Handler>>;
|
|
34
|
+
export type HandlerTarget = Partial<Record<HandlerName, HTMLCanvasElement | Document>>;
|
|
35
|
+
export interface State {
|
|
36
|
+
originalScaleLimits: OriginalScaleLimits;
|
|
37
|
+
updatedScaleLimits: UpdatedScaleLimits;
|
|
38
|
+
handlers: Handlers;
|
|
39
|
+
targets: HandlerTarget;
|
|
40
|
+
panDelta: Record<string, number>;
|
|
41
|
+
dragging: boolean;
|
|
42
|
+
panning: boolean;
|
|
43
|
+
options: ZoomPluginOptions;
|
|
44
|
+
dragStart?: MouseEvent;
|
|
45
|
+
dragEnd?: MouseEvent;
|
|
46
|
+
filterNextClick?: boolean;
|
|
47
|
+
scale?: number | null;
|
|
48
|
+
delta?: Point | null;
|
|
49
|
+
panScales?: string[];
|
|
50
|
+
}
|
|
51
|
+
export declare function getState(chart: Chart): State;
|
|
52
|
+
export declare function removeState(chart: Chart): void;
|
|
53
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Point } from 'chart.js';
|
|
2
|
+
export type ZoomAmount = number | (Partial<Point> & {
|
|
3
|
+
focalPoint?: Point;
|
|
4
|
+
});
|
|
5
|
+
export type PanAmount = number | Partial<Point>;
|
|
6
|
+
export type ScaleRange = {
|
|
7
|
+
min: number;
|
|
8
|
+
max: number;
|
|
9
|
+
};
|
|
10
|
+
export type DistributiveArray<T> = [T] extends [unknown] ? Array<T> : never;
|
|
11
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Chart, Point, Scale } from 'chart.js';
|
|
2
|
+
import type { DragOptions, ModeOption, ModifierKey, PanOptions } from './options';
|
|
3
|
+
export declare const getModifierKey: (opts?: DragOptions | PanOptions) => ModifierKey | undefined;
|
|
4
|
+
export declare const keyPressed: (key: ModifierKey | undefined, event: TouchEvent | MouseEvent | PointerEvent) => boolean | undefined;
|
|
5
|
+
export declare const keyNotPressed: (key: ModifierKey | undefined, event: TouchEvent | MouseEvent | PointerEvent) => boolean | undefined;
|
|
6
|
+
export declare function directionEnabled(mode: ModeOption | undefined, dir: 'x' | 'y', chart: Chart): boolean;
|
|
7
|
+
export declare function debounce(fn: () => void, delay: number | undefined): () => number | undefined;
|
|
8
|
+
/**
|
|
9
|
+
* Evaluate the chart's mode, scaleMode, and overScaleMode properties to
|
|
10
|
+
* determine which axes are eligible for scaling.
|
|
11
|
+
* options.overScaleMode can be a function if user want zoom only one scale of many for example.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getEnabledScalesByPoint(options: PanOptions | undefined, point: Point, chart: Chart): Scale[];
|
|
14
|
+
//# sourceMappingURL=utils.d.ts.map
|