|
1 | 1 | import defaults from './core.defaults'; |
2 | 2 | import Element from './core.element'; |
3 | 3 | import {_alignPixel, _measureText, renderText, clipArea, unclipArea} from '../helpers/helpers.canvas'; |
4 | | -import {callback as call, each, finiteOrDefault, isArray, isFinite, isNullOrUndef, isObject, valueOrDefault} from '../helpers/helpers.core'; |
5 | | -import {_factorize, toDegrees, toRadians, _int16Range, _limitValue, HALF_PI} from '../helpers/helpers.math'; |
| 4 | +import {callback as call, each, finiteOrDefault, isArray, isFinite, isNullOrUndef, isObject} from '../helpers/helpers.core'; |
| 5 | +import {toDegrees, toRadians, _int16Range, _limitValue, HALF_PI} from '../helpers/helpers.math'; |
6 | 6 | import {_alignStartEnd, _toLeftRightCenter} from '../helpers/helpers.extras'; |
7 | 7 | import {toFont, toPadding} from '../helpers/helpers.options'; |
8 | 8 | import Ticks from './core.ticks'; |
| 9 | +import {autoSkip} from './core.scale.autoskip'; |
9 | 10 |
|
10 | 11 | const reverseAlign = (align) => align === 'left' ? 'right' : align === 'right' ? 'left' : align; |
11 | 12 | const offsetFromEdge = (scale, edge, offset) => edge === 'top' || edge === 'left' ? scale[edge] + offset : scale[edge] - offset; |
@@ -192,128 +193,6 @@ function getTitleHeight(options, fallback) { |
192 | 193 | return (lines * font.lineHeight) + padding.height; |
193 | 194 | } |
194 | 195 |
|
195 | | -function determineMaxTicks(scale) { |
196 | | - const offset = scale.options.offset; |
197 | | - const tickLength = scale._tickSize(); |
198 | | - const maxScale = scale._length / tickLength + (offset ? 0 : 1); |
199 | | - const maxChart = scale._maxLength / tickLength; |
200 | | - return Math.floor(Math.min(maxScale, maxChart)); |
201 | | -} |
202 | | - |
203 | | -/** |
204 | | - * @param {number[]} arr |
205 | | - */ |
206 | | -function getEvenSpacing(arr) { |
207 | | - const len = arr.length; |
208 | | - let i, diff; |
209 | | - |
210 | | - if (len < 2) { |
211 | | - return false; |
212 | | - } |
213 | | - |
214 | | - for (diff = arr[0], i = 1; i < len; ++i) { |
215 | | - if (arr[i] - arr[i - 1] !== diff) { |
216 | | - return false; |
217 | | - } |
218 | | - } |
219 | | - return diff; |
220 | | -} |
221 | | - |
222 | | -/** |
223 | | - * @param {number[]} majorIndices |
224 | | - * @param {Tick[]} ticks |
225 | | - * @param {number} ticksLimit |
226 | | - */ |
227 | | -function calculateSpacing(majorIndices, ticks, ticksLimit) { |
228 | | - const evenMajorSpacing = getEvenSpacing(majorIndices); |
229 | | - const spacing = ticks.length / ticksLimit; |
230 | | - |
231 | | - // If the major ticks are evenly spaced apart, place the minor ticks |
232 | | - // so that they divide the major ticks into even chunks |
233 | | - if (!evenMajorSpacing) { |
234 | | - return Math.max(spacing, 1); |
235 | | - } |
236 | | - |
237 | | - const factors = _factorize(evenMajorSpacing); |
238 | | - for (let i = 0, ilen = factors.length - 1; i < ilen; i++) { |
239 | | - const factor = factors[i]; |
240 | | - if (factor > spacing) { |
241 | | - return factor; |
242 | | - } |
243 | | - } |
244 | | - return Math.max(spacing, 1); |
245 | | -} |
246 | | - |
247 | | -/** |
248 | | - * @param {Tick[]} ticks |
249 | | - */ |
250 | | -function getMajorIndices(ticks) { |
251 | | - const result = []; |
252 | | - let i, ilen; |
253 | | - for (i = 0, ilen = ticks.length; i < ilen; i++) { |
254 | | - if (ticks[i].major) { |
255 | | - result.push(i); |
256 | | - } |
257 | | - } |
258 | | - return result; |
259 | | -} |
260 | | - |
261 | | -/** |
262 | | - * @param {Tick[]} ticks |
263 | | - * @param {Tick[]} newTicks |
264 | | - * @param {number[]} majorIndices |
265 | | - * @param {number} spacing |
266 | | - */ |
267 | | -function skipMajors(ticks, newTicks, majorIndices, spacing) { |
268 | | - let count = 0; |
269 | | - let next = majorIndices[0]; |
270 | | - let i; |
271 | | - |
272 | | - spacing = Math.ceil(spacing); |
273 | | - for (i = 0; i < ticks.length; i++) { |
274 | | - if (i === next) { |
275 | | - newTicks.push(ticks[i]); |
276 | | - count++; |
277 | | - next = majorIndices[count * spacing]; |
278 | | - } |
279 | | - } |
280 | | -} |
281 | | - |
282 | | -/** |
283 | | - * @param {Tick[]} ticks |
284 | | - * @param {Tick[]} newTicks |
285 | | - * @param {number} spacing |
286 | | - * @param {number} [majorStart] |
287 | | - * @param {number} [majorEnd] |
288 | | - */ |
289 | | -function skip(ticks, newTicks, spacing, majorStart, majorEnd) { |
290 | | - const start = valueOrDefault(majorStart, 0); |
291 | | - const end = Math.min(valueOrDefault(majorEnd, ticks.length), ticks.length); |
292 | | - let count = 0; |
293 | | - let length, i, next; |
294 | | - |
295 | | - spacing = Math.ceil(spacing); |
296 | | - if (majorEnd) { |
297 | | - length = majorEnd - majorStart; |
298 | | - spacing = length / Math.floor(length / spacing); |
299 | | - } |
300 | | - |
301 | | - next = start; |
302 | | - |
303 | | - while (next < 0) { |
304 | | - count++; |
305 | | - next = Math.round(start + count * spacing); |
306 | | - } |
307 | | - |
308 | | - for (i = Math.max(start, 0); i < end; i++) { |
309 | | - if (i === next) { |
310 | | - newTicks.push(ticks[i]); |
311 | | - count++; |
312 | | - next = Math.round(start + count * spacing); |
313 | | - } |
314 | | - } |
315 | | -} |
316 | | - |
317 | 196 | function createScaleContext(parent, scale) { |
318 | 197 | return Object.assign(Object.create(parent), { |
319 | 198 | scale, |
@@ -635,7 +514,7 @@ export default class Scale extends Element { |
635 | 514 |
|
636 | 515 | // Auto-skip |
637 | 516 | if (tickOpts.display && (tickOpts.autoSkip || tickOpts.source === 'auto')) { |
638 | | - me.ticks = me._autoSkip(me.ticks); |
| 517 | + me.ticks = autoSkip(me, me.ticks); |
639 | 518 | me._labelSizes = null; |
640 | 519 | } |
641 | 520 |
|
@@ -1149,44 +1028,6 @@ export default class Scale extends Element { |
1149 | 1028 | (me.$context = createScaleContext(me.chart.getContext(), me)); |
1150 | 1029 | } |
1151 | 1030 |
|
1152 | | - /** |
1153 | | - * Returns a subset of ticks to be plotted to avoid overlapping labels. |
1154 | | - * @param {Tick[]} ticks |
1155 | | - * @return {Tick[]} |
1156 | | - * @private |
1157 | | - */ |
1158 | | - _autoSkip(ticks) { |
1159 | | - const me = this; |
1160 | | - const tickOpts = me.options.ticks; |
1161 | | - const ticksLimit = tickOpts.maxTicksLimit || determineMaxTicks(me); |
1162 | | - const majorIndices = tickOpts.major.enabled ? getMajorIndices(ticks) : []; |
1163 | | - const numMajorIndices = majorIndices.length; |
1164 | | - const first = majorIndices[0]; |
1165 | | - const last = majorIndices[numMajorIndices - 1]; |
1166 | | - const newTicks = []; |
1167 | | - |
1168 | | - // If there are too many major ticks to display them all |
1169 | | - if (numMajorIndices > ticksLimit) { |
1170 | | - skipMajors(ticks, newTicks, majorIndices, numMajorIndices / ticksLimit); |
1171 | | - return newTicks; |
1172 | | - } |
1173 | | - |
1174 | | - const spacing = calculateSpacing(majorIndices, ticks, ticksLimit); |
1175 | | - |
1176 | | - if (numMajorIndices > 0) { |
1177 | | - let i, ilen; |
1178 | | - const avgMajorSpacing = numMajorIndices > 1 ? Math.round((last - first) / (numMajorIndices - 1)) : null; |
1179 | | - skip(ticks, newTicks, spacing, isNullOrUndef(avgMajorSpacing) ? 0 : first - avgMajorSpacing, first); |
1180 | | - for (i = 0, ilen = numMajorIndices - 1; i < ilen; i++) { |
1181 | | - skip(ticks, newTicks, spacing, majorIndices[i], majorIndices[i + 1]); |
1182 | | - } |
1183 | | - skip(ticks, newTicks, spacing, last, isNullOrUndef(avgMajorSpacing) ? ticks.length : last + avgMajorSpacing); |
1184 | | - return newTicks; |
1185 | | - } |
1186 | | - skip(ticks, newTicks, spacing); |
1187 | | - return newTicks; |
1188 | | - } |
1189 | | - |
1190 | 1031 | /** |
1191 | 1032 | * @return {number} |
1192 | 1033 | * @private |
|
0 commit comments