Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions docs/samples/basic.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,18 @@ const zoomOptions = {
enabled: true
},
mode: 'xy',
onZoomComplete({chart}) {
// This update is needed to display up to date zoom level in the title.
// Without this, previous zoom level is displayed.
// The reason is: title uses the same beforeUpdate hook, and is evaluated before zoom.
chart.update('none');
}
}
};
// </block:zoom>

const panStatus = () => zoomOptions.pan.enabled ? 'enabled' : 'disabled';
const zoomStatus = () => zoomOptions.zoom.wheel.enabled ? 'enabled' : 'disabled';
const zoomStatus = (chart) => (zoomOptions.zoom.wheel.enabled ? 'enabled' : 'disabled') + ' (' + chart.getZoomLevel() + 'x)';

// <block:config:1>
const config = {
Expand All @@ -86,7 +92,7 @@ const config = {
title: {
display: true,
position: 'bottom',
text: (ctx) => 'Zoom: ' + zoomStatus() + ', Pan: ' + panStatus()
text: (ctx) => 'Zoom: ' + zoomStatus(ctx.chart) + ', Pan: ' + panStatus()
}
},
onClick(e) {
Expand Down
29 changes: 26 additions & 3 deletions src/core.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {each, callback as call, sign} from 'chart.js/helpers';
import {each, callback as call, sign, valueOrDefault} from 'chart.js/helpers';
import {panFunctions, updateRange, zoomFunctions} from './scale.types';
import {getState} from './state';
import {directionEnabled, getEnabledScalesByPoint} from './utils';
Expand Down Expand Up @@ -102,9 +102,9 @@ export function zoomScale(chart, scaleId, range, transition = 'none') {
chart.update(transition);
}


export function resetZoom(chart, transition = 'default') {
const originalScaleLimits = storeOriginalScaleLimits(chart, getState(chart));
const state = getState(chart);
const originalScaleLimits = storeOriginalScaleLimits(chart, state);

each(chart.scales, function(scale) {
const scaleOptions = scale.options;
Expand All @@ -117,6 +117,29 @@ export function resetZoom(chart, transition = 'default') {
}
});
chart.update(transition);
call(state.options.zoom.onZoomComplete, [{chart}]);
}

function getOriginalRange(state, scaleId) {
const original = state.originalScaleLimits[scaleId];
if (!original) {
return;
}
const {min, max} = original;
return valueOrDefault(max.options, max.scale) - valueOrDefault(min.options, min.scale);
}

export function getZoomLevel(chart) {
const state = getState(chart);
let min = 1;
let max = 1;
each(chart.scales, function(scale) {
const origRange = getOriginalRange(state, scale.id);
const level = Math.round(origRange / (scale.max - scale.min) * 100) / 100;
min = Math.min(min, level);
max = Math.max(max, level);
});
return min < 1 ? min : max;
}

function panScale(scale, delta, limits, state) {
Expand Down
3 changes: 2 additions & 1 deletion src/plugin.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Hammer from 'hammerjs';
import {addListeners, computeDragRect, removeListeners} from './handlers';
import {startHammer, stopHammer} from './hammer';
import {pan, zoom, resetZoom, zoomScale} from './core';
import {pan, zoom, resetZoom, zoomScale, getZoomLevel} from './core';
import {panFunctions, zoomFunctions} from './scale.types';
import {getState, removeState} from './state';
import {version} from '../package.json';
Expand Down Expand Up @@ -50,6 +50,7 @@ export default {
chart.zoom = (args, transition) => zoom(chart, args, transition);
chart.zoomScale = (id, range, transition) => zoomScale(chart, id, range, transition);
chart.resetZoom = (transition) => resetZoom(chart, transition);
chart.getZoomLevel = () => getZoomLevel(chart);
},

beforeEvent(chart) {
Expand Down
18 changes: 8 additions & 10 deletions src/scale.types.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {valueOrDefault} from 'chart.js/helpers';
import {getState} from './state';

function zoomDelta(scale, zoom, center) {
Expand All @@ -14,26 +15,23 @@ function zoomDelta(scale, zoom, center) {
};
}

function getLimit(chartState, scale, scaleLimits, prop, fallback) {
function getLimit(state, scale, scaleLimits, prop, fallback) {
let limit = scaleLimits[prop];
if (limit === 'original') {
const original = chartState.originalScaleLimits[scale.id][prop];
limit = original.options !== null && original.options !== undefined ? original.options : original.scale;
const original = state.originalScaleLimits[scale.id][prop];
limit = valueOrDefault(original.options, original.scale);
}
if (limit === null || limit === undefined) {
limit = fallback;
}
return limit;
return valueOrDefault(limit, fallback);
}

export function updateRange(scale, {min, max}, limits, zoom = false) {
const chartState = getState(scale.chart);
const state = getState(scale.chart);
const {id, axis, options: scaleOpts} = scale;

const scaleLimits = limits && (limits[id] || limits[axis]) || {};
const {minRange = 0} = scaleLimits;
const minLimit = getLimit(chartState, scale, scaleLimits, 'min', -Infinity);
const maxLimit = getLimit(chartState, scale, scaleLimits, 'max', Infinity);
const minLimit = getLimit(state, scale, scaleLimits, 'min', -Infinity);
const maxLimit = getLimit(state, scale, scaleLimits, 'max', Infinity);

const cmin = Math.max(min, minLimit);
const cmax = Math.min(max, maxLimit);
Expand Down
2 changes: 2 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ declare module 'chart.js' {
zoom(zoom: ZoomAmount, useTransition?: boolean, mode?: UpdateMode): void;
zoomScale(id: string, range: ScaleRange, mode?: UpdateMode): void;
resetZoom(mode?: UpdateMode): void;
getZoomLevel(): number;
}
}

Expand All @@ -46,3 +47,4 @@ export function pan(chart: Chart, amount: PanAmount, scales?: Scale[], mode?: Up
export function zoom(chart: Chart, amount: ZoomAmount, mode?: UpdateMode): void;
export function zoomScale(chart: Chart, scaleId: string, range: ScaleRange, mode?: UpdateMode): void;
export function resetZoom(chart: Chart, mode?: UpdateMode): void;
export function getZoomLevel(chart): number;