chartkick 4.0.4 → 4.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e28ff576b7b488cc3ca1add95bf96832461189f5b085816e67d9923fdf13494
4
- data.tar.gz: 282c01fdc0d199d4dd9d17a0aa887a67a0d8ce52df584a46d172e636496ad25e
3
+ metadata.gz: ecf49f61e1962e1952df47113fea621bafe1bb423e50903ce98e1b6213c3c9cb
4
+ data.tar.gz: 29167dca418215178ea525061dc3113d186a53076ce77472241f54e99edc4b13
5
5
  SHA512:
6
- metadata.gz: 3a450c12a1973131b412d99525d400d2910e63e24edb93cb6ce27670dc6a1eaf70e13dfec9829a67cae6afcf4e77737eea2c442232c00bdd3c5d5e7b126a1a93
7
- data.tar.gz: 3d59060b8e7dd24f3239dccc0b7079a66e3d1351a1e565e948e46faa2a2b28a462ee6d91b99602a334f91861ea2cf3a77419bf0c86677a83c278b4f97ef3d4fb
6
+ metadata.gz: 4ba35050af1933c7d343125a291a515e26f6ae143b081d6346e0e709b920d299ff44a0f262559b1b358d778154b2a103132b751f9c37a905c5e789776bafca17
7
+ data.tar.gz: 3a3f5d3c57e7af61bcfc7b86d5888b4f2124b5e07fa86256eb7eb6298125b14c5a6293e926802ea3ac2d45a48fdf5fd222a2c47ba9ffb08209f8dc5768ad6000
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 4.0.5 (2021-07-07)
2
+
3
+ - Updated Chartkick.js to 4.0.5
4
+ - Updated Chart.js to 3.4.1
5
+
1
6
  ## 4.0.4 (2021-05-01)
2
7
 
3
8
  - Updated Chartkick.js to 4.0.4
@@ -1,3 +1,3 @@
1
1
  module Chartkick
2
- VERSION = "4.0.4"
2
+ VERSION = "4.0.5"
3
3
  end
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Chart.js v3.2.1
2
+ * Chart.js v3.4.1
3
3
  * https://www.chartjs.org
4
4
  * (c) 2021 Chart.js Contributors
5
5
  * Released under the MIT License
@@ -217,6 +217,10 @@
217
217
  return _get(target, property, receiver || target);
218
218
  }
219
219
 
220
+ function _slicedToArray(arr, i) {
221
+ return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
222
+ }
223
+
220
224
  function _toConsumableArray(arr) {
221
225
  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
222
226
  }
@@ -225,10 +229,41 @@
225
229
  if (Array.isArray(arr)) return _arrayLikeToArray(arr);
226
230
  }
227
231
 
232
+ function _arrayWithHoles(arr) {
233
+ if (Array.isArray(arr)) return arr;
234
+ }
235
+
228
236
  function _iterableToArray(iter) {
229
237
  if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
230
238
  }
231
239
 
240
+ function _iterableToArrayLimit(arr, i) {
241
+ if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
242
+ var _arr = [];
243
+ var _n = true;
244
+ var _d = false;
245
+ var _e = undefined;
246
+
247
+ try {
248
+ for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
249
+ _arr.push(_s.value);
250
+
251
+ if (i && _arr.length === i) break;
252
+ }
253
+ } catch (err) {
254
+ _d = true;
255
+ _e = err;
256
+ } finally {
257
+ try {
258
+ if (!_n && _i["return"] != null) _i["return"]();
259
+ } finally {
260
+ if (_d) throw _e;
261
+ }
262
+ }
263
+
264
+ return _arr;
265
+ }
266
+
232
267
  function _unsupportedIterableToArray(o, minLen) {
233
268
  if (!o) return;
234
269
  if (typeof o === "string") return _arrayLikeToArray(o, minLen);
@@ -250,6 +285,10 @@
250
285
  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
251
286
  }
252
287
 
288
+ function _nonIterableRest() {
289
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
290
+ }
291
+
253
292
  function _createForOfIteratorHelper(o, allowArrayLike) {
254
293
  var it;
255
294
 
@@ -363,8 +402,9 @@
363
402
  return align === 'start' ? start : align === 'end' ? end : (start + end) / 2;
364
403
  };
365
404
 
366
- var _textX = function _textX(align, left, right) {
367
- return align === 'right' ? right : align === 'center' ? (left + right) / 2 : left;
405
+ var _textX = function _textX(align, left, right, rtl) {
406
+ var check = rtl ? 'left' : 'right';
407
+ return align === check ? right : align === 'center' ? (left + right) / 2 : left;
368
408
  };
369
409
 
370
410
  function noop() {}
@@ -631,6 +671,8 @@
631
671
  var sign = Math.sign;
632
672
 
633
673
  function niceNum(range) {
674
+ var roundedRange = Math.round(range);
675
+ range = almostEquals(range, roundedRange, range / 1000) ? roundedRange : range;
634
676
  var niceRange = Math.pow(10, Math.floor(log10(range)));
635
677
  var fraction = range / niceRange;
636
678
  var niceFraction = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 5 ? 5 : 10;
@@ -737,7 +779,7 @@
737
779
  return (a % TAU + TAU) % TAU;
738
780
  }
739
781
 
740
- function _angleBetween(angle, start, end) {
782
+ function _angleBetween(angle, start, end, sameAngleIsFullCircle) {
741
783
  var a = _normalizeAngle(angle);
742
784
 
743
785
  var s = _normalizeAngle(start);
@@ -752,7 +794,7 @@
752
794
 
753
795
  var endToAngle = _normalizeAngle(a - e);
754
796
 
755
- return a === s || a === e || angleToStart > angleToEnd && startToAngle < endToAngle;
797
+ return a === s || a === e || sameAngleIsFullCircle && s === e || angleToStart > angleToEnd && startToAngle < endToAngle;
756
798
  }
757
799
 
758
800
  function _limitValue(value, min, max) {
@@ -902,7 +944,7 @@
902
944
  * Released under the MIT License
903
945
  */
904
946
 
905
- var map = {
947
+ var map$1 = {
906
948
  0: 0,
907
949
  1: 1,
908
950
  2: 2,
@@ -951,17 +993,17 @@
951
993
  if (str[0] === '#') {
952
994
  if (len === 4 || len === 5) {
953
995
  ret = {
954
- r: 255 & map[str[1]] * 17,
955
- g: 255 & map[str[2]] * 17,
956
- b: 255 & map[str[3]] * 17,
957
- a: len === 5 ? map[str[4]] * 17 : 255
996
+ r: 255 & map$1[str[1]] * 17,
997
+ g: 255 & map$1[str[2]] * 17,
998
+ b: 255 & map$1[str[3]] * 17,
999
+ a: len === 5 ? map$1[str[4]] * 17 : 255
958
1000
  };
959
1001
  } else if (len === 7 || len === 9) {
960
1002
  ret = {
961
- r: map[str[1]] << 4 | map[str[2]],
962
- g: map[str[3]] << 4 | map[str[4]],
963
- b: map[str[5]] << 4 | map[str[6]],
964
- a: len === 9 ? map[str[7]] << 4 | map[str[8]] : 255
1003
+ r: map$1[str[1]] << 4 | map$1[str[2]],
1004
+ g: map$1[str[3]] << 4 | map$1[str[4]],
1005
+ b: map$1[str[5]] << 4 | map$1[str[6]],
1006
+ a: len === 9 ? map$1[str[7]] << 4 | map$1[str[8]] : 255
965
1007
  };
966
1008
  }
967
1009
  }
@@ -1166,7 +1208,7 @@
1166
1208
  return v.a < 255 ? "hsla(".concat(h, ", ").concat(s, "%, ").concat(l, "%, ").concat(b2n(v.a), ")") : "hsl(".concat(h, ", ").concat(s, "%, ").concat(l, "%)");
1167
1209
  }
1168
1210
 
1169
- var map$1 = {
1211
+ var map$1$1 = {
1170
1212
  x: 'dark',
1171
1213
  Z: 'light',
1172
1214
  Y: 're',
@@ -1349,7 +1391,7 @@
1349
1391
  function unpack() {
1350
1392
  var unpacked = {};
1351
1393
  var keys = Object.keys(names);
1352
- var tkeys = Object.keys(map$1);
1394
+ var tkeys = Object.keys(map$1$1);
1353
1395
  var i, j, k, ok, nk;
1354
1396
 
1355
1397
  for (i = 0; i < keys.length; i++) {
@@ -1357,7 +1399,7 @@
1357
1399
 
1358
1400
  for (j = 0; j < tkeys.length; j++) {
1359
1401
  k = tkeys[j];
1360
- nk = nk.replace(k, map$1[k]);
1402
+ nk = nk.replace(k, map$1$1[k]);
1361
1403
  }
1362
1404
 
1363
1405
  k = parseInt(names[ok], 16);
@@ -2015,28 +2057,8 @@
2015
2057
  var stroke = opts.strokeWidth > 0 && opts.strokeColor !== '';
2016
2058
  var i, line;
2017
2059
  ctx.save();
2018
-
2019
- if (opts.translation) {
2020
- ctx.translate(opts.translation[0], opts.translation[1]);
2021
- }
2022
-
2023
- if (!isNullOrUndef(opts.rotation)) {
2024
- ctx.rotate(opts.rotation);
2025
- }
2026
-
2027
2060
  ctx.font = font.string;
2028
-
2029
- if (opts.color) {
2030
- ctx.fillStyle = opts.color;
2031
- }
2032
-
2033
- if (opts.textAlign) {
2034
- ctx.textAlign = opts.textAlign;
2035
- }
2036
-
2037
- if (opts.textBaseline) {
2038
- ctx.textBaseline = opts.textBaseline;
2039
- }
2061
+ setRenderOpts(ctx, opts);
2040
2062
 
2041
2063
  for (i = 0; i < lines.length; ++i) {
2042
2064
  line = lines[i];
@@ -2054,28 +2076,52 @@
2054
2076
  }
2055
2077
 
2056
2078
  ctx.fillText(line, x, y, opts.maxWidth);
2057
-
2058
- if (opts.strikethrough || opts.underline) {
2059
- var metrics = ctx.measureText(line);
2060
- var left = x - metrics.actualBoundingBoxLeft;
2061
- var right = x + metrics.actualBoundingBoxRight;
2062
- var top = y - metrics.actualBoundingBoxAscent;
2063
- var bottom = y + metrics.actualBoundingBoxDescent;
2064
- var yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom;
2065
- ctx.strokeStyle = ctx.fillStyle;
2066
- ctx.beginPath();
2067
- ctx.lineWidth = opts.decorationWidth || 2;
2068
- ctx.moveTo(left, yDecoration);
2069
- ctx.lineTo(right, yDecoration);
2070
- ctx.stroke();
2071
- }
2072
-
2079
+ decorateText(ctx, x, y, line, opts);
2073
2080
  y += font.lineHeight;
2074
2081
  }
2075
2082
 
2076
2083
  ctx.restore();
2077
2084
  }
2078
2085
 
2086
+ function setRenderOpts(ctx, opts) {
2087
+ if (opts.translation) {
2088
+ ctx.translate(opts.translation[0], opts.translation[1]);
2089
+ }
2090
+
2091
+ if (!isNullOrUndef(opts.rotation)) {
2092
+ ctx.rotate(opts.rotation);
2093
+ }
2094
+
2095
+ if (opts.color) {
2096
+ ctx.fillStyle = opts.color;
2097
+ }
2098
+
2099
+ if (opts.textAlign) {
2100
+ ctx.textAlign = opts.textAlign;
2101
+ }
2102
+
2103
+ if (opts.textBaseline) {
2104
+ ctx.textBaseline = opts.textBaseline;
2105
+ }
2106
+ }
2107
+
2108
+ function decorateText(ctx, x, y, line, opts) {
2109
+ if (opts.strikethrough || opts.underline) {
2110
+ var metrics = ctx.measureText(line);
2111
+ var left = x - metrics.actualBoundingBoxLeft;
2112
+ var right = x + metrics.actualBoundingBoxRight;
2113
+ var top = y - metrics.actualBoundingBoxAscent;
2114
+ var bottom = y + metrics.actualBoundingBoxDescent;
2115
+ var yDecoration = opts.strikethrough ? (top + bottom) / 2 : bottom;
2116
+ ctx.strokeStyle = ctx.fillStyle;
2117
+ ctx.beginPath();
2118
+ ctx.lineWidth = opts.decorationWidth || 2;
2119
+ ctx.moveTo(left, yDecoration);
2120
+ ctx.lineTo(right, yDecoration);
2121
+ ctx.stroke();
2122
+ }
2123
+ }
2124
+
2079
2125
  function addRoundedRectPath(ctx, rect) {
2080
2126
  var x = rect.x,
2081
2127
  y = rect.y,
@@ -2367,11 +2413,7 @@
2367
2413
  return items;
2368
2414
  }
2369
2415
 
2370
- var result = [];
2371
- set.forEach(function (item) {
2372
- result.push(item);
2373
- });
2374
- return result;
2416
+ return Array.from(set);
2375
2417
  }
2376
2418
 
2377
2419
  function _createResolver(scopes) {
@@ -2553,7 +2595,7 @@
2553
2595
  _stack = target._stack;
2554
2596
 
2555
2597
  if (_stack.has(prop)) {
2556
- throw new Error('Recursion detected: ' + _toConsumableArray(_stack).join('->') + '->' + prop);
2598
+ throw new Error('Recursion detected: ' + Array.from(_stack).join('->') + '->' + prop);
2557
2599
  }
2558
2600
 
2559
2601
  _stack.add(prop);
@@ -2662,14 +2704,8 @@
2662
2704
  }
2663
2705
  }
2664
2706
 
2665
- return _createResolver(_toConsumableArray(set), [''], rootScopes, fallback, function () {
2666
- var parent = resolver._getTarget();
2667
-
2668
- if (!(prop in parent)) {
2669
- parent[prop] = {};
2670
- }
2671
-
2672
- return parent[prop];
2707
+ return _createResolver(Array.from(set), [''], rootScopes, fallback, function () {
2708
+ return subGetTarget(resolver, prop, value);
2673
2709
  });
2674
2710
  }
2675
2711
 
@@ -2681,6 +2717,22 @@
2681
2717
  return key;
2682
2718
  }
2683
2719
 
2720
+ function subGetTarget(resolver, prop, value) {
2721
+ var parent = resolver._getTarget();
2722
+
2723
+ if (!(prop in parent)) {
2724
+ parent[prop] = {};
2725
+ }
2726
+
2727
+ var target = parent[prop];
2728
+
2729
+ if (isArray(target) && isObject(value)) {
2730
+ return value;
2731
+ }
2732
+
2733
+ return target;
2734
+ }
2735
+
2684
2736
  function _resolveWithPrefixes(prop, prefixes, scopes, proxy) {
2685
2737
  var value;
2686
2738
 
@@ -2770,7 +2822,7 @@
2770
2822
  _iterator7.f();
2771
2823
  }
2772
2824
 
2773
- return _toConsumableArray(set);
2825
+ return Array.from(set);
2774
2826
  }
2775
2827
 
2776
2828
  var EPSILON = Number.EPSILON || 1e-14;
@@ -2779,6 +2831,10 @@
2779
2831
  return i < points.length && !points[i].skip && points[i];
2780
2832
  };
2781
2833
 
2834
+ var getValueAxis = function getValueAxis(indexAxis) {
2835
+ return indexAxis === 'x' ? 'y' : 'x';
2836
+ };
2837
+
2782
2838
  function splineCurve(firstPoint, middlePoint, afterPoint, t) {
2783
2839
  var previous = firstPoint.skip ? middlePoint : firstPoint;
2784
2840
  var current = middlePoint;
@@ -2836,8 +2892,10 @@
2836
2892
  }
2837
2893
 
2838
2894
  function monotoneCompute(points, mK) {
2895
+ var indexAxis = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'x';
2896
+ var valueAxis = getValueAxis(indexAxis);
2839
2897
  var pointsLen = points.length;
2840
- var deltaX, pointBefore, pointCurrent;
2898
+ var delta, pointBefore, pointCurrent;
2841
2899
  var pointAfter = getPoint(points, 0);
2842
2900
 
2843
2901
  for (var i = 0; i < pointsLen; ++i) {
@@ -2849,25 +2907,26 @@
2849
2907
  continue;
2850
2908
  }
2851
2909
 
2852
- var _pointCurrent = pointCurrent,
2853
- x = _pointCurrent.x,
2854
- y = _pointCurrent.y;
2910
+ var iPixel = pointCurrent[indexAxis];
2911
+ var vPixel = pointCurrent[valueAxis];
2855
2912
 
2856
2913
  if (pointBefore) {
2857
- deltaX = (x - pointBefore.x) / 3;
2858
- pointCurrent.cp1x = x - deltaX;
2859
- pointCurrent.cp1y = y - deltaX * mK[i];
2914
+ delta = (iPixel - pointBefore[indexAxis]) / 3;
2915
+ pointCurrent["cp1".concat(indexAxis)] = iPixel - delta;
2916
+ pointCurrent["cp1".concat(valueAxis)] = vPixel - delta * mK[i];
2860
2917
  }
2861
2918
 
2862
2919
  if (pointAfter) {
2863
- deltaX = (pointAfter.x - x) / 3;
2864
- pointCurrent.cp2x = x + deltaX;
2865
- pointCurrent.cp2y = y + deltaX * mK[i];
2920
+ delta = (pointAfter[indexAxis] - iPixel) / 3;
2921
+ pointCurrent["cp2".concat(indexAxis)] = iPixel + delta;
2922
+ pointCurrent["cp2".concat(valueAxis)] = vPixel + delta * mK[i];
2866
2923
  }
2867
2924
  }
2868
2925
  }
2869
2926
 
2870
2927
  function splineCurveMonotone(points) {
2928
+ var indexAxis = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'x';
2929
+ var valueAxis = getValueAxis(indexAxis);
2871
2930
  var pointsLen = points.length;
2872
2931
  var deltaK = Array(pointsLen).fill(0);
2873
2932
  var mK = Array(pointsLen);
@@ -2884,15 +2943,15 @@
2884
2943
  }
2885
2944
 
2886
2945
  if (pointAfter) {
2887
- var slopeDeltaX = pointAfter.x - pointCurrent.x;
2888
- deltaK[i] = slopeDeltaX !== 0 ? (pointAfter.y - pointCurrent.y) / slopeDeltaX : 0;
2946
+ var slopeDelta = pointAfter[indexAxis] - pointCurrent[indexAxis];
2947
+ deltaK[i] = slopeDelta !== 0 ? (pointAfter[valueAxis] - pointCurrent[valueAxis]) / slopeDelta : 0;
2889
2948
  }
2890
2949
 
2891
2950
  mK[i] = !pointBefore ? deltaK[i] : !pointAfter ? deltaK[i - 1] : sign(deltaK[i - 1]) !== sign(deltaK[i]) ? 0 : (deltaK[i - 1] + deltaK[i]) / 2;
2892
2951
  }
2893
2952
 
2894
2953
  monotoneAdjust(points, deltaK, mK);
2895
- monotoneCompute(points, mK);
2954
+ monotoneCompute(points, mK, indexAxis);
2896
2955
  }
2897
2956
 
2898
2957
  function capControlPoint(pt, min, max) {
@@ -2927,7 +2986,7 @@
2927
2986
  }
2928
2987
  }
2929
2988
 
2930
- function _updateBezierControlPoints(points, options, area, loop) {
2989
+ function _updateBezierControlPoints(points, options, area, loop, indexAxis) {
2931
2990
  var i, ilen, point, controlPoints;
2932
2991
 
2933
2992
  if (options.spanGaps) {
@@ -2937,7 +2996,7 @@
2937
2996
  }
2938
2997
 
2939
2998
  if (options.cubicInterpolationMode === 'monotone') {
2940
- splineCurveMonotone(points);
2999
+ splineCurveMonotone(points, indexAxis);
2941
3000
  } else {
2942
3001
  var prev = loop ? points[points.length - 1] : points[0];
2943
3002
 
@@ -3131,18 +3190,27 @@
3131
3190
  }
3132
3191
 
3133
3192
  function retinaScale(chart, forceRatio, forceStyle) {
3134
- var pixelRatio = chart.currentDevicePixelRatio = forceRatio || 1;
3135
- var canvas = chart.canvas,
3136
- width = chart.width,
3137
- height = chart.height;
3138
- canvas.height = height * pixelRatio;
3139
- canvas.width = width * pixelRatio;
3140
- chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
3193
+ var pixelRatio = forceRatio || 1;
3194
+ var deviceHeight = Math.floor(chart.height * pixelRatio);
3195
+ var deviceWidth = Math.floor(chart.width * pixelRatio);
3196
+ chart.height = deviceHeight / pixelRatio;
3197
+ chart.width = deviceWidth / pixelRatio;
3198
+ var canvas = chart.canvas;
3141
3199
 
3142
3200
  if (canvas.style && (forceStyle || !canvas.style.height && !canvas.style.width)) {
3143
- canvas.style.height = height + 'px';
3144
- canvas.style.width = width + 'px';
3201
+ canvas.style.height = "".concat(chart.height, "px");
3202
+ canvas.style.width = "".concat(chart.width, "px");
3203
+ }
3204
+
3205
+ if (chart.currentDevicePixelRatio !== pixelRatio || canvas.height !== deviceHeight || canvas.width !== deviceWidth) {
3206
+ chart.currentDevicePixelRatio = pixelRatio;
3207
+ canvas.height = deviceHeight;
3208
+ canvas.width = deviceWidth;
3209
+ chart.ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
3210
+ return true;
3145
3211
  }
3212
+
3213
+ return false;
3146
3214
  }
3147
3215
 
3148
3216
  var supportsEventListenerOptions = function () {
@@ -3419,6 +3487,11 @@
3419
3487
  }
3420
3488
 
3421
3489
  value = normalize(point[property]);
3490
+
3491
+ if (value === prevValue) {
3492
+ continue;
3493
+ }
3494
+
3422
3495
  inside = between(value, startBound, endBound);
3423
3496
 
3424
3497
  if (subStart === null && shouldStart()) {
@@ -4269,7 +4342,8 @@
4269
4342
  top: t,
4270
4343
  right: r,
4271
4344
  bottom: b,
4272
- left: l
4345
+ left: l,
4346
+ disabled: value === false
4273
4347
  };
4274
4348
  }
4275
4349
 
@@ -4439,6 +4513,12 @@
4439
4513
  }
4440
4514
 
4441
4515
  function clearStacks(meta, items) {
4516
+ var axis = meta.vScale && meta.vScale.axis;
4517
+
4518
+ if (!axis) {
4519
+ return;
4520
+ }
4521
+
4442
4522
  items = items || meta._parsed;
4443
4523
 
4444
4524
  var _iterator3 = _createForOfIteratorHelper(items),
@@ -4449,11 +4529,11 @@
4449
4529
  var parsed = _step3.value;
4450
4530
  var stacks = parsed._stacks;
4451
4531
 
4452
- if (!stacks || stacks[meta.vScale.id] === undefined || stacks[meta.vScale.id][meta.index] === undefined) {
4532
+ if (!stacks || stacks[axis] === undefined || stacks[axis][meta.index] === undefined) {
4453
4533
  return;
4454
4534
  }
4455
4535
 
4456
- delete stacks[meta.vScale.id][meta.index];
4536
+ delete stacks[axis][meta.index];
4457
4537
  }
4458
4538
  } catch (err) {
4459
4539
  _iterator3.e(err);
@@ -4489,6 +4569,7 @@
4489
4569
  this._drawCount = undefined;
4490
4570
  this.enableOptionSharing = false;
4491
4571
  this.$context = undefined;
4572
+ this._syncList = [];
4492
4573
  this.initialize();
4493
4574
  }
4494
4575
 
@@ -4505,6 +4586,10 @@
4505
4586
  }, {
4506
4587
  key: "updateIndex",
4507
4588
  value: function updateIndex(datasetIndex) {
4589
+ if (this.index !== datasetIndex) {
4590
+ clearStacks(this._cachedMeta);
4591
+ }
4592
+
4508
4593
  this.index = datasetIndex;
4509
4594
  }
4510
4595
  }, {
@@ -4576,19 +4661,23 @@
4576
4661
  var me = this;
4577
4662
  var dataset = me.getDataset();
4578
4663
  var data = dataset.data || (dataset.data = []);
4664
+ var _data = me._data;
4579
4665
 
4580
4666
  if (isObject(data)) {
4581
4667
  me._data = convertObjectDataToArray(data);
4582
- } else if (me._data !== data) {
4583
- if (me._data) {
4584
- unlistenArrayEvents(me._data, me);
4585
- clearStacks(me._cachedMeta);
4668
+ } else if (_data !== data) {
4669
+ if (_data) {
4670
+ unlistenArrayEvents(_data, me);
4671
+ var meta = me._cachedMeta;
4672
+ clearStacks(meta);
4673
+ meta._parsed = [];
4586
4674
  }
4587
4675
 
4588
4676
  if (data && Object.isExtensible(data)) {
4589
4677
  listenArrayEvents(data, me);
4590
4678
  }
4591
4679
 
4680
+ me._syncList = [];
4592
4681
  me._data = data;
4593
4682
  }
4594
4683
  }
@@ -4614,6 +4703,7 @@
4614
4703
 
4615
4704
  me._dataCheck();
4616
4705
 
4706
+ var oldStacked = meta._stacked;
4617
4707
  meta._stacked = isStacked(meta.vScale, meta);
4618
4708
 
4619
4709
  if (meta.stack !== dataset.stack) {
@@ -4624,7 +4714,7 @@
4624
4714
 
4625
4715
  me._resyncElements(resetNewElements);
4626
4716
 
4627
- if (stackChanged) {
4717
+ if (stackChanged || oldStacked !== meta._stacked) {
4628
4718
  updateStacks(me, meta._parsed);
4629
4719
  }
4630
4720
  }
@@ -4950,9 +5040,11 @@
4950
5040
  context = element.$context || (element.$context = createDataContext(me.getContext(), index, element));
4951
5041
  context.parsed = me.getParsed(index);
4952
5042
  context.raw = dataset.data[index];
5043
+ context.index = context.dataIndex = index;
4953
5044
  } else {
4954
5045
  context = me.$context || (me.$context = createDatasetContext(me.chart.getContext(), me.index));
4955
5046
  context.dataset = dataset;
5047
+ context.index = context.datasetIndex = me.index;
4956
5048
  }
4957
5049
 
4958
5050
  context.active = !!active;
@@ -5106,20 +5198,41 @@
5106
5198
  key: "_resyncElements",
5107
5199
  value: function _resyncElements(resetNewElements) {
5108
5200
  var me = this;
5109
- var numMeta = me._cachedMeta.data.length;
5110
- var numData = me._data.length;
5201
+ var data = me._data;
5202
+ var elements = me._cachedMeta.data;
5111
5203
 
5112
- if (numData > numMeta) {
5113
- me._insertElements(numMeta, numData - numMeta, resetNewElements);
5114
- } else if (numData < numMeta) {
5115
- me._removeElements(numData, numMeta - numData);
5204
+ var _iterator4 = _createForOfIteratorHelper(me._syncList),
5205
+ _step4;
5206
+
5207
+ try {
5208
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
5209
+ var _step4$value = _slicedToArray(_step4.value, 3),
5210
+ method = _step4$value[0],
5211
+ arg1 = _step4$value[1],
5212
+ arg2 = _step4$value[2];
5213
+
5214
+ me[method](arg1, arg2);
5215
+ }
5216
+ } catch (err) {
5217
+ _iterator4.e(err);
5218
+ } finally {
5219
+ _iterator4.f();
5116
5220
  }
5117
5221
 
5222
+ me._syncList = [];
5223
+ var numMeta = elements.length;
5224
+ var numData = data.length;
5118
5225
  var count = Math.min(numData, numMeta);
5119
5226
 
5120
5227
  if (count) {
5121
5228
  me.parse(0, count);
5122
5229
  }
5230
+
5231
+ if (numData > numMeta) {
5232
+ me._insertElements(numMeta, numData - numMeta, resetNewElements);
5233
+ } else if (numData < numMeta) {
5234
+ me._removeElements(numData, numMeta - numData);
5235
+ }
5123
5236
  }
5124
5237
  }, {
5125
5238
  key: "_insertElements",
@@ -5179,29 +5292,29 @@
5179
5292
  value: function _onDataPush() {
5180
5293
  var count = arguments.length;
5181
5294
 
5182
- this._insertElements(this.getDataset().data.length - count, count);
5295
+ this._syncList.push(['_insertElements', this.getDataset().data.length - count, count]);
5183
5296
  }
5184
5297
  }, {
5185
5298
  key: "_onDataPop",
5186
5299
  value: function _onDataPop() {
5187
- this._removeElements(this._cachedMeta.data.length - 1, 1);
5300
+ this._syncList.push(['_removeElements', this._cachedMeta.data.length - 1, 1]);
5188
5301
  }
5189
5302
  }, {
5190
5303
  key: "_onDataShift",
5191
5304
  value: function _onDataShift() {
5192
- this._removeElements(0, 1);
5305
+ this._syncList.push(['_removeElements', 0, 1]);
5193
5306
  }
5194
5307
  }, {
5195
5308
  key: "_onDataSplice",
5196
5309
  value: function _onDataSplice(start, count) {
5197
- this._removeElements(start, count);
5310
+ this._syncList.push(['_removeElements', start, count]);
5198
5311
 
5199
- this._insertElements(start, arguments.length - 2);
5312
+ this._syncList.push(['_insertElements', start, arguments.length - 2]);
5200
5313
  }
5201
5314
  }, {
5202
5315
  key: "_onDataUnshift",
5203
5316
  value: function _onDataUnshift() {
5204
- this._insertElements(0, arguments.length);
5317
+ this._syncList.push(['_insertElements', 0, arguments.length]);
5205
5318
  }
5206
5319
  }]);
5207
5320
 
@@ -5417,6 +5530,11 @@
5417
5530
  range.max = Math.max(range.max, custom.max);
5418
5531
  }
5419
5532
  }
5533
+ }, {
5534
+ key: "getMaxOverflow",
5535
+ value: function getMaxOverflow() {
5536
+ return 0;
5537
+ }
5420
5538
  }, {
5421
5539
  key: "getLabelAndValue",
5422
5540
  value: function getLabelAndValue(index) {
@@ -5482,12 +5600,12 @@
5482
5600
  enableBorderRadius: !stack || isFloatBar(parsed._custom) || me.index === stack._top || me.index === stack._bottom,
5483
5601
  x: horizontal ? vpixels.head : ipixels.center,
5484
5602
  y: horizontal ? ipixels.center : vpixels.head,
5485
- height: horizontal ? ipixels.size : undefined,
5486
- width: horizontal ? undefined : ipixels.size
5603
+ height: horizontal ? ipixels.size : Math.abs(vpixels.size),
5604
+ width: horizontal ? Math.abs(vpixels.size) : ipixels.size
5487
5605
  };
5488
5606
 
5489
5607
  if (includeOptions) {
5490
- properties.options = sharedOptions || me.resolveDataElementOptions(i, mode);
5608
+ properties.options = sharedOptions || me.resolveDataElementOptions(i, bars[i].active ? 'active' : mode);
5491
5609
  }
5492
5610
 
5493
5611
  me.updateElement(bars[i], i, properties, mode);
@@ -5508,6 +5626,10 @@
5508
5626
  for (i = 0; i < ilen; ++i) {
5509
5627
  item = metasets[i];
5510
5628
 
5629
+ if (!item.controller.options.grouped) {
5630
+ continue;
5631
+ }
5632
+
5511
5633
  if (typeof dataIndex !== 'undefined') {
5512
5634
  var val = item.controller.getParsed(dataIndex)[item.controller._cachedMeta.vScale.axis];
5513
5635
 
@@ -5681,21 +5803,17 @@
5681
5803
  key: "draw",
5682
5804
  value: function draw() {
5683
5805
  var me = this;
5684
- var chart = me.chart;
5685
5806
  var meta = me._cachedMeta;
5686
5807
  var vScale = meta.vScale;
5687
5808
  var rects = meta.data;
5688
5809
  var ilen = rects.length;
5689
5810
  var i = 0;
5690
- clipArea(chart.ctx, chart.chartArea);
5691
5811
 
5692
5812
  for (; i < ilen; ++i) {
5693
5813
  if (me.getParsed(i)[vScale.axis] !== null) {
5694
5814
  rects[i].draw(me._ctx);
5695
5815
  }
5696
5816
  }
5697
-
5698
- unclipArea(chart.ctx);
5699
5817
  }
5700
5818
  }]);
5701
5819
 
@@ -5820,25 +5938,24 @@
5820
5938
  var me = this;
5821
5939
  var reset = mode === 'reset';
5822
5940
  var _me$_cachedMeta2 = me._cachedMeta,
5823
- xScale = _me$_cachedMeta2.xScale,
5824
- yScale = _me$_cachedMeta2.yScale;
5941
+ iScale = _me$_cachedMeta2.iScale,
5942
+ vScale = _me$_cachedMeta2.vScale;
5825
5943
  var firstOpts = me.resolveDataElementOptions(start, mode);
5826
5944
  var sharedOptions = me.getSharedOptions(firstOpts);
5827
5945
  var includeOptions = me.includeOptions(mode, sharedOptions);
5946
+ var iAxis = iScale.axis;
5947
+ var vAxis = vScale.axis;
5828
5948
 
5829
5949
  for (var i = start; i < start + count; i++) {
5830
5950
  var point = points[i];
5831
5951
  var parsed = !reset && me.getParsed(i);
5832
- var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(parsed.x);
5833
- var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(parsed.y);
5834
- var properties = {
5835
- x: x,
5836
- y: y,
5837
- skip: isNaN(x) || isNaN(y)
5838
- };
5952
+ var properties = {};
5953
+ var iPixel = properties[iAxis] = reset ? iScale.getPixelForDecimal(0.5) : iScale.getPixelForValue(parsed[iAxis]);
5954
+ var vPixel = properties[vAxis] = reset ? vScale.getBasePixel() : vScale.getPixelForValue(parsed[vAxis]);
5955
+ properties.skip = isNaN(iPixel) || isNaN(vPixel);
5839
5956
 
5840
5957
  if (includeOptions) {
5841
- properties.options = me.resolveDataElementOptions(i, mode);
5958
+ properties.options = me.resolveDataElementOptions(i, point.active ? 'active' : mode);
5842
5959
 
5843
5960
  if (reset) {
5844
5961
  properties.options.radius = 0;
@@ -5923,11 +6040,11 @@
5923
6040
  var endY = Math.sin(endAngle);
5924
6041
 
5925
6042
  var calcMax = function calcMax(angle, a, b) {
5926
- return _angleBetween(angle, startAngle, endAngle) ? 1 : Math.max(a, a * cutout, b, b * cutout);
6043
+ return _angleBetween(angle, startAngle, endAngle, true) ? 1 : Math.max(a, a * cutout, b, b * cutout);
5927
6044
  };
5928
6045
 
5929
6046
  var calcMin = function calcMin(angle, a, b) {
5930
- return _angleBetween(angle, startAngle, endAngle) ? -1 : Math.min(a, a * cutout, b, b * cutout);
6047
+ return _angleBetween(angle, startAngle, endAngle, true) ? -1 : Math.min(a, a * cutout, b, b * cutout);
5931
6048
  };
5932
6049
 
5933
6050
  var maxX = calcMax(0, startX, endX);
@@ -6024,7 +6141,7 @@
6024
6141
  var chartArea = chart.chartArea;
6025
6142
  var meta = me._cachedMeta;
6026
6143
  var arcs = meta.data;
6027
- var spacing = me.getMaxBorderWidth() + me.getMaxOffset(arcs);
6144
+ var spacing = me.getMaxBorderWidth() + me.getMaxOffset(arcs) + me.options.spacing;
6028
6145
  var maxSize = Math.max((Math.min(chartArea.width, chartArea.height) - spacing) / 2, 0);
6029
6146
  var cutout = Math.min(toPercentage(me.options.cutout, maxSize), 1);
6030
6147
 
@@ -6111,7 +6228,7 @@
6111
6228
  };
6112
6229
 
6113
6230
  if (includeOptions) {
6114
- properties.options = sharedOptions || me.resolveDataElementOptions(i, mode);
6231
+ properties.options = sharedOptions || me.resolveDataElementOptions(i, arc.active ? 'active' : mode);
6115
6232
  }
6116
6233
 
6117
6234
  startAngle += circumference;
@@ -6251,15 +6368,24 @@
6251
6368
  animations: {
6252
6369
  numbers: {
6253
6370
  type: 'number',
6254
- properties: ['circumference', 'endAngle', 'innerRadius', 'outerRadius', 'startAngle', 'x', 'y', 'offset', 'borderWidth']
6371
+ properties: ['circumference', 'endAngle', 'innerRadius', 'outerRadius', 'startAngle', 'x', 'y', 'offset', 'borderWidth', 'spacing']
6255
6372
  }
6256
6373
  },
6257
6374
  cutout: '50%',
6258
6375
  rotation: 0,
6259
6376
  circumference: 360,
6260
6377
  radius: '100%',
6378
+ spacing: 0,
6261
6379
  indexAxis: 'r'
6262
6380
  };
6381
+ DoughnutController.descriptors = {
6382
+ _scriptable: function _scriptable(name) {
6383
+ return name !== 'spacing';
6384
+ },
6385
+ _indexable: function _indexable(name) {
6386
+ return name !== 'spacing';
6387
+ }
6388
+ };
6263
6389
  DoughnutController.overrides = {
6264
6390
  aspectRatio: 1,
6265
6391
  plugins: {
@@ -6269,6 +6395,7 @@
6269
6395
  var data = chart.data;
6270
6396
 
6271
6397
  if (data.labels.length && data.datasets.length) {
6398
+ var pointStyle = chart.legend.options.labels.pointStyle;
6272
6399
  return data.labels.map(function (label, i) {
6273
6400
  var meta = chart.getDatasetMeta(0);
6274
6401
  var style = meta.controller.getStyle(i);
@@ -6277,6 +6404,7 @@
6277
6404
  fillStyle: style.backgroundColor,
6278
6405
  strokeStyle: style.borderColor,
6279
6406
  lineWidth: style.borderWidth,
6407
+ pointStyle: pointStyle,
6280
6408
  hidden: !chart.getDataVisibility(i),
6281
6409
  index: i
6282
6410
  };
@@ -6376,12 +6504,14 @@
6376
6504
  var me = this;
6377
6505
  var reset = mode === 'reset';
6378
6506
  var _me$_cachedMeta3 = me._cachedMeta,
6379
- xScale = _me$_cachedMeta3.xScale,
6380
- yScale = _me$_cachedMeta3.yScale,
6507
+ iScale = _me$_cachedMeta3.iScale,
6508
+ vScale = _me$_cachedMeta3.vScale,
6381
6509
  _stacked = _me$_cachedMeta3._stacked;
6382
6510
  var firstOpts = me.resolveDataElementOptions(start, mode);
6383
6511
  var sharedOptions = me.getSharedOptions(firstOpts);
6384
6512
  var includeOptions = me.includeOptions(mode, sharedOptions);
6513
+ var iAxis = iScale.axis;
6514
+ var vAxis = vScale.axis;
6385
6515
  var spanGaps = me.options.spanGaps;
6386
6516
  var maxGapLength = isNumber(spanGaps) ? spanGaps : Number.POSITIVE_INFINITY;
6387
6517
  var directUpdate = me.chart._animationsDisabled || reset || mode === 'none';
@@ -6391,15 +6521,15 @@
6391
6521
  var point = points[i];
6392
6522
  var parsed = me.getParsed(i);
6393
6523
  var properties = directUpdate ? point : {};
6394
- var nullData = isNullOrUndef(parsed.y);
6395
- var x = properties.x = xScale.getPixelForValue(parsed.x, i);
6396
- var y = properties.y = reset || nullData ? yScale.getBasePixel() : yScale.getPixelForValue(_stacked ? me.applyStack(yScale, parsed, _stacked) : parsed.y, i);
6397
- properties.skip = isNaN(x) || isNaN(y) || nullData;
6398
- properties.stop = i > 0 && parsed.x - prevParsed.x > maxGapLength;
6524
+ var nullData = isNullOrUndef(parsed[vAxis]);
6525
+ var iPixel = properties[iAxis] = iScale.getPixelForValue(parsed[iAxis], i);
6526
+ var vPixel = properties[vAxis] = reset || nullData ? vScale.getBasePixel() : vScale.getPixelForValue(_stacked ? me.applyStack(vScale, parsed, _stacked) : parsed[vAxis], i);
6527
+ properties.skip = isNaN(iPixel) || isNaN(vPixel) || nullData;
6528
+ properties.stop = i > 0 && parsed[iAxis] - prevParsed[iAxis] > maxGapLength;
6399
6529
  properties.parsed = parsed;
6400
6530
 
6401
6531
  if (includeOptions) {
6402
- properties.options = sharedOptions || me.resolveDataElementOptions(i, mode);
6532
+ properties.options = sharedOptions || me.resolveDataElementOptions(i, point.active ? 'active' : mode);
6403
6533
  }
6404
6534
 
6405
6535
  if (!directUpdate) {
@@ -6431,7 +6561,8 @@
6431
6561
  }, {
6432
6562
  key: "draw",
6433
6563
  value: function draw() {
6434
- this._cachedMeta.dataset.updateControlPoints(this.chart.chartArea);
6564
+ var meta = this._cachedMeta;
6565
+ meta.dataset.updateControlPoints(this.chart.chartArea, meta.iScale.axis);
6435
6566
 
6436
6567
  _get(_getPrototypeOf(LineController.prototype), "draw", this).call(this);
6437
6568
  }
@@ -6529,6 +6660,19 @@
6529
6660
  }
6530
6661
 
6531
6662
  _createClass(PolarAreaController, [{
6663
+ key: "getLabelAndValue",
6664
+ value: function getLabelAndValue(index) {
6665
+ var me = this;
6666
+ var meta = me._cachedMeta;
6667
+ var chart = me.chart;
6668
+ var labels = chart.data.labels || [];
6669
+ var value = formatNumber(meta._parsed[index].r, chart.options.locale);
6670
+ return {
6671
+ label: labels[index] || '',
6672
+ value: value
6673
+ };
6674
+ }
6675
+ }, {
6532
6676
  key: "update",
6533
6677
  value: function update(mode) {
6534
6678
  var arcs = this._cachedMeta.data;
@@ -6598,7 +6742,7 @@
6598
6742
  outerRadius: outerRadius,
6599
6743
  startAngle: startAngle,
6600
6744
  endAngle: endAngle,
6601
- options: me.resolveDataElementOptions(i, mode)
6745
+ options: me.resolveDataElementOptions(i, arc.active ? 'active' : mode)
6602
6746
  };
6603
6747
  me.updateElement(arc, i, properties, mode);
6604
6748
  }
@@ -6653,6 +6797,7 @@
6653
6797
  var data = chart.data;
6654
6798
 
6655
6799
  if (data.labels.length && data.datasets.length) {
6800
+ var pointStyle = chart.legend.options.labels.pointStyle;
6656
6801
  return data.labels.map(function (label, i) {
6657
6802
  var meta = chart.getDatasetMeta(0);
6658
6803
  var style = meta.controller.getStyle(i);
@@ -6661,6 +6806,7 @@
6661
6806
  fillStyle: style.backgroundColor,
6662
6807
  strokeStyle: style.borderColor,
6663
6808
  lineWidth: style.borderWidth,
6809
+ pointStyle: pointStyle,
6664
6810
  hidden: !chart.getDataVisibility(i),
6665
6811
  index: i
6666
6812
  };
@@ -6785,7 +6931,7 @@
6785
6931
 
6786
6932
  for (var i = start; i < start + count; i++) {
6787
6933
  var point = points[i];
6788
- var options = me.resolveDataElementOptions(i, mode);
6934
+ var options = me.resolveDataElementOptions(i, point.active ? 'active' : mode);
6789
6935
  var pointPosition = scale.getPointPositionForValue(i, dataset.data[i]);
6790
6936
  var x = reset ? scale.xCenter : pointPosition.x;
6791
6937
  var y = reset ? scale.yCenter : pointPosition.y;
@@ -6882,7 +7028,7 @@
6882
7028
  });
6883
7029
 
6884
7030
  function abstract() {
6885
- throw new Error('This method is not implemented: either no adapter can be found or an incomplete integration was provided.');
7031
+ throw new Error('This method is not implemented: Check that a complete date adapter is provided.');
6886
7032
  }
6887
7033
 
6888
7034
  var DateAdapter = /*#__PURE__*/function () {
@@ -7071,6 +7217,11 @@
7071
7217
  }
7072
7218
 
7073
7219
  var center = element.getCenterPoint(useFinalPosition);
7220
+
7221
+ if (!_isPointInArea(center, chart.chartArea, chart._minPadding)) {
7222
+ return;
7223
+ }
7224
+
7074
7225
  var distance = distanceMetric(position, center);
7075
7226
 
7076
7227
  if (distance < minDistance) {
@@ -7386,7 +7537,7 @@
7386
7537
  box.left = x;
7387
7538
  box.right = x + box.width;
7388
7539
  box.top = box.fullSize ? userPadding.top : chartArea.top;
7389
- box.bottom = box.fullSize ? params.outerHeight - userPadding.right : chartArea.top + chartArea.h;
7540
+ box.bottom = box.fullSize ? params.outerHeight - userPadding.bottom : chartArea.top + chartArea.h;
7390
7541
  box.height = box.bottom - box.top;
7391
7542
  x = box.right;
7392
7543
  }
@@ -7443,8 +7594,8 @@
7443
7594
  }
7444
7595
 
7445
7596
  var padding = toPadding(chart.options.layout.padding);
7446
- var availableWidth = width - padding.width;
7447
- var availableHeight = height - padding.height;
7597
+ var availableWidth = Math.max(width - padding.width, 0);
7598
+ var availableHeight = Math.max(height - padding.height, 0);
7448
7599
  var boxes = buildLayoutBoxes(chart.boxes);
7449
7600
  var verticalBoxes = boxes.vertical;
7450
7601
  var horizontalBoxes = boxes.horizontal;
@@ -8002,7 +8153,7 @@
8002
8153
  function calculateDelta(tickValue, ticks) {
8003
8154
  var delta = ticks.length > 3 ? ticks[2].value - ticks[1].value : ticks[1].value - ticks[0].value;
8004
8155
 
8005
- if (Math.abs(delta) > 1 && tickValue !== Math.floor(tickValue)) {
8156
+ if (Math.abs(delta) >= 1 && tickValue !== Math.floor(tickValue)) {
8006
8157
  delta = tickValue - Math.floor(tickValue);
8007
8158
  }
8008
8159
 
@@ -8082,6 +8233,14 @@
8082
8233
  defaults.describe('scales', {
8083
8234
  _fallback: 'scale'
8084
8235
  });
8236
+ defaults.describe('scale.ticks', {
8237
+ _scriptable: function _scriptable(name) {
8238
+ return name !== 'backdropPadding' && name !== 'callback';
8239
+ },
8240
+ _indexable: function _indexable(name) {
8241
+ return name !== 'backdropPadding';
8242
+ }
8243
+ });
8085
8244
 
8086
8245
  function autoSkip(scale, ticks) {
8087
8246
  var tickOpts = scale.options.ticks;
@@ -8684,14 +8843,6 @@
8684
8843
  tick = ticks[i];
8685
8844
  tick.label = callback(tickOpts.callback, [tick.value, i, ticks], me);
8686
8845
  }
8687
-
8688
- for (i = 0; i < ilen; i++) {
8689
- if (isNullOrUndef(ticks[i].label)) {
8690
- ticks.splice(i, 1);
8691
- ilen--;
8692
- i--;
8693
- }
8694
- }
8695
8846
  }
8696
8847
  }, {
8697
8848
  key: "afterTickToLabelConversion",
@@ -8901,6 +9052,16 @@
8901
9052
  var me = this;
8902
9053
  me.beforeTickToLabelConversion();
8903
9054
  me.generateTickLabels(ticks);
9055
+ var i, ilen;
9056
+
9057
+ for (i = 0, ilen = ticks.length; i < ilen; i++) {
9058
+ if (isNullOrUndef(ticks[i].label)) {
9059
+ ticks.splice(i, 1);
9060
+ ilen--;
9061
+ i--;
9062
+ }
9063
+ }
9064
+
8904
9065
  me.afterTickToLabelConversion();
8905
9066
  }
8906
9067
  }, {
@@ -9156,7 +9317,10 @@
9156
9317
  x2 = chartArea.right;
9157
9318
  }
9158
9319
 
9159
- for (i = 0; i < ticksLength; ++i) {
9320
+ var limit = valueOrDefault(options.ticks.maxTicksLimit, ticksLength);
9321
+ var step = Math.max(1, Math.ceil(ticksLength / limit));
9322
+
9323
+ for (i = 0; i < ticksLength; i += step) {
9160
9324
  var optsAtIndex = grid.setContext(me.getContext(i));
9161
9325
  var lineWidth = optsAtIndex.lineWidth;
9162
9326
  var lineColor = optsAtIndex.color;
@@ -9786,7 +9950,7 @@
9786
9950
 
9787
9951
  var fontSize = me._resolveTickFontOptions(0).lineHeight;
9788
9952
 
9789
- return me.isHorizontal() ? me.width / fontSize / 0.7 : me.height / fontSize;
9953
+ return (me.isHorizontal() ? me.width : me.height) / fontSize;
9790
9954
  }
9791
9955
  }]);
9792
9956
 
@@ -10113,12 +10277,12 @@
10113
10277
  value: function _notify(descriptors, chart, hook, args) {
10114
10278
  args = args || {};
10115
10279
 
10116
- var _iterator4 = _createForOfIteratorHelper(descriptors),
10117
- _step4;
10280
+ var _iterator5 = _createForOfIteratorHelper(descriptors),
10281
+ _step5;
10118
10282
 
10119
10283
  try {
10120
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
10121
- var descriptor = _step4.value;
10284
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
10285
+ var descriptor = _step5.value;
10122
10286
  var plugin = descriptor.plugin;
10123
10287
  var method = plugin[hook];
10124
10288
  var params = [chart, args, descriptor.options];
@@ -10128,9 +10292,9 @@
10128
10292
  }
10129
10293
  }
10130
10294
  } catch (err) {
10131
- _iterator4.e(err);
10295
+ _iterator5.e(err);
10132
10296
  } finally {
10133
- _iterator4.f();
10297
+ _iterator5.f();
10134
10298
  }
10135
10299
 
10136
10300
  return true;
@@ -10507,8 +10671,7 @@
10507
10671
  return addIfFound(scopes, descriptors, key);
10508
10672
  });
10509
10673
  });
10510
-
10511
- var array = _toConsumableArray(scopes);
10674
+ var array = Array.from(scopes);
10512
10675
 
10513
10676
  if (keysCached.has(keyLists)) {
10514
10677
  cache.set(keyLists, array);
@@ -10546,18 +10709,18 @@
10546
10709
  options = _attachContext(resolver, context, subResolver);
10547
10710
  }
10548
10711
 
10549
- var _iterator5 = _createForOfIteratorHelper(names),
10550
- _step5;
10712
+ var _iterator6 = _createForOfIteratorHelper(names),
10713
+ _step6;
10551
10714
 
10552
10715
  try {
10553
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
10554
- var prop = _step5.value;
10716
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
10717
+ var prop = _step6.value;
10555
10718
  result[prop] = options[prop];
10556
10719
  }
10557
10720
  } catch (err) {
10558
- _iterator5.e(err);
10721
+ _iterator6.e(err);
10559
10722
  } finally {
10560
- _iterator5.f();
10723
+ _iterator6.f();
10561
10724
  }
10562
10725
 
10563
10726
  return result;
@@ -10609,27 +10772,27 @@
10609
10772
  isScriptable = _descriptors2.isScriptable,
10610
10773
  isIndexable = _descriptors2.isIndexable;
10611
10774
 
10612
- var _iterator6 = _createForOfIteratorHelper(names),
10613
- _step6;
10775
+ var _iterator7 = _createForOfIteratorHelper(names),
10776
+ _step7;
10614
10777
 
10615
10778
  try {
10616
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
10617
- var prop = _step6.value;
10779
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
10780
+ var prop = _step7.value;
10618
10781
 
10619
10782
  if (isScriptable(prop) && isFunction(proxy[prop]) || isIndexable(prop) && isArray(proxy[prop])) {
10620
10783
  return true;
10621
10784
  }
10622
10785
  }
10623
10786
  } catch (err) {
10624
- _iterator6.e(err);
10787
+ _iterator7.e(err);
10625
10788
  } finally {
10626
- _iterator6.f();
10789
+ _iterator7.f();
10627
10790
  }
10628
10791
 
10629
10792
  return false;
10630
10793
  }
10631
10794
 
10632
- var version = "3.2.1";
10795
+ var version = "3.4.1";
10633
10796
  var KNOWN_POSITIONS = ['top', 'bottom', 'left', 'right', 'chartArea'];
10634
10797
 
10635
10798
  function positionIsHorizontal(position, axis) {
@@ -10719,6 +10882,7 @@
10719
10882
  this._active = [];
10720
10883
  this._lastEvent = undefined;
10721
10884
  this._listeners = {};
10885
+ this._responsiveListeners = undefined;
10722
10886
  this._sortedMetasets = [];
10723
10887
  this.scales = {};
10724
10888
  this.scale = undefined;
@@ -10843,17 +11007,15 @@
10843
11007
  var canvas = me.canvas;
10844
11008
  var aspectRatio = options.maintainAspectRatio && me.aspectRatio;
10845
11009
  var newSize = me.platform.getMaximumSize(canvas, width, height, aspectRatio);
10846
- var oldRatio = me.currentDevicePixelRatio;
10847
11010
  var newRatio = options.devicePixelRatio || me.platform.getDevicePixelRatio();
11011
+ me.width = newSize.width;
11012
+ me.height = newSize.height;
11013
+ me._aspectRatio = me.aspectRatio;
10848
11014
 
10849
- if (me.width === newSize.width && me.height === newSize.height && oldRatio === newRatio) {
11015
+ if (!retinaScale(me, newRatio, true)) {
10850
11016
  return;
10851
11017
  }
10852
11018
 
10853
- me.width = newSize.width;
10854
- me.height = newSize.height;
10855
- me._aspectRatio = me.aspectRatio;
10856
- retinaScale(me, newRatio, true);
10857
11019
  me.notifyPlugins('resize', {
10858
11020
  size: newSize
10859
11021
  });
@@ -10939,18 +11101,6 @@
10939
11101
  layouts.addBox(me, scale);
10940
11102
  });
10941
11103
  }
10942
- }, {
10943
- key: "_updateMetasetIndex",
10944
- value: function _updateMetasetIndex(meta, index) {
10945
- var metasets = this._metasets;
10946
- var oldIndex = meta.index;
10947
-
10948
- if (oldIndex !== index) {
10949
- metasets[oldIndex] = metasets[index];
10950
- metasets[index] = meta;
10951
- meta.index = index;
10952
- }
10953
- }
10954
11104
  }, {
10955
11105
  key: "_updateMetasets",
10956
11106
  value: function _updateMetasets() {
@@ -10958,6 +11108,9 @@
10958
11108
  var metasets = me._metasets;
10959
11109
  var numData = me.data.datasets.length;
10960
11110
  var numMeta = metasets.length;
11111
+ metasets.sort(function (a, b) {
11112
+ return a.index - b.index;
11113
+ });
10961
11114
 
10962
11115
  if (numMeta > numData) {
10963
11116
  for (var i = numData; i < numMeta; ++i) {
@@ -11012,9 +11165,7 @@
11012
11165
  meta.type = type;
11013
11166
  meta.indexAxis = dataset.indexAxis || getIndexAxis(type, me.options);
11014
11167
  meta.order = dataset.order || 0;
11015
-
11016
- me._updateMetasetIndex(meta, i);
11017
-
11168
+ meta.index = i;
11018
11169
  meta.label = '' + dataset.label;
11019
11170
  meta.visible = me.isDatasetVisible(i);
11020
11171
 
@@ -11070,7 +11221,7 @@
11070
11221
  var existingEvents = new Set(Object.keys(me._listeners));
11071
11222
  var newEvents = new Set(me.options.events);
11072
11223
 
11073
- if (!setsEqual(existingEvents, newEvents)) {
11224
+ if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== me.options.responsive) {
11074
11225
  me.unbindEvents();
11075
11226
  me.bindEvents();
11076
11227
  }
@@ -11312,6 +11463,7 @@
11312
11463
  var me = this;
11313
11464
  var ctx = me.ctx;
11314
11465
  var clip = meta._clip;
11466
+ var useClip = !clip.disabled;
11315
11467
  var area = me.chartArea;
11316
11468
  var args = {
11317
11469
  meta: meta,
@@ -11323,14 +11475,21 @@
11323
11475
  return;
11324
11476
  }
11325
11477
 
11326
- clipArea(ctx, {
11327
- left: clip.left === false ? 0 : area.left - clip.left,
11328
- right: clip.right === false ? me.width : area.right + clip.right,
11329
- top: clip.top === false ? 0 : area.top - clip.top,
11330
- bottom: clip.bottom === false ? me.height : area.bottom + clip.bottom
11331
- });
11478
+ if (useClip) {
11479
+ clipArea(ctx, {
11480
+ left: clip.left === false ? 0 : area.left - clip.left,
11481
+ right: clip.right === false ? me.width : area.right + clip.right,
11482
+ top: clip.top === false ? 0 : area.top - clip.top,
11483
+ bottom: clip.bottom === false ? me.height : area.bottom + clip.bottom
11484
+ });
11485
+ }
11486
+
11332
11487
  meta.controller.draw();
11333
- unclipArea(ctx);
11488
+
11489
+ if (useClip) {
11490
+ unclipArea(ctx);
11491
+ }
11492
+
11334
11493
  args.cancelable = false;
11335
11494
  me.notifyPlugins('afterDatasetDraw', args);
11336
11495
  }
@@ -11356,7 +11515,7 @@
11356
11515
  }).pop();
11357
11516
 
11358
11517
  if (!meta) {
11359
- meta = metasets[datasetIndex] = {
11518
+ meta = {
11360
11519
  type: null,
11361
11520
  data: [],
11362
11521
  dataset: null,
@@ -11370,6 +11529,7 @@
11370
11529
  _parsed: [],
11371
11530
  _sorted: false
11372
11531
  };
11532
+ metasets.push(meta);
11373
11533
  }
11374
11534
 
11375
11535
  return meta;
@@ -11491,6 +11651,17 @@
11491
11651
  }, {
11492
11652
  key: "bindEvents",
11493
11653
  value: function bindEvents() {
11654
+ this.bindUserEvents();
11655
+
11656
+ if (this.options.responsive) {
11657
+ this.bindResponsiveEvents();
11658
+ } else {
11659
+ this.attached = true;
11660
+ }
11661
+ }
11662
+ }, {
11663
+ key: "bindUserEvents",
11664
+ value: function bindUserEvents() {
11494
11665
  var me = this;
11495
11666
  var listeners = me._listeners;
11496
11667
  var platform = me.platform;
@@ -11500,13 +11671,6 @@
11500
11671
  listeners[type] = listener;
11501
11672
  };
11502
11673
 
11503
- var _remove = function _remove(type, listener) {
11504
- if (listeners[type]) {
11505
- platform.removeEventListener(me, type, listener);
11506
- delete listeners[type];
11507
- }
11508
- };
11509
-
11510
11674
  var listener = function listener(e, x, y) {
11511
11675
  e.offsetX = x;
11512
11676
  e.offsetY = y;
@@ -11517,58 +11681,76 @@
11517
11681
  each(me.options.events, function (type) {
11518
11682
  return _add(type, listener);
11519
11683
  });
11684
+ }
11685
+ }, {
11686
+ key: "bindResponsiveEvents",
11687
+ value: function bindResponsiveEvents() {
11688
+ var me = this;
11520
11689
 
11521
- if (me.options.responsive) {
11522
- listener = function listener(width, height) {
11523
- if (me.canvas) {
11524
- me.resize(width, height);
11525
- }
11526
- };
11690
+ if (!me._responsiveListeners) {
11691
+ me._responsiveListeners = {};
11692
+ }
11527
11693
 
11528
- var detached;
11694
+ var listeners = me._responsiveListeners;
11695
+ var platform = me.platform;
11529
11696
 
11530
- var attached = function attached() {
11531
- _remove('attach', attached);
11697
+ var _add = function _add(type, listener) {
11698
+ platform.addEventListener(me, type, listener);
11699
+ listeners[type] = listener;
11700
+ };
11532
11701
 
11533
- me.attached = true;
11534
- me.resize();
11702
+ var _remove = function _remove(type, listener) {
11703
+ if (listeners[type]) {
11704
+ platform.removeEventListener(me, type, listener);
11705
+ delete listeners[type];
11706
+ }
11707
+ };
11535
11708
 
11536
- _add('resize', listener);
11709
+ var listener = function listener(width, height) {
11710
+ if (me.canvas) {
11711
+ me.resize(width, height);
11712
+ }
11713
+ };
11537
11714
 
11538
- _add('detach', detached);
11539
- };
11715
+ var detached;
11540
11716
 
11541
- detached = function detached() {
11542
- me.attached = false;
11717
+ var attached = function attached() {
11718
+ _remove('attach', attached);
11543
11719
 
11544
- _remove('resize', listener);
11720
+ me.attached = true;
11721
+ me.resize();
11545
11722
 
11546
- _add('attach', attached);
11547
- };
11723
+ _add('resize', listener);
11548
11724
 
11549
- if (platform.isAttached(me.canvas)) {
11550
- attached();
11551
- } else {
11552
- detached();
11553
- }
11725
+ _add('detach', detached);
11726
+ };
11727
+
11728
+ detached = function detached() {
11729
+ me.attached = false;
11730
+
11731
+ _remove('resize', listener);
11732
+
11733
+ _add('attach', attached);
11734
+ };
11735
+
11736
+ if (platform.isAttached(me.canvas)) {
11737
+ attached();
11554
11738
  } else {
11555
- me.attached = true;
11739
+ detached();
11556
11740
  }
11557
11741
  }
11558
11742
  }, {
11559
11743
  key: "unbindEvents",
11560
11744
  value: function unbindEvents() {
11561
11745
  var me = this;
11562
- var listeners = me._listeners;
11563
-
11564
- if (!listeners) {
11565
- return;
11566
- }
11567
-
11746
+ each(me._listeners, function (listener, type) {
11747
+ me.platform.removeEventListener(me, type, listener);
11748
+ });
11568
11749
  me._listeners = {};
11569
- each(listeners, function (listener, type) {
11750
+ each(me._responsiveListeners, function (listener, type) {
11570
11751
  me.platform.removeEventListener(me, type, listener);
11571
11752
  });
11753
+ me._responsiveListeners = undefined;
11572
11754
  }
11573
11755
  }, {
11574
11756
  key: "updateHoverStyle",
@@ -11776,9 +11958,8 @@
11776
11958
  }
11777
11959
  });
11778
11960
 
11779
- function clipArc(ctx, element) {
11961
+ function clipArc(ctx, element, endAngle) {
11780
11962
  var startAngle = element.startAngle,
11781
- endAngle = element.endAngle,
11782
11963
  pixelMargin = element.pixelMargin,
11783
11964
  x = element.x,
11784
11965
  y = element.y,
@@ -11828,14 +12009,29 @@
11828
12009
  };
11829
12010
  }
11830
12011
 
11831
- function pathArc(ctx, element) {
12012
+ function pathArc(ctx, element, offset, spacing, end) {
11832
12013
  var x = element.x,
11833
12014
  y = element.y,
11834
- startAngle = element.startAngle,
11835
- endAngle = element.endAngle,
11836
- pixelMargin = element.pixelMargin;
11837
- var outerRadius = Math.max(element.outerRadius - pixelMargin, 0);
11838
- var innerRadius = element.innerRadius + pixelMargin;
12015
+ start = element.startAngle,
12016
+ pixelMargin = element.pixelMargin,
12017
+ innerR = element.innerRadius;
12018
+ var outerRadius = Math.max(element.outerRadius + spacing + offset - pixelMargin, 0);
12019
+ var innerRadius = innerR > 0 ? innerR + spacing + offset + pixelMargin : 0;
12020
+ var spacingOffset = 0;
12021
+ var alpha = end - start;
12022
+
12023
+ if (spacing) {
12024
+ var noSpacingInnerRadius = innerR > 0 ? innerR - spacing : 0;
12025
+ var noSpacingOuterRadius = outerRadius > 0 ? outerRadius - spacing : 0;
12026
+ var avNogSpacingRadius = (noSpacingInnerRadius + noSpacingOuterRadius) / 2;
12027
+ var adjustedAngle = avNogSpacingRadius !== 0 ? alpha * avNogSpacingRadius / (avNogSpacingRadius + spacing) : alpha;
12028
+ spacingOffset = (alpha - adjustedAngle) / 2;
12029
+ }
12030
+
12031
+ var beta = Math.max(0.001, alpha * outerRadius - offset / PI) / outerRadius;
12032
+ var angleOffset = (alpha - beta) / 2;
12033
+ var startAngle = start + angleOffset + spacingOffset;
12034
+ var endAngle = end - angleOffset - spacingOffset;
11839
12035
 
11840
12036
  var _parseBorderRadius$ = parseBorderRadius$1(element, innerRadius, outerRadius, endAngle - startAngle),
11841
12037
  outerStart = _parseBorderRadius$.outerStart,
@@ -11888,61 +12084,63 @@
11888
12084
  ctx.closePath();
11889
12085
  }
11890
12086
 
11891
- function drawArc(ctx, element) {
11892
- if (element.fullCircles) {
11893
- element.endAngle = element.startAngle + TAU;
11894
- pathArc(ctx, element);
12087
+ function drawArc(ctx, element, offset, spacing) {
12088
+ var fullCircles = element.fullCircles,
12089
+ startAngle = element.startAngle,
12090
+ circumference = element.circumference;
12091
+ var endAngle = element.endAngle;
11895
12092
 
11896
- for (var i = 0; i < element.fullCircles; ++i) {
12093
+ if (fullCircles) {
12094
+ pathArc(ctx, element, offset, spacing, startAngle + TAU);
12095
+
12096
+ for (var i = 0; i < fullCircles; ++i) {
11897
12097
  ctx.fill();
11898
12098
  }
11899
- }
11900
12099
 
11901
- if (!isNaN(element.circumference)) {
11902
- element.endAngle = element.startAngle + element.circumference % TAU;
12100
+ if (!isNaN(circumference)) {
12101
+ endAngle = startAngle + circumference % TAU;
12102
+
12103
+ if (circumference % TAU === 0) {
12104
+ endAngle += TAU;
12105
+ }
12106
+ }
11903
12107
  }
11904
12108
 
11905
- pathArc(ctx, element);
12109
+ pathArc(ctx, element, offset, spacing, endAngle);
11906
12110
  ctx.fill();
12111
+ return endAngle;
11907
12112
  }
11908
12113
 
11909
12114
  function drawFullCircleBorders(ctx, element, inner) {
11910
12115
  var x = element.x,
11911
12116
  y = element.y,
11912
12117
  startAngle = element.startAngle,
11913
- endAngle = element.endAngle,
11914
- pixelMargin = element.pixelMargin;
12118
+ pixelMargin = element.pixelMargin,
12119
+ fullCircles = element.fullCircles;
11915
12120
  var outerRadius = Math.max(element.outerRadius - pixelMargin, 0);
11916
12121
  var innerRadius = element.innerRadius + pixelMargin;
11917
12122
  var i;
11918
12123
 
11919
12124
  if (inner) {
11920
- element.endAngle = element.startAngle + TAU;
11921
- clipArc(ctx, element);
11922
- element.endAngle = endAngle;
11923
-
11924
- if (element.endAngle === element.startAngle) {
11925
- element.endAngle += TAU;
11926
- element.fullCircles--;
11927
- }
12125
+ clipArc(ctx, element, startAngle + TAU);
11928
12126
  }
11929
12127
 
11930
12128
  ctx.beginPath();
11931
12129
  ctx.arc(x, y, innerRadius, startAngle + TAU, startAngle, true);
11932
12130
 
11933
- for (i = 0; i < element.fullCircles; ++i) {
12131
+ for (i = 0; i < fullCircles; ++i) {
11934
12132
  ctx.stroke();
11935
12133
  }
11936
12134
 
11937
12135
  ctx.beginPath();
11938
12136
  ctx.arc(x, y, outerRadius, startAngle, startAngle + TAU);
11939
12137
 
11940
- for (i = 0; i < element.fullCircles; ++i) {
12138
+ for (i = 0; i < fullCircles; ++i) {
11941
12139
  ctx.stroke();
11942
12140
  }
11943
12141
  }
11944
12142
 
11945
- function drawBorder(ctx, element) {
12143
+ function drawBorder(ctx, element, offset, spacing, endAngle) {
11946
12144
  var options = element.options;
11947
12145
  var inner = options.borderAlign === 'inner';
11948
12146
 
@@ -11963,10 +12161,10 @@
11963
12161
  }
11964
12162
 
11965
12163
  if (inner) {
11966
- clipArc(ctx, element);
12164
+ clipArc(ctx, element, endAngle);
11967
12165
  }
11968
12166
 
11969
- pathArc(ctx, element);
12167
+ pathArc(ctx, element, offset, spacing, endAngle);
11970
12168
  ctx.stroke();
11971
12169
  }
11972
12170
 
@@ -12016,15 +12214,17 @@
12016
12214
  outerRadius = _this$getProps2.outerRadius,
12017
12215
  circumference = _this$getProps2.circumference;
12018
12216
 
12217
+ var rAdjust = this.options.spacing / 2;
12218
+
12019
12219
  var betweenAngles = circumference >= TAU || _angleBetween(angle, startAngle, endAngle);
12020
12220
 
12021
- var withinRadius = distance >= innerRadius && distance <= outerRadius;
12221
+ var withinRadius = distance >= innerRadius + rAdjust && distance <= outerRadius + rAdjust;
12022
12222
  return betweenAngles && withinRadius;
12023
12223
  }
12024
12224
  }, {
12025
12225
  key: "getCenterPoint",
12026
12226
  value: function getCenterPoint(useFinalPosition) {
12027
- var _this$getProps3 = this.getProps(['x', 'y', 'startAngle', 'endAngle', 'innerRadius', 'outerRadius'], useFinalPosition),
12227
+ var _this$getProps3 = this.getProps(['x', 'y', 'startAngle', 'endAngle', 'innerRadius', 'outerRadius', 'circumference'], useFinalPosition),
12028
12228
  x = _this$getProps3.x,
12029
12229
  y = _this$getProps3.y,
12030
12230
  startAngle = _this$getProps3.startAngle,
@@ -12032,8 +12232,11 @@
12032
12232
  innerRadius = _this$getProps3.innerRadius,
12033
12233
  outerRadius = _this$getProps3.outerRadius;
12034
12234
 
12235
+ var _this$options4 = this.options,
12236
+ offset = _this$options4.offset,
12237
+ spacing = _this$options4.spacing;
12035
12238
  var halfAngle = (startAngle + endAngle) / 2;
12036
- var halfRadius = (innerRadius + outerRadius) / 2;
12239
+ var halfRadius = (innerRadius + outerRadius + spacing + offset) / 2;
12037
12240
  return {
12038
12241
  x: x + Math.cos(halfAngle) * halfRadius,
12039
12242
  y: y + Math.sin(halfAngle) * halfRadius
@@ -12048,26 +12251,34 @@
12048
12251
  key: "draw",
12049
12252
  value: function draw(ctx) {
12050
12253
  var me = this;
12051
- var options = me.options;
12052
- var offset = options.offset || 0;
12254
+ var options = me.options,
12255
+ circumference = me.circumference;
12256
+ var offset = (options.offset || 0) / 2;
12257
+ var spacing = (options.spacing || 0) / 2;
12053
12258
  me.pixelMargin = options.borderAlign === 'inner' ? 0.33 : 0;
12054
- me.fullCircles = Math.floor(me.circumference / TAU);
12259
+ me.fullCircles = circumference > TAU ? Math.floor(circumference / TAU) : 0;
12055
12260
 
12056
- if (me.circumference === 0 || me.innerRadius < 0 || me.outerRadius < 0) {
12261
+ if (circumference === 0 || me.innerRadius < 0 || me.outerRadius < 0) {
12057
12262
  return;
12058
12263
  }
12059
12264
 
12060
12265
  ctx.save();
12266
+ var radiusOffset = 0;
12061
12267
 
12062
- if (offset && me.circumference < TAU) {
12268
+ if (offset) {
12269
+ radiusOffset = offset / 2;
12063
12270
  var halfAngle = (me.startAngle + me.endAngle) / 2;
12064
- ctx.translate(Math.cos(halfAngle) * offset, Math.sin(halfAngle) * offset);
12271
+ ctx.translate(Math.cos(halfAngle) * radiusOffset, Math.sin(halfAngle) * radiusOffset);
12272
+
12273
+ if (me.circumference >= PI) {
12274
+ radiusOffset = offset;
12275
+ }
12065
12276
  }
12066
12277
 
12067
12278
  ctx.fillStyle = options.backgroundColor;
12068
12279
  ctx.strokeStyle = options.borderColor;
12069
- drawArc(ctx, me);
12070
- drawBorder(ctx, me);
12280
+ var endAngle = drawArc(ctx, me, radiusOffset, spacing);
12281
+ drawBorder(ctx, me, radiusOffset, spacing, endAngle);
12071
12282
  ctx.restore();
12072
12283
  }
12073
12284
  }]);
@@ -12082,6 +12293,7 @@
12082
12293
  borderRadius: 0,
12083
12294
  borderWidth: 2,
12084
12295
  offset: 0,
12296
+ spacing: 0,
12085
12297
  angle: undefined
12086
12298
  };
12087
12299
  ArcElement.defaultRoutes = {
@@ -12283,12 +12495,12 @@
12283
12495
 
12284
12496
  var segmentMethod = _getSegmentMethod(line);
12285
12497
 
12286
- var _iterator7 = _createForOfIteratorHelper(segments),
12287
- _step7;
12498
+ var _iterator8 = _createForOfIteratorHelper(segments),
12499
+ _step8;
12288
12500
 
12289
12501
  try {
12290
- for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
12291
- var segment = _step7.value;
12502
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
12503
+ var segment = _step8.value;
12292
12504
  setStyle(ctx, options, segment.style);
12293
12505
  ctx.beginPath();
12294
12506
 
@@ -12302,9 +12514,9 @@
12302
12514
  ctx.stroke();
12303
12515
  }
12304
12516
  } catch (err) {
12305
- _iterator7.e(err);
12517
+ _iterator8.e(err);
12306
12518
  } finally {
12307
- _iterator7.f();
12519
+ _iterator8.f();
12308
12520
  }
12309
12521
  }
12310
12522
 
@@ -12348,14 +12560,14 @@
12348
12560
 
12349
12561
  _createClass(LineElement, [{
12350
12562
  key: "updateControlPoints",
12351
- value: function updateControlPoints(chartArea) {
12563
+ value: function updateControlPoints(chartArea, indexAxis) {
12352
12564
  var me = this;
12353
12565
  var options = me.options;
12354
12566
 
12355
12567
  if ((options.tension || options.cubicInterpolationMode === 'monotone') && !options.stepped && !me._pointsUpdated) {
12356
12568
  var loop = options.spanGaps ? me._loop : me._fullLoop;
12357
12569
 
12358
- _updateBezierControlPoints(me._points, options, chartArea, loop);
12570
+ _updateBezierControlPoints(me._points, options, chartArea, loop, indexAxis);
12359
12571
 
12360
12572
  me._pointsUpdated = true;
12361
12573
  }
@@ -12457,21 +12669,21 @@
12457
12669
  start = start || 0;
12458
12670
  count = count || me.points.length - start;
12459
12671
 
12460
- var _iterator8 = _createForOfIteratorHelper(segments),
12461
- _step8;
12672
+ var _iterator9 = _createForOfIteratorHelper(segments),
12673
+ _step9;
12462
12674
 
12463
12675
  try {
12464
- for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
12465
- var segment = _step8.value;
12676
+ for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
12677
+ var segment = _step9.value;
12466
12678
  loop &= segmentMethod(ctx, me, segment, {
12467
12679
  start: start,
12468
12680
  end: start + count - 1
12469
12681
  });
12470
12682
  }
12471
12683
  } catch (err) {
12472
- _iterator8.e(err);
12684
+ _iterator9.e(err);
12473
12685
  } finally {
12474
- _iterator8.f();
12686
+ _iterator9.f();
12475
12687
  }
12476
12688
 
12477
12689
  return !!loop;
@@ -13304,6 +13516,18 @@
13304
13516
  return computeLinearBoundary(source);
13305
13517
  }
13306
13518
 
13519
+ function findSegmentEnd(start, end, points) {
13520
+ for (; end > start; end--) {
13521
+ var point = points[end];
13522
+
13523
+ if (!isNaN(point.x) && !isNaN(point.y)) {
13524
+ break;
13525
+ }
13526
+ }
13527
+
13528
+ return end;
13529
+ }
13530
+
13307
13531
  function pointsFromSegments(boundary, line) {
13308
13532
  var _ref4 = boundary || {},
13309
13533
  _ref4$x = _ref4.x,
@@ -13313,9 +13537,12 @@
13313
13537
 
13314
13538
  var linePoints = line.points;
13315
13539
  var points = [];
13316
- line.segments.forEach(function (segment) {
13317
- var first = linePoints[segment.start];
13318
- var last = linePoints[segment.end];
13540
+ line.segments.forEach(function (_ref5) {
13541
+ var start = _ref5.start,
13542
+ end = _ref5.end;
13543
+ end = findSegmentEnd(start, end, linePoints);
13544
+ var first = linePoints[start];
13545
+ var last = linePoints[end];
13319
13546
 
13320
13547
  if (y !== null) {
13321
13548
  points.push({
@@ -13570,42 +13797,45 @@
13570
13797
  var tpoints = target.points;
13571
13798
  var parts = [];
13572
13799
 
13573
- var _iterator9 = _createForOfIteratorHelper(segments),
13574
- _step9;
13800
+ var _iterator10 = _createForOfIteratorHelper(segments),
13801
+ _step10;
13575
13802
 
13576
13803
  try {
13577
- for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
13578
- var segment = _step9.value;
13579
- var bounds = getBounds(property, points[segment.start], points[segment.end], segment.loop);
13804
+ for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
13805
+ var segment = _step10.value;
13806
+ var start = segment.start,
13807
+ end = segment.end;
13808
+ end = findSegmentEnd(start, end, points);
13809
+ var bounds = getBounds(property, points[start], points[end], segment.loop);
13580
13810
 
13581
13811
  if (!target.segments) {
13582
13812
  parts.push({
13583
13813
  source: segment,
13584
13814
  target: bounds,
13585
- start: points[segment.start],
13586
- end: points[segment.end]
13815
+ start: points[start],
13816
+ end: points[end]
13587
13817
  });
13588
13818
  continue;
13589
13819
  }
13590
13820
 
13591
13821
  var targetSegments = _boundSegments(target, bounds);
13592
13822
 
13593
- var _iterator10 = _createForOfIteratorHelper(targetSegments),
13594
- _step10;
13823
+ var _iterator11 = _createForOfIteratorHelper(targetSegments),
13824
+ _step11;
13595
13825
 
13596
13826
  try {
13597
- for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
13598
- var tgt = _step10.value;
13827
+ for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
13828
+ var tgt = _step11.value;
13599
13829
  var subBounds = getBounds(property, tpoints[tgt.start], tpoints[tgt.end], tgt.loop);
13600
13830
 
13601
13831
  var fillSources = _boundSegment(segment, points, subBounds);
13602
13832
 
13603
- var _iterator11 = _createForOfIteratorHelper(fillSources),
13604
- _step11;
13833
+ var _iterator12 = _createForOfIteratorHelper(fillSources),
13834
+ _step12;
13605
13835
 
13606
13836
  try {
13607
- for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
13608
- var fillSource = _step11.value;
13837
+ for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
13838
+ var fillSource = _step12.value;
13609
13839
  parts.push({
13610
13840
  source: fillSource,
13611
13841
  target: tgt,
@@ -13614,21 +13844,21 @@
13614
13844
  });
13615
13845
  }
13616
13846
  } catch (err) {
13617
- _iterator11.e(err);
13847
+ _iterator12.e(err);
13618
13848
  } finally {
13619
- _iterator11.f();
13849
+ _iterator12.f();
13620
13850
  }
13621
13851
  }
13622
13852
  } catch (err) {
13623
- _iterator10.e(err);
13853
+ _iterator11.e(err);
13624
13854
  } finally {
13625
- _iterator10.f();
13855
+ _iterator11.f();
13626
13856
  }
13627
13857
  }
13628
13858
  } catch (err) {
13629
- _iterator9.e(err);
13859
+ _iterator10.e(err);
13630
13860
  } finally {
13631
- _iterator9.f();
13861
+ _iterator10.f();
13632
13862
  }
13633
13863
 
13634
13864
  return parts;
@@ -13639,10 +13869,10 @@
13639
13869
  top = _scale$chart$chartAre.top,
13640
13870
  bottom = _scale$chart$chartAre.bottom;
13641
13871
 
13642
- var _ref5 = bounds || {},
13643
- property = _ref5.property,
13644
- start = _ref5.start,
13645
- end = _ref5.end;
13872
+ var _ref6 = bounds || {},
13873
+ property = _ref6.property,
13874
+ start = _ref6.start,
13875
+ end = _ref6.end;
13646
13876
 
13647
13877
  if (property === 'x') {
13648
13878
  ctx.beginPath();
@@ -13668,16 +13898,16 @@
13668
13898
 
13669
13899
  var segments = _segments(line, target, property);
13670
13900
 
13671
- var _iterator12 = _createForOfIteratorHelper(segments),
13672
- _step12;
13901
+ var _iterator13 = _createForOfIteratorHelper(segments),
13902
+ _step13;
13673
13903
 
13674
13904
  try {
13675
- for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
13676
- var _step12$value = _step12.value,
13677
- src = _step12$value.source,
13678
- tgt = _step12$value.target,
13679
- start = _step12$value.start,
13680
- end = _step12$value.end;
13905
+ for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
13906
+ var _step13$value = _step13.value,
13907
+ src = _step13$value.source,
13908
+ tgt = _step13$value.target,
13909
+ start = _step13$value.start,
13910
+ end = _step13$value.end;
13681
13911
  var _src$style = src.style;
13682
13912
  _src$style = _src$style === void 0 ? {} : _src$style;
13683
13913
  var _src$style$background = _src$style.backgroundColor,
@@ -13709,9 +13939,9 @@
13709
13939
  ctx.restore();
13710
13940
  }
13711
13941
  } catch (err) {
13712
- _iterator12.e(err);
13942
+ _iterator13.e(err);
13713
13943
  } finally {
13714
- _iterator12.f();
13944
+ _iterator13.f();
13715
13945
  }
13716
13946
  }
13717
13947
 
@@ -13762,11 +13992,11 @@
13762
13992
  var fillOption = lineOpts.fill;
13763
13993
  var color = lineOpts.backgroundColor;
13764
13994
 
13765
- var _ref6 = fillOption || {},
13766
- _ref6$above = _ref6.above,
13767
- above = _ref6$above === void 0 ? color : _ref6$above,
13768
- _ref6$below = _ref6.below,
13769
- below = _ref6$below === void 0 ? color : _ref6$below;
13995
+ var _ref7 = fillOption || {},
13996
+ _ref7$above = _ref7.above,
13997
+ above = _ref7$above === void 0 ? color : _ref7$above,
13998
+ _ref7$below = _ref7.below,
13999
+ below = _ref7$below === void 0 ? color : _ref7$below;
13770
14000
 
13771
14001
  if (target && line.points.length) {
13772
14002
  clipArea(ctx, area);
@@ -13833,7 +14063,7 @@
13833
14063
  continue;
13834
14064
  }
13835
14065
 
13836
- source.line.updateControlPoints(area);
14066
+ source.line.updateControlPoints(area, source.axis);
13837
14067
 
13838
14068
  if (draw) {
13839
14069
  drawfill(chart.ctx, source, area);
@@ -13946,11 +14176,11 @@
13946
14176
 
13947
14177
  if (me.isHorizontal()) {
13948
14178
  me.width = me.maxWidth;
13949
- me.left = 0;
14179
+ me.left = me._margins.left;
13950
14180
  me.right = me.width;
13951
14181
  } else {
13952
14182
  me.height = me.maxHeight;
13953
- me.top = 0;
14183
+ me.top = me._margins.top;
13954
14184
  me.bottom = me.height;
13955
14185
  }
13956
14186
  }
@@ -14065,12 +14295,11 @@
14065
14295
  var currentColWidth = 0;
14066
14296
  var currentColHeight = 0;
14067
14297
  var left = 0;
14068
- var top = 0;
14069
14298
  var col = 0;
14070
14299
  me.legendItems.forEach(function (legendItem, i) {
14071
14300
  var itemWidth = boxWidth + fontSize / 2 + ctx.measureText(legendItem.text).width;
14072
14301
 
14073
- if (i > 0 && currentColHeight + fontSize + 2 * padding > heightLimit) {
14302
+ if (i > 0 && currentColHeight + itemHeight + 2 * padding > heightLimit) {
14074
14303
  totalWidth += currentColWidth + padding;
14075
14304
  columnSizes.push({
14076
14305
  width: currentColWidth,
@@ -14078,20 +14307,18 @@
14078
14307
  });
14079
14308
  left += currentColWidth + padding;
14080
14309
  col++;
14081
- top = 0;
14082
14310
  currentColWidth = currentColHeight = 0;
14083
14311
  }
14084
14312
 
14085
- currentColWidth = Math.max(currentColWidth, itemWidth);
14086
- currentColHeight += fontSize + padding;
14087
14313
  hitboxes[i] = {
14088
14314
  left: left,
14089
- top: top,
14315
+ top: currentColHeight,
14090
14316
  col: col,
14091
14317
  width: itemWidth,
14092
14318
  height: itemHeight
14093
14319
  };
14094
- top += itemHeight + padding;
14320
+ currentColWidth = Math.max(currentColWidth, itemWidth);
14321
+ currentColHeight += itemHeight + padding;
14095
14322
  });
14096
14323
  totalWidth += currentColWidth;
14097
14324
  columnSizes.push({
@@ -14114,19 +14341,20 @@
14114
14341
  var hitboxes = me.legendHitBoxes,
14115
14342
  _me$options6 = me.options,
14116
14343
  align = _me$options6.align,
14117
- padding = _me$options6.labels.padding;
14344
+ padding = _me$options6.labels.padding,
14345
+ rtl = _me$options6.rtl;
14118
14346
 
14119
14347
  if (this.isHorizontal()) {
14120
14348
  var row = 0;
14121
14349
 
14122
14350
  var left = _alignStartEnd(align, me.left + padding, me.right - me.lineWidths[row]);
14123
14351
 
14124
- var _iterator13 = _createForOfIteratorHelper(hitboxes),
14125
- _step13;
14352
+ var _iterator14 = _createForOfIteratorHelper(hitboxes),
14353
+ _step14;
14126
14354
 
14127
14355
  try {
14128
- for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
14129
- var hitbox = _step13.value;
14356
+ for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
14357
+ var hitbox = _step14.value;
14130
14358
 
14131
14359
  if (row !== hitbox.row) {
14132
14360
  row = hitbox.row;
@@ -14138,21 +14366,35 @@
14138
14366
  left += hitbox.width + padding;
14139
14367
  }
14140
14368
  } catch (err) {
14141
- _iterator13.e(err);
14369
+ _iterator14.e(err);
14142
14370
  } finally {
14143
- _iterator13.f();
14371
+ _iterator14.f();
14372
+ }
14373
+
14374
+ if (rtl) {
14375
+ var boxMap = hitboxes.reduce(function (map, box) {
14376
+ map[box.row] = map[box.row] || [];
14377
+ map[box.row].push(box);
14378
+ return map;
14379
+ }, {});
14380
+ var newBoxes = [];
14381
+ Object.keys(boxMap).forEach(function (key) {
14382
+ boxMap[key].reverse();
14383
+ newBoxes.push.apply(newBoxes, _toConsumableArray(boxMap[key]));
14384
+ });
14385
+ me.legendHitBoxes = newBoxes;
14144
14386
  }
14145
14387
  } else {
14146
14388
  var col = 0;
14147
14389
 
14148
14390
  var top = _alignStartEnd(align, me.top + titleHeight + padding, me.bottom - me.columnSizes[col].height);
14149
14391
 
14150
- var _iterator14 = _createForOfIteratorHelper(hitboxes),
14151
- _step14;
14392
+ var _iterator15 = _createForOfIteratorHelper(hitboxes),
14393
+ _step15;
14152
14394
 
14153
14395
  try {
14154
- for (_iterator14.s(); !(_step14 = _iterator14.n()).done;) {
14155
- var _hitbox = _step14.value;
14396
+ for (_iterator15.s(); !(_step15 = _iterator15.n()).done;) {
14397
+ var _hitbox = _step15.value;
14156
14398
 
14157
14399
  if (_hitbox.col !== col) {
14158
14400
  col = _hitbox.col;
@@ -14164,9 +14406,9 @@
14164
14406
  top += _hitbox.height + padding;
14165
14407
  }
14166
14408
  } catch (err) {
14167
- _iterator14.e(err);
14409
+ _iterator15.e(err);
14168
14410
  } finally {
14169
- _iterator14.f();
14411
+ _iterator15.f();
14170
14412
  }
14171
14413
  }
14172
14414
  }
@@ -14276,7 +14518,7 @@
14276
14518
  var fillText = function fillText(x, y, legendItem) {
14277
14519
  renderText(ctx, legendItem.text, x, y + itemHeight / 2, labelFont, {
14278
14520
  strikethrough: legendItem.hidden,
14279
- textAlign: legendItem.textAlign
14521
+ textAlign: rtlHelper.textAlign(legendItem.textAlign)
14280
14522
  });
14281
14523
  };
14282
14524
 
@@ -14305,7 +14547,7 @@
14305
14547
  ctx.fillStyle = legendItem.fontColor || fontColor;
14306
14548
  var textWidth = ctx.measureText(legendItem.text).width;
14307
14549
  var textAlign = rtlHelper.textAlign(legendItem.textAlign || (legendItem.textAlign = labelOpts.textAlign));
14308
- var width = boxWidth + fontSize / 2 + textWidth;
14550
+ var width = boxWidth + halfFontSize + textWidth;
14309
14551
  var x = cursor.x;
14310
14552
  var y = cursor.y;
14311
14553
  rtlHelper.setWidth(me.width);
@@ -14324,7 +14566,7 @@
14324
14566
 
14325
14567
  var realX = rtlHelper.x(x);
14326
14568
  drawLegendBox(realX, y, legendItem);
14327
- x = _textX(textAlign, x + boxWidth + halfFontSize, me.right);
14569
+ x = _textX(textAlign, x + boxWidth + halfFontSize, isHorizontal ? x + width : me.right, opts.rtl);
14328
14570
  fillText(rtlHelper.x(x), y, legendItem);
14329
14571
 
14330
14572
  if (isHorizontal) {
@@ -14738,6 +14980,48 @@
14738
14980
  _indexable: false
14739
14981
  }
14740
14982
  };
14983
+ var map = new WeakMap();
14984
+ var plugin_subtitle = {
14985
+ id: 'subtitle',
14986
+ start: function start(chart, _args, options) {
14987
+ var title = new Title({
14988
+ ctx: chart.ctx,
14989
+ options: options,
14990
+ chart: chart
14991
+ });
14992
+ layouts.configure(chart, title, options);
14993
+ layouts.addBox(chart, title);
14994
+ map.set(chart, title);
14995
+ },
14996
+ stop: function stop(chart) {
14997
+ layouts.removeBox(chart, map.get(chart));
14998
+ map.delete(chart);
14999
+ },
15000
+ beforeUpdate: function beforeUpdate(chart, _args, options) {
15001
+ var title = map.get(chart);
15002
+ layouts.configure(chart, title, options);
15003
+ title.options = options;
15004
+ },
15005
+ defaults: {
15006
+ align: 'center',
15007
+ display: false,
15008
+ font: {
15009
+ weight: 'normal'
15010
+ },
15011
+ fullSize: true,
15012
+ padding: 0,
15013
+ position: 'top',
15014
+ text: '',
15015
+ weight: 1500
15016
+ },
15017
+ defaultRoutes: {
15018
+ color: 'color'
15019
+ },
15020
+ descriptors: {
15021
+ _scriptable: true,
15022
+ _indexable: false
15023
+ }
15024
+ };
14741
15025
  var positioners = {
14742
15026
  average: function average(items) {
14743
15027
  if (!items.length) {
@@ -15655,9 +15939,9 @@
15655
15939
  value: function setActiveElements(activeElements, eventPosition) {
15656
15940
  var me = this;
15657
15941
  var lastActive = me._active;
15658
- var active = activeElements.map(function (_ref7) {
15659
- var datasetIndex = _ref7.datasetIndex,
15660
- index = _ref7.index;
15942
+ var active = activeElements.map(function (_ref8) {
15943
+ var datasetIndex = _ref8.datasetIndex,
15944
+ index = _ref8.index;
15661
15945
 
15662
15946
  var meta = me._chart.getDatasetMeta(datasetIndex);
15663
15947
 
@@ -15928,6 +16212,7 @@
15928
16212
  Decimation: plugin_decimation,
15929
16213
  Filler: plugin_filler,
15930
16214
  Legend: plugin_legend,
16215
+ SubTitle: plugin_subtitle,
15931
16216
  Title: plugin_title,
15932
16217
  Tooltip: plugin_tooltip
15933
16218
  });
@@ -16097,14 +16382,15 @@
16097
16382
  function generateTicks$1(generationOptions, dataRange) {
16098
16383
  var ticks = [];
16099
16384
  var MIN_SPACING = 1e-14;
16100
- var step = generationOptions.step,
16385
+ var bounds = generationOptions.bounds,
16386
+ step = generationOptions.step,
16101
16387
  min = generationOptions.min,
16102
16388
  max = generationOptions.max,
16103
16389
  precision = generationOptions.precision,
16104
16390
  count = generationOptions.count,
16105
16391
  maxTicks = generationOptions.maxTicks,
16106
16392
  maxDigits = generationOptions.maxDigits,
16107
- horizontal = generationOptions.horizontal;
16393
+ includeBounds = generationOptions.includeBounds;
16108
16394
  var unit = step || 1;
16109
16395
  var maxSpaces = maxTicks - 1;
16110
16396
  var rmin = dataRange.min,
@@ -16112,7 +16398,7 @@
16112
16398
  var minDefined = !isNullOrUndef(min);
16113
16399
  var maxDefined = !isNullOrUndef(max);
16114
16400
  var countDefined = !isNullOrUndef(count);
16115
- var minSpacing = (rmax - rmin) / maxDigits;
16401
+ var minSpacing = (rmax - rmin) / (maxDigits + 1);
16116
16402
  var spacing = niceNum((rmax - rmin) / maxSpaces / unit) * unit;
16117
16403
  var factor, niceMin, niceMax, numSpaces;
16118
16404
 
@@ -16135,11 +16421,16 @@
16135
16421
  spacing = Math.ceil(spacing * factor) / factor;
16136
16422
  }
16137
16423
 
16138
- niceMin = Math.floor(rmin / spacing) * spacing;
16139
- niceMax = Math.ceil(rmax / spacing) * spacing;
16424
+ if (bounds === 'ticks') {
16425
+ niceMin = Math.floor(rmin / spacing) * spacing;
16426
+ niceMax = Math.ceil(rmax / spacing) * spacing;
16427
+ } else {
16428
+ niceMin = rmin;
16429
+ niceMax = rmax;
16430
+ }
16140
16431
 
16141
16432
  if (minDefined && maxDefined && step && almostWhole((max - min) / step, spacing / 1000)) {
16142
- numSpaces = Math.min((max - min) / spacing, maxTicks);
16433
+ numSpaces = Math.round(Math.min((max - min) / spacing, maxTicks));
16143
16434
  spacing = (max - min) / numSpaces;
16144
16435
  niceMin = min;
16145
16436
  niceMax = max;
@@ -16158,21 +16449,26 @@
16158
16449
  }
16159
16450
  }
16160
16451
 
16161
- factor = Math.pow(10, isNullOrUndef(precision) ? _decimalPlaces(spacing) : precision);
16452
+ var decimalPlaces = Math.max(_decimalPlaces(spacing), _decimalPlaces(niceMin));
16453
+ factor = Math.pow(10, isNullOrUndef(precision) ? decimalPlaces : precision);
16162
16454
  niceMin = Math.round(niceMin * factor) / factor;
16163
16455
  niceMax = Math.round(niceMax * factor) / factor;
16164
16456
  var j = 0;
16165
16457
 
16166
16458
  if (minDefined) {
16167
- ticks.push({
16168
- value: min
16169
- });
16459
+ if (includeBounds && niceMin !== min) {
16460
+ ticks.push({
16461
+ value: min
16462
+ });
16170
16463
 
16171
- if (niceMin <= min) {
16172
- j++;
16173
- }
16464
+ if (niceMin < min) {
16465
+ j++;
16466
+ }
16174
16467
 
16175
- if (almostEquals(Math.round((niceMin + j * spacing) * factor) / factor, min, minSpacing * (horizontal ? ('' + min).length : 1))) {
16468
+ if (almostEquals(Math.round((niceMin + j * spacing) * factor) / factor, min, relativeLabelSize(min, minSpacing, generationOptions))) {
16469
+ j++;
16470
+ }
16471
+ } else if (niceMin < min) {
16176
16472
  j++;
16177
16473
  }
16178
16474
  }
@@ -16183,15 +16479,15 @@
16183
16479
  });
16184
16480
  }
16185
16481
 
16186
- if (maxDefined) {
16187
- if (almostEquals(ticks[ticks.length - 1].value, max, minSpacing * (horizontal ? ('' + max).length : 1))) {
16482
+ if (maxDefined && includeBounds && niceMax !== max) {
16483
+ if (almostEquals(ticks[ticks.length - 1].value, max, relativeLabelSize(max, minSpacing, generationOptions))) {
16188
16484
  ticks[ticks.length - 1].value = max;
16189
16485
  } else {
16190
16486
  ticks.push({
16191
16487
  value: max
16192
16488
  });
16193
16489
  }
16194
- } else {
16490
+ } else if (!maxDefined || niceMax === max) {
16195
16491
  ticks.push({
16196
16492
  value: niceMax
16197
16493
  });
@@ -16200,6 +16496,15 @@
16200
16496
  return ticks;
16201
16497
  }
16202
16498
 
16499
+ function relativeLabelSize(value, minSpacing, _ref9) {
16500
+ var horizontal = _ref9.horizontal,
16501
+ minRotation = _ref9.minRotation;
16502
+ var rad = toRadians(minRotation);
16503
+ var ratio = (horizontal ? Math.sin(rad) : Math.cos(rad)) || 0.001;
16504
+ var length = 0.75 * minSpacing * ('' + value).length;
16505
+ return Math.min(minSpacing / ratio, length);
16506
+ }
16507
+
16203
16508
  var LinearScaleBase = /*#__PURE__*/function (_Scale2) {
16204
16509
  _inherits(LinearScaleBase, _Scale2);
16205
16510
 
@@ -16236,9 +16541,7 @@
16236
16541
  key: "handleTickRangeOptions",
16237
16542
  value: function handleTickRangeOptions() {
16238
16543
  var me = this;
16239
- var _me$options7 = me.options,
16240
- beginAtZero = _me$options7.beginAtZero,
16241
- stacked = _me$options7.stacked;
16544
+ var beginAtZero = me.options.beginAtZero;
16242
16545
 
16243
16546
  var _me$getUserBounds3 = me.getUserBounds(),
16244
16547
  minDefined = _me$getUserBounds3.minDefined,
@@ -16255,7 +16558,7 @@
16255
16558
  return max = maxDefined ? max : v;
16256
16559
  };
16257
16560
 
16258
- if (beginAtZero || stacked) {
16561
+ if (beginAtZero) {
16259
16562
  var minSign = sign(min);
16260
16563
  var maxSign = sign(max);
16261
16564
 
@@ -16314,13 +16617,16 @@
16314
16617
  maxTicks = Math.max(2, maxTicks);
16315
16618
  var numericGeneratorOptions = {
16316
16619
  maxTicks: maxTicks,
16620
+ bounds: opts.bounds,
16317
16621
  min: opts.min,
16318
16622
  max: opts.max,
16319
16623
  precision: tickOpts.precision,
16320
16624
  step: tickOpts.stepSize,
16321
16625
  count: tickOpts.count,
16322
16626
  maxDigits: me._maxDigits(),
16323
- horizontal: me.isHorizontal()
16627
+ horizontal: me.isHorizontal(),
16628
+ minRotation: tickOpts.minRotation || 0,
16629
+ includeBounds: tickOpts.includeBounds !== false
16324
16630
  };
16325
16631
  var dataRange = me._range || me;
16326
16632
  var ticks = generateTicks$1(numericGeneratorOptions, dataRange);
@@ -16398,14 +16704,14 @@
16398
16704
  key: "computeTickLimit",
16399
16705
  value: function computeTickLimit() {
16400
16706
  var me = this;
16401
-
16402
- if (me.isHorizontal()) {
16403
- return Math.ceil(me.width / 40);
16404
- }
16707
+ var horizontal = me.isHorizontal();
16708
+ var length = horizontal ? me.width : me.height;
16709
+ var minRotation = toRadians(me.options.ticks.minRotation);
16710
+ var ratio = (horizontal ? Math.sin(minRotation) : Math.cos(minRotation)) || 0.001;
16405
16711
 
16406
16712
  var tickFont = me._resolveTickFontOptions(0);
16407
16713
 
16408
- return Math.ceil(me.height / tickFont.lineHeight);
16714
+ return Math.ceil(length / Math.min(40, tickFont.lineHeight / ratio));
16409
16715
  }
16410
16716
  }, {
16411
16717
  key: "getPixelForValue",
@@ -16654,17 +16960,11 @@
16654
16960
  return 0;
16655
16961
  }
16656
16962
 
16657
- function measureLabelSize(ctx, lineHeight, label) {
16658
- if (isArray(label)) {
16659
- return {
16660
- w: _longestText(ctx, ctx.font, label),
16661
- h: label.length * lineHeight
16662
- };
16663
- }
16664
-
16963
+ function measureLabelSize(ctx, font, label) {
16964
+ label = isArray(label) ? label : [label];
16665
16965
  return {
16666
- w: ctx.measureText(label).width,
16667
- h: lineHeight
16966
+ w: _longestText(ctx, font.string, label),
16967
+ h: label.length * font.lineHeight
16668
16968
  };
16669
16969
  }
16670
16970
 
@@ -16695,19 +16995,16 @@
16695
16995
  b: scale.height - scale.paddingTop
16696
16996
  };
16697
16997
  var furthestAngles = {};
16698
- var i, textSize, pointPosition;
16699
16998
  var labelSizes = [];
16700
16999
  var padding = [];
16701
17000
  var valueCount = scale.getLabels().length;
16702
17001
 
16703
- for (i = 0; i < valueCount; i++) {
16704
- var _opts = scale.options.pointLabels.setContext(scale.getContext(i));
16705
-
16706
- padding[i] = _opts.padding;
16707
- pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i]);
16708
- var plFont = toFont(_opts.font);
16709
- scale.ctx.font = plFont.string;
16710
- textSize = measureLabelSize(scale.ctx, plFont.lineHeight, scale._pointLabels[i]);
17002
+ for (var i = 0; i < valueCount; i++) {
17003
+ var opts = scale.options.pointLabels.setContext(scale.getContext(i));
17004
+ padding[i] = opts.padding;
17005
+ var pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i]);
17006
+ var plFont = toFont(opts.font);
17007
+ var textSize = measureLabelSize(scale.ctx, plFont, scale._pointLabels[i]);
16711
17008
  labelSizes[i] = textSize;
16712
17009
  var angleRadians = scale.getIndexAngle(i);
16713
17010
  var angle = toDegrees(angleRadians);
@@ -16737,41 +17034,36 @@
16737
17034
 
16738
17035
  scale._setReductions(scale.drawingArea, furthestLimits, furthestAngles);
16739
17036
 
16740
- scale._pointLabelItems = [];
17037
+ scale._pointLabelItems = buildPointLabelItems(scale, labelSizes, padding);
17038
+ }
17039
+
17040
+ function buildPointLabelItems(scale, labelSizes, padding) {
17041
+ var items = [];
17042
+ var valueCount = scale.getLabels().length;
16741
17043
  var opts = scale.options;
16742
17044
  var tickBackdropHeight = getTickBackdropHeight(opts);
16743
17045
  var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);
16744
17046
 
16745
- for (i = 0; i < valueCount; i++) {
17047
+ for (var i = 0; i < valueCount; i++) {
16746
17048
  var extra = i === 0 ? tickBackdropHeight / 2 : 0;
16747
17049
  var pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + padding[i]);
16748
-
16749
- var _angle = toDegrees(scale.getIndexAngle(i));
16750
-
17050
+ var angle = toDegrees(scale.getIndexAngle(i));
16751
17051
  var size = labelSizes[i];
16752
- adjustPointPositionForLabelHeight(_angle, size, pointLabelPosition);
16753
- var textAlign = getTextAlignForAngle(_angle);
16754
- var left = void 0;
16755
-
16756
- if (textAlign === 'left') {
16757
- left = pointLabelPosition.x;
16758
- } else if (textAlign === 'center') {
16759
- left = pointLabelPosition.x - size.w / 2;
16760
- } else {
16761
- left = pointLabelPosition.x - size.w;
16762
- }
16763
-
16764
- var right = left + size.w;
16765
- scale._pointLabelItems[i] = {
17052
+ var y = yForAngle(pointLabelPosition.y, size.h, angle);
17053
+ var textAlign = getTextAlignForAngle(angle);
17054
+ var left = leftForTextAlign(pointLabelPosition.x, size.w, textAlign);
17055
+ items.push({
16766
17056
  x: pointLabelPosition.x,
16767
- y: pointLabelPosition.y,
17057
+ y: y,
16768
17058
  textAlign: textAlign,
16769
17059
  left: left,
16770
- top: pointLabelPosition.y,
16771
- right: right,
16772
- bottom: pointLabelPosition.y + size.h
16773
- };
17060
+ top: y,
17061
+ right: left + size.w,
17062
+ bottom: y + size.h
17063
+ });
16774
17064
  }
17065
+
17066
+ return items;
16775
17067
  }
16776
17068
 
16777
17069
  function getTextAlignForAngle(angle) {
@@ -16784,12 +17076,24 @@
16784
17076
  return 'right';
16785
17077
  }
16786
17078
 
16787
- function adjustPointPositionForLabelHeight(angle, textSize, position) {
17079
+ function leftForTextAlign(x, w, align) {
17080
+ if (align === 'right') {
17081
+ x -= w;
17082
+ } else if (align === 'center') {
17083
+ x -= w / 2;
17084
+ }
17085
+
17086
+ return x;
17087
+ }
17088
+
17089
+ function yForAngle(y, h, angle) {
16788
17090
  if (angle === 90 || angle === 270) {
16789
- position.y -= textSize.h / 2;
17091
+ y -= h / 2;
16790
17092
  } else if (angle > 270 || angle < 90) {
16791
- position.y -= textSize.h;
17093
+ y -= h;
16792
17094
  }
17095
+
17096
+ return y;
16793
17097
  }
16794
17098
 
16795
17099
  function drawPointLabels(scale, labelCount) {
@@ -17036,9 +17340,9 @@
17036
17340
  key: "drawBackground",
17037
17341
  value: function drawBackground() {
17038
17342
  var me = this;
17039
- var _me$options8 = me.options,
17040
- backgroundColor = _me$options8.backgroundColor,
17041
- circular = _me$options8.grid.circular;
17343
+ var _me$options7 = me.options,
17344
+ backgroundColor = _me$options7.backgroundColor,
17345
+ circular = _me$options7.grid.circular;
17042
17346
 
17043
17347
  if (backgroundColor) {
17044
17348
  var ctx = me.ctx;
@@ -17135,6 +17439,7 @@
17135
17439
  offset = me.getDistanceFromCenterForValue(me.ticks[index].value);
17136
17440
 
17137
17441
  if (optsAtIndex.showLabelBackdrop) {
17442
+ ctx.font = tickFont.string;
17138
17443
  width = ctx.measureText(tick.label).width;
17139
17444
  ctx.fillStyle = optsAtIndex.backdropColor;
17140
17445
  var padding = toPadding(optsAtIndex.backdropPadding);
@@ -17752,20 +18057,38 @@
17752
18057
  };
17753
18058
 
17754
18059
  function interpolate(table, val, reverse) {
18060
+ var lo = 0;
18061
+ var hi = table.length - 1;
17755
18062
  var prevSource, nextSource, prevTarget, nextTarget;
17756
18063
 
17757
18064
  if (reverse) {
17758
- prevSource = Math.floor(val);
17759
- nextSource = Math.ceil(val);
17760
- prevTarget = table[prevSource];
17761
- nextTarget = table[nextSource];
18065
+ if (val >= table[lo].pos && val <= table[hi].pos) {
18066
+ var _lookupByKey2 = _lookupByKey(table, 'pos', val);
18067
+
18068
+ lo = _lookupByKey2.lo;
18069
+ hi = _lookupByKey2.hi;
18070
+ }
18071
+
18072
+ var _table$lo = table[lo];
18073
+ prevSource = _table$lo.pos;
18074
+ prevTarget = _table$lo.time;
18075
+ var _table$hi = table[hi];
18076
+ nextSource = _table$hi.pos;
18077
+ nextTarget = _table$hi.time;
17762
18078
  } else {
17763
- var result = _lookup(table, val);
18079
+ if (val >= table[lo].time && val <= table[hi].time) {
18080
+ var _lookupByKey3 = _lookupByKey(table, 'time', val);
18081
+
18082
+ lo = _lookupByKey3.lo;
18083
+ hi = _lookupByKey3.hi;
18084
+ }
17764
18085
 
17765
- prevTarget = result.lo;
17766
- nextTarget = result.hi;
17767
- prevSource = table[prevTarget];
17768
- nextSource = table[nextTarget];
18086
+ var _table$lo2 = table[lo];
18087
+ prevSource = _table$lo2.time;
18088
+ prevTarget = _table$lo2.pos;
18089
+ var _table$hi2 = table[hi];
18090
+ nextSource = _table$hi2.time;
18091
+ nextTarget = _table$hi2.pos;
17769
18092
  }
17770
18093
 
17771
18094
  var span = nextSource - prevSource;
@@ -17784,7 +18107,8 @@
17784
18107
 
17785
18108
  _this19 = _super25.call(this, props);
17786
18109
  _this19._table = [];
17787
- _this19._maxIndex = undefined;
18110
+ _this19._minPos = undefined;
18111
+ _this19._tableRange = undefined;
17788
18112
  return _this19;
17789
18113
  }
17790
18114
 
@@ -17795,19 +18119,30 @@
17795
18119
 
17796
18120
  var timestamps = me._getTimestampsForTable();
17797
18121
 
17798
- me._table = me.buildLookupTable(timestamps);
17799
- me._maxIndex = me._table.length - 1;
18122
+ var table = me._table = me.buildLookupTable(timestamps);
18123
+ me._minPos = interpolate(table, me.min);
18124
+ me._tableRange = interpolate(table, me.max) - me._minPos;
17800
18125
 
17801
18126
  _get(_getPrototypeOf(TimeSeriesScale.prototype), "initOffsets", this).call(this, timestamps);
17802
18127
  }
17803
18128
  }, {
17804
18129
  key: "buildLookupTable",
17805
18130
  value: function buildLookupTable(timestamps) {
17806
- var me = this;
17807
- var min = me.min,
17808
- max = me.max;
18131
+ var min = this.min,
18132
+ max = this.max;
18133
+ var items = [];
18134
+ var table = [];
18135
+ var i, ilen, prev, curr, next;
18136
+
18137
+ for (i = 0, ilen = timestamps.length; i < ilen; ++i) {
18138
+ curr = timestamps[i];
17809
18139
 
17810
- if (!timestamps.length) {
18140
+ if (curr >= min && curr <= max) {
18141
+ items.push(curr);
18142
+ }
18143
+ }
18144
+
18145
+ if (items.length < 2) {
17811
18146
  return [{
17812
18147
  time: min,
17813
18148
  pos: 0
@@ -17817,19 +18152,20 @@
17817
18152
  }];
17818
18153
  }
17819
18154
 
17820
- var items = [min];
17821
- var i, ilen, curr;
17822
-
17823
- for (i = 0, ilen = timestamps.length; i < ilen; ++i) {
17824
- curr = timestamps[i];
17825
-
17826
- if (curr > min && curr < max) {
17827
- items.push(curr);
18155
+ for (i = 0, ilen = items.length; i < ilen; ++i) {
18156
+ next = items[i + 1];
18157
+ prev = items[i - 1];
18158
+ curr = items[i];
18159
+
18160
+ if (Math.round((next + prev) / 2) !== curr) {
18161
+ table.push({
18162
+ time: curr,
18163
+ pos: i / (ilen - 1)
18164
+ });
17828
18165
  }
17829
18166
  }
17830
18167
 
17831
- items.push(max);
17832
- return items;
18168
+ return table;
17833
18169
  }
17834
18170
  }, {
17835
18171
  key: "_getTimestampsForTable",
@@ -17853,18 +18189,10 @@
17853
18189
  timestamps = me._cache.all = timestamps;
17854
18190
  return timestamps;
17855
18191
  }
17856
- }, {
17857
- key: "getPixelForValue",
17858
- value: function getPixelForValue(value, index) {
17859
- var me = this;
17860
- var offsets = me._offsets;
17861
- var pos = me._normalized && me._maxIndex > 0 && !isNullOrUndef(index) ? index / me._maxIndex : me.getDecimalForValue(value);
17862
- return me.getPixelForDecimal((offsets.start + pos) * offsets.factor);
17863
- }
17864
18192
  }, {
17865
18193
  key: "getDecimalForValue",
17866
18194
  value: function getDecimalForValue(value) {
17867
- return interpolate(this._table, value) / this._maxIndex;
18195
+ return (interpolate(this._table, value) - this._minPos) / this._tableRange;
17868
18196
  }
17869
18197
  }, {
17870
18198
  key: "getValueForPixel",
@@ -17872,7 +18200,7 @@
17872
18200
  var me = this;
17873
18201
  var offsets = me._offsets;
17874
18202
  var decimal = me.getDecimalForPixel(pixel) / offsets.factor - offsets.end;
17875
- return interpolate(me._table, decimal * this._maxIndex, true);
18203
+ return interpolate(me._table, decimal * me._tableRange + me._minPos, true);
17876
18204
  }
17877
18205
  }]);
17878
18206