You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2020/03/06 09:10:28 UTC
[incubator-echarts] branch typescript updated: ts: add types for
graph
This is an automated email from the ASF dual-hosted git repository.
shenyi pushed a commit to branch typescript
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
The following commit(s) were added to refs/heads/typescript by this push:
new f5d5466 ts: add types for graph
f5d5466 is described below
commit f5d5466844a9197fc8e15c1d1d9b7a40d73b1941
Author: pissang <bm...@gmail.com>
AuthorDate: Fri Mar 6 17:10:10 2020 +0800
ts: add types for graph
---
src/action/roamHelper.ts | 23 +-
src/chart/effectScatter/EffectScatterSeries.ts | 8 +-
src/chart/funnel/FunnelSeries.ts | 10 +-
src/chart/funnel/funnelLayout.ts | 8 +-
src/chart/graph.ts | 4 +-
src/chart/graph/GraphSeries.ts | 287 ++++++++--
src/chart/graph/GraphView.ts | 204 ++++---
src/chart/graph/adjustEdge.ts | 25 +-
src/chart/graph/backwardCompat.ts | 19 -
src/chart/graph/categoryFilter.ts | 12 +-
src/chart/graph/categoryVisual.ts | 12 +-
src/chart/graph/circularLayout.ts | 8 +-
src/chart/graph/circularLayoutHelper.ts | 36 +-
src/chart/graph/createView.ts | 23 +-
src/chart/graph/edgeVisual.ts | 13 +-
src/chart/graph/forceHelper.ts | 82 ++-
src/chart/graph/forceLayout.ts | 106 ++--
src/chart/graph/graphAction.ts | 15 +-
src/chart/graph/graphHelper.ts | 10 +-
src/chart/graph/simpleLayout.ts | 13 +-
src/chart/graph/simpleLayoutHelper.ts | 8 +-
src/chart/heatmap/HeatmapSeries.ts | 2 +-
src/chart/helper/Line.ts | 722 +++++++++++++------------
src/chart/helper/LineDraw.ts | 252 +++++----
src/chart/helper/LinePath.ts | 101 ++--
src/chart/helper/Symbol.ts | 2 +-
src/chart/line/LineSeries.ts | 6 +-
src/chart/map/MapSeries.ts | 12 +-
src/chart/pictorialBar.ts | 2 -
src/chart/pie/PieSeries.ts | 10 +-
src/chart/radar.ts | 2 -
src/chart/scatter/ScatterSeries.ts | 6 +-
src/chart/themeRiver.ts | 2 -
src/chart/tree.ts | 2 -
src/chart/treemap.ts | 2 -
src/component/helper/RoamController.ts | 4 +-
src/coord/View.ts | 2 +-
src/coord/geo/GeoModel.ts | 9 +-
src/data/Graph.ts | 12 +-
src/data/List.ts | 26 +-
src/data/Tree.ts | 2 +-
src/echarts.ts | 4 +-
src/model/Series.ts | 29 +-
src/model/mixin/dataFormat.ts | 7 -
src/util/format.ts | 17 +-
src/util/types.ts | 54 +-
src/visual/symbol.ts | 15 +-
47 files changed, 1331 insertions(+), 899 deletions(-)
diff --git a/src/action/roamHelper.ts b/src/action/roamHelper.ts
index 52892e4..f5d8305 100644
--- a/src/action/roamHelper.ts
+++ b/src/action/roamHelper.ts
@@ -17,15 +17,24 @@
* under the License.
*/
-// @ts-nocheck
+import View from '../coord/View';
+import { Payload } from '../util/types';
+
+export interface RoamPaylod extends Payload {
+ dx: number
+ dy: number
+ zoom: number
+ originX: number
+ originY: number
+}
-/**
- * @param {module:echarts/coord/View} view
- * @param {Object} payload
- * @param {Object} [zoomLimit]
- */
export function updateCenterAndZoom(
- view, payload, zoomLimit
+ view: View,
+ payload: RoamPaylod,
+ zoomLimit?: {
+ min?: number,
+ max?: number
+ }
) {
var previousZoom = view.getZoom();
var center = view.getCenter();
diff --git a/src/chart/effectScatter/EffectScatterSeries.ts b/src/chart/effectScatter/EffectScatterSeries.ts
index e8258e6..bbbb8d3 100644
--- a/src/chart/effectScatter/EffectScatterSeries.ts
+++ b/src/chart/effectScatter/EffectScatterSeries.ts
@@ -26,7 +26,7 @@ import {
SeriesOnCalendarOptionMixin,
SeriesOnGeoOptionMixin,
SeriesOnSingleOptionMixin,
- SeriesSymbolOptionMixin,
+ SymbolOptionMixin,
OptionDataValue,
ItemStyleOption,
LabelOption,
@@ -37,7 +37,7 @@ import List from '../../data/List';
type ScatterDataValue = OptionDataValue | OptionDataValue[]
-export interface EffectScatterDataItemOption {
+export interface EffectScatterDataItemOption extends SymbolOptionMixin {
name?: string
value?: ScatterDataValue
@@ -53,7 +53,7 @@ export interface EffectScatterDataItemOption {
export interface EffectScatterSeriesOption extends SeriesOption,
SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, SeriesOnCalendarOptionMixin,
- SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin, SeriesSymbolOptionMixin {
+ SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin, SymbolOptionMixin {
coordinateSystem?: string
@@ -93,7 +93,7 @@ class EffectScatterSeriesModel extends SeriesModel<EffectScatterSeriesOption> {
return createListFromArray(this.getSource(), this, {useEncodeDefaulter: true});
}
- defaultOption: EffectScatterSeriesOption = {
+ static defaultOption: EffectScatterSeriesOption = {
coordinateSystem: 'cartesian2d',
zlevel: 0,
z: 2,
diff --git a/src/chart/funnel/FunnelSeries.ts b/src/chart/funnel/FunnelSeries.ts
index 04792b3..9967d90 100644
--- a/src/chart/funnel/FunnelSeries.ts
+++ b/src/chart/funnel/FunnelSeries.ts
@@ -28,7 +28,7 @@ import {
BoxLayoutOptionMixin,
HorizontalAlign,
LabelOption,
- LabelLineOption,
+ LabelGuideLineOption,
ItemStyleOption,
OptionDataValueNumeric
} from '../../util/types';
@@ -48,12 +48,12 @@ interface FunnelDataItem {
itemStyle?: ItemStyleOption
label?: FunnelLabelOption
- labelLine?: LabelLineOption
+ labelLine?: LabelGuideLineOption
emphasis?: {
itemStyle?: ItemStyleOption
label?: FunnelLabelOption
- labelLine?: LabelLineOption
+ labelLine?: LabelGuideLineOption
}
}
@@ -76,12 +76,12 @@ export interface FunnelSeriesOption
funnelAlign?: HorizontalAlign
label?: FunnelLabelOption
- labelLine?: LabelLineOption
+ labelLine?: LabelGuideLineOption
itemStyle?: ItemStyleOption
emphasis?: {
label?: FunnelLabelOption
- labelLine?: LabelLineOption
+ labelLine?: LabelGuideLineOption
itemStyle?: ItemStyleOption
}
diff --git a/src/chart/funnel/funnelLayout.ts b/src/chart/funnel/funnelLayout.ts
index 6b4e0c6..78d838a 100644
--- a/src/chart/funnel/funnelLayout.ts
+++ b/src/chart/funnel/funnelLayout.ts
@@ -38,10 +38,10 @@ function getViewRect(seriesModel: FunnelSeriesModel, api: ExtensionAPI) {
function getSortedIndices(data: List, sort: FunnelSeriesOption['sort']) {
var valueDim = data.mapDimension('value');
- var valueArr = data.mapArray(valueDim, function (val) {
+ var valueArr = data.mapArray(valueDim, function (val: number) {
return val;
});
- var indices = [];
+ var indices: number[] = [];
var isAscending = sort === 'ascending';
for (var i = 0, len = data.count(); i < len; i++) {
indices[i] = i;
@@ -53,7 +53,9 @@ function getSortedIndices(data: List, sort: FunnelSeriesOption['sort']) {
}
else if (sort !== 'none') {
indices.sort(function (a, b) {
- return isAscending ? valueArr[a] - valueArr[b] : valueArr[b] - valueArr[a];
+ return isAscending
+ ? valueArr[a] - valueArr[b]
+ : valueArr[b] - valueArr[a];
});
}
return indices;
diff --git a/src/chart/graph.ts b/src/chart/graph.ts
index 9a390e9..6dcb736 100644
--- a/src/chart/graph.ts
+++ b/src/chart/graph.ts
@@ -17,8 +17,6 @@
* under the License.
*/
-// @ts-nocheck
-
import * as echarts from '../echarts';
import './graph/GraphSeries';
@@ -33,6 +31,7 @@ import simpleLayout from './graph/simpleLayout';
import circularLayout from './graph/circularLayout';
import forceLayout from './graph/forceLayout';
import createView from './graph/createView';
+import View from '../coord/View';
echarts.registerProcessor(categoryFilter);
@@ -46,5 +45,6 @@ echarts.registerLayout(forceLayout);
// Graph view coordinate system
echarts.registerCoordinateSystem('graphView', {
+ dimensions: View.dimensions,
create: createView
});
\ No newline at end of file
diff --git a/src/chart/graph/GraphSeries.ts b/src/chart/graph/GraphSeries.ts
index 4cd1339..a2be48d 100644
--- a/src/chart/graph/GraphSeries.ts
+++ b/src/chart/graph/GraphSeries.ts
@@ -17,9 +17,6 @@
* under the License.
*/
-// @ts-nocheck
-
-import * as echarts from '../../echarts';
import List from '../../data/List';
import * as zrUtil from 'zrender/src/core/util';
import {defaultEmphasis} from '../../util/model';
@@ -27,13 +24,198 @@ import Model from '../../model/Model';
import {encodeHTML} from '../../util/format';
import createGraphFromNodeEdge from '../helper/createGraphFromNodeEdge';
import LegendVisualProvider from '../../visual/LegendVisualProvider';
+import {
+ SeriesOption,
+ SeriesOnCartesianOptionMixin,
+ SeriesOnPolarOptionMixin,
+ SeriesOnCalendarOptionMixin,
+ SeriesOnGeoOptionMixin,
+ SeriesOnSingleOptionMixin,
+ OptionDataValue,
+ RoamOptionMixin,
+ LabelOption,
+ ItemStyleOption,
+ LineStyleOption,
+ SymbolOptionMixin,
+ BoxLayoutOptionMixin,
+ LabelFormatterCallback,
+ Dictionary
+} from '../../util/types';
+import SeriesModel from '../../model/Series';
+import Graph from '../../data/Graph';
+import GlobalModel from '../../model/Global';
+import { VectorArray } from 'zrender/src/core/vector';
+import { ForceLayoutInstance } from './forceLayout';
+
+type GraphDataValue = OptionDataValue | OptionDataValue[]
+
+interface GraphEdgeLineStyleOption extends LineStyleOption {
+ curveness: number
+}
+export interface GraphNodeItemOption extends SymbolOptionMixin {
+ id?: string
+ name?: string
+ value?: GraphDataValue
+
+ itemStyle?: ItemStyleOption
+ label?: LabelOption
+
+ emphasis?: {
+ itemStyle?: ItemStyleOption
+ label?: LabelOption
+ }
+
+ /**
+ * Fixed x position
+ */
+ x?: number
+ /**
+ * Fixed y position
+ */
+ y?: number
+
+ /**
+ * If this node is fixed during force layout.
+ */
+ fixed?: boolean
+
+ category?: number
+
+ draggable?: boolean
+
+ focusNodeAdjacency?: boolean
+}
+
+export interface GraphEdgeItemOption {
+ /**
+ * Name or index of source node.
+ */
+ source?: string | number
+ /**
+ * Name or index of target node.
+ */
+ target?: string | number
+
+ value?: number
+
+ lineStyle?: GraphEdgeLineStyleOption
+ label?: LabelOption
+
+ emphasis?: {
+ lineStyle?: GraphEdgeLineStyleOption
+ label?: LabelOption
+ }
+
+ /**
+ * Symbol of both line ends
+ */
+ symbol?: string | string[]
+
+ symbolSize?: number | number[]
+}
+
+export interface GraphCategoryItemOption extends SymbolOptionMixin {
+ name?: string
+
+ value?: OptionDataValue
+
+ itemStyle?: ItemStyleOption
+ label?: LabelOption
+
+ emphasis?: {
+ itemStyle?: ItemStyleOption
+ label?: LabelOption
+ }
+}
+
+interface GraphSeriesOption extends SeriesOption,
+ SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, SeriesOnCalendarOptionMixin,
+ SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin,
+ SymbolOptionMixin,
+ RoamOptionMixin,
+ BoxLayoutOptionMixin {
+
+ coordinateSystem?: string
+
+ hoverAnimation?: boolean
+ legendHoverLink?: boolean
+
+ layout?: 'none' | 'force' | 'circular'
+
+ data?: GraphNodeItemOption[]
+ nodes?: GraphNodeItemOption[]
+
+ edges?: GraphEdgeItemOption[]
+ links?: GraphEdgeItemOption[]
+
+ categories?: GraphCategoryItemOption[]
+
+ focusNodeAdjacency?: boolean
-var GraphSeries = echarts.extendSeriesModel({
+ /**
+ * Symbol size scale ratio in roam
+ */
+ nodeScaleRatio: 0.6,
+
+ draggable?: boolean
+
+ edgeSymbol: string | string[]
+ edgeSymbolSize: number | number[]
+
+ edgeLabel?: LabelOption & {
+ formatter?: LabelFormatterCallback | string
+ }
+ label?: LabelOption & {
+ formatter?: LabelFormatterCallback | string
+ }
+
+ itemStyle?: ItemStyleOption
+ lineStyle?: GraphEdgeLineStyleOption
+
+ emphasis?: {
+ label?: LabelOption
+ edgeLabel?: LabelOption
+ itemStyle?: ItemStyleOption
+ lineStyle?: LineStyleOption
+ }
- type: 'series.graph',
+ // Configuration of circular layout
+ circular?: {
+ rotateLabel?: boolean
+ }
+
+ // Configuration of force directed layout
+ force: {
+ initLayout: 'circular' | 'none'
+ // Node repulsion. Can be an array to represent range.
+ repulsion: number | number[]
+ gravity: number
+ // Initial friction
+ friction: number
+
+ // Edge length. Can be an array to represent range.
+ edgeLength: number | number[]
+
+ layoutAnimation: boolean
+ }
+}
+
+class GraphSeriesModel extends SeriesModel<GraphSeriesOption> {
+ static readonly type = 'series.graph'
+ readonly type = GraphSeriesModel.type
+
+ private _categoriesData: List
+ private _categoriesModels: Model<GraphCategoryItemOption>[]
+
+ /**
+ * Preserved points during layouting
+ */
+ preservedPoints?: Dictionary<VectorArray>
- init: function (option) {
- GraphSeries.superApply(this, 'init', arguments);
+ forceLayout?: ForceLayoutInstance
+
+ init(option: GraphSeriesOption) {
+ super.init.apply(this, arguments as any);
var self = this;
function getCategoriesData() {
@@ -47,22 +229,22 @@ var GraphSeries = echarts.extendSeriesModel({
this.fillDataTextStyle(option.edges || option.links);
this._updateCategoriesData();
- },
+ }
- mergeOption: function (option) {
- GraphSeries.superApply(this, 'mergeOption', arguments);
+ mergeOption(option: GraphSeriesOption) {
+ super.mergeOption.apply(this, arguments as any);
this.fillDataTextStyle(option.edges || option.links);
this._updateCategoriesData();
- },
+ }
- mergeDefaultAndTheme: function (option) {
- GraphSeries.superApply(this, 'mergeDefaultAndTheme', arguments);
+ mergeDefaultAndTheme(option: GraphSeriesOption) {
+ super.mergeDefaultAndTheme.apply(this, arguments as any);
defaultEmphasis(option, 'edgeLabel', ['show']);
- },
+ }
- getInitialData: function (option, ecModel) {
+ getInitialData(option: GraphSeriesOption, ecModel: GlobalModel) {
var edges = option.edges || option.links || [];
var nodes = option.data || option.nodes || [];
var self = this;
@@ -71,7 +253,7 @@ var GraphSeries = echarts.extendSeriesModel({
return createGraphFromNodeEdge(nodes, edges, this, true, beforeLink).data;
}
- function beforeLink(nodeData, edgeData) {
+ function beforeLink(nodeData: List, edgeData: List) {
// Overwrite nodeData.getItemModel to
nodeData.wrapMethod('getItemModel', function (model) {
var categoriesModels = self._categoriesModels;
@@ -91,7 +273,7 @@ var GraphSeries = echarts.extendSeriesModel({
edgeLabelModel.parentModel,
ecModel
);
- var emphasisEdgeLabelModel = self.getModel('emphasis.edgeLabel');
+ var emphasisEdgeLabelModel = self.getModel(['emphasis', 'edgeLabel']);
var emphasisFakeSeriesModel = new Model(
{emphasis: {label: emphasisEdgeLabelModel.option}},
emphasisEdgeLabelModel.parentModel,
@@ -103,42 +285,33 @@ var GraphSeries = echarts.extendSeriesModel({
return model;
});
- function edgeGetParent(path) {
- path = this.parsePath(path);
- return (path && path[0] === 'label')
+ function edgeGetParent(this: Model, path: string | string[]) {
+ const pathArr = this.parsePath(path);
+ return (pathArr && pathArr[0] === 'label')
? fakeSeriesModel
- : (path && path[0] === 'emphasis' && path[1] === 'label')
+ : (pathArr && pathArr[0] === 'emphasis' && pathArr[1] === 'label')
? emphasisFakeSeriesModel
: this.parentModel;
}
}
- },
+ }
- /**
- * @return {module:echarts/data/Graph}
- */
- getGraph: function () {
+ getGraph(): Graph {
return this.getData().graph;
- },
+ }
- /**
- * @return {module:echarts/data/List}
- */
- getEdgeData: function () {
+ getEdgeData(): List {
return this.getGraph().edgeData;
- },
+ }
- /**
- * @return {module:echarts/data/List}
- */
- getCategoriesData: function () {
+ getCategoriesData(): List {
return this._categoriesData;
- },
+ }
/**
* @override
*/
- formatTooltip: function (dataIndex, multipleSeries, dataType) {
+ formatTooltip(dataIndex: number, multipleSeries: boolean, dataType: string) {
if (dataType === 'edge') {
var nodeData = this.getData();
var params = this.getDataParams(dataIndex, dataType);
@@ -149,19 +322,19 @@ var GraphSeries = echarts.extendSeriesModel({
var html = [];
sourceName != null && html.push(sourceName);
targetName != null && html.push(targetName);
- html = encodeHTML(html.join(' > '));
+ var htmlStr = encodeHTML(html.join(' > '));
if (params.value) {
- html += ' : ' + encodeHTML(params.value);
+ htmlStr += ' : ' + encodeHTML(params.value);
}
- return html;
+ return htmlStr;
}
else { // dataType === 'node' or empty
- return GraphSeries.superApply(this, 'formatTooltip', arguments);
+ return super.formatTooltip.apply(this, arguments as any);
}
- },
+ }
- _updateCategoriesData: function () {
+ _updateCategoriesData() {
var categories = zrUtil.map(this.option.categories || [], function (category) {
// Data must has value
return category.value != null ? category : zrUtil.extend({
@@ -174,25 +347,25 @@ var GraphSeries = echarts.extendSeriesModel({
this._categoriesData = categoriesData;
this._categoriesModels = categoriesData.mapArray(function (idx) {
- return categoriesData.getItemModel(idx, true);
+ return categoriesData.getItemModel(idx);
});
- },
+ }
- setZoom: function (zoom) {
+ setZoom(zoom: number) {
this.option.zoom = zoom;
- },
+ }
- setCenter: function (center) {
+ setCenter(center: number[]) {
this.option.center = center;
- },
+ }
- isAnimationEnabled: function () {
- return GraphSeries.superCall(this, 'isAnimationEnabled')
+ isAnimationEnabled() {
+ return super.isAnimationEnabled()
// Not enable animation when do force layout
- && !(this.get('layout') === 'force' && this.get('force.layoutAnimation'));
- },
+ && !(this.get('layout') === 'force' && this.get(['force', 'layoutAnimation']));
+ }
- defaultOption: {
+ static defaultOption: GraphSeriesOption = {
zlevel: 0,
z: 2,
@@ -288,6 +461,6 @@ var GraphSeries = echarts.extendSeriesModel({
}
}
}
-});
+}
-export default GraphSeries;
\ No newline at end of file
+export default GraphSeriesModel;
\ No newline at end of file
diff --git a/src/chart/graph/GraphView.ts b/src/chart/graph/GraphView.ts
index da2e325..12f3f6a 100644
--- a/src/chart/graph/GraphView.ts
+++ b/src/chart/graph/GraphView.ts
@@ -17,9 +17,6 @@
* under the License.
*/
-// @ts-nocheck
-
-import * as echarts from '../../echarts';
import * as zrUtil from 'zrender/src/core/util';
import SymbolDraw from '../helper/SymbolDraw';
import LineDraw from '../helper/LineDraw';
@@ -29,20 +26,48 @@ import {onIrrelevantElement} from '../../component/helper/cursorHelper';
import * as graphic from '../../util/graphic';
import adjustEdge from './adjustEdge';
import {getNodeGlobalScale} from './graphHelper';
+import ChartView from '../../view/Chart';
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import GraphSeriesModel, { GraphNodeItemOption } from './GraphSeries';
+import { CoordinateSystem } from '../../coord/CoordinateSystem';
+import View from '../../coord/View';
+import { GraphNode, GraphEdge } from '../../data/Graph';
+import Displayable from 'zrender/src/graphic/Displayable';
+import Symbol from '../helper/Symbol';
+import Model from '../../model/Model';
+import { Payload } from '../../util/types';
+import { LineLabel } from '../helper/Line';
+
+const FOCUS_ADJACENCY = '__focusNodeAdjacency';
+const UNFOCUS_ADJACENCY = '__unfocusNodeAdjacency';
+
+const nodeOpacityPath = ['itemStyle', 'opacity'] as const;
+const lineOpacityPath = ['lineStyle', 'opacity'] as const;
+
+interface FocusNodePayload extends Payload {
+ dataIndex: number
+ edgeDataIndex: number
+}
-var FOCUS_ADJACENCY = '__focusNodeAdjacency';
-var UNFOCUS_ADJACENCY = '__unfocusNodeAdjacency';
-
-var nodeOpacityPath = ['itemStyle', 'opacity'];
-var lineOpacityPath = ['lineStyle', 'opacity'];
+function isViewCoordSys(coordSys: CoordinateSystem): coordSys is View {
+ return coordSys.type === 'view';
+}
-function getItemOpacity(item, opacityPath) {
+function getItemOpacity(
+ item: GraphNode | GraphEdge,
+ opacityPath: typeof nodeOpacityPath | typeof lineOpacityPath
+): number {
var opacity = item.getVisual('opacity');
return opacity != null ? opacity : item.getModel().get(opacityPath);
}
-function fadeOutItem(item, opacityPath, opacityRatio) {
- var el = item.getGraphicEl();
+function fadeOutItem(
+ item: GraphNode | GraphEdge,
+ opacityPath: typeof nodeOpacityPath | typeof lineOpacityPath,
+ opacityRatio?: number
+) {
+ var el = item.getGraphicEl() as Symbol; // TODO Symbol?
var opacity = getItemOpacity(item, opacityPath);
if (opacityRatio != null) {
@@ -51,7 +76,7 @@ function fadeOutItem(item, opacityPath, opacityRatio) {
}
el.downplay && el.downplay();
- el.traverse(function (child) {
+ el.traverse(function (child: LineLabel) {
if (!child.isGroup) {
var opct = child.lineLabelOriginalOpacity;
if (opct == null || opacityRatio != null) {
@@ -62,29 +87,54 @@ function fadeOutItem(item, opacityPath, opacityRatio) {
});
}
-function fadeInItem(item, opacityPath) {
+function fadeInItem(
+ item: GraphNode | GraphEdge,
+ opacityPath: typeof nodeOpacityPath | typeof lineOpacityPath
+) {
var opacity = getItemOpacity(item, opacityPath);
- var el = item.getGraphicEl();
+ var el = item.getGraphicEl() as Symbol;
// Should go back to normal opacity first, consider hoverLayer,
// where current state is copied to elMirror, and support
// emphasis opacity here.
- el.traverse(function (child) {
+ el.traverse(function (child: Displayable) {
!child.isGroup && child.setStyle('opacity', opacity);
});
el.highlight && el.highlight();
}
-export default echarts.extendChartView({
+class GraphView extends ChartView {
+
+ static readonly type = 'graph'
+ readonly type = GraphView.type
+
+ private _symbolDraw: SymbolDraw
+ private _lineDraw: LineDraw
+
+ private _controller: RoamController
+ private _controllerHost: {
+ target: graphic.Group
+ zoom?: number
+ zoomLimit?: {min?: number, max?: number}
+ }
+
+ private _firstRender: boolean
+
+ private _model: GraphSeriesModel
- type: 'graph',
+ private _layoutTimeout: number
+ private _unfocusDelayTimer: number
- init: function (ecModel, api) {
+ private _layouting: boolean
+
+ init(ecModel: GlobalModel, api: ExtensionAPI) {
var symbolDraw = new SymbolDraw();
var lineDraw = new LineDraw();
var group = this.group;
this._controller = new RoamController(api.getZr());
- this._controllerHost = {target: group};
+ this._controllerHost = {
+ target: group
+ };
group.add(symbolDraw.group);
group.add(lineDraw.group);
@@ -93,9 +143,9 @@ export default echarts.extendChartView({
this._lineDraw = lineDraw;
this._firstRender = true;
- },
+ }
- render: function (seriesModel, ecModel, api) {
+ render(seriesModel: GraphSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
var graphView = this;
var coordSys = seriesModel.coordinateSystem;
@@ -106,7 +156,7 @@ export default echarts.extendChartView({
var group = this.group;
- if (coordSys.type === 'view') {
+ if (isViewCoordSys(coordSys)) {
var groupNewProp = {
position: coordSys.position,
scale: coordSys.scale
@@ -133,18 +183,18 @@ export default echarts.extendChartView({
clearTimeout(this._layoutTimeout);
var forceLayout = seriesModel.forceLayout;
- var layoutAnimation = seriesModel.get('force.layoutAnimation');
+ var layoutAnimation = seriesModel.get(['force', 'layoutAnimation']);
if (forceLayout) {
this._startForceLayoutIteration(forceLayout, layoutAnimation);
}
- data.eachItemGraphicEl(function (el, idx) {
- var itemModel = data.getItemModel(idx);
+ data.eachItemGraphicEl((el: Symbol, idx) => {
+ var itemModel = data.getItemModel(idx) as Model<GraphNodeItemOption>;
// Update draggable
el.off('drag').off('dragend');
var draggable = itemModel.get('draggable');
if (draggable) {
- el.on('drag', function () {
+ el.on('drag', () => {
if (forceLayout) {
forceLayout.warmUp();
!this._layouting
@@ -153,19 +203,19 @@ export default echarts.extendChartView({
// Write position back to layout
data.setItemLayout(idx, el.position);
}
- }, this).on('dragend', function () {
+ }).on('dragend', () => {
if (forceLayout) {
forceLayout.setUnfixed(idx);
}
- }, this);
+ });
}
- el.setDraggable(draggable && forceLayout);
+ el.setDraggable(draggable && !!forceLayout);
- el[FOCUS_ADJACENCY] && el.off('mouseover', el[FOCUS_ADJACENCY]);
- el[UNFOCUS_ADJACENCY] && el.off('mouseout', el[UNFOCUS_ADJACENCY]);
+ (el as any)[FOCUS_ADJACENCY] && el.off('mouseover', (el as any)[FOCUS_ADJACENCY]);
+ (el as any)[UNFOCUS_ADJACENCY] && el.off('mouseout', (el as any)[UNFOCUS_ADJACENCY]);
if (itemModel.get('focusNodeAdjacency')) {
- el.on('mouseover', el[FOCUS_ADJACENCY] = function () {
+ el.on('mouseover', (el as any)[FOCUS_ADJACENCY] = function () {
graphView._clearTimer();
api.dispatchAction({
type: 'focusNodeAdjacency',
@@ -173,21 +223,21 @@ export default echarts.extendChartView({
dataIndex: el.dataIndex
});
});
- el.on('mouseout', el[UNFOCUS_ADJACENCY] = function () {
+ el.on('mouseout', (el as any)[UNFOCUS_ADJACENCY] = function () {
graphView._dispatchUnfocus(api);
});
}
- }, this);
+ });
data.graph.eachEdge(function (edge) {
var el = edge.getGraphicEl();
- el[FOCUS_ADJACENCY] && el.off('mouseover', el[FOCUS_ADJACENCY]);
- el[UNFOCUS_ADJACENCY] && el.off('mouseout', el[UNFOCUS_ADJACENCY]);
+ (el as any)[FOCUS_ADJACENCY] && el.off('mouseover', (el as any)[FOCUS_ADJACENCY]);
+ (el as any)[UNFOCUS_ADJACENCY] && el.off('mouseout', (el as any)[UNFOCUS_ADJACENCY]);
if (edge.getModel().get('focusNodeAdjacency')) {
- el.on('mouseover', el[FOCUS_ADJACENCY] = function () {
+ el.on('mouseover', (el as any)[FOCUS_ADJACENCY] = function () {
graphView._clearTimer();
api.dispatchAction({
type: 'focusNodeAdjacency',
@@ -195,17 +245,17 @@ export default echarts.extendChartView({
edgeDataIndex: edge.dataIndex
});
});
- el.on('mouseout', el[UNFOCUS_ADJACENCY] = function () {
+ el.on('mouseout', (el as any)[UNFOCUS_ADJACENCY] = function () {
graphView._dispatchUnfocus(api);
});
}
});
var circularRotateLabel = seriesModel.get('layout') === 'circular'
- && seriesModel.get('circular.rotateLabel');
+ && seriesModel.get(['circular', 'rotateLabel']);
var cx = data.getLayout('cx');
var cy = data.getLayout('cy');
- data.eachItemGraphicEl(function (el, idx) {
+ data.eachItemGraphicEl(function (el: Symbol, idx) {
var itemModel = data.getItemModel(idx);
var labelRotate = itemModel.get('label.rotate') || 0;
var symbolPath = el.getSymbolPath();
@@ -243,15 +293,15 @@ export default echarts.extendChartView({
});
this._firstRender = false;
- },
+ }
- dispose: function () {
+ dispose() {
this._controller && this._controller.dispose();
- this._controllerHost = {};
+ this._controllerHost = null;
this._clearTimer();
- },
+ }
- _dispatchUnfocus: function (api, opt) {
+ _dispatchUnfocus(api: ExtensionAPI) {
var self = this;
this._clearTimer();
this._unfocusDelayTimer = setTimeout(function () {
@@ -260,18 +310,23 @@ export default echarts.extendChartView({
type: 'unfocusNodeAdjacency',
seriesId: self._model.id
});
- }, 500);
+ }, 500) as any;
- },
+ }
- _clearTimer: function () {
+ _clearTimer() {
if (this._unfocusDelayTimer) {
clearTimeout(this._unfocusDelayTimer);
this._unfocusDelayTimer = null;
}
- },
+ }
- focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
+ focusNodeAdjacency(
+ seriesModel: GraphSeriesModel,
+ ecModel: GlobalModel,
+ api: ExtensionAPI,
+ payload: FocusNodePayload
+ ) {
var data = seriesModel.getData();
var graph = data.graph;
var dataIndex = payload.dataIndex;
@@ -307,9 +362,11 @@ export default echarts.extendChartView({
fadeInItem(edge.node1, nodeOpacityPath);
fadeInItem(edge.node2, nodeOpacityPath);
}
- },
+ }
- unfocusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
+ unfocusNodeAdjacency(
+ seriesModel: GraphSeriesModel
+ ) {
var graph = seriesModel.getData().graph;
graph.eachNode(function (node) {
@@ -318,23 +375,30 @@ export default echarts.extendChartView({
graph.eachEdge(function (edge) {
fadeOutItem(edge, lineOpacityPath);
});
- },
+ }
- _startForceLayoutIteration: function (forceLayout, layoutAnimation) {
+ _startForceLayoutIteration(
+ forceLayout: GraphSeriesModel['forceLayout'],
+ layoutAnimation?: boolean
+ ) {
var self = this;
(function step() {
forceLayout.step(function (stopped) {
self.updateLayout(self._model);
(self._layouting = !stopped) && (
layoutAnimation
- ? (self._layoutTimeout = setTimeout(step, 16))
+ ? (self._layoutTimeout = setTimeout(step, 16) as any)
: step()
);
});
})();
- },
+ }
- _updateController: function (seriesModel, ecModel, api) {
+ _updateController(
+ seriesModel: GraphSeriesModel,
+ ecModel: GlobalModel,
+ api: ExtensionAPI
+ ) {
var controller = this._controller;
var controllerHost = this._controllerHost;
var group = this.group;
@@ -346,7 +410,7 @@ export default echarts.extendChartView({
&& !onIrrelevantElement(e, api, seriesModel);
});
- if (seriesModel.coordinateSystem.type !== 'view') {
+ if (!isViewCoordSys(seriesModel.coordinateSystem)) {
controller.disable();
return;
}
@@ -357,7 +421,7 @@ export default echarts.extendChartView({
controller
.off('pan')
.off('zoom')
- .on('pan', function (e) {
+ .on('pan', (e) => {
roamHelper.updateViewOnPan(controllerHost, e.dx, e.dy);
api.dispatchAction({
seriesId: seriesModel.id,
@@ -366,7 +430,7 @@ export default echarts.extendChartView({
dy: e.dy
});
})
- .on('zoom', function (e) {
+ .on('zoom', (e) => {
roamHelper.updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY);
api.dispatchAction({
seriesId: seriesModel.id,
@@ -378,10 +442,10 @@ export default echarts.extendChartView({
this._updateNodeAndLinkScale();
adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));
this._lineDraw.updateLayout();
- }, this);
- },
+ });
+ }
- _updateNodeAndLinkScale: function () {
+ _updateNodeAndLinkScale() {
var seriesModel = this._model;
var data = seriesModel.getData();
@@ -391,17 +455,21 @@ export default echarts.extendChartView({
data.eachItemGraphicEl(function (el, idx) {
el.attr('scale', invScale);
});
- },
+ }
- updateLayout: function (seriesModel) {
+ updateLayout(seriesModel: GraphSeriesModel) {
adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel));
this._symbolDraw.updateLayout();
this._lineDraw.updateLayout();
- },
+ }
- remove: function (ecModel, api) {
+ remove(ecModel: GlobalModel, api: ExtensionAPI) {
this._symbolDraw && this._symbolDraw.remove();
this._lineDraw && this._lineDraw.remove();
}
-});
+}
+
+ChartView.registerClass(GraphView);
+
+export default GraphView;
\ No newline at end of file
diff --git a/src/chart/graph/adjustEdge.ts b/src/chart/graph/adjustEdge.ts
index 8c0588d..b8fa14e 100644
--- a/src/chart/graph/adjustEdge.ts
+++ b/src/chart/graph/adjustEdge.ts
@@ -17,19 +17,22 @@
* under the License.
*/
-// @ts-nocheck
-
import * as curveTool from 'zrender/src/core/curve';
import * as vec2 from 'zrender/src/core/vector';
import {getSymbolSize} from './graphHelper';
+import Graph from '../../data/Graph';
-var v1 = [];
-var v2 = [];
-var v3 = [];
+var v1: number[] = [];
+var v2: number[] = [];
+var v3: number[] = [];
var quadraticAt = curveTool.quadraticAt;
var v2DistSquare = vec2.distSquare;
var mathAbs = Math.abs;
-function intersectCurveCircle(curvePoints, center, radius) {
+function intersectCurveCircle(
+ curvePoints: number[][],
+ center: number[],
+ radius: number
+) {
var p0 = curvePoints[0];
var p1 = curvePoints[1];
var p2 = curvePoints[2];
@@ -92,12 +95,12 @@ function intersectCurveCircle(curvePoints, center, radius) {
}
// Adjust edge to avoid
-export default function (graph, scale) {
- var tmp0 = [];
+export default function (graph: Graph, scale: number) {
+ var tmp0: number[] = [];
var quadraticSubdivide = curveTool.quadraticSubdivide;
- var pts = [[], [], []];
- var pts2 = [[], []];
- var v = [];
+ var pts: number[][] = [[], [], []];
+ var pts2: number[][] = [[], []];
+ var v: number[] = [];
scale /= 2;
graph.eachEdge(function (edge, idx) {
diff --git a/src/chart/graph/backwardCompat.ts b/src/chart/graph/backwardCompat.ts
deleted file mode 100644
index 56c6a92..0000000
--- a/src/chart/graph/backwardCompat.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one
-* or more contributor license agreements. See the NOTICE file
-* distributed with this work for additional information
-* regarding copyright ownership. The ASF licenses this file
-* to you under the Apache License, Version 2.0 (the
-* "License"); you may not use this file except in compliance
-* with the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing,
-* software distributed under the License is distributed on an
-* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-* KIND, either express or implied. See the License for the
-* specific language governing permissions and limitations
-* under the License.
-*/
-
diff --git a/src/chart/graph/categoryFilter.ts b/src/chart/graph/categoryFilter.ts
index 836a34d..66b6b4e 100644
--- a/src/chart/graph/categoryFilter.ts
+++ b/src/chart/graph/categoryFilter.ts
@@ -17,16 +17,18 @@
* under the License.
*/
-// @ts-nocheck
+import GlobalModel from '../../model/Global';
+import GraphSeriesModel from './GraphSeries';
+import type LegendModel from '../../component/legend/LegendModel';
-export default function (ecModel) {
+export default function (ecModel: GlobalModel) {
var legendModels = ecModel.findComponents({
mainType: 'legend'
- });
+ }) as LegendModel[];
if (!legendModels || !legendModels.length) {
return;
}
- ecModel.eachSeriesByType('graph', function (graphSeries) {
+ ecModel.eachSeriesByType('graph', function (graphSeries: GraphSeriesModel) {
var categoriesData = graphSeries.getCategoriesData();
var graph = graphSeries.getGraph();
var data = graph.data;
@@ -49,5 +51,5 @@ export default function (ecModel) {
}
return true;
});
- }, this);
+ });
}
diff --git a/src/chart/graph/categoryVisual.ts b/src/chart/graph/categoryVisual.ts
index 31bec52..2ee40b1 100644
--- a/src/chart/graph/categoryVisual.ts
+++ b/src/chart/graph/categoryVisual.ts
@@ -17,16 +17,18 @@
* under the License.
*/
-// @ts-nocheck
+import GlobalModel from '../../model/Global';
+import GraphSeriesModel from './GraphSeries';
+import { Dictionary, ColorString } from '../../util/types';
-export default function (ecModel) {
+export default function (ecModel: GlobalModel) {
- var paletteScope = {};
- ecModel.eachSeriesByType('graph', function (seriesModel) {
+ var paletteScope: Dictionary<ColorString> = {};
+ ecModel.eachSeriesByType('graph', function (seriesModel: GraphSeriesModel) {
var categoriesData = seriesModel.getCategoriesData();
var data = seriesModel.getData();
- var categoryNameIdxMap = {};
+ var categoryNameIdxMap: Dictionary<number> = {};
categoriesData.each(function (idx) {
var name = categoriesData.getName(idx);
diff --git a/src/chart/graph/circularLayout.ts b/src/chart/graph/circularLayout.ts
index 5434728..8f1712a 100644
--- a/src/chart/graph/circularLayout.ts
+++ b/src/chart/graph/circularLayout.ts
@@ -17,12 +17,12 @@
* under the License.
*/
-// @ts-nocheck
-
import {circularLayout} from './circularLayoutHelper';
+import GlobalModel from '../../model/Global';
+import GraphSeriesModel from './GraphSeries';
-export default function (ecModel) {
- ecModel.eachSeriesByType('graph', function (seriesModel) {
+export default function (ecModel: GlobalModel) {
+ ecModel.eachSeriesByType('graph', function (seriesModel: GraphSeriesModel) {
if (seriesModel.get('layout') === 'circular') {
circularLayout(seriesModel, 'symbolSize');
}
diff --git a/src/chart/graph/circularLayoutHelper.ts b/src/chart/graph/circularLayoutHelper.ts
index 8d72c96..4919057 100644
--- a/src/chart/graph/circularLayoutHelper.ts
+++ b/src/chart/graph/circularLayoutHelper.ts
@@ -17,14 +17,16 @@
* under the License.
*/
-// @ts-nocheck
import * as vec2 from 'zrender/src/core/vector';
import {getSymbolSize, getNodeGlobalScale} from './graphHelper';
+import GraphSeriesModel from './GraphSeries';
+import Graph from '../../data/Graph';
+import List from '../../data/List';
var PI = Math.PI;
-var _symbolRadiansHalf = [];
+var _symbolRadiansHalf: number[] = [];
/**
* `basedOn` can be:
@@ -44,11 +46,11 @@ var _symbolRadiansHalf = [];
* FIXME
* If progressive rendering is applied to graph some day,
* probably we have to use `basedOn: 'value'`.
- *
- * @param {module:echarts/src/model/Series} seriesModel
- * @param {string} basedOn 'value' or 'symbolSize'
*/
-export function circularLayout(seriesModel, basedOn) {
+export function circularLayout(
+ seriesModel: GraphSeriesModel,
+ basedOn: 'value' | 'symbolSize'
+) {
var coordSys = seriesModel.coordinateSystem;
if (coordSys && coordSys.type !== 'view') {
return;
@@ -73,7 +75,7 @@ export function circularLayout(seriesModel, basedOn) {
return;
}
- _layoutNodesBasedOn[basedOn](seriesModel, coordSys, graph, nodeData, r, cx, cy, count);
+ _layoutNodesBasedOn[basedOn](seriesModel, graph, nodeData, r, cx, cy, count);
graph.eachEdge(function (edge) {
var curveness = edge.getModel().get('lineStyle.curveness') || 0;
@@ -93,15 +95,27 @@ export function circularLayout(seriesModel, basedOn) {
});
}
-var _layoutNodesBasedOn = {
+interface LayoutNode {
+ (
+ seriesModel: GraphSeriesModel,
+ graph: Graph,
+ nodeData: List,
+ r: number,
+ cx: number,
+ cy: number,
+ count: number
+ ): void
+}
+
+var _layoutNodesBasedOn: Record<'value' | 'symbolSize', LayoutNode> = {
- value: function (seriesModel, coordSys, graph, nodeData, r, cx, cy, count) {
+ value(seriesModel, graph, nodeData, r, cx, cy, count) {
var angle = 0;
var sum = nodeData.getSum('value');
var unitAngle = Math.PI * 2 / (sum || count);
graph.eachNode(function (node) {
- var value = node.getValue('value');
+ var value = node.getValue('value') as number;
var radianHalf = unitAngle * (sum ? value : 1) / 2;
angle += radianHalf;
@@ -113,7 +127,7 @@ var _layoutNodesBasedOn = {
});
},
- symbolSize: function (seriesModel, coordSys, graph, nodeData, r, cx, cy, count) {
+ symbolSize(seriesModel, graph, nodeData, r, cx, cy, count) {
var sumRadian = 0;
_symbolRadiansHalf.length = count;
diff --git a/src/chart/graph/createView.ts b/src/chart/graph/createView.ts
index a251a95..ceaa7ab 100644
--- a/src/chart/graph/createView.ts
+++ b/src/chart/graph/createView.ts
@@ -17,25 +17,28 @@
* under the License.
*/
-// @ts-nocheck
-
// FIXME Where to create the simple view coordinate system
import View from '../../coord/View';
import {getLayoutRect} from '../../util/layout';
import * as bbox from 'zrender/src/core/bbox';
+import GraphSeriesModel from './GraphSeries';
+import ExtensionAPI from '../../ExtensionAPI';
+import GlobalModel from '../../model/Global';
+import { extend } from 'zrender/src/core/util';
-function getViewRect(seriesModel, api, aspect) {
- var option = seriesModel.getBoxLayoutParams();
- option.aspect = aspect;
+function getViewRect(seriesModel: GraphSeriesModel, api: ExtensionAPI, aspect: number) {
+ var option = extend(seriesModel.getBoxLayoutParams(), {
+ aspect: aspect
+ });
return getLayoutRect(option, {
width: api.getWidth(),
height: api.getHeight()
});
}
-export default function (ecModel, api) {
- var viewList = [];
- ecModel.eachSeriesByType('graph', function (seriesModel) {
+export default function (ecModel: GlobalModel, api: ExtensionAPI) {
+ var viewList: View[] = [];
+ ecModel.eachSeriesByType('graph', function (seriesModel: GraphSeriesModel) {
var coordSysType = seriesModel.get('coordinateSystem');
if (!coordSysType || coordSysType === 'view') {
@@ -45,8 +48,8 @@ export default function (ecModel, api) {
return [+itemModel.get('x'), +itemModel.get('y')];
});
- var min = [];
- var max = [];
+ var min: number[] = [];
+ var max: number[] = [];
bbox.fromPoints(positions, min, max);
diff --git a/src/chart/graph/edgeVisual.ts b/src/chart/graph/edgeVisual.ts
index d2d430c..e5fb1d7 100644
--- a/src/chart/graph/edgeVisual.ts
+++ b/src/chart/graph/edgeVisual.ts
@@ -17,24 +17,25 @@
* under the License.
*/
-// @ts-nocheck
+import GlobalModel from '../../model/Global';
+import GraphSeriesModel from './GraphSeries';
-function normalize(a) {
+function normalize(a: string | number | (string | number)[]): (string | number)[] {
if (!(a instanceof Array)) {
a = [a, a];
}
return a;
}
-export default function (ecModel) {
- ecModel.eachSeriesByType('graph', function (seriesModel) {
+export default function (ecModel: GlobalModel) {
+ ecModel.eachSeriesByType('graph', function (seriesModel: GraphSeriesModel) {
var graph = seriesModel.getGraph();
var edgeData = seriesModel.getEdgeData();
var symbolType = normalize(seriesModel.get('edgeSymbol'));
var symbolSize = normalize(seriesModel.get('edgeSymbolSize'));
- var colorQuery = 'lineStyle.color'.split('.');
- var opacityQuery = 'lineStyle.opacity'.split('.');
+ var colorQuery = ['lineStyle', 'color'] as const;
+ var opacityQuery = ['lineStyle', 'opacity'] as const;
edgeData.setVisual('fromSymbol', symbolType && symbolType[0]);
edgeData.setVisual('toSymbol', symbolType && symbolType[1]);
diff --git a/src/chart/graph/forceHelper.ts b/src/chart/graph/forceHelper.ts
index 96d3b00..f8703c5 100644
--- a/src/chart/graph/forceHelper.ts
+++ b/src/chart/graph/forceHelper.ts
@@ -17,8 +17,6 @@
* under the License.
*/
-// @ts-nocheck
-
/*
* A third-party license is embeded for some of the code in this file:
* Some formulas were originally copied from "d3.js" with some
@@ -30,14 +28,56 @@
*/
import * as vec2 from 'zrender/src/core/vector';
+import { RectLike } from 'zrender/src/core/BoundingRect';
var scaleAndAdd = vec2.scaleAndAdd;
+interface InputNode {
+ p?: vec2.VectorArray
+ fixed?: boolean
+ /**
+ * Weight
+ */
+ w: number
+ /**
+ * Repulsion
+ */
+ rep: number
+}
+interface LayoutNode extends InputNode {
+ pp?: vec2.VectorArray
+ edges?: LayoutEdge[]
+}
+interface InputEdge {
+ ignoreForceLayout?: boolean
+ n1: InputNode
+ n2: InputNode
+
+ /**
+ * Distance
+ */
+ d: number
+}
+interface LayoutEdge extends InputEdge {
+ n1: LayoutNode
+ n2: LayoutNode
+}
+interface LayoutCfg {
+ gravity?: number
+ friction?: number
+ rect?: RectLike
+}
// function adjacentNode(n, e) {
// return e.n1 === n ? e.n2 : e.n1;
// }
-export function forceLayout(nodes, edges, opts) {
+export function forceLayout<N extends InputNode, E extends InputEdge>(
+ inNodes: N[],
+ inEdges: E[],
+ opts: LayoutCfg
+) {
+ var nodes = inNodes as LayoutNode[];
+ var edges = inEdges as LayoutEdge[];
var rect = opts.rect;
var width = rect.width;
var height = rect.height;
@@ -56,7 +96,7 @@ export function forceLayout(nodes, edges, opts) {
// }
// Init position
for (var i = 0; i < nodes.length; i++) {
- var n = nodes[i];
+ var n = nodes[i] as LayoutNode;
if (!n.p) {
n.p = vec2.create(
width * (Math.random() - 0.5) + center[0],
@@ -74,27 +114,45 @@ export function forceLayout(nodes, edges, opts) {
var initialFriction = opts.friction == null ? 0.6 : opts.friction;
var friction = initialFriction;
+ var beforeStepCallback: (nodes: N[], edges: E[]) => void;
+ var afterStepCallback: (nodes: N[], edges: E[], finished: boolean) => void;
+
return {
warmUp: function () {
friction = initialFriction * 0.8;
},
- setFixed: function (idx) {
+ setFixed: function (idx: number) {
nodes[idx].fixed = true;
},
- setUnfixed: function (idx) {
+ setUnfixed: function (idx: number) {
nodes[idx].fixed = false;
},
/**
+ * Before step hook
+ */
+ beforeStep: function (cb: typeof beforeStepCallback) {
+ beforeStepCallback = cb;
+ },
+ /**
+ * After step hook
+ */
+ afterStep: function (cb: typeof afterStepCallback) {
+ afterStepCallback = cb;
+ },
+
+ /**
* Some formulas were originally copied from "d3.js"
* https://github.com/d3/d3/blob/b516d77fb8566b576088e73410437494717ada26/src/layout/force.js
* with some modifications made for this project.
* See the license statement at the head of this file.
*/
- step: function (cb) {
- var v12 = [];
+ step: function (cb?: (finished: boolean) => void) {
+ beforeStepCallback && beforeStepCallback(nodes as N[], edges as E[]);
+
+ var v12: number[] = [];
var nLen = nodes.length;
for (var i = 0; i < edges.length; i++) {
var e = edges[i];
@@ -147,7 +205,7 @@ export function forceLayout(nodes, edges, opts) {
!n2.fixed && scaleAndAdd(n2.pp, n2.pp, v12, -repFact);
}
}
- var v = [];
+ var v: number[] = [];
for (var i = 0; i < nLen; i++) {
var n = nodes[i];
if (!n.fixed) {
@@ -159,7 +217,11 @@ export function forceLayout(nodes, edges, opts) {
friction = friction * 0.992;
- cb && cb(nodes, edges, friction < 0.01);
+ const finished = friction < 0.01;
+
+ afterStepCallback && afterStepCallback(nodes as N[], edges as E[], finished);
+
+ cb && cb(finished);
}
};
}
diff --git a/src/chart/graph/forceLayout.ts b/src/chart/graph/forceLayout.ts
index 30edaa6..e7501ee 100644
--- a/src/chart/graph/forceLayout.ts
+++ b/src/chart/graph/forceLayout.ts
@@ -17,17 +17,25 @@
* under the License.
*/
-// @ts-nocheck
-
import {forceLayout} from './forceHelper';
import {simpleLayout} from './simpleLayoutHelper';
import {circularLayout} from './circularLayoutHelper';
import {linearMap} from '../../util/number';
import * as vec2 from 'zrender/src/core/vector';
import * as zrUtil from 'zrender/src/core/util';
+import GlobalModel from '../../model/Global';
+import GraphSeriesModel from './GraphSeries';
+
+export interface ForceLayoutInstance {
+ step(cb: (stopped: boolean) => void): void
+ warmUp(): void
+ setFixed(idx: number): void
+ setUnfixed(idx: number): void
+}
+
-export default function (ecModel) {
- ecModel.eachSeriesByType('graph', function (graphSeries) {
+export default function (ecModel: GlobalModel) {
+ ecModel.eachSeriesByType('graph', function (graphSeries: GraphSeriesModel) {
var coordSys = graphSeries.coordinateSystem;
if (coordSys && coordSys.type !== 'view') {
return;
@@ -57,20 +65,19 @@ export default function (ecModel) {
// var edgeDataExtent = edgeData.getDataExtent('value');
var repulsion = forceModel.get('repulsion');
var edgeLength = forceModel.get('edgeLength');
- if (!zrUtil.isArray(repulsion)) {
- repulsion = [repulsion, repulsion];
- }
- if (!zrUtil.isArray(edgeLength)) {
- edgeLength = [edgeLength, edgeLength];
- }
+ var repulsionArr = zrUtil.isArray(repulsion)
+ ? repulsion : [repulsion, repulsion];
+ var edgeLengthArr = zrUtil.isArray(edgeLength)
+ ? edgeLength : [edgeLength, edgeLength];
+
// Larger value has smaller length
- edgeLength = [edgeLength[1], edgeLength[0]];
+ edgeLengthArr = [edgeLengthArr[1], edgeLengthArr[0]];
- var nodes = nodeData.mapArray('value', function (value, idx) {
- var point = nodeData.getItemLayout(idx);
- var rep = linearMap(value, nodeDataExtent, repulsion);
+ var nodes = nodeData.mapArray('value', function (value: number, idx) {
+ var point = nodeData.getItemLayout(idx) as number[];
+ var rep = linearMap(value, nodeDataExtent, repulsionArr);
if (isNaN(rep)) {
- rep = (repulsion[0] + repulsion[1]) / 2;
+ rep = (repulsionArr[0] + repulsionArr[1]) / 2;
}
return {
w: rep,
@@ -79,11 +86,11 @@ export default function (ecModel) {
p: (!point || isNaN(point[0]) || isNaN(point[1])) ? null : point
};
});
- var edges = edgeData.mapArray('value', function (value, idx) {
+ var edges = edgeData.mapArray('value', function (value: number, idx) {
var edge = graph.getEdgeByIndex(idx);
- var d = linearMap(value, edgeDataExtent, edgeLength);
+ var d = linearMap(value, edgeDataExtent, edgeLengthArr);
if (isNaN(d)) {
- d = (edgeLength[0] + edgeLength[1]) / 2;
+ d = (edgeLengthArr[0] + edgeLengthArr[1]) / 2;
}
var edgeModel = edge.getModel();
return {
@@ -102,45 +109,44 @@ export default function (ecModel) {
gravity: forceModel.get('gravity'),
friction: forceModel.get('friction')
});
- var oldStep = forceInstance.step;
- forceInstance.step = function (cb) {
+ forceInstance.beforeStep(function (nodes, edges) {
for (var i = 0, l = nodes.length; i < l; i++) {
if (nodes[i].fixed) {
// Write back to layout instance
- vec2.copy(nodes[i].p, graph.getNodeByIndex(i).getLayout());
+ vec2.copy(
+ nodes[i].p,
+ graph.getNodeByIndex(i).getLayout() as number[]
+ );
}
}
- oldStep(function (nodes, edges, stopped) {
- for (var i = 0, l = nodes.length; i < l; i++) {
- if (!nodes[i].fixed) {
- graph.getNodeByIndex(i).setLayout(nodes[i].p);
- }
- preservedPoints[nodeData.getId(i)] = nodes[i].p;
+ });
+ forceInstance.afterStep(function (nodes, edges, stopped) {
+ for (var i = 0, l = nodes.length; i < l; i++) {
+ if (!nodes[i].fixed) {
+ graph.getNodeByIndex(i).setLayout(nodes[i].p);
}
- for (var i = 0, l = edges.length; i < l; i++) {
- var e = edges[i];
- var edge = graph.getEdgeByIndex(i);
- var p1 = e.n1.p;
- var p2 = e.n2.p;
- var points = edge.getLayout();
- points = points ? points.slice() : [];
- points[0] = points[0] || [];
- points[1] = points[1] || [];
- vec2.copy(points[0], p1);
- vec2.copy(points[1], p2);
- if (+e.curveness) {
- points[2] = [
- (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * e.curveness,
- (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * e.curveness
- ];
- }
- edge.setLayout(points);
+ preservedPoints[nodeData.getId(i)] = nodes[i].p;
+ }
+ for (var i = 0, l = edges.length; i < l; i++) {
+ var e = edges[i];
+ var edge = graph.getEdgeByIndex(i);
+ var p1 = e.n1.p;
+ var p2 = e.n2.p;
+ var points = edge.getLayout() as number[][];
+ points = points ? points.slice() : [];
+ points[0] = points[0] || [];
+ points[1] = points[1] || [];
+ vec2.copy(points[0], p1);
+ vec2.copy(points[1], p2);
+ if (+e.curveness) {
+ points[2] = [
+ (p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * e.curveness,
+ (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * e.curveness
+ ];
}
- // Update layout
-
- cb && cb(stopped);
- });
- };
+ edge.setLayout(points);
+ }
+ });
graphSeries.forceLayout = forceInstance;
graphSeries.preservedPoints = preservedPoints;
diff --git a/src/chart/graph/graphAction.ts b/src/chart/graph/graphAction.ts
index 5d2a129..5ef560d 100644
--- a/src/chart/graph/graphAction.ts
+++ b/src/chart/graph/graphAction.ts
@@ -17,11 +17,12 @@
* under the License.
*/
-// @ts-nocheck
-
import * as echarts from '../../echarts';
-import {updateCenterAndZoom} from '../../action/roamHelper';
+import {updateCenterAndZoom, RoamPaylod} from '../../action/roamHelper';
import '../helper/focusNodeAdjacencyAction';
+import GlobalModel from '../../model/Global';
+import GraphSeriesModel from './GraphSeries';
+import View from '../../coord/View';
var actionInfo = {
type: 'graphRoam',
@@ -38,9 +39,11 @@ var actionInfo = {
* @property {number} [originX]
* @property {number} [originY]
*/
-echarts.registerAction(actionInfo, function (payload, ecModel) {
- ecModel.eachComponent({mainType: 'series', query: payload}, function (seriesModel) {
- var coordSys = seriesModel.coordinateSystem;
+echarts.registerAction(actionInfo, function (payload: RoamPaylod, ecModel: GlobalModel) {
+ ecModel.eachComponent({
+ mainType: 'series', query: payload
+ }, function (seriesModel: GraphSeriesModel) {
+ var coordSys = seriesModel.coordinateSystem as View;
var res = updateCenterAndZoom(coordSys, payload);
diff --git a/src/chart/graph/graphHelper.ts b/src/chart/graph/graphHelper.ts
index 47ed84a..6075987 100644
--- a/src/chart/graph/graphHelper.ts
+++ b/src/chart/graph/graphHelper.ts
@@ -17,10 +17,12 @@
* under the License.
*/
-// @ts-nocheck
+import GraphSeriesModel from './GraphSeries';
+import View from '../../coord/View';
+import { GraphNode } from '../../data/Graph';
-export function getNodeGlobalScale(seriesModel) {
- var coordSys = seriesModel.coordinateSystem;
+export function getNodeGlobalScale(seriesModel: GraphSeriesModel) {
+ var coordSys = seriesModel.coordinateSystem as View;
if (coordSys.type !== 'view') {
return 1;
}
@@ -36,7 +38,7 @@ export function getNodeGlobalScale(seriesModel) {
return nodeScale / groupZoom;
}
-export function getSymbolSize(node) {
+export function getSymbolSize(node: GraphNode) {
var symbolSize = node.getVisual('symbolSize');
if (symbolSize instanceof Array) {
symbolSize = (symbolSize[0] + symbolSize[1]) / 2;
diff --git a/src/chart/graph/simpleLayout.ts b/src/chart/graph/simpleLayout.ts
index b596a38..353a734 100644
--- a/src/chart/graph/simpleLayout.ts
+++ b/src/chart/graph/simpleLayout.ts
@@ -17,19 +17,20 @@
* under the License.
*/
-// @ts-nocheck
-
import {each} from 'zrender/src/core/util';
import {simpleLayout, simpleLayoutEdge} from './simpleLayoutHelper';
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import GraphSeriesModel from './GraphSeries';
-export default function (ecModel, api) {
- ecModel.eachSeriesByType('graph', function (seriesModel) {
+export default function (ecModel: GlobalModel, api: ExtensionAPI) {
+ ecModel.eachSeriesByType('graph', function (seriesModel: GraphSeriesModel) {
var layout = seriesModel.get('layout');
var coordSys = seriesModel.coordinateSystem;
if (coordSys && coordSys.type !== 'view') {
var data = seriesModel.getData();
- var dimensions = [];
+ var dimensions: string[] = [];
each(coordSys.dimensions, function (coordDim) {
dimensions = dimensions.concat(data.mapDimension(coordDim, true));
});
@@ -38,7 +39,7 @@ export default function (ecModel, api) {
var value = [];
var hasValue = false;
for (var i = 0; i < dimensions.length; i++) {
- var val = data.get(dimensions[i], dataIndex);
+ var val = data.get(dimensions[i], dataIndex) as number;
if (!isNaN(val)) {
hasValue = true;
}
diff --git a/src/chart/graph/simpleLayoutHelper.ts b/src/chart/graph/simpleLayoutHelper.ts
index d56c665..9a5abcc 100644
--- a/src/chart/graph/simpleLayoutHelper.ts
+++ b/src/chart/graph/simpleLayoutHelper.ts
@@ -17,11 +17,11 @@
* under the License.
*/
-// @ts-nocheck
-
import * as vec2 from 'zrender/src/core/vector';
+import GraphSeriesModel from './GraphSeries';
+import Graph from '../../data/Graph';
-export function simpleLayout(seriesModel) {
+export function simpleLayout(seriesModel: GraphSeriesModel) {
var coordSys = seriesModel.coordinateSystem;
if (coordSys && coordSys.type !== 'view') {
return;
@@ -36,7 +36,7 @@ export function simpleLayout(seriesModel) {
simpleLayoutEdge(graph);
}
-export function simpleLayoutEdge(graph) {
+export function simpleLayoutEdge(graph: Graph) {
graph.eachEdge(function (edge) {
var curveness = edge.getModel().get('lineStyle.curveness') || 0;
var p1 = vec2.clone(edge.node1.getLayout());
diff --git a/src/chart/heatmap/HeatmapSeries.ts b/src/chart/heatmap/HeatmapSeries.ts
index c776cc3..2f44a13 100644
--- a/src/chart/heatmap/HeatmapSeries.ts
+++ b/src/chart/heatmap/HeatmapSeries.ts
@@ -92,7 +92,7 @@ class HeatmapSeriesModel extends SeriesModel<HeatmapSeriesOption> {
}
}
- defaultOption: HeatmapSeriesOption = {
+ static defaultOption: HeatmapSeriesOption = {
coordinateSystem: 'cartesian2d',
diff --git a/src/chart/helper/Line.ts b/src/chart/helper/Line.ts
index 07a4bb3..969789e 100644
--- a/src/chart/helper/Line.ts
+++ b/src/chart/helper/Line.ts
@@ -17,28 +17,48 @@
* under the License.
*/
-// @ts-nocheck
-
-/**
- * @module echarts/chart/helper/Line
- */
-
import * as zrUtil from 'zrender/src/core/util';
import * as vector from 'zrender/src/core/vector';
import * as symbolUtil from '../../util/symbol';
-import LinePath from './LinePath';
+import ECLinePath from './LinePath';
import * as graphic from '../../util/graphic';
import {round} from '../../util/number';
+import List from '../../data/List';
+import { StyleProps } from 'zrender/src/graphic/Style';
+import { LineLabelOption, ZRTextAlign, ZRTextVerticalAlign } from '../../util/types';
+import Model from '../../model/Model';
+import SeriesModel from '../../model/Series';
+
+var SYMBOL_CATEGORIES = ['fromSymbol', 'toSymbol'] as const;
+
+type ECSymbol = ReturnType<typeof createSymbol>
+
+export interface LineLabel extends graphic.Text {
+ lineLabelOriginalOpacity: number
+}
+
+interface InnerLineLabel extends LineLabel {
+ __textAlign: StyleProps['textAlign']
+ __verticalAlign: StyleProps['textVerticalAlign']
+ __position: StyleProps['textPosition']
+ __labelDistance: number[]
+}
+
+function makeSymbolTypeKey(symbolCategory: string) {
+ return '_' + symbolCategory + 'Type' as '_fromSymbolType' | '_toSymbolType';
+}
-var SYMBOL_CATEGORIES = ['fromSymbol', 'toSymbol'];
+export interface SeriesScope {
+ lineStyle?: StyleProps
+ hoverLineStyle?: StyleProps
-function makeSymbolTypeKey(symbolCategory) {
- return '_' + symbolCategory + 'Type';
+ labelModel?: Model<LineLabelOption>
+ hoverLabelModel?: Model<LineLabelOption>
}
/**
* @inner
*/
-function createSymbol(name, lineData, idx) {
+function createSymbol(name: string, lineData: List, idx: number) {
var color = lineData.getItemVisual(idx, 'color');
var symbolType = lineData.getItemVisual(idx, name);
var symbolSize = lineData.getItemVisual(idx, name + 'Size');
@@ -60,8 +80,8 @@ function createSymbol(name, lineData, idx) {
return symbolPath;
}
-function createLine(points) {
- var line = new LinePath({
+function createLine(points: number[][]) {
+ var line = new ECLinePath({
name: 'line',
subPixelOptimize: true
});
@@ -69,7 +89,12 @@ function createLine(points) {
return line;
}
-function setLinePoints(targetShape, points) {
+function setLinePoints(targetShape: ECLinePath['shape'], points: number[][]) {
+ type CurveShape = ECLinePath['shape'] & {
+ cpx1: number
+ cpy1: number
+ }
+
targetShape.x1 = points[0][0];
targetShape.y1 = points[0][1];
targetShape.x2 = points[1][0];
@@ -78,389 +103,382 @@ function setLinePoints(targetShape, points) {
var cp1 = points[2];
if (cp1) {
- targetShape.cpx1 = cp1[0];
- targetShape.cpy1 = cp1[1];
+ (targetShape as CurveShape).cpx1 = cp1[0];
+ (targetShape as CurveShape).cpy1 = cp1[1];
}
else {
- targetShape.cpx1 = NaN;
- targetShape.cpy1 = NaN;
+ (targetShape as CurveShape).cpx1 = NaN;
+ (targetShape as CurveShape).cpy1 = NaN;
}
}
-function updateSymbolAndLabelBeforeLineUpdate() {
- var lineGroup = this;
- var symbolFrom = lineGroup.childOfName('fromSymbol');
- var symbolTo = lineGroup.childOfName('toSymbol');
- var label = lineGroup.childOfName('label');
- // Quick reject
- if (!symbolFrom && !symbolTo && label.ignore) {
- return;
- }
+class Line extends graphic.Group {
- var invScale = 1;
- var parentNode = this.parent;
- while (parentNode) {
- if (parentNode.scale) {
- invScale /= parentNode.scale[0];
- }
- parentNode = parentNode.parent;
- }
+ private _fromSymbolType: string
+ private _toSymbolType: string
- var line = lineGroup.childOfName('line');
- // If line not changed
- // FIXME Parent scale changed
- if (!this.__dirty && !line.__dirty) {
- return;
+ constructor(lineData: List, idx: number, seriesScope?: SeriesScope) {
+ super();
+ this._createLine(lineData, idx, seriesScope);
}
- var percent = line.shape.percent;
- var fromPos = line.pointAt(0);
- var toPos = line.pointAt(percent);
+ _createLine(lineData: List, idx: number, seriesScope?: SeriesScope) {
+ var seriesModel = lineData.hostModel;
+ var linePoints = lineData.getItemLayout(idx);
+ var line = createLine(linePoints);
+ line.shape.percent = 0;
+ graphic.initProps(line, {
+ shape: {
+ percent: 1
+ }
+ }, seriesModel, idx);
- var d = vector.sub([], toPos, fromPos);
- vector.normalize(d, d);
+ this.add(line);
- if (symbolFrom) {
- symbolFrom.attr('position', fromPos);
- var tangent = line.tangentAt(0);
- symbolFrom.attr('rotation', Math.PI / 2 - Math.atan2(
- tangent[1], tangent[0]
- ));
- symbolFrom.attr('scale', [invScale * percent, invScale * percent]);
- }
- if (symbolTo) {
- symbolTo.attr('position', toPos);
- var tangent = line.tangentAt(1);
- symbolTo.attr('rotation', -Math.PI / 2 - Math.atan2(
- tangent[1], tangent[0]
- ));
- symbolTo.attr('scale', [invScale * percent, invScale * percent]);
+ var label = new graphic.Text({
+ name: 'label'
+ }) as InnerLineLabel;
+ // FIXME
+ // Temporary solution for `focusNodeAdjacency`.
+ // line label do not use the opacity of lineStyle.
+ label.lineLabelOriginalOpacity = 1;
+ this.add(label);
+
+ zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
+ var symbol = createSymbol(symbolCategory, lineData, idx);
+ // symbols must added after line to make sure
+ // it will be updated after line#update.
+ // Or symbol position and rotation update in line#beforeUpdate will be one frame slow
+ this.add(symbol);
+ this[makeSymbolTypeKey(symbolCategory)] = lineData.getItemVisual(idx, symbolCategory);
+ }, this);
+
+ this._updateCommonStl(lineData, idx, seriesScope);
}
- if (!label.ignore) {
- label.attr('position', toPos);
-
- var textPosition;
- var textAlign;
- var textVerticalAlign;
- var textOrigin;
-
- var distance = label.__labelDistance;
- var distanceX = distance[0] * invScale;
- var distanceY = distance[1] * invScale;
- var halfPercent = percent / 2;
- var tangent = line.tangentAt(halfPercent);
- var n = [tangent[1], -tangent[0]];
- var cp = line.pointAt(halfPercent);
- if (n[1] > 0) {
- n[0] = -n[0];
- n[1] = -n[1];
- }
- var dir = tangent[0] < 0 ? -1 : 1;
+ updateData(lineData: List, idx: number, seriesScope: SeriesScope) {
+ var seriesModel = lineData.hostModel;
- if (label.__position !== 'start' && label.__position !== 'end') {
- var rotation = -Math.atan2(tangent[1], tangent[0]);
- if (toPos[0] < fromPos[0]) {
- rotation = Math.PI + rotation;
- }
- label.attr('rotation', rotation);
- }
+ var line = this.childOfName('line') as ECLinePath;
+ var linePoints = lineData.getItemLayout(idx);
+ var target = {
+ shape: {} as ECLinePath['shape']
+ };
- var dy;
- switch (label.__position) {
- case 'insideStartTop':
- case 'insideMiddleTop':
- case 'insideEndTop':
- case 'middle':
- dy = -distanceY;
- textVerticalAlign = 'bottom';
- break;
-
- case 'insideStartBottom':
- case 'insideMiddleBottom':
- case 'insideEndBottom':
- dy = distanceY;
- textVerticalAlign = 'top';
- break;
-
- default:
- dy = 0;
- textVerticalAlign = 'middle';
- }
+ setLinePoints(target.shape, linePoints);
+ graphic.updateProps(line, target, seriesModel, idx);
+
+ zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
+ var symbolType = lineData.getItemVisual(idx, symbolCategory);
+ var key = makeSymbolTypeKey(symbolCategory);
+ // Symbol changed
+ if (this[key] !== symbolType) {
+ this.remove(this.childOfName(symbolCategory));
+ var symbol = createSymbol(symbolCategory, lineData, idx);
+ this.add(symbol);
+ }
+ this[key] = symbolType;
+ }, this);
- switch (label.__position) {
- case 'end':
- textPosition = [d[0] * distanceX + toPos[0], d[1] * distanceY + toPos[1]];
- textAlign = d[0] > 0.8 ? 'left' : (d[0] < -0.8 ? 'right' : 'center');
- textVerticalAlign = d[1] > 0.8 ? 'top' : (d[1] < -0.8 ? 'bottom' : 'middle');
- break;
-
- case 'start':
- textPosition = [-d[0] * distanceX + fromPos[0], -d[1] * distanceY + fromPos[1]];
- textAlign = d[0] > 0.8 ? 'right' : (d[0] < -0.8 ? 'left' : 'center');
- textVerticalAlign = d[1] > 0.8 ? 'bottom' : (d[1] < -0.8 ? 'top' : 'middle');
- break;
-
- case 'insideStartTop':
- case 'insideStart':
- case 'insideStartBottom':
- textPosition = [distanceX * dir + fromPos[0], fromPos[1] + dy];
- textAlign = tangent[0] < 0 ? 'right' : 'left';
- textOrigin = [-distanceX * dir, -dy];
- break;
-
- case 'insideMiddleTop':
- case 'insideMiddle':
- case 'insideMiddleBottom':
- case 'middle':
- textPosition = [cp[0], cp[1] + dy];
- textAlign = 'center';
- textOrigin = [0, -dy];
- break;
-
- case 'insideEndTop':
- case 'insideEnd':
- case 'insideEndBottom':
- textPosition = [-distanceX * dir + toPos[0], toPos[1] + dy];
- textAlign = tangent[0] >= 0 ? 'right' : 'left';
- textOrigin = [distanceX * dir, -dy];
- break;
- }
+ this._updateCommonStl(lineData, idx, seriesScope);
+ };
- label.attr({
- style: {
- // Use the user specified text align and baseline first
- textVerticalAlign: label.__verticalAlign || textVerticalAlign,
- textAlign: label.__textAlign || textAlign
- },
- position: textPosition,
- scale: [invScale, invScale],
- origin: textOrigin
- });
- }
-}
+ _updateCommonStl(lineData: List, idx: number, seriesScope?: SeriesScope) {
+ var seriesModel = lineData.hostModel as SeriesModel;
-/**
- * @constructor
- * @extends {module:zrender/graphic/Group}
- * @alias {module:echarts/chart/helper/Line}
- */
-function Line(lineData, idx, seriesScope) {
- graphic.Group.call(this);
+ var line = this.childOfName('line') as ECLinePath;
- this._createLine(lineData, idx, seriesScope);
-}
+ var lineStyle = seriesScope && seriesScope.lineStyle;
+ var hoverLineStyle = seriesScope && seriesScope.hoverLineStyle;
+ var labelModel = seriesScope && seriesScope.labelModel;
+ var hoverLabelModel = seriesScope && seriesScope.hoverLabelModel;
-var lineProto = Line.prototype;
+ // Optimization for large dataset
+ if (!seriesScope || lineData.hasItemOption) {
+ var itemModel = lineData.getItemModel(idx);
-// Update symbol position and rotation
-lineProto.beforeUpdate = updateSymbolAndLabelBeforeLineUpdate;
+ lineStyle = itemModel.getModel('lineStyle').getLineStyle();
+ hoverLineStyle = itemModel.getModel(['emphasis', 'lineStyle']).getLineStyle();
-lineProto._createLine = function (lineData, idx, seriesScope) {
- var seriesModel = lineData.hostModel;
- var linePoints = lineData.getItemLayout(idx);
- var line = createLine(linePoints);
- line.shape.percent = 0;
- graphic.initProps(line, {
- shape: {
- percent: 1
+ labelModel = itemModel.getModel('label');
+ hoverLabelModel = itemModel.getModel(['emphasis', 'label']);
}
- }, seriesModel, idx);
- this.add(line);
-
- var label = new graphic.Text({
- name: 'label',
- // FIXME
- // Temporary solution for `focusNodeAdjacency`.
- // line label do not use the opacity of lineStyle.
- lineLabelOriginalOpacity: 1
- });
- this.add(label);
-
- zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
- var symbol = createSymbol(symbolCategory, lineData, idx);
- // symbols must added after line to make sure
- // it will be updated after line#update.
- // Or symbol position and rotation update in line#beforeUpdate will be one frame slow
- this.add(symbol);
- this[makeSymbolTypeKey(symbolCategory)] = lineData.getItemVisual(idx, symbolCategory);
- }, this);
-
- this._updateCommonStl(lineData, idx, seriesScope);
-};
-
-lineProto.updateData = function (lineData, idx, seriesScope) {
- var seriesModel = lineData.hostModel;
-
- var line = this.childOfName('line');
- var linePoints = lineData.getItemLayout(idx);
- var target = {
- shape: {}
- };
+ var visualColor = lineData.getItemVisual(idx, 'color');
+ var visualOpacity = zrUtil.retrieve3(
+ lineData.getItemVisual(idx, 'opacity'),
+ lineStyle.opacity,
+ 1
+ );
+
+ line.useStyle(zrUtil.defaults(
+ {
+ strokeNoScale: true,
+ fill: 'none',
+ stroke: visualColor,
+ opacity: visualOpacity
+ },
+ lineStyle
+ ));
+ line.hoverStyle = hoverLineStyle;
+
+ // Update symbol
+ zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
+ var symbol = this.childOfName(symbolCategory) as ECSymbol;
+ if (symbol) {
+ symbol.setColor(visualColor);
+ symbol.setStyle({
+ opacity: visualOpacity
+ });
+ }
+ }, this);
+
+ var showLabel = labelModel.getShallow('show');
+ var hoverShowLabel = hoverLabelModel.getShallow('show');
+
+ var label = this.childOfName('label') as InnerLineLabel;
+ var defaultLabelColor;
+ var baseText;
+
+ // FIXME: the logic below probably should be merged to `graphic.setLabelStyle`.
+ if (showLabel || hoverShowLabel) {
+ defaultLabelColor = visualColor || '#000';
+
+ baseText = seriesModel.getFormattedLabel(idx, 'normal', lineData.dataType);
+ if (baseText == null) {
+ var rawVal = seriesModel.getRawValue(idx);
+ baseText = rawVal == null
+ ? lineData.getName(idx)
+ : isFinite(rawVal)
+ ? round(rawVal)
+ : rawVal;
+ }
+ }
+ var normalText = showLabel ? baseText : null;
+ var emphasisText = hoverShowLabel
+ ? zrUtil.retrieve2(
+ seriesModel.getFormattedLabel(idx, 'emphasis', lineData.dataType),
+ baseText
+ )
+ : null;
+
+ var labelStyle = label.style;
+
+ // Always set `textStyle` even if `normalStyle.text` is null, because default
+ // values have to be set on `normalStyle`.
+ if (normalText != null || emphasisText != null) {
+ graphic.setTextStyle(label.style, labelModel, {
+ text: normalText
+ }, {
+ autoColor: defaultLabelColor
+ });
- setLinePoints(target.shape, linePoints);
- graphic.updateProps(line, target, seriesModel, idx);
+ label.__textAlign = labelStyle.textAlign;
+ label.__verticalAlign = labelStyle.textVerticalAlign;
+ // 'start', 'middle', 'end'
+ label.__position = labelModel.get('position') || 'middle';
- zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
- var symbolType = lineData.getItemVisual(idx, symbolCategory);
- var key = makeSymbolTypeKey(symbolCategory);
- // Symbol changed
- if (this[key] !== symbolType) {
- this.remove(this.childOfName(symbolCategory));
- var symbol = createSymbol(symbolCategory, lineData, idx);
- this.add(symbol);
+ var distance = labelModel.get('distance');
+ if (!zrUtil.isArray(distance)) {
+ distance = [distance, distance];
+ }
+ label.__labelDistance = distance;
}
- this[key] = symbolType;
- }, this);
-
- this._updateCommonStl(lineData, idx, seriesScope);
-};
-lineProto._updateCommonStl = function (lineData, idx, seriesScope) {
- var seriesModel = lineData.hostModel;
+ if (emphasisText != null) {
+ // Only these properties supported in this emphasis style here.
+ label.hoverStyle = {
+ text: emphasisText,
+ textFill: hoverLabelModel.getTextColor(true),
+ // For merging hover style to normal style, do not use
+ // `hoverLabelModel.getFont()` here.
+ fontStyle: hoverLabelModel.getShallow('fontStyle'),
+ fontWeight: hoverLabelModel.getShallow('fontWeight'),
+ fontSize: hoverLabelModel.getShallow('fontSize'),
+ fontFamily: hoverLabelModel.getShallow('fontFamily')
+ };
+ }
+ else {
+ label.hoverStyle = {
+ text: null
+ };
+ }
- var line = this.childOfName('line');
+ label.ignore = !showLabel && !hoverShowLabel;
- var lineStyle = seriesScope && seriesScope.lineStyle;
- var hoverLineStyle = seriesScope && seriesScope.hoverLineStyle;
- var labelModel = seriesScope && seriesScope.labelModel;
- var hoverLabelModel = seriesScope && seriesScope.hoverLabelModel;
+ graphic.setHoverStyle(this);
+ }
- // Optimization for large dataset
- if (!seriesScope || lineData.hasItemOption) {
- var itemModel = lineData.getItemModel(idx);
+ highlight() {
+ this.trigger('emphasis');
+ }
- lineStyle = itemModel.getModel('lineStyle').getLineStyle();
- hoverLineStyle = itemModel.getModel('emphasis.lineStyle').getLineStyle();
+ downplay() {
+ this.trigger('normal');
+ }
- labelModel = itemModel.getModel('label');
- hoverLabelModel = itemModel.getModel('emphasis.label');
+ updateLayout(lineData: List, idx: number) {
+ this.setLinePoints(lineData.getItemLayout(idx));
}
- var visualColor = lineData.getItemVisual(idx, 'color');
- var visualOpacity = zrUtil.retrieve3(
- lineData.getItemVisual(idx, 'opacity'),
- lineStyle.opacity,
- 1
- );
+ setLinePoints(points: number[][]) {
+ var linePath = this.childOfName('line') as ECLinePath;
+ setLinePoints(linePath.shape, points);
+ linePath.dirty();
+ }
- line.useStyle(zrUtil.defaults(
- {
- strokeNoScale: true,
- fill: 'none',
- stroke: visualColor,
- opacity: visualOpacity
- },
- lineStyle
- ));
- line.hoverStyle = hoverLineStyle;
-
- // Update symbol
- zrUtil.each(SYMBOL_CATEGORIES, function (symbolCategory) {
- var symbol = this.childOfName(symbolCategory);
- if (symbol) {
- symbol.setColor(visualColor);
- symbol.setStyle({
- opacity: visualOpacity
- });
- }
- }, this);
-
- var showLabel = labelModel.getShallow('show');
- var hoverShowLabel = hoverLabelModel.getShallow('show');
-
- var label = this.childOfName('label');
- var defaultLabelColor;
- var baseText;
-
- // FIXME: the logic below probably should be merged to `graphic.setLabelStyle`.
- if (showLabel || hoverShowLabel) {
- defaultLabelColor = visualColor || '#000';
-
- baseText = seriesModel.getFormattedLabel(idx, 'normal', lineData.dataType);
- if (baseText == null) {
- var rawVal = seriesModel.getRawValue(idx);
- baseText = rawVal == null
- ? lineData.getName(idx)
- : isFinite(rawVal)
- ? round(rawVal)
- : rawVal;
+ beforeUpdate() {
+ var lineGroup = this;
+ var symbolFrom = lineGroup.childOfName('fromSymbol') as ECSymbol;
+ var symbolTo = lineGroup.childOfName('toSymbol') as ECSymbol;
+ var label = lineGroup.childOfName('label') as InnerLineLabel;
+ // Quick reject
+ if (!symbolFrom && !symbolTo && label.ignore) {
+ return;
}
- }
- var normalText = showLabel ? baseText : null;
- var emphasisText = hoverShowLabel
- ? zrUtil.retrieve2(
- seriesModel.getFormattedLabel(idx, 'emphasis', lineData.dataType),
- baseText
- )
- : null;
-
- var labelStyle = label.style;
-
- // Always set `textStyle` even if `normalStyle.text` is null, because default
- // values have to be set on `normalStyle`.
- if (normalText != null || emphasisText != null) {
- graphic.setTextStyle(label.style, labelModel, {
- text: normalText
- }, {
- autoColor: defaultLabelColor
- });
-
- label.__textAlign = labelStyle.textAlign;
- label.__verticalAlign = labelStyle.textVerticalAlign;
- // 'start', 'middle', 'end'
- label.__position = labelModel.get('position') || 'middle';
-
- var distance = labelModel.get('distance');
- if (!zrUtil.isArray(distance)) {
- distance = [distance, distance];
+
+ var invScale = 1;
+ var parentNode = this.parent;
+ while (parentNode) {
+ if (parentNode.scale) {
+ invScale /= parentNode.scale[0];
+ }
+ parentNode = parentNode.parent;
}
- label.__labelDistance = distance;
- }
- if (emphasisText != null) {
- // Only these properties supported in this emphasis style here.
- label.hoverStyle = {
- text: emphasisText,
- textFill: hoverLabelModel.getTextColor(true),
- // For merging hover style to normal style, do not use
- // `hoverLabelModel.getFont()` here.
- fontStyle: hoverLabelModel.getShallow('fontStyle'),
- fontWeight: hoverLabelModel.getShallow('fontWeight'),
- fontSize: hoverLabelModel.getShallow('fontSize'),
- fontFamily: hoverLabelModel.getShallow('fontFamily')
- };
- }
- else {
- label.hoverStyle = {
- text: null
- };
- }
+ var line = lineGroup.childOfName('line') as ECLinePath;
+ // If line not changed
+ // FIXME Parent scale changed
+ if (!this.__dirty && !line.__dirty) {
+ return;
+ }
- label.ignore = !showLabel && !hoverShowLabel;
+ var percent = line.shape.percent;
+ var fromPos = line.pointAt(0);
+ var toPos = line.pointAt(percent);
- graphic.setHoverStyle(this);
-};
+ var d = vector.sub([], toPos, fromPos);
+ vector.normalize(d, d);
-lineProto.highlight = function () {
- this.trigger('emphasis');
-};
+ if (symbolFrom) {
+ symbolFrom.attr('position', fromPos);
+ var tangent = line.tangentAt(0);
+ symbolFrom.attr('rotation', Math.PI / 2 - Math.atan2(
+ tangent[1], tangent[0]
+ ));
+ symbolFrom.attr('scale', [invScale * percent, invScale * percent]);
+ }
+ if (symbolTo) {
+ symbolTo.attr('position', toPos);
+ var tangent = line.tangentAt(1);
+ symbolTo.attr('rotation', -Math.PI / 2 - Math.atan2(
+ tangent[1], tangent[0]
+ ));
+ symbolTo.attr('scale', [invScale * percent, invScale * percent]);
+ }
-lineProto.downplay = function () {
- this.trigger('normal');
-};
+ if (!label.ignore) {
+ label.attr('position', toPos);
+
+ var textPosition;
+ var textAlign: ZRTextAlign;
+ var textVerticalAlign: ZRTextVerticalAlign;
+ var textOrigin;
+
+ var distance = label.__labelDistance;
+ var distanceX = distance[0] * invScale;
+ var distanceY = distance[1] * invScale;
+ var halfPercent = percent / 2;
+ var tangent = line.tangentAt(halfPercent);
+ var n = [tangent[1], -tangent[0]];
+ var cp = line.pointAt(halfPercent);
+ if (n[1] > 0) {
+ n[0] = -n[0];
+ n[1] = -n[1];
+ }
+ var dir = tangent[0] < 0 ? -1 : 1;
+
+ if (label.__position !== 'start' && label.__position !== 'end') {
+ var rotation = -Math.atan2(tangent[1], tangent[0]);
+ if (toPos[0] < fromPos[0]) {
+ rotation = Math.PI + rotation;
+ }
+ label.attr('rotation', rotation);
+ }
-lineProto.updateLayout = function (lineData, idx) {
- this.setLinePoints(lineData.getItemLayout(idx));
-};
+ var dy;
+ switch (label.__position) {
+ case 'insideStartTop':
+ case 'insideMiddleTop':
+ case 'insideEndTop':
+ case 'middle':
+ dy = -distanceY;
+ textVerticalAlign = 'bottom';
+ break;
+
+ case 'insideStartBottom':
+ case 'insideMiddleBottom':
+ case 'insideEndBottom':
+ dy = distanceY;
+ textVerticalAlign = 'top';
+ break;
+
+ default:
+ dy = 0;
+ textVerticalAlign = 'middle';
+ }
-lineProto.setLinePoints = function (points) {
- var linePath = this.childOfName('line');
- setLinePoints(linePath.shape, points);
- linePath.dirty();
-};
+ switch (label.__position) {
+ case 'end':
+ textPosition = [d[0] * distanceX + toPos[0], d[1] * distanceY + toPos[1]];
+ textAlign = d[0] > 0.8 ? 'left' : (d[0] < -0.8 ? 'right' : 'center');
+ textVerticalAlign = d[1] > 0.8 ? 'top' : (d[1] < -0.8 ? 'bottom' : 'middle');
+ break;
+
+ case 'start':
+ textPosition = [-d[0] * distanceX + fromPos[0], -d[1] * distanceY + fromPos[1]];
+ textAlign = d[0] > 0.8 ? 'right' : (d[0] < -0.8 ? 'left' : 'center');
+ textVerticalAlign = d[1] > 0.8 ? 'bottom' : (d[1] < -0.8 ? 'top' : 'middle');
+ break;
+
+ case 'insideStartTop':
+ case 'insideStart':
+ case 'insideStartBottom':
+ textPosition = [distanceX * dir + fromPos[0], fromPos[1] + dy];
+ textAlign = tangent[0] < 0 ? 'right' : 'left';
+ textOrigin = [-distanceX * dir, -dy];
+ break;
+
+ case 'insideMiddleTop':
+ case 'insideMiddle':
+ case 'insideMiddleBottom':
+ case 'middle':
+ textPosition = [cp[0], cp[1] + dy];
+ textAlign = 'center';
+ textOrigin = [0, -dy];
+ break;
+
+ case 'insideEndTop':
+ case 'insideEnd':
+ case 'insideEndBottom':
+ textPosition = [-distanceX * dir + toPos[0], toPos[1] + dy];
+ textAlign = tangent[0] >= 0 ? 'right' : 'left';
+ textOrigin = [distanceX * dir, -dy];
+ break;
+ }
-zrUtil.inherits(Line, graphic.Group);
+ label.attr({
+ style: {
+ // Use the user specified text align and baseline first
+ textVerticalAlign: label.__verticalAlign || textVerticalAlign,
+ textAlign: label.__textAlign || textAlign
+ },
+ position: textPosition,
+ scale: [invScale, invScale],
+ origin: textOrigin
+ });
+ }
+ }
+}
export default Line;
\ No newline at end of file
diff --git a/src/chart/helper/LineDraw.ts b/src/chart/helper/LineDraw.ts
index 378badf..eb241fb 100644
--- a/src/chart/helper/LineDraw.ts
+++ b/src/chart/helper/LineDraw.ts
@@ -17,163 +17,179 @@
* under the License.
*/
-// @ts-nocheck
-
-/**
- * @module echarts/chart/helper/LineDraw
- */
-
import * as graphic from '../../util/graphic';
-import LineGroup from './Line';
-// import IncrementalDisplayable from 'zrender/src/graphic/IncrementalDisplayable';
+import LineGroup, {SeriesScope} from './Line';
+import List from '../../data/List';
+import { StageHandlerProgressParams, LineStyleOption, LineLabelOption } from '../../util/types';
+import Displayable from 'zrender/src/graphic/Displayable';
+import Model from '../../model/Model';
+
+interface LineLike extends graphic.Group {
+ updateData(data: List, idx: number, scope?: SeriesScope): void
+ updateLayout(data: List, idx: number): void
+ fadeOut?(cb: () => void): void
+}
-/**
- * @alias module:echarts/component/marker/LineDraw
- * @constructor
- */
-function LineDraw(ctor) {
- this._ctor = ctor || LineGroup;
+interface LineLikeCtor {
+ new(data: List, idx: number, scope?: SeriesScope): LineLike
+}
- this.group = new graphic.Group();
+interface LineOption {
+ lineStyle?: LineStyleOption
+ label?: LineLabelOption
+ emphasis: {
+ lineStyle?: LineStyleOption
+ label?: LineLabelOption
+ }
}
-var lineDrawProto = LineDraw.prototype;
+class LineDraw {
+ group = new graphic.Group()
-lineDrawProto.isPersistent = function () {
- return true;
-};
+ private _LineCtor: LineLikeCtor
-/**
- * @param {module:echarts/data/List} lineData
- */
-lineDrawProto.updateData = function (lineData) {
- var lineDraw = this;
- var group = lineDraw.group;
+ private _lineData: List
- var oldLineData = lineDraw._lineData;
- lineDraw._lineData = lineData;
+ private _seriesScope: SeriesScope
- // There is no oldLineData only when first rendering or switching from
- // stream mode to normal mode, where previous elements should be removed.
- if (!oldLineData) {
- group.removeAll();
+ constructor(LineCtor?: LineLikeCtor) {
+ this._LineCtor = LineCtor || LineGroup;
}
- var seriesScope = makeSeriesScope(lineData);
-
- lineData.diff(oldLineData)
- .add(function (idx) {
- doAdd(lineDraw, lineData, idx, seriesScope);
- })
- .update(function (newIdx, oldIdx) {
- doUpdate(lineDraw, oldLineData, lineData, oldIdx, newIdx, seriesScope);
- })
- .remove(function (idx) {
- group.remove(oldLineData.getItemGraphicEl(idx));
- })
- .execute();
-};
-
-function doAdd(lineDraw, lineData, idx, seriesScope) {
- var itemLayout = lineData.getItemLayout(idx);
-
- if (!lineNeedsDraw(itemLayout)) {
- return;
- }
+ isPersistent() {
+ return true;
+ };
- var el = new lineDraw._ctor(lineData, idx, seriesScope);
- lineData.setItemGraphicEl(idx, el);
- lineDraw.group.add(el);
-}
+ updateData(lineData: List<Model<LineOption>>) {
+ var lineDraw = this;
+ var group = lineDraw.group;
-function doUpdate(lineDraw, oldLineData, newLineData, oldIdx, newIdx, seriesScope) {
- var itemEl = oldLineData.getItemGraphicEl(oldIdx);
+ var oldLineData = lineDraw._lineData;
+ lineDraw._lineData = lineData;
- if (!lineNeedsDraw(newLineData.getItemLayout(newIdx))) {
- lineDraw.group.remove(itemEl);
- return;
- }
+ // There is no oldLineData only when first rendering or switching from
+ // stream mode to normal mode, where previous elements should be removed.
+ if (!oldLineData) {
+ group.removeAll();
+ }
- if (!itemEl) {
- itemEl = new lineDraw._ctor(newLineData, newIdx, seriesScope);
- }
- else {
- itemEl.updateData(newLineData, newIdx, seriesScope);
- }
+ var seriesScope = makeSeriesScope(lineData);
+
+ lineData.diff(oldLineData)
+ .add((idx) => {
+ this._doAdd(lineData, idx, seriesScope);
+ })
+ .update((newIdx, oldIdx) => {
+ this._doUpdate(oldLineData, lineData, oldIdx, newIdx, seriesScope);
+ })
+ .remove((idx) => {
+ group.remove(oldLineData.getItemGraphicEl(idx));
+ })
+ .execute();
+ };
- newLineData.setItemGraphicEl(newIdx, itemEl);
+ updateLayout() {
+ var lineData = this._lineData;
- lineDraw.group.add(itemEl);
-}
+ // Do not support update layout in incremental mode.
+ if (!lineData) {
+ return;
+ }
-lineDrawProto.updateLayout = function () {
- var lineData = this._lineData;
+ lineData.eachItemGraphicEl(function (el: LineLike, idx) {
+ el.updateLayout(lineData, idx);
+ }, this);
+ };
- // Do not support update layout in incremental mode.
- if (!lineData) {
- return;
- }
+ incrementalPrepareUpdate(lineData: List) {
+ this._seriesScope = makeSeriesScope(lineData);
+ this._lineData = null;
+ this.group.removeAll();
+ };
- lineData.eachItemGraphicEl(function (el, idx) {
- el.updateLayout(lineData, idx);
- }, this);
-};
-
-lineDrawProto.incrementalPrepareUpdate = function (lineData) {
- this._seriesScope = makeSeriesScope(lineData);
- this._lineData = null;
- this.group.removeAll();
-};
-
-lineDrawProto.incrementalUpdate = function (taskParams, lineData) {
- function updateIncrementalAndHover(el) {
- if (!el.isGroup) {
- el.incremental = el.useHoverLayer = true;
+ incrementalUpdate(taskParams: StageHandlerProgressParams, lineData: List) {
+ function updateIncrementalAndHover(el: Displayable) {
+ if (!el.isGroup) {
+ el.incremental = el.useHoverLayer = true;
+ }
}
- }
- for (var idx = taskParams.start; idx < taskParams.end; idx++) {
+ for (var idx = taskParams.start; idx < taskParams.end; idx++) {
+ var itemLayout = lineData.getItemLayout(idx);
+
+ if (lineNeedsDraw(itemLayout)) {
+ var el = new this._LineCtor(lineData, idx, this._seriesScope);
+ el.traverse(updateIncrementalAndHover);
+
+ this.group.add(el);
+ lineData.setItemGraphicEl(idx, el);
+ }
+ }
+ };
+
+ remove() {
+ this.group.removeAll();
+ };
+
+ private _doAdd(
+ lineData: List,
+ idx: number,
+ seriesScope: SeriesScope
+ ) {
var itemLayout = lineData.getItemLayout(idx);
- if (lineNeedsDraw(itemLayout)) {
- var el = new this._ctor(lineData, idx, this._seriesScope);
- el.traverse(updateIncrementalAndHover);
+ if (!lineNeedsDraw(itemLayout)) {
+ return;
+ }
- this.group.add(el);
- lineData.setItemGraphicEl(idx, el);
+ var el = new this._LineCtor(lineData, idx, seriesScope);
+ lineData.setItemGraphicEl(idx, el);
+ this.group.add(el);
+ }
+ private _doUpdate(
+ oldLineData: List,
+ newLineData: List,
+ oldIdx: number,
+ newIdx: number,
+ seriesScope: SeriesScope
+ ) {
+ var itemEl = oldLineData.getItemGraphicEl(oldIdx) as LineLike;
+
+ if (!lineNeedsDraw(newLineData.getItemLayout(newIdx))) {
+ this.group.remove(itemEl);
+ return;
}
+
+ if (!itemEl) {
+ itemEl = new this._LineCtor(newLineData, newIdx, seriesScope);
+ }
+ else {
+ itemEl.updateData(newLineData, newIdx, seriesScope);
+ }
+
+ newLineData.setItemGraphicEl(newIdx, itemEl);
+
+ this.group.add(itemEl);
}
-};
+}
-function makeSeriesScope(lineData) {
+function makeSeriesScope(lineData: List<Model<LineOption>>) {
var hostModel = lineData.hostModel;
return {
lineStyle: hostModel.getModel('lineStyle').getLineStyle(),
- hoverLineStyle: hostModel.getModel('emphasis.lineStyle').getLineStyle(),
+ hoverLineStyle: hostModel.getModel(['emphasis', 'lineStyle']).getLineStyle(),
labelModel: hostModel.getModel('label'),
- hoverLabelModel: hostModel.getModel('emphasis.label')
+ hoverLabelModel: hostModel.getModel(['emphasis', 'label'])
};
}
-lineDrawProto.remove = function () {
- this._clearIncremental();
- this._incremental = null;
- this.group.removeAll();
-};
-
-lineDrawProto._clearIncremental = function () {
- var incremental = this._incremental;
- if (incremental) {
- incremental.clearDisplaybles();
- }
-};
-
-function isPointNaN(pt) {
+function isPointNaN(pt: number[]) {
return isNaN(pt[0]) || isNaN(pt[1]);
}
-function lineNeedsDraw(pts) {
+function lineNeedsDraw(pts: number[][]) {
return !isPointNaN(pts[0]) && !isPointNaN(pts[1]);
}
+
export default LineDraw;
diff --git a/src/chart/helper/LinePath.ts b/src/chart/helper/LinePath.ts
index b1acce6..a6a414c 100644
--- a/src/chart/helper/LinePath.ts
+++ b/src/chart/helper/LinePath.ts
@@ -17,60 +17,79 @@
* under the License.
*/
-// @ts-nocheck
-
/**
* Line path for bezier and straight line draw
*/
import * as graphic from '../../util/graphic';
import * as vec2 from 'zrender/src/core/vector';
+import { PathProps } from 'zrender/src/graphic/Path';
var straightLineProto = graphic.Line.prototype;
var bezierCurveProto = graphic.BezierCurve.prototype;
-function isLine(shape) {
- return isNaN(+shape.cpx1) || isNaN(+shape.cpy1);
+class StraightLineShape {
+ // Start point
+ x1 = 0
+ y1 = 0
+ // End point
+ x2 = 0
+ y2 = 0
+
+ percent = 1
+}
+
+class CurveShape extends StraightLineShape {
+ cpx1: number
+ cpy1: number
}
-export default graphic.extendShape({
-
- type: 'ec-line',
-
- style: {
- stroke: '#000',
- fill: null
- },
-
- shape: {
- x1: 0,
- y1: 0,
- x2: 0,
- y2: 0,
- percent: 1,
- cpx1: null,
- cpy1: null
- },
-
- buildPath: function (ctx, shape) {
- this[isLine(shape) ? '_buildPathLine' : '_buildPathCurve'](ctx, shape);
- },
- _buildPathLine: straightLineProto.buildPath,
- _buildPathCurve: bezierCurveProto.buildPath,
-
- pointAt: function (t) {
- return this[isLine(this.shape) ? '_pointAtLine' : '_pointAtCurve'](t);
- },
- _pointAtLine: straightLineProto.pointAt,
- _pointAtCurve: bezierCurveProto.pointAt,
-
- tangentAt: function (t) {
+interface ECLineProps extends PathProps {
+ shape?: Partial<StraightLineShape | CurveShape>
+}
+function isStraightLine(shape: StraightLineShape | CurveShape): shape is StraightLineShape {
+ return isNaN(+(shape as CurveShape).cpx1) || isNaN(+(shape as CurveShape).cpy1);
+}
+
+class ECLinePath extends graphic.Path<ECLineProps> {
+
+ type = 'ec-line'
+
+ shape: StraightLineShape | CurveShape
+
+ constructor(opts?: ECLineProps) {
+ super(opts, {
+ stroke: '#000',
+ fill: null
+ }, new StraightLineShape());// Default to be line
+ }
+
+ buildPath(ctx: CanvasRenderingContext2D, shape: StraightLineShape | CurveShape) {
+ if (isStraightLine(shape)) {
+ straightLineProto.buildPath(ctx, shape);
+ }
+ else {
+ bezierCurveProto.buildPath(ctx, shape);
+ }
+ }
+
+ pointAt(t: number) {
+ if (isStraightLine(this.shape)) {
+ return straightLineProto.pointAt(t);
+ }
+ else {
+ return bezierCurveProto.pointAt(t);
+ }
+ }
+
+ tangentAt(t: number) {
var shape = this.shape;
- var p = isLine(shape)
+ var p = isStraightLine(shape)
? [shape.x2 - shape.x1, shape.y2 - shape.y1]
- : this._tangentAtCurve(t);
+ : bezierCurveProto.tangentAt(t);
return vec2.normalize(p, p);
- },
- _tangentAtCurve: bezierCurveProto.tangentAt
+ }
+
+}
-});
\ No newline at end of file
+export default ECLinePath;
\ No newline at end of file
diff --git a/src/chart/helper/Symbol.ts b/src/chart/helper/Symbol.ts
index 6c7242d..b9bc623 100644
--- a/src/chart/helper/Symbol.ts
+++ b/src/chart/helper/Symbol.ts
@@ -121,7 +121,7 @@ class Symbol extends graphic.Group {
* Get symbol path element.
*/
getSymbolPath() {
- return this.childAt(0);
+ return this.childAt(0) as ECSymbol;
}
/**
diff --git a/src/chart/line/LineSeries.ts b/src/chart/line/LineSeries.ts
index ac64978..cd788e1 100644
--- a/src/chart/line/LineSeries.ts
+++ b/src/chart/line/LineSeries.ts
@@ -30,7 +30,7 @@ import {
ItemStyleOption,
AreaStyleOption,
OptionDataValue,
- SeriesSymbolOptionMixin
+ SymbolOptionMixin
} from '../../util/types';
import List from '../../data/List';
import type Cartesian2D from '../../coord/cartesian/Cartesian2D';
@@ -40,7 +40,7 @@ type SamplingFunc = (frame: number[]) => number
type LineDataValue = OptionDataValue | OptionDataValue[]
-export interface LineDataItemOption {
+export interface LineDataItemOption extends SymbolOptionMixin {
name?: string
value?: LineDataValue
@@ -58,7 +58,7 @@ export interface LineSeriesOption extends SeriesOption,
SeriesOnCartesianOptionMixin,
SeriesOnPolarOptionMixin,
SeriesStackOptionMixin,
- SeriesSymbolOptionMixin {
+ SymbolOptionMixin {
coordinateSystem?: 'cartesian2d' | 'polar'
hoverAnimation?: boolean
diff --git a/src/chart/map/MapSeries.ts b/src/chart/map/MapSeries.ts
index 6b1c8b1..7c4625f 100644
--- a/src/chart/map/MapSeries.ts
+++ b/src/chart/map/MapSeries.ts
@@ -26,7 +26,17 @@ import {DataSelectableMixin, DataSelectableOptionMixin, SelectableTarget} from '
import {retrieveRawAttr} from '../../data/helper/dataProvider';
import geoSourceManager from '../../coord/geo/geoSourceManager';
import {makeSeriesEncodeForNameBased} from '../../data/helper/sourceHelper';
-import { SeriesOption, BoxLayoutOptionMixin, SeriesEncodeOptionMixin, LabelOption, SeriesTooltipOption, OptionDataItemObject, OptionDataValueNumeric, ParsedValue, SeriesOnGeoOptionMixin } from '../../util/types';
+import {
+ SeriesOption,
+ BoxLayoutOptionMixin,
+ SeriesEncodeOptionMixin,
+ LabelOption,
+ SeriesTooltipOption,
+ OptionDataItemObject,
+ OptionDataValueNumeric,
+ ParsedValue,
+ SeriesOnGeoOptionMixin
+} from '../../util/types';
import { Dictionary } from 'zrender/src/core/types';
import GeoModel, { GeoCommonOptionMixin, GeoItemStyleOption } from '../../coord/geo/GeoModel';
import List from '../../data/List';
diff --git a/src/chart/pictorialBar.ts b/src/chart/pictorialBar.ts
index 86dadf7..975e4d9 100644
--- a/src/chart/pictorialBar.ts
+++ b/src/chart/pictorialBar.ts
@@ -17,8 +17,6 @@
* under the License.
*/
-// @ts-nocheck
-
import * as echarts from '../echarts';
import * as zrUtil from 'zrender/src/core/util';
diff --git a/src/chart/pie/PieSeries.ts b/src/chart/pie/PieSeries.ts
index 9a51351..a161e41 100644
--- a/src/chart/pie/PieSeries.ts
+++ b/src/chart/pie/PieSeries.ts
@@ -30,7 +30,7 @@ import {
SeriesOption,
CallbackDataParams,
CircleLayoutOptionMixin,
- LabelLineOption,
+ LabelGuideLineOption,
ItemStyleOption,
LabelOption,
BoxLayoutOptionMixin,
@@ -54,12 +54,12 @@ interface PieDataItem extends
itemStyle?: ItemStyleOption
label?: PieLabelOption
- labelLine?: LabelLineOption
+ labelLine?: LabelGuideLineOption
emphasis?: {
itemStyle?: ItemStyleOption
label?: PieLabelOption
- labelLine?: LabelLineOption
+ labelLine?: LabelGuideLineOption
}
}
export interface PieSeriesOption extends
@@ -78,7 +78,7 @@ export interface PieSeriesOption extends
// TODO: TYPE Color Callback
itemStyle?: ItemStyleOption
label?: PieLabelOption
- labelLine?: LabelLineOption
+ labelLine?: LabelGuideLineOption
clockwise?: boolean
startAngle?: number
@@ -96,7 +96,7 @@ export interface PieSeriesOption extends
emphasis?: {
itemStyle?: ItemStyleOption
label?: PieLabelOption
- labelLine?: LabelLineOption
+ labelLine?: LabelGuideLineOption
}
animationType?: 'expansion' | 'scale'
diff --git a/src/chart/radar.ts b/src/chart/radar.ts
index 39ce9be..0ed87f7 100644
--- a/src/chart/radar.ts
+++ b/src/chart/radar.ts
@@ -17,8 +17,6 @@
* under the License.
*/
-// @ts-nocheck
-
import * as echarts from '../echarts';
// Must use radar component
diff --git a/src/chart/scatter/ScatterSeries.ts b/src/chart/scatter/ScatterSeries.ts
index db4829c..f5cd3df 100644
--- a/src/chart/scatter/ScatterSeries.ts
+++ b/src/chart/scatter/ScatterSeries.ts
@@ -31,14 +31,14 @@ import {
LabelOption,
SeriesLargeOptionMixin,
SeriesStackOptionMixin,
- SeriesSymbolOptionMixin
+ SymbolOptionMixin
} from '../../util/types';
import GlobalModel from '../../model/Global';
import List from '../../data/List';
type ScatterDataValue = OptionDataValue | OptionDataValue[]
-export interface ScatterDataItemOption {
+export interface ScatterDataItemOption extends SymbolOptionMixin {
name?: string
value?: ScatterDataValue
@@ -56,7 +56,7 @@ export interface ScatterSeriesOption extends SeriesOption,
SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, SeriesOnCalendarOptionMixin,
SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin,
SeriesLargeOptionMixin, SeriesStackOptionMixin,
- SeriesSymbolOptionMixin {
+ SymbolOptionMixin {
coordinateSystem?: string
diff --git a/src/chart/themeRiver.ts b/src/chart/themeRiver.ts
index 87cec62..26f136c 100644
--- a/src/chart/themeRiver.ts
+++ b/src/chart/themeRiver.ts
@@ -17,8 +17,6 @@
* under the License.
*/
-// @ts-nocheck
-
import * as echarts from '../echarts';
import '../component/singleAxis';
diff --git a/src/chart/tree.ts b/src/chart/tree.ts
index 20ab129..e498d25 100644
--- a/src/chart/tree.ts
+++ b/src/chart/tree.ts
@@ -17,8 +17,6 @@
* under the License.
*/
-// @ts-nocheck
-
import * as echarts from '../echarts';
import './tree/TreeSeries';
diff --git a/src/chart/treemap.ts b/src/chart/treemap.ts
index 60bf7f0..3414052 100644
--- a/src/chart/treemap.ts
+++ b/src/chart/treemap.ts
@@ -17,8 +17,6 @@
* under the License.
*/
-// @ts-nocheck
-
import * as echarts from '../echarts';
import './treemap/TreemapSeries';
diff --git a/src/component/helper/RoamController.ts b/src/component/helper/RoamController.ts
index 5f6454c..4a1d12e 100644
--- a/src/component/helper/RoamController.ts
+++ b/src/component/helper/RoamController.ts
@@ -21,12 +21,12 @@ import Eventful from 'zrender/src/core/Eventful';
import * as eventTool from 'zrender/src/core/event';
import * as interactionMutex from './interactionMutex';
import { ZRenderType } from 'zrender/src/zrender';
-import { ZRElementEvent } from '../../util/types';
+import { ZRElementEvent, RoamOptionMixin } from '../../util/types';
import { Bind3, isString, bind, defaults, clone } from 'zrender/src/core/util';
// Can be null/undefined or true/false
// or 'pan/move' or 'zoom'/'scale'
-export type RoamType = boolean | 'pan' | 'move' | 'zoom' | 'scale';
+export type RoamType = RoamOptionMixin['roam']
interface RoamOption {
zoomOnMouseWheel?: boolean | 'ctrl' | 'shift' | 'alt'
diff --git a/src/coord/View.ts b/src/coord/View.ts
index ebf0e42..1e0762f 100644
--- a/src/coord/View.ts
+++ b/src/coord/View.ts
@@ -57,7 +57,7 @@ class View extends Transformable implements CoordinateSystemMaster, CoordinateSy
private _rawTransform: matrix.MatrixArray;
- constructor(name: string) {
+ constructor(name?: string) {
super();
this.name = name;
}
diff --git a/src/coord/geo/GeoModel.ts b/src/coord/geo/GeoModel.ts
index 3b590a5..00d795f 100644
--- a/src/coord/geo/GeoModel.ts
+++ b/src/coord/geo/GeoModel.ts
@@ -31,7 +31,8 @@ import {
ItemStyleOption,
ZRColor,
LabelOption,
- DisplayState
+ DisplayState,
+ RoamOptionMixin
} from '../../util/types';
import { RoamType } from '../../component/helper/RoamController';
import { NameMap } from './geoTypes';
@@ -58,7 +59,7 @@ export interface RegoinOption extends SelectableTarget {
}
};
-export interface GeoCommonOptionMixin {
+export interface GeoCommonOptionMixin extends RoamOptionMixin {
// Map name
map: string;
@@ -76,10 +77,6 @@ export interface GeoCommonOptionMixin {
// For example, [ [180, 90], [-180, -90] ]
// higher priority than center and zoom
boundingCoords?: number[][];
- // Default on center of map
- center?: number[];
- roam?: RoamType;
- zoom?: number;
scaleLimit?: {
min?: number;
diff --git a/src/data/Graph.ts b/src/data/Graph.ts
index b5eef6c..6322319 100644
--- a/src/data/Graph.ts
+++ b/src/data/Graph.ts
@@ -317,8 +317,6 @@ class Graph {
return graph;
};
- static Node: typeof GraphNode
- static Edge: typeof GraphEdge
}
@@ -367,7 +365,7 @@ class GraphNode {
}
// TODO: TYPE Same type with Model#getModel
- getModel(path: string | string[]): Model {
+ getModel(path?: string | string[]): Model {
if (this.dataIndex < 0) {
return;
}
@@ -399,7 +397,7 @@ class GraphEdge {
this.dataIndex = dataIndex == null ? -1 : dataIndex;
}
- getModel(path: string | string[]): Model {
+ getModel(path?: string | string[]): Model {
if (this.dataIndex < 0) {
return;
}
@@ -460,8 +458,6 @@ interface GraphNode extends ReturnType<typeof createGraphDataProxyMixin> {};
zrUtil.mixin(GraphEdge, createGraphDataProxyMixin('hostGraph', 'data'));
zrUtil.mixin(GraphNode, createGraphDataProxyMixin('hostGraph', 'edgeData'));
-Graph.Node = GraphNode;
-Graph.Edge = GraphEdge;
-
-
export default Graph;
+
+export {GraphNode, GraphEdge};
\ No newline at end of file
diff --git a/src/data/List.ts b/src/data/List.ts
index 6a1be69..37be86c 100644
--- a/src/data/List.ts
+++ b/src/data/List.ts
@@ -39,6 +39,8 @@ import {
} from '../util/types';
import {parseDate} from '../util/number';
import {isDataItemOption} from '../util/model';
+import type Graph from './Graph';
+import type Tree from './Tree';
var isObject = zrUtil.isObject;
@@ -120,8 +122,7 @@ var CLONE_PROPERTIES = [
];
-
-class List <HostModel extends Model = Model> {
+class List<HostModel extends Model = Model> {
readonly type = 'list';
@@ -134,6 +135,15 @@ class List <HostModel extends Model = Model> {
readonly dataType: string;
+ /**
+ * Host graph if List is used to store graph nodes / edges.
+ */
+ readonly graph: Graph
+ /**
+ * Host tree if List is used to store tree ndoes.
+ */
+ readonly tree: Tree
+
// Indices stores the indices of data subset after filtered.
// This data subset will be used in chart.
private _indices: ArrayLike<any>;
@@ -1375,11 +1385,11 @@ class List <HostModel extends Model = Model> {
/**
* Data mapping to a plain array
*/
- mapArray<Ctx>(cb: MapArrayCb0<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): any[];
- mapArray<Ctx>(dims: DimensionLoose, cb: MapArrayCb1<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): any[];
- mapArray<Ctx>(dims: [DimensionLoose], cb: MapArrayCb1<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): any[];
- mapArray<Ctx>(dims: [DimensionLoose, DimensionLoose], cb: MapArrayCb2<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): any[];
- mapArray<Ctx>(dims: ItrParamDims, cb: MapArrayCb<Ctx>, ctx?: Ctx, ctxCompat?: Ctx): any[];
+ mapArray<Ctx, Cb extends MapArrayCb0<Ctx>>(cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
+ mapArray<Ctx, Cb extends MapArrayCb1<Ctx>>(dims: DimensionLoose, cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
+ mapArray<Ctx, Cb extends MapArrayCb1<Ctx>>(dims: [DimensionLoose], cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
+ mapArray<Ctx, Cb extends MapArrayCb2<Ctx>>(dims: [DimensionLoose, DimensionLoose], cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
+ mapArray<Ctx, Cb extends MapArrayCb<Ctx>>(dims: ItrParamDims, cb: Cb, ctx?: Ctx, ctxCompat?: Ctx): ReturnType<Cb>[];
mapArray<Ctx>(
dims: ItrParamDims | MapArrayCb<Ctx>,
cb: MapArrayCb<Ctx> | Ctx,
@@ -1637,7 +1647,7 @@ class List <HostModel extends Model = Model> {
/**
* Get layout of single data item
*/
- getItemLayout(idx: number): Dictionary<any> {
+ getItemLayout(idx: number): any {
return this._itemLayouts[idx];
}
diff --git a/src/data/Tree.ts b/src/data/Tree.ts
index a8aa124..c9c0e85 100644
--- a/src/data/Tree.ts
+++ b/src/data/Tree.ts
@@ -287,7 +287,7 @@ class TreeNode {
}
};
-class Tree<HostModel extends Model, LevelOption, LeavesOption> {
+class Tree<HostModel extends Model = Model, LevelOption = any, LeavesOption = any> {
type: 'tree' = 'tree'
diff --git a/src/echarts.ts b/src/echarts.ts
index c82c1d6..0c97527 100644
--- a/src/echarts.ts
+++ b/src/echarts.ts
@@ -722,7 +722,9 @@ class ECharts {
getVisual(finder: ModelFinder, visualType: string) {
var ecModel = this._model;
- finder = modelUtil.parseFinder(ecModel, finder, {defaultMainType: 'series'});
+ finder = modelUtil.parseFinder(ecModel, finder, {
+ defaultMainType: 'series'
+ });
var seriesModel = finder.seriesModel;
diff --git a/src/model/Series.ts b/src/model/Series.ts
index e0ea224..acb70db 100644
--- a/src/model/Series.ts
+++ b/src/model/Series.ts
@@ -29,7 +29,7 @@ import {
import * as modelUtil from '../util/model';
import {
DataHost, DimensionName, StageHandlerProgressParams,
- SeriesOption, TooltipRenderMode, ZRColor, BoxLayoutOptionMixin, ScaleDataValue
+ SeriesOption, TooltipRenderMode, ZRColor, BoxLayoutOptionMixin, ScaleDataValue, Dictionary, ColorString
} from '../util/types';
import ComponentModel, { ComponentModelConstructor } from './Component';
import {ColorPaletteMixin} from './mixin/colorPalette';
@@ -54,6 +54,7 @@ import LegendVisualProvider from '../visual/LegendVisualProvider';
import List from '../data/List';
import Source from '../data/Source';
import Axis from '../coord/Axis';
+import { GradientObject } from 'zrender/src/graphic/Gradient';
var inner = modelUtil.makeInner<{
data: List
@@ -340,14 +341,14 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
renderMode?: TooltipRenderMode
): {
html: string,
- markers: {[markName: string]: string}
+ markers: Dictionary<ColorString>
} | string { // The override method can also return string
var series = this;
renderMode = renderMode || 'html';
var newLine = renderMode === 'html' ? '<br/>' : '\n';
var isRichText = renderMode === 'richText';
- var markers: {[markName: string]: string} = {};
+ var markers: Dictionary<ColorString> = {};
var markerId = 0;
function formatArrayValue(value: any[]) {
@@ -376,7 +377,7 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
var dimType = dimInfo.type;
var markName = 'sub' + series.seriesIndex + 'at' + markerId;
var dimHead = getTooltipMarker({
- color: color,
+ color: colorStr,
type: 'subItem',
renderMode: renderMode,
markerId: markName
@@ -397,7 +398,7 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
valStr && result.push(valStr);
if (isRichText) {
- markers[markName] = color;
+ markers[markName] = colorStr;
++markerId;
}
}
@@ -426,11 +427,15 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
var value = this.getRawValue(dataIndex);
var isValueArr = zrUtil.isArray(value);
- var color = data.getItemVisual(dataIndex, 'color');
- if (zrUtil.isObject(color) && color.colorStops) {
- color = (color.colorStops[0] || {}).color;
+ var color = data.getItemVisual(dataIndex, 'color') as ZRColor;
+ var colorStr: ColorString;
+ if (zrUtil.isString(color)) {
+ colorStr = color;
}
- color = color || 'transparent';
+ else if (color && (color as GradientObject).colorStops) {
+ colorStr = ((color as GradientObject).colorStops[0] || {}).color;
+ }
+ colorStr = colorStr || 'transparent';
// Complicated rule for pretty tooltip.
var formattedValue = (tooltipDimLen > 1 || (isValueArr && !tooltipDimLen))
@@ -442,12 +447,12 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
var markName = series.seriesIndex + 'at' + markerId;
var colorEl = getTooltipMarker({
- color: color,
+ color: colorStr,
type: 'item',
renderMode: renderMode,
markerId: markName
});
- markers[markName] = color;
+ markers[markName] = colorStr;
++markerId;
var name = data.getName(dataIndex);
@@ -495,7 +500,7 @@ class SeriesModel<Opt extends SeriesOption = SeriesOption> extends ComponentMode
this.dataTask.dirty();
}
- getColorFromPalette(name: string, scope: any, requestColorNum: number): ZRColor {
+ getColorFromPalette(name: string, scope: any, requestColorNum?: number): ZRColor {
var ecModel = this.ecModel;
// PENDING
var color = ColorPaletteMixin.prototype.getColorFromPalette.call(this, name, scope, requestColorNum);
diff --git a/src/model/mixin/dataFormat.ts b/src/model/mixin/dataFormat.ts
index 696f350..3ccaa2f 100644
--- a/src/model/mixin/dataFormat.ts
+++ b/src/model/mixin/dataFormat.ts
@@ -42,7 +42,6 @@ class DataFormatMixin {
* Get params for formatter
*/
getDataParams(
- this: DataFormatMixin,
dataIndex: number,
dataType?: string,
el?: Element // May be used in override.
@@ -101,7 +100,6 @@ class DataFormatMixin {
* @return If not formatter, return null/undefined
*/
getFormattedLabel(
- this: DataFormatMixin,
dataIndex: number,
status?: DisplayState,
dataType?: string,
@@ -145,12 +143,8 @@ class DataFormatMixin {
/**
* Get raw value in option
- * @param {number} idx
- * @param {string} [dataType]
- * @return {Array|number|string}
*/
getRawValue(
- this: DataFormatMixin,
idx: number,
dataType?: string
) {
@@ -169,7 +163,6 @@ class DataFormatMixin {
* DOM operation is not supported.
*/
formatTooltip(
- this: DataFormatMixin,
dataIndex: number,
multipleSeries?: boolean,
dataType?: string,
diff --git a/src/util/format.ts b/src/util/format.ts
index 217aef6..ca945a4 100644
--- a/src/util/format.ts
+++ b/src/util/format.ts
@@ -20,7 +20,7 @@
import * as zrUtil from 'zrender/src/core/util';
import * as textContain from 'zrender/src/contain/text';
import * as numberUtil from './number';
-import {TooltipRenderMode} from './types';
+import {TooltipRenderMode, ColorString} from './types';
import { Dictionary } from 'zrender/src/core/types';
import { StyleProps } from 'zrender/src/graphic/Style';
// import Text from 'zrender/src/graphic/Text';
@@ -131,13 +131,13 @@ interface RichTextTooltipMarker {
renderMode: TooltipRenderMode;
content: string;
style: {
- color: string
+ color: ColorString
[key: string]: any
};
}
export type TooltipMarker = string | RichTextTooltipMarker;
interface GetTooltipMarkerOpt {
- color?: string;
+ color?: ColorString;
extraCssText?: string;
// By default: 'item'
type?: 'item' | 'subItem';
@@ -146,10 +146,14 @@ interface GetTooltipMarkerOpt {
// By default: 'X'
markerId?: string;
}
-export function getTooltipMarker(color: string, extraCssText?: string): TooltipMarker;
+// Only support color string
+export function getTooltipMarker(color: ColorString, extraCssText?: string): TooltipMarker;
export function getTooltipMarker(opt: GetTooltipMarkerOpt): TooltipMarker;
-export function getTooltipMarker(opt: string | GetTooltipMarkerOpt, extraCssText?: string): TooltipMarker {
- opt = zrUtil.isString(opt) ? {color: opt, extraCssText: extraCssText} : (opt || {});
+export function getTooltipMarker(inOpt: ColorString | GetTooltipMarkerOpt, extraCssText?: string): TooltipMarker {
+ var opt = zrUtil.isString(inOpt) ? {
+ color: inOpt,
+ extraCssText: extraCssText
+ } : (inOpt || {}) as GetTooltipMarkerOpt;
var color = opt.color;
var type = opt.type;
var extraCssText = opt.extraCssText;
@@ -164,6 +168,7 @@ export function getTooltipMarker(opt: string | GetTooltipMarkerOpt, extraCssText
return type === 'subItem'
? '<span style="display:inline-block;vertical-align:middle;margin-right:8px;margin-left:3px;'
+ 'border-radius:4px;width:4px;height:4px;background-color:'
+ // Only support string
+ encodeHTML(color) + ';' + (extraCssText || '') + '"></span>'
: '<span style="display:inline-block;margin-right:5px;'
+ 'border-radius:10px;width:10px;height:10px;background-color:'
diff --git a/src/util/types.ts b/src/util/types.ts
index d2b34c5..6667c53 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -590,22 +590,44 @@ export interface AnimationOptionMixin {
animationDelayUpdate?: number | AnimationDelayCallback
}
+export interface RoamOptionMixin {
+ /**
+ * If enable roam. can be specified 'scale' or 'move'
+ */
+ roam?: boolean | 'pan' | 'move' | 'zoom' | 'scale'
+ /**
+ * Current center position.
+ */
+ center?: number[]
+ /**
+ * Current zoom level. Default is 1
+ */
+ zoom?: number
+
+ scaleLimit?: {
+ min?: number
+ max?: number
+ }
+}
+
// TODO: TYPE value type?
-export type SymbolSizeCallback = (rawValue: any, params: CallbackDataParams) => number | number[]
-export type SymbolCallback = (rawValue: any, params: CallbackDataParams) => string
+export type SymbolSizeCallback<T> = (rawValue: any, params: T) => number | number[]
+export type SymbolCallback<T> = (rawValue: any, params: T) => string
/**
* Mixin of option set to control the element symbol.
* Include type of symbol, and size of symbol.
*/
-export interface SymbolOptionMixin {
+export interface SymbolOptionMixin<T = unknown> {
/**
* type of symbol, like `cirlce`, `rect`, or custom path and image.
*/
- symbol?: string | SymbolCallback
+ symbol?: string | (unknown extends T ? never : SymbolCallback<T>)
/**
* Size of symbol.
*/
- symbolSize?: number | number[] | SymbolSizeCallback
+ symbolSize?: number | number[] | (unknown extends T ? never : SymbolSizeCallback<T>)
+
+ symbolRotate?: number
symbolKeepAspect?: boolean
}
@@ -712,6 +734,10 @@ export interface TextCommonOption extends ShadowOptionMixin {
tag?: string
}
+
+export interface LabelFormatterCallback<T = CallbackDataParams> {
+ (params: T): string
+}
/**
* LabelOption is an option set to control the style of labels.
* Include color, background, shadow, truncate, rotation, distance, etc..
@@ -734,7 +760,18 @@ export interface LabelOption extends TextCommonOption {
rich?: Dictionary<TextCommonOption>
}
-export interface LabelLineOption {
+/**
+ * Option for labels on line, like markLine, lines
+ */
+export interface LineLabelOption extends Omit<LabelOption, 'distance'> {
+ /**
+ * Distance can be an array.
+ * Which will specify horizontal and vertical distance respectively
+ */
+ distance?: number | number[]
+}
+
+export interface LabelGuideLineOption {
show?: boolean
length?: number
length2?: number
@@ -1052,11 +1089,6 @@ export interface SeriesLargeOptionMixin {
export interface SeriesStackOptionMixin {
stack?: string
}
-export interface SeriesSymbolOptionMixin {
- symbol?: string
- symbolSize?: number | number[]
- symbolRotate?: number
-}
export interface SeriesEncodeOptionMixin {
datasetIndex?: number;
diff --git a/src/visual/symbol.ts b/src/visual/symbol.ts
index facc227..c9d2012 100644
--- a/src/visual/symbol.ts
+++ b/src/visual/symbol.ts
@@ -18,7 +18,14 @@
*/
import {isFunction} from 'zrender/src/core/util';
-import { StageHandler, SeriesOption, SymbolOptionMixin, SymbolSizeCallback, SymbolCallback } from '../util/types';
+import {
+ StageHandler,
+ SeriesOption,
+ SymbolOptionMixin,
+ SymbolSizeCallback,
+ SymbolCallback,
+ CallbackDataParams
+} from '../util/types';
import List from '../data/List';
import SeriesModel from '../model/Series';
import GlobalModel from '../model/Global';
@@ -32,7 +39,7 @@ export default function (seriesType: string, defaultSymbolType: string, legendSy
performRawSeries: true,
reset: function (
- seriesModel: SeriesModel<SeriesOption & SymbolOptionMixin>,
+ seriesModel: SeriesModel<SeriesOption & SymbolOptionMixin<CallbackDataParams>>,
ecModel: GlobalModel
) {
var data = seriesModel.getData();
@@ -68,10 +75,10 @@ export default function (seriesType: string, defaultSymbolType: string, legendSy
var rawValue = seriesModel.getRawValue(idx);
var params = seriesModel.getDataParams(idx);
hasSymbolTypeCallback && data.setItemVisual(
- idx, 'symbol', (symbolType as SymbolCallback)(rawValue, params)
+ idx, 'symbol', (symbolType as SymbolCallback<CallbackDataParams>)(rawValue, params)
);
hasSymbolSizeCallback && data.setItemVisual(
- idx, 'symbolSize', (symbolSize as SymbolSizeCallback)(rawValue, params)
+ idx, 'symbolSize', (symbolSize as SymbolSizeCallback<CallbackDataParams>)(rawValue, params)
);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org