d6bb182ee0334b2635204214610d75bc50087969.svn-base 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /**
  2. * Highcharts JS v4.2.5 (2016-05-06)
  3. * Highcharts Broken Axis module
  4. *
  5. * License: www.highcharts.com/license
  6. */
  7. (function (factory) {
  8. /*= if (!build.assembly) { =*/
  9. if (typeof module === 'object' && module.exports) {
  10. module.exports = factory;
  11. return;
  12. }
  13. /*= } =*/
  14. factory(Highcharts);
  15. }(function (H) {
  16. 'use strict';
  17. var pick = H.pick,
  18. wrap = H.wrap,
  19. each = H.each,
  20. extend = H.extend,
  21. fireEvent = H.fireEvent,
  22. Axis = H.Axis,
  23. Series = H.Series;
  24. function stripArguments() {
  25. return Array.prototype.slice.call(arguments, 1);
  26. }
  27. extend(Axis.prototype, {
  28. isInBreak: function (brk, val) {
  29. var ret,
  30. repeat = brk.repeat || Infinity,
  31. from = brk.from,
  32. length = brk.to - brk.from,
  33. test = (val >= from ? (val - from) % repeat : repeat - ((from - val) % repeat));
  34. if (!brk.inclusive) {
  35. ret = test < length && test !== 0;
  36. } else {
  37. ret = test <= length;
  38. }
  39. return ret;
  40. },
  41. isInAnyBreak: function (val, testKeep) {
  42. var breaks = this.options.breaks,
  43. i = breaks && breaks.length,
  44. inbrk,
  45. keep,
  46. ret;
  47. if (i) {
  48. while (i--) {
  49. if (this.isInBreak(breaks[i], val)) {
  50. inbrk = true;
  51. if (!keep) {
  52. keep = pick(breaks[i].showPoints, this.isXAxis ? false : true);
  53. }
  54. }
  55. }
  56. if (inbrk && testKeep) {
  57. ret = inbrk && !keep;
  58. } else {
  59. ret = inbrk;
  60. }
  61. }
  62. return ret;
  63. }
  64. });
  65. wrap(Axis.prototype, 'setTickPositions', function (proceed) {
  66. proceed.apply(this, Array.prototype.slice.call(arguments, 1));
  67. if (this.options.breaks) {
  68. var axis = this,
  69. tickPositions = this.tickPositions,
  70. info = this.tickPositions.info,
  71. newPositions = [],
  72. i;
  73. for (i = 0; i < tickPositions.length; i++) {
  74. if (!axis.isInAnyBreak(tickPositions[i])) {
  75. newPositions.push(tickPositions[i]);
  76. }
  77. }
  78. this.tickPositions = newPositions;
  79. this.tickPositions.info = info;
  80. }
  81. });
  82. wrap(Axis.prototype, 'init', function (proceed, chart, userOptions) {
  83. // Force Axis to be not-ordinal when breaks are defined
  84. if (userOptions.breaks && userOptions.breaks.length) {
  85. userOptions.ordinal = false;
  86. }
  87. proceed.call(this, chart, userOptions);
  88. if (this.options.breaks) {
  89. var axis = this;
  90. axis.isBroken = true;
  91. this.val2lin = function (val) {
  92. var nval = val,
  93. brk,
  94. i;
  95. for (i = 0; i < axis.breakArray.length; i++) {
  96. brk = axis.breakArray[i];
  97. if (brk.to <= val) {
  98. nval -= brk.len;
  99. } else if (brk.from >= val) {
  100. break;
  101. } else if (axis.isInBreak(brk, val)) {
  102. nval -= (val - brk.from);
  103. break;
  104. }
  105. }
  106. return nval;
  107. };
  108. this.lin2val = function (val) {
  109. var nval = val,
  110. brk,
  111. i;
  112. for (i = 0; i < axis.breakArray.length; i++) {
  113. brk = axis.breakArray[i];
  114. if (brk.from >= nval) {
  115. break;
  116. } else if (brk.to < nval) {
  117. nval += brk.len;
  118. } else if (axis.isInBreak(brk, nval)) {
  119. nval += brk.len;
  120. }
  121. }
  122. return nval;
  123. };
  124. this.setExtremes = function (newMin, newMax, redraw, animation, eventArguments) {
  125. // If trying to set extremes inside a break, extend it to before and after the break ( #3857 )
  126. while (this.isInAnyBreak(newMin)) {
  127. newMin -= this.closestPointRange;
  128. }
  129. while (this.isInAnyBreak(newMax)) {
  130. newMax -= this.closestPointRange;
  131. }
  132. Axis.prototype.setExtremes.call(this, newMin, newMax, redraw, animation, eventArguments);
  133. };
  134. this.setAxisTranslation = function (saveOld) {
  135. Axis.prototype.setAxisTranslation.call(this, saveOld);
  136. var breaks = axis.options.breaks,
  137. breakArrayT = [], // Temporary one
  138. breakArray = [],
  139. length = 0,
  140. inBrk,
  141. repeat,
  142. brk,
  143. min = axis.userMin || axis.min,
  144. max = axis.userMax || axis.max,
  145. start,
  146. i,
  147. j;
  148. // Min & max check (#4247)
  149. for (i in breaks) {
  150. brk = breaks[i];
  151. repeat = brk.repeat || Infinity;
  152. if (axis.isInBreak(brk, min)) {
  153. min += (brk.to % repeat) - (min % repeat);
  154. }
  155. if (axis.isInBreak(brk, max)) {
  156. max -= (max % repeat) - (brk.from % repeat);
  157. }
  158. }
  159. // Construct an array holding all breaks in the axis
  160. for (i in breaks) {
  161. brk = breaks[i];
  162. start = brk.from;
  163. repeat = brk.repeat || Infinity;
  164. while (start - repeat > min) {
  165. start -= repeat;
  166. }
  167. while (start < min) {
  168. start += repeat;
  169. }
  170. for (j = start; j < max; j += repeat) {
  171. breakArrayT.push({
  172. value: j,
  173. move: 'in'
  174. });
  175. breakArrayT.push({
  176. value: j + (brk.to - brk.from),
  177. move: 'out',
  178. size: brk.breakSize
  179. });
  180. }
  181. }
  182. breakArrayT.sort(function (a, b) {
  183. var ret;
  184. if (a.value === b.value) {
  185. ret = (a.move === 'in' ? 0 : 1) - (b.move === 'in' ? 0 : 1);
  186. } else {
  187. ret = a.value - b.value;
  188. }
  189. return ret;
  190. });
  191. // Simplify the breaks
  192. inBrk = 0;
  193. start = min;
  194. for (i in breakArrayT) {
  195. brk = breakArrayT[i];
  196. inBrk += (brk.move === 'in' ? 1 : -1);
  197. if (inBrk === 1 && brk.move === 'in') {
  198. start = brk.value;
  199. }
  200. if (inBrk === 0) {
  201. breakArray.push({
  202. from: start,
  203. to: brk.value,
  204. len: brk.value - start - (brk.size || 0)
  205. });
  206. length += brk.value - start - (brk.size || 0);
  207. }
  208. }
  209. axis.breakArray = breakArray;
  210. fireEvent(axis, 'afterBreaks');
  211. axis.transA *= ((max - axis.min) / (max - min - length));
  212. axis.min = min;
  213. axis.max = max;
  214. };
  215. }
  216. });
  217. wrap(Series.prototype, 'generatePoints', function (proceed) {
  218. proceed.apply(this, stripArguments(arguments));
  219. var series = this,
  220. xAxis = series.xAxis,
  221. yAxis = series.yAxis,
  222. points = series.points,
  223. point,
  224. i = points.length,
  225. connectNulls = series.options.connectNulls,
  226. nullGap;
  227. if (xAxis && yAxis && (xAxis.options.breaks || yAxis.options.breaks)) {
  228. while (i--) {
  229. point = points[i];
  230. nullGap = point.y === null && connectNulls === false; // respect nulls inside the break (#4275)
  231. if (!nullGap && (xAxis.isInAnyBreak(point.x, true) || yAxis.isInAnyBreak(point.y, true))) {
  232. points.splice(i, 1);
  233. if (this.data[i]) {
  234. this.data[i].destroyElements(); // removes the graphics for this point if they exist
  235. }
  236. }
  237. }
  238. }
  239. });
  240. function drawPointsWrapped(proceed) {
  241. proceed.apply(this);
  242. this.drawBreaks(this.xAxis, ['x']);
  243. this.drawBreaks(this.yAxis, pick(this.pointArrayMap, ['y']));
  244. }
  245. H.Series.prototype.drawBreaks = function (axis, keys) {
  246. var series = this,
  247. points = series.points,
  248. breaks,
  249. threshold,
  250. eventName,
  251. y;
  252. each(keys, function (key) {
  253. breaks = axis.breakArray || [];
  254. threshold = axis.isXAxis ? axis.min : pick(series.options.threshold, axis.min);
  255. each(points, function (point) {
  256. y = pick(point['stack' + key.toUpperCase()], point[key]);
  257. each(breaks, function (brk) {
  258. eventName = false;
  259. if ((threshold < brk.from && y > brk.to) || (threshold > brk.from && y < brk.from)) {
  260. eventName = 'pointBreak';
  261. } else if ((threshold < brk.from && y > brk.from && y < brk.to) || (threshold > brk.from && y > brk.to && y < brk.from)) { // point falls inside the break
  262. eventName = 'pointInBreak';
  263. }
  264. if (eventName) {
  265. fireEvent(axis, eventName, { point: point, brk: brk });
  266. }
  267. });
  268. });
  269. });
  270. };
  271. wrap(H.seriesTypes.column.prototype, 'drawPoints', drawPointsWrapped);
  272. wrap(H.Series.prototype, 'drawPoints', drawPointsWrapped);
  273. }));