xrange-series.src.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /**
  2. * @license Highcharts JS v5.0.6 (2016-12-07)
  3. * X-range series
  4. *
  5. * (c) 2010-2016 Torstein Honsi, Lars A. V. Cabrera
  6. *
  7. * --- WORK IN PROGRESS ---
  8. *
  9. * License: www.highcharts.com/license
  10. */
  11. (function(factory) {
  12. if (typeof module === 'object' && module.exports) {
  13. module.exports = factory;
  14. } else {
  15. factory(Highcharts);
  16. }
  17. }(function(Highcharts) {
  18. (function(H) {
  19. /**
  20. * (c) 2014-2016 Highsoft AS
  21. * Authors: Torstein Honsi, Lars A. V. Cabrera
  22. *
  23. * License: www.highcharts.com/license
  24. */
  25. 'use strict';
  26. var defaultPlotOptions = H.getOptions().plotOptions,
  27. color = H.Color,
  28. columnType = H.seriesTypes.column,
  29. each = H.each,
  30. extendClass = H.extendClass,
  31. isNumber = H.isNumber,
  32. isObject = H.isObject,
  33. merge = H.merge,
  34. pick = H.pick,
  35. seriesTypes = H.seriesTypes,
  36. wrap = H.wrap,
  37. Axis = H.Axis,
  38. Point = H.Point,
  39. Series = H.Series,
  40. pointFormat = '<span style="color:{point.color}">' +
  41. '\u25CF' +
  42. '</span> {series.name}: <b>{point.yCategory}</b><br/>',
  43. xrange = 'xrange';
  44. defaultPlotOptions.xrange = merge(defaultPlotOptions.column, {
  45. tooltip: {
  46. pointFormat: pointFormat
  47. }
  48. });
  49. seriesTypes.xrange = extendClass(columnType, {
  50. pointClass: extendClass(Point, {
  51. // Add x2 and yCategory to the available properties for tooltip formats
  52. getLabelConfig: function() {
  53. var cfg = Point.prototype.getLabelConfig.call(this);
  54. cfg.x2 = this.x2;
  55. cfg.yCategory = this.yCategory = this.series.yAxis.categories && this.series.yAxis.categories[this.y];
  56. return cfg;
  57. }
  58. }),
  59. type: xrange,
  60. forceDL: true,
  61. parallelArrays: ['x', 'x2', 'y'],
  62. requireSorting: false,
  63. animate: seriesTypes.line.prototype.animate,
  64. /**
  65. * Borrow the column series metrics, but with swapped axes. This gives free access
  66. * to features like groupPadding, grouping, pointWidth etc.
  67. */
  68. getColumnMetrics: function() {
  69. var metrics,
  70. chart = this.chart;
  71. function swapAxes() {
  72. each(chart.series, function(s) {
  73. var xAxis = s.xAxis;
  74. s.xAxis = s.yAxis;
  75. s.yAxis = xAxis;
  76. });
  77. }
  78. swapAxes();
  79. this.yAxis.closestPointRange = 1;
  80. metrics = columnType.prototype.getColumnMetrics.call(this);
  81. swapAxes();
  82. return metrics;
  83. },
  84. /**
  85. * Override cropData to show a point where x is outside visible range
  86. * but x2 is outside.
  87. */
  88. cropData: function(xData, yData, min, max) {
  89. // Replace xData with x2Data to find the appropriate cropStart
  90. var cropData = Series.prototype.cropData,
  91. crop = cropData.call(this, this.x2Data, yData, min, max);
  92. // Re-insert the cropped xData
  93. crop.xData = xData.slice(crop.start, crop.end);
  94. return crop;
  95. },
  96. translate: function() {
  97. columnType.prototype.translate.apply(this, arguments);
  98. var series = this,
  99. xAxis = series.xAxis,
  100. metrics = series.columnMetrics,
  101. minPointLength = series.options.minPointLength || 0;
  102. each(series.points, function(point) {
  103. var plotX = point.plotX,
  104. posX = pick(point.x2, point.x + (point.len || 0)),
  105. plotX2 = xAxis.toPixels(posX, true),
  106. width = plotX2 - plotX,
  107. widthDifference,
  108. shapeArgs,
  109. partialFill;
  110. if (minPointLength) {
  111. widthDifference = minPointLength - width;
  112. if (widthDifference < 0) {
  113. widthDifference = 0;
  114. }
  115. plotX -= widthDifference / 2;
  116. plotX2 += widthDifference / 2;
  117. }
  118. plotX = Math.max(plotX, -10);
  119. plotX2 = Math.min(Math.max(plotX2, -10), xAxis.len + 10);
  120. point.shapeArgs = {
  121. x: plotX,
  122. y: point.plotY + metrics.offset,
  123. width: plotX2 - plotX,
  124. height: metrics.width
  125. };
  126. point.tooltipPos[0] += width / 2;
  127. point.tooltipPos[1] -= metrics.width / 2;
  128. // Add a partShapeArgs to the point, based on the shapeArgs property
  129. partialFill = point.partialFill;
  130. if (partialFill) {
  131. // Get the partial fill amount
  132. if (isObject(partialFill)) {
  133. partialFill = partialFill.amount;
  134. }
  135. // If it was not a number, assume 0
  136. if (!isNumber(partialFill)) {
  137. partialFill = 0;
  138. }
  139. shapeArgs = point.shapeArgs;
  140. point.partShapeArgs = {
  141. x: shapeArgs.x,
  142. y: shapeArgs.y + 1,
  143. width: shapeArgs.width * partialFill,
  144. height: shapeArgs.height - 2
  145. };
  146. }
  147. });
  148. },
  149. drawPoints: function() {
  150. var series = this,
  151. chart = this.chart,
  152. options = series.options,
  153. renderer = chart.renderer,
  154. animationLimit = options.animationLimit || 250,
  155. verb = chart.pointCount < animationLimit ? 'animate' : 'attr';
  156. // draw the columns
  157. each(series.points, function(point) {
  158. var plotY = point.plotY,
  159. graphic = point.graphic,
  160. type = point.shapeType,
  161. shapeArgs = point.shapeArgs,
  162. partShapeArgs = point.partShapeArgs,
  163. seriesOpts = series.options,
  164. pfOptions = point.partialFill,
  165. fill,
  166. state = point.selected && 'select',
  167. cutOff = options.stacking && !options.borderRadius;
  168. if (isNumber(plotY) && point.y !== null) {
  169. if (graphic) { // update
  170. point.graphicOriginal[verb](
  171. merge(shapeArgs)
  172. );
  173. if (partShapeArgs) {
  174. point.graphicOverlay[verb](
  175. merge(partShapeArgs)
  176. );
  177. }
  178. } else {
  179. point.graphic = graphic = renderer.g('point')
  180. .attr({
  181. 'class': point.getClassName()
  182. })
  183. .add(point.group || series.group);
  184. point.graphicOriginal = renderer[type](shapeArgs)
  185. .addClass('highcharts-partfill-original')
  186. .add(graphic);
  187. if (partShapeArgs) {
  188. point.graphicOverlay = renderer[type](partShapeArgs)
  189. .addClass('highcharts-partfill-overlay')
  190. .add(graphic);
  191. }
  192. }
  193. } else if (graphic) {
  194. point.graphic = graphic.destroy(); // #1269
  195. }
  196. });
  197. }
  198. });
  199. /**
  200. * Max x2 should be considered in xAxis extremes
  201. */
  202. wrap(Axis.prototype, 'getSeriesExtremes', function(proceed) {
  203. var axis = this,
  204. series = axis.series,
  205. dataMax,
  206. modMax;
  207. proceed.call(this);
  208. if (axis.isXAxis && series.type === xrange) {
  209. dataMax = pick(axis.dataMax, Number.MIN_VALUE);
  210. each(this.series, function(series) {
  211. each(series.x2Data || [], function(val) {
  212. if (val > dataMax) {
  213. dataMax = val;
  214. modMax = true;
  215. }
  216. });
  217. });
  218. if (modMax) {
  219. axis.dataMax = dataMax;
  220. }
  221. }
  222. });
  223. }(Highcharts));
  224. }));