highcharts-rails 5.0.0 → 5.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.markdown +99 -0
  4. data/Gemfile +1 -1
  5. data/README.markdown +2 -1
  6. data/Rakefile +28 -2
  7. data/app/assets/javascripts/highcharts.js +3935 -2584
  8. data/app/assets/javascripts/highcharts/highcharts-3d.js +44 -10
  9. data/app/assets/javascripts/highcharts/highcharts-more.js +32 -12
  10. data/app/assets/javascripts/highcharts/modules/accessibility.js +85 -18
  11. data/app/assets/javascripts/highcharts/modules/annotations.js +1 -1
  12. data/app/assets/javascripts/highcharts/modules/boost.js +34 -19
  13. data/app/assets/javascripts/highcharts/modules/broken-axis.js +1 -1
  14. data/app/assets/javascripts/highcharts/modules/data.js +2 -2
  15. data/app/assets/javascripts/highcharts/modules/drilldown.js +4 -3
  16. data/app/assets/javascripts/highcharts/modules/exporting.js +15 -14
  17. data/app/assets/javascripts/highcharts/modules/funnel.js +1 -1
  18. data/app/assets/javascripts/highcharts/modules/grid-axis.js +547 -0
  19. data/app/assets/javascripts/highcharts/modules/heatmap.js +17 -2
  20. data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +1 -1
  21. data/app/assets/javascripts/highcharts/modules/offline-exporting.js +115 -73
  22. data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +1 -1
  23. data/app/assets/javascripts/highcharts/modules/series-label.js +210 -148
  24. data/app/assets/javascripts/highcharts/modules/solid-gauge.js +30 -10
  25. data/app/assets/javascripts/highcharts/modules/treemap.js +6 -1
  26. data/app/assets/javascripts/highcharts/modules/xrange-series.js +278 -0
  27. data/lib/highcharts/version.rb +1 -1
  28. metadata +3 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.0 (2016-09-29)
2
+ * @license Highcharts JS v5.0.3 (2016-11-18)
3
3
  *
4
4
  * 3D features for Highcharts JS
5
5
  *
@@ -115,6 +115,25 @@
115
115
  });
116
116
  };
117
117
 
118
+ /**
119
+ * Calculate a distance from camera to points - made for calculating zIndex of scatter points.
120
+ * Parameters:
121
+ * - coordinates: The coordinates of the specific point
122
+ * - chart: the chart
123
+ * Returns:
124
+ * - a distance from camera to point
125
+ */
126
+ H.pointCameraDistance = function(coordinates, chart) {
127
+ var options3d = chart.options.chart.options3d,
128
+ cameraPosition = {
129
+ x: chart.plotWidth / 2,
130
+ y: chart.plotHeight / 2,
131
+ z: pick(options3d.depth, 1) * pick(options3d.viewDistance, 0) + options3d.depth
132
+ },
133
+ distance = Math.sqrt(Math.pow(cameraPosition.x - coordinates.plotX, 2) + Math.pow(cameraPosition.y - coordinates.plotY, 2) + Math.pow(cameraPosition.z - coordinates.plotZ, 2));
134
+ return distance;
135
+ };
136
+
118
137
  }(Highcharts));
119
138
  (function(H) {
120
139
  /**
@@ -605,6 +624,7 @@
605
624
  if (anim.duration) {
606
625
  params = merge(params); // Don't mutate the original object
607
626
  ca = suckOutCustom(params);
627
+ params.dummy = 1; // Params need to have a property in order for the step to run (#5765)
608
628
 
609
629
  if (ca) {
610
630
  to = ca;
@@ -612,14 +632,17 @@
612
632
  function interpolate(key) {
613
633
  return from[key] + (pick(to[key], from[key]) - from[key]) * fx.pos;
614
634
  }
615
- fx.elem.setPaths(merge(from, {
616
- x: interpolate('x'),
617
- y: interpolate('y'),
618
- r: interpolate('r'),
619
- innerR: interpolate('innerR'),
620
- start: interpolate('start'),
621
- end: interpolate('end')
622
- }));
635
+
636
+ if (fx.prop === 'dummy') {
637
+ fx.elem.setPaths(merge(from, {
638
+ x: interpolate('x'),
639
+ y: interpolate('y'),
640
+ r: interpolate('r'),
641
+ innerR: interpolate('innerR'),
642
+ start: interpolate('start'),
643
+ end: interpolate('end')
644
+ }));
645
+ }
623
646
  };
624
647
  }
625
648
  animation = anim; // Only when duration (#5572)
@@ -1987,11 +2010,11 @@
1987
2010
  rawPoint.plotY = projectedPoint.y;
1988
2011
  rawPoint.plotZ = projectedPoint.z;
1989
2012
 
1990
-
1991
2013
  }
1992
2014
 
1993
2015
  });
1994
2016
 
2017
+
1995
2018
  wrap(seriesTypes.scatter.prototype, 'init', function(proceed, chart, options) {
1996
2019
  if (chart.is3d()) {
1997
2020
  // add a third coordinate
@@ -2018,6 +2041,17 @@
2018
2041
  return result;
2019
2042
  });
2020
2043
 
2044
+ /**
2045
+ * Updating zIndex for every point - based on the distance from point to camera
2046
+ */
2047
+ wrap(seriesTypes.scatter.prototype, 'pointAttribs', function(proceed, point) {
2048
+ var pointOptions = proceed.apply(this, [].slice.call(arguments, 1));
2049
+ if (point) {
2050
+ pointOptions.zIndex = H.pointCameraDistance(point, this.chart);
2051
+ }
2052
+ return pointOptions;
2053
+ });
2054
+
2021
2055
  }(Highcharts));
2022
2056
  (function(H) {
2023
2057
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.0 (2016-09-29)
2
+ * @license Highcharts JS v5.0.3 (2016-11-18)
3
3
  *
4
4
  * (c) 2009-2016 Torstein Honsi
5
5
  *
@@ -775,7 +775,8 @@
775
775
  */
776
776
  translate: function() {
777
777
  var series = this,
778
- yAxis = series.yAxis;
778
+ yAxis = series.yAxis,
779
+ hasModifyValue = !!series.modifyValue;
779
780
 
780
781
  seriesTypes.area.prototype.translate.apply(series);
781
782
 
@@ -790,7 +791,16 @@
790
791
  point.isNull = true;
791
792
  } else {
792
793
  point.plotLow = plotY;
793
- point.plotHigh = yAxis.translate(high, 0, 1, 0, 1);
794
+ point.plotHigh = yAxis.translate(
795
+ hasModifyValue ? series.modifyValue(high, point) : high,
796
+ 0,
797
+ 1,
798
+ 0,
799
+ 1
800
+ );
801
+ if (hasModifyValue) {
802
+ point.yBottom = point.plotHigh;
803
+ }
794
804
  }
795
805
  });
796
806
 
@@ -1012,8 +1022,10 @@
1012
1022
  * License: www.highcharts.com/license
1013
1023
  */
1014
1024
  'use strict';
1025
+
1015
1026
  var seriesType = H.seriesType,
1016
1027
  seriesTypes = H.seriesTypes;
1028
+
1017
1029
  /**
1018
1030
  * The areasplinerange series type
1019
1031
  */
@@ -1408,9 +1420,12 @@
1408
1420
  seriesType = H.seriesType,
1409
1421
  seriesTypes = H.seriesTypes;
1410
1422
 
1411
- /* ****************************************************************************
1412
- * Start Box plot series code *
1413
- *****************************************************************************/
1423
+ /**
1424
+ * The boxplot series type.
1425
+ *
1426
+ * @constructor seriesTypes.boxplot
1427
+ * @augments seriesTypes.column
1428
+ */
1414
1429
  seriesType('boxplot', 'column', {
1415
1430
  threshold: null,
1416
1431
  tooltip: {
@@ -1442,8 +1457,7 @@
1442
1457
  whiskerWidth: 2
1443
1458
 
1444
1459
 
1445
- // Prototype members
1446
- }, {
1460
+ }, /** @lends seriesTypes.boxplot */ {
1447
1461
  pointArrayMap: ['low', 'q1', 'median', 'q3', 'high'], // array point configs are mapped to this
1448
1462
  toYData: function(point) { // return a plain array for speedy calculation
1449
1463
  return [point.low, point.q1, point.median, point.q3, point.high];
@@ -1459,7 +1473,7 @@
1459
1473
  color = (point && point.color) || this.color;
1460
1474
 
1461
1475
  return {
1462
- 'fill': options.fillColor || color,
1476
+ 'fill': point.fillColor || options.fillColor || color,
1463
1477
  'stroke': options.lineColor || color,
1464
1478
  'stroke-width': options.lineWidth || 0
1465
1479
  };
@@ -2196,6 +2210,7 @@
2196
2210
  trackerGroups: ['group', 'dataLabelsGroup'],
2197
2211
  bubblePadding: true,
2198
2212
  zoneAxis: 'z',
2213
+ markerAttribs: null,
2199
2214
 
2200
2215
 
2201
2216
  pointAttribs: function(point, state) {
@@ -2359,8 +2374,11 @@
2359
2374
 
2360
2375
  // Point class
2361
2376
  }, {
2362
- haloPath: function() {
2363
- return Point.prototype.haloPath.call(this, this.shapeArgs.r + this.series.options.states.hover.halo.size);
2377
+ haloPath: function(size) {
2378
+ return Point.prototype.haloPath.call(
2379
+ this,
2380
+ this.shapeArgs.r + size
2381
+ );
2364
2382
  },
2365
2383
  ttBelow: false
2366
2384
  });
@@ -2414,7 +2432,9 @@
2414
2432
 
2415
2433
  });
2416
2434
  series.minPxSize = extremes.minSize;
2417
- series.maxPxSize = extremes.maxSize;
2435
+ // Prioritize min size if conflict to make sure bubbles are
2436
+ // always visible. #5873
2437
+ series.maxPxSize = Math.max(extremes.maxSize, extremes.minSize);
2418
2438
 
2419
2439
  // Find the min and max Z
2420
2440
  zData = series.zData;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.0 (2016-09-29)
2
+ * @license Highcharts JS v5.0.3 (2016-11-18)
3
3
  * Accessibility module
4
4
  *
5
5
  * (c) 2010-2016 Highsoft AS
@@ -117,7 +117,7 @@
117
117
  // Put accessible info on series and points of a series
118
118
  H.Series.prototype.setA11yDescription = function() {
119
119
  var a11yOptions = this.chart.options.accessibility,
120
- firstPointEl = this.points && this.points[0].graphic && this.points[0].graphic.element,
120
+ firstPointEl = this.points && this.points.length && this.points[0].graphic && this.points[0].graphic.element,
121
121
  seriesEl = firstPointEl && firstPointEl.parentNode || this.graph && this.graph.element || this.group && this.group.element; // Could be tracker series depending on series type
122
122
 
123
123
  if (seriesEl) {
@@ -340,6 +340,7 @@
340
340
  H.Chart.prototype.highlightAdjacentPoint = function(next) {
341
341
  var series = this.series,
342
342
  curPoint = this.highlightedPoint,
343
+ curPointIndex = curPoint && curPoint.index || 0,
343
344
  newSeries,
344
345
  newPoint;
345
346
 
@@ -353,13 +354,19 @@
353
354
  return series[0].points[0].highlight();
354
355
  }
355
356
 
357
+ // Find index of current point in series.points array. Necessary for dataGrouping (and maybe zoom?)
358
+ if (curPoint.series.points[curPointIndex] !== curPoint) {
359
+ for (var i = 0; i < curPoint.series.points.length; ++i) {
360
+ if (curPoint.series.points[i] === curPoint) {
361
+ curPointIndex = i;
362
+ break;
363
+ }
364
+ }
365
+ }
366
+
367
+ // Try to grab next/prev point
356
368
  newSeries = series[curPoint.series.index + (next ? 1 : -1)];
357
- newPoint = next ?
358
- // Try to grab next point
359
- curPoint.series.points[curPoint.index + 1] || newSeries && newSeries.points[0] :
360
- // Try to grab previous point
361
- curPoint.series.points[curPoint.index - 1] ||
362
- newSeries && newSeries.points[newSeries.points.length - 1];
369
+ newPoint = curPoint.series.points[curPointIndex + (next ? 1 : -1)] || newSeries && newSeries.points[next ? 0 : newSeries.points.length - 1];
363
370
 
364
371
  // If there is no adjacent point, we return false
365
372
  if (newPoint === undefined) {
@@ -425,6 +432,23 @@
425
432
  return false;
426
433
  };
427
434
 
435
+ // Highlight legend item by index
436
+ H.Chart.prototype.highlightLegendItem = function(ix) {
437
+ var items = this.legend.allItems;
438
+ if (items[this.highlightedLegendItemIx]) {
439
+ fireEvent(items[this.highlightedLegendItemIx].legendGroup.element, 'mouseout');
440
+ }
441
+ this.highlightedLegendItemIx = ix;
442
+ if (items[ix]) {
443
+ if (items[ix].legendGroup.element.focus) {
444
+ items[ix].legendGroup.element.focus();
445
+ }
446
+ fireEvent(items[ix].legendGroup.element, 'mouseover');
447
+ return true;
448
+ }
449
+ return false;
450
+ };
451
+
428
452
  // Hide export menu
429
453
  H.Chart.prototype.hideExportMenu = function() {
430
454
  var exportList = this.exportDivElements;
@@ -773,25 +797,56 @@
773
797
  ], {
774
798
  // Only run if we have range selector with input boxes
775
799
  validate: function() {
776
- return chart.rangeSelector && chart.options.rangeSelector.inputEnabled !== false && chart.rangeSelector.minInput && chart.rangeSelector.maxInput;
800
+ var inputVisible = chart.rangeSelector && chart.rangeSelector.inputGroup && chart.rangeSelector.inputGroup.element.getAttribute('visibility') !== 'hidden';
801
+ return inputVisible && chart.options.rangeSelector.inputEnabled !== false && chart.rangeSelector.minInput && chart.rangeSelector.maxInput;
777
802
  },
778
803
 
779
804
  // Handle tabs different from left/right (because we don't want to catch left/right in a text area)
780
805
  transformTabs: false,
781
806
 
782
- // Make boxes focusable by script, and accessible
807
+ // Highlight first/last input box
783
808
  init: function(direction) {
784
- each(['minInput', 'maxInput'], function(key, i) {
785
- if (chart.rangeSelector[key]) {
786
- chart.rangeSelector[key].setAttribute('tabindex', '-1');
787
- chart.rangeSelector[key].setAttribute('role', 'textbox');
788
- chart.rangeSelector[key].setAttribute('aria-label', 'Select ' + (i ? 'end' : 'start') + ' date.');
789
- }
790
- });
791
- // Highlight first/last input box
792
809
  chart.highlightedInputRangeIx = direction > 0 ? 0 : 1;
793
810
  chart.rangeSelector[chart.highlightedInputRangeIx ? 'maxInput' : 'minInput'].focus();
794
811
  }
812
+ }),
813
+
814
+ // Legend navigation
815
+ navModuleFactory([
816
+ // Left/Right/Up/Down
817
+ [
818
+ [37, 39, 38, 40],
819
+ function(keyCode) {
820
+ var direction = (keyCode === 37 || keyCode === 38) ? -1 : 1;
821
+ // Try to highlight next/prev legend item
822
+ if (!chart.highlightLegendItem(chart.highlightedLegendItemIx + direction)) {
823
+ return this.move(direction);
824
+ }
825
+ }
826
+ ],
827
+ // Enter/Spacebar
828
+ [
829
+ [13, 32],
830
+ function() {
831
+ fakeClickEvent(chart.legend.allItems[chart.highlightedLegendItemIx].legendItem.element.parentNode);
832
+ }
833
+ ]
834
+ ], {
835
+ // Only run this module if we have at least one legend - wait for it - item.
836
+ validate: function() {
837
+ return chart.legend && chart.legend.allItems && !chart.colorAxis;
838
+ },
839
+
840
+ // Make elements focusable and accessible
841
+ init: function(direction) {
842
+ each(chart.legend.allItems, function(item) {
843
+ item.legendGroup.element.setAttribute('tabindex', '-1');
844
+ item.legendGroup.element.setAttribute('role', 'button');
845
+ item.legendGroup.element.setAttribute('aria-label', 'Toggle visibility of series ' + item.name);
846
+ });
847
+ // Focus first/last item
848
+ chart.highlightLegendItem(direction > 0 ? 0 : chart.legend.allItems.length - 1);
849
+ }
795
850
  })
796
851
  ];
797
852
 
@@ -915,6 +970,18 @@
915
970
  parent.appendChild(exportGroupElement);
916
971
  }
917
972
 
973
+ // Set screen reader properties on input boxes for range selector. We need to do this regardless of whether or not these are visible, as they are
974
+ // by default part of the page's tabindex unless we set them to -1.
975
+ if (chart.rangeSelector) {
976
+ each(['minInput', 'maxInput'], function(key, i) {
977
+ if (chart.rangeSelector[key]) {
978
+ chart.rangeSelector[key].setAttribute('tabindex', '-1');
979
+ chart.rangeSelector[key].setAttribute('role', 'textbox');
980
+ chart.rangeSelector[key].setAttribute('aria-label', 'Select ' + (i ? 'end' : 'start') + ' date.');
981
+ }
982
+ });
983
+ }
984
+
918
985
  // Hide text elements from screen readers
919
986
  each(textElements, function(el) {
920
987
  el.setAttribute('aria-hidden', 'true');
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.0 (2016-09-29)
2
+ * @license Highcharts JS v5.0.3 (2016-11-18)
3
3
  *
4
4
  * (c) 2009-2016 Torstein Honsi
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.0 (2016-09-29)
2
+ * @license Highcharts JS v5.0.3 (2016-11-18)
3
3
  * Boost module
4
4
  *
5
5
  * (c) 2010-2016 Highsoft AS
@@ -28,14 +28,14 @@
28
28
  *
29
29
  * Development plan
30
30
  * - Column range.
31
- * - Heatmap.
31
+ * - Heatmap. Modify the heatmap-canvas demo so that it uses this module.
32
32
  * - Treemap.
33
33
  * - Check how it works with Highstock and data grouping. Currently it only works when navigator.adaptToUpdatedData
34
34
  * is false. It is also recommended to set scrollbar.liveRedraw to false.
35
35
  * - Check inverted charts.
36
36
  * - Check reversed axes.
37
37
  * - Chart callback should be async after last series is drawn. (But not necessarily, we don't do
38
- that with initial series animation).
38
+ that with initial series animation).
39
39
  * - Cache full-size image so we don't have to redraw on hide/show and zoom up. But k-d-tree still
40
40
  * needs to be built.
41
41
  * - Test IE9 and IE10.
@@ -108,11 +108,14 @@
108
108
  }
109
109
 
110
110
  // Set default options
111
- each(['area', 'arearange', 'column', 'line', 'scatter'], function(type) {
112
- if (plotOptions[type]) {
113
- plotOptions[type].boostThreshold = 5000;
111
+ each(
112
+ ['area', 'arearange', 'bubble', 'column', 'line', 'scatter'],
113
+ function(type) {
114
+ if (plotOptions[type]) {
115
+ plotOptions[type].boostThreshold = 5000;
116
+ }
114
117
  }
115
- });
118
+ );
116
119
 
117
120
  /**
118
121
  * Override a bunch of methods the same way. If the number of points is below the threshold,
@@ -144,12 +147,11 @@
144
147
 
145
148
  // A special case for some types - its translate method is already wrapped
146
149
  if (method === 'translate') {
147
- if (seriesTypes.column) {
148
- wrap(seriesTypes.column.prototype, method, branch);
149
- }
150
- if (seriesTypes.arearange) {
151
- wrap(seriesTypes.arearange.prototype, method, branch);
152
- }
150
+ each(['arearange', 'bubble', 'column'], function(type) {
151
+ if (seriesTypes[type]) {
152
+ wrap(seriesTypes[type].prototype, method, branch);
153
+ }
154
+ });
153
155
  }
154
156
  });
155
157
 
@@ -285,7 +287,10 @@
285
287
  r = options.marker && options.marker.radius,
286
288
  cvsDrawPoint = this.cvsDrawPoint,
287
289
  cvsLineTo = options.lineWidth ? this.cvsLineTo : false,
288
- cvsMarker = r <= 1 ? this.cvsMarkerSquare : this.cvsMarkerCircle,
290
+ cvsMarker = r && r <= 1 ?
291
+ this.cvsMarkerSquare :
292
+ this.cvsMarkerCircle,
293
+ strokeBatch = this.cvsStrokeBatch || 1000,
289
294
  enableMouseTracking = options.enableMouseTracking !== false,
290
295
  lastPoint,
291
296
  threshold = options.threshold,
@@ -318,7 +323,7 @@
318
323
  ctx.stroke();
319
324
  }
320
325
  },
321
- drawPoint = function(clientX, plotY, yBottom) {
326
+ drawPoint = function(clientX, plotY, yBottom, i) {
322
327
  if (c === 0) {
323
328
  ctx.beginPath();
324
329
 
@@ -335,14 +340,14 @@
335
340
  } else if (cvsLineTo) {
336
341
  cvsLineTo(ctx, clientX, plotY);
337
342
  } else if (cvsMarker) {
338
- cvsMarker(ctx, clientX, plotY, r);
343
+ cvsMarker.call(series, ctx, clientX, plotY, r, i);
339
344
  }
340
345
  }
341
346
 
342
347
  // We need to stroke the line for every 1000 pixels. It will crash the browser
343
348
  // memory use if we stroke too infrequently.
344
349
  c = c + 1;
345
- if (c === 1000) {
350
+ if (c === strokeBatch) {
346
351
  stroke();
347
352
  c = 0;
348
353
  }
@@ -483,7 +488,8 @@
483
488
  drawPoint(
484
489
  clientX,
485
490
  hasThreshold ? Math.min(plotY, translatedThreshold) : plotY,
486
- hasThreshold ? Math.max(yBottom, translatedThreshold) : yBottom
491
+ hasThreshold ? Math.max(yBottom, translatedThreshold) : yBottom,
492
+ i
487
493
  );
488
494
  addKDPoint(clientX, plotY, maxI);
489
495
  if (yBottom !== plotY) {
@@ -497,7 +503,7 @@
497
503
  }
498
504
  } else {
499
505
  plotY = Math.round(yAxis.toPixels(y, true));
500
- drawPoint(clientX, plotY, yBottom);
506
+ drawPoint(clientX, plotY, yBottom, i);
501
507
  addKDPoint(clientX, plotY, i);
502
508
  }
503
509
  }
@@ -559,6 +565,15 @@
559
565
  };
560
566
  seriesTypes.scatter.prototype.fill = true;
561
567
 
568
+ if (seriesTypes.bubble) {
569
+ seriesTypes.bubble.prototype.cvsMarkerCircle = function(ctx, clientX, plotY, r, i) {
570
+ ctx.moveTo(clientX, plotY);
571
+ ctx.arc(clientX, plotY, this.radii && this.radii[i], 0, 2 * Math.PI, false);
572
+ };
573
+ seriesTypes.bubble.prototype.cvsStrokeBatch = 1;
574
+ }
575
+
576
+
562
577
  extend(seriesTypes.area.prototype, {
563
578
  cvsDrawPoint: function(ctx, clientX, plotY, yBottom, lastPoint) {
564
579
  if (lastPoint && clientX !== lastPoint.clientX) {