on-series.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /* *
  2. * (c) 2010-2019 Torstein Honsi
  3. *
  4. * License: www.highcharts.com/license
  5. */
  6. 'use strict';
  7. import H from '../parts/Globals.js';
  8. var defined = H.defined,
  9. seriesTypes = H.seriesTypes,
  10. stableSort = H.stableSort;
  11. /**
  12. * @private
  13. * @mixin onSeriesMixin
  14. */
  15. var onSeriesMixin = {
  16. /**
  17. * Override getPlotBox. If the onSeries option is valid, return the plot box
  18. * of the onSeries, otherwise proceed as usual.
  19. *
  20. * @private
  21. * @function onSeriesMixin.getPlotBox
  22. *
  23. * @return {Highcharts.SeriesPlotBoxObject}
  24. */
  25. getPlotBox: function () {
  26. return H.Series.prototype.getPlotBox.call(
  27. (
  28. this.options.onSeries &&
  29. this.chart.get(this.options.onSeries)
  30. ) || this
  31. );
  32. },
  33. /**
  34. * Extend the translate method by placing the point on the related series
  35. *
  36. * @private
  37. * @function onSeriesMixin.translate
  38. */
  39. translate: function () {
  40. seriesTypes.column.prototype.translate.apply(this);
  41. var series = this,
  42. options = series.options,
  43. chart = series.chart,
  44. points = series.points,
  45. cursor = points.length - 1,
  46. point,
  47. lastPoint,
  48. optionsOnSeries = options.onSeries,
  49. onSeries = optionsOnSeries && chart.get(optionsOnSeries),
  50. onKey = options.onKey || 'y',
  51. step = onSeries && onSeries.options.step,
  52. onData = onSeries && onSeries.points,
  53. i = onData && onData.length,
  54. inverted = chart.inverted,
  55. xAxis = series.xAxis,
  56. yAxis = series.yAxis,
  57. xOffset = 0,
  58. leftPoint,
  59. lastX,
  60. rightPoint,
  61. currentDataGrouping,
  62. distanceRatio;
  63. // relate to a master series
  64. if (onSeries && onSeries.visible && i) {
  65. xOffset = (onSeries.pointXOffset || 0) + (onSeries.barW || 0) / 2;
  66. currentDataGrouping = onSeries.currentDataGrouping;
  67. lastX = (
  68. onData[i - 1].x +
  69. (currentDataGrouping ? currentDataGrouping.totalRange : 0)
  70. ); // #2374
  71. // sort the data points
  72. stableSort(points, function (a, b) {
  73. return (a.x - b.x);
  74. });
  75. onKey = 'plot' + onKey[0].toUpperCase() + onKey.substr(1);
  76. while (i-- && points[cursor]) {
  77. leftPoint = onData[i];
  78. point = points[cursor];
  79. point.y = leftPoint.y;
  80. if (leftPoint.x <= point.x && leftPoint[onKey] !== undefined) {
  81. if (point.x <= lastX) { // #803
  82. point.plotY = leftPoint[onKey];
  83. // interpolate between points, #666
  84. if (leftPoint.x < point.x && !step) {
  85. rightPoint = onData[i + 1];
  86. if (rightPoint && rightPoint[onKey] !== undefined) {
  87. // the distance ratio, between 0 and 1
  88. distanceRatio = (point.x - leftPoint.x) /
  89. (rightPoint.x - leftPoint.x);
  90. point.plotY +=
  91. distanceRatio *
  92. // the plotY distance
  93. (rightPoint[onKey] - leftPoint[onKey]);
  94. point.y +=
  95. distanceRatio *
  96. (rightPoint.y - leftPoint.y);
  97. }
  98. }
  99. }
  100. cursor--;
  101. i++; // check again for points in the same x position
  102. if (cursor < 0) {
  103. break;
  104. }
  105. }
  106. }
  107. }
  108. // Add plotY position and handle stacking
  109. points.forEach(function (point, i) {
  110. var stackIndex;
  111. point.plotX += xOffset; // #2049
  112. // Undefined plotY means the point is either on axis, outside series
  113. // range or hidden series. If the series is outside the range of the
  114. // x axis it should fall through with an undefined plotY, but then
  115. // we must remove the shapeArgs (#847). For inverted charts, we need
  116. // to calculate position anyway, because series.invertGroups is not
  117. // defined
  118. if (point.plotY === undefined || inverted) {
  119. if (point.plotX >= 0 && point.plotX <= xAxis.len) {
  120. // We're inside xAxis range
  121. if (inverted) {
  122. point.plotY = xAxis.translate(point.x, 0, 1, 0, 1);
  123. point.plotX = defined(point.y) ?
  124. yAxis.translate(point.y, 0, 0, 0, 1) : 0;
  125. } else {
  126. point.plotY = (xAxis.opposite ? 0 : series.yAxis.len) +
  127. xAxis.offset; // For the windbarb demo
  128. }
  129. } else {
  130. point.shapeArgs = {}; // 847
  131. }
  132. }
  133. // if multiple flags appear at the same x, order them into a stack
  134. lastPoint = points[i - 1];
  135. if (lastPoint && lastPoint.plotX === point.plotX) {
  136. if (lastPoint.stackIndex === undefined) {
  137. lastPoint.stackIndex = 0;
  138. }
  139. stackIndex = lastPoint.stackIndex + 1;
  140. }
  141. point.stackIndex = stackIndex; // #3639
  142. });
  143. this.onSeries = onSeries;
  144. }
  145. };
  146. export default onSeriesMixin;