UNPKG

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