@progress/kendo-charts 2.7.2-develop.3 → 2.7.3-develop.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdn/js/kendo-charts.js +1 -1
- package/dist/cdn/main.js +1 -1
- package/dist/es/chart/bar-chart/bar.js +16 -1
- package/dist/es/chart/chart-container.js +59 -14
- package/dist/es/chart/line-chart/line-point.js +20 -3
- package/dist/es/chart/pane.js +5 -0
- package/dist/es/chart/plotarea/plotarea-base.js +50 -3
- package/dist/es/chart/utils/unclip-box.js +10 -0
- package/dist/es/chart/utils.js +1 -0
- package/dist/es/common/get-supported-features.js +2 -2
- package/dist/es/core/box.js +9 -0
- package/dist/es2015/chart/bar-chart/bar.js +16 -1
- package/dist/es2015/chart/chart-container.js +59 -14
- package/dist/es2015/chart/line-chart/line-point.js +20 -3
- package/dist/es2015/chart/pane.js +5 -0
- package/dist/es2015/chart/plotarea/plotarea-base.js +50 -3
- package/dist/es2015/chart/utils/unclip-box.js +10 -0
- package/dist/es2015/chart/utils.js +1 -0
- package/dist/es2015/common/get-supported-features.js +2 -2
- package/dist/es2015/core/box.js +9 -0
- package/dist/npm/main.js +166 -20
- package/dist/systemjs/kendo-charts.js +1 -1
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ import { CHART_POINT_ROLE_DESCRIPTION, CHART_POINT_CLASSNAME, CHART_POINT_ROLE,
|
|
|
6
6
|
|
|
7
7
|
import hasGradientOverlay from '../utils/has-gradient-overlay';
|
|
8
8
|
|
|
9
|
-
import { ChartElement, createPatternFill, Point } from '../../core';
|
|
9
|
+
import { ChartElement, createPatternFill, Point, Box } from '../../core';
|
|
10
10
|
|
|
11
11
|
import PointEventsMixin from '../mixins/point-events-mixin';
|
|
12
12
|
import NoteMixin from '../mixins/note-mixin';
|
|
@@ -14,6 +14,7 @@ import AccessibilityAttributesMixin from '../mixins/accessibility-attributes-mix
|
|
|
14
14
|
|
|
15
15
|
import { WHITE, LEFT, RIGHT, BOTTOM, TOP } from '../../common/constants';
|
|
16
16
|
import { alignPathToPixel, deepExtend, defined, getTemplate, valueOrDefault } from '../../common';
|
|
17
|
+
import unclipBox from '../utils/unclip-box';
|
|
17
18
|
|
|
18
19
|
const BAR_ALIGN_MIN_WIDTH = 6;
|
|
19
20
|
|
|
@@ -272,6 +273,20 @@ class Bar extends ChartElement {
|
|
|
272
273
|
return this.box.overlaps(box);
|
|
273
274
|
}
|
|
274
275
|
|
|
276
|
+
unclipBox() {
|
|
277
|
+
const label = this.label && this.label.textBox;
|
|
278
|
+
return unclipBox(this.box.clone(), [label, this.note]);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
labelBox() {
|
|
282
|
+
const label = this.label && this.label.textBox;
|
|
283
|
+
return label ? label.box : new Box();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
noteBox() {
|
|
287
|
+
return this.note ? this.note.box : new Box();
|
|
288
|
+
}
|
|
289
|
+
|
|
275
290
|
pointData() {
|
|
276
291
|
return {
|
|
277
292
|
dataItem: this.dataItem,
|
|
@@ -2,6 +2,7 @@ import { drawing as draw } from '@progress/kendo-drawing';
|
|
|
2
2
|
import { alignPathToPixel } from '../common';
|
|
3
3
|
|
|
4
4
|
import { ChartElement } from '../core';
|
|
5
|
+
import { Box } from '../core';
|
|
5
6
|
|
|
6
7
|
class ChartContainer extends ChartElement {
|
|
7
8
|
constructor(options, pane) {
|
|
@@ -49,31 +50,75 @@ class ChartContainer extends ChartElement {
|
|
|
49
50
|
const { children: charts, clipBox } = this;
|
|
50
51
|
|
|
51
52
|
for (let i = 0; i < charts.length; i++) {
|
|
52
|
-
const points = charts[i].points ||
|
|
53
|
+
const points = charts[i].points || [];
|
|
53
54
|
const length = points.length;
|
|
54
55
|
|
|
55
56
|
for (let j = 0; j < length; j++) {
|
|
56
57
|
const point = points[j];
|
|
57
|
-
if (point && point.visible !== false && point.overlapsBox
|
|
58
|
-
if (point.
|
|
59
|
-
point.unclipElements
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (label.
|
|
65
|
-
label.alignToClipBox
|
|
58
|
+
if (point && point.visible !== false && point.overlapsBox) {
|
|
59
|
+
if (point.overlapsBox(clipBox)) {
|
|
60
|
+
if (point.unclipElements) {
|
|
61
|
+
point.unclipElements();
|
|
62
|
+
} else {
|
|
63
|
+
const { label, note } = point;
|
|
64
|
+
|
|
65
|
+
if (label && label.options.visible) {
|
|
66
|
+
if (label.alignToClipBox) {
|
|
67
|
+
label.alignToClipBox(clipBox);
|
|
68
|
+
}
|
|
69
|
+
label.options.noclip = true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (note && note.options.visible) {
|
|
73
|
+
note.options.noclip = true;
|
|
66
74
|
}
|
|
67
|
-
label.options.noclip = true;
|
|
68
75
|
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
unclipBox() {
|
|
83
|
+
const { children: charts } = this;
|
|
84
|
+
const clipBox = this._clipBox();
|
|
85
|
+
const box = clipBox.clone();
|
|
86
|
+
|
|
87
|
+
for (let i = 0; i < charts.length; i++) {
|
|
88
|
+
const points = charts[i].points || [];
|
|
89
|
+
const length = points.length;
|
|
69
90
|
|
|
70
|
-
|
|
71
|
-
|
|
91
|
+
for (let j = 0; j < length; j++) {
|
|
92
|
+
const point = points[j];
|
|
93
|
+
|
|
94
|
+
if (point && point.unclipBox && point.overlapsBox && point.visible !== false) {
|
|
95
|
+
if (!point.overlapsBox(clipBox)) {
|
|
96
|
+
// Hide points outside of the viewport (clipBox)
|
|
97
|
+
if (point.clipElements) {
|
|
98
|
+
point.clipElements();
|
|
72
99
|
}
|
|
100
|
+
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Extend viewport to include all point elements, including labels
|
|
105
|
+
const unclipBox = point.unclipBox();
|
|
106
|
+
if (box.overlaps(unclipBox)) {
|
|
107
|
+
const labelBox = point.labelBox ? point.labelBox() : new Box();
|
|
108
|
+
const noteBox = point.noteBox ? point.noteBox() : new Box();
|
|
109
|
+
|
|
110
|
+
const heightLimit = Math.max(labelBox.height(), noteBox.height());
|
|
111
|
+
const widthLimit = Math.max(labelBox.width(), noteBox.width());
|
|
112
|
+
|
|
113
|
+
// Limit the size change of the viewport to the label and note boxes dimensions
|
|
114
|
+
// to avoid extending it too much.
|
|
115
|
+
box.wrapLimit(unclipBox, widthLimit, heightLimit);
|
|
73
116
|
}
|
|
74
117
|
}
|
|
75
118
|
}
|
|
76
119
|
}
|
|
120
|
+
|
|
121
|
+
return box;
|
|
77
122
|
}
|
|
78
123
|
|
|
79
124
|
destroy() {
|
|
@@ -85,4 +130,4 @@ class ChartContainer extends ChartElement {
|
|
|
85
130
|
|
|
86
131
|
ChartContainer.prototype.isStackRoot = true;
|
|
87
132
|
|
|
88
|
-
export default ChartContainer;
|
|
133
|
+
export default ChartContainer;
|
|
@@ -9,13 +9,14 @@ import { LINE_MARKER_SIZE, FADEIN, INITIAL_ANIMATION_DURATION, BORDER_BRIGHTNESS
|
|
|
9
9
|
import { WHITE, CIRCLE, CENTER, TOP, BOTTOM, LEFT, HIGHLIGHT_ZINDEX } from '../../common/constants';
|
|
10
10
|
import { deepExtend, defined, getTemplate, getAriaTemplate, valueOrDefault, getSpacing } from '../../common';
|
|
11
11
|
import guid from '../../core/utils/guid';
|
|
12
|
+
import unclipBox from '../utils/unclip-box';
|
|
12
13
|
|
|
13
14
|
class LinePoint extends ChartElement {
|
|
14
15
|
constructor(value, options) {
|
|
15
16
|
super();
|
|
16
17
|
|
|
17
18
|
this.value = value;
|
|
18
|
-
this.options = options;
|
|
19
|
+
this.options = Object.assign({}, options);
|
|
19
20
|
this.aboveAxis = valueOrDefault(this.options.aboveAxis, true);
|
|
20
21
|
this.tooltipTracking = true;
|
|
21
22
|
this._id = guid();
|
|
@@ -103,7 +104,7 @@ class LinePoint extends ChartElement {
|
|
|
103
104
|
return border;
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
createVisual() {}
|
|
107
|
+
createVisual() { }
|
|
107
108
|
|
|
108
109
|
createMarker() {
|
|
109
110
|
const options = this.options.markers;
|
|
@@ -242,7 +243,7 @@ class LinePoint extends ChartElement {
|
|
|
242
243
|
const size = this.options.markers.size;
|
|
243
244
|
const halfSize = size / 2;
|
|
244
245
|
const center = this.box.center();
|
|
245
|
-
rect = new geom.Rect([
|
|
246
|
+
rect = new geom.Rect([center.x - halfSize, center.y - halfSize], [size, size]);
|
|
246
247
|
}
|
|
247
248
|
|
|
248
249
|
return {
|
|
@@ -311,6 +312,10 @@ class LinePoint extends ChartElement {
|
|
|
311
312
|
return markerBox.overlaps(box);
|
|
312
313
|
}
|
|
313
314
|
|
|
315
|
+
clipElements() {
|
|
316
|
+
this.options.visible = false;
|
|
317
|
+
}
|
|
318
|
+
|
|
314
319
|
unclipElements() {
|
|
315
320
|
if (this.label) {
|
|
316
321
|
this.label.options.noclip = true;
|
|
@@ -321,6 +326,18 @@ class LinePoint extends ChartElement {
|
|
|
321
326
|
}
|
|
322
327
|
}
|
|
323
328
|
|
|
329
|
+
unclipBox() {
|
|
330
|
+
return unclipBox(this.markerBox().clone(), [this.label, this.note]);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
labelBox() {
|
|
334
|
+
return this.label ? this.label.box : new Box();
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
noteBox() {
|
|
338
|
+
return this.note ? this.note.box : new Box();
|
|
339
|
+
}
|
|
340
|
+
|
|
324
341
|
pointData() {
|
|
325
342
|
return {
|
|
326
343
|
dataItem: this.dataItem,
|
package/dist/es/chart/pane.js
CHANGED
|
@@ -99,6 +99,11 @@ class Pane extends BoxElement {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
// This is the box for the charts in the pane _and_ all the overflowing ("unclipped") labels.
|
|
103
|
+
unclipBox() {
|
|
104
|
+
return this.chartContainer.unclipBox();
|
|
105
|
+
}
|
|
106
|
+
|
|
102
107
|
visualStyle() {
|
|
103
108
|
const style = super.visualStyle();
|
|
104
109
|
style.zIndex = -10;
|
|
@@ -7,8 +7,10 @@ import { hasValue } from '../utils';
|
|
|
7
7
|
import SeriesBinder from '../series-binder';
|
|
8
8
|
|
|
9
9
|
import { WHITE, BLACK, X, Y, COORD_PRECISION, TOP, BOTTOM, LEFT, RIGHT, START, END, INHERIT } from '../../common/constants';
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import {
|
|
11
|
+
append, deepExtend, defined, getSpacing, getTemplate, inArray, isFunction, isString,
|
|
12
|
+
limitValue, round, setDefaultOptions, last, cycleIndex
|
|
13
|
+
} from '../../common';
|
|
12
14
|
import { TRENDLINE_SERIES } from '../constants';
|
|
13
15
|
|
|
14
16
|
const visiblePoint = (point) => point.options.visible !== false;
|
|
@@ -291,7 +293,7 @@ class PlotAreaBase extends ChartElement {
|
|
|
291
293
|
if (seriesByPane[pane]) {
|
|
292
294
|
seriesByPane[pane].push(currentSeries);
|
|
293
295
|
} else {
|
|
294
|
-
seriesByPane[pane] = [
|
|
296
|
+
seriesByPane[pane] = [currentSeries];
|
|
295
297
|
}
|
|
296
298
|
}
|
|
297
299
|
|
|
@@ -317,6 +319,15 @@ class PlotAreaBase extends ChartElement {
|
|
|
317
319
|
const margin = getSpacing(options.margin);
|
|
318
320
|
|
|
319
321
|
this.box = targetBox.clone().unpad(margin);
|
|
322
|
+
|
|
323
|
+
this.reflowArea(panes);
|
|
324
|
+
|
|
325
|
+
if (this.ensureLabelsFit(panes)) {
|
|
326
|
+
this.reflowArea(panes);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
reflowArea(panes) {
|
|
320
331
|
this.reflowPanes();
|
|
321
332
|
|
|
322
333
|
this.detachLabels();
|
|
@@ -324,6 +335,42 @@ class PlotAreaBase extends ChartElement {
|
|
|
324
335
|
this.reflowCharts(panes);
|
|
325
336
|
}
|
|
326
337
|
|
|
338
|
+
ensureLabelsFit(panes) {
|
|
339
|
+
let change = false;
|
|
340
|
+
|
|
341
|
+
panes.forEach((pane) => {
|
|
342
|
+
const unclipBox = pane.unclipBox();
|
|
343
|
+
const clipBox = pane.chartContainer._clipBox();
|
|
344
|
+
const padding = getSpacing(pane.options.padding || {});
|
|
345
|
+
|
|
346
|
+
if (unclipBox.y1 < clipBox.y1 + padding.top) {
|
|
347
|
+
change = true;
|
|
348
|
+
padding.top = clipBox.y1 - unclipBox.y1 + padding.top;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (unclipBox.y2 > clipBox.y2 - padding.bottom) {
|
|
352
|
+
change = true;
|
|
353
|
+
padding.bottom = unclipBox.y2 - clipBox.y2 + padding.bottom;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (unclipBox.x1 < clipBox.x1 + padding.left) {
|
|
357
|
+
change = true;
|
|
358
|
+
padding.left = clipBox.x1 - unclipBox.x1 + padding.left;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (unclipBox.x2 > clipBox.x2 - padding.right) {
|
|
362
|
+
change = true;
|
|
363
|
+
padding.right = unclipBox.x2 - clipBox.x2 + padding.right;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (change) {
|
|
367
|
+
pane.options.padding = padding;
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
return change;
|
|
372
|
+
}
|
|
373
|
+
|
|
327
374
|
redraw(panes) {
|
|
328
375
|
const panesArray = [].concat(panes);
|
|
329
376
|
this.initSeries();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default function unclipBox(box, elements) {
|
|
2
|
+
elements.forEach(element => {
|
|
3
|
+
const options = element && element.options;
|
|
4
|
+
const elBox = element && (element.box || element.wrapperBox);
|
|
5
|
+
if (options && elBox && options.noclip !== false && options.visible !== false) {
|
|
6
|
+
box.wrap(elBox);
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
return box;
|
|
10
|
+
}
|
package/dist/es/chart/utils.js
CHANGED
|
@@ -15,3 +15,4 @@ export { default as isDateAxis } from './utils/is-date-axis';
|
|
|
15
15
|
export { default as segmentVisible } from './utils/segment-visible';
|
|
16
16
|
export { default as singleItemOrArray } from './utils/single-item-or-array';
|
|
17
17
|
export { default as createOutOfRangePoints } from './utils/create-out-of-range-points';
|
|
18
|
+
export { default as unclipBox } from './utils/unclip-box';
|
|
@@ -13,8 +13,8 @@ function detectOS(ua) {
|
|
|
13
13
|
wp: /(Windows Phone(?: OS)?)\s(\d+)\.(\d+(\.\d+)?)/,
|
|
14
14
|
fire: /(Silk)\/(\d+)\.(\d+(\.\d+)?)/,
|
|
15
15
|
android: /(Android|Android.*(?:Opera|Firefox).*?\/)\s*(\d+)\.?(\d+(\.\d+)?)?/,
|
|
16
|
-
iphone: /(iPhone|iPod).*OS\s+(\d+)[
|
|
17
|
-
ipad: /(iPad).*OS\s+(\d+)[
|
|
16
|
+
iphone: /(iPhone|iPod).*OS\s+(\d+)[._]([\d._]+)/,
|
|
17
|
+
ipad: /(iPad).*OS\s+(\d+)[._]([\d_]+)/,
|
|
18
18
|
playbook: /(PlayBook).*?Tablet\s*OS\s*(\d+)\.(\d+(\.\d+)?)/,
|
|
19
19
|
windows: /(MSIE)\s+(\d+)\.(\d+(\.\d+)?)/,
|
|
20
20
|
tizen: /(tizen).*?Version\/(\d+)\.(\d+(\.\d+)?)/i,
|
package/dist/es/core/box.js
CHANGED
|
@@ -63,6 +63,15 @@ class Box extends Class {
|
|
|
63
63
|
return this;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
wrapLimit(targetBox, widthLimit, heightLimit) {
|
|
67
|
+
this.x1 = Math.min(this.x1, Math.max(this.x1 - widthLimit, targetBox.x1));
|
|
68
|
+
this.y1 = Math.min(this.y1, Math.max(this.y1 - heightLimit, targetBox.y1));
|
|
69
|
+
this.x2 = Math.max(this.x2, Math.min(this.x2 + widthLimit, targetBox.x2));
|
|
70
|
+
this.y2 = Math.max(this.y2, Math.min(this.y2 + heightLimit, targetBox.y2));
|
|
71
|
+
|
|
72
|
+
return this;
|
|
73
|
+
}
|
|
74
|
+
|
|
66
75
|
wrapPoint(point) {
|
|
67
76
|
const arrayPoint = isArray(point);
|
|
68
77
|
const x = arrayPoint ? point[0] : point.x;
|
|
@@ -6,7 +6,7 @@ import { CHART_POINT_ROLE_DESCRIPTION, CHART_POINT_CLASSNAME, CHART_POINT_ROLE,
|
|
|
6
6
|
|
|
7
7
|
import hasGradientOverlay from '../utils/has-gradient-overlay';
|
|
8
8
|
|
|
9
|
-
import { ChartElement, createPatternFill, Point } from '../../core';
|
|
9
|
+
import { ChartElement, createPatternFill, Point, Box } from '../../core';
|
|
10
10
|
|
|
11
11
|
import PointEventsMixin from '../mixins/point-events-mixin';
|
|
12
12
|
import NoteMixin from '../mixins/note-mixin';
|
|
@@ -14,6 +14,7 @@ import AccessibilityAttributesMixin from '../mixins/accessibility-attributes-mix
|
|
|
14
14
|
|
|
15
15
|
import { WHITE, LEFT, RIGHT, BOTTOM, TOP } from '../../common/constants';
|
|
16
16
|
import { alignPathToPixel, deepExtend, defined, getTemplate, valueOrDefault } from '../../common';
|
|
17
|
+
import unclipBox from '../utils/unclip-box';
|
|
17
18
|
|
|
18
19
|
const BAR_ALIGN_MIN_WIDTH = 6;
|
|
19
20
|
|
|
@@ -272,6 +273,20 @@ class Bar extends ChartElement {
|
|
|
272
273
|
return this.box.overlaps(box);
|
|
273
274
|
}
|
|
274
275
|
|
|
276
|
+
unclipBox() {
|
|
277
|
+
const label = this.label && this.label.textBox;
|
|
278
|
+
return unclipBox(this.box.clone(), [label, this.note]);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
labelBox() {
|
|
282
|
+
const label = this.label && this.label.textBox;
|
|
283
|
+
return label ? label.box : new Box();
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
noteBox() {
|
|
287
|
+
return this.note ? this.note.box : new Box();
|
|
288
|
+
}
|
|
289
|
+
|
|
275
290
|
pointData() {
|
|
276
291
|
return {
|
|
277
292
|
dataItem: this.dataItem,
|
|
@@ -2,6 +2,7 @@ import { drawing as draw } from '@progress/kendo-drawing';
|
|
|
2
2
|
import { alignPathToPixel } from '../common';
|
|
3
3
|
|
|
4
4
|
import { ChartElement } from '../core';
|
|
5
|
+
import { Box } from '../core';
|
|
5
6
|
|
|
6
7
|
class ChartContainer extends ChartElement {
|
|
7
8
|
constructor(options, pane) {
|
|
@@ -49,31 +50,75 @@ class ChartContainer extends ChartElement {
|
|
|
49
50
|
const { children: charts, clipBox } = this;
|
|
50
51
|
|
|
51
52
|
for (let i = 0; i < charts.length; i++) {
|
|
52
|
-
const points = charts[i].points ||
|
|
53
|
+
const points = charts[i].points || [];
|
|
53
54
|
const length = points.length;
|
|
54
55
|
|
|
55
56
|
for (let j = 0; j < length; j++) {
|
|
56
57
|
const point = points[j];
|
|
57
|
-
if (point && point.visible !== false && point.overlapsBox
|
|
58
|
-
if (point.
|
|
59
|
-
point.unclipElements
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (label.
|
|
65
|
-
label.alignToClipBox
|
|
58
|
+
if (point && point.visible !== false && point.overlapsBox) {
|
|
59
|
+
if (point.overlapsBox(clipBox)) {
|
|
60
|
+
if (point.unclipElements) {
|
|
61
|
+
point.unclipElements();
|
|
62
|
+
} else {
|
|
63
|
+
const { label, note } = point;
|
|
64
|
+
|
|
65
|
+
if (label && label.options.visible) {
|
|
66
|
+
if (label.alignToClipBox) {
|
|
67
|
+
label.alignToClipBox(clipBox);
|
|
68
|
+
}
|
|
69
|
+
label.options.noclip = true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (note && note.options.visible) {
|
|
73
|
+
note.options.noclip = true;
|
|
66
74
|
}
|
|
67
|
-
label.options.noclip = true;
|
|
68
75
|
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
unclipBox() {
|
|
83
|
+
const { children: charts } = this;
|
|
84
|
+
const clipBox = this._clipBox();
|
|
85
|
+
const box = clipBox.clone();
|
|
86
|
+
|
|
87
|
+
for (let i = 0; i < charts.length; i++) {
|
|
88
|
+
const points = charts[i].points || [];
|
|
89
|
+
const length = points.length;
|
|
69
90
|
|
|
70
|
-
|
|
71
|
-
|
|
91
|
+
for (let j = 0; j < length; j++) {
|
|
92
|
+
const point = points[j];
|
|
93
|
+
|
|
94
|
+
if (point && point.unclipBox && point.overlapsBox && point.visible !== false) {
|
|
95
|
+
if (!point.overlapsBox(clipBox)) {
|
|
96
|
+
// Hide points outside of the viewport (clipBox)
|
|
97
|
+
if (point.clipElements) {
|
|
98
|
+
point.clipElements();
|
|
72
99
|
}
|
|
100
|
+
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Extend viewport to include all point elements, including labels
|
|
105
|
+
const unclipBox = point.unclipBox();
|
|
106
|
+
if (box.overlaps(unclipBox)) {
|
|
107
|
+
const labelBox = point.labelBox ? point.labelBox() : new Box();
|
|
108
|
+
const noteBox = point.noteBox ? point.noteBox() : new Box();
|
|
109
|
+
|
|
110
|
+
const heightLimit = Math.max(labelBox.height(), noteBox.height());
|
|
111
|
+
const widthLimit = Math.max(labelBox.width(), noteBox.width());
|
|
112
|
+
|
|
113
|
+
// Limit the size change of the viewport to the label and note boxes dimensions
|
|
114
|
+
// to avoid extending it too much.
|
|
115
|
+
box.wrapLimit(unclipBox, widthLimit, heightLimit);
|
|
73
116
|
}
|
|
74
117
|
}
|
|
75
118
|
}
|
|
76
119
|
}
|
|
120
|
+
|
|
121
|
+
return box;
|
|
77
122
|
}
|
|
78
123
|
|
|
79
124
|
destroy() {
|
|
@@ -85,4 +130,4 @@ class ChartContainer extends ChartElement {
|
|
|
85
130
|
|
|
86
131
|
ChartContainer.prototype.isStackRoot = true;
|
|
87
132
|
|
|
88
|
-
export default ChartContainer;
|
|
133
|
+
export default ChartContainer;
|
|
@@ -9,13 +9,14 @@ import { LINE_MARKER_SIZE, FADEIN, INITIAL_ANIMATION_DURATION, BORDER_BRIGHTNESS
|
|
|
9
9
|
import { WHITE, CIRCLE, CENTER, TOP, BOTTOM, LEFT, HIGHLIGHT_ZINDEX } from '../../common/constants';
|
|
10
10
|
import { deepExtend, defined, getTemplate, getAriaTemplate, valueOrDefault, getSpacing } from '../../common';
|
|
11
11
|
import guid from '../../core/utils/guid';
|
|
12
|
+
import unclipBox from '../utils/unclip-box';
|
|
12
13
|
|
|
13
14
|
class LinePoint extends ChartElement {
|
|
14
15
|
constructor(value, options) {
|
|
15
16
|
super();
|
|
16
17
|
|
|
17
18
|
this.value = value;
|
|
18
|
-
this.options = options;
|
|
19
|
+
this.options = Object.assign({}, options);
|
|
19
20
|
this.aboveAxis = valueOrDefault(this.options.aboveAxis, true);
|
|
20
21
|
this.tooltipTracking = true;
|
|
21
22
|
this._id = guid();
|
|
@@ -103,7 +104,7 @@ class LinePoint extends ChartElement {
|
|
|
103
104
|
return border;
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
createVisual() {}
|
|
107
|
+
createVisual() { }
|
|
107
108
|
|
|
108
109
|
createMarker() {
|
|
109
110
|
const options = this.options.markers;
|
|
@@ -242,7 +243,7 @@ class LinePoint extends ChartElement {
|
|
|
242
243
|
const size = this.options.markers.size;
|
|
243
244
|
const halfSize = size / 2;
|
|
244
245
|
const center = this.box.center();
|
|
245
|
-
rect = new geom.Rect([
|
|
246
|
+
rect = new geom.Rect([center.x - halfSize, center.y - halfSize], [size, size]);
|
|
246
247
|
}
|
|
247
248
|
|
|
248
249
|
return {
|
|
@@ -311,6 +312,10 @@ class LinePoint extends ChartElement {
|
|
|
311
312
|
return markerBox.overlaps(box);
|
|
312
313
|
}
|
|
313
314
|
|
|
315
|
+
clipElements() {
|
|
316
|
+
this.options.visible = false;
|
|
317
|
+
}
|
|
318
|
+
|
|
314
319
|
unclipElements() {
|
|
315
320
|
if (this.label) {
|
|
316
321
|
this.label.options.noclip = true;
|
|
@@ -321,6 +326,18 @@ class LinePoint extends ChartElement {
|
|
|
321
326
|
}
|
|
322
327
|
}
|
|
323
328
|
|
|
329
|
+
unclipBox() {
|
|
330
|
+
return unclipBox(this.markerBox().clone(), [this.label, this.note]);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
labelBox() {
|
|
334
|
+
return this.label ? this.label.box : new Box();
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
noteBox() {
|
|
338
|
+
return this.note ? this.note.box : new Box();
|
|
339
|
+
}
|
|
340
|
+
|
|
324
341
|
pointData() {
|
|
325
342
|
return {
|
|
326
343
|
dataItem: this.dataItem,
|
|
@@ -99,6 +99,11 @@ class Pane extends BoxElement {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
// This is the box for the charts in the pane _and_ all the overflowing ("unclipped") labels.
|
|
103
|
+
unclipBox() {
|
|
104
|
+
return this.chartContainer.unclipBox();
|
|
105
|
+
}
|
|
106
|
+
|
|
102
107
|
visualStyle() {
|
|
103
108
|
const style = super.visualStyle();
|
|
104
109
|
style.zIndex = -10;
|
|
@@ -7,8 +7,10 @@ import { hasValue } from '../utils';
|
|
|
7
7
|
import SeriesBinder from '../series-binder';
|
|
8
8
|
|
|
9
9
|
import { WHITE, BLACK, X, Y, COORD_PRECISION, TOP, BOTTOM, LEFT, RIGHT, START, END, INHERIT } from '../../common/constants';
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import {
|
|
11
|
+
append, deepExtend, defined, getSpacing, getTemplate, inArray, isFunction, isString,
|
|
12
|
+
limitValue, round, setDefaultOptions, last, cycleIndex
|
|
13
|
+
} from '../../common';
|
|
12
14
|
import { TRENDLINE_SERIES } from '../constants';
|
|
13
15
|
|
|
14
16
|
const visiblePoint = (point) => point.options.visible !== false;
|
|
@@ -291,7 +293,7 @@ class PlotAreaBase extends ChartElement {
|
|
|
291
293
|
if (seriesByPane[pane]) {
|
|
292
294
|
seriesByPane[pane].push(currentSeries);
|
|
293
295
|
} else {
|
|
294
|
-
seriesByPane[pane] = [
|
|
296
|
+
seriesByPane[pane] = [currentSeries];
|
|
295
297
|
}
|
|
296
298
|
}
|
|
297
299
|
|
|
@@ -317,6 +319,15 @@ class PlotAreaBase extends ChartElement {
|
|
|
317
319
|
const margin = getSpacing(options.margin);
|
|
318
320
|
|
|
319
321
|
this.box = targetBox.clone().unpad(margin);
|
|
322
|
+
|
|
323
|
+
this.reflowArea(panes);
|
|
324
|
+
|
|
325
|
+
if (this.ensureLabelsFit(panes)) {
|
|
326
|
+
this.reflowArea(panes);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
reflowArea(panes) {
|
|
320
331
|
this.reflowPanes();
|
|
321
332
|
|
|
322
333
|
this.detachLabels();
|
|
@@ -324,6 +335,42 @@ class PlotAreaBase extends ChartElement {
|
|
|
324
335
|
this.reflowCharts(panes);
|
|
325
336
|
}
|
|
326
337
|
|
|
338
|
+
ensureLabelsFit(panes) {
|
|
339
|
+
let change = false;
|
|
340
|
+
|
|
341
|
+
panes.forEach((pane) => {
|
|
342
|
+
const unclipBox = pane.unclipBox();
|
|
343
|
+
const clipBox = pane.chartContainer._clipBox();
|
|
344
|
+
const padding = getSpacing(pane.options.padding || {});
|
|
345
|
+
|
|
346
|
+
if (unclipBox.y1 < clipBox.y1 + padding.top) {
|
|
347
|
+
change = true;
|
|
348
|
+
padding.top = clipBox.y1 - unclipBox.y1 + padding.top;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (unclipBox.y2 > clipBox.y2 - padding.bottom) {
|
|
352
|
+
change = true;
|
|
353
|
+
padding.bottom = unclipBox.y2 - clipBox.y2 + padding.bottom;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (unclipBox.x1 < clipBox.x1 + padding.left) {
|
|
357
|
+
change = true;
|
|
358
|
+
padding.left = clipBox.x1 - unclipBox.x1 + padding.left;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (unclipBox.x2 > clipBox.x2 - padding.right) {
|
|
362
|
+
change = true;
|
|
363
|
+
padding.right = unclipBox.x2 - clipBox.x2 + padding.right;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (change) {
|
|
367
|
+
pane.options.padding = padding;
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
return change;
|
|
372
|
+
}
|
|
373
|
+
|
|
327
374
|
redraw(panes) {
|
|
328
375
|
const panesArray = [].concat(panes);
|
|
329
376
|
this.initSeries();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default function unclipBox(box, elements) {
|
|
2
|
+
elements.forEach(element => {
|
|
3
|
+
const options = element && element.options;
|
|
4
|
+
const elBox = element && (element.box || element.wrapperBox);
|
|
5
|
+
if (options && elBox && options.noclip !== false && options.visible !== false) {
|
|
6
|
+
box.wrap(elBox);
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
return box;
|
|
10
|
+
}
|
|
@@ -15,3 +15,4 @@ export { default as isDateAxis } from './utils/is-date-axis';
|
|
|
15
15
|
export { default as segmentVisible } from './utils/segment-visible';
|
|
16
16
|
export { default as singleItemOrArray } from './utils/single-item-or-array';
|
|
17
17
|
export { default as createOutOfRangePoints } from './utils/create-out-of-range-points';
|
|
18
|
+
export { default as unclipBox } from './utils/unclip-box';
|
|
@@ -13,8 +13,8 @@ function detectOS(ua) {
|
|
|
13
13
|
wp: /(Windows Phone(?: OS)?)\s(\d+)\.(\d+(\.\d+)?)/,
|
|
14
14
|
fire: /(Silk)\/(\d+)\.(\d+(\.\d+)?)/,
|
|
15
15
|
android: /(Android|Android.*(?:Opera|Firefox).*?\/)\s*(\d+)\.?(\d+(\.\d+)?)?/,
|
|
16
|
-
iphone: /(iPhone|iPod).*OS\s+(\d+)[
|
|
17
|
-
ipad: /(iPad).*OS\s+(\d+)[
|
|
16
|
+
iphone: /(iPhone|iPod).*OS\s+(\d+)[._]([\d._]+)/,
|
|
17
|
+
ipad: /(iPad).*OS\s+(\d+)[._]([\d_]+)/,
|
|
18
18
|
playbook: /(PlayBook).*?Tablet\s*OS\s*(\d+)\.(\d+(\.\d+)?)/,
|
|
19
19
|
windows: /(MSIE)\s+(\d+)\.(\d+(\.\d+)?)/,
|
|
20
20
|
tizen: /(tizen).*?Version\/(\d+)\.(\d+(\.\d+)?)/i,
|