• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

chartjs / chartjs-plugin-zoom / 11881672105

17 Nov 2024 07:38PM UTC coverage: 83.498%. Remained the same
11881672105

push

github

web-flow
Bump karma-spec-reporter from 0.0.32 to 0.0.36 (#881)

Bumps [karma-spec-reporter](https://github.com/tmcgee123/karma-spec-reporter) from 0.0.32 to 0.0.36.
- [Commits](https://github.com/tmcgee123/karma-spec-reporter/compare/v0.0.32...v0.0.36)

---
updated-dependencies:
- dependency-name: karma-spec-reporter
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

217 of 275 branches covered (78.91%)

Branch coverage included in aggregate %.

461 of 537 relevant lines covered (85.85%)

1426.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.5
/src/core.js
1
import {each, callback as call, sign, valueOrDefault} from 'chart.js/helpers';
2
import {panFunctions, updateRange, zoomFunctions, zoomRectFunctions} from './scale.types';
3
import {getState} from './state';
4
import {directionEnabled, getEnabledScalesByPoint} from './utils';
5

6
function shouldUpdateScaleLimits(scale, originalScaleLimits, updatedScaleLimits) {
7
  const {id, options: {min, max}} = scale;
2,088✔
8
  if (!originalScaleLimits[id] || !updatedScaleLimits[id]) {
2,088✔
9
    return true;
1,280✔
10
  }
11
  const previous = updatedScaleLimits[id];
808✔
12
  return previous.min !== min || previous.max !== max;
808✔
13
}
14

15
function removeMissingScales(limits, scales) {
16
  each(limits, (opt, key) => {
2,048✔
17
    if (!scales[key]) {
2,896!
18
      delete limits[key];
×
19
    }
20
  });
21
}
22

23
function storeOriginalScaleLimits(chart, state) {
24
  const {scales} = chart;
1,024✔
25
  const {originalScaleLimits, updatedScaleLimits} = state;
1,024✔
26

27
  each(scales, function(scale) {
1,024✔
28
    if (shouldUpdateScaleLimits(scale, originalScaleLimits, updatedScaleLimits)) {
2,088✔
29
      originalScaleLimits[scale.id] = {
1,280✔
30
        min: {scale: scale.min, options: scale.options.min},
31
        max: {scale: scale.max, options: scale.options.max},
32
      };
33
    }
34
  });
35

36
  removeMissingScales(originalScaleLimits, scales);
1,024✔
37
  removeMissingScales(updatedScaleLimits, scales);
1,024✔
38
  return originalScaleLimits;
1,024✔
39
}
40

41
function doZoom(scale, amount, center, limits) {
42
  const fn = zoomFunctions[scale.type] || zoomFunctions.default;
316✔
43
  call(fn, [scale, amount, center, limits]);
316✔
44
}
45

46
function doZoomRect(scale, from, to, limits) {
47
  const fn = zoomRectFunctions[scale.type] || zoomRectFunctions.default;
88✔
48
  call(fn, [scale, from, to, limits]);
88✔
49
}
50

51
function getCenter(chart) {
52
  const ca = chart.chartArea;
92✔
53
  return {
92✔
54
    x: (ca.left + ca.right) / 2,
55
    y: (ca.top + ca.bottom) / 2,
56
  };
57
}
58

59
/**
60
 * @param chart The chart instance
61
 * @param {number | {x?: number, y?: number, focalPoint?: {x: number, y: number}}} amount The zoom percentage or percentages and focal point
62
 * @param {string} [transition] Which transition mode to use. Defaults to 'none'
63
 */
64
export function zoom(chart, amount, transition = 'none') {
240✔
65
  const {x = 1, y = 1, focalPoint = getCenter(chart)} = typeof amount === 'number' ? {x: amount, y: amount} : amount;
240!
66
  const state = getState(chart);
240✔
67
  const {options: {limits, zoom: zoomOptions}} = state;
240✔
68

69
  storeOriginalScaleLimits(chart, state);
240✔
70

71
  const xEnabled = x !== 1;
240✔
72
  const yEnabled = y !== 1;
240✔
73
  const enabledScales = getEnabledScalesByPoint(zoomOptions, focalPoint, chart);
240✔
74

75
  each(enabledScales || chart.scales, function(scale) {
240!
76
    if (scale.isHorizontal() && xEnabled) {
352✔
77
      doZoom(scale, x, focalPoint, limits);
196✔
78
    } else if (!scale.isHorizontal() && yEnabled) {
156✔
79
      doZoom(scale, y, focalPoint, limits);
120✔
80
    }
81
  });
82

83
  chart.update(transition);
240✔
84

85
  call(zoomOptions.onZoom, [{chart}]);
240✔
86
}
87

88
export function zoomRect(chart, p0, p1, transition = 'none') {
×
89
  const state = getState(chart);
56✔
90
  const {options: {limits, zoom: zoomOptions}} = state;
56✔
91
  const {mode = 'xy'} = zoomOptions;
56!
92

93
  storeOriginalScaleLimits(chart, state);
56✔
94
  const xEnabled = directionEnabled(mode, 'x', chart);
56✔
95
  const yEnabled = directionEnabled(mode, 'y', chart);
56✔
96

97
  each(chart.scales, function(scale) {
56✔
98
    if (scale.isHorizontal() && xEnabled) {
152✔
99
      doZoomRect(scale, p0.x, p1.x, limits);
60✔
100
    } else if (!scale.isHorizontal() && yEnabled) {
92✔
101
      doZoomRect(scale, p0.y, p1.y, limits);
28✔
102
    }
103
  });
104

105
  chart.update(transition);
56✔
106

107
  call(zoomOptions.onZoom, [{chart}]);
56✔
108
}
109

110
export function zoomScale(chart, scaleId, range, transition = 'none') {
8✔
111
  storeOriginalScaleLimits(chart, getState(chart));
8✔
112
  const scale = chart.scales[scaleId];
8✔
113
  updateRange(scale, range, undefined, true);
8✔
114
  chart.update(transition);
8✔
115
}
116

117
export function resetZoom(chart, transition = 'default') {
64✔
118
  const state = getState(chart);
64✔
119
  const originalScaleLimits = storeOriginalScaleLimits(chart, state);
64✔
120

121
  each(chart.scales, function(scale) {
64✔
122
    const scaleOptions = scale.options;
128✔
123
    if (originalScaleLimits[scale.id]) {
128!
124
      scaleOptions.min = originalScaleLimits[scale.id].min.options;
128✔
125
      scaleOptions.max = originalScaleLimits[scale.id].max.options;
128✔
126
    } else {
127
      delete scaleOptions.min;
×
128
      delete scaleOptions.max;
×
129
    }
130
    delete state.updatedScaleLimits[scale.id];
128✔
131
  });
132
  chart.update(transition);
64✔
133
  call(state.options.zoom.onZoomComplete, [{chart}]);
64✔
134
}
135

136
function getOriginalRange(state, scaleId) {
137
  const original = state.originalScaleLimits[scaleId];
×
138
  if (!original) {
×
139
    return;
×
140
  }
141
  const {min, max} = original;
×
142
  return valueOrDefault(max.options, max.scale) - valueOrDefault(min.options, min.scale);
×
143
}
144

145
export function getZoomLevel(chart) {
146
  const state = getState(chart);
×
147
  let min = 1;
×
148
  let max = 1;
×
149
  each(chart.scales, function(scale) {
×
150
    const origRange = getOriginalRange(state, scale.id);
×
151
    if (origRange) {
×
152
      const level = Math.round(origRange / (scale.max - scale.min) * 100) / 100;
×
153
      min = Math.min(min, level);
×
154
      max = Math.max(max, level);
×
155
    }
156
  });
157
  return min < 1 ? min : max;
×
158
}
159

160
function panScale(scale, delta, limits, state) {
161
  const {panDelta} = state;
596✔
162
  // Add possible cumulative delta from previous pan attempts where scale did not change
163
  const storedDelta = panDelta[scale.id] || 0;
596✔
164
  if (sign(storedDelta) === sign(delta)) {
596✔
165
    delta += storedDelta;
72✔
166
  }
167
  const fn = panFunctions[scale.type] || panFunctions.default;
596✔
168
  if (call(fn, [scale, delta, limits])) {
596✔
169
    // The scale changed, reset cumulative delta
170
    panDelta[scale.id] = 0;
520✔
171
  } else {
172
    // The scale did not change, store cumulative delta
173
    panDelta[scale.id] = delta;
76✔
174
  }
175
}
176

177
export function pan(chart, delta, enabledScales, transition = 'none') {
552✔
178
  const {x = 0, y = 0} = typeof delta === 'number' ? {x: delta, y: delta} : delta;
552!
179
  const state = getState(chart);
552✔
180
  const {options: {pan: panOptions, limits}} = state;
552✔
181
  const {onPan} = panOptions || {};
552!
182

183
  storeOriginalScaleLimits(chart, state);
552✔
184

185
  const xEnabled = x !== 0;
552✔
186
  const yEnabled = y !== 0;
552✔
187

188
  each(enabledScales || chart.scales, function(scale) {
552✔
189
    if (scale.isHorizontal() && xEnabled) {
912✔
190
      panScale(scale, x, limits, state);
548✔
191
    } else if (!scale.isHorizontal() && yEnabled) {
364✔
192
      panScale(scale, y, limits, state);
48✔
193
    }
194
  });
195

196
  chart.update(transition);
552✔
197

198
  call(onPan, [{chart}]);
552✔
199
}
200

201
export function getInitialScaleBounds(chart) {
202
  const state = getState(chart);
104✔
203
  storeOriginalScaleLimits(chart, state);
104✔
204
  const scaleBounds = {};
104✔
205
  for (const scaleId of Object.keys(chart.scales)) {
104✔
206
    const {min, max} = state.originalScaleLimits[scaleId] || {min: {}, max: {}};
208!
207
    scaleBounds[scaleId] = {min: min.scale, max: max.scale};
208✔
208
  }
209

210
  return scaleBounds;
104✔
211
}
212

213
export function getZoomedScaleBounds(chart) {
214
  const state = getState(chart);
12✔
215
  const scaleBounds = {};
12✔
216
  for (const scaleId of Object.keys(chart.scales)) {
12✔
217
    scaleBounds[scaleId] = state.updatedScaleLimits[scaleId];
24✔
218
  }
219

220
  return scaleBounds;
12✔
221
}
222

223
export function isZoomedOrPanned(chart) {
224
  const scaleBounds = getInitialScaleBounds(chart);
40✔
225
  for (const scaleId of Object.keys(chart.scales)) {
40✔
226
    const {min: originalMin, max: originalMax} = scaleBounds[scaleId];
68✔
227

228
    if (originalMin !== undefined && chart.scales[scaleId].min !== originalMin) {
68✔
229
      return true;
12✔
230
    }
231

232
    if (originalMax !== undefined && chart.scales[scaleId].max !== originalMax) {
56!
233
      return true;
×
234
    }
235
  }
236

237
  return false;
28✔
238
}
239

240
export function isZoomingOrPanning(chart) {
241
  const state = getState(chart);
26✔
242
  return state.panning || state.dragging;
26✔
243
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc