chart 0.1.4.9 → 0.1.5.0.pre

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
  SHA1:
3
- metadata.gz: 75c52b55338f3bd15897e409fb7c0e0eebecba65
4
- data.tar.gz: 8d37358086aa7c81d45b06b916ccab72c0fb6b4c
3
+ metadata.gz: d4225c1955f40f8dcf778eee2ef9e95073e7c122
4
+ data.tar.gz: ce6c3583f0a3de0632ca29ad26a79ebc62f78416
5
5
  SHA512:
6
- metadata.gz: 0a5a091be068aabd681debb72a8fe3301e3783ed5cbfb226d6b3f983b9e70142f38f2cab9eea677824cf774589a2285888b27701ebd7750b9dd4d0a8d718e64a
7
- data.tar.gz: 935f5f6f7809b35257b62587b90fc510879511eb75ccccbd2bd7c161e1e23cac40cf1a73e473051ca93f4f420cfe0b15250cc918e61ebe7909b14b53e1daa795
6
+ metadata.gz: 7053a201f730e01e912314c5a29c0dbdd35b00dd569b03c8e24567321af95d51efebd7f602970190da137355f3b905abe95d88164cf04de9e087fc16bf0e1b05
7
+ data.tar.gz: 283abed337cff774cc8a77a0a846751ffc2a7b4bc27a931421de26ffb6849966ec1b31e75d17d1d9c7396aacd1649ea6902437eb3fc8850bf84a5b69d8420573
data/lib/chart/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Chart
2
- VERSION = "0.1.4.9"
2
+ VERSION = "0.1.5.0.pre"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  /*!
2
2
  * Chart.js
3
3
  * http://chartjs.org/
4
- * Version: 2.1.6
4
+ * Version: 2.2.1
5
5
  *
6
6
  * Copyright 2016 Nick Downie
7
7
  * Released under the MIT license
@@ -1665,32 +1665,33 @@ module.exports = {
1665
1665
  /**
1666
1666
  * @namespace Chart
1667
1667
  */
1668
- var Chart = require(26)();
1668
+ var Chart = require(27)();
1669
1669
 
1670
+ require(26)(Chart);
1671
+ require(22)(Chart);
1670
1672
  require(25)(Chart);
1671
- require(24)(Chart);
1672
1673
  require(21)(Chart);
1673
- require(22)(Chart);
1674
1674
  require(23)(Chart);
1675
- require(27)(Chart);
1676
- require(31)(Chart);
1677
- require(29)(Chart);
1678
- require(30)(Chart);
1679
- require(32)(Chart);
1675
+ require(24)(Chart);
1680
1676
  require(28)(Chart);
1677
+ require(32)(Chart);
1678
+ require(30)(Chart);
1679
+ require(31)(Chart);
1681
1680
  require(33)(Chart);
1682
-
1681
+ require(29)(Chart);
1683
1682
  require(34)(Chart);
1683
+
1684
1684
  require(35)(Chart);
1685
1685
  require(36)(Chart);
1686
1686
  require(37)(Chart);
1687
-
1688
- require(40)(Chart);
1689
1687
  require(38)(Chart);
1690
- require(39)(Chart);
1688
+
1691
1689
  require(41)(Chart);
1690
+ require(39)(Chart);
1691
+ require(40)(Chart);
1692
1692
  require(42)(Chart);
1693
1693
  require(43)(Chart);
1694
+ require(44)(Chart);
1694
1695
 
1695
1696
  // Controllers must be loaded after elements
1696
1697
  // See Chart.core.datasetController.dataElementType
@@ -1711,7 +1712,7 @@ require(14)(Chart);
1711
1712
 
1712
1713
  window.Chart = module.exports = Chart;
1713
1714
 
1714
- },{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"36":36,"37":37,"38":38,"39":39,"40":40,"41":41,"42":42,"43":43,"8":8,"9":9}],8:[function(require,module,exports){
1715
+ },{"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16,"17":17,"18":18,"19":19,"20":20,"21":21,"22":22,"23":23,"24":24,"25":25,"26":26,"27":27,"28":28,"29":29,"30":30,"31":31,"32":32,"33":33,"34":34,"35":35,"36":36,"37":37,"38":38,"39":39,"40":40,"41":41,"42":42,"43":43,"44":44,"8":8,"9":9}],8:[function(require,module,exports){
1715
1716
  "use strict";
1716
1717
 
1717
1718
  module.exports = function(Chart) {
@@ -1809,11 +1810,11 @@ module.exports = function(Chart) {
1809
1810
 
1810
1811
  tooltips: {
1811
1812
  callbacks: {
1812
- title: function(tooltipItems, data) {
1813
+ title: function() {
1813
1814
  // Title doesn't make sense for scatter since we format the data as a point
1814
1815
  return '';
1815
1816
  },
1816
- label: function(tooltipItem, data) {
1817
+ label: function(tooltipItem) {
1817
1818
  return '(' + tooltipItem.xLabel + ', ' + tooltipItem.yLabel + ')';
1818
1819
  }
1819
1820
  }
@@ -1875,7 +1876,7 @@ module.exports = function(Chart) {
1875
1876
  },
1876
1877
 
1877
1878
  // Get the number of datasets that display bars. We use this to correctly calculate the bar width
1878
- getBarCount: function getBarCount() {
1879
+ getBarCount: function() {
1879
1880
  var me = this;
1880
1881
  var barCount = 0;
1881
1882
  helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {
@@ -1887,14 +1888,14 @@ module.exports = function(Chart) {
1887
1888
  return barCount;
1888
1889
  },
1889
1890
 
1890
- update: function update(reset) {
1891
+ update: function(reset) {
1891
1892
  var me = this;
1892
1893
  helpers.each(me.getMeta().data, function(rectangle, index) {
1893
1894
  me.updateElement(rectangle, index, reset);
1894
1895
  }, me);
1895
1896
  },
1896
1897
 
1897
- updateElement: function updateElement(rectangle, index, reset) {
1898
+ updateElement: function(rectangle, index, reset) {
1898
1899
  var me = this;
1899
1900
  var meta = me.getMeta();
1900
1901
  var xScale = me.getScaleForId(meta.xAxisID);
@@ -1941,23 +1942,14 @@ module.exports = function(Chart) {
1941
1942
  if (yScale.options.stacked) {
1942
1943
  var chart = me.chart;
1943
1944
  var datasets = chart.data.datasets;
1944
- var value = datasets[datasetIndex].data[index];
1945
+ var value = Number(datasets[datasetIndex].data[index]);
1945
1946
 
1946
- if (value < 0) {
1947
- for (var i = 0; i < datasetIndex; i++) {
1948
- var negDS = datasets[i];
1949
- var negDSMeta = chart.getDatasetMeta(i);
1950
- if (negDSMeta.bar && negDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
1951
- base += negDS.data[index] < 0 ? negDS.data[index] : 0;
1952
- }
1953
- }
1954
- } else {
1955
- for (var j = 0; j < datasetIndex; j++) {
1956
- var posDS = datasets[j];
1957
- var posDSMeta = chart.getDatasetMeta(j);
1958
- if (posDSMeta.bar && posDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(j)) {
1959
- base += posDS.data[index] > 0 ? posDS.data[index] : 0;
1960
- }
1947
+ for (var i = 0; i < datasetIndex; i++) {
1948
+ var currentDs = datasets[i];
1949
+ var currentDsMeta = chart.getDatasetMeta(i);
1950
+ if (currentDsMeta.bar && currentDsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
1951
+ var currentVal = Number(currentDs.data[index]);
1952
+ base += value < 0 ? Math.min(currentVal, 0) : Math.max(currentVal, 0);
1961
1953
  }
1962
1954
  }
1963
1955
 
@@ -2006,6 +1998,9 @@ module.exports = function(Chart) {
2006
1998
 
2007
1999
  calculateBarWidth: function(index) {
2008
2000
  var xScale = this.getScaleForId(this.getMeta().xAxisID);
2001
+ if (xScale.options.barThickness) {
2002
+ return xScale.options.barThickness;
2003
+ }
2009
2004
  var ruler = this.getRuler(index);
2010
2005
  return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth;
2011
2006
  },
@@ -2051,7 +2046,7 @@ module.exports = function(Chart) {
2051
2046
  var me = this;
2052
2047
  var meta = me.getMeta();
2053
2048
  var yScale = me.getScaleForId(meta.yAxisID);
2054
- var value = me.getDataset().data[index];
2049
+ var value = Number(me.getDataset().data[index]);
2055
2050
 
2056
2051
  if (yScale.options.stacked) {
2057
2052
 
@@ -2062,10 +2057,11 @@ module.exports = function(Chart) {
2062
2057
  var ds = me.chart.data.datasets[i];
2063
2058
  var dsMeta = me.chart.getDatasetMeta(i);
2064
2059
  if (dsMeta.bar && dsMeta.yAxisID === yScale.id && me.chart.isDatasetVisible(i)) {
2065
- if (ds.data[index] < 0) {
2066
- sumNeg += ds.data[index] || 0;
2060
+ var stackedVal = Number(ds.data[index]);
2061
+ if (stackedVal < 0) {
2062
+ sumNeg += stackedVal || 0;
2067
2063
  } else {
2068
- sumPos += ds.data[index] || 0;
2064
+ sumPos += stackedVal || 0;
2069
2065
  }
2070
2066
  }
2071
2067
  }
@@ -2173,7 +2169,7 @@ module.exports = function(Chart) {
2173
2169
  };
2174
2170
 
2175
2171
  Chart.controllers.horizontalBar = Chart.controllers.bar.extend({
2176
- updateElement: function updateElement(rectangle, index, reset, numBars) {
2172
+ updateElement: function(rectangle, index, reset) {
2177
2173
  var me = this;
2178
2174
  var meta = me.getMeta();
2179
2175
  var xScale = me.getScaleForId(meta.xAxisID);
@@ -2289,24 +2285,16 @@ module.exports = function(Chart) {
2289
2285
  var base = 0;
2290
2286
 
2291
2287
  if (xScale.options.stacked) {
2288
+ var chart = me.chart;
2289
+ var datasets = chart.data.datasets;
2290
+ var value = Number(datasets[datasetIndex].data[index]);
2292
2291
 
2293
- var value = me.chart.data.datasets[datasetIndex].data[index];
2294
-
2295
- if (value < 0) {
2296
- for (var i = 0; i < datasetIndex; i++) {
2297
- var negDS = me.chart.data.datasets[i];
2298
- var negDSMeta = me.chart.getDatasetMeta(i);
2299
- if (negDSMeta.bar && negDSMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) {
2300
- base += negDS.data[index] < 0 ? negDS.data[index] : 0;
2301
- }
2302
- }
2303
- } else {
2304
- for (var j = 0; j < datasetIndex; j++) {
2305
- var posDS = me.chart.data.datasets[j];
2306
- var posDSMeta = me.chart.getDatasetMeta(j);
2307
- if (posDSMeta.bar && posDSMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(j)) {
2308
- base += posDS.data[index] > 0 ? posDS.data[index] : 0;
2309
- }
2292
+ for (var i = 0; i < datasetIndex; i++) {
2293
+ var currentDs = datasets[i];
2294
+ var currentDsMeta = chart.getDatasetMeta(i);
2295
+ if (currentDsMeta.bar && currentDsMeta.xAxisID === xScale.id && chart.isDatasetVisible(i)) {
2296
+ var currentVal = Number(currentDs.data[index]);
2297
+ base += value < 0 ? Math.min(currentVal, 0) : Math.max(currentVal, 0);
2310
2298
  }
2311
2299
  }
2312
2300
 
@@ -2355,6 +2343,9 @@ module.exports = function(Chart) {
2355
2343
  calculateBarHeight: function (index) {
2356
2344
  var me = this;
2357
2345
  var yScale = me.getScaleForId(me.getMeta().yAxisID);
2346
+ if (yScale.options.barThickness) {
2347
+ return yScale.options.barThickness;
2348
+ }
2358
2349
  var ruler = me.getRuler(index);
2359
2350
  return yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight;
2360
2351
  },
@@ -2363,7 +2354,7 @@ module.exports = function(Chart) {
2363
2354
  var me = this;
2364
2355
  var meta = me.getMeta();
2365
2356
  var xScale = me.getScaleForId(meta.xAxisID);
2366
- var value = me.getDataset().data[index];
2357
+ var value = Number(me.getDataset().data[index]);
2367
2358
 
2368
2359
  if (xScale.options.stacked) {
2369
2360
 
@@ -2374,10 +2365,11 @@ module.exports = function(Chart) {
2374
2365
  var ds = me.chart.data.datasets[i];
2375
2366
  var dsMeta = me.chart.getDatasetMeta(i);
2376
2367
  if (dsMeta.bar && dsMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) {
2377
- if (ds.data[index] < 0) {
2378
- sumNeg += ds.data[index] || 0;
2368
+ var stackedVal = Number(ds.data[index]);
2369
+ if (stackedVal < 0) {
2370
+ sumNeg += stackedVal || 0;
2379
2371
  } else {
2380
- sumPos += ds.data[index] || 0;
2372
+ sumPos += stackedVal || 0;
2381
2373
  }
2382
2374
  }
2383
2375
  }
@@ -2443,7 +2435,7 @@ module.exports = function(Chart) {
2443
2435
 
2444
2436
  tooltips: {
2445
2437
  callbacks: {
2446
- title: function(tooltipItems, data) {
2438
+ title: function() {
2447
2439
  // Title doesn't make sense for scatter since we format the data as a point
2448
2440
  return '';
2449
2441
  },
@@ -2460,7 +2452,7 @@ module.exports = function(Chart) {
2460
2452
 
2461
2453
  dataElementType: Chart.elements.Point,
2462
2454
 
2463
- update: function update(reset) {
2455
+ update: function(reset) {
2464
2456
  var me = this;
2465
2457
  var meta = me.getMeta();
2466
2458
  var points = meta.data;
@@ -2492,7 +2484,7 @@ module.exports = function(Chart) {
2492
2484
 
2493
2485
  // Desired view properties
2494
2486
  _model: {
2495
- x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(data, index, dsIndex, me.chart.isCombo),
2487
+ x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex, me.chart.isCombo),
2496
2488
  y: reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex),
2497
2489
  // Appearance
2498
2490
  radius: reset ? 0 : custom.radius ? custom.radius : me.getRadius(data),
@@ -2589,7 +2581,7 @@ module.exports = function(Chart) {
2589
2581
  var meta = chart.getDatasetMeta(0);
2590
2582
  var ds = data.datasets[0];
2591
2583
  var arc = meta.data[i];
2592
- var custom = arc.custom || {};
2584
+ var custom = arc && arc.custom || {};
2593
2585
  var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
2594
2586
  var arcOpts = chart.options.elements.arc;
2595
2587
  var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
@@ -2662,7 +2654,7 @@ module.exports = function(Chart) {
2662
2654
  linkScales: helpers.noop,
2663
2655
 
2664
2656
  // Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
2665
- getRingIndex: function getRingIndex(datasetIndex) {
2657
+ getRingIndex: function(datasetIndex) {
2666
2658
  var ringIndex = 0;
2667
2659
 
2668
2660
  for (var j = 0; j < datasetIndex; ++j) {
@@ -2674,7 +2666,7 @@ module.exports = function(Chart) {
2674
2666
  return ringIndex;
2675
2667
  },
2676
2668
 
2677
- update: function update(reset) {
2669
+ update: function(reset) {
2678
2670
  var me = this;
2679
2671
  var chart = me.chart,
2680
2672
  chartArea = chart.chartArea,
@@ -2709,8 +2701,9 @@ module.exports = function(Chart) {
2709
2701
  minSize = Math.min(availableWidth / size.width, availableHeight / size.height);
2710
2702
  offset = {x: (max.x + min.x) * -0.5, y: (max.y + min.y) * -0.5};
2711
2703
  }
2704
+ chart.borderWidth = me.getMaxBorderWidth(meta.data);
2712
2705
 
2713
- chart.outerRadius = Math.max(minSize / 2, 0);
2706
+ chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);
2714
2707
  chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 1, 0);
2715
2708
  chart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();
2716
2709
  chart.offsetX = offset.x * chart.outerRadius;
@@ -2732,7 +2725,6 @@ module.exports = function(Chart) {
2732
2725
  chartArea = chart.chartArea,
2733
2726
  opts = chart.options,
2734
2727
  animationOpts = opts.animation,
2735
- arcOpts = opts.elements.arc,
2736
2728
  centerX = (chartArea.left + chartArea.right) / 2,
2737
2729
  centerY = (chartArea.top + chartArea.bottom) / 2,
2738
2730
  startAngle = opts.rotation, // non reset case handled later
@@ -2741,7 +2733,6 @@ module.exports = function(Chart) {
2741
2733
  circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)),
2742
2734
  innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius,
2743
2735
  outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius,
2744
- custom = arc.custom || {},
2745
2736
  valueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
2746
2737
 
2747
2738
  helpers.extend(arc, {
@@ -2797,6 +2788,10 @@ module.exports = function(Chart) {
2797
2788
  }
2798
2789
  });
2799
2790
 
2791
+ /*if (total === 0) {
2792
+ total = NaN;
2793
+ }*/
2794
+
2800
2795
  return total;
2801
2796
  },
2802
2797
 
@@ -2807,7 +2802,25 @@ module.exports = function(Chart) {
2807
2802
  } else {
2808
2803
  return 0;
2809
2804
  }
2810
- }
2805
+ },
2806
+
2807
+ //gets the max border or hover width to properly scale pie charts
2808
+ getMaxBorderWidth: function (elements) {
2809
+ var max = 0,
2810
+ index = this.index,
2811
+ length = elements.length,
2812
+ borderWidth,
2813
+ hoverWidth;
2814
+
2815
+ for (var i = 0; i < length; i++) {
2816
+ borderWidth = elements[i]._model ? elements[i]._model.borderWidth : 0;
2817
+ hoverWidth = elements[i]._chart ? elements[i]._chart.config.data.datasets[index].hoverBorderWidth : 0;
2818
+
2819
+ max = borderWidth > max ? borderWidth : max;
2820
+ max = hoverWidth > max ? hoverWidth : max;
2821
+ }
2822
+ return max;
2823
+ }
2811
2824
  });
2812
2825
  };
2813
2826
 
@@ -2820,6 +2833,7 @@ module.exports = function(Chart) {
2820
2833
 
2821
2834
  Chart.defaults.line = {
2822
2835
  showLines: true,
2836
+ spanGaps: false,
2823
2837
 
2824
2838
  hover: {
2825
2839
  mode: "label"
@@ -2860,7 +2874,7 @@ module.exports = function(Chart) {
2860
2874
  }
2861
2875
  },
2862
2876
 
2863
- update: function update(reset) {
2877
+ update: function(reset) {
2864
2878
  var me = this;
2865
2879
  var meta = me.getMeta();
2866
2880
  var line = meta.dataset;
@@ -2892,7 +2906,7 @@ module.exports = function(Chart) {
2892
2906
  // The default behavior of lines is to break at null values, according
2893
2907
  // to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158
2894
2908
  // This option gives linse the ability to span gaps
2895
- spanGaps: dataset.spanGaps ? dataset.spanGaps : false,
2909
+ spanGaps: dataset.spanGaps ? dataset.spanGaps : options.spanGaps,
2896
2910
  tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension),
2897
2911
  backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor),
2898
2912
  borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth),
@@ -2902,6 +2916,7 @@ module.exports = function(Chart) {
2902
2916
  borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset),
2903
2917
  borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle),
2904
2918
  fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill),
2919
+ steppedLine: custom.steppedLine ? custom.steppedLine : helpers.getValueOrDefault(dataset.steppedLine, lineElementOptions.stepped),
2905
2920
  // Scale
2906
2921
  scaleTop: scale.top,
2907
2922
  scaleBottom: scale.bottom,
@@ -2994,8 +3009,8 @@ module.exports = function(Chart) {
2994
3009
  dataset.pointHitRadius = dataset.hitRadius;
2995
3010
  }
2996
3011
 
2997
- x = xScale.getPixelForValue(value, index, datasetIndex, me.chart.isCombo);
2998
- y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex, me.chart.isCombo);
3012
+ x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex, me.chart.isCombo);
3013
+ y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
2999
3014
 
3000
3015
  // Utility
3001
3016
  point._xScale = xScale;
@@ -3015,12 +3030,13 @@ module.exports = function(Chart) {
3015
3030
  borderColor: me.getPointBorderColor(point, index),
3016
3031
  borderWidth: me.getPointBorderWidth(point, index),
3017
3032
  tension: meta.dataset._model ? meta.dataset._model.tension : 0,
3033
+ steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false,
3018
3034
  // Tooltip
3019
3035
  hitRadius: custom.hitRadius || helpers.getValueAtIndexOrDefault(dataset.pointHitRadius, index, pointOptions.hitRadius)
3020
3036
  };
3021
3037
  },
3022
3038
 
3023
- calculatePointY: function(value, index, datasetIndex, isCombo) {
3039
+ calculatePointY: function(value, index, datasetIndex) {
3024
3040
  var me = this;
3025
3041
  var chart = me.chart;
3026
3042
  var meta = me.getMeta();
@@ -3033,19 +3049,21 @@ module.exports = function(Chart) {
3033
3049
  for (i = 0; i < datasetIndex; i++) {
3034
3050
  ds = chart.data.datasets[i];
3035
3051
  dsMeta = chart.getDatasetMeta(i);
3036
- if (dsMeta.type === 'line' && chart.isDatasetVisible(i)) {
3037
- if (ds.data[index] < 0) {
3038
- sumNeg += ds.data[index] || 0;
3052
+ if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
3053
+ var stackedRightValue = Number(yScale.getRightValue(ds.data[index]));
3054
+ if (stackedRightValue < 0) {
3055
+ sumNeg += stackedRightValue || 0;
3039
3056
  } else {
3040
- sumPos += ds.data[index] || 0;
3057
+ sumPos += stackedRightValue || 0;
3041
3058
  }
3042
3059
  }
3043
3060
  }
3044
3061
 
3045
- if (value < 0) {
3046
- return yScale.getPixelForValue(sumNeg + value);
3062
+ var rightValue = Number(yScale.getRightValue(value));
3063
+ if (rightValue < 0) {
3064
+ return yScale.getPixelForValue(sumNeg + rightValue);
3047
3065
  } else {
3048
- return yScale.getPixelForValue(sumPos + value);
3066
+ return yScale.getPixelForValue(sumPos + rightValue);
3049
3067
  }
3050
3068
  }
3051
3069
 
@@ -3053,11 +3071,19 @@ module.exports = function(Chart) {
3053
3071
  },
3054
3072
 
3055
3073
  updateBezierControlPoints: function() {
3056
- var meta = this.getMeta();
3057
- var area = this.chart.chartArea;
3058
- var points = meta.data || [];
3074
+ var me = this;
3075
+ var meta = me.getMeta();
3076
+ var area = me.chart.chartArea;
3077
+
3078
+ // only consider points that are drawn in case the spanGaps option is ued
3079
+ var points = (meta.data || []).filter(function(pt) { return !pt._model.skip; });
3059
3080
  var i, ilen, point, model, controlPoints;
3060
3081
 
3082
+ var needToCap = me.chart.options.elements.line.capBezierPoints;
3083
+ function capIfNecessary(pt, min, max) {
3084
+ return needToCap ? Math.max(Math.min(pt, max), min) : pt;
3085
+ }
3086
+
3061
3087
  for (i=0, ilen=points.length; i<ilen; ++i) {
3062
3088
  point = points[i];
3063
3089
  model = point._model;
@@ -3068,10 +3094,10 @@ module.exports = function(Chart) {
3068
3094
  meta.dataset._model.tension
3069
3095
  );
3070
3096
 
3071
- model.controlPointPreviousX = controlPoints.previous.x;
3072
- model.controlPointPreviousY = controlPoints.previous.y;
3073
- model.controlPointNextX = controlPoints.next.x;
3074
- model.controlPointNextY = controlPoints.next.y;
3097
+ model.controlPointPreviousX = capIfNecessary(controlPoints.previous.x, area.left, area.right);
3098
+ model.controlPointPreviousY = capIfNecessary(controlPoints.previous.y, area.top, area.bottom);
3099
+ model.controlPointNextX = capIfNecessary(controlPoints.next.x, area.left, area.right);
3100
+ model.controlPointNextY = capIfNecessary(controlPoints.next.y, area.top, area.bottom);
3075
3101
  }
3076
3102
  },
3077
3103
 
@@ -3142,7 +3168,10 @@ module.exports = function(Chart) {
3142
3168
 
3143
3169
  scale: {
3144
3170
  type: "radialLinear",
3145
- lineArc: true // so that lines are circular
3171
+ lineArc: true, // so that lines are circular
3172
+ ticks: {
3173
+ beginAtZero: true
3174
+ }
3146
3175
  },
3147
3176
 
3148
3177
  //Boolean - Whether to animate the rotation of the chart
@@ -3151,6 +3180,7 @@ module.exports = function(Chart) {
3151
3180
  animateScale: true
3152
3181
  },
3153
3182
 
3183
+ startAngle: -0.5 * Math.PI,
3154
3184
  aspectRatio: 1,
3155
3185
  legendCallback: function(chart) {
3156
3186
  var text = [];
@@ -3239,7 +3269,7 @@ module.exports = function(Chart) {
3239
3269
 
3240
3270
  linkScales: helpers.noop,
3241
3271
 
3242
- update: function update(reset) {
3272
+ update: function(reset) {
3243
3273
  var me = this;
3244
3274
  var chart = me.chart;
3245
3275
  var chartArea = chart.chartArea;
@@ -3264,19 +3294,16 @@ module.exports = function(Chart) {
3264
3294
  updateElement: function(arc, index, reset) {
3265
3295
  var me = this;
3266
3296
  var chart = me.chart;
3267
- var chartArea = chart.chartArea;
3268
3297
  var dataset = me.getDataset();
3269
3298
  var opts = chart.options;
3270
3299
  var animationOpts = opts.animation;
3271
- var arcOpts = opts.elements.arc;
3272
- var custom = arc.custom || {};
3273
3300
  var scale = chart.scale;
3274
3301
  var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault;
3275
3302
  var labels = chart.data.labels;
3276
3303
 
3277
3304
  var circumference = me.calculateCircumference(dataset.data[index]);
3278
- var centerX = (chartArea.left + chartArea.right) / 2;
3279
- var centerY = (chartArea.top + chartArea.bottom) / 2;
3305
+ var centerX = scale.xCenter;
3306
+ var centerY = scale.yCenter;
3280
3307
 
3281
3308
  // If there is NaN data before us, we need to calculate the starting angle correctly.
3282
3309
  // We could be way more efficient here, but its unlikely that the polar area chart will have a lot of data
@@ -3288,9 +3315,10 @@ module.exports = function(Chart) {
3288
3315
  }
3289
3316
  }
3290
3317
 
3291
- var negHalfPI = -0.5 * Math.PI;
3318
+ //var negHalfPI = -0.5 * Math.PI;
3319
+ var datasetStartAngle = opts.startAngle;
3292
3320
  var distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
3293
- var startAngle = (negHalfPI) + (circumference * visibleCount);
3321
+ var startAngle = datasetStartAngle + (circumference * visibleCount);
3294
3322
  var endAngle = startAngle + (arc.hidden ? 0 : circumference);
3295
3323
 
3296
3324
  var resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);
@@ -3307,8 +3335,8 @@ module.exports = function(Chart) {
3307
3335
  y: centerY,
3308
3336
  innerRadius: 0,
3309
3337
  outerRadius: reset ? resetRadius : distance,
3310
- startAngle: reset && animationOpts.animateRotate ? negHalfPI : startAngle,
3311
- endAngle: reset && animationOpts.animateRotate ? negHalfPI : endAngle,
3338
+ startAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,
3339
+ endAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,
3312
3340
  label: getValueAtIndexOrDefault(labels, index, labels[index])
3313
3341
  }
3314
3342
  });
@@ -3381,7 +3409,7 @@ module.exports = function(Chart) {
3381
3409
  this.updateBezierControlPoints();
3382
3410
  },
3383
3411
 
3384
- update: function update(reset) {
3412
+ update: function(reset) {
3385
3413
  var me = this;
3386
3414
  var meta = me.getMeta();
3387
3415
  var line = meta.dataset;
@@ -3497,7 +3525,7 @@ module.exports = function(Chart) {
3497
3525
  var easingDecimal = ease || 1;
3498
3526
 
3499
3527
  // Transition Point Locations
3500
- helpers.each(meta.data, function(point, index) {
3528
+ helpers.each(meta.data, function(point) {
3501
3529
  point.transition(easingDecimal);
3502
3530
  });
3503
3531
 
@@ -3673,6 +3701,111 @@ module.exports = function(Chart) {
3673
3701
  },{}],22:[function(require,module,exports){
3674
3702
  "use strict";
3675
3703
 
3704
+ module.exports = function(Chart) {
3705
+ // Global Chart canvas helpers object for drawing items to canvas
3706
+ var helpers = Chart.canvasHelpers = {};
3707
+
3708
+ helpers.drawPoint = function(ctx, pointStyle, radius, x, y) {
3709
+ var type, edgeLength, xOffset, yOffset, height, size;
3710
+
3711
+ if (typeof pointStyle === 'object') {
3712
+ type = pointStyle.toString();
3713
+ if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
3714
+ ctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2);
3715
+ return;
3716
+ }
3717
+ }
3718
+
3719
+ if (isNaN(radius) || radius <= 0) {
3720
+ return;
3721
+ }
3722
+
3723
+ switch (pointStyle) {
3724
+ // Default includes circle
3725
+ default:
3726
+ ctx.beginPath();
3727
+ ctx.arc(x, y, radius, 0, Math.PI * 2);
3728
+ ctx.closePath();
3729
+ ctx.fill();
3730
+ break;
3731
+ case 'triangle':
3732
+ ctx.beginPath();
3733
+ edgeLength = 3 * radius / Math.sqrt(3);
3734
+ height = edgeLength * Math.sqrt(3) / 2;
3735
+ ctx.moveTo(x - edgeLength / 2, y + height / 3);
3736
+ ctx.lineTo(x + edgeLength / 2, y + height / 3);
3737
+ ctx.lineTo(x, y - 2 * height / 3);
3738
+ ctx.closePath();
3739
+ ctx.fill();
3740
+ break;
3741
+ case 'rect':
3742
+ size = 1 / Math.SQRT2 * radius;
3743
+ ctx.beginPath();
3744
+ ctx.fillRect(x - size, y - size, 2 * size, 2 * size);
3745
+ ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);
3746
+ break;
3747
+ case 'rectRot':
3748
+ size = 1 / Math.SQRT2 * radius;
3749
+ ctx.beginPath();
3750
+ ctx.moveTo(x - size, y);
3751
+ ctx.lineTo(x, y + size);
3752
+ ctx.lineTo(x + size, y);
3753
+ ctx.lineTo(x, y - size);
3754
+ ctx.closePath();
3755
+ ctx.fill();
3756
+ break;
3757
+ case 'cross':
3758
+ ctx.beginPath();
3759
+ ctx.moveTo(x, y + radius);
3760
+ ctx.lineTo(x, y - radius);
3761
+ ctx.moveTo(x - radius, y);
3762
+ ctx.lineTo(x + radius, y);
3763
+ ctx.closePath();
3764
+ break;
3765
+ case 'crossRot':
3766
+ ctx.beginPath();
3767
+ xOffset = Math.cos(Math.PI / 4) * radius;
3768
+ yOffset = Math.sin(Math.PI / 4) * radius;
3769
+ ctx.moveTo(x - xOffset, y - yOffset);
3770
+ ctx.lineTo(x + xOffset, y + yOffset);
3771
+ ctx.moveTo(x - xOffset, y + yOffset);
3772
+ ctx.lineTo(x + xOffset, y - yOffset);
3773
+ ctx.closePath();
3774
+ break;
3775
+ case 'star':
3776
+ ctx.beginPath();
3777
+ ctx.moveTo(x, y + radius);
3778
+ ctx.lineTo(x, y - radius);
3779
+ ctx.moveTo(x - radius, y);
3780
+ ctx.lineTo(x + radius, y);
3781
+ xOffset = Math.cos(Math.PI / 4) * radius;
3782
+ yOffset = Math.sin(Math.PI / 4) * radius;
3783
+ ctx.moveTo(x - xOffset, y - yOffset);
3784
+ ctx.lineTo(x + xOffset, y + yOffset);
3785
+ ctx.moveTo(x - xOffset, y + yOffset);
3786
+ ctx.lineTo(x + xOffset, y - yOffset);
3787
+ ctx.closePath();
3788
+ break;
3789
+ case 'line':
3790
+ ctx.beginPath();
3791
+ ctx.moveTo(x - radius, y);
3792
+ ctx.lineTo(x + radius, y);
3793
+ ctx.closePath();
3794
+ break;
3795
+ case 'dash':
3796
+ ctx.beginPath();
3797
+ ctx.moveTo(x, y);
3798
+ ctx.lineTo(x + radius, y);
3799
+ ctx.closePath();
3800
+ break;
3801
+ }
3802
+
3803
+ ctx.stroke();
3804
+ };
3805
+ };
3806
+ },{}],23:[function(require,module,exports){
3807
+ "use strict";
3808
+
3676
3809
  module.exports = function(Chart) {
3677
3810
 
3678
3811
  var helpers = Chart.helpers;
@@ -3718,7 +3851,7 @@ module.exports = function(Chart) {
3718
3851
 
3719
3852
  helpers.extend(Chart.Controller.prototype, /** @lends Chart.Controller */ {
3720
3853
 
3721
- initialize: function initialize() {
3854
+ initialize: function() {
3722
3855
  var me = this;
3723
3856
  // Before init plugin notification
3724
3857
  Chart.plugins.notify('beforeInit', [me]);
@@ -3741,12 +3874,12 @@ module.exports = function(Chart) {
3741
3874
  return me;
3742
3875
  },
3743
3876
 
3744
- clear: function clear() {
3877
+ clear: function() {
3745
3878
  helpers.clear(this.chart);
3746
3879
  return this;
3747
3880
  },
3748
3881
 
3749
- stop: function stop() {
3882
+ stop: function() {
3750
3883
  // Stops any current animation loop occuring
3751
3884
  Chart.animationService.cancelAnimation(this);
3752
3885
  return this;
@@ -3788,7 +3921,7 @@ module.exports = function(Chart) {
3788
3921
  return me;
3789
3922
  },
3790
3923
 
3791
- ensureScalesHaveIDs: function ensureScalesHaveIDs() {
3924
+ ensureScalesHaveIDs: function() {
3792
3925
  var options = this.options;
3793
3926
  var scalesOptions = options.scales || {};
3794
3927
  var scaleOptions = options.scale;
@@ -3809,7 +3942,7 @@ module.exports = function(Chart) {
3809
3942
  /**
3810
3943
  * Builds a map of scale ID to scale object for future lookup.
3811
3944
  */
3812
- buildScales: function buildScales() {
3945
+ buildScales: function() {
3813
3946
  var me = this;
3814
3947
  var options = me.options;
3815
3948
  var scales = me.scales = {};
@@ -3827,7 +3960,7 @@ module.exports = function(Chart) {
3827
3960
  items.push({ options: options.scale, dtype: 'radialLinear', isDefault: true });
3828
3961
  }
3829
3962
 
3830
- helpers.each(items, function(item, index) {
3963
+ helpers.each(items, function(item) {
3831
3964
  var scaleOptions = item.options;
3832
3965
  var scaleType = helpers.getValueOrDefault(scaleOptions.type, item.dtype);
3833
3966
  var scaleClass = Chart.scaleService.getScaleConstructor(scaleType);
@@ -3859,7 +3992,7 @@ module.exports = function(Chart) {
3859
3992
  Chart.layoutService.update(this, this.chart.width, this.chart.height);
3860
3993
  },
3861
3994
 
3862
- buildOrUpdateControllers: function buildOrUpdateControllers() {
3995
+ buildOrUpdateControllers: function() {
3863
3996
  var me = this;
3864
3997
  var types = [];
3865
3998
  var newControllers = [];
@@ -3892,7 +4025,7 @@ module.exports = function(Chart) {
3892
4025
  return newControllers;
3893
4026
  },
3894
4027
 
3895
- resetElements: function resetElements() {
4028
+ resetElements: function() {
3896
4029
  var me = this;
3897
4030
  helpers.each(me.data.datasets, function(dataset, datasetIndex) {
3898
4031
  me.getDatasetMeta(datasetIndex).controller.reset();
@@ -4048,7 +4181,7 @@ module.exports = function(Chart) {
4048
4181
  helpers.each(me.data.datasets, function(dataset, datasetIndex) {
4049
4182
  if (me.isDatasetVisible(datasetIndex)) {
4050
4183
  var meta = me.getDatasetMeta(datasetIndex);
4051
- helpers.each(meta.data, function(element, index) {
4184
+ helpers.each(meta.data, function(element) {
4052
4185
  if (element.inRange(eventPosition.x, eventPosition.y)) {
4053
4186
  elementsArray.push(element);
4054
4187
  return elementsArray;
@@ -4057,7 +4190,7 @@ module.exports = function(Chart) {
4057
4190
  }
4058
4191
  });
4059
4192
 
4060
- return elementsArray;
4193
+ return elementsArray.slice(0, 1);
4061
4194
  },
4062
4195
 
4063
4196
  getElementsAtEvent: function(e) {
@@ -4084,10 +4217,52 @@ module.exports = function(Chart) {
4084
4217
  return elementsArray;
4085
4218
  }
4086
4219
 
4220
+ helpers.each(me.data.datasets, function(dataset, datasetIndex) {
4221
+ if (me.isDatasetVisible(datasetIndex)) {
4222
+ var meta = me.getDatasetMeta(datasetIndex),
4223
+ element = meta.data[found._index];
4224
+ if(element && !element._view.skip){
4225
+ elementsArray.push(element);
4226
+ }
4227
+ }
4228
+ }, me);
4229
+
4230
+ return elementsArray;
4231
+ },
4232
+
4233
+ getElementsAtXAxis: function(e) {
4234
+ var me = this;
4235
+ var eventPosition = helpers.getRelativePosition(e, me.chart);
4236
+ var elementsArray = [];
4237
+
4238
+ var found = (function() {
4239
+ if (me.data.datasets) {
4240
+ for (var i = 0; i < me.data.datasets.length; i++) {
4241
+ var meta = me.getDatasetMeta(i);
4242
+ if (me.isDatasetVisible(i)) {
4243
+ for (var j = 0; j < meta.data.length; j++) {
4244
+ if (meta.data[j].inLabelRange(eventPosition.x, eventPosition.y)) {
4245
+ return meta.data[j];
4246
+ }
4247
+ }
4248
+ }
4249
+ }
4250
+ }
4251
+ }).call(me);
4252
+
4253
+ if (!found) {
4254
+ return elementsArray;
4255
+ }
4256
+
4087
4257
  helpers.each(me.data.datasets, function(dataset, datasetIndex) {
4088
4258
  if (me.isDatasetVisible(datasetIndex)) {
4089
4259
  var meta = me.getDatasetMeta(datasetIndex);
4090
- elementsArray.push(meta.data[found._index]);
4260
+ var index = helpers.findIndex(meta.data, function (it) {
4261
+ return found._model.x === it._model.x;
4262
+ });
4263
+ if(index !== -1 && !meta.data[index]._view.skip) {
4264
+ elementsArray.push(meta.data[index]);
4265
+ }
4091
4266
  }
4092
4267
  }, me);
4093
4268
 
@@ -4103,6 +4278,8 @@ module.exports = function(Chart) {
4103
4278
  return me.getElementsAtEvent(e);
4104
4279
  case 'dataset':
4105
4280
  return me.getDatasetAtEvent(e);
4281
+ case 'x-axis':
4282
+ return me.getElementsAtXAxis(e);
4106
4283
  default:
4107
4284
  return e;
4108
4285
  }
@@ -4159,11 +4336,11 @@ module.exports = function(Chart) {
4159
4336
  return typeof meta.hidden === 'boolean'? !meta.hidden : !this.data.datasets[datasetIndex].hidden;
4160
4337
  },
4161
4338
 
4162
- generateLegend: function generateLegend() {
4339
+ generateLegend: function() {
4163
4340
  return this.options.legendCallback(this);
4164
4341
  },
4165
4342
 
4166
- destroy: function destroy() {
4343
+ destroy: function() {
4167
4344
  var me = this;
4168
4345
  me.stop();
4169
4346
  me.clear();
@@ -4189,11 +4366,11 @@ module.exports = function(Chart) {
4189
4366
  delete Chart.instances[me.id];
4190
4367
  },
4191
4368
 
4192
- toBase64Image: function toBase64Image() {
4369
+ toBase64Image: function() {
4193
4370
  return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);
4194
4371
  },
4195
4372
 
4196
- initToolTip: function initToolTip() {
4373
+ initToolTip: function() {
4197
4374
  var me = this;
4198
4375
  me.tooltip = new Chart.Tooltip({
4199
4376
  _chart: me.chart,
@@ -4203,7 +4380,7 @@ module.exports = function(Chart) {
4203
4380
  }, me);
4204
4381
  },
4205
4382
 
4206
- bindEvents: function bindEvents() {
4383
+ bindEvents: function() {
4207
4384
  var me = this;
4208
4385
  helpers.bindEvents(me, me.options.events, function(evt) {
4209
4386
  me.eventHandler(evt);
@@ -4220,6 +4397,7 @@ module.exports = function(Chart) {
4220
4397
  break;
4221
4398
  case 'label':
4222
4399
  case 'dataset':
4400
+ case 'x-axis':
4223
4401
  // elements = elements;
4224
4402
  break;
4225
4403
  default:
@@ -4313,7 +4491,7 @@ module.exports = function(Chart) {
4313
4491
  });
4314
4492
  };
4315
4493
 
4316
- },{}],23:[function(require,module,exports){
4494
+ },{}],24:[function(require,module,exports){
4317
4495
  "use strict";
4318
4496
 
4319
4497
  module.exports = function(Chart) {
@@ -4421,7 +4599,7 @@ module.exports = function(Chart) {
4421
4599
  me.updateElement(element, index, true);
4422
4600
  },
4423
4601
 
4424
- buildOrUpdateElements: function buildOrUpdateElements() {
4602
+ buildOrUpdateElements: function() {
4425
4603
  // Handle the number of data points changing
4426
4604
  var meta = this.getMeta(),
4427
4605
  md = meta.data,
@@ -4444,7 +4622,7 @@ module.exports = function(Chart) {
4444
4622
 
4445
4623
  draw: function(ease) {
4446
4624
  var easingDecimal = ease || 1;
4447
- helpers.each(this.getMeta().data, function(element, index) {
4625
+ helpers.each(this.getMeta().data, function(element) {
4448
4626
  element.transition(easingDecimal).draw();
4449
4627
  });
4450
4628
  },
@@ -4454,7 +4632,6 @@ module.exports = function(Chart) {
4454
4632
  index = element._index,
4455
4633
  custom = element.custom || {},
4456
4634
  valueOrDefault = helpers.getValueAtIndexOrDefault,
4457
- color = helpers.color,
4458
4635
  model = element._model;
4459
4636
 
4460
4637
  model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor);
@@ -4467,7 +4644,6 @@ module.exports = function(Chart) {
4467
4644
  index = element._index,
4468
4645
  custom = element.custom || {},
4469
4646
  valueOrDefault = helpers.getValueAtIndexOrDefault,
4470
- color = helpers.color,
4471
4647
  getHoverColor = helpers.getHoverColor,
4472
4648
  model = element._model;
4473
4649
 
@@ -4475,11 +4651,13 @@ module.exports = function(Chart) {
4475
4651
  model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor));
4476
4652
  model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth);
4477
4653
  }
4478
- });
4654
+
4655
+ });
4656
+
4479
4657
 
4480
4658
  Chart.DatasetController.extend = helpers.inherits;
4481
4659
  };
4482
- },{}],24:[function(require,module,exports){
4660
+ },{}],25:[function(require,module,exports){
4483
4661
  "use strict";
4484
4662
 
4485
4663
  module.exports = function(Chart) {
@@ -4585,7 +4763,7 @@ module.exports = function(Chart) {
4585
4763
 
4586
4764
  };
4587
4765
 
4588
- },{}],25:[function(require,module,exports){
4766
+ },{}],26:[function(require,module,exports){
4589
4767
  /*global window: false */
4590
4768
  /*global document: false */
4591
4769
  "use strict";
@@ -5534,7 +5712,7 @@ module.exports = function(Chart) {
5534
5712
  };
5535
5713
  };
5536
5714
 
5537
- },{"3":3}],26:[function(require,module,exports){
5715
+ },{"3":3}],27:[function(require,module,exports){
5538
5716
  "use strict";
5539
5717
 
5540
5718
  module.exports = function() {
@@ -5543,7 +5721,11 @@ module.exports = function() {
5543
5721
  var Chart = function(context, config) {
5544
5722
  var me = this;
5545
5723
  var helpers = Chart.helpers;
5546
- me.config = config;
5724
+ me.config = config || {
5725
+ data: {
5726
+ datasets: []
5727
+ }
5728
+ };
5547
5729
 
5548
5730
  // Support a jQuery'd canvas element
5549
5731
  if (context.length && context[0].getContext) {
@@ -5582,10 +5764,7 @@ module.exports = function() {
5582
5764
 
5583
5765
  // High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
5584
5766
  helpers.retinaScale(me);
5585
-
5586
- if (config) {
5587
- me.controller = new Chart.Controller(me);
5588
- }
5767
+ me.controller = new Chart.Controller(me);
5589
5768
 
5590
5769
  // Always bind this so that if the responsive state changes we still work
5591
5770
  helpers.addResizeListener(context.canvas.parentNode, function() {
@@ -5645,7 +5824,7 @@ module.exports = function() {
5645
5824
 
5646
5825
  };
5647
5826
 
5648
- },{}],27:[function(require,module,exports){
5827
+ },{}],28:[function(require,module,exports){
5649
5828
  "use strict";
5650
5829
 
5651
5830
  module.exports = function(Chart) {
@@ -5915,8 +6094,6 @@ module.exports = function(Chart) {
5915
6094
  // Step 7 - Position the boxes
5916
6095
  var left = xPadding;
5917
6096
  var top = yPadding;
5918
- var right = 0;
5919
- var bottom = 0;
5920
6097
 
5921
6098
  helpers.each(leftBoxes.concat(topBoxes), placeBox);
5922
6099
 
@@ -5970,7 +6147,7 @@ module.exports = function(Chart) {
5970
6147
  };
5971
6148
  };
5972
6149
 
5973
- },{}],28:[function(require,module,exports){
6150
+ },{}],29:[function(require,module,exports){
5974
6151
  "use strict";
5975
6152
 
5976
6153
  module.exports = function(Chart) {
@@ -6025,6 +6202,7 @@ module.exports = function(Chart) {
6025
6202
  lineJoin: dataset.borderJoinStyle,
6026
6203
  lineWidth: dataset.borderWidth,
6027
6204
  strokeStyle: dataset.borderColor,
6205
+ pointStyle: dataset.pointStyle,
6028
6206
 
6029
6207
  // Below is extra data used for toggling the datasets
6030
6208
  datasetIndex: i
@@ -6174,7 +6352,11 @@ module.exports = function(Chart) {
6174
6352
  ctx.textBaseline = 'top';
6175
6353
 
6176
6354
  helpers.each(me.legendItems, function(legendItem, i) {
6177
- var width = labelOpts.boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
6355
+ var boxWidth = labelOpts.usePointStyle ?
6356
+ fontSize * Math.sqrt(2) :
6357
+ labelOpts.boxWidth;
6358
+
6359
+ var width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
6178
6360
  if (lineWidths[lineWidths.length - 1] + width + labelOpts.padding >= me.width) {
6179
6361
  totalHeight += fontSize + (labelOpts.padding);
6180
6362
  lineWidths[lineWidths.length] = me.left;
@@ -6202,7 +6384,11 @@ module.exports = function(Chart) {
6202
6384
  var itemHeight = fontSize + vPadding;
6203
6385
 
6204
6386
  helpers.each(me.legendItems, function(legendItem, i) {
6205
- var itemWidth = labelOpts.boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
6387
+ // If usePointStyle is set, multiple boxWidth by 2 since it represents
6388
+ // the radius and not truly the width
6389
+ var boxWidth = labelOpts.usePointStyle ? 2 * labelOpts.boxWidth : labelOpts.boxWidth;
6390
+
6391
+ var itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
6206
6392
 
6207
6393
  // If too tall, go to new column
6208
6394
  if (currentColHeight + itemHeight > minSize.height) {
@@ -6250,7 +6436,6 @@ module.exports = function(Chart) {
6250
6436
  var globalDefault = Chart.defaults.global,
6251
6437
  lineDefault = globalDefault.elements.line,
6252
6438
  legendWidth = me.width,
6253
- legendHeight = me.height,
6254
6439
  lineWidths = me.lineWidths;
6255
6440
 
6256
6441
  if (opts.display) {
@@ -6276,6 +6461,10 @@ module.exports = function(Chart) {
6276
6461
 
6277
6462
  // current position
6278
6463
  var drawLegendBox = function(x, y, legendItem) {
6464
+ if (isNaN(boxWidth) || boxWidth <= 0) {
6465
+ return;
6466
+ }
6467
+
6279
6468
  // Set the ctx for the box
6280
6469
  ctx.save();
6281
6470
 
@@ -6291,9 +6480,22 @@ module.exports = function(Chart) {
6291
6480
  ctx.setLineDash(itemOrDefault(legendItem.lineDash, lineDefault.borderDash));
6292
6481
  }
6293
6482
 
6294
- // Draw the box
6295
- ctx.strokeRect(x, y, boxWidth, fontSize);
6296
- ctx.fillRect(x, y, boxWidth, fontSize);
6483
+ if (opts.labels && opts.labels.usePointStyle) {
6484
+ // Recalulate x and y for drawPoint() because its expecting
6485
+ // x and y to be center of figure (instead of top left)
6486
+ var radius = fontSize * Math.SQRT2 / 2;
6487
+ var offSet = radius / Math.SQRT2;
6488
+ var centerX = x + offSet;
6489
+ var centerY = y + offSet;
6490
+
6491
+ // Draw pointStyle as legend symbol
6492
+ Chart.canvasHelpers.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY);
6493
+ }
6494
+ else {
6495
+ // Draw box as legend symbol
6496
+ ctx.strokeRect(x, y, boxWidth, fontSize);
6497
+ ctx.fillRect(x, y, boxWidth, fontSize);
6498
+ }
6297
6499
 
6298
6500
  ctx.restore();
6299
6501
  };
@@ -6321,7 +6523,7 @@ module.exports = function(Chart) {
6321
6523
  } else {
6322
6524
  cursor = {
6323
6525
  x: me.left + labelOpts.padding,
6324
- y: me.top,
6526
+ y: me.top + labelOpts.padding,
6325
6527
  line: 0
6326
6528
  };
6327
6529
  }
@@ -6329,13 +6531,15 @@ module.exports = function(Chart) {
6329
6531
  var itemHeight = fontSize + labelOpts.padding;
6330
6532
  helpers.each(me.legendItems, function(legendItem, i) {
6331
6533
  var textWidth = ctx.measureText(legendItem.text).width,
6332
- width = boxWidth + (fontSize / 2) + textWidth,
6534
+ width = labelOpts.usePointStyle ?
6535
+ fontSize + (fontSize / 2) + textWidth :
6536
+ boxWidth + (fontSize / 2) + textWidth,
6333
6537
  x = cursor.x,
6334
6538
  y = cursor.y;
6335
6539
 
6336
6540
  if (isHorizontal) {
6337
6541
  if (x + width >= legendWidth) {
6338
- y = cursor.y += fontSize + (labelOpts.padding);
6542
+ y = cursor.y += itemHeight;
6339
6543
  cursor.line++;
6340
6544
  x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);
6341
6545
  }
@@ -6347,7 +6551,6 @@ module.exports = function(Chart) {
6347
6551
  }
6348
6552
  }
6349
6553
 
6350
-
6351
6554
  drawLegendBox(x, y, legendItem);
6352
6555
 
6353
6556
  hitboxes[i].left = x;
@@ -6411,7 +6614,7 @@ module.exports = function(Chart) {
6411
6614
  });
6412
6615
  };
6413
6616
 
6414
- },{}],29:[function(require,module,exports){
6617
+ },{}],30:[function(require,module,exports){
6415
6618
  "use strict";
6416
6619
 
6417
6620
  module.exports = function(Chart) {
@@ -6542,7 +6745,7 @@ module.exports = function(Chart) {
6542
6745
  Chart.pluginService = Chart.plugins;
6543
6746
  };
6544
6747
 
6545
- },{}],30:[function(require,module,exports){
6748
+ },{}],31:[function(require,module,exports){
6546
6749
  "use strict";
6547
6750
 
6548
6751
  module.exports = function(Chart) {
@@ -6829,9 +7032,6 @@ module.exports = function(Chart) {
6829
7032
  var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
6830
7033
 
6831
7034
  var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabelOpts.fontSize, globalDefaults.defaultFontSize);
6832
- var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabelOpts.fontStyle, globalDefaults.defaultFontStyle);
6833
- var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabelOpts.fontFamily, globalDefaults.defaultFontFamily);
6834
- var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily);
6835
7035
 
6836
7036
  var tickMarkLength = opts.gridLines.tickMarkLength;
6837
7037
 
@@ -6938,7 +7138,7 @@ module.exports = function(Chart) {
6938
7138
  },
6939
7139
 
6940
7140
  // Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not
6941
- getRightValue: function getRightValue(rawValue) {
7141
+ getRightValue: function(rawValue) {
6942
7142
  // Null and undefined values first
6943
7143
  if (rawValue === null || typeof(rawValue) === 'undefined') {
6944
7144
  return NaN;
@@ -6952,7 +7152,7 @@ module.exports = function(Chart) {
6952
7152
  if ((rawValue instanceof Date) || (rawValue.isValid)) {
6953
7153
  return rawValue;
6954
7154
  } else {
6955
- return getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);
7155
+ return this.getRightValue(this.isHorizontal() ? rawValue.x : rawValue.y);
6956
7156
  }
6957
7157
  }
6958
7158
 
@@ -7059,9 +7259,7 @@ module.exports = function(Chart) {
7059
7259
 
7060
7260
  var labelRotationRadians = helpers.toRadians(me.labelRotation);
7061
7261
  var cosRotation = Math.cos(labelRotationRadians);
7062
- var sinRotation = Math.sin(labelRotationRadians);
7063
7262
  var longestRotatedLabel = me.longestLabelWidth * cosRotation;
7064
- var rotatedLabelHeight = tickFontSize * sinRotation;
7065
7263
 
7066
7264
  // Make sure we draw text in the correct color and font
7067
7265
  context.fillStyle = tickFontColor;
@@ -7071,11 +7269,11 @@ module.exports = function(Chart) {
7071
7269
  if (isHorizontal) {
7072
7270
  skipRatio = false;
7073
7271
 
7074
- // Only calculate the skip ratio with the half width of longestRotateLabel if we got an actual rotation
7075
- // See #2584
7076
- if (isRotated) {
7077
- longestRotatedLabel /= 2;
7078
- }
7272
+ // Only calculate the skip ratio with the half width of longestRotateLabel if we got an actual rotation
7273
+ // See #2584
7274
+ if (isRotated) {
7275
+ longestRotatedLabel /= 2;
7276
+ }
7079
7277
 
7080
7278
  if ((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length > (me.width - (me.paddingLeft + me.paddingRight))) {
7081
7279
  skipRatio = 1 + Math.floor(((longestRotatedLabel + optionTicks.autoSkipPadding) * me.ticks.length) / (me.width - (me.paddingLeft + me.paddingRight)));
@@ -7298,7 +7496,7 @@ module.exports = function(Chart) {
7298
7496
  });
7299
7497
  };
7300
7498
 
7301
- },{}],31:[function(require,module,exports){
7499
+ },{}],32:[function(require,module,exports){
7302
7500
  "use strict";
7303
7501
 
7304
7502
  module.exports = function(Chart) {
@@ -7339,7 +7537,7 @@ module.exports = function(Chart) {
7339
7537
  }
7340
7538
  };
7341
7539
  };
7342
- },{}],32:[function(require,module,exports){
7540
+ },{}],33:[function(require,module,exports){
7343
7541
  "use strict";
7344
7542
 
7345
7543
  module.exports = function(Chart) {
@@ -7453,9 +7651,7 @@ module.exports = function(Chart) {
7453
7651
 
7454
7652
  beforeFit: noop,
7455
7653
  fit: function() {
7456
-
7457
7654
  var me = this,
7458
- ctx = me.ctx,
7459
7655
  valueOrDefault = helpers.getValueOrDefault,
7460
7656
  opts = me.options,
7461
7657
  globalDefaults = Chart.defaults.global,
@@ -7547,7 +7743,7 @@ module.exports = function(Chart) {
7547
7743
  });
7548
7744
  };
7549
7745
 
7550
- },{}],33:[function(require,module,exports){
7746
+ },{}],34:[function(require,module,exports){
7551
7747
  "use strict";
7552
7748
 
7553
7749
  module.exports = function(Chart) {
@@ -7666,9 +7862,11 @@ module.exports = function(Chart) {
7666
7862
 
7667
7863
  var x = 0,
7668
7864
  y = 0;
7669
- for (i = 0, len - xPositions.length; i < len; ++i) {
7670
- x += xPositions[i];
7671
- y += yPositions[i];
7865
+ for (i = 0; i < xPositions.length; ++i) {
7866
+ if (xPositions[ i ]) {
7867
+ x += xPositions[i];
7868
+ y += yPositions[i];
7869
+ }
7672
7870
  }
7673
7871
 
7674
7872
  return {
@@ -7706,8 +7904,8 @@ module.exports = function(Chart) {
7706
7904
  // Positioning
7707
7905
  xPadding: tooltipOpts.xPadding,
7708
7906
  yPadding: tooltipOpts.yPadding,
7709
- xAlign : tooltipOpts.yAlign,
7710
- yAlign : tooltipOpts.xAlign,
7907
+ xAlign : tooltipOpts.xAlign,
7908
+ yAlign : tooltipOpts.yAlign,
7711
7909
 
7712
7910
  // Body
7713
7911
  bodyFontColor: tooltipOpts.bodyFontColor,
@@ -7878,7 +8076,7 @@ module.exports = function(Chart) {
7878
8076
 
7879
8077
  return me;
7880
8078
  },
7881
- getTooltipSize: function getTooltipSize(vm) {
8079
+ getTooltipSize: function(vm) {
7882
8080
  var ctx = this._chart.ctx;
7883
8081
 
7884
8082
  var size = {
@@ -7941,7 +8139,7 @@ module.exports = function(Chart) {
7941
8139
 
7942
8140
  return size;
7943
8141
  },
7944
- determineAlignment: function determineAlignment(size) {
8142
+ determineAlignment: function(size) {
7945
8143
  var me = this;
7946
8144
  var model = me._model;
7947
8145
  var chart = me._chart;
@@ -8003,7 +8201,7 @@ module.exports = function(Chart) {
8003
8201
  }
8004
8202
  }
8005
8203
  },
8006
- getBackgroundPoint: function getBackgroundPoint(vm, size) {
8204
+ getBackgroundPoint: function(vm, size) {
8007
8205
  // Background Position
8008
8206
  var pt = {
8009
8207
  x: vm.x,
@@ -8048,7 +8246,7 @@ module.exports = function(Chart) {
8048
8246
 
8049
8247
  return pt;
8050
8248
  },
8051
- drawCaret: function drawCaret(tooltipPoint, size, opacity, caretPadding) {
8249
+ drawCaret: function(tooltipPoint, size, opacity) {
8052
8250
  var vm = this._view;
8053
8251
  var ctx = this._chart.ctx;
8054
8252
  var x1, x2, x3;
@@ -8112,7 +8310,7 @@ module.exports = function(Chart) {
8112
8310
  ctx.closePath();
8113
8311
  ctx.fill();
8114
8312
  },
8115
- drawTitle: function drawTitle(pt, vm, ctx, opacity) {
8313
+ drawTitle: function(pt, vm, ctx, opacity) {
8116
8314
  var title = vm.title;
8117
8315
 
8118
8316
  if (title.length) {
@@ -8137,7 +8335,7 @@ module.exports = function(Chart) {
8137
8335
  }
8138
8336
  }
8139
8337
  },
8140
- drawBody: function drawBody(pt, vm, ctx, opacity) {
8338
+ drawBody: function(pt, vm, ctx, opacity) {
8141
8339
  var bodyFontSize = vm.bodyFontSize;
8142
8340
  var bodySpacing = vm.bodySpacing;
8143
8341
  var body = vm.body;
@@ -8198,7 +8396,7 @@ module.exports = function(Chart) {
8198
8396
  helpers.each(vm.afterBody, fillLineOfText);
8199
8397
  pt.y -= bodySpacing; // Remove last body spacing
8200
8398
  },
8201
- drawFooter: function drawFooter(pt, vm, ctx, opacity) {
8399
+ drawFooter: function(pt, vm, ctx, opacity) {
8202
8400
  var footer = vm.footer;
8203
8401
 
8204
8402
  if (footer.length) {
@@ -8217,7 +8415,7 @@ module.exports = function(Chart) {
8217
8415
  });
8218
8416
  }
8219
8417
  },
8220
- draw: function draw() {
8418
+ draw: function() {
8221
8419
  var ctx = this._chart.ctx;
8222
8420
  var vm = this._view;
8223
8421
 
@@ -8242,7 +8440,7 @@ module.exports = function(Chart) {
8242
8440
  ctx.fill();
8243
8441
 
8244
8442
  // Draw Caret
8245
- this.drawCaret(pt, tooltipSize, opacity, vm.caretPadding);
8443
+ this.drawCaret(pt, tooltipSize, opacity);
8246
8444
 
8247
8445
  // Draw Title, Body, and Footer
8248
8446
  pt.x += vm.xPadding;
@@ -8261,10 +8459,10 @@ module.exports = function(Chart) {
8261
8459
  });
8262
8460
  };
8263
8461
 
8264
- },{}],34:[function(require,module,exports){
8462
+ },{}],35:[function(require,module,exports){
8265
8463
  "use strict";
8266
8464
 
8267
- module.exports = function(Chart, moment) {
8465
+ module.exports = function(Chart) {
8268
8466
 
8269
8467
  var helpers = Chart.helpers,
8270
8468
  globalOpts = Chart.defaults.global;
@@ -8356,7 +8554,7 @@ module.exports = function(Chart, moment) {
8356
8554
  });
8357
8555
  };
8358
8556
 
8359
- },{}],35:[function(require,module,exports){
8557
+ },{}],36:[function(require,module,exports){
8360
8558
  "use strict";
8361
8559
 
8362
8560
  module.exports = function(Chart) {
@@ -8373,108 +8571,110 @@ module.exports = function(Chart) {
8373
8571
  borderDash: [],
8374
8572
  borderDashOffset: 0.0,
8375
8573
  borderJoinStyle: 'miter',
8574
+ capBezierPoints: true,
8376
8575
  fill: true // do we fill in the area between the line and its base axis
8377
8576
  };
8378
8577
 
8379
8578
  Chart.elements.Line = Chart.Element.extend({
8380
- lineToNextPoint: function(previousPoint, point, nextPoint, skipHandler, previousSkipHandler) {
8381
- var me = this;
8382
- var ctx = me._chart.ctx;
8383
- var spanGaps = me._view ? me._view.spanGaps : false;
8384
-
8385
- if (point._view.skip && !spanGaps) {
8386
- skipHandler.call(me, previousPoint, point, nextPoint);
8387
- } else if (previousPoint._view.skip && !spanGaps) {
8388
- previousSkipHandler.call(me, previousPoint, point, nextPoint);
8389
- } else if (point._view.tension === 0) {
8390
- ctx.lineTo(point._view.x, point._view.y);
8391
- } else {
8392
- // Line between points
8393
- ctx.bezierCurveTo(
8394
- previousPoint._view.controlPointNextX,
8395
- previousPoint._view.controlPointNextY,
8396
- point._view.controlPointPreviousX,
8397
- point._view.controlPointPreviousY,
8398
- point._view.x,
8399
- point._view.y
8400
- );
8401
- }
8402
- },
8403
-
8404
8579
  draw: function() {
8405
8580
  var me = this;
8406
-
8407
8581
  var vm = me._view;
8582
+ var spanGaps = vm.spanGaps;
8583
+ var scaleZero = vm.scaleZero;
8584
+ var loop = me._loop;
8585
+
8408
8586
  var ctx = me._chart.ctx;
8409
- var first = me._children[0];
8410
- var last = me._children[me._children.length - 1];
8587
+ ctx.save();
8411
8588
 
8412
- function loopBackToStart(drawLineToCenter) {
8413
- if (!first._view.skip && !last._view.skip) {
8414
- // Draw a bezier line from last to first
8589
+ // Helper function to draw a line to a point
8590
+ function lineToPoint(previousPoint, point) {
8591
+ var vm = point._view;
8592
+ if (point._view.steppedLine === true) {
8593
+ ctx.lineTo(point._view.x, previousPoint._view.y);
8594
+ ctx.lineTo(point._view.x, point._view.y);
8595
+ } else if (point._view.tension === 0) {
8596
+ ctx.lineTo(vm.x, vm.y);
8597
+ } else {
8415
8598
  ctx.bezierCurveTo(
8416
- last._view.controlPointNextX,
8417
- last._view.controlPointNextY,
8418
- first._view.controlPointPreviousX,
8419
- first._view.controlPointPreviousY,
8420
- first._view.x,
8421
- first._view.y
8599
+ previousPoint._view.controlPointNextX,
8600
+ previousPoint._view.controlPointNextY,
8601
+ vm.controlPointPreviousX,
8602
+ vm.controlPointPreviousY,
8603
+ vm.x,
8604
+ vm.y
8422
8605
  );
8423
- } else if (drawLineToCenter) {
8424
- // Go to center
8425
- ctx.lineTo(me._view.scaleZero.x, me._view.scaleZero.y);
8426
8606
  }
8427
8607
  }
8428
8608
 
8429
- ctx.save();
8609
+ var points = me._children.slice(); // clone array
8610
+ var lastDrawnIndex = -1;
8611
+
8612
+ // If we are looping, adding the first point again
8613
+ if (loop && points.length) {
8614
+ points.push(points[0]);
8615
+ }
8430
8616
 
8431
- // If we had points and want to fill this line, do so.
8432
- if (me._children.length > 0 && vm.fill) {
8433
- // Draw the background first (so the border is always on top)
8617
+ var index, current, previous, currentVM;
8618
+
8619
+ // Fill Line
8620
+ if (points.length && vm.fill) {
8434
8621
  ctx.beginPath();
8435
8622
 
8436
- helpers.each(me._children, function(point, index) {
8437
- var previous = helpers.previousItem(me._children, index);
8438
- var next = helpers.nextItem(me._children, index);
8623
+ for (index = 0; index < points.length; ++index) {
8624
+ current = points[index];
8625
+ previous = helpers.previousItem(points, index);
8626
+ currentVM = current._view;
8439
8627
 
8440
8628
  // First point moves to it's starting position no matter what
8441
8629
  if (index === 0) {
8442
- if (me._loop) {
8443
- ctx.moveTo(vm.scaleZero.x, vm.scaleZero.y);
8630
+ if (loop) {
8631
+ ctx.moveTo(scaleZero.x, scaleZero.y);
8444
8632
  } else {
8445
- ctx.moveTo(point._view.x, vm.scaleZero);
8633
+ ctx.moveTo(currentVM.x, scaleZero);
8446
8634
  }
8447
8635
 
8448
- if (point._view.skip) {
8449
- if (!me._loop) {
8450
- ctx.moveTo(next._view.x, me._view.scaleZero);
8451
- }
8452
- } else {
8453
- ctx.lineTo(point._view.x, point._view.y);
8636
+ if (!currentVM.skip) {
8637
+ lastDrawnIndex = index;
8638
+ ctx.lineTo(currentVM.x, currentVM.y);
8454
8639
  }
8455
8640
  } else {
8456
- me.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {
8457
- if (me._loop) {
8458
- // Go to center
8459
- ctx.lineTo(me._view.scaleZero.x, me._view.scaleZero.y);
8641
+ previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
8642
+
8643
+ if (currentVM.skip) {
8644
+ // Only do this if this is the first point that is skipped
8645
+ if (!spanGaps && lastDrawnIndex === (index - 1)) {
8646
+ if (loop) {
8647
+ ctx.lineTo(scaleZero.x, scaleZero.y);
8648
+ } else {
8649
+ ctx.lineTo(previous._view.x, scaleZero);
8650
+ }
8651
+ }
8652
+ } else {
8653
+ if (lastDrawnIndex !== (index - 1)) {
8654
+ // There was a gap and this is the first point after the gap. If we've never drawn a point, this is a special case.
8655
+ // If the first data point is NaN, then there is no real gap to skip
8656
+ if (spanGaps && lastDrawnIndex !== -1) {
8657
+ // We are spanning the gap, so simple draw a line to this point
8658
+ lineToPoint(previous, current);
8659
+ } else {
8660
+ if (loop) {
8661
+ ctx.lineTo(currentVM.x, currentVM.y);
8662
+ } else {
8663
+ ctx.lineTo(currentVM.x, scaleZero);
8664
+ ctx.lineTo(currentVM.x, currentVM.y);
8665
+ }
8666
+ }
8460
8667
  } else {
8461
- ctx.lineTo(previousPoint._view.x, me._view.scaleZero);
8462
- ctx.moveTo(nextPoint._view.x, me._view.scaleZero);
8668
+ // Line to next point
8669
+ lineToPoint(previous, current);
8463
8670
  }
8464
- }, function(previousPoint, point) {
8465
- // If we skipped the last point, draw a line to ourselves so that the fill is nice
8466
- ctx.lineTo(point._view.x, point._view.y);
8467
- });
8671
+ lastDrawnIndex = index;
8672
+ }
8468
8673
  }
8469
- }, me);
8674
+ }
8470
8675
 
8471
- // For radial scales, loop back around to the first point
8472
- if (me._loop) {
8473
- loopBackToStart(true);
8474
- } else {
8475
- //Round off the line by going to the base of the chart, back to the start, then fill.
8476
- ctx.lineTo(me._children[me._children.length - 1]._view.x, vm.scaleZero);
8477
- ctx.lineTo(me._children[0]._view.x, vm.scaleZero);
8676
+ if (!loop) {
8677
+ ctx.lineTo(points[lastDrawnIndex]._view.x, scaleZero);
8478
8678
  }
8479
8679
 
8480
8680
  ctx.fillStyle = vm.backgroundColor || globalDefaults.defaultColor;
@@ -8482,8 +8682,8 @@ module.exports = function(Chart) {
8482
8682
  ctx.fill();
8483
8683
  }
8484
8684
 
8685
+ // Stroke Line Options
8485
8686
  var globalOptionLineElements = globalDefaults.elements.line;
8486
- // Now draw the line between all the points with any borders
8487
8687
  ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;
8488
8688
 
8489
8689
  // IE 9 and 10 do not support line dash
@@ -8495,26 +8695,38 @@ module.exports = function(Chart) {
8495
8695
  ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;
8496
8696
  ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth;
8497
8697
  ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;
8698
+
8699
+ // Stroke Line
8498
8700
  ctx.beginPath();
8701
+ lastDrawnIndex = -1;
8499
8702
 
8500
- helpers.each(me._children, function(point, index) {
8501
- var previous = helpers.previousItem(me._children, index);
8502
- var next = helpers.nextItem(me._children, index);
8703
+ for (index = 0; index < points.length; ++index) {
8704
+ current = points[index];
8705
+ previous = helpers.previousItem(points, index);
8706
+ currentVM = current._view;
8503
8707
 
8708
+ // First point moves to it's starting position no matter what
8504
8709
  if (index === 0) {
8505
- ctx.moveTo(point._view.x, point._view.y);
8710
+ if (currentVM.skip) {
8711
+
8712
+ } else {
8713
+ ctx.moveTo(currentVM.x, currentVM.y);
8714
+ lastDrawnIndex = index;
8715
+ }
8506
8716
  } else {
8507
- me.lineToNextPoint(previous, point, next, function(previousPoint, point, nextPoint) {
8508
- ctx.moveTo(nextPoint._view.x, nextPoint._view.y);
8509
- }, function(previousPoint, point) {
8510
- // If we skipped the last point, move up to our point preventing a line from being drawn
8511
- ctx.moveTo(point._view.x, point._view.y);
8512
- });
8513
- }
8514
- }, me);
8717
+ previous = lastDrawnIndex === -1 ? previous : points[lastDrawnIndex];
8515
8718
 
8516
- if (me._loop && me._children.length > 0) {
8517
- loopBackToStart();
8719
+ if (!currentVM.skip) {
8720
+ if ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {
8721
+ // There was a gap and this is the first point after the gap
8722
+ ctx.moveTo(currentVM.x, currentVM.y);
8723
+ } else {
8724
+ // Line to next point
8725
+ lineToPoint(previous, current);
8726
+ }
8727
+ lastDrawnIndex = index;
8728
+ }
8729
+ }
8518
8730
  }
8519
8731
 
8520
8732
  ctx.stroke();
@@ -8522,7 +8734,7 @@ module.exports = function(Chart) {
8522
8734
  }
8523
8735
  });
8524
8736
  };
8525
- },{}],36:[function(require,module,exports){
8737
+ },{}],37:[function(require,module,exports){
8526
8738
  "use strict";
8527
8739
 
8528
8740
  module.exports = function(Chart) {
@@ -8567,119 +8779,26 @@ module.exports = function(Chart) {
8567
8779
  var radius = vm.radius;
8568
8780
  var x = vm.x;
8569
8781
  var y = vm.y;
8570
- var type, edgeLength, xOffset, yOffset, height, size;
8571
8782
 
8572
8783
  if (vm.skip) {
8573
8784
  return;
8574
8785
  }
8575
8786
 
8576
- if (typeof pointStyle === 'object') {
8577
- type = pointStyle.toString();
8578
- if (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {
8579
- ctx.drawImage(pointStyle, x - pointStyle.width / 2, y - pointStyle.height / 2);
8580
- return;
8581
- }
8582
- }
8583
-
8584
- if (isNaN(radius) || radius <= 0) {
8585
- return;
8586
- }
8587
-
8588
8787
  ctx.strokeStyle = vm.borderColor || defaultColor;
8589
8788
  ctx.lineWidth = helpers.getValueOrDefault(vm.borderWidth, globalOpts.elements.point.borderWidth);
8590
8789
  ctx.fillStyle = vm.backgroundColor || defaultColor;
8591
8790
 
8592
- switch (pointStyle) {
8593
- // Default includes circle
8594
- default:
8595
- ctx.beginPath();
8596
- ctx.arc(x, y, radius, 0, Math.PI * 2);
8597
- ctx.closePath();
8598
- ctx.fill();
8599
- break;
8600
- case 'triangle':
8601
- ctx.beginPath();
8602
- edgeLength = 3 * radius / Math.sqrt(3);
8603
- height = edgeLength * Math.sqrt(3) / 2;
8604
- ctx.moveTo(x - edgeLength / 2, y + height / 3);
8605
- ctx.lineTo(x + edgeLength / 2, y + height / 3);
8606
- ctx.lineTo(x, y - 2 * height / 3);
8607
- ctx.closePath();
8608
- ctx.fill();
8609
- break;
8610
- case 'rect':
8611
- size = 1 / Math.SQRT2 * radius;
8612
- ctx.fillRect(x - size, y - size, 2 * size, 2 * size);
8613
- ctx.strokeRect(x - size, y - size, 2 * size, 2 * size);
8614
- break;
8615
- case 'rectRot':
8616
- size = 1 / Math.SQRT2 * radius;
8617
- ctx.beginPath();
8618
- ctx.moveTo(x - size, y);
8619
- ctx.lineTo(x, y + size);
8620
- ctx.lineTo(x + size, y);
8621
- ctx.lineTo(x, y - size);
8622
- ctx.closePath();
8623
- ctx.fill();
8624
- break;
8625
- case 'cross':
8626
- ctx.beginPath();
8627
- ctx.moveTo(x, y + radius);
8628
- ctx.lineTo(x, y - radius);
8629
- ctx.moveTo(x - radius, y);
8630
- ctx.lineTo(x + radius, y);
8631
- ctx.closePath();
8632
- break;
8633
- case 'crossRot':
8634
- ctx.beginPath();
8635
- xOffset = Math.cos(Math.PI / 4) * radius;
8636
- yOffset = Math.sin(Math.PI / 4) * radius;
8637
- ctx.moveTo(x - xOffset, y - yOffset);
8638
- ctx.lineTo(x + xOffset, y + yOffset);
8639
- ctx.moveTo(x - xOffset, y + yOffset);
8640
- ctx.lineTo(x + xOffset, y - yOffset);
8641
- ctx.closePath();
8642
- break;
8643
- case 'star':
8644
- ctx.beginPath();
8645
- ctx.moveTo(x, y + radius);
8646
- ctx.lineTo(x, y - radius);
8647
- ctx.moveTo(x - radius, y);
8648
- ctx.lineTo(x + radius, y);
8649
- xOffset = Math.cos(Math.PI / 4) * radius;
8650
- yOffset = Math.sin(Math.PI / 4) * radius;
8651
- ctx.moveTo(x - xOffset, y - yOffset);
8652
- ctx.lineTo(x + xOffset, y + yOffset);
8653
- ctx.moveTo(x - xOffset, y + yOffset);
8654
- ctx.lineTo(x + xOffset, y - yOffset);
8655
- ctx.closePath();
8656
- break;
8657
- case 'line':
8658
- ctx.beginPath();
8659
- ctx.moveTo(x - radius, y);
8660
- ctx.lineTo(x + radius, y);
8661
- ctx.closePath();
8662
- break;
8663
- case 'dash':
8664
- ctx.beginPath();
8665
- ctx.moveTo(x, y);
8666
- ctx.lineTo(x + radius, y);
8667
- ctx.closePath();
8668
- break;
8669
- }
8670
-
8671
- ctx.stroke();
8791
+ Chart.canvasHelpers.drawPoint(ctx, pointStyle, radius, x, y);
8672
8792
  }
8673
8793
  });
8674
8794
  };
8675
8795
 
8676
- },{}],37:[function(require,module,exports){
8796
+ },{}],38:[function(require,module,exports){
8677
8797
  "use strict";
8678
8798
 
8679
8799
  module.exports = function(Chart) {
8680
8800
 
8681
- var helpers = Chart.helpers,
8682
- globalOpts = Chart.defaults.global;
8801
+ var globalOpts = Chart.defaults.global;
8683
8802
 
8684
8803
  globalOpts.elements.rectangle = {
8685
8804
  backgroundColor: globalOpts.defaultColor,
@@ -8768,7 +8887,7 @@ module.exports = function(Chart) {
8768
8887
  });
8769
8888
 
8770
8889
  };
8771
- },{}],38:[function(require,module,exports){
8890
+ },{}],39:[function(require,module,exports){
8772
8891
  "use strict";
8773
8892
 
8774
8893
  module.exports = function(Chart) {
@@ -8780,36 +8899,47 @@ module.exports = function(Chart) {
8780
8899
  };
8781
8900
 
8782
8901
  var DatasetScale = Chart.Scale.extend({
8902
+ /**
8903
+ * Internal function to get the correct labels. If data.xLabels or data.yLabels are defined, use tose
8904
+ * else fall back to data.labels
8905
+ * @private
8906
+ */
8907
+ getLabels: function() {
8908
+ var data = this.chart.data;
8909
+ return (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels;
8910
+ },
8783
8911
  // Implement this so that
8784
8912
  determineDataLimits: function() {
8785
8913
  var me = this;
8914
+ var labels = me.getLabels();
8786
8915
  me.minIndex = 0;
8787
- me.maxIndex = me.chart.data.labels.length - 1;
8916
+ me.maxIndex = labels.length - 1;
8788
8917
  var findIndex;
8789
8918
 
8790
8919
  if (me.options.ticks.min !== undefined) {
8791
8920
  // user specified min value
8792
- findIndex = helpers.indexOf(me.chart.data.labels, me.options.ticks.min);
8921
+ findIndex = helpers.indexOf(labels, me.options.ticks.min);
8793
8922
  me.minIndex = findIndex !== -1 ? findIndex : me.minIndex;
8794
8923
  }
8795
8924
 
8796
8925
  if (me.options.ticks.max !== undefined) {
8797
8926
  // user specified max value
8798
- findIndex = helpers.indexOf(me.chart.data.labels, me.options.ticks.max);
8927
+ findIndex = helpers.indexOf(labels, me.options.ticks.max);
8799
8928
  me.maxIndex = findIndex !== -1 ? findIndex : me.maxIndex;
8800
8929
  }
8801
8930
 
8802
- me.min = me.chart.data.labels[me.minIndex];
8803
- me.max = me.chart.data.labels[me.maxIndex];
8931
+ me.min = labels[me.minIndex];
8932
+ me.max = labels[me.maxIndex];
8804
8933
  },
8805
8934
 
8806
- buildTicks: function(index) {
8935
+ buildTicks: function() {
8807
8936
  var me = this;
8937
+ var labels = me.getLabels();
8808
8938
  // If we are viewing some subset of labels, slice the original array
8809
- me.ticks = (me.minIndex === 0 && me.maxIndex === me.chart.data.labels.length - 1) ? me.chart.data.labels : me.chart.data.labels.slice(me.minIndex, me.maxIndex + 1);
8939
+ me.ticks = (me.minIndex === 0 && me.maxIndex === labels.length - 1) ? labels : labels.slice(me.minIndex, me.maxIndex + 1);
8810
8940
  },
8811
8941
 
8812
- getLabelForIndex: function(index, datasetIndex) {
8942
+ getLabelForIndex: function(index) {
8813
8943
  return this.ticks[index];
8814
8944
  },
8815
8945
 
@@ -8819,6 +8949,12 @@ module.exports = function(Chart) {
8819
8949
  // 1 is added because we need the length but we have the indexes
8820
8950
  var offsetAmt = Math.max((me.maxIndex + 1 - me.minIndex - ((me.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
8821
8951
 
8952
+ if (value !== undefined) {
8953
+ var labels = me.getLabels();
8954
+ var idx = labels.indexOf(value);
8955
+ index = idx !== -1 ? idx : index;
8956
+ }
8957
+
8822
8958
  if (me.isHorizontal()) {
8823
8959
  var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
8824
8960
  var valueWidth = innerWidth / offsetAmt;
@@ -8852,6 +8988,8 @@ module.exports = function(Chart) {
8852
8988
  var innerDimension = horz ? me.width - (me.paddingLeft + me.paddingRight) : me.height - (me.paddingTop + me.paddingBottom);
8853
8989
  var valueDimension = innerDimension / offsetAmt;
8854
8990
 
8991
+ pixel -= horz ? me.left : me.top;
8992
+
8855
8993
  if (me.options.gridLines.offsetGridLines) {
8856
8994
  pixel -= (valueDimension / 2);
8857
8995
  }
@@ -8864,13 +9002,16 @@ module.exports = function(Chart) {
8864
9002
  }
8865
9003
 
8866
9004
  return value;
9005
+ },
9006
+ getBasePixel: function() {
9007
+ return this.bottom;
8867
9008
  }
8868
9009
  });
8869
9010
 
8870
9011
  Chart.scaleService.registerScaleType("category", DatasetScale, defaultConfig);
8871
9012
 
8872
9013
  };
8873
- },{}],39:[function(require,module,exports){
9014
+ },{}],40:[function(require,module,exports){
8874
9015
  "use strict";
8875
9016
 
8876
9017
  module.exports = function(Chart) {
@@ -8912,7 +9053,6 @@ module.exports = function(Chart) {
8912
9053
  determineDataLimits: function() {
8913
9054
  var me = this;
8914
9055
  var opts = me.options;
8915
- var tickOpts = opts.ticks;
8916
9056
  var chart = me.chart;
8917
9057
  var data = chart.data;
8918
9058
  var datasets = data.datasets;
@@ -9032,9 +9172,9 @@ module.exports = function(Chart) {
9032
9172
  return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
9033
9173
  },
9034
9174
  // Utils
9035
- getPixelForValue: function(value, index, datasetIndex, includeOffset) {
9175
+ getPixelForValue: function(value) {
9036
9176
  // This must be called after fit has been run so that
9037
- // this.left, this.top, this.right, and this.bottom have been defined
9177
+ // this.left, this.top, this.right, and this.bottom have been defined
9038
9178
  var me = this;
9039
9179
  var paddingLeft = me.paddingLeft;
9040
9180
  var paddingBottom = me.paddingBottom;
@@ -9064,14 +9204,14 @@ module.exports = function(Chart) {
9064
9204
  var offset = (isHorizontal ? pixel - me.left - paddingLeft : me.bottom - paddingBottom - pixel) / innerDimension;
9065
9205
  return me.start + ((me.end - me.start) * offset);
9066
9206
  },
9067
- getPixelForTick: function(index, includeOffset) {
9068
- return this.getPixelForValue(this.ticksAsNumbers[index], null, null, includeOffset);
9207
+ getPixelForTick: function(index) {
9208
+ return this.getPixelForValue(this.ticksAsNumbers[index]);
9069
9209
  }
9070
9210
  });
9071
9211
  Chart.scaleService.registerScaleType("linear", LinearScale, defaultConfig);
9072
9212
 
9073
9213
  };
9074
- },{}],40:[function(require,module,exports){
9214
+ },{}],41:[function(require,module,exports){
9075
9215
  "use strict";
9076
9216
 
9077
9217
  module.exports = function(Chart) {
@@ -9127,11 +9267,9 @@ module.exports = function(Chart) {
9127
9267
  buildTicks: function() {
9128
9268
  var me = this;
9129
9269
  var opts = me.options;
9270
+ var ticks = me.ticks = [];
9130
9271
  var tickOpts = opts.ticks;
9131
9272
  var getValueOrDefault = helpers.getValueOrDefault;
9132
- var isHorizontal = me.isHorizontal();
9133
-
9134
- var ticks = me.ticks = [];
9135
9273
 
9136
9274
  // Figure out what the max number of ticks we can support it is based on the size of
9137
9275
  // the axis area. For now, we say that the minimum tick spacing in pixels must be 50
@@ -9199,7 +9337,7 @@ module.exports = function(Chart) {
9199
9337
  },
9200
9338
  });
9201
9339
  };
9202
- },{}],41:[function(require,module,exports){
9340
+ },{}],42:[function(require,module,exports){
9203
9341
  "use strict";
9204
9342
 
9205
9343
  module.exports = function(Chart) {
@@ -9379,10 +9517,10 @@ module.exports = function(Chart) {
9379
9517
  getLabelForIndex: function(index, datasetIndex) {
9380
9518
  return +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);
9381
9519
  },
9382
- getPixelForTick: function(index, includeOffset) {
9383
- return this.getPixelForValue(this.tickValues[index], null, null, includeOffset);
9520
+ getPixelForTick: function(index) {
9521
+ return this.getPixelForValue(this.tickValues[index]);
9384
9522
  },
9385
- getPixelForValue: function(value, index, datasetIndex, includeOffset) {
9523
+ getPixelForValue: function(value) {
9386
9524
  var me = this;
9387
9525
  var innerDimension;
9388
9526
  var pixel;
@@ -9417,10 +9555,8 @@ module.exports = function(Chart) {
9417
9555
  },
9418
9556
  getValueForPixel: function(pixel) {
9419
9557
  var me = this;
9420
- var offset;
9421
9558
  var range = helpers.log10(me.end) - helpers.log10(me.start);
9422
- var value;
9423
- var innerDimension;
9559
+ var value, innerDimension;
9424
9560
 
9425
9561
  if (me.isHorizontal()) {
9426
9562
  innerDimension = me.width - (me.paddingLeft + me.paddingRight);
@@ -9436,7 +9572,7 @@ module.exports = function(Chart) {
9436
9572
  Chart.scaleService.registerScaleType("logarithmic", LogarithmicScale, defaultConfig);
9437
9573
 
9438
9574
  };
9439
- },{}],42:[function(require,module,exports){
9575
+ },{}],43:[function(require,module,exports){
9440
9576
  "use strict";
9441
9577
 
9442
9578
  module.exports = function(Chart) {
@@ -9603,16 +9739,20 @@ module.exports = function(Chart) {
9603
9739
  xProtrusionLeft,
9604
9740
  xProtrusionRight,
9605
9741
  radiusReductionRight,
9606
- radiusReductionLeft,
9607
- maxWidthRadius;
9742
+ radiusReductionLeft;
9608
9743
  this.ctx.font = pointLabeFont;
9609
9744
 
9610
9745
  for (i = 0; i < this.getValueCount(); i++) {
9611
9746
  // 5px to space the text slightly out - similar to what we do in the draw function.
9612
9747
  pointPosition = this.getPointPosition(i, largestPossibleRadius);
9613
9748
  textWidth = this.ctx.measureText(this.pointLabels[i] ? this.pointLabels[i] : '').width + 5;
9614
- if (i === 0 || i === this.getValueCount() / 2) {
9615
- // If we're at index zero, or exactly the middle, we're at exactly the top/bottom
9749
+
9750
+ // Add quarter circle to make degree 0 mean top of circle
9751
+ var angleRadians = this.getIndexAngle(i) + (Math.PI / 2);
9752
+ var angle = (angleRadians * 360 / (2 * Math.PI)) % 360;
9753
+
9754
+ if (angle === 0 || angle === 180) {
9755
+ // At angle 0 and 180, we're at exactly the top/bottom
9616
9756
  // of the radar chart, so text will be aligned centrally, so we'll half it and compare
9617
9757
  // w/left and right text sizes
9618
9758
  halfTextWidth = textWidth / 2;
@@ -9624,13 +9764,13 @@ module.exports = function(Chart) {
9624
9764
  furthestLeft = pointPosition.x - halfTextWidth;
9625
9765
  furthestLeftIndex = i;
9626
9766
  }
9627
- } else if (i < this.getValueCount() / 2) {
9767
+ } else if (angle < 180) {
9628
9768
  // Less than half the values means we'll left align the text
9629
9769
  if (pointPosition.x + textWidth > furthestRight) {
9630
9770
  furthestRight = pointPosition.x + textWidth;
9631
9771
  furthestRightIndex = i;
9632
9772
  }
9633
- } else if (i > this.getValueCount() / 2) {
9773
+ } else {
9634
9774
  // More than half the values means we'll right align the text
9635
9775
  if (pointPosition.x - textWidth < furthestLeft) {
9636
9776
  furthestLeft = pointPosition.x - textWidth;
@@ -9667,9 +9807,14 @@ module.exports = function(Chart) {
9667
9807
 
9668
9808
  getIndexAngle: function(index) {
9669
9809
  var angleMultiplier = (Math.PI * 2) / this.getValueCount();
9670
- // Start from the top instead of right, so remove a quarter of the circle
9810
+ var startAngle = this.chart.options && this.chart.options.startAngle ?
9811
+ this.chart.options.startAngle :
9812
+ 0;
9671
9813
 
9672
- return index * angleMultiplier - (Math.PI / 2);
9814
+ var startAngleRadians = startAngle * Math.PI * 2 / 360;
9815
+
9816
+ // Start from the top instead of right, so remove a quarter of the circle
9817
+ return index * angleMultiplier - (Math.PI / 2) + startAngleRadians;
9673
9818
  },
9674
9819
  getDistanceFromCenterForValue: function(value) {
9675
9820
  var me = this;
@@ -9813,26 +9958,24 @@ module.exports = function(Chart) {
9813
9958
  ctx.font = pointLabeFont;
9814
9959
  ctx.fillStyle = pointLabelFontColor;
9815
9960
 
9816
- var pointLabels = me.pointLabels,
9817
- labelsCount = pointLabels.length,
9818
- halfLabelsCount = pointLabels.length / 2,
9819
- quarterLabelsCount = halfLabelsCount / 2,
9820
- upperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),
9821
- exactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);
9822
- if (i === 0) {
9823
- ctx.textAlign = 'center';
9824
- } else if (i === halfLabelsCount) {
9961
+ var pointLabels = me.pointLabels;
9962
+
9963
+ // Add quarter circle to make degree 0 mean top of circle
9964
+ var angleRadians = this.getIndexAngle(i) + (Math.PI / 2);
9965
+ var angle = (angleRadians * 360 / (2 * Math.PI)) % 360;
9966
+
9967
+ if (angle === 0 || angle === 180) {
9825
9968
  ctx.textAlign = 'center';
9826
- } else if (i < halfLabelsCount) {
9969
+ } else if (angle < 180) {
9827
9970
  ctx.textAlign = 'left';
9828
9971
  } else {
9829
9972
  ctx.textAlign = 'right';
9830
9973
  }
9831
9974
 
9832
9975
  // Set the correct text baseline based on outer positioning
9833
- if (exactQuarter) {
9976
+ if (angle === 90 || angle === 270) {
9834
9977
  ctx.textBaseline = 'middle';
9835
- } else if (upperHalf) {
9978
+ } else if (angle > 270 || angle < 90) {
9836
9979
  ctx.textBaseline = 'bottom';
9837
9980
  } else {
9838
9981
  ctx.textBaseline = 'top';
@@ -9848,7 +9991,7 @@ module.exports = function(Chart) {
9848
9991
 
9849
9992
  };
9850
9993
 
9851
- },{}],43:[function(require,module,exports){
9994
+ },{}],44:[function(require,module,exports){
9852
9995
  /*global window: false */
9853
9996
  "use strict";
9854
9997
 
@@ -9927,7 +10070,11 @@ module.exports = function(Chart) {
9927
10070
  Chart.Scale.prototype.initialize.call(this);
9928
10071
  },
9929
10072
  getLabelMoment: function(datasetIndex, index) {
9930
- return this.labelMoments[datasetIndex][index];
10073
+ if (typeof this.labelMoments[datasetIndex] != 'undefined') {
10074
+ return this.labelMoments[datasetIndex][index];
10075
+ }
10076
+
10077
+ return null;
9931
10078
  },
9932
10079
  getMomentStartOf: function(tick) {
9933
10080
  var me = this;
@@ -9945,7 +10092,7 @@ module.exports = function(Chart) {
9945
10092
  // these
9946
10093
  var scaleLabelMoments = [];
9947
10094
  if (me.chart.data.labels && me.chart.data.labels.length > 0) {
9948
- helpers.each(me.chart.data.labels, function(label, index) {
10095
+ helpers.each(me.chart.data.labels, function(label) {
9949
10096
  var labelMoment = me.parseTime(label);
9950
10097
 
9951
10098
  if (labelMoment.isValid()) {
@@ -9968,7 +10115,7 @@ module.exports = function(Chart) {
9968
10115
  var datasetVisible = me.chart.isDatasetVisible(datasetIndex);
9969
10116
 
9970
10117
  if (typeof dataset.data[0] === 'object' && dataset.data[0] !== null) {
9971
- helpers.each(dataset.data, function(value, index) {
10118
+ helpers.each(dataset.data, function(value) {
9972
10119
  var labelMoment = me.parseTime(me.getRightValue(value));
9973
10120
 
9974
10121
  if (labelMoment.isValid()) {
@@ -10005,7 +10152,7 @@ module.exports = function(Chart) {
10005
10152
  me.firstTick = (me.firstTick || moment()).clone();
10006
10153
  me.lastTick = (me.lastTick || moment()).clone();
10007
10154
  },
10008
- buildTicks: function(index) {
10155
+ buildTicks: function() {
10009
10156
  var me = this;
10010
10157
 
10011
10158
  me.ctx.save();
@@ -10091,10 +10238,15 @@ module.exports = function(Chart) {
10091
10238
  // Only round the last tick if we have no hard maximum
10092
10239
  if (!me.options.time.max) {
10093
10240
  var roundedEnd = me.getMomentStartOf(me.lastTick);
10094
- if (roundedEnd.diff(me.lastTick, me.tickUnit, true) !== 0) {
10241
+ var delta = roundedEnd.diff(me.lastTick, me.tickUnit, true);
10242
+ if (delta < 0) {
10095
10243
  // Do not use end of because we need me to be in the next time unit
10096
10244
  me.lastTick = me.getMomentStartOf(me.lastTick.add(1, me.tickUnit));
10245
+ } else if (delta >= 0) {
10246
+ me.lastTick = roundedEnd;
10097
10247
  }
10248
+
10249
+ me.scaleSizeInUnits = me.lastTick.diff(me.firstTick, me.tickUnit, true);
10098
10250
  }
10099
10251
 
10100
10252
  me.smallestLabelSeparation = me.width;
@@ -10160,7 +10312,7 @@ module.exports = function(Chart) {
10160
10312
  return label;
10161
10313
  },
10162
10314
  // Function to format an individual tick mark
10163
- tickFormatFunction: function tickFormatFunction(tick, index, ticks) {
10315
+ tickFormatFunction: function(tick, index, ticks) {
10164
10316
  var formattedTick = tick.format(this.displayFormat);
10165
10317
  var tickOpts = this.options.ticks;
10166
10318
  var callback = helpers.getValueOrDefault(tickOpts.callback, tickOpts.userCallback);
@@ -10176,32 +10328,34 @@ module.exports = function(Chart) {
10176
10328
  me.tickMoments = me.ticks;
10177
10329
  me.ticks = me.ticks.map(me.tickFormatFunction, me);
10178
10330
  },
10179
- getPixelForValue: function(value, index, datasetIndex, includeOffset) {
10331
+ getPixelForValue: function(value, index, datasetIndex) {
10180
10332
  var me = this;
10333
+ if (!value || !value.isValid) {
10334
+ // not already a moment object
10335
+ value = moment(me.getRightValue(value));
10336
+ }
10181
10337
  var labelMoment = value && value.isValid && value.isValid() ? value : me.getLabelMoment(datasetIndex, index);
10182
10338
 
10183
10339
  if (labelMoment) {
10184
10340
  var offset = labelMoment.diff(me.firstTick, me.tickUnit, true);
10185
10341
 
10186
- var decimal = offset / me.scaleSizeInUnits;
10342
+ var decimal = offset !== 0 ? offset / me.scaleSizeInUnits : offset;
10187
10343
 
10188
10344
  if (me.isHorizontal()) {
10189
10345
  var innerWidth = me.width - (me.paddingLeft + me.paddingRight);
10190
- var valueWidth = innerWidth / Math.max(me.ticks.length - 1, 1);
10191
10346
  var valueOffset = (innerWidth * decimal) + me.paddingLeft;
10192
10347
 
10193
10348
  return me.left + Math.round(valueOffset);
10194
10349
  } else {
10195
10350
  var innerHeight = me.height - (me.paddingTop + me.paddingBottom);
10196
- var valueHeight = innerHeight / Math.max(me.ticks.length - 1, 1);
10197
10351
  var heightOffset = (innerHeight * decimal) + me.paddingTop;
10198
10352
 
10199
10353
  return me.top + Math.round(heightOffset);
10200
10354
  }
10201
10355
  }
10202
10356
  },
10203
- getPixelForTick: function(index, includeOffset) {
10204
- return this.getPixelForValue(this.tickMoments[index], null, null, includeOffset);
10357
+ getPixelForTick: function(index) {
10358
+ return this.getPixelForValue(this.tickMoments[index], null, null);
10205
10359
  },
10206
10360
  getValueForPixel: function(pixel) {
10207
10361
  var me = this;