| /* |
| * 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. |
| */ |
| |
| import SeriesModel from '../../model/Series'; |
| import Tree from '../../data/Tree'; |
| import { |
| SeriesOption, |
| SymbolOptionMixin, |
| BoxLayoutOptionMixin, |
| RoamOptionMixin, |
| LineStyleOption, |
| ItemStyleOption, |
| SeriesLabelOption, |
| OptionDataValue, |
| StatesOptionMixin, |
| OptionDataItemObject, |
| CallbackDataParams, |
| DefaultEmphasisFocus |
| } from '../../util/types'; |
| import List from '../../data/List'; |
| import View from '../../coord/View'; |
| import { LayoutRect } from '../../util/layout'; |
| import Model from '../../model/Model'; |
| import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup'; |
| import { wrapTreePathInfo } from '../helper/treeHelper'; |
| |
| interface CurveLineStyleOption extends LineStyleOption{ |
| curveness?: number |
| } |
| |
| export interface TreeSeriesStateOption { |
| itemStyle?: ItemStyleOption |
| /** |
| * Line style of the edge between node and it's parent. |
| */ |
| lineStyle?: CurveLineStyleOption |
| label?: SeriesLabelOption |
| } |
| |
| interface ExtraStateOption { |
| emphasis?: { |
| focus?: DefaultEmphasisFocus | 'ancestor' | 'descendant' |
| scale?: boolean |
| } |
| } |
| |
| export interface TreeSeriesNodeItemOption extends SymbolOptionMixin<CallbackDataParams>, |
| TreeSeriesStateOption, StatesOptionMixin<TreeSeriesStateOption, ExtraStateOption>, |
| OptionDataItemObject<OptionDataValue> { |
| |
| children?: TreeSeriesNodeItemOption[] |
| |
| collapsed?: boolean |
| |
| link?: string |
| target?: string |
| } |
| |
| /** |
| * Configuration of leaves nodes. |
| */ |
| export interface TreeSeriesLeavesOption extends TreeSeriesStateOption, StatesOptionMixin<TreeSeriesStateOption> { |
| |
| } |
| |
| export interface TreeSeriesOption extends |
| SeriesOption<TreeSeriesStateOption, ExtraStateOption>, TreeSeriesStateOption, |
| SymbolOptionMixin, BoxLayoutOptionMixin, RoamOptionMixin { |
| type?: 'tree' |
| |
| layout?: 'orthogonal' | 'radial' |
| |
| edgeShape?: 'polyline' | 'curve' |
| |
| /** |
| * Available when edgeShape is polyline |
| */ |
| edgeForkPosition?: string | number |
| |
| nodeScaleRatio?: number |
| |
| /** |
| * The orient of orthoginal layout, can be setted to 'LR', 'TB', 'RL', 'BT'. |
| * and the backward compatibility configuration 'horizontal = LR', 'vertical = TB'. |
| */ |
| orient?: 'LR' | 'TB' | 'RL' | 'BT' | 'horizontal' | 'vertical' |
| |
| expandAndCollapse?: boolean |
| |
| /** |
| * The initial expanded depth of tree |
| */ |
| initialTreeDepth?: number |
| |
| leaves?: TreeSeriesLeavesOption |
| |
| data?: TreeSeriesNodeItemOption[] |
| } |
| |
| export interface TreeAncestors { |
| name: string |
| dataIndex: number |
| value: number |
| } |
| |
| export interface TreeSeriesCallbackDataParams extends CallbackDataParams { |
| treeAncestors?: TreeAncestors[] |
| } |
| |
| class TreeSeriesModel extends SeriesModel<TreeSeriesOption> { |
| static readonly type = 'series.tree'; |
| |
| // can support the position parameters 'left', 'top','right','bottom', 'width', |
| // 'height' in the setOption() with 'merge' mode normal. |
| static readonly layoutMode = 'box'; |
| |
| coordinateSystem: View; |
| |
| layoutInfo: LayoutRect; |
| |
| hasSymbolVisual = true; |
| |
| // Do it self. |
| ignoreStyleOnData = true; |
| |
| /** |
| * Init a tree data structure from data in option series |
| * @param option the object used to config echarts view |
| * @return storage initial data |
| */ |
| getInitialData(option: TreeSeriesOption): List { |
| |
| //create an virtual root |
| const root: TreeSeriesNodeItemOption = { |
| name: option.name, |
| children: option.data |
| }; |
| |
| const leaves = option.leaves || {}; |
| const leavesModel = new Model(leaves, this, this.ecModel); |
| |
| const tree = Tree.createTree(root, this, beforeLink); |
| |
| function beforeLink(nodeData: List) { |
| nodeData.wrapMethod('getItemModel', function (model, idx) { |
| const node = tree.getNodeByDataIndex(idx); |
| if (!(node && node.children.length && node.isExpand)) { |
| model.parentModel = leavesModel; |
| } |
| return model; |
| }); |
| } |
| |
| let treeDepth = 0; |
| |
| tree.eachNode('preorder', function (node) { |
| if (node.depth > treeDepth) { |
| treeDepth = node.depth; |
| } |
| }); |
| |
| const expandAndCollapse = option.expandAndCollapse; |
| const expandTreeDepth = (expandAndCollapse && option.initialTreeDepth >= 0) |
| ? option.initialTreeDepth : treeDepth; |
| |
| tree.root.eachNode('preorder', function (node) { |
| const item = node.hostTree.data.getRawDataItem(node.dataIndex) as TreeSeriesNodeItemOption; |
| // Add item.collapsed != null, because users can collapse node original in the series.data. |
| node.isExpand = (item && item.collapsed != null) |
| ? !item.collapsed |
| : node.depth <= expandTreeDepth; |
| }); |
| |
| return tree.data; |
| } |
| |
| /** |
| * Make the configuration 'orient' backward compatibly, with 'horizontal = LR', 'vertical = TB'. |
| * @returns {string} orient |
| */ |
| getOrient() { |
| let orient = this.get('orient'); |
| if (orient === 'horizontal') { |
| orient = 'LR'; |
| } |
| else if (orient === 'vertical') { |
| orient = 'TB'; |
| } |
| return orient; |
| } |
| |
| setZoom(zoom: number) { |
| this.option.zoom = zoom; |
| } |
| |
| setCenter(center: number[]) { |
| this.option.center = center; |
| } |
| |
| formatTooltip( |
| dataIndex: number, |
| multipleSeries: boolean, |
| dataType: string |
| ) { |
| const tree = this.getData().tree; |
| const realRoot = tree.root.children[0]; |
| let node = tree.getNodeByDataIndex(dataIndex); |
| const value = node.getValue(); |
| let name = node.name; |
| while (node && (node !== realRoot)) { |
| name = node.parentNode.name + '.' + name; |
| node = node.parentNode; |
| } |
| |
| return createTooltipMarkup('nameValue', { |
| name: name, |
| value: value, |
| noValue: isNaN(value as number) || value == null |
| }); |
| } |
| |
| // Add tree path to tooltip param |
| getDataParams(dataIndex: number) { |
| const params = super.getDataParams.apply(this, arguments as any) as TreeSeriesCallbackDataParams; |
| |
| const node = this.getData().tree.getNodeByDataIndex(dataIndex); |
| params.treeAncestors = wrapTreePathInfo(node, this); |
| |
| return params; |
| } |
| |
| static defaultOption: TreeSeriesOption = { |
| zlevel: 0, |
| z: 2, |
| coordinateSystem: 'view', |
| |
| // the position of the whole view |
| left: '12%', |
| top: '12%', |
| right: '12%', |
| bottom: '12%', |
| |
| // the layout of the tree, two value can be selected, 'orthogonal' or 'radial' |
| layout: 'orthogonal', |
| |
| // value can be 'polyline' |
| edgeShape: 'curve', |
| |
| edgeForkPosition: '50%', |
| |
| // true | false | 'move' | 'scale', see module:component/helper/RoamController. |
| roam: false, |
| |
| // Symbol size scale ratio in roam |
| nodeScaleRatio: 0.4, |
| |
| // Default on center of graph |
| center: null, |
| |
| zoom: 1, |
| |
| orient: 'LR', |
| |
| symbol: 'emptyCircle', |
| |
| symbolSize: 7, |
| |
| expandAndCollapse: true, |
| |
| initialTreeDepth: 2, |
| |
| lineStyle: { |
| color: '#ccc', |
| width: 1.5, |
| curveness: 0.5 |
| }, |
| |
| itemStyle: { |
| color: 'lightsteelblue', |
| // borderColor: '#c23531', |
| borderWidth: 1.5 |
| }, |
| |
| label: { |
| show: true |
| }, |
| |
| animationEasing: 'linear', |
| |
| animationDuration: 700, |
| |
| animationDurationUpdate: 500 |
| }; |
| } |
| |
| export default TreeSeriesModel; |