chartkick 4.0.4 → 4.0.5

Sign up to get free protection for your applications and to get access to all the features.
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