q2-tecton-elements 1.23.0-alpha.0 → 1.24.0
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/cjs/action-sheet-4b366e9a.js +84 -0
- package/dist/cjs/charting-d02cba1f.js +3127 -0
- package/dist/cjs/{index-3518c78c.js → index-e00b4210.js} +33 -7
- package/dist/cjs/{installCanvasRenderer-b4d10c92.js → installCanvasRenderer-6c4fbcc9.js} +230 -1130
- package/dist/cjs/installLabelLayout-d6b548fe.js +1048 -0
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/q2-action-sheet.cjs.entry.js +218 -0
- package/dist/cjs/q2-badge_2.cjs.entry.js +1 -1
- package/dist/cjs/q2-btn_2.cjs.entry.js +2 -2
- package/dist/cjs/q2-calendar.cjs.entry.js +1 -1
- package/dist/cjs/q2-card.cjs.entry.js +2 -2
- package/dist/cjs/q2-carousel-pane.cjs.entry.js +1 -1
- package/dist/cjs/q2-carousel.cjs.entry.js +1 -1
- package/dist/cjs/q2-chart-area.cjs.entry.js +4569 -0
- package/dist/cjs/q2-chart-bar.cjs.entry.js +25 -3133
- package/dist/cjs/q2-chart-donut.cjs.entry.js +9 -8
- package/dist/cjs/q2-checkbox-group.cjs.entry.js +1 -1
- package/dist/cjs/q2-checkbox.cjs.entry.js +2 -2
- package/dist/cjs/q2-dropdown-item.cjs.entry.js +1 -1
- package/dist/cjs/q2-dropdown.cjs.entry.js +1 -1
- package/dist/cjs/q2-editable-field.cjs.entry.js +1 -1
- package/dist/cjs/q2-icon.cjs.entry.js +1 -1
- package/dist/cjs/q2-loading-element.cjs.entry.js +1 -1
- package/dist/cjs/q2-loc.cjs.entry.js +1 -1
- package/dist/cjs/q2-message.cjs.entry.js +1 -1
- package/dist/cjs/q2-month-picker.cjs.entry.js +1 -1
- package/dist/cjs/q2-optgroup_2.cjs.entry.js +93 -0
- package/dist/cjs/q2-option-list_2.cjs.entry.js +230 -88
- package/dist/cjs/q2-pagination.cjs.entry.js +1 -1
- package/dist/cjs/q2-pill.cjs.entry.js +57 -18
- package/dist/cjs/q2-radio-group.cjs.entry.js +1 -1
- package/dist/cjs/q2-radio.cjs.entry.js +1 -1
- package/dist/cjs/q2-section.cjs.entry.js +1 -1
- package/dist/cjs/q2-select.cjs.entry.js +149 -409
- package/dist/cjs/q2-stepper-pane.cjs.entry.js +1 -1
- package/dist/cjs/q2-stepper-vertical.cjs.entry.js +1 -1
- package/dist/cjs/q2-stepper.cjs.entry.js +1 -1
- package/dist/cjs/q2-tab-container.cjs.entry.js +1 -1
- package/dist/cjs/q2-tag.cjs.entry.js +21 -6
- package/dist/cjs/q2-tecton-elements.cjs.js +1 -1
- package/dist/cjs/q2-textarea.cjs.entry.js +1 -1
- package/dist/collection/collection-manifest.json +2 -0
- package/dist/collection/components/q2-action-sheet/index.js +345 -0
- package/dist/collection/components/q2-action-sheet/styles.css +215 -0
- package/dist/collection/components/q2-card/index.js +1 -1
- package/dist/collection/components/q2-chart-area/index.js +622 -0
- package/dist/collection/components/q2-chart-area/styles.css +82 -0
- package/dist/collection/components/q2-chart-bar/index.js +4 -4
- package/dist/collection/components/q2-chart-bar/styles.css +3 -6
- package/dist/collection/components/q2-chart-donut/index.js +1 -1
- package/dist/collection/components/q2-checkbox/index.js +2 -2
- package/dist/collection/components/q2-checkbox/styles.css +1 -0
- package/dist/collection/components/q2-dropdown/index.js +1 -1
- package/dist/collection/components/q2-loading/index.js +1 -1
- package/dist/collection/components/q2-loading/skeleton/q2-loading-element/styles.css +4 -0
- package/dist/collection/components/q2-loading/styles.css +4 -0
- package/dist/collection/components/q2-optgroup/styles.css +2 -2
- package/dist/collection/components/q2-option/index.js +1 -56
- package/dist/collection/components/q2-option/styles.css +7 -0
- package/dist/collection/components/q2-option-list/index.js +290 -102
- package/dist/collection/components/q2-pill/index.js +79 -18
- package/dist/collection/components/q2-pill/styles.css +1 -2
- package/dist/collection/components/q2-popover/index.js +21 -5
- package/dist/collection/components/q2-popover/styles.css +10 -67
- package/dist/collection/components/q2-radio/index.js +2 -2
- package/dist/collection/components/q2-select/index.js +197 -427
- package/dist/collection/components/q2-select/styles.css +5 -11
- package/dist/collection/components/q2-tag/index.js +38 -5
- package/dist/collection/utils/action-sheet.js +79 -0
- package/dist/collection/utils/index.js +31 -7
- package/dist/components/action-sheet.js +81 -0
- package/dist/components/charting.js +3113 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.js +2 -0
- package/dist/components/index10.js +1 -1
- package/dist/components/index11.js +42 -353
- package/dist/components/index12.js +44 -97
- package/dist/components/index13.js +495 -580
- package/dist/components/index14.js +137 -0
- package/dist/components/index15.js +626 -0
- package/dist/components/index5.js +1 -1
- package/dist/components/index6.js +1 -1
- package/dist/components/index7.js +1 -1
- package/dist/components/index8.js +1 -1
- package/dist/components/index9.js +3 -3
- package/dist/components/installCanvasRenderer.js +188 -1123
- package/dist/components/installLabelLayout.js +1042 -0
- package/dist/components/q2-action-sheet.d.ts +11 -0
- package/dist/components/q2-action-sheet.js +282 -0
- package/dist/components/q2-calendar.js +1 -1
- package/dist/components/q2-card.js +2 -2
- package/dist/components/q2-carousel-pane.js +1 -1
- package/dist/components/q2-carousel.js +1 -1
- package/dist/components/q2-chart-area.d.ts +11 -0
- package/dist/components/q2-chart-area.js +4604 -0
- package/dist/components/q2-chart-bar.js +11 -3119
- package/dist/components/q2-chart-donut.js +4 -3
- package/dist/components/q2-checkbox-group.js +1 -1
- package/dist/components/q2-checkbox.js +2 -2
- package/dist/components/q2-dropdown.js +2 -2
- package/dist/components/q2-editable-field.js +1 -1
- package/dist/components/q2-loading-element.js +1 -1
- package/dist/components/q2-loc.js +1 -1
- package/dist/components/q2-month-picker.js +1 -1
- package/dist/components/q2-optgroup.js +1 -70
- package/dist/components/q2-option-list.js +1 -1
- package/dist/components/q2-option.js +1 -76
- package/dist/components/q2-pagination.js +1 -1
- package/dist/components/q2-pill.js +62 -21
- package/dist/components/q2-popover.js +1 -1
- package/dist/components/q2-radio-group.js +1 -1
- package/dist/components/q2-radio.js +3 -3
- package/dist/components/q2-section.js +1 -1
- package/dist/components/q2-select.js +181 -427
- package/dist/components/q2-stepper-pane.js +1 -1
- package/dist/components/q2-stepper-vertical.js +1 -1
- package/dist/components/q2-stepper.js +1 -1
- package/dist/components/q2-tab-container.js +1 -1
- package/dist/components/q2-tag.js +24 -8
- package/dist/components/q2-textarea.js +1 -1
- package/dist/esm/action-sheet-a9597b32.js +81 -0
- package/dist/esm/charting-2a73ba8e.js +3113 -0
- package/dist/esm/{index-9c591682.js → index-ca21e539.js} +32 -8
- package/dist/esm/{installCanvasRenderer-0143b52d.js → installCanvasRenderer-4a470516.js} +188 -1123
- package/dist/esm/installLabelLayout-d660eaad.js +1042 -0
- package/dist/esm/loader.js +1 -1
- package/dist/esm/q2-action-sheet.entry.js +214 -0
- package/dist/esm/q2-badge_2.entry.js +1 -1
- package/dist/esm/q2-btn_2.entry.js +2 -2
- package/dist/esm/q2-calendar.entry.js +1 -1
- package/dist/esm/q2-card.entry.js +2 -2
- package/dist/esm/q2-carousel-pane.entry.js +1 -1
- package/dist/esm/q2-carousel.entry.js +1 -1
- package/dist/esm/q2-chart-area.entry.js +4565 -0
- package/dist/esm/q2-chart-bar.entry.js +11 -3119
- package/dist/esm/q2-chart-donut.entry.js +4 -3
- package/dist/esm/q2-checkbox-group.entry.js +1 -1
- package/dist/esm/q2-checkbox.entry.js +2 -2
- package/dist/esm/q2-dropdown-item.entry.js +1 -1
- package/dist/esm/q2-dropdown.entry.js +1 -1
- package/dist/esm/q2-editable-field.entry.js +1 -1
- package/dist/esm/q2-icon.entry.js +1 -1
- package/dist/esm/q2-loading-element.entry.js +1 -1
- package/dist/esm/q2-loc.entry.js +1 -1
- package/dist/esm/q2-message.entry.js +1 -1
- package/dist/esm/q2-month-picker.entry.js +1 -1
- package/dist/esm/q2-optgroup_2.entry.js +88 -0
- package/dist/esm/q2-option-list_2.entry.js +230 -88
- package/dist/esm/q2-pagination.entry.js +1 -1
- package/dist/esm/q2-pill.entry.js +57 -18
- package/dist/esm/q2-radio-group.entry.js +1 -1
- package/dist/esm/q2-radio.entry.js +1 -1
- package/dist/esm/q2-section.entry.js +1 -1
- package/dist/esm/q2-select.entry.js +149 -409
- package/dist/esm/q2-stepper-pane.entry.js +1 -1
- package/dist/esm/q2-stepper-vertical.entry.js +1 -1
- package/dist/esm/q2-stepper.entry.js +1 -1
- package/dist/esm/q2-tab-container.entry.js +1 -1
- package/dist/esm/q2-tag.entry.js +21 -6
- package/dist/esm/q2-tecton-elements.js +1 -1
- package/dist/esm/q2-textarea.entry.js +1 -1
- package/dist/q2-tecton-elements/{p-db873db2.entry.js → p-0473f4f7.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-520c40f6.entry.js → p-13a1390b.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-9ebb283a.entry.js → p-13deb3ed.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-0ba564b1.entry.js → p-1d854203.entry.js} +1 -1
- package/dist/q2-tecton-elements/p-1f71774f.entry.js +1 -0
- package/dist/q2-tecton-elements/{p-18cc4758.entry.js → p-256d3fe6.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-9281adaa.entry.js → p-282f0f8c.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-2d2c5af2.entry.js → p-30969629.entry.js} +1 -1
- package/dist/q2-tecton-elements/p-30cd888b.entry.js +1 -0
- package/dist/q2-tecton-elements/{p-fc134a5d.entry.js → p-37cf9c97.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-fb37e67e.entry.js → p-388349b5.entry.js} +1 -1
- package/dist/q2-tecton-elements/p-458b1987.js +1 -0
- package/dist/q2-tecton-elements/p-52063431.js +39 -0
- package/dist/q2-tecton-elements/p-5589ae0f.entry.js +1 -0
- package/dist/q2-tecton-elements/p-619aed74.entry.js +1 -0
- package/dist/q2-tecton-elements/{p-4625184b.entry.js → p-63b67260.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-e4dc9ac0.entry.js → p-63e363ad.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-cbd1289a.entry.js → p-6736df05.entry.js} +1 -1
- package/dist/q2-tecton-elements/p-72fe10cc.entry.js +1 -0
- package/dist/q2-tecton-elements/{p-c4640b55.entry.js → p-75b817c6.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-c3f27fe2.entry.js → p-7a116095.entry.js} +1 -1
- package/dist/q2-tecton-elements/p-7c94119b.entry.js +1 -0
- package/dist/q2-tecton-elements/p-833398d1.js +1 -0
- package/dist/q2-tecton-elements/{p-ce015552.entry.js → p-90572e43.entry.js} +1 -1
- package/dist/q2-tecton-elements/p-91153c61.entry.js +1 -0
- package/dist/q2-tecton-elements/p-9792de8a.entry.js +1 -0
- package/dist/q2-tecton-elements/p-9acfa94e.js +1 -0
- package/dist/q2-tecton-elements/p-a1926e65.js +1 -0
- package/dist/q2-tecton-elements/{p-ffb48ccc.entry.js → p-b3a8cdc5.entry.js} +1 -1
- package/dist/q2-tecton-elements/p-ce3f203c.entry.js +1 -0
- package/dist/q2-tecton-elements/{p-041b3a82.entry.js → p-ce91cd9b.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-b8b00394.entry.js → p-cefc9d0b.entry.js} +1 -1
- package/dist/q2-tecton-elements/p-d05beeb7.entry.js +1 -0
- package/dist/q2-tecton-elements/p-dc7c8371.entry.js +1 -0
- package/dist/q2-tecton-elements/{p-16c11d74.entry.js → p-e58581fc.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-f800fd1e.entry.js → p-e886c55b.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-6e6b5b80.entry.js → p-f0ec4d2c.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-97aa8423.entry.js → p-f94e7043.entry.js} +1 -1
- package/dist/q2-tecton-elements/{p-c444a60b.entry.js → p-fcb7d191.entry.js} +1 -1
- package/dist/q2-tecton-elements/q2-tecton-elements.esm.js +1 -1
- package/dist/test/helpers.js +3 -2
- package/dist/types/components/q2-action-sheet/index.d.ts +52 -0
- package/dist/types/components/q2-card/index.d.ts +1 -1
- package/dist/types/components/q2-chart-area/index.d.ts +40 -0
- package/dist/types/components/q2-chart-bar/index.d.ts +2 -2
- package/dist/types/components/q2-chart-donut/index.d.ts +1 -1
- package/dist/types/components/q2-checkbox/index.d.ts +4 -1
- package/dist/types/components/q2-option/index.d.ts +0 -3
- package/dist/types/components/q2-option-list/index.d.ts +16 -8
- package/dist/types/components/q2-pill/index.d.ts +10 -1
- package/dist/types/components/q2-popover/index.d.ts +2 -0
- package/dist/types/components/q2-select/index.d.ts +46 -47
- package/dist/types/components/q2-tag/index.d.ts +3 -2
- package/dist/types/components.d.ts +100 -13
- package/dist/types/global.d.ts +10 -1
- package/dist/types/utils/action-sheet.d.ts +12 -0
- package/dist/types/utils/index.d.ts +3 -1
- package/dist/types/workspace/workspace/{_production_release_1.22.x-alpha → Tecton_tecton-production_master}/packages/q2-tecton-elements/.stencil/test/helpers.d.ts +1 -1
- package/package.json +3 -2
- package/dist/cjs/q2-optgroup.cjs.entry.js +0 -56
- package/dist/cjs/q2-option.cjs.entry.js +0 -46
- package/dist/esm/q2-optgroup.entry.js +0 -52
- package/dist/esm/q2-option.entry.js +0 -42
- package/dist/q2-tecton-elements/p-0d8dd75a.entry.js +0 -1
- package/dist/q2-tecton-elements/p-0fad9c5a.entry.js +0 -1
- package/dist/q2-tecton-elements/p-1f85cced.js +0 -39
- package/dist/q2-tecton-elements/p-2c9b1308.entry.js +0 -1
- package/dist/q2-tecton-elements/p-5e374fbd.js +0 -1
- package/dist/q2-tecton-elements/p-6b52a262.entry.js +0 -1
- package/dist/q2-tecton-elements/p-aaf42539.entry.js +0 -1
- package/dist/q2-tecton-elements/p-cf41970f.entry.js +0 -1
- package/dist/q2-tecton-elements/p-de164483.entry.js +0 -1
- package/dist/q2-tecton-elements/p-e6d26f39.entry.js +0 -1
- package/dist/q2-tecton-elements/p-f1d06917.entry.js +0 -1
- package/dist/q2-tecton-elements/p-f35bf6a3.entry.js +0 -1
|
@@ -0,0 +1,4604 @@
|
|
|
1
|
+
import { proxyCustomElement, HTMLElement, createEvent, h } from '@stencil/core/internal/client';
|
|
2
|
+
import { o as overrideFocus, l as loc } from './index15.js';
|
|
3
|
+
import { g as getDefaultLabel, c as createSeriesData, a as getDefaultInterpolatedLabel, i as isCoordinateSystemType, b as createGridClipPath, d as createPolarClipPath, e as dataSample, f as install$3, h as install$4, j as getCSSProperty, k as isValidColor, l as formatValue } from './charting.js';
|
|
4
|
+
import { _ as __extends, c as createSymbol, e as enterEmphasis, l as leaveEmphasis, u as updateProps, s as saveOldStyle, i as initProps, g as getLabelStatesModels, n as normalizeSymbolOffset, Z as ZRImage, a as extend, b as setLabelStyle, t as toggleHoverEmphasis, d as getECData, r as removeElement, f as normalizeSymbolSize, G as Group, h as traverseElements, j as isObject, S as SeriesModel, m as map, k as isDimensionStacked, o as isNumber, p as createFloat32Array, q as cubicRootAt, P as Path, v as PathProxy, w as cubicAt, x as convertToColorString, y as defaults, z as setStatesStylesFromModel, A as queryDataIndex, C as ChartView, B as setStatesFlag, D as isFunction, E as ZRText, F as interpolateRawValues, H as labelInner, I as each, L as LinearGradient, J as SPECIAL_STATES, K as lerp, M as createRenderPlanner, N as cubicSubdivide, O as fromPoints, Q as BoundingRect, R as clonePath, T as Polygon, U as Sector, V as Rect, W as Point, X as Transformable, Y as lerp$1, $ as getAnimationConfig, a0 as isArray, a1 as normalizeToArray, a2 as SERIES_UNIVERSAL_TRANSITION_PROP, a3 as makeInner, a4 as DataDiffer, a5 as filter, a6 as createHashMap, a7 as Displayable, a8 as getOldStyle, a9 as use, aa as install$1, ab as install$2, ac as init } from './installCanvasRenderer.js';
|
|
5
|
+
|
|
6
|
+
var Symbol =
|
|
7
|
+
/** @class */
|
|
8
|
+
function (_super) {
|
|
9
|
+
__extends(Symbol, _super);
|
|
10
|
+
|
|
11
|
+
function Symbol(data, idx, seriesScope, opts) {
|
|
12
|
+
var _this = _super.call(this) || this;
|
|
13
|
+
|
|
14
|
+
_this.updateData(data, idx, seriesScope, opts);
|
|
15
|
+
|
|
16
|
+
return _this;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
Symbol.prototype._createSymbol = function (symbolType, data, idx, symbolSize, keepAspect) {
|
|
20
|
+
// Remove paths created before
|
|
21
|
+
this.removeAll(); // let symbolPath = createSymbol(
|
|
22
|
+
// symbolType, -0.5, -0.5, 1, 1, color
|
|
23
|
+
// );
|
|
24
|
+
// If width/height are set too small (e.g., set to 1) on ios10
|
|
25
|
+
// and macOS Sierra, a circle stroke become a rect, no matter what
|
|
26
|
+
// the scale is set. So we set width/height as 2. See #4150.
|
|
27
|
+
|
|
28
|
+
var symbolPath = createSymbol(symbolType, -1, -1, 2, 2, null, keepAspect);
|
|
29
|
+
symbolPath.attr({
|
|
30
|
+
z2: 100,
|
|
31
|
+
culling: true,
|
|
32
|
+
scaleX: symbolSize[0] / 2,
|
|
33
|
+
scaleY: symbolSize[1] / 2
|
|
34
|
+
}); // Rewrite drift method
|
|
35
|
+
|
|
36
|
+
symbolPath.drift = driftSymbol;
|
|
37
|
+
this._symbolType = symbolType;
|
|
38
|
+
this.add(symbolPath);
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Stop animation
|
|
42
|
+
* @param {boolean} toLastFrame
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
Symbol.prototype.stopSymbolAnimation = function (toLastFrame) {
|
|
47
|
+
this.childAt(0).stopAnimation(null, toLastFrame);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
Symbol.prototype.getSymbolType = function () {
|
|
51
|
+
return this._symbolType;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* FIXME:
|
|
55
|
+
* Caution: This method breaks the encapsulation of this module,
|
|
56
|
+
* but it indeed brings convenience. So do not use the method
|
|
57
|
+
* unless you detailedly know all the implements of `Symbol`,
|
|
58
|
+
* especially animation.
|
|
59
|
+
*
|
|
60
|
+
* Get symbol path element.
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
Symbol.prototype.getSymbolPath = function () {
|
|
65
|
+
return this.childAt(0);
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Highlight symbol
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
Symbol.prototype.highlight = function () {
|
|
73
|
+
enterEmphasis(this.childAt(0));
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Downplay symbol
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
Symbol.prototype.downplay = function () {
|
|
81
|
+
leaveEmphasis(this.childAt(0));
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* @param {number} zlevel
|
|
85
|
+
* @param {number} z
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
Symbol.prototype.setZ = function (zlevel, z) {
|
|
90
|
+
var symbolPath = this.childAt(0);
|
|
91
|
+
symbolPath.zlevel = zlevel;
|
|
92
|
+
symbolPath.z = z;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
Symbol.prototype.setDraggable = function (draggable, hasCursorOption) {
|
|
96
|
+
var symbolPath = this.childAt(0);
|
|
97
|
+
symbolPath.draggable = draggable;
|
|
98
|
+
symbolPath.cursor = !hasCursorOption && draggable ? 'move' : symbolPath.cursor;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Update symbol properties
|
|
102
|
+
*/
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
Symbol.prototype.updateData = function (data, idx, seriesScope, opts) {
|
|
106
|
+
this.silent = false;
|
|
107
|
+
var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
|
|
108
|
+
var seriesModel = data.hostModel;
|
|
109
|
+
var symbolSize = Symbol.getSymbolSize(data, idx);
|
|
110
|
+
var isInit = symbolType !== this._symbolType;
|
|
111
|
+
var disableAnimation = opts && opts.disableAnimation;
|
|
112
|
+
|
|
113
|
+
if (isInit) {
|
|
114
|
+
var keepAspect = data.getItemVisual(idx, 'symbolKeepAspect');
|
|
115
|
+
|
|
116
|
+
this._createSymbol(symbolType, data, idx, symbolSize, keepAspect);
|
|
117
|
+
} else {
|
|
118
|
+
var symbolPath = this.childAt(0);
|
|
119
|
+
symbolPath.silent = false;
|
|
120
|
+
var target = {
|
|
121
|
+
scaleX: symbolSize[0] / 2,
|
|
122
|
+
scaleY: symbolSize[1] / 2
|
|
123
|
+
};
|
|
124
|
+
disableAnimation ? symbolPath.attr(target) : updateProps(symbolPath, target, seriesModel, idx);
|
|
125
|
+
saveOldStyle(symbolPath);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
this._updateCommon(data, idx, symbolSize, seriesScope, opts);
|
|
129
|
+
|
|
130
|
+
if (isInit) {
|
|
131
|
+
var symbolPath = this.childAt(0);
|
|
132
|
+
|
|
133
|
+
if (!disableAnimation) {
|
|
134
|
+
var target = {
|
|
135
|
+
scaleX: this._sizeX,
|
|
136
|
+
scaleY: this._sizeY,
|
|
137
|
+
style: {
|
|
138
|
+
// Always fadeIn. Because it has fadeOut animation when symbol is removed..
|
|
139
|
+
opacity: symbolPath.style.opacity
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
symbolPath.scaleX = symbolPath.scaleY = 0;
|
|
143
|
+
symbolPath.style.opacity = 0;
|
|
144
|
+
initProps(symbolPath, target, seriesModel, idx);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (disableAnimation) {
|
|
149
|
+
// Must stop leave transition manually if don't call initProps or updateProps.
|
|
150
|
+
this.childAt(0).stopAnimation('leave');
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
Symbol.prototype._updateCommon = function (data, idx, symbolSize, seriesScope, opts) {
|
|
155
|
+
var symbolPath = this.childAt(0);
|
|
156
|
+
var seriesModel = data.hostModel;
|
|
157
|
+
var emphasisItemStyle;
|
|
158
|
+
var blurItemStyle;
|
|
159
|
+
var selectItemStyle;
|
|
160
|
+
var focus;
|
|
161
|
+
var blurScope;
|
|
162
|
+
var emphasisDisabled;
|
|
163
|
+
var labelStatesModels;
|
|
164
|
+
var hoverScale;
|
|
165
|
+
var cursorStyle;
|
|
166
|
+
|
|
167
|
+
if (seriesScope) {
|
|
168
|
+
emphasisItemStyle = seriesScope.emphasisItemStyle;
|
|
169
|
+
blurItemStyle = seriesScope.blurItemStyle;
|
|
170
|
+
selectItemStyle = seriesScope.selectItemStyle;
|
|
171
|
+
focus = seriesScope.focus;
|
|
172
|
+
blurScope = seriesScope.blurScope;
|
|
173
|
+
labelStatesModels = seriesScope.labelStatesModels;
|
|
174
|
+
hoverScale = seriesScope.hoverScale;
|
|
175
|
+
cursorStyle = seriesScope.cursorStyle;
|
|
176
|
+
emphasisDisabled = seriesScope.emphasisDisabled;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!seriesScope || data.hasItemOption) {
|
|
180
|
+
var itemModel = seriesScope && seriesScope.itemModel ? seriesScope.itemModel : data.getItemModel(idx);
|
|
181
|
+
var emphasisModel = itemModel.getModel('emphasis');
|
|
182
|
+
emphasisItemStyle = emphasisModel.getModel('itemStyle').getItemStyle();
|
|
183
|
+
selectItemStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle();
|
|
184
|
+
blurItemStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle();
|
|
185
|
+
focus = emphasisModel.get('focus');
|
|
186
|
+
blurScope = emphasisModel.get('blurScope');
|
|
187
|
+
emphasisDisabled = emphasisModel.get('disabled');
|
|
188
|
+
labelStatesModels = getLabelStatesModels(itemModel);
|
|
189
|
+
hoverScale = emphasisModel.getShallow('scale');
|
|
190
|
+
cursorStyle = itemModel.getShallow('cursor');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
var symbolRotate = data.getItemVisual(idx, 'symbolRotate');
|
|
194
|
+
symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0);
|
|
195
|
+
var symbolOffset = normalizeSymbolOffset(data.getItemVisual(idx, 'symbolOffset'), symbolSize);
|
|
196
|
+
|
|
197
|
+
if (symbolOffset) {
|
|
198
|
+
symbolPath.x = symbolOffset[0];
|
|
199
|
+
symbolPath.y = symbolOffset[1];
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
cursorStyle && symbolPath.attr('cursor', cursorStyle);
|
|
203
|
+
var symbolStyle = data.getItemVisual(idx, 'style');
|
|
204
|
+
var visualColor = symbolStyle.fill;
|
|
205
|
+
|
|
206
|
+
if (symbolPath instanceof ZRImage) {
|
|
207
|
+
var pathStyle = symbolPath.style;
|
|
208
|
+
symbolPath.useStyle(extend({
|
|
209
|
+
// TODO other properties like x, y ?
|
|
210
|
+
image: pathStyle.image,
|
|
211
|
+
x: pathStyle.x,
|
|
212
|
+
y: pathStyle.y,
|
|
213
|
+
width: pathStyle.width,
|
|
214
|
+
height: pathStyle.height
|
|
215
|
+
}, symbolStyle));
|
|
216
|
+
} else {
|
|
217
|
+
if (symbolPath.__isEmptyBrush) {
|
|
218
|
+
// fill and stroke will be swapped if it's empty.
|
|
219
|
+
// So we cloned a new style to avoid it affecting the original style in visual storage.
|
|
220
|
+
// TODO Better implementation. No empty logic!
|
|
221
|
+
symbolPath.useStyle(extend({}, symbolStyle));
|
|
222
|
+
} else {
|
|
223
|
+
symbolPath.useStyle(symbolStyle);
|
|
224
|
+
} // Disable decal because symbol scale will been applied on the decal.
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
symbolPath.style.decal = null;
|
|
228
|
+
symbolPath.setColor(visualColor, opts && opts.symbolInnerColor);
|
|
229
|
+
symbolPath.style.strokeNoScale = true;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
var liftZ = data.getItemVisual(idx, 'liftZ');
|
|
233
|
+
var z2Origin = this._z2;
|
|
234
|
+
|
|
235
|
+
if (liftZ != null) {
|
|
236
|
+
if (z2Origin == null) {
|
|
237
|
+
this._z2 = symbolPath.z2;
|
|
238
|
+
symbolPath.z2 += liftZ;
|
|
239
|
+
}
|
|
240
|
+
} else if (z2Origin != null) {
|
|
241
|
+
symbolPath.z2 = z2Origin;
|
|
242
|
+
this._z2 = null;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
var useNameLabel = opts && opts.useNameLabel;
|
|
246
|
+
setLabelStyle(symbolPath, labelStatesModels, {
|
|
247
|
+
labelFetcher: seriesModel,
|
|
248
|
+
labelDataIndex: idx,
|
|
249
|
+
defaultText: getLabelDefaultText,
|
|
250
|
+
inheritColor: visualColor,
|
|
251
|
+
defaultOpacity: symbolStyle.opacity
|
|
252
|
+
}); // Do not execute util needed.
|
|
253
|
+
|
|
254
|
+
function getLabelDefaultText(idx) {
|
|
255
|
+
return useNameLabel ? data.getName(idx) : getDefaultLabel(data, idx);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
this._sizeX = symbolSize[0] / 2;
|
|
259
|
+
this._sizeY = symbolSize[1] / 2;
|
|
260
|
+
var emphasisState = symbolPath.ensureState('emphasis');
|
|
261
|
+
emphasisState.style = emphasisItemStyle;
|
|
262
|
+
symbolPath.ensureState('select').style = selectItemStyle;
|
|
263
|
+
symbolPath.ensureState('blur').style = blurItemStyle; // null / undefined / true means to use default strategy.
|
|
264
|
+
// 0 / false / negative number / NaN / Infinity means no scale.
|
|
265
|
+
|
|
266
|
+
var scaleRatio = hoverScale == null || hoverScale === true ? Math.max(1.1, 3 / this._sizeY) // PENDING: restrict hoverScale > 1? It seems unreasonable to scale down
|
|
267
|
+
: isFinite(hoverScale) && hoverScale > 0 ? +hoverScale : 1; // always set scale to allow resetting
|
|
268
|
+
|
|
269
|
+
emphasisState.scaleX = this._sizeX * scaleRatio;
|
|
270
|
+
emphasisState.scaleY = this._sizeY * scaleRatio;
|
|
271
|
+
this.setSymbolScale(1);
|
|
272
|
+
toggleHoverEmphasis(this, focus, blurScope, emphasisDisabled);
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
Symbol.prototype.setSymbolScale = function (scale) {
|
|
276
|
+
this.scaleX = this.scaleY = scale;
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
Symbol.prototype.fadeOut = function (cb, seriesModel, opt) {
|
|
280
|
+
var symbolPath = this.childAt(0);
|
|
281
|
+
var dataIndex = getECData(this).dataIndex;
|
|
282
|
+
var animationOpt = opt && opt.animation; // Avoid mistaken hover when fading out
|
|
283
|
+
|
|
284
|
+
this.silent = symbolPath.silent = true; // Not show text when animating
|
|
285
|
+
|
|
286
|
+
if (opt && opt.fadeLabel) {
|
|
287
|
+
var textContent = symbolPath.getTextContent();
|
|
288
|
+
|
|
289
|
+
if (textContent) {
|
|
290
|
+
removeElement(textContent, {
|
|
291
|
+
style: {
|
|
292
|
+
opacity: 0
|
|
293
|
+
}
|
|
294
|
+
}, seriesModel, {
|
|
295
|
+
dataIndex: dataIndex,
|
|
296
|
+
removeOpt: animationOpt,
|
|
297
|
+
cb: function () {
|
|
298
|
+
symbolPath.removeTextContent();
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
} else {
|
|
303
|
+
symbolPath.removeTextContent();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
removeElement(symbolPath, {
|
|
307
|
+
style: {
|
|
308
|
+
opacity: 0
|
|
309
|
+
},
|
|
310
|
+
scaleX: 0,
|
|
311
|
+
scaleY: 0
|
|
312
|
+
}, seriesModel, {
|
|
313
|
+
dataIndex: dataIndex,
|
|
314
|
+
cb: cb,
|
|
315
|
+
removeOpt: animationOpt
|
|
316
|
+
});
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
Symbol.getSymbolSize = function (data, idx) {
|
|
320
|
+
return normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
return Symbol;
|
|
324
|
+
}(Group);
|
|
325
|
+
|
|
326
|
+
function driftSymbol(dx, dy) {
|
|
327
|
+
this.parent.drift(dx, dy);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
function symbolNeedsDraw(data, point, idx, opt) {
|
|
331
|
+
return point && !isNaN(point[0]) && !isNaN(point[1]) && !(opt.isIgnore && opt.isIgnore(idx)) // We do not set clipShape on group, because it will cut part of
|
|
332
|
+
// the symbol element shape. We use the same clip shape here as
|
|
333
|
+
// the line clip.
|
|
334
|
+
&& !(opt.clipShape && !opt.clipShape.contain(point[0], point[1])) && data.getItemVisual(idx, 'symbol') !== 'none';
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
function normalizeUpdateOpt(opt) {
|
|
338
|
+
if (opt != null && !isObject(opt)) {
|
|
339
|
+
opt = {
|
|
340
|
+
isIgnore: opt
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return opt || {};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function makeSeriesScope(data) {
|
|
348
|
+
var seriesModel = data.hostModel;
|
|
349
|
+
var emphasisModel = seriesModel.getModel('emphasis');
|
|
350
|
+
return {
|
|
351
|
+
emphasisItemStyle: emphasisModel.getModel('itemStyle').getItemStyle(),
|
|
352
|
+
blurItemStyle: seriesModel.getModel(['blur', 'itemStyle']).getItemStyle(),
|
|
353
|
+
selectItemStyle: seriesModel.getModel(['select', 'itemStyle']).getItemStyle(),
|
|
354
|
+
focus: emphasisModel.get('focus'),
|
|
355
|
+
blurScope: emphasisModel.get('blurScope'),
|
|
356
|
+
emphasisDisabled: emphasisModel.get('disabled'),
|
|
357
|
+
hoverScale: emphasisModel.get('scale'),
|
|
358
|
+
labelStatesModels: getLabelStatesModels(seriesModel),
|
|
359
|
+
cursorStyle: seriesModel.get('cursor')
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
var SymbolDraw =
|
|
364
|
+
/** @class */
|
|
365
|
+
function () {
|
|
366
|
+
function SymbolDraw(SymbolCtor) {
|
|
367
|
+
this.group = new Group();
|
|
368
|
+
this._SymbolCtor = SymbolCtor || Symbol;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Update symbols draw by new data
|
|
372
|
+
*/
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
SymbolDraw.prototype.updateData = function (data, opt) {
|
|
376
|
+
// Remove progressive els.
|
|
377
|
+
this._progressiveEls = null;
|
|
378
|
+
opt = normalizeUpdateOpt(opt);
|
|
379
|
+
var group = this.group;
|
|
380
|
+
var seriesModel = data.hostModel;
|
|
381
|
+
var oldData = this._data;
|
|
382
|
+
var SymbolCtor = this._SymbolCtor;
|
|
383
|
+
var disableAnimation = opt.disableAnimation;
|
|
384
|
+
var seriesScope = makeSeriesScope(data);
|
|
385
|
+
var symbolUpdateOpt = {
|
|
386
|
+
disableAnimation: disableAnimation
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
var getSymbolPoint = opt.getSymbolPoint || function (idx) {
|
|
390
|
+
return data.getItemLayout(idx);
|
|
391
|
+
}; // There is no oldLineData only when first rendering or switching from
|
|
392
|
+
// stream mode to normal mode, where previous elements should be removed.
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
if (!oldData) {
|
|
396
|
+
group.removeAll();
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
data.diff(oldData).add(function (newIdx) {
|
|
400
|
+
var point = getSymbolPoint(newIdx);
|
|
401
|
+
|
|
402
|
+
if (symbolNeedsDraw(data, point, newIdx, opt)) {
|
|
403
|
+
var symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt);
|
|
404
|
+
symbolEl.setPosition(point);
|
|
405
|
+
data.setItemGraphicEl(newIdx, symbolEl);
|
|
406
|
+
group.add(symbolEl);
|
|
407
|
+
}
|
|
408
|
+
}).update(function (newIdx, oldIdx) {
|
|
409
|
+
var symbolEl = oldData.getItemGraphicEl(oldIdx);
|
|
410
|
+
var point = getSymbolPoint(newIdx);
|
|
411
|
+
|
|
412
|
+
if (!symbolNeedsDraw(data, point, newIdx, opt)) {
|
|
413
|
+
group.remove(symbolEl);
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
var newSymbolType = data.getItemVisual(newIdx, 'symbol') || 'circle';
|
|
418
|
+
var oldSymbolType = symbolEl && symbolEl.getSymbolType && symbolEl.getSymbolType();
|
|
419
|
+
|
|
420
|
+
if (!symbolEl // Create a new if symbol type changed.
|
|
421
|
+
|| oldSymbolType && oldSymbolType !== newSymbolType) {
|
|
422
|
+
group.remove(symbolEl);
|
|
423
|
+
symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt);
|
|
424
|
+
symbolEl.setPosition(point);
|
|
425
|
+
} else {
|
|
426
|
+
symbolEl.updateData(data, newIdx, seriesScope, symbolUpdateOpt);
|
|
427
|
+
var target = {
|
|
428
|
+
x: point[0],
|
|
429
|
+
y: point[1]
|
|
430
|
+
};
|
|
431
|
+
disableAnimation ? symbolEl.attr(target) : updateProps(symbolEl, target, seriesModel);
|
|
432
|
+
} // Add back
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
group.add(symbolEl);
|
|
436
|
+
data.setItemGraphicEl(newIdx, symbolEl);
|
|
437
|
+
}).remove(function (oldIdx) {
|
|
438
|
+
var el = oldData.getItemGraphicEl(oldIdx);
|
|
439
|
+
el && el.fadeOut(function () {
|
|
440
|
+
group.remove(el);
|
|
441
|
+
}, seriesModel);
|
|
442
|
+
}).execute();
|
|
443
|
+
this._getSymbolPoint = getSymbolPoint;
|
|
444
|
+
this._data = data;
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
SymbolDraw.prototype.updateLayout = function () {
|
|
448
|
+
var _this = this;
|
|
449
|
+
|
|
450
|
+
var data = this._data;
|
|
451
|
+
|
|
452
|
+
if (data) {
|
|
453
|
+
// Not use animation
|
|
454
|
+
data.eachItemGraphicEl(function (el, idx) {
|
|
455
|
+
var point = _this._getSymbolPoint(idx);
|
|
456
|
+
|
|
457
|
+
el.setPosition(point);
|
|
458
|
+
el.markRedraw();
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
SymbolDraw.prototype.incrementalPrepareUpdate = function (data) {
|
|
464
|
+
this._seriesScope = makeSeriesScope(data);
|
|
465
|
+
this._data = null;
|
|
466
|
+
this.group.removeAll();
|
|
467
|
+
};
|
|
468
|
+
/**
|
|
469
|
+
* Update symbols draw by new data
|
|
470
|
+
*/
|
|
471
|
+
|
|
472
|
+
SymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) {
|
|
473
|
+
// Clear
|
|
474
|
+
this._progressiveEls = [];
|
|
475
|
+
opt = normalizeUpdateOpt(opt);
|
|
476
|
+
|
|
477
|
+
function updateIncrementalAndHover(el) {
|
|
478
|
+
if (!el.isGroup) {
|
|
479
|
+
el.incremental = true;
|
|
480
|
+
el.ensureState('emphasis').hoverLayer = true;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
for (var idx = taskParams.start; idx < taskParams.end; idx++) {
|
|
485
|
+
var point = data.getItemLayout(idx);
|
|
486
|
+
|
|
487
|
+
if (symbolNeedsDraw(data, point, idx, opt)) {
|
|
488
|
+
var el = new this._SymbolCtor(data, idx, this._seriesScope);
|
|
489
|
+
el.traverse(updateIncrementalAndHover);
|
|
490
|
+
el.setPosition(point);
|
|
491
|
+
this.group.add(el);
|
|
492
|
+
data.setItemGraphicEl(idx, el);
|
|
493
|
+
|
|
494
|
+
this._progressiveEls.push(el);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
SymbolDraw.prototype.eachRendered = function (cb) {
|
|
500
|
+
traverseElements(this._progressiveEls || this.group, cb);
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
SymbolDraw.prototype.remove = function (enableAnimation) {
|
|
504
|
+
var group = this.group;
|
|
505
|
+
var data = this._data; // Incremental model do not have this._data.
|
|
506
|
+
|
|
507
|
+
if (data && enableAnimation) {
|
|
508
|
+
data.eachItemGraphicEl(function (el) {
|
|
509
|
+
el.fadeOut(function () {
|
|
510
|
+
group.remove(el);
|
|
511
|
+
}, data.hostModel);
|
|
512
|
+
});
|
|
513
|
+
} else {
|
|
514
|
+
group.removeAll();
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
return SymbolDraw;
|
|
518
|
+
}();
|
|
519
|
+
|
|
520
|
+
var LineSeriesModel =
|
|
521
|
+
/** @class */
|
|
522
|
+
function (_super) {
|
|
523
|
+
__extends(LineSeriesModel, _super);
|
|
524
|
+
|
|
525
|
+
function LineSeriesModel() {
|
|
526
|
+
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
527
|
+
|
|
528
|
+
_this.type = LineSeriesModel.type;
|
|
529
|
+
_this.hasSymbolVisual = true;
|
|
530
|
+
return _this;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
LineSeriesModel.prototype.getInitialData = function (option) {
|
|
534
|
+
|
|
535
|
+
return createSeriesData(null, this, {
|
|
536
|
+
useEncodeDefaulter: true
|
|
537
|
+
});
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
LineSeriesModel.prototype.getLegendIcon = function (opt) {
|
|
541
|
+
var group = new Group();
|
|
542
|
+
var line = createSymbol('line', 0, opt.itemHeight / 2, opt.itemWidth, 0, opt.lineStyle.stroke, false);
|
|
543
|
+
group.add(line);
|
|
544
|
+
line.setStyle(opt.lineStyle);
|
|
545
|
+
var visualType = this.getData().getVisual('symbol');
|
|
546
|
+
var visualRotate = this.getData().getVisual('symbolRotate');
|
|
547
|
+
var symbolType = visualType === 'none' ? 'circle' : visualType; // Symbol size is 80% when there is a line
|
|
548
|
+
|
|
549
|
+
var size = opt.itemHeight * 0.8;
|
|
550
|
+
var symbol = createSymbol(symbolType, (opt.itemWidth - size) / 2, (opt.itemHeight - size) / 2, size, size, opt.itemStyle.fill);
|
|
551
|
+
group.add(symbol);
|
|
552
|
+
symbol.setStyle(opt.itemStyle);
|
|
553
|
+
var symbolRotate = opt.iconRotate === 'inherit' ? visualRotate : opt.iconRotate || 0;
|
|
554
|
+
symbol.rotation = symbolRotate * Math.PI / 180;
|
|
555
|
+
symbol.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]);
|
|
556
|
+
|
|
557
|
+
if (symbolType.indexOf('empty') > -1) {
|
|
558
|
+
symbol.style.stroke = symbol.style.fill;
|
|
559
|
+
symbol.style.fill = '#fff';
|
|
560
|
+
symbol.style.lineWidth = 2;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
return group;
|
|
564
|
+
};
|
|
565
|
+
|
|
566
|
+
LineSeriesModel.type = 'series.line';
|
|
567
|
+
LineSeriesModel.dependencies = ['grid', 'polar'];
|
|
568
|
+
LineSeriesModel.defaultOption = {
|
|
569
|
+
// zlevel: 0,
|
|
570
|
+
z: 3,
|
|
571
|
+
coordinateSystem: 'cartesian2d',
|
|
572
|
+
legendHoverLink: true,
|
|
573
|
+
clip: true,
|
|
574
|
+
label: {
|
|
575
|
+
position: 'top'
|
|
576
|
+
},
|
|
577
|
+
// itemStyle: {
|
|
578
|
+
// },
|
|
579
|
+
endLabel: {
|
|
580
|
+
show: false,
|
|
581
|
+
valueAnimation: true,
|
|
582
|
+
distance: 8
|
|
583
|
+
},
|
|
584
|
+
lineStyle: {
|
|
585
|
+
width: 2,
|
|
586
|
+
type: 'solid'
|
|
587
|
+
},
|
|
588
|
+
emphasis: {
|
|
589
|
+
scale: true
|
|
590
|
+
},
|
|
591
|
+
// areaStyle: {
|
|
592
|
+
// origin of areaStyle. Valid values:
|
|
593
|
+
// `'auto'/null/undefined`: from axisLine to data
|
|
594
|
+
// `'start'`: from min to data
|
|
595
|
+
// `'end'`: from data to max
|
|
596
|
+
// origin: 'auto'
|
|
597
|
+
// },
|
|
598
|
+
// false, 'start', 'end', 'middle'
|
|
599
|
+
step: false,
|
|
600
|
+
// Disabled if step is true
|
|
601
|
+
smooth: false,
|
|
602
|
+
smoothMonotone: null,
|
|
603
|
+
symbol: 'emptyCircle',
|
|
604
|
+
symbolSize: 4,
|
|
605
|
+
symbolRotate: null,
|
|
606
|
+
showSymbol: true,
|
|
607
|
+
// `false`: follow the label interval strategy.
|
|
608
|
+
// `true`: show all symbols.
|
|
609
|
+
// `'auto'`: If possible, show all symbols, otherwise
|
|
610
|
+
// follow the label interval strategy.
|
|
611
|
+
showAllSymbol: 'auto',
|
|
612
|
+
// Whether to connect break point.
|
|
613
|
+
connectNulls: false,
|
|
614
|
+
// Sampling for large data. Can be: 'average', 'max', 'min', 'sum', 'lttb'.
|
|
615
|
+
sampling: 'none',
|
|
616
|
+
animationEasing: 'linear',
|
|
617
|
+
// Disable progressive
|
|
618
|
+
progressive: 0,
|
|
619
|
+
hoverLayerThreshold: Infinity,
|
|
620
|
+
universalTransition: {
|
|
621
|
+
divideShape: 'clone'
|
|
622
|
+
},
|
|
623
|
+
triggerLineEvent: false
|
|
624
|
+
};
|
|
625
|
+
return LineSeriesModel;
|
|
626
|
+
}(SeriesModel);
|
|
627
|
+
|
|
628
|
+
function prepareDataCoordInfo(coordSys, data, valueOrigin) {
|
|
629
|
+
var baseAxis = coordSys.getBaseAxis();
|
|
630
|
+
var valueAxis = coordSys.getOtherAxis(baseAxis);
|
|
631
|
+
var valueStart = getValueStart(valueAxis, valueOrigin);
|
|
632
|
+
var baseAxisDim = baseAxis.dim;
|
|
633
|
+
var valueAxisDim = valueAxis.dim;
|
|
634
|
+
var valueDim = data.mapDimension(valueAxisDim);
|
|
635
|
+
var baseDim = data.mapDimension(baseAxisDim);
|
|
636
|
+
var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0;
|
|
637
|
+
var dims = map(coordSys.dimensions, function (coordDim) {
|
|
638
|
+
return data.mapDimension(coordDim);
|
|
639
|
+
});
|
|
640
|
+
var stacked = false;
|
|
641
|
+
var stackResultDim = data.getCalculationInfo('stackResultDimension');
|
|
642
|
+
|
|
643
|
+
if (isDimensionStacked(data, dims[0]
|
|
644
|
+
/* , dims[1] */
|
|
645
|
+
)) {
|
|
646
|
+
// jshint ignore:line
|
|
647
|
+
stacked = true;
|
|
648
|
+
dims[0] = stackResultDim;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (isDimensionStacked(data, dims[1]
|
|
652
|
+
/* , dims[0] */
|
|
653
|
+
)) {
|
|
654
|
+
// jshint ignore:line
|
|
655
|
+
stacked = true;
|
|
656
|
+
dims[1] = stackResultDim;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
return {
|
|
660
|
+
dataDimsForPoint: dims,
|
|
661
|
+
valueStart: valueStart,
|
|
662
|
+
valueAxisDim: valueAxisDim,
|
|
663
|
+
baseAxisDim: baseAxisDim,
|
|
664
|
+
stacked: !!stacked,
|
|
665
|
+
valueDim: valueDim,
|
|
666
|
+
baseDim: baseDim,
|
|
667
|
+
baseDataOffset: baseDataOffset,
|
|
668
|
+
stackedOverDimension: data.getCalculationInfo('stackedOverDimension')
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
function getValueStart(valueAxis, valueOrigin) {
|
|
673
|
+
var valueStart = 0;
|
|
674
|
+
var extent = valueAxis.scale.getExtent();
|
|
675
|
+
|
|
676
|
+
if (valueOrigin === 'start') {
|
|
677
|
+
valueStart = extent[0];
|
|
678
|
+
} else if (valueOrigin === 'end') {
|
|
679
|
+
valueStart = extent[1];
|
|
680
|
+
} // If origin is specified as a number, use it as
|
|
681
|
+
// valueStart directly
|
|
682
|
+
else if (isNumber(valueOrigin) && !isNaN(valueOrigin)) {
|
|
683
|
+
valueStart = valueOrigin;
|
|
684
|
+
} // auto
|
|
685
|
+
else {
|
|
686
|
+
// Both positive
|
|
687
|
+
if (extent[0] > 0) {
|
|
688
|
+
valueStart = extent[0];
|
|
689
|
+
} // Both negative
|
|
690
|
+
else if (extent[1] < 0) {
|
|
691
|
+
valueStart = extent[1];
|
|
692
|
+
} // If is one positive, and one negative, onZero shall be true
|
|
693
|
+
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
return valueStart;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
function getStackedOnPoint(dataCoordInfo, coordSys, data, idx) {
|
|
700
|
+
var value = NaN;
|
|
701
|
+
|
|
702
|
+
if (dataCoordInfo.stacked) {
|
|
703
|
+
value = data.get(data.getCalculationInfo('stackedOverDimension'), idx);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
if (isNaN(value)) {
|
|
707
|
+
value = dataCoordInfo.valueStart;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
var baseDataOffset = dataCoordInfo.baseDataOffset;
|
|
711
|
+
var stackedData = [];
|
|
712
|
+
stackedData[baseDataOffset] = data.get(dataCoordInfo.baseDim, idx);
|
|
713
|
+
stackedData[1 - baseDataOffset] = value;
|
|
714
|
+
return coordSys.dataToPoint(stackedData);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
function diffData(oldData, newData) {
|
|
718
|
+
var diffResult = [];
|
|
719
|
+
newData.diff(oldData).add(function (idx) {
|
|
720
|
+
diffResult.push({
|
|
721
|
+
cmd: '+',
|
|
722
|
+
idx: idx
|
|
723
|
+
});
|
|
724
|
+
}).update(function (newIdx, oldIdx) {
|
|
725
|
+
diffResult.push({
|
|
726
|
+
cmd: '=',
|
|
727
|
+
idx: oldIdx,
|
|
728
|
+
idx1: newIdx
|
|
729
|
+
});
|
|
730
|
+
}).remove(function (idx) {
|
|
731
|
+
diffResult.push({
|
|
732
|
+
cmd: '-',
|
|
733
|
+
idx: idx
|
|
734
|
+
});
|
|
735
|
+
}).execute();
|
|
736
|
+
return diffResult;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
function lineAnimationDiff(oldData, newData, oldStackedOnPoints, newStackedOnPoints, oldCoordSys, newCoordSys, oldValueOrigin, newValueOrigin) {
|
|
740
|
+
var diff = diffData(oldData, newData); // let newIdList = newData.mapArray(newData.getId);
|
|
741
|
+
// let oldIdList = oldData.mapArray(oldData.getId);
|
|
742
|
+
// convertToIntId(newIdList, oldIdList);
|
|
743
|
+
// // FIXME One data ?
|
|
744
|
+
// diff = arrayDiff(oldIdList, newIdList);
|
|
745
|
+
|
|
746
|
+
var currPoints = [];
|
|
747
|
+
var nextPoints = []; // Points for stacking base line
|
|
748
|
+
|
|
749
|
+
var currStackedPoints = [];
|
|
750
|
+
var nextStackedPoints = [];
|
|
751
|
+
var status = [];
|
|
752
|
+
var sortedIndices = [];
|
|
753
|
+
var rawIndices = [];
|
|
754
|
+
var newDataOldCoordInfo = prepareDataCoordInfo(oldCoordSys, newData, oldValueOrigin); // const oldDataNewCoordInfo = prepareDataCoordInfo(newCoordSys, oldData, newValueOrigin);
|
|
755
|
+
|
|
756
|
+
var oldPoints = oldData.getLayout('points') || [];
|
|
757
|
+
var newPoints = newData.getLayout('points') || [];
|
|
758
|
+
|
|
759
|
+
for (var i = 0; i < diff.length; i++) {
|
|
760
|
+
var diffItem = diff[i];
|
|
761
|
+
var pointAdded = true;
|
|
762
|
+
var oldIdx2 = void 0;
|
|
763
|
+
var newIdx2 = void 0; // FIXME, animation is not so perfect when dataZoom window moves fast
|
|
764
|
+
// Which is in case remvoing or add more than one data in the tail or head
|
|
765
|
+
|
|
766
|
+
switch (diffItem.cmd) {
|
|
767
|
+
case '=':
|
|
768
|
+
oldIdx2 = diffItem.idx * 2;
|
|
769
|
+
newIdx2 = diffItem.idx1 * 2;
|
|
770
|
+
var currentX = oldPoints[oldIdx2];
|
|
771
|
+
var currentY = oldPoints[oldIdx2 + 1];
|
|
772
|
+
var nextX = newPoints[newIdx2];
|
|
773
|
+
var nextY = newPoints[newIdx2 + 1]; // If previous data is NaN, use next point directly
|
|
774
|
+
|
|
775
|
+
if (isNaN(currentX) || isNaN(currentY)) {
|
|
776
|
+
currentX = nextX;
|
|
777
|
+
currentY = nextY;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
currPoints.push(currentX, currentY);
|
|
781
|
+
nextPoints.push(nextX, nextY);
|
|
782
|
+
currStackedPoints.push(oldStackedOnPoints[oldIdx2], oldStackedOnPoints[oldIdx2 + 1]);
|
|
783
|
+
nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]);
|
|
784
|
+
rawIndices.push(newData.getRawIndex(diffItem.idx1));
|
|
785
|
+
break;
|
|
786
|
+
|
|
787
|
+
case '+':
|
|
788
|
+
var newIdx = diffItem.idx;
|
|
789
|
+
var newDataDimsForPoint = newDataOldCoordInfo.dataDimsForPoint;
|
|
790
|
+
var oldPt = oldCoordSys.dataToPoint([newData.get(newDataDimsForPoint[0], newIdx), newData.get(newDataDimsForPoint[1], newIdx)]);
|
|
791
|
+
newIdx2 = newIdx * 2;
|
|
792
|
+
currPoints.push(oldPt[0], oldPt[1]);
|
|
793
|
+
nextPoints.push(newPoints[newIdx2], newPoints[newIdx2 + 1]);
|
|
794
|
+
var stackedOnPoint = getStackedOnPoint(newDataOldCoordInfo, oldCoordSys, newData, newIdx);
|
|
795
|
+
currStackedPoints.push(stackedOnPoint[0], stackedOnPoint[1]);
|
|
796
|
+
nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]);
|
|
797
|
+
rawIndices.push(newData.getRawIndex(newIdx));
|
|
798
|
+
break;
|
|
799
|
+
|
|
800
|
+
case '-':
|
|
801
|
+
pointAdded = false;
|
|
802
|
+
} // Original indices
|
|
803
|
+
|
|
804
|
+
|
|
805
|
+
if (pointAdded) {
|
|
806
|
+
status.push(diffItem);
|
|
807
|
+
sortedIndices.push(sortedIndices.length);
|
|
808
|
+
}
|
|
809
|
+
} // Diff result may be crossed if all items are changed
|
|
810
|
+
// Sort by data index
|
|
811
|
+
|
|
812
|
+
|
|
813
|
+
sortedIndices.sort(function (a, b) {
|
|
814
|
+
return rawIndices[a] - rawIndices[b];
|
|
815
|
+
});
|
|
816
|
+
var len = currPoints.length;
|
|
817
|
+
var sortedCurrPoints = createFloat32Array(len);
|
|
818
|
+
var sortedNextPoints = createFloat32Array(len);
|
|
819
|
+
var sortedCurrStackedPoints = createFloat32Array(len);
|
|
820
|
+
var sortedNextStackedPoints = createFloat32Array(len);
|
|
821
|
+
var sortedStatus = [];
|
|
822
|
+
|
|
823
|
+
for (var i = 0; i < sortedIndices.length; i++) {
|
|
824
|
+
var idx = sortedIndices[i];
|
|
825
|
+
var i2 = i * 2;
|
|
826
|
+
var idx2 = idx * 2;
|
|
827
|
+
sortedCurrPoints[i2] = currPoints[idx2];
|
|
828
|
+
sortedCurrPoints[i2 + 1] = currPoints[idx2 + 1];
|
|
829
|
+
sortedNextPoints[i2] = nextPoints[idx2];
|
|
830
|
+
sortedNextPoints[i2 + 1] = nextPoints[idx2 + 1];
|
|
831
|
+
sortedCurrStackedPoints[i2] = currStackedPoints[idx2];
|
|
832
|
+
sortedCurrStackedPoints[i2 + 1] = currStackedPoints[idx2 + 1];
|
|
833
|
+
sortedNextStackedPoints[i2] = nextStackedPoints[idx2];
|
|
834
|
+
sortedNextStackedPoints[i2 + 1] = nextStackedPoints[idx2 + 1];
|
|
835
|
+
sortedStatus[i] = status[idx];
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
return {
|
|
839
|
+
current: sortedCurrPoints,
|
|
840
|
+
next: sortedNextPoints,
|
|
841
|
+
stackedOnCurrent: sortedCurrStackedPoints,
|
|
842
|
+
stackedOnNext: sortedNextStackedPoints,
|
|
843
|
+
status: sortedStatus
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
var mathMin = Math.min;
|
|
848
|
+
var mathMax = Math.max;
|
|
849
|
+
|
|
850
|
+
function isPointNull$1(x, y) {
|
|
851
|
+
return isNaN(x) || isNaN(y);
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Draw smoothed line in non-monotone, in may cause undesired curve in extreme
|
|
855
|
+
* situations. This should be used when points are non-monotone neither in x or
|
|
856
|
+
* y dimension.
|
|
857
|
+
*/
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
function drawSegment(ctx, points, start, segLen, allLen, dir, smooth, smoothMonotone, connectNulls) {
|
|
861
|
+
var prevX;
|
|
862
|
+
var prevY;
|
|
863
|
+
var cpx0;
|
|
864
|
+
var cpy0;
|
|
865
|
+
var cpx1;
|
|
866
|
+
var cpy1;
|
|
867
|
+
var idx = start;
|
|
868
|
+
var k = 0;
|
|
869
|
+
|
|
870
|
+
for (; k < segLen; k++) {
|
|
871
|
+
var x = points[idx * 2];
|
|
872
|
+
var y = points[idx * 2 + 1];
|
|
873
|
+
|
|
874
|
+
if (idx >= allLen || idx < 0) {
|
|
875
|
+
break;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
if (isPointNull$1(x, y)) {
|
|
879
|
+
if (connectNulls) {
|
|
880
|
+
idx += dir;
|
|
881
|
+
continue;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
break;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
if (idx === start) {
|
|
888
|
+
ctx[dir > 0 ? 'moveTo' : 'lineTo'](x, y);
|
|
889
|
+
cpx0 = x;
|
|
890
|
+
cpy0 = y;
|
|
891
|
+
} else {
|
|
892
|
+
var dx = x - prevX;
|
|
893
|
+
var dy = y - prevY; // Ignore tiny segment.
|
|
894
|
+
|
|
895
|
+
if (dx * dx + dy * dy < 0.5) {
|
|
896
|
+
idx += dir;
|
|
897
|
+
continue;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
if (smooth > 0) {
|
|
901
|
+
var nextIdx = idx + dir;
|
|
902
|
+
var nextX = points[nextIdx * 2];
|
|
903
|
+
var nextY = points[nextIdx * 2 + 1]; // Ignore duplicate point
|
|
904
|
+
|
|
905
|
+
while (nextX === x && nextY === y && k < segLen) {
|
|
906
|
+
k++;
|
|
907
|
+
nextIdx += dir;
|
|
908
|
+
idx += dir;
|
|
909
|
+
nextX = points[nextIdx * 2];
|
|
910
|
+
nextY = points[nextIdx * 2 + 1];
|
|
911
|
+
x = points[idx * 2];
|
|
912
|
+
y = points[idx * 2 + 1];
|
|
913
|
+
dx = x - prevX;
|
|
914
|
+
dy = y - prevY;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
var tmpK = k + 1;
|
|
918
|
+
|
|
919
|
+
if (connectNulls) {
|
|
920
|
+
// Find next point not null
|
|
921
|
+
while (isPointNull$1(nextX, nextY) && tmpK < segLen) {
|
|
922
|
+
tmpK++;
|
|
923
|
+
nextIdx += dir;
|
|
924
|
+
nextX = points[nextIdx * 2];
|
|
925
|
+
nextY = points[nextIdx * 2 + 1];
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
var ratioNextSeg = 0.5;
|
|
930
|
+
var vx = 0;
|
|
931
|
+
var vy = 0;
|
|
932
|
+
var nextCpx0 = void 0;
|
|
933
|
+
var nextCpy0 = void 0; // Is last point
|
|
934
|
+
|
|
935
|
+
if (tmpK >= segLen || isPointNull$1(nextX, nextY)) {
|
|
936
|
+
cpx1 = x;
|
|
937
|
+
cpy1 = y;
|
|
938
|
+
} else {
|
|
939
|
+
vx = nextX - prevX;
|
|
940
|
+
vy = nextY - prevY;
|
|
941
|
+
var dx0 = x - prevX;
|
|
942
|
+
var dx1 = nextX - x;
|
|
943
|
+
var dy0 = y - prevY;
|
|
944
|
+
var dy1 = nextY - y;
|
|
945
|
+
var lenPrevSeg = void 0;
|
|
946
|
+
var lenNextSeg = void 0;
|
|
947
|
+
|
|
948
|
+
if (smoothMonotone === 'x') {
|
|
949
|
+
lenPrevSeg = Math.abs(dx0);
|
|
950
|
+
lenNextSeg = Math.abs(dx1);
|
|
951
|
+
var dir_1 = vx > 0 ? 1 : -1;
|
|
952
|
+
cpx1 = x - dir_1 * lenPrevSeg * smooth;
|
|
953
|
+
cpy1 = y;
|
|
954
|
+
nextCpx0 = x + dir_1 * lenNextSeg * smooth;
|
|
955
|
+
nextCpy0 = y;
|
|
956
|
+
} else if (smoothMonotone === 'y') {
|
|
957
|
+
lenPrevSeg = Math.abs(dy0);
|
|
958
|
+
lenNextSeg = Math.abs(dy1);
|
|
959
|
+
var dir_2 = vy > 0 ? 1 : -1;
|
|
960
|
+
cpx1 = x;
|
|
961
|
+
cpy1 = y - dir_2 * lenPrevSeg * smooth;
|
|
962
|
+
nextCpx0 = x;
|
|
963
|
+
nextCpy0 = y + dir_2 * lenNextSeg * smooth;
|
|
964
|
+
} else {
|
|
965
|
+
lenPrevSeg = Math.sqrt(dx0 * dx0 + dy0 * dy0);
|
|
966
|
+
lenNextSeg = Math.sqrt(dx1 * dx1 + dy1 * dy1); // Use ratio of seg length
|
|
967
|
+
|
|
968
|
+
ratioNextSeg = lenNextSeg / (lenNextSeg + lenPrevSeg);
|
|
969
|
+
cpx1 = x - vx * smooth * (1 - ratioNextSeg);
|
|
970
|
+
cpy1 = y - vy * smooth * (1 - ratioNextSeg); // cp0 of next segment
|
|
971
|
+
|
|
972
|
+
nextCpx0 = x + vx * smooth * ratioNextSeg;
|
|
973
|
+
nextCpy0 = y + vy * smooth * ratioNextSeg; // Smooth constraint between point and next point.
|
|
974
|
+
// Avoid exceeding extreme after smoothing.
|
|
975
|
+
|
|
976
|
+
nextCpx0 = mathMin(nextCpx0, mathMax(nextX, x));
|
|
977
|
+
nextCpy0 = mathMin(nextCpy0, mathMax(nextY, y));
|
|
978
|
+
nextCpx0 = mathMax(nextCpx0, mathMin(nextX, x));
|
|
979
|
+
nextCpy0 = mathMax(nextCpy0, mathMin(nextY, y)); // Reclaculate cp1 based on the adjusted cp0 of next seg.
|
|
980
|
+
|
|
981
|
+
vx = nextCpx0 - x;
|
|
982
|
+
vy = nextCpy0 - y;
|
|
983
|
+
cpx1 = x - vx * lenPrevSeg / lenNextSeg;
|
|
984
|
+
cpy1 = y - vy * lenPrevSeg / lenNextSeg; // Smooth constraint between point and prev point.
|
|
985
|
+
// Avoid exceeding extreme after smoothing.
|
|
986
|
+
|
|
987
|
+
cpx1 = mathMin(cpx1, mathMax(prevX, x));
|
|
988
|
+
cpy1 = mathMin(cpy1, mathMax(prevY, y));
|
|
989
|
+
cpx1 = mathMax(cpx1, mathMin(prevX, x));
|
|
990
|
+
cpy1 = mathMax(cpy1, mathMin(prevY, y)); // Adjust next cp0 again.
|
|
991
|
+
|
|
992
|
+
vx = x - cpx1;
|
|
993
|
+
vy = y - cpy1;
|
|
994
|
+
nextCpx0 = x + vx * lenNextSeg / lenPrevSeg;
|
|
995
|
+
nextCpy0 = y + vy * lenNextSeg / lenPrevSeg;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
ctx.bezierCurveTo(cpx0, cpy0, cpx1, cpy1, x, y);
|
|
1000
|
+
cpx0 = nextCpx0;
|
|
1001
|
+
cpy0 = nextCpy0;
|
|
1002
|
+
} else {
|
|
1003
|
+
ctx.lineTo(x, y);
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
prevX = x;
|
|
1008
|
+
prevY = y;
|
|
1009
|
+
idx += dir;
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
return k;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
var ECPolylineShape =
|
|
1016
|
+
/** @class */
|
|
1017
|
+
function () {
|
|
1018
|
+
function ECPolylineShape() {
|
|
1019
|
+
this.smooth = 0;
|
|
1020
|
+
this.smoothConstraint = true;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
return ECPolylineShape;
|
|
1024
|
+
}();
|
|
1025
|
+
|
|
1026
|
+
var ECPolyline =
|
|
1027
|
+
/** @class */
|
|
1028
|
+
function (_super) {
|
|
1029
|
+
__extends(ECPolyline, _super);
|
|
1030
|
+
|
|
1031
|
+
function ECPolyline(opts) {
|
|
1032
|
+
var _this = _super.call(this, opts) || this;
|
|
1033
|
+
|
|
1034
|
+
_this.type = 'ec-polyline';
|
|
1035
|
+
return _this;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
ECPolyline.prototype.getDefaultStyle = function () {
|
|
1039
|
+
return {
|
|
1040
|
+
stroke: '#000',
|
|
1041
|
+
fill: null
|
|
1042
|
+
};
|
|
1043
|
+
};
|
|
1044
|
+
|
|
1045
|
+
ECPolyline.prototype.getDefaultShape = function () {
|
|
1046
|
+
return new ECPolylineShape();
|
|
1047
|
+
};
|
|
1048
|
+
|
|
1049
|
+
ECPolyline.prototype.buildPath = function (ctx, shape) {
|
|
1050
|
+
var points = shape.points;
|
|
1051
|
+
var i = 0;
|
|
1052
|
+
var len = points.length / 2; // const result = getBoundingBox(points, shape.smoothConstraint);
|
|
1053
|
+
|
|
1054
|
+
if (shape.connectNulls) {
|
|
1055
|
+
// Must remove first and last null values avoid draw error in polygon
|
|
1056
|
+
for (; len > 0; len--) {
|
|
1057
|
+
if (!isPointNull$1(points[len * 2 - 2], points[len * 2 - 1])) {
|
|
1058
|
+
break;
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
for (; i < len; i++) {
|
|
1063
|
+
if (!isPointNull$1(points[i * 2], points[i * 2 + 1])) {
|
|
1064
|
+
break;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
while (i < len) {
|
|
1070
|
+
i += drawSegment(ctx, points, i, len, len, 1, shape.smooth, shape.smoothMonotone, shape.connectNulls) + 1;
|
|
1071
|
+
}
|
|
1072
|
+
};
|
|
1073
|
+
|
|
1074
|
+
ECPolyline.prototype.getPointOn = function (xOrY, dim) {
|
|
1075
|
+
if (!this.path) {
|
|
1076
|
+
this.createPathProxy();
|
|
1077
|
+
this.buildPath(this.path, this.shape);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
var path = this.path;
|
|
1081
|
+
var data = path.data;
|
|
1082
|
+
var CMD = PathProxy.CMD;
|
|
1083
|
+
var x0;
|
|
1084
|
+
var y0;
|
|
1085
|
+
var isDimX = dim === 'x';
|
|
1086
|
+
var roots = [];
|
|
1087
|
+
|
|
1088
|
+
for (var i = 0; i < data.length;) {
|
|
1089
|
+
var cmd = data[i++];
|
|
1090
|
+
var x = void 0;
|
|
1091
|
+
var y = void 0;
|
|
1092
|
+
var x2 = void 0;
|
|
1093
|
+
var y2 = void 0;
|
|
1094
|
+
var x3 = void 0;
|
|
1095
|
+
var y3 = void 0;
|
|
1096
|
+
var t = void 0;
|
|
1097
|
+
|
|
1098
|
+
switch (cmd) {
|
|
1099
|
+
case CMD.M:
|
|
1100
|
+
x0 = data[i++];
|
|
1101
|
+
y0 = data[i++];
|
|
1102
|
+
break;
|
|
1103
|
+
|
|
1104
|
+
case CMD.L:
|
|
1105
|
+
x = data[i++];
|
|
1106
|
+
y = data[i++];
|
|
1107
|
+
t = isDimX ? (xOrY - x0) / (x - x0) : (xOrY - y0) / (y - y0);
|
|
1108
|
+
|
|
1109
|
+
if (t <= 1 && t >= 0) {
|
|
1110
|
+
var val = isDimX ? (y - y0) * t + y0 : (x - x0) * t + x0;
|
|
1111
|
+
return isDimX ? [xOrY, val] : [val, xOrY];
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
x0 = x;
|
|
1115
|
+
y0 = y;
|
|
1116
|
+
break;
|
|
1117
|
+
|
|
1118
|
+
case CMD.C:
|
|
1119
|
+
x = data[i++];
|
|
1120
|
+
y = data[i++];
|
|
1121
|
+
x2 = data[i++];
|
|
1122
|
+
y2 = data[i++];
|
|
1123
|
+
x3 = data[i++];
|
|
1124
|
+
y3 = data[i++];
|
|
1125
|
+
var nRoot = isDimX ? cubicRootAt(x0, x, x2, x3, xOrY, roots) : cubicRootAt(y0, y, y2, y3, xOrY, roots);
|
|
1126
|
+
|
|
1127
|
+
if (nRoot > 0) {
|
|
1128
|
+
for (var i_1 = 0; i_1 < nRoot; i_1++) {
|
|
1129
|
+
var t_1 = roots[i_1];
|
|
1130
|
+
|
|
1131
|
+
if (t_1 <= 1 && t_1 >= 0) {
|
|
1132
|
+
var val = isDimX ? cubicAt(y0, y, y2, y3, t_1) : cubicAt(x0, x, x2, x3, t_1);
|
|
1133
|
+
return isDimX ? [xOrY, val] : [val, xOrY];
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
x0 = x3;
|
|
1139
|
+
y0 = y3;
|
|
1140
|
+
break;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
};
|
|
1144
|
+
|
|
1145
|
+
return ECPolyline;
|
|
1146
|
+
}(Path);
|
|
1147
|
+
|
|
1148
|
+
var ECPolygonShape =
|
|
1149
|
+
/** @class */
|
|
1150
|
+
function (_super) {
|
|
1151
|
+
__extends(ECPolygonShape, _super);
|
|
1152
|
+
|
|
1153
|
+
function ECPolygonShape() {
|
|
1154
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
return ECPolygonShape;
|
|
1158
|
+
}(ECPolylineShape);
|
|
1159
|
+
|
|
1160
|
+
var ECPolygon =
|
|
1161
|
+
/** @class */
|
|
1162
|
+
function (_super) {
|
|
1163
|
+
__extends(ECPolygon, _super);
|
|
1164
|
+
|
|
1165
|
+
function ECPolygon(opts) {
|
|
1166
|
+
var _this = _super.call(this, opts) || this;
|
|
1167
|
+
|
|
1168
|
+
_this.type = 'ec-polygon';
|
|
1169
|
+
return _this;
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
ECPolygon.prototype.getDefaultShape = function () {
|
|
1173
|
+
return new ECPolygonShape();
|
|
1174
|
+
};
|
|
1175
|
+
|
|
1176
|
+
ECPolygon.prototype.buildPath = function (ctx, shape) {
|
|
1177
|
+
var points = shape.points;
|
|
1178
|
+
var stackedOnPoints = shape.stackedOnPoints;
|
|
1179
|
+
var i = 0;
|
|
1180
|
+
var len = points.length / 2;
|
|
1181
|
+
var smoothMonotone = shape.smoothMonotone;
|
|
1182
|
+
|
|
1183
|
+
if (shape.connectNulls) {
|
|
1184
|
+
// Must remove first and last null values avoid draw error in polygon
|
|
1185
|
+
for (; len > 0; len--) {
|
|
1186
|
+
if (!isPointNull$1(points[len * 2 - 2], points[len * 2 - 1])) {
|
|
1187
|
+
break;
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
for (; i < len; i++) {
|
|
1192
|
+
if (!isPointNull$1(points[i * 2], points[i * 2 + 1])) {
|
|
1193
|
+
break;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
while (i < len) {
|
|
1199
|
+
var k = drawSegment(ctx, points, i, len, len, 1, shape.smooth, smoothMonotone, shape.connectNulls);
|
|
1200
|
+
drawSegment(ctx, stackedOnPoints, i + k - 1, k, len, -1, shape.stackedOnSmooth, smoothMonotone, shape.connectNulls);
|
|
1201
|
+
i += k + 1;
|
|
1202
|
+
ctx.closePath();
|
|
1203
|
+
}
|
|
1204
|
+
};
|
|
1205
|
+
|
|
1206
|
+
return ECPolygon;
|
|
1207
|
+
}(Path);
|
|
1208
|
+
|
|
1209
|
+
function isPointsSame(points1, points2) {
|
|
1210
|
+
if (points1.length !== points2.length) {
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
for (var i = 0; i < points1.length; i++) {
|
|
1215
|
+
if (points1[i] !== points2[i]) {
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
return true;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
function bboxFromPoints(points) {
|
|
1224
|
+
var minX = Infinity;
|
|
1225
|
+
var minY = Infinity;
|
|
1226
|
+
var maxX = -Infinity;
|
|
1227
|
+
var maxY = -Infinity;
|
|
1228
|
+
|
|
1229
|
+
for (var i = 0; i < points.length;) {
|
|
1230
|
+
var x = points[i++];
|
|
1231
|
+
var y = points[i++];
|
|
1232
|
+
|
|
1233
|
+
if (!isNaN(x)) {
|
|
1234
|
+
minX = Math.min(x, minX);
|
|
1235
|
+
maxX = Math.max(x, maxX);
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
if (!isNaN(y)) {
|
|
1239
|
+
minY = Math.min(y, minY);
|
|
1240
|
+
maxY = Math.max(y, maxY);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
return [[minX, minY], [maxX, maxY]];
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
function getBoundingDiff(points1, points2) {
|
|
1248
|
+
var _a = bboxFromPoints(points1),
|
|
1249
|
+
min1 = _a[0],
|
|
1250
|
+
max1 = _a[1];
|
|
1251
|
+
|
|
1252
|
+
var _b = bboxFromPoints(points2),
|
|
1253
|
+
min2 = _b[0],
|
|
1254
|
+
max2 = _b[1]; // Get a max value from each corner of two boundings.
|
|
1255
|
+
|
|
1256
|
+
|
|
1257
|
+
return Math.max(Math.abs(min1[0] - min2[0]), Math.abs(min1[1] - min2[1]), Math.abs(max1[0] - max2[0]), Math.abs(max1[1] - max2[1]));
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
function getSmooth(smooth) {
|
|
1261
|
+
return isNumber(smooth) ? smooth : smooth ? 0.5 : 0;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
function getStackedOnPoints(coordSys, data, dataCoordInfo) {
|
|
1265
|
+
if (!dataCoordInfo.valueDim) {
|
|
1266
|
+
return [];
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
var len = data.count();
|
|
1270
|
+
var points = createFloat32Array(len * 2);
|
|
1271
|
+
|
|
1272
|
+
for (var idx = 0; idx < len; idx++) {
|
|
1273
|
+
var pt = getStackedOnPoint(dataCoordInfo, coordSys, data, idx);
|
|
1274
|
+
points[idx * 2] = pt[0];
|
|
1275
|
+
points[idx * 2 + 1] = pt[1];
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
return points;
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
function turnPointsIntoStep(points, coordSys, stepTurnAt, connectNulls) {
|
|
1282
|
+
var baseAxis = coordSys.getBaseAxis();
|
|
1283
|
+
var baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1;
|
|
1284
|
+
var stepPoints = [];
|
|
1285
|
+
var i = 0;
|
|
1286
|
+
var stepPt = [];
|
|
1287
|
+
var pt = [];
|
|
1288
|
+
var nextPt = [];
|
|
1289
|
+
var filteredPoints = [];
|
|
1290
|
+
|
|
1291
|
+
if (connectNulls) {
|
|
1292
|
+
for (i = 0; i < points.length; i += 2) {
|
|
1293
|
+
if (!isNaN(points[i]) && !isNaN(points[i + 1])) {
|
|
1294
|
+
filteredPoints.push(points[i], points[i + 1]);
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
points = filteredPoints;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
for (i = 0; i < points.length - 2; i += 2) {
|
|
1302
|
+
nextPt[0] = points[i + 2];
|
|
1303
|
+
nextPt[1] = points[i + 3];
|
|
1304
|
+
pt[0] = points[i];
|
|
1305
|
+
pt[1] = points[i + 1];
|
|
1306
|
+
stepPoints.push(pt[0], pt[1]);
|
|
1307
|
+
|
|
1308
|
+
switch (stepTurnAt) {
|
|
1309
|
+
case 'end':
|
|
1310
|
+
stepPt[baseIndex] = nextPt[baseIndex];
|
|
1311
|
+
stepPt[1 - baseIndex] = pt[1 - baseIndex];
|
|
1312
|
+
stepPoints.push(stepPt[0], stepPt[1]);
|
|
1313
|
+
break;
|
|
1314
|
+
|
|
1315
|
+
case 'middle':
|
|
1316
|
+
var middle = (pt[baseIndex] + nextPt[baseIndex]) / 2;
|
|
1317
|
+
var stepPt2 = [];
|
|
1318
|
+
stepPt[baseIndex] = stepPt2[baseIndex] = middle;
|
|
1319
|
+
stepPt[1 - baseIndex] = pt[1 - baseIndex];
|
|
1320
|
+
stepPt2[1 - baseIndex] = nextPt[1 - baseIndex];
|
|
1321
|
+
stepPoints.push(stepPt[0], stepPt[1]);
|
|
1322
|
+
stepPoints.push(stepPt2[0], stepPt2[1]);
|
|
1323
|
+
break;
|
|
1324
|
+
|
|
1325
|
+
default:
|
|
1326
|
+
// default is start
|
|
1327
|
+
stepPt[baseIndex] = pt[baseIndex];
|
|
1328
|
+
stepPt[1 - baseIndex] = nextPt[1 - baseIndex];
|
|
1329
|
+
stepPoints.push(stepPt[0], stepPt[1]);
|
|
1330
|
+
}
|
|
1331
|
+
} // Last points
|
|
1332
|
+
|
|
1333
|
+
|
|
1334
|
+
stepPoints.push(points[i++], points[i++]);
|
|
1335
|
+
return stepPoints;
|
|
1336
|
+
}
|
|
1337
|
+
/**
|
|
1338
|
+
* Clip color stops to edge. Avoid creating too large gradients.
|
|
1339
|
+
* Which may lead to blurry when GPU acceleration is enabled. See #15680
|
|
1340
|
+
*
|
|
1341
|
+
* The stops has been sorted from small to large.
|
|
1342
|
+
*/
|
|
1343
|
+
|
|
1344
|
+
|
|
1345
|
+
function clipColorStops(colorStops, maxSize) {
|
|
1346
|
+
var newColorStops = [];
|
|
1347
|
+
var len = colorStops.length; // coord will always < 0 in prevOutOfRangeColorStop.
|
|
1348
|
+
|
|
1349
|
+
var prevOutOfRangeColorStop;
|
|
1350
|
+
var prevInRangeColorStop;
|
|
1351
|
+
|
|
1352
|
+
function lerpStop(stop0, stop1, clippedCoord) {
|
|
1353
|
+
var coord0 = stop0.coord;
|
|
1354
|
+
var p = (clippedCoord - coord0) / (stop1.coord - coord0);
|
|
1355
|
+
var color = lerp(p, [stop0.color, stop1.color]);
|
|
1356
|
+
return {
|
|
1357
|
+
coord: clippedCoord,
|
|
1358
|
+
color: color
|
|
1359
|
+
};
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
for (var i = 0; i < len; i++) {
|
|
1363
|
+
var stop_1 = colorStops[i];
|
|
1364
|
+
var coord = stop_1.coord;
|
|
1365
|
+
|
|
1366
|
+
if (coord < 0) {
|
|
1367
|
+
prevOutOfRangeColorStop = stop_1;
|
|
1368
|
+
} else if (coord > maxSize) {
|
|
1369
|
+
if (prevInRangeColorStop) {
|
|
1370
|
+
newColorStops.push(lerpStop(prevInRangeColorStop, stop_1, maxSize));
|
|
1371
|
+
} else if (prevOutOfRangeColorStop) {
|
|
1372
|
+
// If there are two stops and coord range is between these two stops
|
|
1373
|
+
newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0), lerpStop(prevOutOfRangeColorStop, stop_1, maxSize));
|
|
1374
|
+
} // All following stop will be out of range. So just ignore them.
|
|
1375
|
+
|
|
1376
|
+
|
|
1377
|
+
break;
|
|
1378
|
+
} else {
|
|
1379
|
+
if (prevOutOfRangeColorStop) {
|
|
1380
|
+
newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0)); // Reset
|
|
1381
|
+
|
|
1382
|
+
prevOutOfRangeColorStop = null;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
newColorStops.push(stop_1);
|
|
1386
|
+
prevInRangeColorStop = stop_1;
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
return newColorStops;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
function getVisualGradient(data, coordSys, api) {
|
|
1394
|
+
var visualMetaList = data.getVisual('visualMeta');
|
|
1395
|
+
|
|
1396
|
+
if (!visualMetaList || !visualMetaList.length || !data.count()) {
|
|
1397
|
+
// When data.count() is 0, gradient range can not be calculated.
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
if (coordSys.type !== 'cartesian2d') {
|
|
1402
|
+
|
|
1403
|
+
return;
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
var coordDim;
|
|
1407
|
+
var visualMeta;
|
|
1408
|
+
|
|
1409
|
+
for (var i = visualMetaList.length - 1; i >= 0; i--) {
|
|
1410
|
+
var dimInfo = data.getDimensionInfo(visualMetaList[i].dimension);
|
|
1411
|
+
coordDim = dimInfo && dimInfo.coordDim; // Can only be x or y
|
|
1412
|
+
|
|
1413
|
+
if (coordDim === 'x' || coordDim === 'y') {
|
|
1414
|
+
visualMeta = visualMetaList[i];
|
|
1415
|
+
break;
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
if (!visualMeta) {
|
|
1420
|
+
|
|
1421
|
+
return;
|
|
1422
|
+
} // If the area to be rendered is bigger than area defined by LinearGradient,
|
|
1423
|
+
// the canvas spec prescribes that the color of the first stop and the last
|
|
1424
|
+
// stop should be used. But if two stops are added at offset 0, in effect
|
|
1425
|
+
// browsers use the color of the second stop to render area outside
|
|
1426
|
+
// LinearGradient. So we can only infinitesimally extend area defined in
|
|
1427
|
+
// LinearGradient to render `outerColors`.
|
|
1428
|
+
|
|
1429
|
+
|
|
1430
|
+
var axis = coordSys.getAxis(coordDim); // dataToCoord mapping may not be linear, but must be monotonic.
|
|
1431
|
+
|
|
1432
|
+
var colorStops = map(visualMeta.stops, function (stop) {
|
|
1433
|
+
// offset will be calculated later.
|
|
1434
|
+
return {
|
|
1435
|
+
coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)),
|
|
1436
|
+
color: stop.color
|
|
1437
|
+
};
|
|
1438
|
+
});
|
|
1439
|
+
var stopLen = colorStops.length;
|
|
1440
|
+
var outerColors = visualMeta.outerColors.slice();
|
|
1441
|
+
|
|
1442
|
+
if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) {
|
|
1443
|
+
colorStops.reverse();
|
|
1444
|
+
outerColors.reverse();
|
|
1445
|
+
}
|
|
1446
|
+
|
|
1447
|
+
var colorStopsInRange = clipColorStops(colorStops, coordDim === 'x' ? api.getWidth() : api.getHeight());
|
|
1448
|
+
var inRangeStopLen = colorStopsInRange.length;
|
|
1449
|
+
|
|
1450
|
+
if (!inRangeStopLen && stopLen) {
|
|
1451
|
+
// All stops are out of range. All will be the same color.
|
|
1452
|
+
return colorStops[0].coord < 0 ? outerColors[1] ? outerColors[1] : colorStops[stopLen - 1].color : outerColors[0] ? outerColors[0] : colorStops[0].color;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
var tinyExtent = 10; // Arbitrary value: 10px
|
|
1456
|
+
|
|
1457
|
+
var minCoord = colorStopsInRange[0].coord - tinyExtent;
|
|
1458
|
+
var maxCoord = colorStopsInRange[inRangeStopLen - 1].coord + tinyExtent;
|
|
1459
|
+
var coordSpan = maxCoord - minCoord;
|
|
1460
|
+
|
|
1461
|
+
if (coordSpan < 1e-3) {
|
|
1462
|
+
return 'transparent';
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
each(colorStopsInRange, function (stop) {
|
|
1466
|
+
stop.offset = (stop.coord - minCoord) / coordSpan;
|
|
1467
|
+
});
|
|
1468
|
+
colorStopsInRange.push({
|
|
1469
|
+
// NOTE: inRangeStopLen may still be 0 if stoplen is zero.
|
|
1470
|
+
offset: inRangeStopLen ? colorStopsInRange[inRangeStopLen - 1].offset : 0.5,
|
|
1471
|
+
color: outerColors[1] || 'transparent'
|
|
1472
|
+
});
|
|
1473
|
+
colorStopsInRange.unshift({
|
|
1474
|
+
offset: inRangeStopLen ? colorStopsInRange[0].offset : 0.5,
|
|
1475
|
+
color: outerColors[0] || 'transparent'
|
|
1476
|
+
});
|
|
1477
|
+
var gradient = new LinearGradient(0, 0, 0, 0, colorStopsInRange, true);
|
|
1478
|
+
gradient[coordDim] = minCoord;
|
|
1479
|
+
gradient[coordDim + '2'] = maxCoord;
|
|
1480
|
+
return gradient;
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
function getIsIgnoreFunc(seriesModel, data, coordSys) {
|
|
1484
|
+
var showAllSymbol = seriesModel.get('showAllSymbol');
|
|
1485
|
+
var isAuto = showAllSymbol === 'auto';
|
|
1486
|
+
|
|
1487
|
+
if (showAllSymbol && !isAuto) {
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
var categoryAxis = coordSys.getAxesByScale('ordinal')[0];
|
|
1492
|
+
|
|
1493
|
+
if (!categoryAxis) {
|
|
1494
|
+
return;
|
|
1495
|
+
} // Note that category label interval strategy might bring some weird effect
|
|
1496
|
+
// in some scenario: users may wonder why some of the symbols are not
|
|
1497
|
+
// displayed. So we show all symbols as possible as we can.
|
|
1498
|
+
|
|
1499
|
+
|
|
1500
|
+
if (isAuto // Simplify the logic, do not determine label overlap here.
|
|
1501
|
+
&& canShowAllSymbolForCategory(categoryAxis, data)) {
|
|
1502
|
+
return;
|
|
1503
|
+
} // Otherwise follow the label interval strategy on category axis.
|
|
1504
|
+
|
|
1505
|
+
|
|
1506
|
+
var categoryDataDim = data.mapDimension(categoryAxis.dim);
|
|
1507
|
+
var labelMap = {};
|
|
1508
|
+
each(categoryAxis.getViewLabels(), function (labelItem) {
|
|
1509
|
+
var ordinalNumber = categoryAxis.scale.getRawOrdinalNumber(labelItem.tickValue);
|
|
1510
|
+
labelMap[ordinalNumber] = 1;
|
|
1511
|
+
});
|
|
1512
|
+
return function (dataIndex) {
|
|
1513
|
+
return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex));
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
function canShowAllSymbolForCategory(categoryAxis, data) {
|
|
1518
|
+
// In most cases, line is monotonous on category axis, and the label size
|
|
1519
|
+
// is close with each other. So we check the symbol size and some of the
|
|
1520
|
+
// label size alone with the category axis to estimate whether all symbol
|
|
1521
|
+
// can be shown without overlap.
|
|
1522
|
+
var axisExtent = categoryAxis.getExtent();
|
|
1523
|
+
var availSize = Math.abs(axisExtent[1] - axisExtent[0]) / categoryAxis.scale.count();
|
|
1524
|
+
isNaN(availSize) && (availSize = 0); // 0/0 is NaN.
|
|
1525
|
+
// Sampling some points, max 5.
|
|
1526
|
+
|
|
1527
|
+
var dataLen = data.count();
|
|
1528
|
+
var step = Math.max(1, Math.round(dataLen / 5));
|
|
1529
|
+
|
|
1530
|
+
for (var dataIndex = 0; dataIndex < dataLen; dataIndex += step) {
|
|
1531
|
+
if (Symbol.getSymbolSize(data, dataIndex // Only for cartesian, where `isHorizontal` exists.
|
|
1532
|
+
)[categoryAxis.isHorizontal() ? 1 : 0] // Empirical number
|
|
1533
|
+
* 1.5 > availSize) {
|
|
1534
|
+
return false;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
return true;
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
function isPointNull(x, y) {
|
|
1542
|
+
return isNaN(x) || isNaN(y);
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
function getLastIndexNotNull(points) {
|
|
1546
|
+
var len = points.length / 2;
|
|
1547
|
+
|
|
1548
|
+
for (; len > 0; len--) {
|
|
1549
|
+
if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) {
|
|
1550
|
+
break;
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
return len - 1;
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
function getPointAtIndex(points, idx) {
|
|
1558
|
+
return [points[idx * 2], points[idx * 2 + 1]];
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
function getIndexRange(points, xOrY, dim) {
|
|
1562
|
+
var len = points.length / 2;
|
|
1563
|
+
var dimIdx = dim === 'x' ? 0 : 1;
|
|
1564
|
+
var a;
|
|
1565
|
+
var b;
|
|
1566
|
+
var prevIndex = 0;
|
|
1567
|
+
var nextIndex = -1;
|
|
1568
|
+
|
|
1569
|
+
for (var i = 0; i < len; i++) {
|
|
1570
|
+
b = points[i * 2 + dimIdx];
|
|
1571
|
+
|
|
1572
|
+
if (isNaN(b) || isNaN(points[i * 2 + 1 - dimIdx])) {
|
|
1573
|
+
continue;
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
if (i === 0) {
|
|
1577
|
+
a = b;
|
|
1578
|
+
continue;
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
if (a <= xOrY && b >= xOrY || a >= xOrY && b <= xOrY) {
|
|
1582
|
+
nextIndex = i;
|
|
1583
|
+
break;
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1586
|
+
prevIndex = i;
|
|
1587
|
+
a = b;
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
return {
|
|
1591
|
+
range: [prevIndex, nextIndex],
|
|
1592
|
+
t: (xOrY - a) / (b - a)
|
|
1593
|
+
};
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
function anyStateShowEndLabel(seriesModel) {
|
|
1597
|
+
if (seriesModel.get(['endLabel', 'show'])) {
|
|
1598
|
+
return true;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
for (var i = 0; i < SPECIAL_STATES.length; i++) {
|
|
1602
|
+
if (seriesModel.get([SPECIAL_STATES[i], 'endLabel', 'show'])) {
|
|
1603
|
+
return true;
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
return false;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
function createLineClipPath(lineView, coordSys, hasAnimation, seriesModel) {
|
|
1611
|
+
if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
|
|
1612
|
+
var endLabelModel_1 = seriesModel.getModel('endLabel');
|
|
1613
|
+
var valueAnimation_1 = endLabelModel_1.get('valueAnimation');
|
|
1614
|
+
var data_1 = seriesModel.getData();
|
|
1615
|
+
var labelAnimationRecord_1 = {
|
|
1616
|
+
lastFrameIndex: 0
|
|
1617
|
+
};
|
|
1618
|
+
var during = anyStateShowEndLabel(seriesModel) ? function (percent, clipRect) {
|
|
1619
|
+
lineView._endLabelOnDuring(percent, clipRect, data_1, labelAnimationRecord_1, valueAnimation_1, endLabelModel_1, coordSys);
|
|
1620
|
+
} : null;
|
|
1621
|
+
var isHorizontal = coordSys.getBaseAxis().isHorizontal();
|
|
1622
|
+
var clipPath = createGridClipPath(coordSys, hasAnimation, seriesModel, function () {
|
|
1623
|
+
var endLabel = lineView._endLabel;
|
|
1624
|
+
|
|
1625
|
+
if (endLabel && hasAnimation) {
|
|
1626
|
+
if (labelAnimationRecord_1.originalX != null) {
|
|
1627
|
+
endLabel.attr({
|
|
1628
|
+
x: labelAnimationRecord_1.originalX,
|
|
1629
|
+
y: labelAnimationRecord_1.originalY
|
|
1630
|
+
});
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
}, during); // Expand clip shape to avoid clipping when line value exceeds axis
|
|
1634
|
+
|
|
1635
|
+
if (!seriesModel.get('clip', true)) {
|
|
1636
|
+
var rectShape = clipPath.shape;
|
|
1637
|
+
var expandSize = Math.max(rectShape.width, rectShape.height);
|
|
1638
|
+
|
|
1639
|
+
if (isHorizontal) {
|
|
1640
|
+
rectShape.y -= expandSize;
|
|
1641
|
+
rectShape.height += expandSize * 2;
|
|
1642
|
+
} else {
|
|
1643
|
+
rectShape.x -= expandSize;
|
|
1644
|
+
rectShape.width += expandSize * 2;
|
|
1645
|
+
}
|
|
1646
|
+
} // Set to the final frame. To make sure label layout is right.
|
|
1647
|
+
|
|
1648
|
+
|
|
1649
|
+
if (during) {
|
|
1650
|
+
during(1, clipPath);
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
return clipPath;
|
|
1654
|
+
} else {
|
|
1655
|
+
|
|
1656
|
+
return createPolarClipPath(coordSys, hasAnimation, seriesModel);
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
function getEndLabelStateSpecified(endLabelModel, coordSys) {
|
|
1661
|
+
var baseAxis = coordSys.getBaseAxis();
|
|
1662
|
+
var isHorizontal = baseAxis.isHorizontal();
|
|
1663
|
+
var isBaseInversed = baseAxis.inverse;
|
|
1664
|
+
var align = isHorizontal ? isBaseInversed ? 'right' : 'left' : 'center';
|
|
1665
|
+
var verticalAlign = isHorizontal ? 'middle' : isBaseInversed ? 'top' : 'bottom';
|
|
1666
|
+
return {
|
|
1667
|
+
normal: {
|
|
1668
|
+
align: endLabelModel.get('align') || align,
|
|
1669
|
+
verticalAlign: endLabelModel.get('verticalAlign') || verticalAlign
|
|
1670
|
+
}
|
|
1671
|
+
};
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
var LineView =
|
|
1675
|
+
/** @class */
|
|
1676
|
+
function (_super) {
|
|
1677
|
+
__extends(LineView, _super);
|
|
1678
|
+
|
|
1679
|
+
function LineView() {
|
|
1680
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
LineView.prototype.init = function () {
|
|
1684
|
+
var lineGroup = new Group();
|
|
1685
|
+
var symbolDraw = new SymbolDraw();
|
|
1686
|
+
this.group.add(symbolDraw.group);
|
|
1687
|
+
this._symbolDraw = symbolDraw;
|
|
1688
|
+
this._lineGroup = lineGroup;
|
|
1689
|
+
};
|
|
1690
|
+
|
|
1691
|
+
LineView.prototype.render = function (seriesModel, ecModel, api) {
|
|
1692
|
+
var _this = this;
|
|
1693
|
+
|
|
1694
|
+
var coordSys = seriesModel.coordinateSystem;
|
|
1695
|
+
var group = this.group;
|
|
1696
|
+
var data = seriesModel.getData();
|
|
1697
|
+
var lineStyleModel = seriesModel.getModel('lineStyle');
|
|
1698
|
+
var areaStyleModel = seriesModel.getModel('areaStyle');
|
|
1699
|
+
var points = data.getLayout('points') || [];
|
|
1700
|
+
var isCoordSysPolar = coordSys.type === 'polar';
|
|
1701
|
+
var prevCoordSys = this._coordSys;
|
|
1702
|
+
var symbolDraw = this._symbolDraw;
|
|
1703
|
+
var polyline = this._polyline;
|
|
1704
|
+
var polygon = this._polygon;
|
|
1705
|
+
var lineGroup = this._lineGroup;
|
|
1706
|
+
var hasAnimation = seriesModel.get('animation');
|
|
1707
|
+
var isAreaChart = !areaStyleModel.isEmpty();
|
|
1708
|
+
var valueOrigin = areaStyleModel.get('origin');
|
|
1709
|
+
var dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin);
|
|
1710
|
+
var stackedOnPoints = isAreaChart && getStackedOnPoints(coordSys, data, dataCoordInfo);
|
|
1711
|
+
var showSymbol = seriesModel.get('showSymbol');
|
|
1712
|
+
var connectNulls = seriesModel.get('connectNulls');
|
|
1713
|
+
var isIgnoreFunc = showSymbol && !isCoordSysPolar && getIsIgnoreFunc(seriesModel, data, coordSys); // Remove temporary symbols
|
|
1714
|
+
|
|
1715
|
+
var oldData = this._data;
|
|
1716
|
+
oldData && oldData.eachItemGraphicEl(function (el, idx) {
|
|
1717
|
+
if (el.__temp) {
|
|
1718
|
+
group.remove(el);
|
|
1719
|
+
oldData.setItemGraphicEl(idx, null);
|
|
1720
|
+
}
|
|
1721
|
+
}); // Remove previous created symbols if showSymbol changed to false
|
|
1722
|
+
|
|
1723
|
+
if (!showSymbol) {
|
|
1724
|
+
symbolDraw.remove();
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
group.add(lineGroup); // FIXME step not support polar
|
|
1728
|
+
|
|
1729
|
+
var step = !isCoordSysPolar ? seriesModel.get('step') : false;
|
|
1730
|
+
var clipShapeForSymbol;
|
|
1731
|
+
|
|
1732
|
+
if (coordSys && coordSys.getArea && seriesModel.get('clip', true)) {
|
|
1733
|
+
clipShapeForSymbol = coordSys.getArea(); // Avoid float number rounding error for symbol on the edge of axis extent.
|
|
1734
|
+
// See #7913 and `test/dataZoom-clip.html`.
|
|
1735
|
+
|
|
1736
|
+
if (clipShapeForSymbol.width != null) {
|
|
1737
|
+
clipShapeForSymbol.x -= 0.1;
|
|
1738
|
+
clipShapeForSymbol.y -= 0.1;
|
|
1739
|
+
clipShapeForSymbol.width += 0.2;
|
|
1740
|
+
clipShapeForSymbol.height += 0.2;
|
|
1741
|
+
} else if (clipShapeForSymbol.r0) {
|
|
1742
|
+
clipShapeForSymbol.r0 -= 0.5;
|
|
1743
|
+
clipShapeForSymbol.r += 0.5;
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
this._clipShapeForSymbol = clipShapeForSymbol;
|
|
1748
|
+
var visualColor = getVisualGradient(data, coordSys, api) || data.getVisual('style')[data.getVisual('drawType')]; // Initialization animation or coordinate system changed
|
|
1749
|
+
|
|
1750
|
+
if (!(polyline && prevCoordSys.type === coordSys.type && step === this._step)) {
|
|
1751
|
+
showSymbol && symbolDraw.updateData(data, {
|
|
1752
|
+
isIgnore: isIgnoreFunc,
|
|
1753
|
+
clipShape: clipShapeForSymbol,
|
|
1754
|
+
disableAnimation: true,
|
|
1755
|
+
getSymbolPoint: function (idx) {
|
|
1756
|
+
return [points[idx * 2], points[idx * 2 + 1]];
|
|
1757
|
+
}
|
|
1758
|
+
});
|
|
1759
|
+
hasAnimation && this._initSymbolLabelAnimation(data, coordSys, clipShapeForSymbol);
|
|
1760
|
+
|
|
1761
|
+
if (step) {
|
|
1762
|
+
// TODO If stacked series is not step
|
|
1763
|
+
points = turnPointsIntoStep(points, coordSys, step, connectNulls);
|
|
1764
|
+
|
|
1765
|
+
if (stackedOnPoints) {
|
|
1766
|
+
stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
polyline = this._newPolyline(points);
|
|
1771
|
+
|
|
1772
|
+
if (isAreaChart) {
|
|
1773
|
+
polygon = this._newPolygon(points, stackedOnPoints);
|
|
1774
|
+
} // If areaStyle is removed
|
|
1775
|
+
else if (polygon) {
|
|
1776
|
+
lineGroup.remove(polygon);
|
|
1777
|
+
polygon = this._polygon = null;
|
|
1778
|
+
} // NOTE: Must update _endLabel before setClipPath.
|
|
1779
|
+
|
|
1780
|
+
|
|
1781
|
+
if (!isCoordSysPolar) {
|
|
1782
|
+
this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel));
|
|
1786
|
+
} else {
|
|
1787
|
+
if (isAreaChart && !polygon) {
|
|
1788
|
+
// If areaStyle is added
|
|
1789
|
+
polygon = this._newPolygon(points, stackedOnPoints);
|
|
1790
|
+
} else if (polygon && !isAreaChart) {
|
|
1791
|
+
// If areaStyle is removed
|
|
1792
|
+
lineGroup.remove(polygon);
|
|
1793
|
+
polygon = this._polygon = null;
|
|
1794
|
+
} // NOTE: Must update _endLabel before setClipPath.
|
|
1795
|
+
|
|
1796
|
+
|
|
1797
|
+
if (!isCoordSysPolar) {
|
|
1798
|
+
this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
|
|
1799
|
+
} // Update clipPath
|
|
1800
|
+
|
|
1801
|
+
|
|
1802
|
+
var oldClipPath = lineGroup.getClipPath();
|
|
1803
|
+
|
|
1804
|
+
if (oldClipPath) {
|
|
1805
|
+
var newClipPath = createLineClipPath(this, coordSys, false, seriesModel);
|
|
1806
|
+
initProps(oldClipPath, {
|
|
1807
|
+
shape: newClipPath.shape
|
|
1808
|
+
}, seriesModel);
|
|
1809
|
+
} else {
|
|
1810
|
+
lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel));
|
|
1811
|
+
} // Always update, or it is wrong in the case turning on legend
|
|
1812
|
+
// because points are not changed.
|
|
1813
|
+
|
|
1814
|
+
|
|
1815
|
+
showSymbol && symbolDraw.updateData(data, {
|
|
1816
|
+
isIgnore: isIgnoreFunc,
|
|
1817
|
+
clipShape: clipShapeForSymbol,
|
|
1818
|
+
disableAnimation: true,
|
|
1819
|
+
getSymbolPoint: function (idx) {
|
|
1820
|
+
return [points[idx * 2], points[idx * 2 + 1]];
|
|
1821
|
+
}
|
|
1822
|
+
}); // In the case data zoom triggered refreshing frequently
|
|
1823
|
+
// Data may not change if line has a category axis. So it should animate nothing.
|
|
1824
|
+
|
|
1825
|
+
if (!isPointsSame(this._stackedOnPoints, stackedOnPoints) || !isPointsSame(this._points, points)) {
|
|
1826
|
+
if (hasAnimation) {
|
|
1827
|
+
this._doUpdateAnimation(data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls);
|
|
1828
|
+
} else {
|
|
1829
|
+
// Not do it in update with animation
|
|
1830
|
+
if (step) {
|
|
1831
|
+
// TODO If stacked series is not step
|
|
1832
|
+
points = turnPointsIntoStep(points, coordSys, step, connectNulls);
|
|
1833
|
+
|
|
1834
|
+
if (stackedOnPoints) {
|
|
1835
|
+
stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
polyline.setShape({
|
|
1840
|
+
points: points
|
|
1841
|
+
});
|
|
1842
|
+
polygon && polygon.setShape({
|
|
1843
|
+
points: points,
|
|
1844
|
+
stackedOnPoints: stackedOnPoints
|
|
1845
|
+
});
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
var emphasisModel = seriesModel.getModel('emphasis');
|
|
1851
|
+
var focus = emphasisModel.get('focus');
|
|
1852
|
+
var blurScope = emphasisModel.get('blurScope');
|
|
1853
|
+
var emphasisDisabled = emphasisModel.get('disabled');
|
|
1854
|
+
polyline.useStyle(defaults( // Use color in lineStyle first
|
|
1855
|
+
lineStyleModel.getLineStyle(), {
|
|
1856
|
+
fill: 'none',
|
|
1857
|
+
stroke: visualColor,
|
|
1858
|
+
lineJoin: 'bevel'
|
|
1859
|
+
}));
|
|
1860
|
+
setStatesStylesFromModel(polyline, seriesModel, 'lineStyle');
|
|
1861
|
+
|
|
1862
|
+
if (polyline.style.lineWidth > 0 && seriesModel.get(['emphasis', 'lineStyle', 'width']) === 'bolder') {
|
|
1863
|
+
var emphasisLineStyle = polyline.getState('emphasis').style;
|
|
1864
|
+
emphasisLineStyle.lineWidth = +polyline.style.lineWidth + 1;
|
|
1865
|
+
} // Needs seriesIndex for focus
|
|
1866
|
+
|
|
1867
|
+
|
|
1868
|
+
getECData(polyline).seriesIndex = seriesModel.seriesIndex;
|
|
1869
|
+
toggleHoverEmphasis(polyline, focus, blurScope, emphasisDisabled);
|
|
1870
|
+
var smooth = getSmooth(seriesModel.get('smooth'));
|
|
1871
|
+
var smoothMonotone = seriesModel.get('smoothMonotone');
|
|
1872
|
+
polyline.setShape({
|
|
1873
|
+
smooth: smooth,
|
|
1874
|
+
smoothMonotone: smoothMonotone,
|
|
1875
|
+
connectNulls: connectNulls
|
|
1876
|
+
});
|
|
1877
|
+
|
|
1878
|
+
if (polygon) {
|
|
1879
|
+
var stackedOnSeries = data.getCalculationInfo('stackedOnSeries');
|
|
1880
|
+
var stackedOnSmooth = 0;
|
|
1881
|
+
polygon.useStyle(defaults(areaStyleModel.getAreaStyle(), {
|
|
1882
|
+
fill: visualColor,
|
|
1883
|
+
opacity: 0.7,
|
|
1884
|
+
lineJoin: 'bevel',
|
|
1885
|
+
decal: data.getVisual('style').decal
|
|
1886
|
+
}));
|
|
1887
|
+
|
|
1888
|
+
if (stackedOnSeries) {
|
|
1889
|
+
stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
|
|
1890
|
+
}
|
|
1891
|
+
|
|
1892
|
+
polygon.setShape({
|
|
1893
|
+
smooth: smooth,
|
|
1894
|
+
stackedOnSmooth: stackedOnSmooth,
|
|
1895
|
+
smoothMonotone: smoothMonotone,
|
|
1896
|
+
connectNulls: connectNulls
|
|
1897
|
+
});
|
|
1898
|
+
setStatesStylesFromModel(polygon, seriesModel, 'areaStyle'); // Needs seriesIndex for focus
|
|
1899
|
+
|
|
1900
|
+
getECData(polygon).seriesIndex = seriesModel.seriesIndex;
|
|
1901
|
+
toggleHoverEmphasis(polygon, focus, blurScope, emphasisDisabled);
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
var changePolyState = function (toState) {
|
|
1905
|
+
_this._changePolyState(toState);
|
|
1906
|
+
};
|
|
1907
|
+
|
|
1908
|
+
data.eachItemGraphicEl(function (el) {
|
|
1909
|
+
// Switch polyline / polygon state if element changed its state.
|
|
1910
|
+
el && (el.onHoverStateChange = changePolyState);
|
|
1911
|
+
});
|
|
1912
|
+
this._polyline.onHoverStateChange = changePolyState;
|
|
1913
|
+
this._data = data; // Save the coordinate system for transition animation when data changed
|
|
1914
|
+
|
|
1915
|
+
this._coordSys = coordSys;
|
|
1916
|
+
this._stackedOnPoints = stackedOnPoints;
|
|
1917
|
+
this._points = points;
|
|
1918
|
+
this._step = step;
|
|
1919
|
+
this._valueOrigin = valueOrigin;
|
|
1920
|
+
|
|
1921
|
+
if (seriesModel.get('triggerLineEvent')) {
|
|
1922
|
+
this.packEventData(seriesModel, polyline);
|
|
1923
|
+
polygon && this.packEventData(seriesModel, polygon);
|
|
1924
|
+
}
|
|
1925
|
+
};
|
|
1926
|
+
|
|
1927
|
+
LineView.prototype.packEventData = function (seriesModel, el) {
|
|
1928
|
+
getECData(el).eventData = {
|
|
1929
|
+
componentType: 'series',
|
|
1930
|
+
componentSubType: 'line',
|
|
1931
|
+
componentIndex: seriesModel.componentIndex,
|
|
1932
|
+
seriesIndex: seriesModel.seriesIndex,
|
|
1933
|
+
seriesName: seriesModel.name,
|
|
1934
|
+
seriesType: 'line'
|
|
1935
|
+
};
|
|
1936
|
+
};
|
|
1937
|
+
|
|
1938
|
+
LineView.prototype.highlight = function (seriesModel, ecModel, api, payload) {
|
|
1939
|
+
var data = seriesModel.getData();
|
|
1940
|
+
var dataIndex = queryDataIndex(data, payload);
|
|
1941
|
+
|
|
1942
|
+
this._changePolyState('emphasis');
|
|
1943
|
+
|
|
1944
|
+
if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) {
|
|
1945
|
+
var points = data.getLayout('points');
|
|
1946
|
+
var symbol = data.getItemGraphicEl(dataIndex);
|
|
1947
|
+
|
|
1948
|
+
if (!symbol) {
|
|
1949
|
+
// Create a temporary symbol if it is not exists
|
|
1950
|
+
var x = points[dataIndex * 2];
|
|
1951
|
+
var y = points[dataIndex * 2 + 1];
|
|
1952
|
+
|
|
1953
|
+
if (isNaN(x) || isNaN(y)) {
|
|
1954
|
+
// Null data
|
|
1955
|
+
return;
|
|
1956
|
+
} // fix #11360: shouldn't draw symbol outside clipShapeForSymbol
|
|
1957
|
+
|
|
1958
|
+
|
|
1959
|
+
if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(x, y)) {
|
|
1960
|
+
return;
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
var zlevel = seriesModel.get('zlevel') || 0;
|
|
1964
|
+
var z = seriesModel.get('z') || 0;
|
|
1965
|
+
symbol = new Symbol(data, dataIndex);
|
|
1966
|
+
symbol.x = x;
|
|
1967
|
+
symbol.y = y;
|
|
1968
|
+
symbol.setZ(zlevel, z); // ensure label text of the temporary symbol is in front of line and area polygon
|
|
1969
|
+
|
|
1970
|
+
var symbolLabel = symbol.getSymbolPath().getTextContent();
|
|
1971
|
+
|
|
1972
|
+
if (symbolLabel) {
|
|
1973
|
+
symbolLabel.zlevel = zlevel;
|
|
1974
|
+
symbolLabel.z = z;
|
|
1975
|
+
symbolLabel.z2 = this._polyline.z2 + 1;
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1978
|
+
symbol.__temp = true;
|
|
1979
|
+
data.setItemGraphicEl(dataIndex, symbol); // Stop scale animation
|
|
1980
|
+
|
|
1981
|
+
symbol.stopSymbolAnimation(true);
|
|
1982
|
+
this.group.add(symbol);
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
symbol.highlight();
|
|
1986
|
+
} else {
|
|
1987
|
+
// Highlight whole series
|
|
1988
|
+
ChartView.prototype.highlight.call(this, seriesModel, ecModel, api, payload);
|
|
1989
|
+
}
|
|
1990
|
+
};
|
|
1991
|
+
|
|
1992
|
+
LineView.prototype.downplay = function (seriesModel, ecModel, api, payload) {
|
|
1993
|
+
var data = seriesModel.getData();
|
|
1994
|
+
var dataIndex = queryDataIndex(data, payload);
|
|
1995
|
+
|
|
1996
|
+
this._changePolyState('normal');
|
|
1997
|
+
|
|
1998
|
+
if (dataIndex != null && dataIndex >= 0) {
|
|
1999
|
+
var symbol = data.getItemGraphicEl(dataIndex);
|
|
2000
|
+
|
|
2001
|
+
if (symbol) {
|
|
2002
|
+
if (symbol.__temp) {
|
|
2003
|
+
data.setItemGraphicEl(dataIndex, null);
|
|
2004
|
+
this.group.remove(symbol);
|
|
2005
|
+
} else {
|
|
2006
|
+
symbol.downplay();
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
} else {
|
|
2010
|
+
// FIXME
|
|
2011
|
+
// can not downplay completely.
|
|
2012
|
+
// Downplay whole series
|
|
2013
|
+
ChartView.prototype.downplay.call(this, seriesModel, ecModel, api, payload);
|
|
2014
|
+
}
|
|
2015
|
+
};
|
|
2016
|
+
|
|
2017
|
+
LineView.prototype._changePolyState = function (toState) {
|
|
2018
|
+
var polygon = this._polygon;
|
|
2019
|
+
setStatesFlag(this._polyline, toState);
|
|
2020
|
+
polygon && setStatesFlag(polygon, toState);
|
|
2021
|
+
};
|
|
2022
|
+
|
|
2023
|
+
LineView.prototype._newPolyline = function (points) {
|
|
2024
|
+
var polyline = this._polyline; // Remove previous created polyline
|
|
2025
|
+
|
|
2026
|
+
if (polyline) {
|
|
2027
|
+
this._lineGroup.remove(polyline);
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
polyline = new ECPolyline({
|
|
2031
|
+
shape: {
|
|
2032
|
+
points: points
|
|
2033
|
+
},
|
|
2034
|
+
segmentIgnoreThreshold: 2,
|
|
2035
|
+
z2: 10
|
|
2036
|
+
});
|
|
2037
|
+
|
|
2038
|
+
this._lineGroup.add(polyline);
|
|
2039
|
+
|
|
2040
|
+
this._polyline = polyline;
|
|
2041
|
+
return polyline;
|
|
2042
|
+
};
|
|
2043
|
+
|
|
2044
|
+
LineView.prototype._newPolygon = function (points, stackedOnPoints) {
|
|
2045
|
+
var polygon = this._polygon; // Remove previous created polygon
|
|
2046
|
+
|
|
2047
|
+
if (polygon) {
|
|
2048
|
+
this._lineGroup.remove(polygon);
|
|
2049
|
+
}
|
|
2050
|
+
|
|
2051
|
+
polygon = new ECPolygon({
|
|
2052
|
+
shape: {
|
|
2053
|
+
points: points,
|
|
2054
|
+
stackedOnPoints: stackedOnPoints
|
|
2055
|
+
},
|
|
2056
|
+
segmentIgnoreThreshold: 2
|
|
2057
|
+
});
|
|
2058
|
+
|
|
2059
|
+
this._lineGroup.add(polygon);
|
|
2060
|
+
|
|
2061
|
+
this._polygon = polygon;
|
|
2062
|
+
return polygon;
|
|
2063
|
+
};
|
|
2064
|
+
|
|
2065
|
+
LineView.prototype._initSymbolLabelAnimation = function (data, coordSys, clipShape) {
|
|
2066
|
+
var isHorizontalOrRadial;
|
|
2067
|
+
var isCoordSysPolar;
|
|
2068
|
+
var baseAxis = coordSys.getBaseAxis();
|
|
2069
|
+
var isAxisInverse = baseAxis.inverse;
|
|
2070
|
+
|
|
2071
|
+
if (coordSys.type === 'cartesian2d') {
|
|
2072
|
+
isHorizontalOrRadial = baseAxis.isHorizontal();
|
|
2073
|
+
isCoordSysPolar = false;
|
|
2074
|
+
} else if (coordSys.type === 'polar') {
|
|
2075
|
+
isHorizontalOrRadial = baseAxis.dim === 'angle';
|
|
2076
|
+
isCoordSysPolar = true;
|
|
2077
|
+
}
|
|
2078
|
+
|
|
2079
|
+
var seriesModel = data.hostModel;
|
|
2080
|
+
var seriesDuration = seriesModel.get('animationDuration');
|
|
2081
|
+
|
|
2082
|
+
if (isFunction(seriesDuration)) {
|
|
2083
|
+
seriesDuration = seriesDuration(null);
|
|
2084
|
+
}
|
|
2085
|
+
|
|
2086
|
+
var seriesDalay = seriesModel.get('animationDelay') || 0;
|
|
2087
|
+
var seriesDalayValue = isFunction(seriesDalay) ? seriesDalay(null) : seriesDalay;
|
|
2088
|
+
data.eachItemGraphicEl(function (symbol, idx) {
|
|
2089
|
+
var el = symbol;
|
|
2090
|
+
|
|
2091
|
+
if (el) {
|
|
2092
|
+
var point = [symbol.x, symbol.y];
|
|
2093
|
+
var start = void 0;
|
|
2094
|
+
var end = void 0;
|
|
2095
|
+
var current = void 0;
|
|
2096
|
+
|
|
2097
|
+
if (clipShape) {
|
|
2098
|
+
if (isCoordSysPolar) {
|
|
2099
|
+
var polarClip = clipShape;
|
|
2100
|
+
var coord = coordSys.pointToCoord(point);
|
|
2101
|
+
|
|
2102
|
+
if (isHorizontalOrRadial) {
|
|
2103
|
+
start = polarClip.startAngle;
|
|
2104
|
+
end = polarClip.endAngle;
|
|
2105
|
+
current = -coord[1] / 180 * Math.PI;
|
|
2106
|
+
} else {
|
|
2107
|
+
start = polarClip.r0;
|
|
2108
|
+
end = polarClip.r;
|
|
2109
|
+
current = coord[0];
|
|
2110
|
+
}
|
|
2111
|
+
} else {
|
|
2112
|
+
var gridClip = clipShape;
|
|
2113
|
+
|
|
2114
|
+
if (isHorizontalOrRadial) {
|
|
2115
|
+
start = gridClip.x;
|
|
2116
|
+
end = gridClip.x + gridClip.width;
|
|
2117
|
+
current = symbol.x;
|
|
2118
|
+
} else {
|
|
2119
|
+
start = gridClip.y + gridClip.height;
|
|
2120
|
+
end = gridClip.y;
|
|
2121
|
+
current = symbol.y;
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
var ratio = end === start ? 0 : (current - start) / (end - start);
|
|
2127
|
+
|
|
2128
|
+
if (isAxisInverse) {
|
|
2129
|
+
ratio = 1 - ratio;
|
|
2130
|
+
}
|
|
2131
|
+
|
|
2132
|
+
var delay = isFunction(seriesDalay) ? seriesDalay(idx) : seriesDuration * ratio + seriesDalayValue;
|
|
2133
|
+
var symbolPath = el.getSymbolPath();
|
|
2134
|
+
var text = symbolPath.getTextContent();
|
|
2135
|
+
el.attr({
|
|
2136
|
+
scaleX: 0,
|
|
2137
|
+
scaleY: 0
|
|
2138
|
+
});
|
|
2139
|
+
el.animateTo({
|
|
2140
|
+
scaleX: 1,
|
|
2141
|
+
scaleY: 1
|
|
2142
|
+
}, {
|
|
2143
|
+
duration: 200,
|
|
2144
|
+
setToFinal: true,
|
|
2145
|
+
delay: delay
|
|
2146
|
+
});
|
|
2147
|
+
|
|
2148
|
+
if (text) {
|
|
2149
|
+
text.animateFrom({
|
|
2150
|
+
style: {
|
|
2151
|
+
opacity: 0
|
|
2152
|
+
}
|
|
2153
|
+
}, {
|
|
2154
|
+
duration: 300,
|
|
2155
|
+
delay: delay
|
|
2156
|
+
});
|
|
2157
|
+
}
|
|
2158
|
+
|
|
2159
|
+
symbolPath.disableLabelAnimation = true;
|
|
2160
|
+
}
|
|
2161
|
+
});
|
|
2162
|
+
};
|
|
2163
|
+
|
|
2164
|
+
LineView.prototype._initOrUpdateEndLabel = function (seriesModel, coordSys, inheritColor) {
|
|
2165
|
+
var endLabelModel = seriesModel.getModel('endLabel');
|
|
2166
|
+
|
|
2167
|
+
if (anyStateShowEndLabel(seriesModel)) {
|
|
2168
|
+
var data_2 = seriesModel.getData();
|
|
2169
|
+
var polyline = this._polyline; // series may be filtered.
|
|
2170
|
+
|
|
2171
|
+
var points = data_2.getLayout('points');
|
|
2172
|
+
|
|
2173
|
+
if (!points) {
|
|
2174
|
+
polyline.removeTextContent();
|
|
2175
|
+
this._endLabel = null;
|
|
2176
|
+
return;
|
|
2177
|
+
}
|
|
2178
|
+
|
|
2179
|
+
var endLabel = this._endLabel;
|
|
2180
|
+
|
|
2181
|
+
if (!endLabel) {
|
|
2182
|
+
endLabel = this._endLabel = new ZRText({
|
|
2183
|
+
z2: 200 // should be higher than item symbol
|
|
2184
|
+
|
|
2185
|
+
});
|
|
2186
|
+
endLabel.ignoreClip = true;
|
|
2187
|
+
polyline.setTextContent(this._endLabel);
|
|
2188
|
+
polyline.disableLabelAnimation = true;
|
|
2189
|
+
} // Find last non-NaN data to display data
|
|
2190
|
+
|
|
2191
|
+
|
|
2192
|
+
var dataIndex = getLastIndexNotNull(points);
|
|
2193
|
+
|
|
2194
|
+
if (dataIndex >= 0) {
|
|
2195
|
+
setLabelStyle(polyline, getLabelStatesModels(seriesModel, 'endLabel'), {
|
|
2196
|
+
inheritColor: inheritColor,
|
|
2197
|
+
labelFetcher: seriesModel,
|
|
2198
|
+
labelDataIndex: dataIndex,
|
|
2199
|
+
defaultText: function (dataIndex, opt, interpolatedValue) {
|
|
2200
|
+
return interpolatedValue != null ? getDefaultInterpolatedLabel(data_2, interpolatedValue) : getDefaultLabel(data_2, dataIndex);
|
|
2201
|
+
},
|
|
2202
|
+
enableTextSetter: true
|
|
2203
|
+
}, getEndLabelStateSpecified(endLabelModel, coordSys));
|
|
2204
|
+
polyline.textConfig.position = null;
|
|
2205
|
+
}
|
|
2206
|
+
} else if (this._endLabel) {
|
|
2207
|
+
this._polyline.removeTextContent();
|
|
2208
|
+
|
|
2209
|
+
this._endLabel = null;
|
|
2210
|
+
}
|
|
2211
|
+
};
|
|
2212
|
+
|
|
2213
|
+
LineView.prototype._endLabelOnDuring = function (percent, clipRect, data, animationRecord, valueAnimation, endLabelModel, coordSys) {
|
|
2214
|
+
var endLabel = this._endLabel;
|
|
2215
|
+
var polyline = this._polyline;
|
|
2216
|
+
|
|
2217
|
+
if (endLabel) {
|
|
2218
|
+
// NOTE: Don't remove percent < 1. percent === 1 means the first frame during render.
|
|
2219
|
+
// The label is not prepared at this time.
|
|
2220
|
+
if (percent < 1 && animationRecord.originalX == null) {
|
|
2221
|
+
animationRecord.originalX = endLabel.x;
|
|
2222
|
+
animationRecord.originalY = endLabel.y;
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
var points = data.getLayout('points');
|
|
2226
|
+
var seriesModel = data.hostModel;
|
|
2227
|
+
var connectNulls = seriesModel.get('connectNulls');
|
|
2228
|
+
var precision = endLabelModel.get('precision');
|
|
2229
|
+
var distance = endLabelModel.get('distance') || 0;
|
|
2230
|
+
var baseAxis = coordSys.getBaseAxis();
|
|
2231
|
+
var isHorizontal = baseAxis.isHorizontal();
|
|
2232
|
+
var isBaseInversed = baseAxis.inverse;
|
|
2233
|
+
var clipShape = clipRect.shape;
|
|
2234
|
+
var xOrY = isBaseInversed ? isHorizontal ? clipShape.x : clipShape.y + clipShape.height : isHorizontal ? clipShape.x + clipShape.width : clipShape.y;
|
|
2235
|
+
var distanceX = (isHorizontal ? distance : 0) * (isBaseInversed ? -1 : 1);
|
|
2236
|
+
var distanceY = (isHorizontal ? 0 : -distance) * (isBaseInversed ? -1 : 1);
|
|
2237
|
+
var dim = isHorizontal ? 'x' : 'y';
|
|
2238
|
+
var dataIndexRange = getIndexRange(points, xOrY, dim);
|
|
2239
|
+
var indices = dataIndexRange.range;
|
|
2240
|
+
var diff = indices[1] - indices[0];
|
|
2241
|
+
var value = void 0;
|
|
2242
|
+
|
|
2243
|
+
if (diff >= 1) {
|
|
2244
|
+
// diff > 1 && connectNulls, which is on the null data.
|
|
2245
|
+
if (diff > 1 && !connectNulls) {
|
|
2246
|
+
var pt = getPointAtIndex(points, indices[0]);
|
|
2247
|
+
endLabel.attr({
|
|
2248
|
+
x: pt[0] + distanceX,
|
|
2249
|
+
y: pt[1] + distanceY
|
|
2250
|
+
});
|
|
2251
|
+
valueAnimation && (value = seriesModel.getRawValue(indices[0]));
|
|
2252
|
+
} else {
|
|
2253
|
+
var pt = polyline.getPointOn(xOrY, dim);
|
|
2254
|
+
pt && endLabel.attr({
|
|
2255
|
+
x: pt[0] + distanceX,
|
|
2256
|
+
y: pt[1] + distanceY
|
|
2257
|
+
});
|
|
2258
|
+
var startValue = seriesModel.getRawValue(indices[0]);
|
|
2259
|
+
var endValue = seriesModel.getRawValue(indices[1]);
|
|
2260
|
+
valueAnimation && (value = interpolateRawValues(data, precision, startValue, endValue, dataIndexRange.t));
|
|
2261
|
+
}
|
|
2262
|
+
|
|
2263
|
+
animationRecord.lastFrameIndex = indices[0];
|
|
2264
|
+
} else {
|
|
2265
|
+
// If diff <= 0, which is the range is not found(Include NaN)
|
|
2266
|
+
// Choose the first point or last point.
|
|
2267
|
+
var idx = percent === 1 || animationRecord.lastFrameIndex > 0 ? indices[0] : 0;
|
|
2268
|
+
var pt = getPointAtIndex(points, idx);
|
|
2269
|
+
valueAnimation && (value = seriesModel.getRawValue(idx));
|
|
2270
|
+
endLabel.attr({
|
|
2271
|
+
x: pt[0] + distanceX,
|
|
2272
|
+
y: pt[1] + distanceY
|
|
2273
|
+
});
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2276
|
+
if (valueAnimation) {
|
|
2277
|
+
labelInner(endLabel).setLabelText(value);
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
};
|
|
2281
|
+
/**
|
|
2282
|
+
* @private
|
|
2283
|
+
*/
|
|
2284
|
+
// FIXME Two value axis
|
|
2285
|
+
|
|
2286
|
+
|
|
2287
|
+
LineView.prototype._doUpdateAnimation = function (data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls) {
|
|
2288
|
+
var polyline = this._polyline;
|
|
2289
|
+
var polygon = this._polygon;
|
|
2290
|
+
var seriesModel = data.hostModel;
|
|
2291
|
+
var diff = lineAnimationDiff(this._data, data, this._stackedOnPoints, stackedOnPoints, this._coordSys, coordSys, this._valueOrigin);
|
|
2292
|
+
var current = diff.current;
|
|
2293
|
+
var stackedOnCurrent = diff.stackedOnCurrent;
|
|
2294
|
+
var next = diff.next;
|
|
2295
|
+
var stackedOnNext = diff.stackedOnNext;
|
|
2296
|
+
|
|
2297
|
+
if (step) {
|
|
2298
|
+
// TODO If stacked series is not step
|
|
2299
|
+
current = turnPointsIntoStep(diff.current, coordSys, step, connectNulls);
|
|
2300
|
+
stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step, connectNulls);
|
|
2301
|
+
next = turnPointsIntoStep(diff.next, coordSys, step, connectNulls);
|
|
2302
|
+
stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step, connectNulls);
|
|
2303
|
+
} // Don't apply animation if diff is large.
|
|
2304
|
+
// For better result and avoid memory explosion problems like
|
|
2305
|
+
// https://github.com/apache/incubator-echarts/issues/12229
|
|
2306
|
+
|
|
2307
|
+
|
|
2308
|
+
if (getBoundingDiff(current, next) > 3000 || polygon && getBoundingDiff(stackedOnCurrent, stackedOnNext) > 3000) {
|
|
2309
|
+
polyline.stopAnimation();
|
|
2310
|
+
polyline.setShape({
|
|
2311
|
+
points: next
|
|
2312
|
+
});
|
|
2313
|
+
|
|
2314
|
+
if (polygon) {
|
|
2315
|
+
polygon.stopAnimation();
|
|
2316
|
+
polygon.setShape({
|
|
2317
|
+
points: next,
|
|
2318
|
+
stackedOnPoints: stackedOnNext
|
|
2319
|
+
});
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
return;
|
|
2323
|
+
}
|
|
2324
|
+
|
|
2325
|
+
polyline.shape.__points = diff.current;
|
|
2326
|
+
polyline.shape.points = current;
|
|
2327
|
+
var target = {
|
|
2328
|
+
shape: {
|
|
2329
|
+
points: next
|
|
2330
|
+
}
|
|
2331
|
+
}; // Also animate the original points.
|
|
2332
|
+
// If points reference is changed when turning into step line.
|
|
2333
|
+
|
|
2334
|
+
if (diff.current !== current) {
|
|
2335
|
+
target.shape.__points = diff.next;
|
|
2336
|
+
} // Stop previous animation.
|
|
2337
|
+
|
|
2338
|
+
|
|
2339
|
+
polyline.stopAnimation();
|
|
2340
|
+
updateProps(polyline, target, seriesModel);
|
|
2341
|
+
|
|
2342
|
+
if (polygon) {
|
|
2343
|
+
polygon.setShape({
|
|
2344
|
+
// Reuse the points with polyline.
|
|
2345
|
+
points: current,
|
|
2346
|
+
stackedOnPoints: stackedOnCurrent
|
|
2347
|
+
});
|
|
2348
|
+
polygon.stopAnimation();
|
|
2349
|
+
updateProps(polygon, {
|
|
2350
|
+
shape: {
|
|
2351
|
+
stackedOnPoints: stackedOnNext
|
|
2352
|
+
}
|
|
2353
|
+
}, seriesModel); // If use attr directly in updateProps.
|
|
2354
|
+
|
|
2355
|
+
if (polyline.shape.points !== polygon.shape.points) {
|
|
2356
|
+
polygon.shape.points = polyline.shape.points;
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2360
|
+
var updatedDataInfo = [];
|
|
2361
|
+
var diffStatus = diff.status;
|
|
2362
|
+
|
|
2363
|
+
for (var i = 0; i < diffStatus.length; i++) {
|
|
2364
|
+
var cmd = diffStatus[i].cmd;
|
|
2365
|
+
|
|
2366
|
+
if (cmd === '=') {
|
|
2367
|
+
var el = data.getItemGraphicEl(diffStatus[i].idx1);
|
|
2368
|
+
|
|
2369
|
+
if (el) {
|
|
2370
|
+
updatedDataInfo.push({
|
|
2371
|
+
el: el,
|
|
2372
|
+
ptIdx: i // Index of points
|
|
2373
|
+
|
|
2374
|
+
});
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2379
|
+
if (polyline.animators && polyline.animators.length) {
|
|
2380
|
+
polyline.animators[0].during(function () {
|
|
2381
|
+
polygon && polygon.dirtyShape();
|
|
2382
|
+
var points = polyline.shape.__points;
|
|
2383
|
+
|
|
2384
|
+
for (var i = 0; i < updatedDataInfo.length; i++) {
|
|
2385
|
+
var el = updatedDataInfo[i].el;
|
|
2386
|
+
var offset = updatedDataInfo[i].ptIdx * 2;
|
|
2387
|
+
el.x = points[offset];
|
|
2388
|
+
el.y = points[offset + 1];
|
|
2389
|
+
el.markRedraw();
|
|
2390
|
+
}
|
|
2391
|
+
});
|
|
2392
|
+
}
|
|
2393
|
+
};
|
|
2394
|
+
|
|
2395
|
+
LineView.prototype.remove = function (ecModel) {
|
|
2396
|
+
var group = this.group;
|
|
2397
|
+
var oldData = this._data;
|
|
2398
|
+
|
|
2399
|
+
this._lineGroup.removeAll();
|
|
2400
|
+
|
|
2401
|
+
this._symbolDraw.remove(true); // Remove temporary created elements when highlighting
|
|
2402
|
+
|
|
2403
|
+
|
|
2404
|
+
oldData && oldData.eachItemGraphicEl(function (el, idx) {
|
|
2405
|
+
if (el.__temp) {
|
|
2406
|
+
group.remove(el);
|
|
2407
|
+
oldData.setItemGraphicEl(idx, null);
|
|
2408
|
+
}
|
|
2409
|
+
});
|
|
2410
|
+
this._polyline = this._polygon = this._coordSys = this._points = this._stackedOnPoints = this._endLabel = this._data = null;
|
|
2411
|
+
};
|
|
2412
|
+
|
|
2413
|
+
LineView.type = 'line';
|
|
2414
|
+
return LineView;
|
|
2415
|
+
}(ChartView);
|
|
2416
|
+
|
|
2417
|
+
function pointsLayout(seriesType, forceStoreInTypedArray) {
|
|
2418
|
+
return {
|
|
2419
|
+
seriesType: seriesType,
|
|
2420
|
+
plan: createRenderPlanner(),
|
|
2421
|
+
reset: function (seriesModel) {
|
|
2422
|
+
var data = seriesModel.getData();
|
|
2423
|
+
var coordSys = seriesModel.coordinateSystem;
|
|
2424
|
+
var pipelineContext = seriesModel.pipelineContext;
|
|
2425
|
+
var useTypedArray = forceStoreInTypedArray || pipelineContext.large;
|
|
2426
|
+
|
|
2427
|
+
if (!coordSys) {
|
|
2428
|
+
return;
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2431
|
+
var dims = map(coordSys.dimensions, function (dim) {
|
|
2432
|
+
return data.mapDimension(dim);
|
|
2433
|
+
}).slice(0, 2);
|
|
2434
|
+
var dimLen = dims.length;
|
|
2435
|
+
var stackResultDim = data.getCalculationInfo('stackResultDimension');
|
|
2436
|
+
|
|
2437
|
+
if (isDimensionStacked(data, dims[0])) {
|
|
2438
|
+
dims[0] = stackResultDim;
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
if (isDimensionStacked(data, dims[1])) {
|
|
2442
|
+
dims[1] = stackResultDim;
|
|
2443
|
+
}
|
|
2444
|
+
|
|
2445
|
+
var store = data.getStore();
|
|
2446
|
+
var dimIdx0 = data.getDimensionIndex(dims[0]);
|
|
2447
|
+
var dimIdx1 = data.getDimensionIndex(dims[1]);
|
|
2448
|
+
return dimLen && {
|
|
2449
|
+
progress: function (params, data) {
|
|
2450
|
+
var segCount = params.end - params.start;
|
|
2451
|
+
var points = useTypedArray && createFloat32Array(segCount * dimLen);
|
|
2452
|
+
var tmpIn = [];
|
|
2453
|
+
var tmpOut = [];
|
|
2454
|
+
|
|
2455
|
+
for (var i = params.start, offset = 0; i < params.end; i++) {
|
|
2456
|
+
var point = void 0;
|
|
2457
|
+
|
|
2458
|
+
if (dimLen === 1) {
|
|
2459
|
+
var x = store.get(dimIdx0, i); // NOTE: Make sure the second parameter is null to use default strategy.
|
|
2460
|
+
|
|
2461
|
+
point = coordSys.dataToPoint(x, null, tmpOut);
|
|
2462
|
+
} else {
|
|
2463
|
+
tmpIn[0] = store.get(dimIdx0, i);
|
|
2464
|
+
tmpIn[1] = store.get(dimIdx1, i); // Let coordinate system to handle the NaN data.
|
|
2465
|
+
|
|
2466
|
+
point = coordSys.dataToPoint(tmpIn, null, tmpOut);
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2469
|
+
if (useTypedArray) {
|
|
2470
|
+
points[offset++] = point[0];
|
|
2471
|
+
points[offset++] = point[1];
|
|
2472
|
+
} else {
|
|
2473
|
+
data.setItemLayout(i, point.slice());
|
|
2474
|
+
}
|
|
2475
|
+
}
|
|
2476
|
+
|
|
2477
|
+
useTypedArray && data.setLayout('points', points);
|
|
2478
|
+
}
|
|
2479
|
+
};
|
|
2480
|
+
}
|
|
2481
|
+
};
|
|
2482
|
+
}
|
|
2483
|
+
|
|
2484
|
+
function install(registers) {
|
|
2485
|
+
registers.registerChartView(LineView);
|
|
2486
|
+
registers.registerSeriesModel(LineSeriesModel);
|
|
2487
|
+
registers.registerLayout(pointsLayout('line', true));
|
|
2488
|
+
registers.registerVisual({
|
|
2489
|
+
seriesType: 'line',
|
|
2490
|
+
reset: function (seriesModel) {
|
|
2491
|
+
var data = seriesModel.getData(); // Visual coding for legend
|
|
2492
|
+
|
|
2493
|
+
var lineStyle = seriesModel.getModel('lineStyle').getLineStyle();
|
|
2494
|
+
|
|
2495
|
+
if (lineStyle && !lineStyle.stroke) {
|
|
2496
|
+
// Fill in visual should be palette color if
|
|
2497
|
+
// has color callback
|
|
2498
|
+
lineStyle.stroke = data.getVisual('style').fill;
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2501
|
+
data.setVisual('legendLineStyle', lineStyle);
|
|
2502
|
+
}
|
|
2503
|
+
}); // Down sample after filter
|
|
2504
|
+
|
|
2505
|
+
registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, dataSample('line'));
|
|
2506
|
+
}
|
|
2507
|
+
|
|
2508
|
+
var CMD = PathProxy.CMD;
|
|
2509
|
+
function aroundEqual(a, b) {
|
|
2510
|
+
return Math.abs(a - b) < 1e-5;
|
|
2511
|
+
}
|
|
2512
|
+
function pathToBezierCurves(path) {
|
|
2513
|
+
var data = path.data;
|
|
2514
|
+
var len = path.len();
|
|
2515
|
+
var bezierArrayGroups = [];
|
|
2516
|
+
var currentSubpath;
|
|
2517
|
+
var xi = 0;
|
|
2518
|
+
var yi = 0;
|
|
2519
|
+
var x0 = 0;
|
|
2520
|
+
var y0 = 0;
|
|
2521
|
+
function createNewSubpath(x, y) {
|
|
2522
|
+
if (currentSubpath && currentSubpath.length > 2) {
|
|
2523
|
+
bezierArrayGroups.push(currentSubpath);
|
|
2524
|
+
}
|
|
2525
|
+
currentSubpath = [x, y];
|
|
2526
|
+
}
|
|
2527
|
+
function addLine(x0, y0, x1, y1) {
|
|
2528
|
+
if (!(aroundEqual(x0, x1) && aroundEqual(y0, y1))) {
|
|
2529
|
+
currentSubpath.push(x0, y0, x1, y1, x1, y1);
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
function addArc(startAngle, endAngle, cx, cy, rx, ry) {
|
|
2533
|
+
var delta = Math.abs(endAngle - startAngle);
|
|
2534
|
+
var len = Math.tan(delta / 4) * 4 / 3;
|
|
2535
|
+
var dir = endAngle < startAngle ? -1 : 1;
|
|
2536
|
+
var c1 = Math.cos(startAngle);
|
|
2537
|
+
var s1 = Math.sin(startAngle);
|
|
2538
|
+
var c2 = Math.cos(endAngle);
|
|
2539
|
+
var s2 = Math.sin(endAngle);
|
|
2540
|
+
var x1 = c1 * rx + cx;
|
|
2541
|
+
var y1 = s1 * ry + cy;
|
|
2542
|
+
var x4 = c2 * rx + cx;
|
|
2543
|
+
var y4 = s2 * ry + cy;
|
|
2544
|
+
var hx = rx * len * dir;
|
|
2545
|
+
var hy = ry * len * dir;
|
|
2546
|
+
currentSubpath.push(x1 - hx * s1, y1 + hy * c1, x4 + hx * s2, y4 - hy * c2, x4, y4);
|
|
2547
|
+
}
|
|
2548
|
+
var x1;
|
|
2549
|
+
var y1;
|
|
2550
|
+
var x2;
|
|
2551
|
+
var y2;
|
|
2552
|
+
for (var i = 0; i < len;) {
|
|
2553
|
+
var cmd = data[i++];
|
|
2554
|
+
var isFirst = i === 1;
|
|
2555
|
+
if (isFirst) {
|
|
2556
|
+
xi = data[i];
|
|
2557
|
+
yi = data[i + 1];
|
|
2558
|
+
x0 = xi;
|
|
2559
|
+
y0 = yi;
|
|
2560
|
+
if (cmd === CMD.L || cmd === CMD.C || cmd === CMD.Q) {
|
|
2561
|
+
currentSubpath = [x0, y0];
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
switch (cmd) {
|
|
2565
|
+
case CMD.M:
|
|
2566
|
+
xi = x0 = data[i++];
|
|
2567
|
+
yi = y0 = data[i++];
|
|
2568
|
+
createNewSubpath(x0, y0);
|
|
2569
|
+
break;
|
|
2570
|
+
case CMD.L:
|
|
2571
|
+
x1 = data[i++];
|
|
2572
|
+
y1 = data[i++];
|
|
2573
|
+
addLine(xi, yi, x1, y1);
|
|
2574
|
+
xi = x1;
|
|
2575
|
+
yi = y1;
|
|
2576
|
+
break;
|
|
2577
|
+
case CMD.C:
|
|
2578
|
+
currentSubpath.push(data[i++], data[i++], data[i++], data[i++], xi = data[i++], yi = data[i++]);
|
|
2579
|
+
break;
|
|
2580
|
+
case CMD.Q:
|
|
2581
|
+
x1 = data[i++];
|
|
2582
|
+
y1 = data[i++];
|
|
2583
|
+
x2 = data[i++];
|
|
2584
|
+
y2 = data[i++];
|
|
2585
|
+
currentSubpath.push(xi + 2 / 3 * (x1 - xi), yi + 2 / 3 * (y1 - yi), x2 + 2 / 3 * (x1 - x2), y2 + 2 / 3 * (y1 - y2), x2, y2);
|
|
2586
|
+
xi = x2;
|
|
2587
|
+
yi = y2;
|
|
2588
|
+
break;
|
|
2589
|
+
case CMD.A:
|
|
2590
|
+
var cx = data[i++];
|
|
2591
|
+
var cy = data[i++];
|
|
2592
|
+
var rx = data[i++];
|
|
2593
|
+
var ry = data[i++];
|
|
2594
|
+
var startAngle = data[i++];
|
|
2595
|
+
var endAngle = data[i++] + startAngle;
|
|
2596
|
+
i += 1;
|
|
2597
|
+
var anticlockwise = !data[i++];
|
|
2598
|
+
x1 = Math.cos(startAngle) * rx + cx;
|
|
2599
|
+
y1 = Math.sin(startAngle) * ry + cy;
|
|
2600
|
+
if (isFirst) {
|
|
2601
|
+
x0 = x1;
|
|
2602
|
+
y0 = y1;
|
|
2603
|
+
createNewSubpath(x0, y0);
|
|
2604
|
+
}
|
|
2605
|
+
else {
|
|
2606
|
+
addLine(xi, yi, x1, y1);
|
|
2607
|
+
}
|
|
2608
|
+
xi = Math.cos(endAngle) * rx + cx;
|
|
2609
|
+
yi = Math.sin(endAngle) * ry + cy;
|
|
2610
|
+
var step = (anticlockwise ? -1 : 1) * Math.PI / 2;
|
|
2611
|
+
for (var angle = startAngle; anticlockwise ? angle > endAngle : angle < endAngle; angle += step) {
|
|
2612
|
+
var nextAngle = anticlockwise ? Math.max(angle + step, endAngle)
|
|
2613
|
+
: Math.min(angle + step, endAngle);
|
|
2614
|
+
addArc(angle, nextAngle, cx, cy, rx, ry);
|
|
2615
|
+
}
|
|
2616
|
+
break;
|
|
2617
|
+
case CMD.R:
|
|
2618
|
+
x0 = xi = data[i++];
|
|
2619
|
+
y0 = yi = data[i++];
|
|
2620
|
+
x1 = x0 + data[i++];
|
|
2621
|
+
y1 = y0 + data[i++];
|
|
2622
|
+
createNewSubpath(x1, y0);
|
|
2623
|
+
addLine(x1, y0, x1, y1);
|
|
2624
|
+
addLine(x1, y1, x0, y1);
|
|
2625
|
+
addLine(x0, y1, x0, y0);
|
|
2626
|
+
addLine(x0, y0, x1, y0);
|
|
2627
|
+
break;
|
|
2628
|
+
case CMD.Z:
|
|
2629
|
+
currentSubpath && addLine(xi, yi, x0, y0);
|
|
2630
|
+
xi = x0;
|
|
2631
|
+
yi = y0;
|
|
2632
|
+
break;
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
if (currentSubpath && currentSubpath.length > 2) {
|
|
2636
|
+
bezierArrayGroups.push(currentSubpath);
|
|
2637
|
+
}
|
|
2638
|
+
return bezierArrayGroups;
|
|
2639
|
+
}
|
|
2640
|
+
function adpativeBezier(x0, y0, x1, y1, x2, y2, x3, y3, out, scale) {
|
|
2641
|
+
if (aroundEqual(x0, x1) && aroundEqual(y0, y1) && aroundEqual(x2, x3) && aroundEqual(y2, y3)) {
|
|
2642
|
+
out.push(x3, y3);
|
|
2643
|
+
return;
|
|
2644
|
+
}
|
|
2645
|
+
var PIXEL_DISTANCE = 2 / scale;
|
|
2646
|
+
var PIXEL_DISTANCE_SQR = PIXEL_DISTANCE * PIXEL_DISTANCE;
|
|
2647
|
+
var dx = x3 - x0;
|
|
2648
|
+
var dy = y3 - y0;
|
|
2649
|
+
var d = Math.sqrt(dx * dx + dy * dy);
|
|
2650
|
+
dx /= d;
|
|
2651
|
+
dy /= d;
|
|
2652
|
+
var dx1 = x1 - x0;
|
|
2653
|
+
var dy1 = y1 - y0;
|
|
2654
|
+
var dx2 = x2 - x3;
|
|
2655
|
+
var dy2 = y2 - y3;
|
|
2656
|
+
var cp1LenSqr = dx1 * dx1 + dy1 * dy1;
|
|
2657
|
+
var cp2LenSqr = dx2 * dx2 + dy2 * dy2;
|
|
2658
|
+
if (cp1LenSqr < PIXEL_DISTANCE_SQR && cp2LenSqr < PIXEL_DISTANCE_SQR) {
|
|
2659
|
+
out.push(x3, y3);
|
|
2660
|
+
return;
|
|
2661
|
+
}
|
|
2662
|
+
var projLen1 = dx * dx1 + dy * dy1;
|
|
2663
|
+
var projLen2 = -dx * dx2 - dy * dy2;
|
|
2664
|
+
var d1Sqr = cp1LenSqr - projLen1 * projLen1;
|
|
2665
|
+
var d2Sqr = cp2LenSqr - projLen2 * projLen2;
|
|
2666
|
+
if (d1Sqr < PIXEL_DISTANCE_SQR && projLen1 >= 0
|
|
2667
|
+
&& d2Sqr < PIXEL_DISTANCE_SQR && projLen2 >= 0) {
|
|
2668
|
+
out.push(x3, y3);
|
|
2669
|
+
return;
|
|
2670
|
+
}
|
|
2671
|
+
var tmpSegX = [];
|
|
2672
|
+
var tmpSegY = [];
|
|
2673
|
+
cubicSubdivide(x0, x1, x2, x3, 0.5, tmpSegX);
|
|
2674
|
+
cubicSubdivide(y0, y1, y2, y3, 0.5, tmpSegY);
|
|
2675
|
+
adpativeBezier(tmpSegX[0], tmpSegY[0], tmpSegX[1], tmpSegY[1], tmpSegX[2], tmpSegY[2], tmpSegX[3], tmpSegY[3], out, scale);
|
|
2676
|
+
adpativeBezier(tmpSegX[4], tmpSegY[4], tmpSegX[5], tmpSegY[5], tmpSegX[6], tmpSegY[6], tmpSegX[7], tmpSegY[7], out, scale);
|
|
2677
|
+
}
|
|
2678
|
+
function pathToPolygons(path, scale) {
|
|
2679
|
+
var bezierArrayGroups = pathToBezierCurves(path);
|
|
2680
|
+
var polygons = [];
|
|
2681
|
+
scale = scale || 1;
|
|
2682
|
+
for (var i = 0; i < bezierArrayGroups.length; i++) {
|
|
2683
|
+
var beziers = bezierArrayGroups[i];
|
|
2684
|
+
var polygon = [];
|
|
2685
|
+
var x0 = beziers[0];
|
|
2686
|
+
var y0 = beziers[1];
|
|
2687
|
+
polygon.push(x0, y0);
|
|
2688
|
+
for (var k = 2; k < beziers.length;) {
|
|
2689
|
+
var x1 = beziers[k++];
|
|
2690
|
+
var y1 = beziers[k++];
|
|
2691
|
+
var x2 = beziers[k++];
|
|
2692
|
+
var y2 = beziers[k++];
|
|
2693
|
+
var x3 = beziers[k++];
|
|
2694
|
+
var y3 = beziers[k++];
|
|
2695
|
+
adpativeBezier(x0, y0, x1, y1, x2, y2, x3, y3, polygon, scale);
|
|
2696
|
+
x0 = x3;
|
|
2697
|
+
y0 = y3;
|
|
2698
|
+
}
|
|
2699
|
+
polygons.push(polygon);
|
|
2700
|
+
}
|
|
2701
|
+
return polygons;
|
|
2702
|
+
}
|
|
2703
|
+
|
|
2704
|
+
function getDividingGrids(dimSize, rowDim, count) {
|
|
2705
|
+
var rowSize = dimSize[rowDim];
|
|
2706
|
+
var columnSize = dimSize[1 - rowDim];
|
|
2707
|
+
var ratio = Math.abs(rowSize / columnSize);
|
|
2708
|
+
var rowCount = Math.ceil(Math.sqrt(ratio * count));
|
|
2709
|
+
var columnCount = Math.floor(count / rowCount);
|
|
2710
|
+
if (columnCount === 0) {
|
|
2711
|
+
columnCount = 1;
|
|
2712
|
+
rowCount = count;
|
|
2713
|
+
}
|
|
2714
|
+
var grids = [];
|
|
2715
|
+
for (var i = 0; i < rowCount; i++) {
|
|
2716
|
+
grids.push(columnCount);
|
|
2717
|
+
}
|
|
2718
|
+
var currentCount = rowCount * columnCount;
|
|
2719
|
+
var remained = count - currentCount;
|
|
2720
|
+
if (remained > 0) {
|
|
2721
|
+
for (var i = 0; i < remained; i++) {
|
|
2722
|
+
grids[i % rowCount] += 1;
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
return grids;
|
|
2726
|
+
}
|
|
2727
|
+
function divideSector(sectorShape, count, outShapes) {
|
|
2728
|
+
var r0 = sectorShape.r0;
|
|
2729
|
+
var r = sectorShape.r;
|
|
2730
|
+
var startAngle = sectorShape.startAngle;
|
|
2731
|
+
var endAngle = sectorShape.endAngle;
|
|
2732
|
+
var angle = Math.abs(endAngle - startAngle);
|
|
2733
|
+
var arcLen = angle * r;
|
|
2734
|
+
var deltaR = r - r0;
|
|
2735
|
+
var isAngleRow = arcLen > Math.abs(deltaR);
|
|
2736
|
+
var grids = getDividingGrids([arcLen, deltaR], isAngleRow ? 0 : 1, count);
|
|
2737
|
+
var rowSize = (isAngleRow ? angle : deltaR) / grids.length;
|
|
2738
|
+
for (var row = 0; row < grids.length; row++) {
|
|
2739
|
+
var columnSize = (isAngleRow ? deltaR : angle) / grids[row];
|
|
2740
|
+
for (var column = 0; column < grids[row]; column++) {
|
|
2741
|
+
var newShape = {};
|
|
2742
|
+
if (isAngleRow) {
|
|
2743
|
+
newShape.startAngle = startAngle + rowSize * row;
|
|
2744
|
+
newShape.endAngle = startAngle + rowSize * (row + 1);
|
|
2745
|
+
newShape.r0 = r0 + columnSize * column;
|
|
2746
|
+
newShape.r = r0 + columnSize * (column + 1);
|
|
2747
|
+
}
|
|
2748
|
+
else {
|
|
2749
|
+
newShape.startAngle = startAngle + columnSize * column;
|
|
2750
|
+
newShape.endAngle = startAngle + columnSize * (column + 1);
|
|
2751
|
+
newShape.r0 = r0 + rowSize * row;
|
|
2752
|
+
newShape.r = r0 + rowSize * (row + 1);
|
|
2753
|
+
}
|
|
2754
|
+
newShape.clockwise = sectorShape.clockwise;
|
|
2755
|
+
newShape.cx = sectorShape.cx;
|
|
2756
|
+
newShape.cy = sectorShape.cy;
|
|
2757
|
+
outShapes.push(newShape);
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
}
|
|
2761
|
+
function divideRect(rectShape, count, outShapes) {
|
|
2762
|
+
var width = rectShape.width;
|
|
2763
|
+
var height = rectShape.height;
|
|
2764
|
+
var isHorizontalRow = width > height;
|
|
2765
|
+
var grids = getDividingGrids([width, height], isHorizontalRow ? 0 : 1, count);
|
|
2766
|
+
var rowSizeDim = isHorizontalRow ? 'width' : 'height';
|
|
2767
|
+
var columnSizeDim = isHorizontalRow ? 'height' : 'width';
|
|
2768
|
+
var rowDim = isHorizontalRow ? 'x' : 'y';
|
|
2769
|
+
var columnDim = isHorizontalRow ? 'y' : 'x';
|
|
2770
|
+
var rowSize = rectShape[rowSizeDim] / grids.length;
|
|
2771
|
+
for (var row = 0; row < grids.length; row++) {
|
|
2772
|
+
var columnSize = rectShape[columnSizeDim] / grids[row];
|
|
2773
|
+
for (var column = 0; column < grids[row]; column++) {
|
|
2774
|
+
var newShape = {};
|
|
2775
|
+
newShape[rowDim] = row * rowSize;
|
|
2776
|
+
newShape[columnDim] = column * columnSize;
|
|
2777
|
+
newShape[rowSizeDim] = rowSize;
|
|
2778
|
+
newShape[columnSizeDim] = columnSize;
|
|
2779
|
+
newShape.x += rectShape.x;
|
|
2780
|
+
newShape.y += rectShape.y;
|
|
2781
|
+
outShapes.push(newShape);
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
function crossProduct2d(x1, y1, x2, y2) {
|
|
2786
|
+
return x1 * y2 - x2 * y1;
|
|
2787
|
+
}
|
|
2788
|
+
function lineLineIntersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) {
|
|
2789
|
+
var mx = a2x - a1x;
|
|
2790
|
+
var my = a2y - a1y;
|
|
2791
|
+
var nx = b2x - b1x;
|
|
2792
|
+
var ny = b2y - b1y;
|
|
2793
|
+
var nmCrossProduct = crossProduct2d(nx, ny, mx, my);
|
|
2794
|
+
if (Math.abs(nmCrossProduct) < 1e-6) {
|
|
2795
|
+
return null;
|
|
2796
|
+
}
|
|
2797
|
+
var b1a1x = a1x - b1x;
|
|
2798
|
+
var b1a1y = a1y - b1y;
|
|
2799
|
+
var p = crossProduct2d(b1a1x, b1a1y, nx, ny) / nmCrossProduct;
|
|
2800
|
+
if (p < 0 || p > 1) {
|
|
2801
|
+
return null;
|
|
2802
|
+
}
|
|
2803
|
+
return new Point(p * mx + a1x, p * my + a1y);
|
|
2804
|
+
}
|
|
2805
|
+
function projPtOnLine(pt, lineA, lineB) {
|
|
2806
|
+
var dir = new Point();
|
|
2807
|
+
Point.sub(dir, lineB, lineA);
|
|
2808
|
+
dir.normalize();
|
|
2809
|
+
var dir2 = new Point();
|
|
2810
|
+
Point.sub(dir2, pt, lineA);
|
|
2811
|
+
var len = dir2.dot(dir);
|
|
2812
|
+
return len;
|
|
2813
|
+
}
|
|
2814
|
+
function addToPoly(poly, pt) {
|
|
2815
|
+
var last = poly[poly.length - 1];
|
|
2816
|
+
if (last && last[0] === pt[0] && last[1] === pt[1]) {
|
|
2817
|
+
return;
|
|
2818
|
+
}
|
|
2819
|
+
poly.push(pt);
|
|
2820
|
+
}
|
|
2821
|
+
function splitPolygonByLine(points, lineA, lineB) {
|
|
2822
|
+
var len = points.length;
|
|
2823
|
+
var intersections = [];
|
|
2824
|
+
for (var i = 0; i < len; i++) {
|
|
2825
|
+
var p0 = points[i];
|
|
2826
|
+
var p1 = points[(i + 1) % len];
|
|
2827
|
+
var intersectionPt = lineLineIntersect(p0[0], p0[1], p1[0], p1[1], lineA.x, lineA.y, lineB.x, lineB.y);
|
|
2828
|
+
if (intersectionPt) {
|
|
2829
|
+
intersections.push({
|
|
2830
|
+
projPt: projPtOnLine(intersectionPt, lineA, lineB),
|
|
2831
|
+
pt: intersectionPt,
|
|
2832
|
+
idx: i
|
|
2833
|
+
});
|
|
2834
|
+
}
|
|
2835
|
+
}
|
|
2836
|
+
if (intersections.length < 2) {
|
|
2837
|
+
return [{ points: points }, { points: points }];
|
|
2838
|
+
}
|
|
2839
|
+
intersections.sort(function (a, b) {
|
|
2840
|
+
return a.projPt - b.projPt;
|
|
2841
|
+
});
|
|
2842
|
+
var splitPt0 = intersections[0];
|
|
2843
|
+
var splitPt1 = intersections[intersections.length - 1];
|
|
2844
|
+
if (splitPt1.idx < splitPt0.idx) {
|
|
2845
|
+
var tmp = splitPt0;
|
|
2846
|
+
splitPt0 = splitPt1;
|
|
2847
|
+
splitPt1 = tmp;
|
|
2848
|
+
}
|
|
2849
|
+
var splitPt0Arr = [splitPt0.pt.x, splitPt0.pt.y];
|
|
2850
|
+
var splitPt1Arr = [splitPt1.pt.x, splitPt1.pt.y];
|
|
2851
|
+
var newPolyA = [splitPt0Arr];
|
|
2852
|
+
var newPolyB = [splitPt1Arr];
|
|
2853
|
+
for (var i = splitPt0.idx + 1; i <= splitPt1.idx; i++) {
|
|
2854
|
+
addToPoly(newPolyA, points[i].slice());
|
|
2855
|
+
}
|
|
2856
|
+
addToPoly(newPolyA, splitPt1Arr);
|
|
2857
|
+
addToPoly(newPolyA, splitPt0Arr);
|
|
2858
|
+
for (var i = splitPt1.idx + 1; i <= splitPt0.idx + len; i++) {
|
|
2859
|
+
addToPoly(newPolyB, points[i % len].slice());
|
|
2860
|
+
}
|
|
2861
|
+
addToPoly(newPolyB, splitPt0Arr);
|
|
2862
|
+
addToPoly(newPolyB, splitPt1Arr);
|
|
2863
|
+
return [{
|
|
2864
|
+
points: newPolyA
|
|
2865
|
+
}, {
|
|
2866
|
+
points: newPolyB
|
|
2867
|
+
}];
|
|
2868
|
+
}
|
|
2869
|
+
function binaryDividePolygon(polygonShape) {
|
|
2870
|
+
var points = polygonShape.points;
|
|
2871
|
+
var min = [];
|
|
2872
|
+
var max = [];
|
|
2873
|
+
fromPoints(points, min, max);
|
|
2874
|
+
var boundingRect = new BoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);
|
|
2875
|
+
var width = boundingRect.width;
|
|
2876
|
+
var height = boundingRect.height;
|
|
2877
|
+
var x = boundingRect.x;
|
|
2878
|
+
var y = boundingRect.y;
|
|
2879
|
+
var pt0 = new Point();
|
|
2880
|
+
var pt1 = new Point();
|
|
2881
|
+
if (width > height) {
|
|
2882
|
+
pt0.x = pt1.x = x + width / 2;
|
|
2883
|
+
pt0.y = y;
|
|
2884
|
+
pt1.y = y + height;
|
|
2885
|
+
}
|
|
2886
|
+
else {
|
|
2887
|
+
pt0.y = pt1.y = y + height / 2;
|
|
2888
|
+
pt0.x = x;
|
|
2889
|
+
pt1.x = x + width;
|
|
2890
|
+
}
|
|
2891
|
+
return splitPolygonByLine(points, pt0, pt1);
|
|
2892
|
+
}
|
|
2893
|
+
function binaryDivideRecursive(divider, shape, count, out) {
|
|
2894
|
+
if (count === 1) {
|
|
2895
|
+
out.push(shape);
|
|
2896
|
+
}
|
|
2897
|
+
else {
|
|
2898
|
+
var mid = Math.floor(count / 2);
|
|
2899
|
+
var sub = divider(shape);
|
|
2900
|
+
binaryDivideRecursive(divider, sub[0], mid, out);
|
|
2901
|
+
binaryDivideRecursive(divider, sub[1], count - mid, out);
|
|
2902
|
+
}
|
|
2903
|
+
return out;
|
|
2904
|
+
}
|
|
2905
|
+
function clone(path, count) {
|
|
2906
|
+
var paths = [];
|
|
2907
|
+
for (var i = 0; i < count; i++) {
|
|
2908
|
+
paths.push(clonePath(path));
|
|
2909
|
+
}
|
|
2910
|
+
return paths;
|
|
2911
|
+
}
|
|
2912
|
+
function copyPathProps(source, target) {
|
|
2913
|
+
target.setStyle(source.style);
|
|
2914
|
+
target.z = source.z;
|
|
2915
|
+
target.z2 = source.z2;
|
|
2916
|
+
target.zlevel = source.zlevel;
|
|
2917
|
+
}
|
|
2918
|
+
function polygonConvert(points) {
|
|
2919
|
+
var out = [];
|
|
2920
|
+
for (var i = 0; i < points.length;) {
|
|
2921
|
+
out.push([points[i++], points[i++]]);
|
|
2922
|
+
}
|
|
2923
|
+
return out;
|
|
2924
|
+
}
|
|
2925
|
+
function split(path, count) {
|
|
2926
|
+
var outShapes = [];
|
|
2927
|
+
var shape = path.shape;
|
|
2928
|
+
var OutShapeCtor;
|
|
2929
|
+
switch (path.type) {
|
|
2930
|
+
case 'rect':
|
|
2931
|
+
divideRect(shape, count, outShapes);
|
|
2932
|
+
OutShapeCtor = Rect;
|
|
2933
|
+
break;
|
|
2934
|
+
case 'sector':
|
|
2935
|
+
divideSector(shape, count, outShapes);
|
|
2936
|
+
OutShapeCtor = Sector;
|
|
2937
|
+
break;
|
|
2938
|
+
case 'circle':
|
|
2939
|
+
divideSector({
|
|
2940
|
+
r0: 0, r: shape.r, startAngle: 0, endAngle: Math.PI * 2,
|
|
2941
|
+
cx: shape.cx, cy: shape.cy
|
|
2942
|
+
}, count, outShapes);
|
|
2943
|
+
OutShapeCtor = Sector;
|
|
2944
|
+
break;
|
|
2945
|
+
default:
|
|
2946
|
+
var m = path.getComputedTransform();
|
|
2947
|
+
var scale = m ? Math.sqrt(Math.max(m[0] * m[0] + m[1] * m[1], m[2] * m[2] + m[3] * m[3])) : 1;
|
|
2948
|
+
var polygons = map(pathToPolygons(path.getUpdatedPathProxy(), scale), function (poly) { return polygonConvert(poly); });
|
|
2949
|
+
var polygonCount = polygons.length;
|
|
2950
|
+
if (polygonCount === 0) {
|
|
2951
|
+
binaryDivideRecursive(binaryDividePolygon, {
|
|
2952
|
+
points: polygons[0]
|
|
2953
|
+
}, count, outShapes);
|
|
2954
|
+
}
|
|
2955
|
+
else if (polygonCount === count) {
|
|
2956
|
+
for (var i = 0; i < polygonCount; i++) {
|
|
2957
|
+
outShapes.push({
|
|
2958
|
+
points: polygons[i]
|
|
2959
|
+
});
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
else {
|
|
2963
|
+
var totalArea_1 = 0;
|
|
2964
|
+
var items = map(polygons, function (poly) {
|
|
2965
|
+
var min = [];
|
|
2966
|
+
var max = [];
|
|
2967
|
+
fromPoints(poly, min, max);
|
|
2968
|
+
var area = (max[1] - min[1]) * (max[0] - min[0]);
|
|
2969
|
+
totalArea_1 += area;
|
|
2970
|
+
return { poly: poly, area: area };
|
|
2971
|
+
});
|
|
2972
|
+
items.sort(function (a, b) { return b.area - a.area; });
|
|
2973
|
+
var left = count;
|
|
2974
|
+
for (var i = 0; i < polygonCount; i++) {
|
|
2975
|
+
var item = items[i];
|
|
2976
|
+
if (left <= 0) {
|
|
2977
|
+
break;
|
|
2978
|
+
}
|
|
2979
|
+
var selfCount = i === polygonCount - 1
|
|
2980
|
+
? left
|
|
2981
|
+
: Math.ceil(item.area / totalArea_1 * count);
|
|
2982
|
+
if (selfCount < 0) {
|
|
2983
|
+
continue;
|
|
2984
|
+
}
|
|
2985
|
+
binaryDivideRecursive(binaryDividePolygon, {
|
|
2986
|
+
points: item.poly
|
|
2987
|
+
}, selfCount, outShapes);
|
|
2988
|
+
left -= selfCount;
|
|
2989
|
+
}
|
|
2990
|
+
}
|
|
2991
|
+
OutShapeCtor = Polygon;
|
|
2992
|
+
break;
|
|
2993
|
+
}
|
|
2994
|
+
if (!OutShapeCtor) {
|
|
2995
|
+
return clone(path, count);
|
|
2996
|
+
}
|
|
2997
|
+
var out = [];
|
|
2998
|
+
for (var i = 0; i < outShapes.length; i++) {
|
|
2999
|
+
var subPath = new OutShapeCtor();
|
|
3000
|
+
subPath.setShape(outShapes[i]);
|
|
3001
|
+
copyPathProps(path, subPath);
|
|
3002
|
+
out.push(subPath);
|
|
3003
|
+
}
|
|
3004
|
+
return out;
|
|
3005
|
+
}
|
|
3006
|
+
|
|
3007
|
+
function alignSubpath(subpath1, subpath2) {
|
|
3008
|
+
var len1 = subpath1.length;
|
|
3009
|
+
var len2 = subpath2.length;
|
|
3010
|
+
if (len1 === len2) {
|
|
3011
|
+
return [subpath1, subpath2];
|
|
3012
|
+
}
|
|
3013
|
+
var tmpSegX = [];
|
|
3014
|
+
var tmpSegY = [];
|
|
3015
|
+
var shorterPath = len1 < len2 ? subpath1 : subpath2;
|
|
3016
|
+
var shorterLen = Math.min(len1, len2);
|
|
3017
|
+
var diff = Math.abs(len2 - len1) / 6;
|
|
3018
|
+
var shorterBezierCount = (shorterLen - 2) / 6;
|
|
3019
|
+
var eachCurveSubDivCount = Math.ceil(diff / shorterBezierCount) + 1;
|
|
3020
|
+
var newSubpath = [shorterPath[0], shorterPath[1]];
|
|
3021
|
+
var remained = diff;
|
|
3022
|
+
for (var i = 2; i < shorterLen;) {
|
|
3023
|
+
var x0 = shorterPath[i - 2];
|
|
3024
|
+
var y0 = shorterPath[i - 1];
|
|
3025
|
+
var x1 = shorterPath[i++];
|
|
3026
|
+
var y1 = shorterPath[i++];
|
|
3027
|
+
var x2 = shorterPath[i++];
|
|
3028
|
+
var y2 = shorterPath[i++];
|
|
3029
|
+
var x3 = shorterPath[i++];
|
|
3030
|
+
var y3 = shorterPath[i++];
|
|
3031
|
+
if (remained <= 0) {
|
|
3032
|
+
newSubpath.push(x1, y1, x2, y2, x3, y3);
|
|
3033
|
+
continue;
|
|
3034
|
+
}
|
|
3035
|
+
var actualSubDivCount = Math.min(remained, eachCurveSubDivCount - 1) + 1;
|
|
3036
|
+
for (var k = 1; k <= actualSubDivCount; k++) {
|
|
3037
|
+
var p = k / actualSubDivCount;
|
|
3038
|
+
cubicSubdivide(x0, x1, x2, x3, p, tmpSegX);
|
|
3039
|
+
cubicSubdivide(y0, y1, y2, y3, p, tmpSegY);
|
|
3040
|
+
x0 = tmpSegX[3];
|
|
3041
|
+
y0 = tmpSegY[3];
|
|
3042
|
+
newSubpath.push(tmpSegX[1], tmpSegY[1], tmpSegX[2], tmpSegY[2], x0, y0);
|
|
3043
|
+
x1 = tmpSegX[5];
|
|
3044
|
+
y1 = tmpSegY[5];
|
|
3045
|
+
x2 = tmpSegX[6];
|
|
3046
|
+
y2 = tmpSegY[6];
|
|
3047
|
+
}
|
|
3048
|
+
remained -= actualSubDivCount - 1;
|
|
3049
|
+
}
|
|
3050
|
+
return shorterPath === subpath1 ? [newSubpath, subpath2] : [subpath1, newSubpath];
|
|
3051
|
+
}
|
|
3052
|
+
function createSubpath(lastSubpathSubpath, otherSubpath) {
|
|
3053
|
+
var len = lastSubpathSubpath.length;
|
|
3054
|
+
var lastX = lastSubpathSubpath[len - 2];
|
|
3055
|
+
var lastY = lastSubpathSubpath[len - 1];
|
|
3056
|
+
var newSubpath = [];
|
|
3057
|
+
for (var i = 0; i < otherSubpath.length;) {
|
|
3058
|
+
newSubpath[i++] = lastX;
|
|
3059
|
+
newSubpath[i++] = lastY;
|
|
3060
|
+
}
|
|
3061
|
+
return newSubpath;
|
|
3062
|
+
}
|
|
3063
|
+
function alignBezierCurves(array1, array2) {
|
|
3064
|
+
var _a;
|
|
3065
|
+
var lastSubpath1;
|
|
3066
|
+
var lastSubpath2;
|
|
3067
|
+
var newArray1 = [];
|
|
3068
|
+
var newArray2 = [];
|
|
3069
|
+
for (var i = 0; i < Math.max(array1.length, array2.length); i++) {
|
|
3070
|
+
var subpath1 = array1[i];
|
|
3071
|
+
var subpath2 = array2[i];
|
|
3072
|
+
var newSubpath1 = void 0;
|
|
3073
|
+
var newSubpath2 = void 0;
|
|
3074
|
+
if (!subpath1) {
|
|
3075
|
+
newSubpath1 = createSubpath(lastSubpath1 || subpath2, subpath2);
|
|
3076
|
+
newSubpath2 = subpath2;
|
|
3077
|
+
}
|
|
3078
|
+
else if (!subpath2) {
|
|
3079
|
+
newSubpath2 = createSubpath(lastSubpath2 || subpath1, subpath1);
|
|
3080
|
+
newSubpath1 = subpath1;
|
|
3081
|
+
}
|
|
3082
|
+
else {
|
|
3083
|
+
_a = alignSubpath(subpath1, subpath2), newSubpath1 = _a[0], newSubpath2 = _a[1];
|
|
3084
|
+
lastSubpath1 = newSubpath1;
|
|
3085
|
+
lastSubpath2 = newSubpath2;
|
|
3086
|
+
}
|
|
3087
|
+
newArray1.push(newSubpath1);
|
|
3088
|
+
newArray2.push(newSubpath2);
|
|
3089
|
+
}
|
|
3090
|
+
return [newArray1, newArray2];
|
|
3091
|
+
}
|
|
3092
|
+
function centroid(array) {
|
|
3093
|
+
var signedArea = 0;
|
|
3094
|
+
var cx = 0;
|
|
3095
|
+
var cy = 0;
|
|
3096
|
+
var len = array.length;
|
|
3097
|
+
for (var i = 0, j = len - 2; i < len; j = i, i += 2) {
|
|
3098
|
+
var x0 = array[j];
|
|
3099
|
+
var y0 = array[j + 1];
|
|
3100
|
+
var x1 = array[i];
|
|
3101
|
+
var y1 = array[i + 1];
|
|
3102
|
+
var a = x0 * y1 - x1 * y0;
|
|
3103
|
+
signedArea += a;
|
|
3104
|
+
cx += (x0 + x1) * a;
|
|
3105
|
+
cy += (y0 + y1) * a;
|
|
3106
|
+
}
|
|
3107
|
+
if (signedArea === 0) {
|
|
3108
|
+
return [array[0] || 0, array[1] || 0];
|
|
3109
|
+
}
|
|
3110
|
+
return [cx / signedArea / 3, cy / signedArea / 3, signedArea];
|
|
3111
|
+
}
|
|
3112
|
+
function findBestRingOffset(fromSubBeziers, toSubBeziers, fromCp, toCp) {
|
|
3113
|
+
var bezierCount = (fromSubBeziers.length - 2) / 6;
|
|
3114
|
+
var bestScore = Infinity;
|
|
3115
|
+
var bestOffset = 0;
|
|
3116
|
+
var len = fromSubBeziers.length;
|
|
3117
|
+
var len2 = len - 2;
|
|
3118
|
+
for (var offset = 0; offset < bezierCount; offset++) {
|
|
3119
|
+
var cursorOffset = offset * 6;
|
|
3120
|
+
var score = 0;
|
|
3121
|
+
for (var k = 0; k < len; k += 2) {
|
|
3122
|
+
var idx = k === 0 ? cursorOffset : ((cursorOffset + k - 2) % len2 + 2);
|
|
3123
|
+
var x0 = fromSubBeziers[idx] - fromCp[0];
|
|
3124
|
+
var y0 = fromSubBeziers[idx + 1] - fromCp[1];
|
|
3125
|
+
var x1 = toSubBeziers[k] - toCp[0];
|
|
3126
|
+
var y1 = toSubBeziers[k + 1] - toCp[1];
|
|
3127
|
+
var dx = x1 - x0;
|
|
3128
|
+
var dy = y1 - y0;
|
|
3129
|
+
score += dx * dx + dy * dy;
|
|
3130
|
+
}
|
|
3131
|
+
if (score < bestScore) {
|
|
3132
|
+
bestScore = score;
|
|
3133
|
+
bestOffset = offset;
|
|
3134
|
+
}
|
|
3135
|
+
}
|
|
3136
|
+
return bestOffset;
|
|
3137
|
+
}
|
|
3138
|
+
function reverse(array) {
|
|
3139
|
+
var newArr = [];
|
|
3140
|
+
var len = array.length;
|
|
3141
|
+
for (var i = 0; i < len; i += 2) {
|
|
3142
|
+
newArr[i] = array[len - i - 2];
|
|
3143
|
+
newArr[i + 1] = array[len - i - 1];
|
|
3144
|
+
}
|
|
3145
|
+
return newArr;
|
|
3146
|
+
}
|
|
3147
|
+
function findBestMorphingRotation(fromArr, toArr, searchAngleIteration, searchAngleRange) {
|
|
3148
|
+
var result = [];
|
|
3149
|
+
var fromNeedsReverse;
|
|
3150
|
+
for (var i = 0; i < fromArr.length; i++) {
|
|
3151
|
+
var fromSubpathBezier = fromArr[i];
|
|
3152
|
+
var toSubpathBezier = toArr[i];
|
|
3153
|
+
var fromCp = centroid(fromSubpathBezier);
|
|
3154
|
+
var toCp = centroid(toSubpathBezier);
|
|
3155
|
+
if (fromNeedsReverse == null) {
|
|
3156
|
+
fromNeedsReverse = fromCp[2] < 0 !== toCp[2] < 0;
|
|
3157
|
+
}
|
|
3158
|
+
var newFromSubpathBezier = [];
|
|
3159
|
+
var newToSubpathBezier = [];
|
|
3160
|
+
var bestAngle = 0;
|
|
3161
|
+
var bestScore = Infinity;
|
|
3162
|
+
var tmpArr = [];
|
|
3163
|
+
var len = fromSubpathBezier.length;
|
|
3164
|
+
if (fromNeedsReverse) {
|
|
3165
|
+
fromSubpathBezier = reverse(fromSubpathBezier);
|
|
3166
|
+
}
|
|
3167
|
+
var offset = findBestRingOffset(fromSubpathBezier, toSubpathBezier, fromCp, toCp) * 6;
|
|
3168
|
+
var len2 = len - 2;
|
|
3169
|
+
for (var k = 0; k < len2; k += 2) {
|
|
3170
|
+
var idx = (offset + k) % len2 + 2;
|
|
3171
|
+
newFromSubpathBezier[k + 2] = fromSubpathBezier[idx] - fromCp[0];
|
|
3172
|
+
newFromSubpathBezier[k + 3] = fromSubpathBezier[idx + 1] - fromCp[1];
|
|
3173
|
+
}
|
|
3174
|
+
newFromSubpathBezier[0] = fromSubpathBezier[offset] - fromCp[0];
|
|
3175
|
+
newFromSubpathBezier[1] = fromSubpathBezier[offset + 1] - fromCp[1];
|
|
3176
|
+
if (searchAngleIteration > 0) {
|
|
3177
|
+
var step = searchAngleRange / searchAngleIteration;
|
|
3178
|
+
for (var angle = -searchAngleRange / 2; angle <= searchAngleRange / 2; angle += step) {
|
|
3179
|
+
var sa = Math.sin(angle);
|
|
3180
|
+
var ca = Math.cos(angle);
|
|
3181
|
+
var score = 0;
|
|
3182
|
+
for (var k = 0; k < fromSubpathBezier.length; k += 2) {
|
|
3183
|
+
var x0 = newFromSubpathBezier[k];
|
|
3184
|
+
var y0 = newFromSubpathBezier[k + 1];
|
|
3185
|
+
var x1 = toSubpathBezier[k] - toCp[0];
|
|
3186
|
+
var y1 = toSubpathBezier[k + 1] - toCp[1];
|
|
3187
|
+
var newX1 = x1 * ca - y1 * sa;
|
|
3188
|
+
var newY1 = x1 * sa + y1 * ca;
|
|
3189
|
+
tmpArr[k] = newX1;
|
|
3190
|
+
tmpArr[k + 1] = newY1;
|
|
3191
|
+
var dx = newX1 - x0;
|
|
3192
|
+
var dy = newY1 - y0;
|
|
3193
|
+
score += dx * dx + dy * dy;
|
|
3194
|
+
}
|
|
3195
|
+
if (score < bestScore) {
|
|
3196
|
+
bestScore = score;
|
|
3197
|
+
bestAngle = angle;
|
|
3198
|
+
for (var m = 0; m < tmpArr.length; m++) {
|
|
3199
|
+
newToSubpathBezier[m] = tmpArr[m];
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
else {
|
|
3205
|
+
for (var i_1 = 0; i_1 < len; i_1 += 2) {
|
|
3206
|
+
newToSubpathBezier[i_1] = toSubpathBezier[i_1] - toCp[0];
|
|
3207
|
+
newToSubpathBezier[i_1 + 1] = toSubpathBezier[i_1 + 1] - toCp[1];
|
|
3208
|
+
}
|
|
3209
|
+
}
|
|
3210
|
+
result.push({
|
|
3211
|
+
from: newFromSubpathBezier,
|
|
3212
|
+
to: newToSubpathBezier,
|
|
3213
|
+
fromCp: fromCp,
|
|
3214
|
+
toCp: toCp,
|
|
3215
|
+
rotation: -bestAngle
|
|
3216
|
+
});
|
|
3217
|
+
}
|
|
3218
|
+
return result;
|
|
3219
|
+
}
|
|
3220
|
+
function isCombineMorphing(path) {
|
|
3221
|
+
return path.__isCombineMorphing;
|
|
3222
|
+
}
|
|
3223
|
+
var SAVED_METHOD_PREFIX = '__mOriginal_';
|
|
3224
|
+
function saveAndModifyMethod(obj, methodName, modifiers) {
|
|
3225
|
+
var savedMethodName = SAVED_METHOD_PREFIX + methodName;
|
|
3226
|
+
var originalMethod = obj[savedMethodName] || obj[methodName];
|
|
3227
|
+
if (!obj[savedMethodName]) {
|
|
3228
|
+
obj[savedMethodName] = obj[methodName];
|
|
3229
|
+
}
|
|
3230
|
+
var replace = modifiers.replace;
|
|
3231
|
+
var after = modifiers.after;
|
|
3232
|
+
var before = modifiers.before;
|
|
3233
|
+
obj[methodName] = function () {
|
|
3234
|
+
var args = arguments;
|
|
3235
|
+
var res;
|
|
3236
|
+
before && before.apply(this, args);
|
|
3237
|
+
if (replace) {
|
|
3238
|
+
res = replace.apply(this, args);
|
|
3239
|
+
}
|
|
3240
|
+
else {
|
|
3241
|
+
res = originalMethod.apply(this, args);
|
|
3242
|
+
}
|
|
3243
|
+
after && after.apply(this, args);
|
|
3244
|
+
return res;
|
|
3245
|
+
};
|
|
3246
|
+
}
|
|
3247
|
+
function restoreMethod(obj, methodName) {
|
|
3248
|
+
var savedMethodName = SAVED_METHOD_PREFIX + methodName;
|
|
3249
|
+
if (obj[savedMethodName]) {
|
|
3250
|
+
obj[methodName] = obj[savedMethodName];
|
|
3251
|
+
obj[savedMethodName] = null;
|
|
3252
|
+
}
|
|
3253
|
+
}
|
|
3254
|
+
function applyTransformOnBeziers(bezierCurves, mm) {
|
|
3255
|
+
for (var i = 0; i < bezierCurves.length; i++) {
|
|
3256
|
+
var subBeziers = bezierCurves[i];
|
|
3257
|
+
for (var k = 0; k < subBeziers.length;) {
|
|
3258
|
+
var x = subBeziers[k];
|
|
3259
|
+
var y = subBeziers[k + 1];
|
|
3260
|
+
subBeziers[k++] = mm[0] * x + mm[2] * y + mm[4];
|
|
3261
|
+
subBeziers[k++] = mm[1] * x + mm[3] * y + mm[5];
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
}
|
|
3265
|
+
function prepareMorphPath(fromPath, toPath) {
|
|
3266
|
+
var fromPathProxy = fromPath.getUpdatedPathProxy();
|
|
3267
|
+
var toPathProxy = toPath.getUpdatedPathProxy();
|
|
3268
|
+
var _a = alignBezierCurves(pathToBezierCurves(fromPathProxy), pathToBezierCurves(toPathProxy)), fromBezierCurves = _a[0], toBezierCurves = _a[1];
|
|
3269
|
+
var fromPathTransform = fromPath.getComputedTransform();
|
|
3270
|
+
var toPathTransform = toPath.getComputedTransform();
|
|
3271
|
+
function updateIdentityTransform() {
|
|
3272
|
+
this.transform = null;
|
|
3273
|
+
}
|
|
3274
|
+
fromPathTransform && applyTransformOnBeziers(fromBezierCurves, fromPathTransform);
|
|
3275
|
+
toPathTransform && applyTransformOnBeziers(toBezierCurves, toPathTransform);
|
|
3276
|
+
saveAndModifyMethod(toPath, 'updateTransform', { replace: updateIdentityTransform });
|
|
3277
|
+
toPath.transform = null;
|
|
3278
|
+
var morphingData = findBestMorphingRotation(fromBezierCurves, toBezierCurves, 10, Math.PI);
|
|
3279
|
+
var tmpArr = [];
|
|
3280
|
+
saveAndModifyMethod(toPath, 'buildPath', { replace: function (path) {
|
|
3281
|
+
var t = toPath.__morphT;
|
|
3282
|
+
var onet = 1 - t;
|
|
3283
|
+
var newCp = [];
|
|
3284
|
+
for (var i = 0; i < morphingData.length; i++) {
|
|
3285
|
+
var item = morphingData[i];
|
|
3286
|
+
var from = item.from;
|
|
3287
|
+
var to = item.to;
|
|
3288
|
+
var angle = item.rotation * t;
|
|
3289
|
+
var fromCp = item.fromCp;
|
|
3290
|
+
var toCp = item.toCp;
|
|
3291
|
+
var sa = Math.sin(angle);
|
|
3292
|
+
var ca = Math.cos(angle);
|
|
3293
|
+
lerp$1(newCp, fromCp, toCp, t);
|
|
3294
|
+
for (var m = 0; m < from.length; m += 2) {
|
|
3295
|
+
var x0_1 = from[m];
|
|
3296
|
+
var y0_1 = from[m + 1];
|
|
3297
|
+
var x1 = to[m];
|
|
3298
|
+
var y1 = to[m + 1];
|
|
3299
|
+
var x = x0_1 * onet + x1 * t;
|
|
3300
|
+
var y = y0_1 * onet + y1 * t;
|
|
3301
|
+
tmpArr[m] = (x * ca - y * sa) + newCp[0];
|
|
3302
|
+
tmpArr[m + 1] = (x * sa + y * ca) + newCp[1];
|
|
3303
|
+
}
|
|
3304
|
+
var x0 = tmpArr[0];
|
|
3305
|
+
var y0 = tmpArr[1];
|
|
3306
|
+
path.moveTo(x0, y0);
|
|
3307
|
+
for (var m = 2; m < from.length;) {
|
|
3308
|
+
var x1 = tmpArr[m++];
|
|
3309
|
+
var y1 = tmpArr[m++];
|
|
3310
|
+
var x2 = tmpArr[m++];
|
|
3311
|
+
var y2 = tmpArr[m++];
|
|
3312
|
+
var x3 = tmpArr[m++];
|
|
3313
|
+
var y3 = tmpArr[m++];
|
|
3314
|
+
if (x0 === x1 && y0 === y1 && x2 === x3 && y2 === y3) {
|
|
3315
|
+
path.lineTo(x3, y3);
|
|
3316
|
+
}
|
|
3317
|
+
else {
|
|
3318
|
+
path.bezierCurveTo(x1, y1, x2, y2, x3, y3);
|
|
3319
|
+
}
|
|
3320
|
+
x0 = x3;
|
|
3321
|
+
y0 = y3;
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
} });
|
|
3325
|
+
}
|
|
3326
|
+
function morphPath(fromPath, toPath, animationOpts) {
|
|
3327
|
+
if (!fromPath || !toPath) {
|
|
3328
|
+
return toPath;
|
|
3329
|
+
}
|
|
3330
|
+
var oldDone = animationOpts.done;
|
|
3331
|
+
var oldDuring = animationOpts.during;
|
|
3332
|
+
prepareMorphPath(fromPath, toPath);
|
|
3333
|
+
toPath.__morphT = 0;
|
|
3334
|
+
function restoreToPath() {
|
|
3335
|
+
restoreMethod(toPath, 'buildPath');
|
|
3336
|
+
restoreMethod(toPath, 'updateTransform');
|
|
3337
|
+
toPath.__morphT = -1;
|
|
3338
|
+
toPath.createPathProxy();
|
|
3339
|
+
toPath.dirtyShape();
|
|
3340
|
+
}
|
|
3341
|
+
toPath.animateTo({
|
|
3342
|
+
__morphT: 1
|
|
3343
|
+
}, defaults({
|
|
3344
|
+
during: function (p) {
|
|
3345
|
+
toPath.dirtyShape();
|
|
3346
|
+
oldDuring && oldDuring(p);
|
|
3347
|
+
},
|
|
3348
|
+
done: function () {
|
|
3349
|
+
restoreToPath();
|
|
3350
|
+
oldDone && oldDone();
|
|
3351
|
+
}
|
|
3352
|
+
}, animationOpts));
|
|
3353
|
+
return toPath;
|
|
3354
|
+
}
|
|
3355
|
+
function hilbert(x, y, minX, minY, maxX, maxY) {
|
|
3356
|
+
var bits = 16;
|
|
3357
|
+
x = (maxX === minX) ? 0 : Math.round(32767 * (x - minX) / (maxX - minX));
|
|
3358
|
+
y = (maxY === minY) ? 0 : Math.round(32767 * (y - minY) / (maxY - minY));
|
|
3359
|
+
var d = 0;
|
|
3360
|
+
var tmp;
|
|
3361
|
+
for (var s = (1 << bits) / 2; s > 0; s /= 2) {
|
|
3362
|
+
var rx = 0;
|
|
3363
|
+
var ry = 0;
|
|
3364
|
+
if ((x & s) > 0) {
|
|
3365
|
+
rx = 1;
|
|
3366
|
+
}
|
|
3367
|
+
if ((y & s) > 0) {
|
|
3368
|
+
ry = 1;
|
|
3369
|
+
}
|
|
3370
|
+
d += s * s * ((3 * rx) ^ ry);
|
|
3371
|
+
if (ry === 0) {
|
|
3372
|
+
if (rx === 1) {
|
|
3373
|
+
x = s - 1 - x;
|
|
3374
|
+
y = s - 1 - y;
|
|
3375
|
+
}
|
|
3376
|
+
tmp = x;
|
|
3377
|
+
x = y;
|
|
3378
|
+
y = tmp;
|
|
3379
|
+
}
|
|
3380
|
+
}
|
|
3381
|
+
return d;
|
|
3382
|
+
}
|
|
3383
|
+
function sortPaths(pathList) {
|
|
3384
|
+
var xMin = Infinity;
|
|
3385
|
+
var yMin = Infinity;
|
|
3386
|
+
var xMax = -Infinity;
|
|
3387
|
+
var yMax = -Infinity;
|
|
3388
|
+
var cps = map(pathList, function (path) {
|
|
3389
|
+
var rect = path.getBoundingRect();
|
|
3390
|
+
var m = path.getComputedTransform();
|
|
3391
|
+
var x = rect.x + rect.width / 2 + (m ? m[4] : 0);
|
|
3392
|
+
var y = rect.y + rect.height / 2 + (m ? m[5] : 0);
|
|
3393
|
+
xMin = Math.min(x, xMin);
|
|
3394
|
+
yMin = Math.min(y, yMin);
|
|
3395
|
+
xMax = Math.max(x, xMax);
|
|
3396
|
+
yMax = Math.max(y, yMax);
|
|
3397
|
+
return [x, y];
|
|
3398
|
+
});
|
|
3399
|
+
var items = map(cps, function (cp, idx) {
|
|
3400
|
+
return {
|
|
3401
|
+
cp: cp,
|
|
3402
|
+
z: hilbert(cp[0], cp[1], xMin, yMin, xMax, yMax),
|
|
3403
|
+
path: pathList[idx]
|
|
3404
|
+
};
|
|
3405
|
+
});
|
|
3406
|
+
return items.sort(function (a, b) { return a.z - b.z; }).map(function (item) { return item.path; });
|
|
3407
|
+
}
|
|
3408
|
+
function defaultDividePath(param) {
|
|
3409
|
+
return split(param.path, param.count);
|
|
3410
|
+
}
|
|
3411
|
+
function createEmptyReturn() {
|
|
3412
|
+
return {
|
|
3413
|
+
fromIndividuals: [],
|
|
3414
|
+
toIndividuals: [],
|
|
3415
|
+
count: 0
|
|
3416
|
+
};
|
|
3417
|
+
}
|
|
3418
|
+
function combineMorph(fromList, toPath, animationOpts) {
|
|
3419
|
+
var fromPathList = [];
|
|
3420
|
+
function addFromPath(fromList) {
|
|
3421
|
+
for (var i = 0; i < fromList.length; i++) {
|
|
3422
|
+
var from = fromList[i];
|
|
3423
|
+
if (isCombineMorphing(from)) {
|
|
3424
|
+
addFromPath(from.childrenRef());
|
|
3425
|
+
}
|
|
3426
|
+
else if (from instanceof Path) {
|
|
3427
|
+
fromPathList.push(from);
|
|
3428
|
+
}
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
addFromPath(fromList);
|
|
3432
|
+
var separateCount = fromPathList.length;
|
|
3433
|
+
if (!separateCount) {
|
|
3434
|
+
return createEmptyReturn();
|
|
3435
|
+
}
|
|
3436
|
+
var dividePath = animationOpts.dividePath || defaultDividePath;
|
|
3437
|
+
var toSubPathList = dividePath({
|
|
3438
|
+
path: toPath, count: separateCount
|
|
3439
|
+
});
|
|
3440
|
+
if (toSubPathList.length !== separateCount) {
|
|
3441
|
+
console.error('Invalid morphing: unmatched splitted path');
|
|
3442
|
+
return createEmptyReturn();
|
|
3443
|
+
}
|
|
3444
|
+
fromPathList = sortPaths(fromPathList);
|
|
3445
|
+
toSubPathList = sortPaths(toSubPathList);
|
|
3446
|
+
var oldDone = animationOpts.done;
|
|
3447
|
+
var oldDuring = animationOpts.during;
|
|
3448
|
+
var individualDelay = animationOpts.individualDelay;
|
|
3449
|
+
var identityTransform = new Transformable();
|
|
3450
|
+
for (var i = 0; i < separateCount; i++) {
|
|
3451
|
+
var from = fromPathList[i];
|
|
3452
|
+
var to = toSubPathList[i];
|
|
3453
|
+
to.parent = toPath;
|
|
3454
|
+
to.copyTransform(identityTransform);
|
|
3455
|
+
if (!individualDelay) {
|
|
3456
|
+
prepareMorphPath(from, to);
|
|
3457
|
+
}
|
|
3458
|
+
}
|
|
3459
|
+
toPath.__isCombineMorphing = true;
|
|
3460
|
+
toPath.childrenRef = function () {
|
|
3461
|
+
return toSubPathList;
|
|
3462
|
+
};
|
|
3463
|
+
function addToSubPathListToZr(zr) {
|
|
3464
|
+
for (var i = 0; i < toSubPathList.length; i++) {
|
|
3465
|
+
toSubPathList[i].addSelfToZr(zr);
|
|
3466
|
+
}
|
|
3467
|
+
}
|
|
3468
|
+
saveAndModifyMethod(toPath, 'addSelfToZr', {
|
|
3469
|
+
after: function (zr) {
|
|
3470
|
+
addToSubPathListToZr(zr);
|
|
3471
|
+
}
|
|
3472
|
+
});
|
|
3473
|
+
saveAndModifyMethod(toPath, 'removeSelfFromZr', {
|
|
3474
|
+
after: function (zr) {
|
|
3475
|
+
for (var i = 0; i < toSubPathList.length; i++) {
|
|
3476
|
+
toSubPathList[i].removeSelfFromZr(zr);
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
});
|
|
3480
|
+
function restoreToPath() {
|
|
3481
|
+
toPath.__isCombineMorphing = false;
|
|
3482
|
+
toPath.__morphT = -1;
|
|
3483
|
+
toPath.childrenRef = null;
|
|
3484
|
+
restoreMethod(toPath, 'addSelfToZr');
|
|
3485
|
+
restoreMethod(toPath, 'removeSelfFromZr');
|
|
3486
|
+
}
|
|
3487
|
+
var toLen = toSubPathList.length;
|
|
3488
|
+
if (individualDelay) {
|
|
3489
|
+
var animating_1 = toLen;
|
|
3490
|
+
var eachDone = function () {
|
|
3491
|
+
animating_1--;
|
|
3492
|
+
if (animating_1 === 0) {
|
|
3493
|
+
restoreToPath();
|
|
3494
|
+
oldDone && oldDone();
|
|
3495
|
+
}
|
|
3496
|
+
};
|
|
3497
|
+
for (var i = 0; i < toLen; i++) {
|
|
3498
|
+
var indivdualAnimationOpts = individualDelay ? defaults({
|
|
3499
|
+
delay: (animationOpts.delay || 0) + individualDelay(i, toLen, fromPathList[i], toSubPathList[i]),
|
|
3500
|
+
done: eachDone
|
|
3501
|
+
}, animationOpts) : animationOpts;
|
|
3502
|
+
morphPath(fromPathList[i], toSubPathList[i], indivdualAnimationOpts);
|
|
3503
|
+
}
|
|
3504
|
+
}
|
|
3505
|
+
else {
|
|
3506
|
+
toPath.__morphT = 0;
|
|
3507
|
+
toPath.animateTo({
|
|
3508
|
+
__morphT: 1
|
|
3509
|
+
}, defaults({
|
|
3510
|
+
during: function (p) {
|
|
3511
|
+
for (var i = 0; i < toLen; i++) {
|
|
3512
|
+
var child = toSubPathList[i];
|
|
3513
|
+
child.__morphT = toPath.__morphT;
|
|
3514
|
+
child.dirtyShape();
|
|
3515
|
+
}
|
|
3516
|
+
oldDuring && oldDuring(p);
|
|
3517
|
+
},
|
|
3518
|
+
done: function () {
|
|
3519
|
+
restoreToPath();
|
|
3520
|
+
for (var i = 0; i < fromList.length; i++) {
|
|
3521
|
+
restoreMethod(fromList[i], 'updateTransform');
|
|
3522
|
+
}
|
|
3523
|
+
oldDone && oldDone();
|
|
3524
|
+
}
|
|
3525
|
+
}, animationOpts));
|
|
3526
|
+
}
|
|
3527
|
+
if (toPath.__zr) {
|
|
3528
|
+
addToSubPathListToZr(toPath.__zr);
|
|
3529
|
+
}
|
|
3530
|
+
return {
|
|
3531
|
+
fromIndividuals: fromPathList,
|
|
3532
|
+
toIndividuals: toSubPathList,
|
|
3533
|
+
count: toLen
|
|
3534
|
+
};
|
|
3535
|
+
}
|
|
3536
|
+
function separateMorph(fromPath, toPathList, animationOpts) {
|
|
3537
|
+
var toLen = toPathList.length;
|
|
3538
|
+
var fromPathList = [];
|
|
3539
|
+
var dividePath = animationOpts.dividePath || defaultDividePath;
|
|
3540
|
+
function addFromPath(fromList) {
|
|
3541
|
+
for (var i = 0; i < fromList.length; i++) {
|
|
3542
|
+
var from = fromList[i];
|
|
3543
|
+
if (isCombineMorphing(from)) {
|
|
3544
|
+
addFromPath(from.childrenRef());
|
|
3545
|
+
}
|
|
3546
|
+
else if (from instanceof Path) {
|
|
3547
|
+
fromPathList.push(from);
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
}
|
|
3551
|
+
if (isCombineMorphing(fromPath)) {
|
|
3552
|
+
addFromPath(fromPath.childrenRef());
|
|
3553
|
+
var fromLen = fromPathList.length;
|
|
3554
|
+
if (fromLen < toLen) {
|
|
3555
|
+
var k = 0;
|
|
3556
|
+
for (var i = fromLen; i < toLen; i++) {
|
|
3557
|
+
fromPathList.push(clonePath(fromPathList[k++ % fromLen]));
|
|
3558
|
+
}
|
|
3559
|
+
}
|
|
3560
|
+
fromPathList.length = toLen;
|
|
3561
|
+
}
|
|
3562
|
+
else {
|
|
3563
|
+
fromPathList = dividePath({ path: fromPath, count: toLen });
|
|
3564
|
+
var fromPathTransform = fromPath.getComputedTransform();
|
|
3565
|
+
for (var i = 0; i < fromPathList.length; i++) {
|
|
3566
|
+
fromPathList[i].setLocalTransform(fromPathTransform);
|
|
3567
|
+
}
|
|
3568
|
+
if (fromPathList.length !== toLen) {
|
|
3569
|
+
console.error('Invalid morphing: unmatched splitted path');
|
|
3570
|
+
return createEmptyReturn();
|
|
3571
|
+
}
|
|
3572
|
+
}
|
|
3573
|
+
fromPathList = sortPaths(fromPathList);
|
|
3574
|
+
toPathList = sortPaths(toPathList);
|
|
3575
|
+
var individualDelay = animationOpts.individualDelay;
|
|
3576
|
+
for (var i = 0; i < toLen; i++) {
|
|
3577
|
+
var indivdualAnimationOpts = individualDelay ? defaults({
|
|
3578
|
+
delay: (animationOpts.delay || 0) + individualDelay(i, toLen, fromPathList[i], toPathList[i])
|
|
3579
|
+
}, animationOpts) : animationOpts;
|
|
3580
|
+
morphPath(fromPathList[i], toPathList[i], indivdualAnimationOpts);
|
|
3581
|
+
}
|
|
3582
|
+
return {
|
|
3583
|
+
fromIndividuals: fromPathList,
|
|
3584
|
+
toIndividuals: toPathList,
|
|
3585
|
+
count: toPathList.length
|
|
3586
|
+
};
|
|
3587
|
+
}
|
|
3588
|
+
|
|
3589
|
+
function isMultiple(elements) {
|
|
3590
|
+
return isArray(elements[0]);
|
|
3591
|
+
}
|
|
3592
|
+
|
|
3593
|
+
function prepareMorphBatches(one, many) {
|
|
3594
|
+
var batches = [];
|
|
3595
|
+
var batchCount = one.length;
|
|
3596
|
+
|
|
3597
|
+
for (var i = 0; i < batchCount; i++) {
|
|
3598
|
+
batches.push({
|
|
3599
|
+
one: one[i],
|
|
3600
|
+
many: []
|
|
3601
|
+
});
|
|
3602
|
+
}
|
|
3603
|
+
|
|
3604
|
+
for (var i = 0; i < many.length; i++) {
|
|
3605
|
+
var len = many[i].length;
|
|
3606
|
+
var k = void 0;
|
|
3607
|
+
|
|
3608
|
+
for (k = 0; k < len; k++) {
|
|
3609
|
+
batches[k % batchCount].many.push(many[i][k]);
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
|
|
3613
|
+
var off = 0; // If one has more paths than each one of many. average them.
|
|
3614
|
+
|
|
3615
|
+
for (var i = batchCount - 1; i >= 0; i--) {
|
|
3616
|
+
if (!batches[i].many.length) {
|
|
3617
|
+
var moveFrom = batches[off].many;
|
|
3618
|
+
|
|
3619
|
+
if (moveFrom.length <= 1) {
|
|
3620
|
+
// Not enough
|
|
3621
|
+
// Start from the first one.
|
|
3622
|
+
if (off) {
|
|
3623
|
+
off = 0;
|
|
3624
|
+
} else {
|
|
3625
|
+
return batches;
|
|
3626
|
+
}
|
|
3627
|
+
}
|
|
3628
|
+
|
|
3629
|
+
var len = moveFrom.length;
|
|
3630
|
+
var mid = Math.ceil(len / 2);
|
|
3631
|
+
batches[i].many = moveFrom.slice(mid, len);
|
|
3632
|
+
batches[off].many = moveFrom.slice(0, mid);
|
|
3633
|
+
off++;
|
|
3634
|
+
}
|
|
3635
|
+
}
|
|
3636
|
+
|
|
3637
|
+
return batches;
|
|
3638
|
+
}
|
|
3639
|
+
|
|
3640
|
+
var pathDividers = {
|
|
3641
|
+
clone: function (params) {
|
|
3642
|
+
var ret = []; // Fitting the alpha
|
|
3643
|
+
|
|
3644
|
+
var approxOpacity = 1 - Math.pow(1 - params.path.style.opacity, 1 / params.count);
|
|
3645
|
+
|
|
3646
|
+
for (var i = 0; i < params.count; i++) {
|
|
3647
|
+
var cloned = clonePath(params.path);
|
|
3648
|
+
cloned.setStyle('opacity', approxOpacity);
|
|
3649
|
+
ret.push(cloned);
|
|
3650
|
+
}
|
|
3651
|
+
|
|
3652
|
+
return ret;
|
|
3653
|
+
},
|
|
3654
|
+
// Use the default divider
|
|
3655
|
+
split: null
|
|
3656
|
+
};
|
|
3657
|
+
function applyMorphAnimation(from, to, divideShape, seriesModel, dataIndex, animateOtherProps) {
|
|
3658
|
+
if (!from.length || !to.length) {
|
|
3659
|
+
return;
|
|
3660
|
+
}
|
|
3661
|
+
|
|
3662
|
+
var updateAnimationCfg = getAnimationConfig('update', seriesModel, dataIndex);
|
|
3663
|
+
|
|
3664
|
+
if (!(updateAnimationCfg && updateAnimationCfg.duration > 0)) {
|
|
3665
|
+
return;
|
|
3666
|
+
}
|
|
3667
|
+
|
|
3668
|
+
var animationDelay = seriesModel.getModel('universalTransition').get('delay');
|
|
3669
|
+
var animationCfg = Object.assign({
|
|
3670
|
+
// Need to setToFinal so the further calculation based on the style can be correct.
|
|
3671
|
+
// Like emphasis color.
|
|
3672
|
+
setToFinal: true
|
|
3673
|
+
}, updateAnimationCfg);
|
|
3674
|
+
var many;
|
|
3675
|
+
var one;
|
|
3676
|
+
|
|
3677
|
+
if (isMultiple(from)) {
|
|
3678
|
+
// manyToOne
|
|
3679
|
+
many = from;
|
|
3680
|
+
one = to;
|
|
3681
|
+
}
|
|
3682
|
+
|
|
3683
|
+
if (isMultiple(to)) {
|
|
3684
|
+
// oneToMany
|
|
3685
|
+
many = to;
|
|
3686
|
+
one = from;
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3689
|
+
function morphOneBatch(batch, fromIsMany, animateIndex, animateCount, forceManyOne) {
|
|
3690
|
+
var batchMany = batch.many;
|
|
3691
|
+
var batchOne = batch.one;
|
|
3692
|
+
|
|
3693
|
+
if (batchMany.length === 1 && !forceManyOne) {
|
|
3694
|
+
// Is one to one
|
|
3695
|
+
var batchFrom = fromIsMany ? batchMany[0] : batchOne;
|
|
3696
|
+
var batchTo = fromIsMany ? batchOne : batchMany[0];
|
|
3697
|
+
|
|
3698
|
+
if (isCombineMorphing(batchFrom)) {
|
|
3699
|
+
// Keep doing combine animation.
|
|
3700
|
+
morphOneBatch({
|
|
3701
|
+
many: [batchFrom],
|
|
3702
|
+
one: batchTo
|
|
3703
|
+
}, true, animateIndex, animateCount, true);
|
|
3704
|
+
} else {
|
|
3705
|
+
var individualAnimationCfg = animationDelay ? defaults({
|
|
3706
|
+
delay: animationDelay(animateIndex, animateCount)
|
|
3707
|
+
}, animationCfg) : animationCfg;
|
|
3708
|
+
morphPath(batchFrom, batchTo, individualAnimationCfg);
|
|
3709
|
+
animateOtherProps(batchFrom, batchTo, batchFrom, batchTo, individualAnimationCfg);
|
|
3710
|
+
}
|
|
3711
|
+
} else {
|
|
3712
|
+
var separateAnimationCfg = defaults({
|
|
3713
|
+
dividePath: pathDividers[divideShape],
|
|
3714
|
+
individualDelay: animationDelay && function (idx, count, fromPath, toPath) {
|
|
3715
|
+
return animationDelay(idx + animateIndex, animateCount);
|
|
3716
|
+
}
|
|
3717
|
+
}, animationCfg);
|
|
3718
|
+
|
|
3719
|
+
var _a = fromIsMany ? combineMorph(batchMany, batchOne, separateAnimationCfg) : separateMorph(batchOne, batchMany, separateAnimationCfg),
|
|
3720
|
+
fromIndividuals = _a.fromIndividuals,
|
|
3721
|
+
toIndividuals = _a.toIndividuals;
|
|
3722
|
+
|
|
3723
|
+
var count = fromIndividuals.length;
|
|
3724
|
+
|
|
3725
|
+
for (var k = 0; k < count; k++) {
|
|
3726
|
+
var individualAnimationCfg = animationDelay ? defaults({
|
|
3727
|
+
delay: animationDelay(k, count)
|
|
3728
|
+
}, animationCfg) : animationCfg;
|
|
3729
|
+
animateOtherProps(fromIndividuals[k], toIndividuals[k], fromIsMany ? batchMany[k] : batch.one, fromIsMany ? batch.one : batchMany[k], individualAnimationCfg);
|
|
3730
|
+
}
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
|
|
3734
|
+
var fromIsMany = many ? many === from // Is one to one. If the path number not match. also needs do merge and separate morphing.
|
|
3735
|
+
: from.length > to.length;
|
|
3736
|
+
var morphBatches = many ? prepareMorphBatches(one, many) : prepareMorphBatches(fromIsMany ? to : from, [fromIsMany ? from : to]);
|
|
3737
|
+
var animateCount = 0;
|
|
3738
|
+
|
|
3739
|
+
for (var i = 0; i < morphBatches.length; i++) {
|
|
3740
|
+
animateCount += morphBatches[i].many.length;
|
|
3741
|
+
}
|
|
3742
|
+
|
|
3743
|
+
var animateIndex = 0;
|
|
3744
|
+
|
|
3745
|
+
for (var i = 0; i < morphBatches.length; i++) {
|
|
3746
|
+
morphOneBatch(morphBatches[i], fromIsMany, animateIndex, animateCount);
|
|
3747
|
+
animateIndex += morphBatches[i].many.length;
|
|
3748
|
+
}
|
|
3749
|
+
}
|
|
3750
|
+
function getPathList(elements) {
|
|
3751
|
+
if (!elements) {
|
|
3752
|
+
return [];
|
|
3753
|
+
}
|
|
3754
|
+
|
|
3755
|
+
if (isArray(elements)) {
|
|
3756
|
+
var pathList_1 = [];
|
|
3757
|
+
|
|
3758
|
+
for (var i = 0; i < elements.length; i++) {
|
|
3759
|
+
pathList_1.push(getPathList(elements[i]));
|
|
3760
|
+
}
|
|
3761
|
+
|
|
3762
|
+
return pathList_1;
|
|
3763
|
+
}
|
|
3764
|
+
|
|
3765
|
+
var pathList = [];
|
|
3766
|
+
elements.traverse(function (el) {
|
|
3767
|
+
if (el instanceof Path && !el.disableMorphing && !el.invisible && !el.ignore) {
|
|
3768
|
+
pathList.push(el);
|
|
3769
|
+
}
|
|
3770
|
+
});
|
|
3771
|
+
return pathList;
|
|
3772
|
+
}
|
|
3773
|
+
|
|
3774
|
+
var DATA_COUNT_THRESHOLD = 1e4;
|
|
3775
|
+
var getUniversalTransitionGlobalStore = makeInner();
|
|
3776
|
+
|
|
3777
|
+
function getGroupIdDimension(data) {
|
|
3778
|
+
var dimensions = data.dimensions;
|
|
3779
|
+
|
|
3780
|
+
for (var i = 0; i < dimensions.length; i++) {
|
|
3781
|
+
var dimInfo = data.getDimensionInfo(dimensions[i]);
|
|
3782
|
+
|
|
3783
|
+
if (dimInfo && dimInfo.otherDims.itemGroupId === 0) {
|
|
3784
|
+
return dimensions[i];
|
|
3785
|
+
}
|
|
3786
|
+
}
|
|
3787
|
+
}
|
|
3788
|
+
|
|
3789
|
+
function flattenDataDiffItems(list) {
|
|
3790
|
+
var items = [];
|
|
3791
|
+
each(list, function (seriesInfo) {
|
|
3792
|
+
var data = seriesInfo.data;
|
|
3793
|
+
|
|
3794
|
+
if (data.count() > DATA_COUNT_THRESHOLD) {
|
|
3795
|
+
|
|
3796
|
+
return;
|
|
3797
|
+
}
|
|
3798
|
+
|
|
3799
|
+
var indices = data.getIndices();
|
|
3800
|
+
var groupDim = getGroupIdDimension(data);
|
|
3801
|
+
|
|
3802
|
+
for (var dataIndex = 0; dataIndex < indices.length; dataIndex++) {
|
|
3803
|
+
items.push({
|
|
3804
|
+
dataGroupId: seriesInfo.dataGroupId,
|
|
3805
|
+
data: data,
|
|
3806
|
+
dim: seriesInfo.dim || groupDim,
|
|
3807
|
+
divide: seriesInfo.divide,
|
|
3808
|
+
dataIndex: dataIndex
|
|
3809
|
+
});
|
|
3810
|
+
}
|
|
3811
|
+
});
|
|
3812
|
+
return items;
|
|
3813
|
+
}
|
|
3814
|
+
|
|
3815
|
+
function fadeInElement(newEl, newSeries, newIndex) {
|
|
3816
|
+
newEl.traverse(function (el) {
|
|
3817
|
+
if (el instanceof Path) {
|
|
3818
|
+
// TODO use fade in animation for target element.
|
|
3819
|
+
initProps(el, {
|
|
3820
|
+
style: {
|
|
3821
|
+
opacity: 0
|
|
3822
|
+
}
|
|
3823
|
+
}, newSeries, {
|
|
3824
|
+
dataIndex: newIndex,
|
|
3825
|
+
isFrom: true
|
|
3826
|
+
});
|
|
3827
|
+
}
|
|
3828
|
+
});
|
|
3829
|
+
}
|
|
3830
|
+
|
|
3831
|
+
function removeEl(el) {
|
|
3832
|
+
if (el.parent) {
|
|
3833
|
+
// Bake parent transform to element.
|
|
3834
|
+
// So it can still have proper transform to transition after it's removed.
|
|
3835
|
+
var computedTransform = el.getComputedTransform();
|
|
3836
|
+
el.setLocalTransform(computedTransform);
|
|
3837
|
+
el.parent.remove(el);
|
|
3838
|
+
}
|
|
3839
|
+
}
|
|
3840
|
+
|
|
3841
|
+
function stopAnimation(el) {
|
|
3842
|
+
el.stopAnimation();
|
|
3843
|
+
|
|
3844
|
+
if (el.isGroup) {
|
|
3845
|
+
el.traverse(function (child) {
|
|
3846
|
+
child.stopAnimation();
|
|
3847
|
+
});
|
|
3848
|
+
}
|
|
3849
|
+
}
|
|
3850
|
+
|
|
3851
|
+
function animateElementStyles(el, dataIndex, seriesModel) {
|
|
3852
|
+
var animationConfig = getAnimationConfig('update', seriesModel, dataIndex);
|
|
3853
|
+
animationConfig && el.traverse(function (child) {
|
|
3854
|
+
if (child instanceof Displayable) {
|
|
3855
|
+
var oldStyle = getOldStyle(child);
|
|
3856
|
+
|
|
3857
|
+
if (oldStyle) {
|
|
3858
|
+
child.animateFrom({
|
|
3859
|
+
style: oldStyle
|
|
3860
|
+
}, animationConfig);
|
|
3861
|
+
}
|
|
3862
|
+
}
|
|
3863
|
+
});
|
|
3864
|
+
}
|
|
3865
|
+
|
|
3866
|
+
function isAllIdSame(oldDiffItems, newDiffItems) {
|
|
3867
|
+
var len = oldDiffItems.length;
|
|
3868
|
+
|
|
3869
|
+
if (len !== newDiffItems.length) {
|
|
3870
|
+
return false;
|
|
3871
|
+
}
|
|
3872
|
+
|
|
3873
|
+
for (var i = 0; i < len; i++) {
|
|
3874
|
+
var oldItem = oldDiffItems[i];
|
|
3875
|
+
var newItem = newDiffItems[i];
|
|
3876
|
+
|
|
3877
|
+
if (oldItem.data.getId(oldItem.dataIndex) !== newItem.data.getId(newItem.dataIndex)) {
|
|
3878
|
+
return false;
|
|
3879
|
+
}
|
|
3880
|
+
}
|
|
3881
|
+
|
|
3882
|
+
return true;
|
|
3883
|
+
}
|
|
3884
|
+
|
|
3885
|
+
function transitionBetween(oldList, newList, api) {
|
|
3886
|
+
var oldDiffItems = flattenDataDiffItems(oldList);
|
|
3887
|
+
var newDiffItems = flattenDataDiffItems(newList);
|
|
3888
|
+
|
|
3889
|
+
function updateMorphingPathProps(from, to, rawFrom, rawTo, animationCfg) {
|
|
3890
|
+
if (rawFrom || from) {
|
|
3891
|
+
to.animateFrom({
|
|
3892
|
+
style: rawFrom && rawFrom !== from ? // dividingMethod like clone may override the style(opacity)
|
|
3893
|
+
// So extend it to raw style.
|
|
3894
|
+
extend(extend({}, rawFrom.style), from.style) : from.style
|
|
3895
|
+
}, animationCfg);
|
|
3896
|
+
}
|
|
3897
|
+
}
|
|
3898
|
+
|
|
3899
|
+
function findKeyDim(items) {
|
|
3900
|
+
for (var i = 0; i < items.length; i++) {
|
|
3901
|
+
if (items[i].dim) {
|
|
3902
|
+
return items[i].dim;
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
|
|
3907
|
+
var oldKeyDim = findKeyDim(oldDiffItems);
|
|
3908
|
+
var newKeyDim = findKeyDim(newDiffItems);
|
|
3909
|
+
var hasMorphAnimation = false;
|
|
3910
|
+
|
|
3911
|
+
function createKeyGetter(isOld, onlyGetId) {
|
|
3912
|
+
return function (diffItem) {
|
|
3913
|
+
var data = diffItem.data;
|
|
3914
|
+
var dataIndex = diffItem.dataIndex; // TODO if specified dim
|
|
3915
|
+
|
|
3916
|
+
if (onlyGetId) {
|
|
3917
|
+
return data.getId(dataIndex);
|
|
3918
|
+
} // Use group id as transition key by default.
|
|
3919
|
+
// So we can achieve multiple to multiple animation like drilldown / up naturally.
|
|
3920
|
+
// If group id not exits. Use id instead. If so, only one to one transition will be applied.
|
|
3921
|
+
|
|
3922
|
+
|
|
3923
|
+
var dataGroupId = diffItem.dataGroupId; // If specified key dimension(itemGroupId by default). Use this same dimension from other data.
|
|
3924
|
+
// PENDING: If only use key dimension of newData.
|
|
3925
|
+
|
|
3926
|
+
var keyDim = isOld ? oldKeyDim || newKeyDim : newKeyDim || oldKeyDim;
|
|
3927
|
+
var dimInfo = keyDim && data.getDimensionInfo(keyDim);
|
|
3928
|
+
var dimOrdinalMeta = dimInfo && dimInfo.ordinalMeta;
|
|
3929
|
+
|
|
3930
|
+
if (dimInfo) {
|
|
3931
|
+
// Get from encode.itemGroupId.
|
|
3932
|
+
var key = data.get(dimInfo.name, dataIndex);
|
|
3933
|
+
|
|
3934
|
+
if (dimOrdinalMeta) {
|
|
3935
|
+
return dimOrdinalMeta.categories[key] || key + '';
|
|
3936
|
+
}
|
|
3937
|
+
|
|
3938
|
+
return key + '';
|
|
3939
|
+
} // Get groupId from raw item. { groupId: '' }
|
|
3940
|
+
|
|
3941
|
+
|
|
3942
|
+
var itemVal = data.getRawDataItem(dataIndex);
|
|
3943
|
+
|
|
3944
|
+
if (itemVal && itemVal.groupId) {
|
|
3945
|
+
return itemVal.groupId + '';
|
|
3946
|
+
}
|
|
3947
|
+
|
|
3948
|
+
return dataGroupId || data.getId(dataIndex);
|
|
3949
|
+
};
|
|
3950
|
+
} // Use id if it's very likely to be an one to one animation
|
|
3951
|
+
// It's more robust than groupId
|
|
3952
|
+
// TODO Check if key dimension is specified.
|
|
3953
|
+
|
|
3954
|
+
|
|
3955
|
+
var useId = isAllIdSame(oldDiffItems, newDiffItems);
|
|
3956
|
+
var isElementStillInChart = {};
|
|
3957
|
+
|
|
3958
|
+
if (!useId) {
|
|
3959
|
+
// We may have different diff strategy with basicTransition if we use other dimension as key.
|
|
3960
|
+
// If so, we can't simply check if oldEl is same with newEl. We need a map to check if oldEl is still being used in the new chart.
|
|
3961
|
+
// We can't use the elements that already being morphed. Let it keep it's original basic transition.
|
|
3962
|
+
for (var i = 0; i < newDiffItems.length; i++) {
|
|
3963
|
+
var newItem = newDiffItems[i];
|
|
3964
|
+
var el = newItem.data.getItemGraphicEl(newItem.dataIndex);
|
|
3965
|
+
|
|
3966
|
+
if (el) {
|
|
3967
|
+
isElementStillInChart[el.id] = true;
|
|
3968
|
+
}
|
|
3969
|
+
}
|
|
3970
|
+
}
|
|
3971
|
+
|
|
3972
|
+
function updateOneToOne(newIndex, oldIndex) {
|
|
3973
|
+
var oldItem = oldDiffItems[oldIndex];
|
|
3974
|
+
var newItem = newDiffItems[newIndex];
|
|
3975
|
+
var newSeries = newItem.data.hostModel; // TODO Mark this elements is morphed and don't morph them anymore
|
|
3976
|
+
|
|
3977
|
+
var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex);
|
|
3978
|
+
var newEl = newItem.data.getItemGraphicEl(newItem.dataIndex); // Can't handle same elements.
|
|
3979
|
+
|
|
3980
|
+
if (oldEl === newEl) {
|
|
3981
|
+
newEl && animateElementStyles(newEl, newItem.dataIndex, newSeries);
|
|
3982
|
+
return;
|
|
3983
|
+
}
|
|
3984
|
+
|
|
3985
|
+
if ( // We can't use the elements that already being morphed
|
|
3986
|
+
oldEl && isElementStillInChart[oldEl.id]) {
|
|
3987
|
+
return;
|
|
3988
|
+
}
|
|
3989
|
+
|
|
3990
|
+
if (newEl) {
|
|
3991
|
+
// TODO: If keep animating the group in case
|
|
3992
|
+
// some of the elements don't want to be morphed.
|
|
3993
|
+
// TODO Label?
|
|
3994
|
+
stopAnimation(newEl);
|
|
3995
|
+
|
|
3996
|
+
if (oldEl) {
|
|
3997
|
+
stopAnimation(oldEl); // If old element is doing leaving animation. stop it and remove it immediately.
|
|
3998
|
+
|
|
3999
|
+
removeEl(oldEl);
|
|
4000
|
+
hasMorphAnimation = true;
|
|
4001
|
+
applyMorphAnimation(getPathList(oldEl), getPathList(newEl), newItem.divide, newSeries, newIndex, updateMorphingPathProps);
|
|
4002
|
+
} else {
|
|
4003
|
+
fadeInElement(newEl, newSeries, newIndex);
|
|
4004
|
+
}
|
|
4005
|
+
} // else keep oldEl leaving animation.
|
|
4006
|
+
|
|
4007
|
+
}
|
|
4008
|
+
|
|
4009
|
+
new DataDiffer(oldDiffItems, newDiffItems, createKeyGetter(true, useId), createKeyGetter(false, useId), null, 'multiple').update(updateOneToOne).updateManyToOne(function (newIndex, oldIndices) {
|
|
4010
|
+
var newItem = newDiffItems[newIndex];
|
|
4011
|
+
var newData = newItem.data;
|
|
4012
|
+
var newSeries = newData.hostModel;
|
|
4013
|
+
var newEl = newData.getItemGraphicEl(newItem.dataIndex);
|
|
4014
|
+
var oldElsList = filter(map(oldIndices, function (idx) {
|
|
4015
|
+
return oldDiffItems[idx].data.getItemGraphicEl(oldDiffItems[idx].dataIndex);
|
|
4016
|
+
}), function (oldEl) {
|
|
4017
|
+
return oldEl && oldEl !== newEl && !isElementStillInChart[oldEl.id];
|
|
4018
|
+
});
|
|
4019
|
+
|
|
4020
|
+
if (newEl) {
|
|
4021
|
+
stopAnimation(newEl);
|
|
4022
|
+
|
|
4023
|
+
if (oldElsList.length) {
|
|
4024
|
+
// If old element is doing leaving animation. stop it and remove it immediately.
|
|
4025
|
+
each(oldElsList, function (oldEl) {
|
|
4026
|
+
stopAnimation(oldEl);
|
|
4027
|
+
removeEl(oldEl);
|
|
4028
|
+
});
|
|
4029
|
+
hasMorphAnimation = true;
|
|
4030
|
+
applyMorphAnimation(getPathList(oldElsList), getPathList(newEl), newItem.divide, newSeries, newIndex, updateMorphingPathProps);
|
|
4031
|
+
} else {
|
|
4032
|
+
fadeInElement(newEl, newSeries, newItem.dataIndex);
|
|
4033
|
+
}
|
|
4034
|
+
} // else keep oldEl leaving animation.
|
|
4035
|
+
|
|
4036
|
+
}).updateOneToMany(function (newIndices, oldIndex) {
|
|
4037
|
+
var oldItem = oldDiffItems[oldIndex];
|
|
4038
|
+
var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex); // We can't use the elements that already being morphed
|
|
4039
|
+
|
|
4040
|
+
if (oldEl && isElementStillInChart[oldEl.id]) {
|
|
4041
|
+
return;
|
|
4042
|
+
}
|
|
4043
|
+
|
|
4044
|
+
var newElsList = filter(map(newIndices, function (idx) {
|
|
4045
|
+
return newDiffItems[idx].data.getItemGraphicEl(newDiffItems[idx].dataIndex);
|
|
4046
|
+
}), function (el) {
|
|
4047
|
+
return el && el !== oldEl;
|
|
4048
|
+
});
|
|
4049
|
+
var newSeris = newDiffItems[newIndices[0]].data.hostModel;
|
|
4050
|
+
|
|
4051
|
+
if (newElsList.length) {
|
|
4052
|
+
each(newElsList, function (newEl) {
|
|
4053
|
+
return stopAnimation(newEl);
|
|
4054
|
+
});
|
|
4055
|
+
|
|
4056
|
+
if (oldEl) {
|
|
4057
|
+
stopAnimation(oldEl); // If old element is doing leaving animation. stop it and remove it immediately.
|
|
4058
|
+
|
|
4059
|
+
removeEl(oldEl);
|
|
4060
|
+
hasMorphAnimation = true;
|
|
4061
|
+
applyMorphAnimation(getPathList(oldEl), getPathList(newElsList), oldItem.divide, // Use divide on old.
|
|
4062
|
+
newSeris, newIndices[0], updateMorphingPathProps);
|
|
4063
|
+
} else {
|
|
4064
|
+
each(newElsList, function (newEl) {
|
|
4065
|
+
return fadeInElement(newEl, newSeris, newIndices[0]);
|
|
4066
|
+
});
|
|
4067
|
+
}
|
|
4068
|
+
} // else keep oldEl leaving animation.
|
|
4069
|
+
|
|
4070
|
+
}).updateManyToMany(function (newIndices, oldIndices) {
|
|
4071
|
+
// If two data are same and both have groupId.
|
|
4072
|
+
// Normally they should be diff by id.
|
|
4073
|
+
new DataDiffer(oldIndices, newIndices, function (rawIdx) {
|
|
4074
|
+
return oldDiffItems[rawIdx].data.getId(oldDiffItems[rawIdx].dataIndex);
|
|
4075
|
+
}, function (rawIdx) {
|
|
4076
|
+
return newDiffItems[rawIdx].data.getId(newDiffItems[rawIdx].dataIndex);
|
|
4077
|
+
}).update(function (newIndex, oldIndex) {
|
|
4078
|
+
// Use the original index
|
|
4079
|
+
updateOneToOne(newIndices[newIndex], oldIndices[oldIndex]);
|
|
4080
|
+
}).execute();
|
|
4081
|
+
}).execute();
|
|
4082
|
+
|
|
4083
|
+
if (hasMorphAnimation) {
|
|
4084
|
+
each(newList, function (_a) {
|
|
4085
|
+
var data = _a.data;
|
|
4086
|
+
var seriesModel = data.hostModel;
|
|
4087
|
+
var view = seriesModel && api.getViewOfSeriesModel(seriesModel);
|
|
4088
|
+
var animationCfg = getAnimationConfig('update', seriesModel, 0); // use 0 index.
|
|
4089
|
+
|
|
4090
|
+
if (view && seriesModel.isAnimationEnabled() && animationCfg && animationCfg.duration > 0) {
|
|
4091
|
+
view.group.traverse(function (el) {
|
|
4092
|
+
if (el instanceof Path && !el.animators.length) {
|
|
4093
|
+
// We can't accept there still exists element that has no animation
|
|
4094
|
+
// if universalTransition is enabled
|
|
4095
|
+
el.animateFrom({
|
|
4096
|
+
style: {
|
|
4097
|
+
opacity: 0
|
|
4098
|
+
}
|
|
4099
|
+
}, animationCfg);
|
|
4100
|
+
}
|
|
4101
|
+
});
|
|
4102
|
+
}
|
|
4103
|
+
});
|
|
4104
|
+
}
|
|
4105
|
+
}
|
|
4106
|
+
|
|
4107
|
+
function getSeriesTransitionKey(series) {
|
|
4108
|
+
var seriesKey = series.getModel('universalTransition').get('seriesKey');
|
|
4109
|
+
|
|
4110
|
+
if (!seriesKey) {
|
|
4111
|
+
// Use series id by default.
|
|
4112
|
+
return series.id;
|
|
4113
|
+
}
|
|
4114
|
+
|
|
4115
|
+
return seriesKey;
|
|
4116
|
+
}
|
|
4117
|
+
|
|
4118
|
+
function convertArraySeriesKeyToString(seriesKey) {
|
|
4119
|
+
if (isArray(seriesKey)) {
|
|
4120
|
+
// Order independent.
|
|
4121
|
+
return seriesKey.sort().join(',');
|
|
4122
|
+
}
|
|
4123
|
+
|
|
4124
|
+
return seriesKey;
|
|
4125
|
+
}
|
|
4126
|
+
|
|
4127
|
+
function getDivideShapeFromData(data) {
|
|
4128
|
+
if (data.hostModel) {
|
|
4129
|
+
return data.hostModel.getModel('universalTransition').get('divideShape');
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
|
|
4133
|
+
function findTransitionSeriesBatches(globalStore, params) {
|
|
4134
|
+
var updateBatches = createHashMap();
|
|
4135
|
+
var oldDataMap = createHashMap(); // Map that only store key in array seriesKey.
|
|
4136
|
+
// Which is used to query the old data when transition from one to multiple series.
|
|
4137
|
+
|
|
4138
|
+
var oldDataMapForSplit = createHashMap();
|
|
4139
|
+
each(globalStore.oldSeries, function (series, idx) {
|
|
4140
|
+
var oldDataGroupId = globalStore.oldDataGroupIds[idx];
|
|
4141
|
+
var oldData = globalStore.oldData[idx];
|
|
4142
|
+
var transitionKey = getSeriesTransitionKey(series);
|
|
4143
|
+
var transitionKeyStr = convertArraySeriesKeyToString(transitionKey);
|
|
4144
|
+
oldDataMap.set(transitionKeyStr, {
|
|
4145
|
+
dataGroupId: oldDataGroupId,
|
|
4146
|
+
data: oldData
|
|
4147
|
+
});
|
|
4148
|
+
|
|
4149
|
+
if (isArray(transitionKey)) {
|
|
4150
|
+
// Same key can't in different array seriesKey.
|
|
4151
|
+
each(transitionKey, function (key) {
|
|
4152
|
+
oldDataMapForSplit.set(key, {
|
|
4153
|
+
key: transitionKeyStr,
|
|
4154
|
+
dataGroupId: oldDataGroupId,
|
|
4155
|
+
data: oldData
|
|
4156
|
+
});
|
|
4157
|
+
});
|
|
4158
|
+
}
|
|
4159
|
+
});
|
|
4160
|
+
|
|
4161
|
+
each(params.updatedSeries, function (series) {
|
|
4162
|
+
if (series.isUniversalTransitionEnabled() && series.isAnimationEnabled()) {
|
|
4163
|
+
var newDataGroupId = series.get('dataGroupId');
|
|
4164
|
+
var newData = series.getData();
|
|
4165
|
+
var transitionKey = getSeriesTransitionKey(series);
|
|
4166
|
+
var transitionKeyStr = convertArraySeriesKeyToString(transitionKey); // Only transition between series with same id.
|
|
4167
|
+
|
|
4168
|
+
var oldData = oldDataMap.get(transitionKeyStr); // string transition key is the best match.
|
|
4169
|
+
|
|
4170
|
+
if (oldData) {
|
|
4171
|
+
|
|
4172
|
+
|
|
4173
|
+
updateBatches.set(transitionKeyStr, {
|
|
4174
|
+
oldSeries: [{
|
|
4175
|
+
dataGroupId: oldData.dataGroupId,
|
|
4176
|
+
divide: getDivideShapeFromData(oldData.data),
|
|
4177
|
+
data: oldData.data
|
|
4178
|
+
}],
|
|
4179
|
+
newSeries: [{
|
|
4180
|
+
dataGroupId: newDataGroupId,
|
|
4181
|
+
divide: getDivideShapeFromData(newData),
|
|
4182
|
+
data: newData
|
|
4183
|
+
}]
|
|
4184
|
+
});
|
|
4185
|
+
} else {
|
|
4186
|
+
// Transition from multiple series.
|
|
4187
|
+
if (isArray(transitionKey)) {
|
|
4188
|
+
|
|
4189
|
+
var oldSeries_1 = [];
|
|
4190
|
+
each(transitionKey, function (key) {
|
|
4191
|
+
var oldData = oldDataMap.get(key);
|
|
4192
|
+
|
|
4193
|
+
if (oldData.data) {
|
|
4194
|
+
oldSeries_1.push({
|
|
4195
|
+
dataGroupId: oldData.dataGroupId,
|
|
4196
|
+
divide: getDivideShapeFromData(oldData.data),
|
|
4197
|
+
data: oldData.data
|
|
4198
|
+
});
|
|
4199
|
+
}
|
|
4200
|
+
});
|
|
4201
|
+
|
|
4202
|
+
if (oldSeries_1.length) {
|
|
4203
|
+
updateBatches.set(transitionKeyStr, {
|
|
4204
|
+
oldSeries: oldSeries_1,
|
|
4205
|
+
newSeries: [{
|
|
4206
|
+
dataGroupId: newDataGroupId,
|
|
4207
|
+
data: newData,
|
|
4208
|
+
divide: getDivideShapeFromData(newData)
|
|
4209
|
+
}]
|
|
4210
|
+
});
|
|
4211
|
+
}
|
|
4212
|
+
} else {
|
|
4213
|
+
// Try transition to multiple series.
|
|
4214
|
+
var oldData_1 = oldDataMapForSplit.get(transitionKey);
|
|
4215
|
+
|
|
4216
|
+
if (oldData_1) {
|
|
4217
|
+
var batch = updateBatches.get(oldData_1.key);
|
|
4218
|
+
|
|
4219
|
+
if (!batch) {
|
|
4220
|
+
batch = {
|
|
4221
|
+
oldSeries: [{
|
|
4222
|
+
dataGroupId: oldData_1.dataGroupId,
|
|
4223
|
+
data: oldData_1.data,
|
|
4224
|
+
divide: getDivideShapeFromData(oldData_1.data)
|
|
4225
|
+
}],
|
|
4226
|
+
newSeries: []
|
|
4227
|
+
};
|
|
4228
|
+
updateBatches.set(oldData_1.key, batch);
|
|
4229
|
+
}
|
|
4230
|
+
|
|
4231
|
+
batch.newSeries.push({
|
|
4232
|
+
dataGroupId: newDataGroupId,
|
|
4233
|
+
data: newData,
|
|
4234
|
+
divide: getDivideShapeFromData(newData)
|
|
4235
|
+
});
|
|
4236
|
+
}
|
|
4237
|
+
}
|
|
4238
|
+
}
|
|
4239
|
+
}
|
|
4240
|
+
});
|
|
4241
|
+
return updateBatches;
|
|
4242
|
+
}
|
|
4243
|
+
|
|
4244
|
+
function querySeries(series, finder) {
|
|
4245
|
+
for (var i = 0; i < series.length; i++) {
|
|
4246
|
+
var found = finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id;
|
|
4247
|
+
|
|
4248
|
+
if (found) {
|
|
4249
|
+
return i;
|
|
4250
|
+
}
|
|
4251
|
+
}
|
|
4252
|
+
}
|
|
4253
|
+
|
|
4254
|
+
function transitionSeriesFromOpt(transitionOpt, globalStore, params, api) {
|
|
4255
|
+
var from = [];
|
|
4256
|
+
var to = [];
|
|
4257
|
+
each(normalizeToArray(transitionOpt.from), function (finder) {
|
|
4258
|
+
var idx = querySeries(globalStore.oldSeries, finder);
|
|
4259
|
+
|
|
4260
|
+
if (idx >= 0) {
|
|
4261
|
+
from.push({
|
|
4262
|
+
dataGroupId: globalStore.oldDataGroupIds[idx],
|
|
4263
|
+
data: globalStore.oldData[idx],
|
|
4264
|
+
// TODO can specify divideShape in transition.
|
|
4265
|
+
divide: getDivideShapeFromData(globalStore.oldData[idx]),
|
|
4266
|
+
dim: finder.dimension
|
|
4267
|
+
});
|
|
4268
|
+
}
|
|
4269
|
+
});
|
|
4270
|
+
each(normalizeToArray(transitionOpt.to), function (finder) {
|
|
4271
|
+
var idx = querySeries(params.updatedSeries, finder);
|
|
4272
|
+
|
|
4273
|
+
if (idx >= 0) {
|
|
4274
|
+
var data = params.updatedSeries[idx].getData();
|
|
4275
|
+
to.push({
|
|
4276
|
+
dataGroupId: globalStore.oldDataGroupIds[idx],
|
|
4277
|
+
data: data,
|
|
4278
|
+
divide: getDivideShapeFromData(data),
|
|
4279
|
+
dim: finder.dimension
|
|
4280
|
+
});
|
|
4281
|
+
}
|
|
4282
|
+
});
|
|
4283
|
+
|
|
4284
|
+
if (from.length > 0 && to.length > 0) {
|
|
4285
|
+
transitionBetween(from, to, api);
|
|
4286
|
+
}
|
|
4287
|
+
}
|
|
4288
|
+
|
|
4289
|
+
function installUniversalTransition(registers) {
|
|
4290
|
+
registers.registerUpdateLifecycle('series:beforeupdate', function (ecMOdel, api, params) {
|
|
4291
|
+
each(normalizeToArray(params.seriesTransition), function (transOpt) {
|
|
4292
|
+
each(normalizeToArray(transOpt.to), function (finder) {
|
|
4293
|
+
var series = params.updatedSeries;
|
|
4294
|
+
|
|
4295
|
+
for (var i = 0; i < series.length; i++) {
|
|
4296
|
+
if (finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id) {
|
|
4297
|
+
series[i][SERIES_UNIVERSAL_TRANSITION_PROP] = true;
|
|
4298
|
+
}
|
|
4299
|
+
}
|
|
4300
|
+
});
|
|
4301
|
+
});
|
|
4302
|
+
});
|
|
4303
|
+
registers.registerUpdateLifecycle('series:transition', function (ecModel, api, params) {
|
|
4304
|
+
// TODO api provide an namespace that can save stuff per instance
|
|
4305
|
+
var globalStore = getUniversalTransitionGlobalStore(api); // TODO multiple to multiple series.
|
|
4306
|
+
|
|
4307
|
+
if (globalStore.oldSeries && params.updatedSeries && params.optionChanged) {
|
|
4308
|
+
// Use give transition config if its' give;
|
|
4309
|
+
var transitionOpt = params.seriesTransition;
|
|
4310
|
+
|
|
4311
|
+
if (transitionOpt) {
|
|
4312
|
+
each(normalizeToArray(transitionOpt), function (opt) {
|
|
4313
|
+
transitionSeriesFromOpt(opt, globalStore, params, api);
|
|
4314
|
+
});
|
|
4315
|
+
} else {
|
|
4316
|
+
// Else guess from series based on transition series key.
|
|
4317
|
+
var updateBatches_1 = findTransitionSeriesBatches(globalStore, params);
|
|
4318
|
+
each(updateBatches_1.keys(), function (key) {
|
|
4319
|
+
var batch = updateBatches_1.get(key);
|
|
4320
|
+
transitionBetween(batch.oldSeries, batch.newSeries, api);
|
|
4321
|
+
});
|
|
4322
|
+
} // Reset
|
|
4323
|
+
|
|
4324
|
+
|
|
4325
|
+
each(params.updatedSeries, function (series) {
|
|
4326
|
+
// Reset;
|
|
4327
|
+
if (series[SERIES_UNIVERSAL_TRANSITION_PROP]) {
|
|
4328
|
+
series[SERIES_UNIVERSAL_TRANSITION_PROP] = false;
|
|
4329
|
+
}
|
|
4330
|
+
});
|
|
4331
|
+
} // Save all series of current update. Not only the updated one.
|
|
4332
|
+
|
|
4333
|
+
|
|
4334
|
+
var allSeries = ecModel.getSeries();
|
|
4335
|
+
var savedSeries = globalStore.oldSeries = [];
|
|
4336
|
+
var savedDataGroupIds = globalStore.oldDataGroupIds = [];
|
|
4337
|
+
var savedData = globalStore.oldData = [];
|
|
4338
|
+
|
|
4339
|
+
for (var i = 0; i < allSeries.length; i++) {
|
|
4340
|
+
var data = allSeries[i].getData(); // Only save the data that can have transition.
|
|
4341
|
+
// Avoid large data costing too much extra memory
|
|
4342
|
+
|
|
4343
|
+
if (data.count() < DATA_COUNT_THRESHOLD) {
|
|
4344
|
+
savedSeries.push(allSeries[i]);
|
|
4345
|
+
savedDataGroupIds.push(allSeries[i].get('dataGroupId'));
|
|
4346
|
+
savedData.push(data);
|
|
4347
|
+
}
|
|
4348
|
+
}
|
|
4349
|
+
});
|
|
4350
|
+
}
|
|
4351
|
+
|
|
4352
|
+
const stylesCss = "*{box-sizing:border-box}*:active{outline:none}*:focus{outline:none;box-shadow:var(--const-double-focus-ring, 0 0 0 2px #ffffff, 0 0 0 4px #33b4ff #06C)}:host{box-shadow:none !important}::-moz-focus-inner{border:none}input,textarea,button{font-family:inherit;font-size:inherit;font-stretch:inherit}:host(.sr),:host(.sr) button{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.sr,.sr button{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;white-space:nowrap}.hidden{display:none}:host([hidden]){display:none}.invisible{visibility:hidden}:host{width:var(--tct-area-chart-width, 100%);height:var(--tct-area-chart-height, 100%);display:block}.container{width:100%;height:100%}.chart-container{width:100%;height:100%}";
|
|
4353
|
+
|
|
4354
|
+
use([install$1, install, install$2, installUniversalTransition, install$3, install$4]);
|
|
4355
|
+
const Q2ChartArea$1 = /*@__PURE__*/ proxyCustomElement(class extends HTMLElement {
|
|
4356
|
+
constructor() {
|
|
4357
|
+
super();
|
|
4358
|
+
this.__registerHost();
|
|
4359
|
+
this.__attachShadow();
|
|
4360
|
+
this.change = createEvent(this, "change", 7);
|
|
4361
|
+
this.data = [];
|
|
4362
|
+
this.alignChartName = undefined;
|
|
4363
|
+
this.chartName = undefined;
|
|
4364
|
+
this.lineColor = undefined;
|
|
4365
|
+
this.pointerLineColor = undefined;
|
|
4366
|
+
this.pointerLineStyle = undefined;
|
|
4367
|
+
this.areaColor = undefined;
|
|
4368
|
+
this.dataNamesOverflow = undefined;
|
|
4369
|
+
this.dataNamesWidth = undefined;
|
|
4370
|
+
this.format = undefined;
|
|
4371
|
+
this.formatModifier = undefined;
|
|
4372
|
+
this.hideNameAxisLabels = false;
|
|
4373
|
+
this.hideValueAxisLabels = false;
|
|
4374
|
+
this.offsetDataNames = false;
|
|
4375
|
+
this.offsetDataValues = false;
|
|
4376
|
+
this.showChartName = false;
|
|
4377
|
+
this.showDatapointLabels = false;
|
|
4378
|
+
this.showGradient = false;
|
|
4379
|
+
this.gridLines = undefined;
|
|
4380
|
+
}
|
|
4381
|
+
componentDidLoad() {
|
|
4382
|
+
const chart = init(this.chartContainer);
|
|
4383
|
+
this.chart = chart;
|
|
4384
|
+
this.resizeEventListener = () => this.resizeChart();
|
|
4385
|
+
window.addEventListener('resize', this.resizeEventListener);
|
|
4386
|
+
this.cacheComputedStyles();
|
|
4387
|
+
this.updateChart(chart);
|
|
4388
|
+
overrideFocus(this.hostElement);
|
|
4389
|
+
}
|
|
4390
|
+
disconnectedCallback() {
|
|
4391
|
+
window.removeEventListener('resize', this.resizeEventListener);
|
|
4392
|
+
}
|
|
4393
|
+
cacheComputedStyles() {
|
|
4394
|
+
this.chartContainerStyles = getComputedStyle(this.chartContainer);
|
|
4395
|
+
this.hostElementStyles = getComputedStyle(this.hostElement);
|
|
4396
|
+
}
|
|
4397
|
+
getAreaFill() {
|
|
4398
|
+
if (this.showGradient) {
|
|
4399
|
+
return {
|
|
4400
|
+
type: 'linear',
|
|
4401
|
+
x: 0,
|
|
4402
|
+
y: 0,
|
|
4403
|
+
x2: 0,
|
|
4404
|
+
y2: 1,
|
|
4405
|
+
colorStops: [
|
|
4406
|
+
{
|
|
4407
|
+
offset: 0,
|
|
4408
|
+
color: this.getColor(this.areaColor),
|
|
4409
|
+
},
|
|
4410
|
+
{
|
|
4411
|
+
offset: 1,
|
|
4412
|
+
color: 'white',
|
|
4413
|
+
},
|
|
4414
|
+
],
|
|
4415
|
+
global: false,
|
|
4416
|
+
};
|
|
4417
|
+
}
|
|
4418
|
+
return this.getColor(this.areaColor);
|
|
4419
|
+
}
|
|
4420
|
+
getColor(color) {
|
|
4421
|
+
const primaryColor = getCSSProperty('var(--t-primary)', this.chartContainerStyles, this.hostElementStyles);
|
|
4422
|
+
const cssColorProp = getCSSProperty(color, this.chartContainerStyles, this.hostElementStyles);
|
|
4423
|
+
if (cssColorProp)
|
|
4424
|
+
return cssColorProp;
|
|
4425
|
+
if (isValidColor(color))
|
|
4426
|
+
return color;
|
|
4427
|
+
return primaryColor;
|
|
4428
|
+
}
|
|
4429
|
+
updateChart(chart) {
|
|
4430
|
+
var _a;
|
|
4431
|
+
const decimals = ((_a = this.formatModifier) === null || _a === void 0 ? void 0 : _a.includes('dec')) ? this.formatModifier.replace('dec', '') : 0;
|
|
4432
|
+
const valueAxis = {
|
|
4433
|
+
type: 'value',
|
|
4434
|
+
axisLabel: {
|
|
4435
|
+
formatter: (value) => formatValue(value, {
|
|
4436
|
+
type: this.format,
|
|
4437
|
+
decimals,
|
|
4438
|
+
}),
|
|
4439
|
+
rotate: this.offsetDataValues ? 45 : 0,
|
|
4440
|
+
margin: this.offsetDataValues ? 15 : 8,
|
|
4441
|
+
show: !this.hideValueAxisLabels,
|
|
4442
|
+
},
|
|
4443
|
+
splitLine: {
|
|
4444
|
+
show: this.gridLines === 'horizontal' || !this.gridLines,
|
|
4445
|
+
},
|
|
4446
|
+
};
|
|
4447
|
+
const categoryAxis = {
|
|
4448
|
+
type: 'category',
|
|
4449
|
+
boundaryGap: false,
|
|
4450
|
+
data: this.data.map(datum => loc(datum.name) || ''),
|
|
4451
|
+
axisLabel: {
|
|
4452
|
+
rotate: this.offsetDataNames ? 45 : 0,
|
|
4453
|
+
margin: this.offsetDataNames ? 15 : 8,
|
|
4454
|
+
width: this.dataNamesWidth || 50,
|
|
4455
|
+
overflow: this.dataNamesOverflow || 'none',
|
|
4456
|
+
truncate: 'ellipsis',
|
|
4457
|
+
show: !this.hideNameAxisLabels,
|
|
4458
|
+
},
|
|
4459
|
+
axisLine: {
|
|
4460
|
+
show: !this.hideNameAxisLabels,
|
|
4461
|
+
},
|
|
4462
|
+
axisTick: {
|
|
4463
|
+
show: !this.hideNameAxisLabels,
|
|
4464
|
+
},
|
|
4465
|
+
axisPointer: {
|
|
4466
|
+
show: true,
|
|
4467
|
+
type: 'line',
|
|
4468
|
+
label: {
|
|
4469
|
+
show: false,
|
|
4470
|
+
formatter: (params) => {
|
|
4471
|
+
const dataIndex = params.seriesData[0].dataIndex;
|
|
4472
|
+
this.change.emit({
|
|
4473
|
+
index: dataIndex,
|
|
4474
|
+
data: this.data[dataIndex],
|
|
4475
|
+
});
|
|
4476
|
+
},
|
|
4477
|
+
},
|
|
4478
|
+
lineStyle: {
|
|
4479
|
+
color: this.getColor(this.pointerLineColor || 'var(--t-gray-10)'),
|
|
4480
|
+
type: this.pointerLineStyle || 'solid',
|
|
4481
|
+
width: 1.5,
|
|
4482
|
+
},
|
|
4483
|
+
z: 1,
|
|
4484
|
+
},
|
|
4485
|
+
splitLine: {
|
|
4486
|
+
show: this.gridLines === 'vertical',
|
|
4487
|
+
},
|
|
4488
|
+
};
|
|
4489
|
+
return chart.setOption({
|
|
4490
|
+
aria: {
|
|
4491
|
+
enabled: true,
|
|
4492
|
+
},
|
|
4493
|
+
title: {
|
|
4494
|
+
text: this.chartName,
|
|
4495
|
+
show: this.showChartName,
|
|
4496
|
+
left: this.alignChartName,
|
|
4497
|
+
},
|
|
4498
|
+
grid: {
|
|
4499
|
+
containLabel: true,
|
|
4500
|
+
},
|
|
4501
|
+
xAxis: categoryAxis,
|
|
4502
|
+
yAxis: valueAxis,
|
|
4503
|
+
series: [
|
|
4504
|
+
{
|
|
4505
|
+
data: this.data.map(datum => datum.value || 0),
|
|
4506
|
+
id: 'area',
|
|
4507
|
+
type: 'line',
|
|
4508
|
+
lineStyle: {
|
|
4509
|
+
color: this.getColor(this.lineColor),
|
|
4510
|
+
},
|
|
4511
|
+
itemStyle: {
|
|
4512
|
+
color: this.getColor(this.lineColor),
|
|
4513
|
+
},
|
|
4514
|
+
areaStyle: {
|
|
4515
|
+
color: this.getAreaFill(),
|
|
4516
|
+
},
|
|
4517
|
+
symbolSize: 10,
|
|
4518
|
+
showSymbol: false,
|
|
4519
|
+
label: {
|
|
4520
|
+
show: this.showDatapointLabels,
|
|
4521
|
+
position: 'right',
|
|
4522
|
+
formatter: (params) => {
|
|
4523
|
+
return formatValue(params.value, {
|
|
4524
|
+
type: this.format,
|
|
4525
|
+
decimals,
|
|
4526
|
+
});
|
|
4527
|
+
},
|
|
4528
|
+
},
|
|
4529
|
+
},
|
|
4530
|
+
],
|
|
4531
|
+
});
|
|
4532
|
+
}
|
|
4533
|
+
resizeChart() {
|
|
4534
|
+
this.chart.resize();
|
|
4535
|
+
}
|
|
4536
|
+
propsUpdates() {
|
|
4537
|
+
this.updateChart(this.chart);
|
|
4538
|
+
}
|
|
4539
|
+
render() {
|
|
4540
|
+
return (h("div", { class: "container" }, h("div", { ref: el => (this.chartContainer = el), class: "chart-container", "test-id": "areaChartContainer" })));
|
|
4541
|
+
}
|
|
4542
|
+
get hostElement() { return this; }
|
|
4543
|
+
static get watchers() { return {
|
|
4544
|
+
"data": ["propsUpdates"],
|
|
4545
|
+
"alignChartName": ["propsUpdates"],
|
|
4546
|
+
"chartName": ["propsUpdates"],
|
|
4547
|
+
"lineColor": ["propsUpdates"],
|
|
4548
|
+
"pointerLineColor": ["propsUpdates"],
|
|
4549
|
+
"pointerLineStyle": ["propsUpdates"],
|
|
4550
|
+
"areaColor": ["propsUpdates"],
|
|
4551
|
+
"dataNamesOverflow": ["propsUpdates"],
|
|
4552
|
+
"dataNamesWidth": ["propsUpdates"],
|
|
4553
|
+
"format": ["propsUpdates"],
|
|
4554
|
+
"formatModifier": ["propsUpdates"],
|
|
4555
|
+
"hideNameAxisLabels": ["propsUpdates"],
|
|
4556
|
+
"hideValueAxisLabels": ["propsUpdates"],
|
|
4557
|
+
"offsetDataNames": ["propsUpdates"],
|
|
4558
|
+
"offsetDataValues": ["propsUpdates"],
|
|
4559
|
+
"showChartName": ["propsUpdates"],
|
|
4560
|
+
"showDatapointLabels": ["propsUpdates"],
|
|
4561
|
+
"showGradient": ["propsUpdates"],
|
|
4562
|
+
"gridLines": ["propsUpdates"]
|
|
4563
|
+
}; }
|
|
4564
|
+
static get style() { return stylesCss; }
|
|
4565
|
+
}, [1, "q2-chart-area", {
|
|
4566
|
+
"data": [16],
|
|
4567
|
+
"alignChartName": [513, "align-chart-name"],
|
|
4568
|
+
"chartName": [513, "chart-name"],
|
|
4569
|
+
"lineColor": [513, "line-color"],
|
|
4570
|
+
"pointerLineColor": [513, "pointer-line-color"],
|
|
4571
|
+
"pointerLineStyle": [513, "pointer-line-style"],
|
|
4572
|
+
"areaColor": [513, "area-color"],
|
|
4573
|
+
"dataNamesOverflow": [513, "data-names-overflow"],
|
|
4574
|
+
"dataNamesWidth": [514, "data-names-width"],
|
|
4575
|
+
"format": [513],
|
|
4576
|
+
"formatModifier": [513, "format-modifier"],
|
|
4577
|
+
"hideNameAxisLabels": [516, "hide-name-axis-labels"],
|
|
4578
|
+
"hideValueAxisLabels": [516, "hide-value-axis-labels"],
|
|
4579
|
+
"offsetDataNames": [516, "offset-data-names"],
|
|
4580
|
+
"offsetDataValues": [516, "offset-data-values"],
|
|
4581
|
+
"showChartName": [516, "show-chart-name"],
|
|
4582
|
+
"showDatapointLabels": [516, "show-datapoint-labels"],
|
|
4583
|
+
"showGradient": [516, "show-gradient"],
|
|
4584
|
+
"gridLines": [513, "grid-lines"]
|
|
4585
|
+
}]);
|
|
4586
|
+
function defineCustomElement$1() {
|
|
4587
|
+
if (typeof customElements === "undefined") {
|
|
4588
|
+
return;
|
|
4589
|
+
}
|
|
4590
|
+
const components = ["q2-chart-area"];
|
|
4591
|
+
components.forEach(tagName => { switch (tagName) {
|
|
4592
|
+
case "q2-chart-area":
|
|
4593
|
+
if (!customElements.get(tagName)) {
|
|
4594
|
+
customElements.define(tagName, Q2ChartArea$1);
|
|
4595
|
+
}
|
|
4596
|
+
break;
|
|
4597
|
+
} });
|
|
4598
|
+
}
|
|
4599
|
+
defineCustomElement$1();
|
|
4600
|
+
|
|
4601
|
+
const Q2ChartArea = Q2ChartArea$1;
|
|
4602
|
+
const defineCustomElement = defineCustomElement$1;
|
|
4603
|
+
|
|
4604
|
+
export { Q2ChartArea, defineCustomElement };
|