chartkick 4.1.2 → 4.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Chart.js v3.6.0
2
+ * Chart.js v3.7.0
3
3
  * https://www.chartjs.org
4
4
  * (c) 2021 Chart.js Contributors
5
5
  * Released under the MIT License
@@ -9,9 +9,9 @@
9
9
  * (c) 2021 chartjs-adapter-date-fns Contributors
10
10
  * Released under the MIT license
11
11
  *
12
- * date-fns v2.25.0
12
+ * date-fns v2.27.0
13
13
  * https://date-fns.org
14
- * (c) 2020 Sasha Koss and Lesha Koss
14
+ * (c) 2021 Sasha Koss and Lesha Koss
15
15
  * Released under the MIT License
16
16
  */
17
17
 
@@ -663,6 +663,10 @@
663
663
  return true;
664
664
  };
665
665
 
666
+ function _isClickEvent(e) {
667
+ return e.type === 'mouseup' || e.type === 'click' || e.type === 'contextmenu';
668
+ }
669
+
666
670
  var PI = Math.PI;
667
671
  var TAU = 2 * PI;
668
672
  var PITAU = TAU + PI;
@@ -809,6 +813,11 @@
809
813
  return _limitValue(value, -32768, 32767);
810
814
  }
811
815
 
816
+ function _isBetween(value, start, end) {
817
+ var epsilon = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1e-6;
818
+ return value >= Math.min(start, end) - epsilon && value <= Math.max(start, end) + epsilon;
819
+ }
820
+
812
821
  var atEdge = function atEdge(t) {
813
822
  return t === 0 || t === 1;
814
823
  };
@@ -1737,6 +1746,7 @@
1737
1746
  this.scale = undefined;
1738
1747
  this.scales = {};
1739
1748
  this.showLine = true;
1749
+ this.drawActiveElementsOnTop = true;
1740
1750
  this.describe(_descriptors);
1741
1751
  }
1742
1752
 
@@ -2166,7 +2176,7 @@
2166
2176
  return size * value;
2167
2177
  }
2168
2178
 
2169
- var numberOrZero$1 = function numberOrZero(v) {
2179
+ var numberOrZero = function numberOrZero(v) {
2170
2180
  return +v || 0;
2171
2181
  };
2172
2182
 
@@ -2188,7 +2198,7 @@
2188
2198
  try {
2189
2199
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
2190
2200
  var prop = _step2.value;
2191
- ret[prop] = numberOrZero$1(read(prop));
2201
+ ret[prop] = numberOrZero(read(prop));
2192
2202
  }
2193
2203
  } catch (err) {
2194
2204
  _iterator2.e(err);
@@ -2473,8 +2483,7 @@
2473
2483
  },
2474
2484
  set: function set(target, prop, value) {
2475
2485
  var storage = target._storage || (target._storage = getTarget());
2476
- storage[prop] = value;
2477
- delete target[prop];
2486
+ target[prop] = storage[prop] = value;
2478
2487
  delete target._keys;
2479
2488
  return true;
2480
2489
  }
@@ -2561,7 +2570,7 @@
2561
2570
  };
2562
2571
 
2563
2572
  var needsSubResolver = function needsSubResolver(prop, value) {
2564
- return isObject(value) && prop !== 'adapters';
2573
+ return isObject(value) && prop !== 'adapters' && (Object.getPrototypeOf(value) === null || value.constructor === Object);
2565
2574
  };
2566
2575
 
2567
2576
  function _cached(target, prop, resolve) {
@@ -2612,7 +2621,7 @@
2612
2621
 
2613
2622
  _stack.delete(prop);
2614
2623
 
2615
- if (isObject(value)) {
2624
+ if (needsSubResolver(prop, value)) {
2616
2625
  value = createSubResolver(_proxy._scopes, _proxy, prop, value);
2617
2626
  }
2618
2627
 
@@ -2663,7 +2672,7 @@
2663
2672
  return key === true ? parent : typeof key === 'string' ? resolveObjectKey(parent, key) : undefined;
2664
2673
  };
2665
2674
 
2666
- function addScopes(set, parentScopes, key, parentFallback) {
2675
+ function addScopes(set, parentScopes, key, parentFallback, value) {
2667
2676
  var _iterator4 = _createForOfIteratorHelper(parentScopes),
2668
2677
  _step4;
2669
2678
 
@@ -2674,7 +2683,7 @@
2674
2683
 
2675
2684
  if (scope) {
2676
2685
  set.add(scope);
2677
- var fallback = resolveFallback(scope._fallback, key, scope);
2686
+ var fallback = resolveFallback(scope._fallback, key, value);
2678
2687
 
2679
2688
  if (defined(fallback) && fallback !== key && fallback !== parentFallback) {
2680
2689
  return fallback;
@@ -2698,14 +2707,14 @@
2698
2707
  var allScopes = [].concat(_toConsumableArray(parentScopes), _toConsumableArray(rootScopes));
2699
2708
  var set = new Set();
2700
2709
  set.add(value);
2701
- var key = addScopesFromKey(set, allScopes, prop, fallback || prop);
2710
+ var key = addScopesFromKey(set, allScopes, prop, fallback || prop, value);
2702
2711
 
2703
2712
  if (key === null) {
2704
2713
  return false;
2705
2714
  }
2706
2715
 
2707
2716
  if (defined(fallback) && fallback !== prop) {
2708
- key = addScopesFromKey(set, allScopes, fallback, key);
2717
+ key = addScopesFromKey(set, allScopes, fallback, key, value);
2709
2718
 
2710
2719
  if (key === null) {
2711
2720
  return false;
@@ -2717,9 +2726,9 @@
2717
2726
  });
2718
2727
  }
2719
2728
 
2720
- function addScopesFromKey(set, allScopes, key, fallback) {
2729
+ function addScopesFromKey(set, allScopes, key, fallback, item) {
2721
2730
  while (key) {
2722
- key = addScopes(set, allScopes, key, fallback);
2731
+ key = addScopes(set, allScopes, key, fallback, item);
2723
2732
  }
2724
2733
 
2725
2734
  return key;
@@ -3379,9 +3388,7 @@
3379
3388
  }
3380
3389
 
3381
3390
  return {
3382
- between: function between(n, s, e) {
3383
- return n >= Math.min(s, e) && n <= Math.max(e, s);
3384
- },
3391
+ between: _isBetween,
3385
3392
  compare: function compare(a, b) {
3386
3393
  return a - b;
3387
3394
  },
@@ -4763,6 +4770,7 @@
4763
4770
  var scopes = config.getOptionScopes(this.getDataset(), scopeKeys, true);
4764
4771
  this.options = config.createResolver(scopes, this.getContext());
4765
4772
  this._parsing = this.options.parsing;
4773
+ this._cachedDataOpts = {};
4766
4774
  }
4767
4775
  }, {
4768
4776
  key: "parse",
@@ -5006,8 +5014,6 @@
5006
5014
  key: "_update",
5007
5015
  value: function _update(mode) {
5008
5016
  var meta = this._cachedMeta;
5009
- this.configure();
5010
- this._cachedDataOpts = {};
5011
5017
  this.update(mode || 'default');
5012
5018
  meta._clip = toClip(valueOrDefault(this.options.clip, defaultClip(meta.xScale, meta.yScale, this.getMaxOverflow())));
5013
5019
  }
@@ -5025,6 +5031,7 @@
5025
5031
  var active = [];
5026
5032
  var start = this._drawStart || 0;
5027
5033
  var count = this._drawCount || elements.length - start;
5034
+ var drawActiveElementsOnTop = this.options.drawActiveElementsOnTop;
5028
5035
  var i;
5029
5036
 
5030
5037
  if (meta.dataset) {
@@ -5038,7 +5045,7 @@
5038
5045
  continue;
5039
5046
  }
5040
5047
 
5041
- if (element.active) {
5048
+ if (element.active && drawActiveElementsOnTop) {
5042
5049
  active.push(element);
5043
5050
  } else {
5044
5051
  element.draw(ctx, area);
@@ -5323,6 +5330,8 @@
5323
5330
 
5324
5331
  this[method](arg1, arg2);
5325
5332
  }
5333
+
5334
+ this.chart._dataChanges.push([this.index].concat(_toConsumableArray(args)));
5326
5335
  }
5327
5336
  }, {
5328
5337
  key: "_onDataPush",
@@ -5344,9 +5353,15 @@
5344
5353
  }, {
5345
5354
  key: "_onDataSplice",
5346
5355
  value: function _onDataSplice(start, count) {
5347
- this._sync(['_removeElements', start, count]);
5356
+ if (count) {
5357
+ this._sync(['_removeElements', start, count]);
5358
+ }
5359
+
5360
+ var newCount = arguments.length - 2;
5348
5361
 
5349
- this._sync(['_insertElements', start, arguments.length - 2]);
5362
+ if (newCount) {
5363
+ this._sync(['_insertElements', start, newCount]);
5364
+ }
5350
5365
  }
5351
5366
  }, {
5352
5367
  key: "_onDataUnshift",
@@ -6429,11 +6444,6 @@
6429
6444
  meta = chart.getDatasetMeta(i);
6430
6445
  arcs = meta.data;
6431
6446
  controller = meta.controller;
6432
-
6433
- if (controller !== this) {
6434
- controller.configure();
6435
- }
6436
-
6437
6447
  break;
6438
6448
  }
6439
6449
  }
@@ -7258,7 +7268,7 @@
7258
7268
  _sorted = metaset._sorted;
7259
7269
  var iScale = controller._cachedMeta.iScale;
7260
7270
 
7261
- if (iScale && axis === iScale.axis && _sorted && data.length) {
7271
+ if (iScale && axis === iScale.axis && axis !== 'r' && _sorted && data.length) {
7262
7272
  var lookupMethod = iScale._reversePixels ? _rlookupByKey : _lookupByKey;
7263
7273
 
7264
7274
  if (!intersect) {
@@ -7338,23 +7348,50 @@
7338
7348
  return items;
7339
7349
  }
7340
7350
 
7341
- function getNearestItems(chart, position, axis, intersect, useFinalPosition) {
7342
- var distanceMetric = getDistanceMetricForAxis(axis);
7343
- var minDistance = Number.POSITIVE_INFINITY;
7351
+ function getNearestRadialItems(chart, position, axis, useFinalPosition) {
7344
7352
  var items = [];
7345
7353
 
7346
- if (!_isPointInArea(position, chart.chartArea, chart._minPadding)) {
7347
- return items;
7354
+ function evaluationFunc(element, datasetIndex, index) {
7355
+ var _element$getProps = element.getProps(['startAngle', 'endAngle'], useFinalPosition),
7356
+ startAngle = _element$getProps.startAngle,
7357
+ endAngle = _element$getProps.endAngle;
7358
+
7359
+ var _getAngleFromPoint = getAngleFromPoint(element, {
7360
+ x: position.x,
7361
+ y: position.y
7362
+ }),
7363
+ angle = _getAngleFromPoint.angle;
7364
+
7365
+ if (_angleBetween(angle, startAngle, endAngle)) {
7366
+ items.push({
7367
+ element: element,
7368
+ datasetIndex: datasetIndex,
7369
+ index: index
7370
+ });
7371
+ }
7348
7372
  }
7349
7373
 
7350
- var evaluationFunc = function evaluationFunc(element, datasetIndex, index) {
7351
- if (intersect && !element.inRange(position.x, position.y, useFinalPosition)) {
7374
+ optimizedEvaluateItems(chart, axis, position, evaluationFunc);
7375
+ return items;
7376
+ }
7377
+
7378
+ function getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition) {
7379
+ var items = [];
7380
+ var distanceMetric = getDistanceMetricForAxis(axis);
7381
+ var minDistance = Number.POSITIVE_INFINITY;
7382
+
7383
+ function evaluationFunc(element, datasetIndex, index) {
7384
+ var inRange = element.inRange(position.x, position.y, useFinalPosition);
7385
+
7386
+ if (intersect && !inRange) {
7352
7387
  return;
7353
7388
  }
7354
7389
 
7355
7390
  var center = element.getCenterPoint(useFinalPosition);
7356
7391
 
7357
- if (!_isPointInArea(center, chart.chartArea, chart._minPadding) && !element.inRange(position.x, position.y, useFinalPosition)) {
7392
+ var pointInArea = _isPointInArea(center, chart.chartArea, chart._minPadding);
7393
+
7394
+ if (!pointInArea && !inRange) {
7358
7395
  return;
7359
7396
  }
7360
7397
 
@@ -7374,12 +7411,20 @@
7374
7411
  index: index
7375
7412
  });
7376
7413
  }
7377
- };
7414
+ }
7378
7415
 
7379
7416
  optimizedEvaluateItems(chart, axis, position, evaluationFunc);
7380
7417
  return items;
7381
7418
  }
7382
7419
 
7420
+ function getNearestItems(chart, position, axis, intersect, useFinalPosition) {
7421
+ if (!_isPointInArea(position, chart.chartArea, chart._minPadding)) {
7422
+ return [];
7423
+ }
7424
+
7425
+ return axis === 'r' && !intersect ? getNearestRadialItems(chart, position, axis, useFinalPosition) : getNearestCartesianItems(chart, position, axis, intersect, useFinalPosition);
7426
+ }
7427
+
7383
7428
  function getAxisItems(chart, e, options, useFinalPosition) {
7384
7429
  var position = getRelativePosition(e, chart);
7385
7430
  var items = [];
@@ -7465,12 +7510,16 @@
7465
7510
  return getNearestItems(chart, position, axis, options.intersect, useFinalPosition);
7466
7511
  },
7467
7512
  x: function x(chart, e, options, useFinalPosition) {
7468
- options.axis = 'x';
7469
- return getAxisItems(chart, e, options, useFinalPosition);
7513
+ return getAxisItems(chart, e, {
7514
+ axis: 'x',
7515
+ intersect: options.intersect
7516
+ }, useFinalPosition);
7470
7517
  },
7471
7518
  y: function y(chart, e, options, useFinalPosition) {
7472
- options.axis = 'y';
7473
- return getAxisItems(chart, e, options, useFinalPosition);
7519
+ return getAxisItems(chart, e, {
7520
+ axis: 'y',
7521
+ intersect: options.intersect
7522
+ }, useFinalPosition);
7474
7523
  }
7475
7524
  }
7476
7525
  };
@@ -7888,7 +7937,12 @@
7888
7937
  each(boxes.chartArea, function (layout) {
7889
7938
  var box = layout.box;
7890
7939
  Object.assign(box, chart.chartArea);
7891
- box.update(chartArea.w, chartArea.h);
7940
+ box.update(chartArea.w, chartArea.h, {
7941
+ left: 0,
7942
+ top: 0,
7943
+ right: 0,
7944
+ bottom: 0
7945
+ });
7892
7946
  });
7893
7947
  }
7894
7948
  };
@@ -8052,37 +8106,47 @@
8052
8106
  };
8053
8107
  }
8054
8108
 
8109
+ function nodeListContains(nodeList, canvas) {
8110
+ var _iterator7 = _createForOfIteratorHelper(nodeList),
8111
+ _step7;
8112
+
8113
+ try {
8114
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
8115
+ var node = _step7.value;
8116
+
8117
+ if (node === canvas || node.contains(canvas)) {
8118
+ return true;
8119
+ }
8120
+ }
8121
+ } catch (err) {
8122
+ _iterator7.e(err);
8123
+ } finally {
8124
+ _iterator7.f();
8125
+ }
8126
+ }
8127
+
8055
8128
  function createAttachObserver(chart, type, listener) {
8056
8129
  var canvas = chart.canvas;
8057
8130
  var observer = new MutationObserver(function (entries) {
8058
- var _iterator7 = _createForOfIteratorHelper(entries),
8059
- _step7;
8060
-
8061
- try {
8062
- for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
8063
- var entry = _step7.value;
8131
+ var trigger = false;
8064
8132
 
8065
- var _iterator8 = _createForOfIteratorHelper(entry.addedNodes),
8066
- _step8;
8133
+ var _iterator8 = _createForOfIteratorHelper(entries),
8134
+ _step8;
8067
8135
 
8068
- try {
8069
- for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
8070
- var node = _step8.value;
8071
-
8072
- if (node === canvas || node.contains(canvas)) {
8073
- return listener();
8074
- }
8075
- }
8076
- } catch (err) {
8077
- _iterator8.e(err);
8078
- } finally {
8079
- _iterator8.f();
8080
- }
8136
+ try {
8137
+ for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
8138
+ var entry = _step8.value;
8139
+ trigger = trigger || nodeListContains(entry.addedNodes, canvas);
8140
+ trigger = trigger && !nodeListContains(entry.removedNodes, canvas);
8081
8141
  }
8082
8142
  } catch (err) {
8083
- _iterator7.e(err);
8143
+ _iterator8.e(err);
8084
8144
  } finally {
8085
- _iterator7.f();
8145
+ _iterator8.f();
8146
+ }
8147
+
8148
+ if (trigger) {
8149
+ listener();
8086
8150
  }
8087
8151
  });
8088
8152
  observer.observe(document, {
@@ -8095,35 +8159,26 @@
8095
8159
  function createDetachObserver(chart, type, listener) {
8096
8160
  var canvas = chart.canvas;
8097
8161
  var observer = new MutationObserver(function (entries) {
8162
+ var trigger = false;
8163
+
8098
8164
  var _iterator9 = _createForOfIteratorHelper(entries),
8099
8165
  _step9;
8100
8166
 
8101
8167
  try {
8102
8168
  for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
8103
8169
  var entry = _step9.value;
8104
-
8105
- var _iterator10 = _createForOfIteratorHelper(entry.removedNodes),
8106
- _step10;
8107
-
8108
- try {
8109
- for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
8110
- var node = _step10.value;
8111
-
8112
- if (node === canvas || node.contains(canvas)) {
8113
- return listener();
8114
- }
8115
- }
8116
- } catch (err) {
8117
- _iterator10.e(err);
8118
- } finally {
8119
- _iterator10.f();
8120
- }
8170
+ trigger = trigger || nodeListContains(entry.removedNodes, canvas);
8171
+ trigger = trigger && !nodeListContains(entry.addedNodes, canvas);
8121
8172
  }
8122
8173
  } catch (err) {
8123
8174
  _iterator9.e(err);
8124
8175
  } finally {
8125
8176
  _iterator9.f();
8126
8177
  }
8178
+
8179
+ if (trigger) {
8180
+ listener();
8181
+ }
8127
8182
  });
8128
8183
  observer.observe(document, {
8129
8184
  childList: true,
@@ -10560,7 +10615,7 @@
10560
10615
 
10561
10616
  var result = this._notify(descriptors, chart, hook, args);
10562
10617
 
10563
- if (hook === 'destroy') {
10618
+ if (hook === 'afterDestroy') {
10564
10619
  this._notify(descriptors, chart, 'stop');
10565
10620
 
10566
10621
  this._notify(this._init, chart, 'uninstall');
@@ -10573,12 +10628,12 @@
10573
10628
  value: function _notify(descriptors, chart, hook, args) {
10574
10629
  args = args || {};
10575
10630
 
10576
- var _iterator11 = _createForOfIteratorHelper(descriptors),
10577
- _step11;
10631
+ var _iterator10 = _createForOfIteratorHelper(descriptors),
10632
+ _step10;
10578
10633
 
10579
10634
  try {
10580
- for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
10581
- var descriptor = _step11.value;
10635
+ for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
10636
+ var descriptor = _step10.value;
10582
10637
  var plugin = descriptor.plugin;
10583
10638
  var method = plugin[hook];
10584
10639
  var params = [chart, args, descriptor.options];
@@ -10588,9 +10643,9 @@
10588
10643
  }
10589
10644
  }
10590
10645
  } catch (err) {
10591
- _iterator11.e(err);
10646
+ _iterator10.e(err);
10592
10647
  } finally {
10593
- _iterator11.f();
10648
+ _iterator10.f();
10594
10649
  }
10595
10650
 
10596
10651
  return true;
@@ -11023,18 +11078,18 @@
11023
11078
  options = _attachContext(resolver, context, subResolver);
11024
11079
  }
11025
11080
 
11026
- var _iterator12 = _createForOfIteratorHelper(names),
11027
- _step12;
11081
+ var _iterator11 = _createForOfIteratorHelper(names),
11082
+ _step11;
11028
11083
 
11029
11084
  try {
11030
- for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
11031
- var prop = _step12.value;
11085
+ for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
11086
+ var prop = _step11.value;
11032
11087
  result[prop] = options[prop];
11033
11088
  }
11034
11089
  } catch (err) {
11035
- _iterator12.e(err);
11090
+ _iterator11.e(err);
11036
11091
  } finally {
11037
- _iterator12.f();
11092
+ _iterator11.f();
11038
11093
  }
11039
11094
 
11040
11095
  return result;
@@ -11092,12 +11147,12 @@
11092
11147
  isScriptable = _descriptors2.isScriptable,
11093
11148
  isIndexable = _descriptors2.isIndexable;
11094
11149
 
11095
- var _iterator13 = _createForOfIteratorHelper(names),
11096
- _step13;
11150
+ var _iterator12 = _createForOfIteratorHelper(names),
11151
+ _step12;
11097
11152
 
11098
11153
  try {
11099
- for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
11100
- var prop = _step13.value;
11154
+ for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
11155
+ var prop = _step12.value;
11101
11156
  var scriptable = isScriptable(prop);
11102
11157
  var indexable = isIndexable(prop);
11103
11158
  var value = (indexable || scriptable) && proxy[prop];
@@ -11107,15 +11162,15 @@
11107
11162
  }
11108
11163
  }
11109
11164
  } catch (err) {
11110
- _iterator13.e(err);
11165
+ _iterator12.e(err);
11111
11166
  } finally {
11112
- _iterator13.f();
11167
+ _iterator12.f();
11113
11168
  }
11114
11169
 
11115
11170
  return false;
11116
11171
  }
11117
11172
 
11118
- var version = "3.6.0";
11173
+ var version = "3.7.0";
11119
11174
  var KNOWN_POSITIONS = ['top', 'bottom', 'left', 'right', 'chartArea'];
11120
11175
 
11121
11176
  function positionIsHorizontal(position, axis) {
@@ -11164,6 +11219,36 @@
11164
11219
  }).pop();
11165
11220
  };
11166
11221
 
11222
+ function moveNumericKeys(obj, start, move) {
11223
+ var keys = Object.keys(obj);
11224
+
11225
+ for (var _i2 = 0, _keys = keys; _i2 < _keys.length; _i2++) {
11226
+ var key = _keys[_i2];
11227
+ var intKey = +key;
11228
+
11229
+ if (intKey >= start) {
11230
+ var value = obj[key];
11231
+ delete obj[key];
11232
+
11233
+ if (move > 0 || intKey > start) {
11234
+ obj[intKey + move] = value;
11235
+ }
11236
+ }
11237
+ }
11238
+ }
11239
+
11240
+ function determineLastEvent(e, lastEvent, inChartArea, isClick) {
11241
+ if (!inChartArea || e.type === 'mouseout') {
11242
+ return null;
11243
+ }
11244
+
11245
+ if (isClick) {
11246
+ return lastEvent;
11247
+ }
11248
+
11249
+ return e;
11250
+ }
11251
+
11167
11252
  var Chart = /*#__PURE__*/function () {
11168
11253
  function Chart(item, userConfig) {
11169
11254
  var _this11 = this;
@@ -11213,6 +11298,7 @@
11213
11298
  this._doResize = debounce(function (mode) {
11214
11299
  return _this11.update(mode);
11215
11300
  }, options.resizeDelay || 0);
11301
+ this._dataChanges = [];
11216
11302
  instances[this.id] = this;
11217
11303
 
11218
11304
  if (!context || !canvas) {
@@ -11515,24 +11601,16 @@
11515
11601
  }, {
11516
11602
  key: "update",
11517
11603
  value: function update(mode) {
11518
- var _this15 = this;
11519
-
11520
11604
  var config = this.config;
11521
11605
  config.update();
11522
11606
  var options = this._options = config.createResolver(config.chartOptionScopes(), this.getContext());
11523
- each(this.scales, function (scale) {
11524
- layouts.removeBox(_this15, scale);
11525
- });
11526
11607
  var animsDisabled = this._animationsDisabled = !options.animation;
11527
- this.ensureScalesHaveIDs();
11528
- this.buildOrUpdateScales();
11529
- var existingEvents = new Set(Object.keys(this._listeners));
11530
- var newEvents = new Set(options.events);
11531
11608
 
11532
- if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== options.responsive) {
11533
- this.unbindEvents();
11534
- this.bindEvents();
11535
- }
11609
+ this._updateScales();
11610
+
11611
+ this._checkEventBindings();
11612
+
11613
+ this._updateHiddenIndices();
11536
11614
 
11537
11615
  this._plugins.invalidate();
11538
11616
 
@@ -11574,12 +11652,102 @@
11574
11652
 
11575
11653
  this._layers.sort(compare2Level('z', '_idx'));
11576
11654
 
11577
- if (this._lastEvent) {
11578
- this._eventHandler(this._lastEvent, true);
11655
+ var _active = this._active,
11656
+ _lastEvent = this._lastEvent;
11657
+
11658
+ if (_lastEvent) {
11659
+ this._eventHandler(_lastEvent, true);
11660
+ } else if (_active.length) {
11661
+ this._updateHoverStyles(_active, _active, true);
11579
11662
  }
11580
11663
 
11581
11664
  this.render();
11582
11665
  }
11666
+ }, {
11667
+ key: "_updateScales",
11668
+ value: function _updateScales() {
11669
+ var _this15 = this;
11670
+
11671
+ each(this.scales, function (scale) {
11672
+ layouts.removeBox(_this15, scale);
11673
+ });
11674
+ this.ensureScalesHaveIDs();
11675
+ this.buildOrUpdateScales();
11676
+ }
11677
+ }, {
11678
+ key: "_checkEventBindings",
11679
+ value: function _checkEventBindings() {
11680
+ var options = this.options;
11681
+ var existingEvents = new Set(Object.keys(this._listeners));
11682
+ var newEvents = new Set(options.events);
11683
+
11684
+ if (!setsEqual(existingEvents, newEvents) || !!this._responsiveListeners !== options.responsive) {
11685
+ this.unbindEvents();
11686
+ this.bindEvents();
11687
+ }
11688
+ }
11689
+ }, {
11690
+ key: "_updateHiddenIndices",
11691
+ value: function _updateHiddenIndices() {
11692
+ var _hiddenIndices = this._hiddenIndices;
11693
+ var changes = this._getUniformDataChanges() || [];
11694
+
11695
+ var _iterator13 = _createForOfIteratorHelper(changes),
11696
+ _step13;
11697
+
11698
+ try {
11699
+ for (_iterator13.s(); !(_step13 = _iterator13.n()).done;) {
11700
+ var _step13$value = _step13.value,
11701
+ method = _step13$value.method,
11702
+ start = _step13$value.start,
11703
+ count = _step13$value.count;
11704
+ var move = method === '_removeElements' ? -count : count;
11705
+ moveNumericKeys(_hiddenIndices, start, move);
11706
+ }
11707
+ } catch (err) {
11708
+ _iterator13.e(err);
11709
+ } finally {
11710
+ _iterator13.f();
11711
+ }
11712
+ }
11713
+ }, {
11714
+ key: "_getUniformDataChanges",
11715
+ value: function _getUniformDataChanges() {
11716
+ var _dataChanges = this._dataChanges;
11717
+
11718
+ if (!_dataChanges || !_dataChanges.length) {
11719
+ return;
11720
+ }
11721
+
11722
+ this._dataChanges = [];
11723
+ var datasetCount = this.data.datasets.length;
11724
+
11725
+ var makeSet = function makeSet(idx) {
11726
+ return new Set(_dataChanges.filter(function (c) {
11727
+ return c[0] === idx;
11728
+ }).map(function (c, i) {
11729
+ return i + ',' + c.splice(1).join(',');
11730
+ }));
11731
+ };
11732
+
11733
+ var changeSet = makeSet(0);
11734
+
11735
+ for (var i = 1; i < datasetCount; i++) {
11736
+ if (!setsEqual(changeSet, makeSet(i))) {
11737
+ return;
11738
+ }
11739
+ }
11740
+
11741
+ return Array.from(changeSet).map(function (c) {
11742
+ return c.split(',');
11743
+ }).map(function (a) {
11744
+ return {
11745
+ method: a[1],
11746
+ start: +a[2],
11747
+ count: +a[3]
11748
+ };
11749
+ });
11750
+ }
11583
11751
  }, {
11584
11752
  key: "_updateLayout",
11585
11753
  value: function _updateLayout(minPadding) {
@@ -11626,8 +11794,12 @@
11626
11794
  }
11627
11795
 
11628
11796
  for (var i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {
11629
- this._updateDataset(i, isFunction(mode) ? mode({
11630
- datasetIndex: i
11797
+ this.getDatasetMeta(i).controller.configure();
11798
+ }
11799
+
11800
+ for (var _i3 = 0, _ilen = this.data.datasets.length; _i3 < _ilen; ++_i3) {
11801
+ this._updateDataset(_i3, isFunction(mode) ? mode({
11802
+ datasetIndex: _i3
11631
11803
  }) : mode);
11632
11804
  }
11633
11805
 
@@ -11927,6 +12099,7 @@
11927
12099
  }, {
11928
12100
  key: "destroy",
11929
12101
  value: function destroy() {
12102
+ this.notifyPlugins('beforeDestroy');
11930
12103
  var canvas = this.canvas,
11931
12104
  ctx = this.ctx;
11932
12105
 
@@ -11944,6 +12117,7 @@
11944
12117
 
11945
12118
  this.notifyPlugins('destroy');
11946
12119
  delete instances[this.id];
12120
+ this.notifyPlugins('afterDestroy');
11947
12121
  }
11948
12122
  }, {
11949
12123
  key: "toBase64Image",
@@ -12114,6 +12288,7 @@
12114
12288
 
12115
12289
  if (changed) {
12116
12290
  this._active = active;
12291
+ this._lastEvent = null;
12117
12292
 
12118
12293
  this._updateHoverStyles(active, lastActive);
12119
12294
  }
@@ -12155,7 +12330,8 @@
12155
12330
  var args = {
12156
12331
  event: e,
12157
12332
  replay: replay,
12158
- cancelable: true
12333
+ cancelable: true,
12334
+ inChartArea: _isPointInArea(e, this.chartArea, this._minPadding)
12159
12335
  };
12160
12336
 
12161
12337
  var eventFilter = function eventFilter(plugin) {
@@ -12166,7 +12342,7 @@
12166
12342
  return;
12167
12343
  }
12168
12344
 
12169
- var changed = this._handleEvent(e, replay);
12345
+ var changed = this._handleEvent(e, replay, args.inChartArea);
12170
12346
 
12171
12347
  args.cancelable = false;
12172
12348
  this.notifyPlugins('afterEvent', args, eventFilter);
@@ -12179,32 +12355,28 @@
12179
12355
  }
12180
12356
  }, {
12181
12357
  key: "_handleEvent",
12182
- value: function _handleEvent(e, replay) {
12358
+ value: function _handleEvent(e, replay, inChartArea) {
12183
12359
  var _this$_active = this._active,
12184
12360
  lastActive = _this$_active === void 0 ? [] : _this$_active,
12185
12361
  options = this.options;
12186
- var hoverOptions = options.hover;
12187
12362
  var useFinalPosition = replay;
12188
- var active = [];
12189
- var changed = false;
12190
- var lastEvent = null;
12191
12363
 
12192
- if (e.type !== 'mouseout') {
12193
- active = this.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions, useFinalPosition);
12194
- lastEvent = e.type === 'click' ? this._lastEvent : e;
12195
- }
12364
+ var active = this._getActiveElements(e, lastActive, inChartArea, useFinalPosition);
12365
+
12366
+ var isClick = _isClickEvent(e);
12196
12367
 
12197
- this._lastEvent = null;
12368
+ var lastEvent = determineLastEvent(e, this._lastEvent, inChartArea, isClick);
12198
12369
 
12199
- if (_isPointInArea(e, this.chartArea, this._minPadding)) {
12370
+ if (inChartArea) {
12371
+ this._lastEvent = null;
12200
12372
  callback(options.onHover, [e, active, this], this);
12201
12373
 
12202
- if (e.type === 'mouseup' || e.type === 'click' || e.type === 'contextmenu') {
12374
+ if (isClick) {
12203
12375
  callback(options.onClick, [e, active, this], this);
12204
12376
  }
12205
12377
  }
12206
12378
 
12207
- changed = !_elementsEqual(active, lastActive);
12379
+ var changed = !_elementsEqual(active, lastActive);
12208
12380
 
12209
12381
  if (changed || replay) {
12210
12382
  this._active = active;
@@ -12215,6 +12387,20 @@
12215
12387
  this._lastEvent = lastEvent;
12216
12388
  return changed;
12217
12389
  }
12390
+ }, {
12391
+ key: "_getActiveElements",
12392
+ value: function _getActiveElements(e, lastActive, inChartArea, useFinalPosition) {
12393
+ if (e.type === 'mouseout') {
12394
+ return [];
12395
+ }
12396
+
12397
+ if (!inChartArea) {
12398
+ return lastActive;
12399
+ }
12400
+
12401
+ var hoverOptions = this.options.hover;
12402
+ return this.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions, useFinalPosition);
12403
+ }
12218
12404
  }]);
12219
12405
 
12220
12406
  return Chart;
@@ -12452,18 +12638,20 @@
12452
12638
 
12453
12639
  function drawBorder(ctx, element, offset, spacing, endAngle) {
12454
12640
  var options = element.options;
12641
+ var borderWidth = options.borderWidth,
12642
+ borderJoinStyle = options.borderJoinStyle;
12455
12643
  var inner = options.borderAlign === 'inner';
12456
12644
 
12457
- if (!options.borderWidth) {
12645
+ if (!borderWidth) {
12458
12646
  return;
12459
12647
  }
12460
12648
 
12461
12649
  if (inner) {
12462
- ctx.lineWidth = options.borderWidth * 2;
12463
- ctx.lineJoin = 'round';
12650
+ ctx.lineWidth = borderWidth * 2;
12651
+ ctx.lineJoin = borderJoinStyle || 'round';
12464
12652
  } else {
12465
- ctx.lineWidth = options.borderWidth;
12466
- ctx.lineJoin = 'bevel';
12653
+ ctx.lineWidth = borderWidth;
12654
+ ctx.lineJoin = borderJoinStyle || 'bevel';
12467
12655
  }
12468
12656
 
12469
12657
  if (element.fullCircles) {
@@ -12510,12 +12698,12 @@
12510
12698
  value: function inRange(chartX, chartY, useFinalPosition) {
12511
12699
  var point = this.getProps(['x', 'y'], useFinalPosition);
12512
12700
 
12513
- var _getAngleFromPoint = getAngleFromPoint(point, {
12701
+ var _getAngleFromPoint2 = getAngleFromPoint(point, {
12514
12702
  x: chartX,
12515
12703
  y: chartY
12516
12704
  }),
12517
- angle = _getAngleFromPoint.angle,
12518
- distance = _getAngleFromPoint.distance;
12705
+ angle = _getAngleFromPoint2.angle,
12706
+ distance = _getAngleFromPoint2.distance;
12519
12707
 
12520
12708
  var _this$getProps2 = this.getProps(['startAngle', 'endAngle', 'innerRadius', 'outerRadius', 'circumference'], useFinalPosition),
12521
12709
  startAngle = _this$getProps2.startAngle,
@@ -12526,9 +12714,12 @@
12526
12714
 
12527
12715
  var rAdjust = this.options.spacing / 2;
12528
12716
 
12529
- var betweenAngles = circumference >= TAU || _angleBetween(angle, startAngle, endAngle);
12717
+ var _circumference = valueOrDefault(circumference, endAngle - startAngle);
12718
+
12719
+ var betweenAngles = _circumference >= TAU || _angleBetween(angle, startAngle, endAngle);
12720
+
12721
+ var withinRadius = _isBetween(distance, innerRadius + rAdjust, outerRadius + rAdjust);
12530
12722
 
12531
- var withinRadius = distance >= innerRadius + rAdjust && distance <= outerRadius + rAdjust;
12532
12723
  return betweenAngles && withinRadius;
12533
12724
  }
12534
12725
  }, {
@@ -12599,6 +12790,7 @@
12599
12790
  ArcElement.defaults = {
12600
12791
  borderAlign: 'center',
12601
12792
  borderColor: '#fff',
12793
+ borderJoinStyle: undefined,
12602
12794
  borderRadius: 0,
12603
12795
  borderWidth: 2,
12604
12796
  offset: 0,
@@ -13257,7 +13449,7 @@
13257
13449
  var skipY = y === null;
13258
13450
  var skipBoth = skipX && skipY;
13259
13451
  var bounds = bar && !skipBoth && getBarBounds(bar, useFinalPosition);
13260
- return bounds && (skipX || x >= bounds.left && x <= bounds.right) && (skipY || y >= bounds.top && y <= bounds.bottom);
13452
+ return bounds && (skipX || _isBetween(x, bounds.left, bounds.right)) && (skipY || _isBetween(y, bounds.top, bounds.bottom));
13261
13453
  }
13262
13454
 
13263
13455
  function hasRadius(radius) {
@@ -13952,7 +14144,7 @@
13952
14144
  var firstValue = linePoints[segment.start][property];
13953
14145
  var lastValue = linePoints[segment.end][property];
13954
14146
 
13955
- if (pointValue >= firstValue && pointValue <= lastValue) {
14147
+ if (_isBetween(pointValue, firstValue, lastValue)) {
13956
14148
  first = pointValue === firstValue;
13957
14149
  last = pointValue === lastValue;
13958
14150
  break;
@@ -14906,13 +15098,13 @@
14906
15098
  value: function _getLegendItemAt(x, y) {
14907
15099
  var i, hitBox, lh;
14908
15100
 
14909
- if (x >= this.left && x <= this.right && y >= this.top && y <= this.bottom) {
15101
+ if (_isBetween(x, this.left, this.right) && _isBetween(y, this.top, this.bottom)) {
14910
15102
  lh = this.legendHitBoxes;
14911
15103
 
14912
15104
  for (i = 0; i < lh.length; ++i) {
14913
15105
  hitBox = lh[i];
14914
15106
 
14915
- if (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {
15107
+ if (_isBetween(x, hitBox.left, hitBox.left + hitBox.width) && _isBetween(y, hitBox.top, hitBox.top + hitBox.height)) {
14916
15108
  return this.legendItems[i];
14917
15109
  }
14918
15110
  }
@@ -15400,7 +15592,7 @@
15400
15592
  }
15401
15593
 
15402
15594
  function getTooltipSize(tooltip, options) {
15403
- var ctx = tooltip._chart.ctx;
15595
+ var ctx = tooltip.chart.ctx;
15404
15596
  var body = tooltip.body,
15405
15597
  footer = tooltip.footer,
15406
15598
  title = tooltip.title;
@@ -15513,9 +15705,9 @@
15513
15705
  }
15514
15706
 
15515
15707
  function determineAlignment(chart, options, size) {
15516
- var yAlign = options.yAlign || determineYAlign(chart, size);
15708
+ var yAlign = size.yAlign || options.yAlign || determineYAlign(chart, size);
15517
15709
  return {
15518
- xAlign: options.xAlign || determineXAlign(chart, options, size, yAlign),
15710
+ xAlign: size.xAlign || options.xAlign || determineXAlign(chart, options, size, yAlign),
15519
15711
  yAlign: yAlign
15520
15712
  };
15521
15713
  }
@@ -15572,9 +15764,9 @@
15572
15764
  x -= paddingAndSize;
15573
15765
  }
15574
15766
  } else if (xAlign === 'left') {
15575
- x -= Math.max(topLeft, bottomLeft) + caretPadding;
15767
+ x -= Math.max(topLeft, bottomLeft) + caretSize;
15576
15768
  } else if (xAlign === 'right') {
15577
- x += Math.max(topRight, bottomRight) + caretPadding;
15769
+ x += Math.max(topRight, bottomRight) + caretSize;
15578
15770
  }
15579
15771
 
15580
15772
  return {
@@ -15618,13 +15810,14 @@
15618
15810
  _this30 = _super18.call(this);
15619
15811
  _this30.opacity = 0;
15620
15812
  _this30._active = [];
15621
- _this30._chart = config._chart;
15622
15813
  _this30._eventPosition = undefined;
15623
15814
  _this30._size = undefined;
15624
15815
  _this30._cachedAnimations = undefined;
15625
15816
  _this30._tooltipItems = [];
15626
15817
  _this30.$animations = undefined;
15627
15818
  _this30.$context = undefined;
15819
+ _this30.chart = config.chart || config._chart;
15820
+ _this30._chart = _this30.chart;
15628
15821
  _this30.options = config.options;
15629
15822
  _this30.dataPoints = undefined;
15630
15823
  _this30.title = undefined;
@@ -15662,10 +15855,10 @@
15662
15855
  return cached;
15663
15856
  }
15664
15857
 
15665
- var chart = this._chart;
15858
+ var chart = this.chart;
15666
15859
  var options = this.options.setContext(this.getContext());
15667
15860
  var opts = options.enabled && chart.options.animation && options.animations;
15668
- var animations = new Animations(this._chart, opts);
15861
+ var animations = new Animations(this.chart, opts);
15669
15862
 
15670
15863
  if (opts._cacheable) {
15671
15864
  this._cachedAnimations = Object.freeze(animations);
@@ -15676,7 +15869,7 @@
15676
15869
  }, {
15677
15870
  key: "getContext",
15678
15871
  value: function getContext() {
15679
- return this.$context || (this.$context = createTooltipContext(this._chart.getContext(), this, this._tooltipItems));
15872
+ return this.$context || (this.$context = createTooltipContext(this.chart.getContext(), this, this._tooltipItems));
15680
15873
  }
15681
15874
  }, {
15682
15875
  key: "getTitle",
@@ -15741,7 +15934,7 @@
15741
15934
  var _this32 = this;
15742
15935
 
15743
15936
  var active = this._active;
15744
- var data = this._chart.data;
15937
+ var data = this.chart.data;
15745
15938
  var labelColors = [];
15746
15939
  var labelPointStyles = [];
15747
15940
  var labelTextColors = [];
@@ -15749,7 +15942,7 @@
15749
15942
  var i, len;
15750
15943
 
15751
15944
  for (i = 0, len = active.length; i < len; ++i) {
15752
- tooltipItems.push(createTooltipItem(this._chart, active[i]));
15945
+ tooltipItems.push(createTooltipItem(this.chart, active[i]));
15753
15946
  }
15754
15947
 
15755
15948
  if (options.filter) {
@@ -15800,8 +15993,8 @@
15800
15993
  this.footer = this.getFooter(tooltipItems, options);
15801
15994
  var size = this._size = getTooltipSize(this, options);
15802
15995
  var positionAndSize = Object.assign({}, position, size);
15803
- var alignment = determineAlignment(this._chart, options, positionAndSize);
15804
- var backgroundPoint = getBackgroundPoint(options, positionAndSize, alignment, this._chart);
15996
+ var alignment = determineAlignment(this.chart, options, positionAndSize);
15997
+ var backgroundPoint = getBackgroundPoint(options, positionAndSize, alignment, this.chart);
15805
15998
  this.xAlign = alignment.xAlign;
15806
15999
  this.yAlign = alignment.yAlign;
15807
16000
  properties = {
@@ -15824,7 +16017,7 @@
15824
16017
 
15825
16018
  if (changed && options.external) {
15826
16019
  options.external.call(this, {
15827
- chart: this._chart,
16020
+ chart: this.chart,
15828
16021
  tooltip: this,
15829
16022
  replay: replay
15830
16023
  });
@@ -16145,7 +16338,7 @@
16145
16338
  }, {
16146
16339
  key: "_updateAnimationTarget",
16147
16340
  value: function _updateAnimationTarget(options) {
16148
- var chart = this._chart;
16341
+ var chart = this.chart;
16149
16342
  var anims = this.$animations;
16150
16343
  var animX = anims && anims.x;
16151
16344
  var animY = anims && anims.y;
@@ -16226,7 +16419,7 @@
16226
16419
  var datasetIndex = _ref9.datasetIndex,
16227
16420
  index = _ref9.index;
16228
16421
 
16229
- var meta = _this33._chart.getDatasetMeta(datasetIndex);
16422
+ var meta = _this33.chart.getDatasetMeta(datasetIndex);
16230
16423
 
16231
16424
  if (!meta) {
16232
16425
  throw new Error('Cannot find a dataset at index ' + datasetIndex);
@@ -16245,28 +16438,28 @@
16245
16438
  if (changed || positionChanged) {
16246
16439
  this._active = active;
16247
16440
  this._eventPosition = eventPosition;
16441
+ this._ignoreReplayEvents = true;
16248
16442
  this.update(true);
16249
16443
  }
16250
16444
  }
16251
16445
  }, {
16252
16446
  key: "handleEvent",
16253
16447
  value: function handleEvent(e, replay) {
16448
+ var inChartArea = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
16449
+
16450
+ if (replay && this._ignoreReplayEvents) {
16451
+ return false;
16452
+ }
16453
+
16454
+ this._ignoreReplayEvents = false;
16254
16455
  var options = this.options;
16255
16456
  var lastActive = this._active || [];
16256
- var changed = false;
16257
- var active = [];
16258
16457
 
16259
- if (e.type !== 'mouseout') {
16260
- active = this._chart.getElementsAtEventForMode(e, options.mode, options, replay);
16261
-
16262
- if (options.reverse) {
16263
- active.reverse();
16264
- }
16265
- }
16458
+ var active = this._getActiveElements(e, lastActive, replay, inChartArea);
16266
16459
 
16267
16460
  var positionChanged = this._positionChanged(active, e);
16268
16461
 
16269
- changed = replay || !_elementsEqual(active, lastActive) || positionChanged;
16462
+ var changed = replay || !_elementsEqual(active, lastActive) || positionChanged;
16270
16463
 
16271
16464
  if (changed) {
16272
16465
  this._active = active;
@@ -16282,6 +16475,27 @@
16282
16475
 
16283
16476
  return changed;
16284
16477
  }
16478
+ }, {
16479
+ key: "_getActiveElements",
16480
+ value: function _getActiveElements(e, lastActive, replay, inChartArea) {
16481
+ var options = this.options;
16482
+
16483
+ if (e.type === 'mouseout') {
16484
+ return [];
16485
+ }
16486
+
16487
+ if (!inChartArea) {
16488
+ return lastActive;
16489
+ }
16490
+
16491
+ var active = this.chart.getElementsAtEventForMode(e, options.mode, options, replay);
16492
+
16493
+ if (options.reverse) {
16494
+ active.reverse();
16495
+ }
16496
+
16497
+ return active;
16498
+ }
16285
16499
  }, {
16286
16500
  key: "_positionChanged",
16287
16501
  value: function _positionChanged(active, e) {
@@ -16304,7 +16518,7 @@
16304
16518
  afterInit: function afterInit(chart, _args, options) {
16305
16519
  if (options) {
16306
16520
  chart.tooltip = new Tooltip({
16307
- _chart: chart,
16521
+ chart: chart,
16308
16522
  options: options
16309
16523
  });
16310
16524
  }
@@ -16339,7 +16553,7 @@
16339
16553
  if (chart.tooltip) {
16340
16554
  var useFinalPosition = args.replay;
16341
16555
 
16342
- if (chart.tooltip.handleEvent(args.event, useFinalPosition)) {
16556
+ if (chart.tooltip.handleEvent(args.event, useFinalPosition, args.inChartArea)) {
16343
16557
  args.changed = true;
16344
16558
  }
16345
16559
  }
@@ -16500,15 +16714,25 @@
16500
16714
  Tooltip: plugin_tooltip
16501
16715
  });
16502
16716
 
16503
- var addIfString = function addIfString(labels, raw, index) {
16504
- return typeof raw === 'string' ? labels.push(raw) - 1 : isNaN(raw) ? null : index;
16717
+ var addIfString = function addIfString(labels, raw, index, addedLabels) {
16718
+ if (typeof raw === 'string') {
16719
+ index = labels.push(raw) - 1;
16720
+ addedLabels.unshift({
16721
+ index: index,
16722
+ label: raw
16723
+ });
16724
+ } else if (isNaN(raw)) {
16725
+ index = null;
16726
+ }
16727
+
16728
+ return index;
16505
16729
  };
16506
16730
 
16507
- function findOrAddLabel(labels, raw, index) {
16731
+ function findOrAddLabel(labels, raw, index, addedLabels) {
16508
16732
  var first = labels.indexOf(raw);
16509
16733
 
16510
16734
  if (first === -1) {
16511
- return addIfString(labels, raw, index);
16735
+ return addIfString(labels, raw, index, addedLabels);
16512
16736
  }
16513
16737
 
16514
16738
  var last = labels.lastIndexOf(raw);
@@ -16532,10 +16756,43 @@
16532
16756
  _this34 = _super19.call(this, cfg);
16533
16757
  _this34._startValue = undefined;
16534
16758
  _this34._valueRange = 0;
16759
+ _this34._addedLabels = [];
16535
16760
  return _this34;
16536
16761
  }
16537
16762
 
16538
16763
  _createClass(CategoryScale, [{
16764
+ key: "init",
16765
+ value: function init(scaleOptions) {
16766
+ var added = this._addedLabels;
16767
+
16768
+ if (added.length) {
16769
+ var labels = this.getLabels();
16770
+
16771
+ var _iterator22 = _createForOfIteratorHelper(added),
16772
+ _step22;
16773
+
16774
+ try {
16775
+ for (_iterator22.s(); !(_step22 = _iterator22.n()).done;) {
16776
+ var _step22$value = _step22.value,
16777
+ index = _step22$value.index,
16778
+ label = _step22$value.label;
16779
+
16780
+ if (labels[index] === label) {
16781
+ labels.splice(index, 1);
16782
+ }
16783
+ }
16784
+ } catch (err) {
16785
+ _iterator22.e(err);
16786
+ } finally {
16787
+ _iterator22.f();
16788
+ }
16789
+
16790
+ this._addedLabels = [];
16791
+ }
16792
+
16793
+ _get(_getPrototypeOf(CategoryScale.prototype), "init", this).call(this, scaleOptions);
16794
+ }
16795
+ }, {
16539
16796
  key: "parse",
16540
16797
  value: function parse(raw, index) {
16541
16798
  if (isNullOrUndef(raw)) {
@@ -16543,7 +16800,7 @@
16543
16800
  }
16544
16801
 
16545
16802
  var labels = this.getLabels();
16546
- index = isFinite(index) && labels[index] === raw ? index : findOrAddLabel(labels, raw, valueOrDefault(index, raw));
16803
+ index = isFinite(index) && labels[index] === raw ? index : findOrAddLabel(labels, raw, valueOrDefault(index, raw), this._addedLabels);
16547
16804
  return validIndex(index, labels.length - 1);
16548
16805
  }
16549
16806
  }, {
@@ -16949,7 +17206,7 @@
16949
17206
  }, {
16950
17207
  key: "getLabelForValue",
16951
17208
  value: function getLabelForValue(value) {
16952
- return formatNumber(value, this.chart.options.locale);
17209
+ return formatNumber(value, this.chart.options.locale, this.options.ticks.format);
16953
17210
  }
16954
17211
  }]);
16955
17212
 
@@ -17171,7 +17428,7 @@
17171
17428
  }, {
17172
17429
  key: "getLabelForValue",
17173
17430
  value: function getLabelForValue(value) {
17174
- return value === undefined ? '0' : formatNumber(value, this.chart.options.locale);
17431
+ return value === undefined ? '0' : formatNumber(value, this.chart.options.locale, this.options.ticks.format);
17175
17432
  }
17176
17433
  }, {
17177
17434
  key: "configure",
@@ -17256,66 +17513,73 @@
17256
17513
  }
17257
17514
 
17258
17515
  function fitWithPointLabels(scale) {
17259
- var furthestLimits = {
17260
- l: 0,
17261
- r: scale.width,
17262
- t: 0,
17263
- b: scale.height - scale.paddingTop
17516
+ var orig = {
17517
+ l: scale.left + scale._padding.left,
17518
+ r: scale.right - scale._padding.right,
17519
+ t: scale.top + scale._padding.top,
17520
+ b: scale.bottom - scale._padding.bottom
17264
17521
  };
17265
- var furthestAngles = {};
17522
+ var limits = Object.assign({}, orig);
17266
17523
  var labelSizes = [];
17267
17524
  var padding = [];
17268
- var valueCount = scale.getLabels().length;
17525
+ var valueCount = scale._pointLabels.length;
17526
+ var pointLabelOpts = scale.options.pointLabels;
17527
+ var additionalAngle = pointLabelOpts.centerPointLabels ? PI / valueCount : 0;
17269
17528
 
17270
17529
  for (var i = 0; i < valueCount; i++) {
17271
- var opts = scale.options.pointLabels.setContext(scale.getPointLabelContext(i));
17530
+ var opts = pointLabelOpts.setContext(scale.getPointLabelContext(i));
17272
17531
  padding[i] = opts.padding;
17273
- var pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i]);
17532
+ var pointPosition = scale.getPointPosition(i, scale.drawingArea + padding[i], additionalAngle);
17274
17533
  var plFont = toFont(opts.font);
17275
17534
  var textSize = measureLabelSize(scale.ctx, plFont, scale._pointLabels[i]);
17276
17535
  labelSizes[i] = textSize;
17277
- var angleRadians = scale.getIndexAngle(i);
17278
- var angle = toDegrees(angleRadians);
17536
+
17537
+ var angleRadians = _normalizeAngle(scale.getIndexAngle(i) + additionalAngle);
17538
+
17539
+ var angle = Math.round(toDegrees(angleRadians));
17279
17540
  var hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);
17280
17541
  var vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);
17542
+ updateLimits(limits, orig, angleRadians, hLimits, vLimits);
17543
+ }
17281
17544
 
17282
- if (hLimits.start < furthestLimits.l) {
17283
- furthestLimits.l = hLimits.start;
17284
- furthestAngles.l = angleRadians;
17285
- }
17286
-
17287
- if (hLimits.end > furthestLimits.r) {
17288
- furthestLimits.r = hLimits.end;
17289
- furthestAngles.r = angleRadians;
17290
- }
17545
+ scale.setCenterPoint(orig.l - limits.l, limits.r - orig.r, orig.t - limits.t, limits.b - orig.b);
17546
+ scale._pointLabelItems = buildPointLabelItems(scale, labelSizes, padding);
17547
+ }
17291
17548
 
17292
- if (vLimits.start < furthestLimits.t) {
17293
- furthestLimits.t = vLimits.start;
17294
- furthestAngles.t = angleRadians;
17295
- }
17549
+ function updateLimits(limits, orig, angle, hLimits, vLimits) {
17550
+ var sin = Math.abs(Math.sin(angle));
17551
+ var cos = Math.abs(Math.cos(angle));
17552
+ var x = 0;
17553
+ var y = 0;
17296
17554
 
17297
- if (vLimits.end > furthestLimits.b) {
17298
- furthestLimits.b = vLimits.end;
17299
- furthestAngles.b = angleRadians;
17300
- }
17555
+ if (hLimits.start < orig.l) {
17556
+ x = (orig.l - hLimits.start) / sin;
17557
+ limits.l = Math.min(limits.l, orig.l - x);
17558
+ } else if (hLimits.end > orig.r) {
17559
+ x = (hLimits.end - orig.r) / sin;
17560
+ limits.r = Math.max(limits.r, orig.r + x);
17301
17561
  }
17302
17562
 
17303
- scale._setReductions(scale.drawingArea, furthestLimits, furthestAngles);
17304
-
17305
- scale._pointLabelItems = buildPointLabelItems(scale, labelSizes, padding);
17563
+ if (vLimits.start < orig.t) {
17564
+ y = (orig.t - vLimits.start) / cos;
17565
+ limits.t = Math.min(limits.t, orig.t - y);
17566
+ } else if (vLimits.end > orig.b) {
17567
+ y = (vLimits.end - orig.b) / cos;
17568
+ limits.b = Math.max(limits.b, orig.b + y);
17569
+ }
17306
17570
  }
17307
17571
 
17308
17572
  function buildPointLabelItems(scale, labelSizes, padding) {
17309
17573
  var items = [];
17310
- var valueCount = scale.getLabels().length;
17574
+ var valueCount = scale._pointLabels.length;
17311
17575
  var opts = scale.options;
17312
- var tickBackdropHeight = getTickBackdropHeight(opts);
17313
- var outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);
17576
+ var extra = getTickBackdropHeight(opts) / 2;
17577
+ var outerDistance = scale.drawingArea;
17578
+ var additionalAngle = opts.pointLabels.centerPointLabels ? PI / valueCount : 0;
17314
17579
 
17315
17580
  for (var i = 0; i < valueCount; i++) {
17316
- var extra = i === 0 ? tickBackdropHeight / 2 : 0;
17317
- var pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + padding[i]);
17318
- var angle = toDegrees(scale.getIndexAngle(i));
17581
+ var pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + padding[i], additionalAngle);
17582
+ var angle = Math.round(toDegrees(_normalizeAngle(pointLabelPosition.angle + HALF_PI)));
17319
17583
  var size = labelSizes[i];
17320
17584
  var y = yForAngle(pointLabelPosition.y, size.h, angle);
17321
17585
  var textAlign = getTextAlignForAngle(angle);
@@ -17433,10 +17697,6 @@
17433
17697
  ctx.restore();
17434
17698
  }
17435
17699
 
17436
- function numberOrZero(param) {
17437
- return isNumber(param) ? param : 0;
17438
- }
17439
-
17440
17700
  function createPointLabelContext(parent, index, label) {
17441
17701
  return createContext(parent, {
17442
17702
  label: label,
@@ -17467,12 +17727,12 @@
17467
17727
  _createClass(RadialLinearScale, [{
17468
17728
  key: "setDimensions",
17469
17729
  value: function setDimensions() {
17470
- this.width = this.maxWidth;
17471
- this.height = this.maxHeight;
17472
- this.paddingTop = getTickBackdropHeight(this.options) / 2;
17473
- this.xCenter = Math.floor(this.width / 2);
17474
- this.yCenter = Math.floor((this.height - this.paddingTop) / 2);
17475
- this.drawingArea = Math.min(this.height - this.paddingTop, this.width) / 2;
17730
+ var padding = this._padding = toPadding(getTickBackdropHeight(this.options) / 2);
17731
+ var w = this.width = this.maxWidth - padding.width;
17732
+ var h = this.height = this.maxHeight - padding.height;
17733
+ this.xCenter = Math.floor(this.left + w / 2 + padding.left);
17734
+ this.yCenter = Math.floor(this.top + h / 2 + padding.top);
17735
+ this.drawingArea = Math.floor(Math.min(w, h) / 2);
17476
17736
  }
17477
17737
  }, {
17478
17738
  key: "determineDataLimits",
@@ -17499,6 +17759,8 @@
17499
17759
  this._pointLabels = this.getLabels().map(function (value, index) {
17500
17760
  var label = callback(_this38.options.pointLabels.callback, [value, index], _this38);
17501
17761
  return label || label === 0 ? label : '';
17762
+ }).filter(function (v, i) {
17763
+ return _this38.chart.getDataVisibility(i);
17502
17764
  });
17503
17765
  }
17504
17766
  }, {
@@ -17512,34 +17774,17 @@
17512
17774
  this.setCenterPoint(0, 0, 0, 0);
17513
17775
  }
17514
17776
  }
17515
- }, {
17516
- key: "_setReductions",
17517
- value: function _setReductions(largestPossibleRadius, furthestLimits, furthestAngles) {
17518
- var radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);
17519
- var radiusReductionRight = Math.max(furthestLimits.r - this.width, 0) / Math.sin(furthestAngles.r);
17520
- var radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);
17521
- var radiusReductionBottom = -Math.max(furthestLimits.b - (this.height - this.paddingTop), 0) / Math.cos(furthestAngles.b);
17522
- radiusReductionLeft = numberOrZero(radiusReductionLeft);
17523
- radiusReductionRight = numberOrZero(radiusReductionRight);
17524
- radiusReductionTop = numberOrZero(radiusReductionTop);
17525
- radiusReductionBottom = numberOrZero(radiusReductionBottom);
17526
- this.drawingArea = Math.max(largestPossibleRadius / 2, Math.min(Math.floor(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2), Math.floor(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2)));
17527
- this.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);
17528
- }
17529
17777
  }, {
17530
17778
  key: "setCenterPoint",
17531
17779
  value: function setCenterPoint(leftMovement, rightMovement, topMovement, bottomMovement) {
17532
- var maxRight = this.width - rightMovement - this.drawingArea;
17533
- var maxLeft = leftMovement + this.drawingArea;
17534
- var maxTop = topMovement + this.drawingArea;
17535
- var maxBottom = this.height - this.paddingTop - bottomMovement - this.drawingArea;
17536
- this.xCenter = Math.floor((maxLeft + maxRight) / 2 + this.left);
17537
- this.yCenter = Math.floor((maxTop + maxBottom) / 2 + this.top + this.paddingTop);
17780
+ this.xCenter += Math.floor((leftMovement - rightMovement) / 2);
17781
+ this.yCenter += Math.floor((topMovement - bottomMovement) / 2);
17782
+ this.drawingArea -= Math.min(this.drawingArea / 2, Math.max(leftMovement, rightMovement, topMovement, bottomMovement));
17538
17783
  }
17539
17784
  }, {
17540
17785
  key: "getIndexAngle",
17541
17786
  value: function getIndexAngle(index) {
17542
- var angleMultiplier = TAU / this.getLabels().length;
17787
+ var angleMultiplier = TAU / (this._pointLabels.length || 1);
17543
17788
  var startAngle = this.options.startAngle || 0;
17544
17789
  return _normalizeAngle(index * angleMultiplier + toRadians(startAngle));
17545
17790
  }
@@ -17581,7 +17826,8 @@
17581
17826
  }, {
17582
17827
  key: "getPointPosition",
17583
17828
  value: function getPointPosition(index, distanceFromCenter) {
17584
- var angle = this.getIndexAngle(index) - HALF_PI;
17829
+ var additionalAngle = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
17830
+ var angle = this.getIndexAngle(index) - HALF_PI + additionalAngle;
17585
17831
  return {
17586
17832
  x: Math.cos(angle) * distanceFromCenter + this.xCenter,
17587
17833
  y: Math.sin(angle) * distanceFromCenter + this.yCenter,
@@ -17624,7 +17870,7 @@
17624
17870
  var ctx = this.ctx;
17625
17871
  ctx.save();
17626
17872
  ctx.beginPath();
17627
- pathRadiusLine(this, this.getDistanceFromCenterForValue(this._endValue), circular, this.getLabels().length);
17873
+ pathRadiusLine(this, this.getDistanceFromCenterForValue(this._endValue), circular, this._pointLabels.length);
17628
17874
  ctx.closePath();
17629
17875
  ctx.fillStyle = backgroundColor;
17630
17876
  ctx.fill();
@@ -17640,7 +17886,7 @@
17640
17886
  var opts = this.options;
17641
17887
  var angleLines = opts.angleLines,
17642
17888
  grid = opts.grid;
17643
- var labelCount = this.getLabels().length;
17889
+ var labelCount = this._pointLabels.length;
17644
17890
  var i, offset, position;
17645
17891
 
17646
17892
  if (opts.pointLabels.display) {
@@ -17660,7 +17906,7 @@
17660
17906
  if (angleLines.display) {
17661
17907
  ctx.save();
17662
17908
 
17663
- for (i = this.getLabels().length - 1; i >= 0; i--) {
17909
+ for (i = labelCount - 1; i >= 0; i--) {
17664
17910
  var optsAtIndex = angleLines.setContext(this.getPointLabelContext(i));
17665
17911
  var color = optsAtIndex.color,
17666
17912
  lineWidth = optsAtIndex.lineWidth;
@@ -17767,7 +18013,8 @@
17767
18013
  callback: function callback(label) {
17768
18014
  return label;
17769
18015
  },
17770
- padding: 5
18016
+ padding: 5,
18017
+ centerPointLabels: false
17771
18018
  }
17772
18019
  };
17773
18020
  RadialLinearScale.defaultRoutes = {