mirror of
https://gitlab.com/JKANetwork/CheckServer.git
synced 2026-04-05 02:02:01 +02:00
Start again
This commit is contained in:
120
vendors/echarts/src/data/DataDiffer.js
vendored
Normal file
120
vendors/echarts/src/data/DataDiffer.js
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
define(function(require) {
|
||||
'use strict';
|
||||
|
||||
function defaultKeyGetter(item) {
|
||||
return item;
|
||||
}
|
||||
|
||||
function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter) {
|
||||
this._old = oldArr;
|
||||
this._new = newArr;
|
||||
|
||||
this._oldKeyGetter = oldKeyGetter || defaultKeyGetter;
|
||||
this._newKeyGetter = newKeyGetter || defaultKeyGetter;
|
||||
}
|
||||
|
||||
DataDiffer.prototype = {
|
||||
|
||||
constructor: DataDiffer,
|
||||
|
||||
/**
|
||||
* Callback function when add a data
|
||||
*/
|
||||
add: function (func) {
|
||||
this._add = func;
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback function when update a data
|
||||
*/
|
||||
update: function (func) {
|
||||
this._update = func;
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback function when remove a data
|
||||
*/
|
||||
remove: function (func) {
|
||||
this._remove = func;
|
||||
return this;
|
||||
},
|
||||
|
||||
execute: function () {
|
||||
var oldArr = this._old;
|
||||
var newArr = this._new;
|
||||
var oldKeyGetter = this._oldKeyGetter;
|
||||
var newKeyGetter = this._newKeyGetter;
|
||||
|
||||
var oldDataIndexMap = {};
|
||||
var newDataIndexMap = {};
|
||||
var i;
|
||||
|
||||
initIndexMap(oldArr, oldDataIndexMap, oldKeyGetter);
|
||||
initIndexMap(newArr, newDataIndexMap, newKeyGetter);
|
||||
|
||||
// Travel by inverted order to make sure order consistency
|
||||
// when duplicate keys exists (consider newDataIndex.pop() below).
|
||||
// For performance consideration, these code below do not look neat.
|
||||
for (i = 0; i < oldArr.length; i++) {
|
||||
var key = oldKeyGetter(oldArr[i]);
|
||||
var idx = newDataIndexMap[key];
|
||||
|
||||
// idx can never be empty array here. see 'set null' logic below.
|
||||
if (idx != null) {
|
||||
// Consider there is duplicate key (for example, use dataItem.name as key).
|
||||
// We should make sure every item in newArr and oldArr can be visited.
|
||||
var len = idx.length;
|
||||
if (len) {
|
||||
len === 1 && (newDataIndexMap[key] = null);
|
||||
idx = idx.unshift();
|
||||
}
|
||||
else {
|
||||
newDataIndexMap[key] = null;
|
||||
}
|
||||
this._update && this._update(idx, i);
|
||||
}
|
||||
else {
|
||||
this._remove && this._remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
for (var key in newDataIndexMap) {
|
||||
if (newDataIndexMap.hasOwnProperty(key)) {
|
||||
var idx = newDataIndexMap[key];
|
||||
if (idx == null) {
|
||||
continue;
|
||||
}
|
||||
// idx can never be empty array here. see 'set null' logic above.
|
||||
if (!idx.length) {
|
||||
this._add && this._add(idx);
|
||||
}
|
||||
else {
|
||||
for (var i = 0, len = idx.length; i < len; i++) {
|
||||
this._add && this._add(idx[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function initIndexMap(arr, map, keyGetter) {
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
var key = keyGetter(arr[i]);
|
||||
var existence = map[key];
|
||||
if (existence == null) {
|
||||
map[key] = i;
|
||||
}
|
||||
else {
|
||||
if (!existence.length) {
|
||||
map[key] = existence = [existence];
|
||||
}
|
||||
existence.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DataDiffer;
|
||||
});
|
||||
515
vendors/echarts/src/data/Graph.js
vendored
Normal file
515
vendors/echarts/src/data/Graph.js
vendored
Normal file
@@ -0,0 +1,515 @@
|
||||
/**
|
||||
* Graph data structure
|
||||
*
|
||||
* @module echarts/data/Graph
|
||||
* @author Yi Shen(https://www.github.com/pissang)
|
||||
*/
|
||||
define(function(require) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var zrUtil = require('zrender/core/util');
|
||||
|
||||
/**
|
||||
* @alias module:echarts/data/Graph
|
||||
* @constructor
|
||||
* @param {boolean} directed
|
||||
*/
|
||||
var Graph = function(directed) {
|
||||
/**
|
||||
* 是否是有向图
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this._directed = directed || false;
|
||||
|
||||
/**
|
||||
* @type {Array.<module:echarts/data/Graph.Node>}
|
||||
* @readOnly
|
||||
*/
|
||||
this.nodes = [];
|
||||
|
||||
/**
|
||||
* @type {Array.<module:echarts/data/Graph.Edge>}
|
||||
* @readOnly
|
||||
*/
|
||||
this.edges = [];
|
||||
|
||||
/**
|
||||
* @type {Object.<string, module:echarts/data/Graph.Node>}
|
||||
* @private
|
||||
*/
|
||||
this._nodesMap = {};
|
||||
/**
|
||||
* @type {Object.<string, module:echarts/data/Graph.Edge>}
|
||||
* @private
|
||||
*/
|
||||
this._edgesMap = {};
|
||||
|
||||
/**
|
||||
* @type {module:echarts/data/List}
|
||||
* @readOnly
|
||||
*/
|
||||
this.data;
|
||||
|
||||
/**
|
||||
* @type {module:echarts/data/List}
|
||||
* @readOnly
|
||||
*/
|
||||
this.edgeData;
|
||||
};
|
||||
|
||||
var graphProto = Graph.prototype;
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
graphProto.type = 'graph';
|
||||
|
||||
/**
|
||||
* If is directed graph
|
||||
* @return {boolean}
|
||||
*/
|
||||
graphProto.isDirected = function () {
|
||||
return this._directed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a new node
|
||||
* @param {string} id
|
||||
* @param {number} [dataIndex]
|
||||
*/
|
||||
graphProto.addNode = function (id, dataIndex) {
|
||||
id = id || ('' + dataIndex);
|
||||
|
||||
var nodesMap = this._nodesMap;
|
||||
|
||||
if (nodesMap[id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
var node = new Node(id, dataIndex);
|
||||
node.hostGraph = this;
|
||||
|
||||
this.nodes.push(node);
|
||||
|
||||
nodesMap[id] = node;
|
||||
return node;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get node by data index
|
||||
* @param {number} dataIndex
|
||||
* @return {module:echarts/data/Graph~Node}
|
||||
*/
|
||||
graphProto.getNodeByIndex = function (dataIndex) {
|
||||
var rawIdx = this.data.getRawIndex(dataIndex);
|
||||
return this.nodes[rawIdx];
|
||||
};
|
||||
/**
|
||||
* Get node by id
|
||||
* @param {string} id
|
||||
* @return {module:echarts/data/Graph.Node}
|
||||
*/
|
||||
graphProto.getNodeById = function (id) {
|
||||
return this._nodesMap[id];
|
||||
};
|
||||
|
||||
/**
|
||||
* Add a new edge
|
||||
* @param {number|string|module:echarts/data/Graph.Node} n1
|
||||
* @param {number|string|module:echarts/data/Graph.Node} n2
|
||||
* @param {number} [dataIndex=-1]
|
||||
* @return {module:echarts/data/Graph.Edge}
|
||||
*/
|
||||
graphProto.addEdge = function (n1, n2, dataIndex) {
|
||||
var nodesMap = this._nodesMap;
|
||||
var edgesMap = this._edgesMap;
|
||||
|
||||
// PNEDING
|
||||
if (typeof n1 === 'number') {
|
||||
n1 = this.nodes[n1];
|
||||
}
|
||||
if (typeof n2 === 'number') {
|
||||
n2 = this.nodes[n2];
|
||||
}
|
||||
|
||||
if (!(n1 instanceof Node)) {
|
||||
n1 = nodesMap[n1];
|
||||
}
|
||||
if (!(n2 instanceof Node)) {
|
||||
n2 = nodesMap[n2];
|
||||
}
|
||||
if (!n1 || !n2) {
|
||||
return;
|
||||
}
|
||||
|
||||
var key = n1.id + '-' + n2.id;
|
||||
// PENDING
|
||||
if (edgesMap[key]) {
|
||||
return;
|
||||
}
|
||||
|
||||
var edge = new Edge(n1, n2, dataIndex);
|
||||
edge.hostGraph = this;
|
||||
|
||||
if (this._directed) {
|
||||
n1.outEdges.push(edge);
|
||||
n2.inEdges.push(edge);
|
||||
}
|
||||
n1.edges.push(edge);
|
||||
if (n1 !== n2) {
|
||||
n2.edges.push(edge);
|
||||
}
|
||||
|
||||
this.edges.push(edge);
|
||||
edgesMap[key] = edge;
|
||||
|
||||
return edge;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get edge by data index
|
||||
* @param {number} dataIndex
|
||||
* @return {module:echarts/data/Graph~Node}
|
||||
*/
|
||||
graphProto.getEdgeByIndex = function (dataIndex) {
|
||||
var rawIdx = this.edgeData.getRawIndex(dataIndex);
|
||||
return this.edges[rawIdx];
|
||||
};
|
||||
/**
|
||||
* Get edge by two linked nodes
|
||||
* @param {module:echarts/data/Graph.Node|string} n1
|
||||
* @param {module:echarts/data/Graph.Node|string} n2
|
||||
* @return {module:echarts/data/Graph.Edge}
|
||||
*/
|
||||
graphProto.getEdge = function (n1, n2) {
|
||||
if (n1 instanceof Node) {
|
||||
n1 = n1.id;
|
||||
}
|
||||
if (n2 instanceof Node) {
|
||||
n2 = n2.id;
|
||||
}
|
||||
|
||||
var edgesMap = this._edgesMap;
|
||||
|
||||
if (this._directed) {
|
||||
return edgesMap[n1 + '-' + n2];
|
||||
} else {
|
||||
return edgesMap[n1 + '-' + n2]
|
||||
|| edgesMap[n2 + '-' + n1];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterate all nodes
|
||||
* @param {Function} cb
|
||||
* @param {*} [context]
|
||||
*/
|
||||
graphProto.eachNode = function (cb, context) {
|
||||
var nodes = this.nodes;
|
||||
var len = nodes.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (nodes[i].dataIndex >= 0) {
|
||||
cb.call(context, nodes[i], i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterate all edges
|
||||
* @param {Function} cb
|
||||
* @param {*} [context]
|
||||
*/
|
||||
graphProto.eachEdge = function (cb, context) {
|
||||
var edges = this.edges;
|
||||
var len = edges.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (edges[i].dataIndex >= 0
|
||||
&& edges[i].node1.dataIndex >= 0
|
||||
&& edges[i].node2.dataIndex >= 0
|
||||
) {
|
||||
cb.call(context, edges[i], i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Breadth first traverse
|
||||
* @param {Function} cb
|
||||
* @param {module:echarts/data/Graph.Node} startNode
|
||||
* @param {string} [direction='none'] 'none'|'in'|'out'
|
||||
* @param {*} [context]
|
||||
*/
|
||||
graphProto.breadthFirstTraverse = function (
|
||||
cb, startNode, direction, context
|
||||
) {
|
||||
if (!(startNode instanceof Node)) {
|
||||
startNode = this._nodesMap[startNode];
|
||||
}
|
||||
if (!startNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
var edgeType = direction === 'out'
|
||||
? 'outEdges' : (direction === 'in' ? 'inEdges' : 'edges');
|
||||
|
||||
for (var i = 0; i < this.nodes.length; i++) {
|
||||
this.nodes[i].__visited = false;
|
||||
}
|
||||
|
||||
if (cb.call(context, startNode, null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var queue = [startNode];
|
||||
while (queue.length) {
|
||||
var currentNode = queue.shift();
|
||||
var edges = currentNode[edgeType];
|
||||
|
||||
for (var i = 0; i < edges.length; i++) {
|
||||
var e = edges[i];
|
||||
var otherNode = e.node1 === currentNode
|
||||
? e.node2 : e.node1;
|
||||
if (!otherNode.__visited) {
|
||||
if (cb.call(otherNode, otherNode, currentNode)) {
|
||||
// Stop traversing
|
||||
return;
|
||||
}
|
||||
queue.push(otherNode);
|
||||
otherNode.__visited = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// TODO
|
||||
// graphProto.depthFirstTraverse = function (
|
||||
// cb, startNode, direction, context
|
||||
// ) {
|
||||
|
||||
// };
|
||||
|
||||
// Filter update
|
||||
graphProto.update = function () {
|
||||
var data = this.data;
|
||||
var edgeData = this.edgeData;
|
||||
var nodes = this.nodes;
|
||||
var edges = this.edges;
|
||||
|
||||
for (var i = 0, len = nodes.length; i < len; i++) {
|
||||
nodes[i].dataIndex = -1;
|
||||
}
|
||||
for (var i = 0, len = data.count(); i < len; i++) {
|
||||
nodes[data.getRawIndex(i)].dataIndex = i;
|
||||
}
|
||||
|
||||
edgeData.filterSelf(function (idx) {
|
||||
var edge = edges[edgeData.getRawIndex(idx)];
|
||||
return edge.node1.dataIndex >= 0 && edge.node2.dataIndex >= 0;
|
||||
});
|
||||
|
||||
// Update edge
|
||||
for (var i = 0, len = edges.length; i < len; i++) {
|
||||
edges[i].dataIndex = -1;
|
||||
}
|
||||
for (var i = 0, len = edgeData.count(); i < len; i++) {
|
||||
edges[edgeData.getRawIndex(i)].dataIndex = i;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {module:echarts/data/Graph}
|
||||
*/
|
||||
graphProto.clone = function () {
|
||||
var graph = new Graph(this._directed);
|
||||
var nodes = this.nodes;
|
||||
var edges = this.edges;
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
graph.addNode(nodes[i].id, nodes[i].dataIndex);
|
||||
}
|
||||
for (var i = 0; i < edges.length; i++) {
|
||||
var e = edges[i];
|
||||
graph.addEdge(e.node1.id, e.node2.id, e.dataIndex);
|
||||
}
|
||||
return graph;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @alias module:echarts/data/Graph.Node
|
||||
*/
|
||||
function Node(id, dataIndex) {
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this.id = id == null ? '' : id;
|
||||
|
||||
/**
|
||||
* @type {Array.<module:echarts/data/Graph.Edge>}
|
||||
*/
|
||||
this.inEdges = [];
|
||||
/**
|
||||
* @type {Array.<module:echarts/data/Graph.Edge>}
|
||||
*/
|
||||
this.outEdges = [];
|
||||
/**
|
||||
* @type {Array.<module:echarts/data/Graph.Edge>}
|
||||
*/
|
||||
this.edges = [];
|
||||
/**
|
||||
* @type {module:echarts/data/Graph}
|
||||
*/
|
||||
this.hostGraph;
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.dataIndex = dataIndex == null ? -1 : dataIndex;
|
||||
}
|
||||
|
||||
Node.prototype = {
|
||||
|
||||
constructor: Node,
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
degree: function () {
|
||||
return this.edges.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
inDegree: function () {
|
||||
return this.inEdges.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
outDegree: function () {
|
||||
return this.outEdges.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} [path]
|
||||
* @return {module:echarts/model/Model}
|
||||
*/
|
||||
getModel: function (path) {
|
||||
if (this.dataIndex < 0) {
|
||||
return;
|
||||
}
|
||||
var graph = this.hostGraph;
|
||||
var itemModel = graph.data.getItemModel(this.dataIndex);
|
||||
|
||||
return itemModel.getModel(path);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 图边
|
||||
* @alias module:echarts/data/Graph.Edge
|
||||
* @param {module:echarts/data/Graph.Node} n1
|
||||
* @param {module:echarts/data/Graph.Node} n2
|
||||
* @param {number} [dataIndex=-1]
|
||||
*/
|
||||
function Edge(n1, n2, dataIndex) {
|
||||
|
||||
/**
|
||||
* 节点1,如果是有向图则为源节点
|
||||
* @type {module:echarts/data/Graph.Node}
|
||||
*/
|
||||
this.node1 = n1;
|
||||
|
||||
/**
|
||||
* 节点2,如果是有向图则为目标节点
|
||||
* @type {module:echarts/data/Graph.Node}
|
||||
*/
|
||||
this.node2 = n2;
|
||||
|
||||
this.dataIndex = dataIndex == null ? -1 : dataIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} [path]
|
||||
* @return {module:echarts/model/Model}
|
||||
*/
|
||||
Edge.prototype.getModel = function (path) {
|
||||
if (this.dataIndex < 0) {
|
||||
return;
|
||||
}
|
||||
var graph = this.hostGraph;
|
||||
var itemModel = graph.edgeData.getItemModel(this.dataIndex);
|
||||
|
||||
return itemModel.getModel(path);
|
||||
};
|
||||
|
||||
var createGraphDataProxyMixin = function (hostName, dataName) {
|
||||
return {
|
||||
/**
|
||||
* @param {string=} [dimension='value'] Default 'value'. can be 'a', 'b', 'c', 'd', 'e'.
|
||||
* @return {number}
|
||||
*/
|
||||
getValue: function (dimension) {
|
||||
var data = this[hostName][dataName];
|
||||
return data.get(data.getDimension(dimension || 'value'), this.dataIndex);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object|string} key
|
||||
* @param {*} [value]
|
||||
*/
|
||||
setVisual: function (key, value) {
|
||||
this.dataIndex >= 0
|
||||
&& this[hostName][dataName].setItemVisual(this.dataIndex, key, value);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} key
|
||||
* @return {boolean}
|
||||
*/
|
||||
getVisual: function (key, ignoreParent) {
|
||||
return this[hostName][dataName].getItemVisual(this.dataIndex, key, ignoreParent);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} layout
|
||||
* @return {boolean} [merge=false]
|
||||
*/
|
||||
setLayout: function (layout, merge) {
|
||||
this.dataIndex >= 0
|
||||
&& this[hostName][dataName].setItemLayout(this.dataIndex, layout, merge);
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {Object}
|
||||
*/
|
||||
getLayout: function () {
|
||||
return this[hostName][dataName].getItemLayout(this.dataIndex);
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {module:zrender/Element}
|
||||
*/
|
||||
getGraphicEl: function () {
|
||||
return this[hostName][dataName].getItemGraphicEl(this.dataIndex);
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
getRawIndex: function () {
|
||||
return this[hostName][dataName].getRawIndex(this.dataIndex);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
zrUtil.mixin(Node, createGraphDataProxyMixin('hostGraph', 'data'));
|
||||
zrUtil.mixin(Edge, createGraphDataProxyMixin('hostGraph', 'edgeData'));
|
||||
|
||||
Graph.Node = Node;
|
||||
Graph.Edge = Edge;
|
||||
|
||||
return Graph;
|
||||
});
|
||||
1058
vendors/echarts/src/data/List.js
vendored
Normal file
1058
vendors/echarts/src/data/List.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
472
vendors/echarts/src/data/Tree.js
vendored
Normal file
472
vendors/echarts/src/data/Tree.js
vendored
Normal file
@@ -0,0 +1,472 @@
|
||||
/**
|
||||
* Tree data structure
|
||||
*
|
||||
* @module echarts/data/Tree
|
||||
*/
|
||||
define(function(require) {
|
||||
|
||||
var zrUtil = require('zrender/core/util');
|
||||
var Model = require('../model/Model');
|
||||
var List = require('./List');
|
||||
var linkList = require('./helper/linkList');
|
||||
var completeDimensions = require('./helper/completeDimensions');
|
||||
|
||||
/**
|
||||
* @constructor module:echarts/data/Tree~TreeNode
|
||||
* @param {string} name
|
||||
* @param {module:echarts/data/Tree} hostTree
|
||||
*/
|
||||
var TreeNode = function (name, hostTree) {
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
this.name = name || '';
|
||||
|
||||
/**
|
||||
* Depth of node
|
||||
*
|
||||
* @type {number}
|
||||
* @readOnly
|
||||
*/
|
||||
this.depth = 0;
|
||||
|
||||
/**
|
||||
* Height of the subtree rooted at this node.
|
||||
* @type {number}
|
||||
* @readOnly
|
||||
*/
|
||||
this.height = 0;
|
||||
|
||||
/**
|
||||
* @type {module:echarts/data/Tree~TreeNode}
|
||||
* @readOnly
|
||||
*/
|
||||
this.parentNode = null;
|
||||
|
||||
/**
|
||||
* Reference to list item.
|
||||
* Do not persistent dataIndex outside,
|
||||
* besause it may be changed by list.
|
||||
* If dataIndex -1,
|
||||
* this node is logical deleted (filtered) in list.
|
||||
*
|
||||
* @type {Object}
|
||||
* @readOnly
|
||||
*/
|
||||
this.dataIndex = -1;
|
||||
|
||||
/**
|
||||
* @type {Array.<module:echarts/data/Tree~TreeNode>}
|
||||
* @readOnly
|
||||
*/
|
||||
this.children = [];
|
||||
|
||||
/**
|
||||
* @type {Array.<module:echarts/data/Tree~TreeNode>}
|
||||
* @pubilc
|
||||
*/
|
||||
this.viewChildren = [];
|
||||
|
||||
/**
|
||||
* @type {moduel:echarts/data/Tree}
|
||||
* @readOnly
|
||||
*/
|
||||
this.hostTree = hostTree;
|
||||
};
|
||||
|
||||
TreeNode.prototype = {
|
||||
|
||||
constructor: TreeNode,
|
||||
|
||||
/**
|
||||
* The node is removed.
|
||||
* @return {boolean} is removed.
|
||||
*/
|
||||
isRemoved: function () {
|
||||
return this.dataIndex < 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Travel this subtree (include this node).
|
||||
* Usage:
|
||||
* node.eachNode(function () { ... }); // preorder
|
||||
* node.eachNode('preorder', function () { ... }); // preorder
|
||||
* node.eachNode('postorder', function () { ... }); // postorder
|
||||
* node.eachNode(
|
||||
* {order: 'postorder', attr: 'viewChildren'},
|
||||
* function () { ... }
|
||||
* ); // postorder
|
||||
*
|
||||
* @param {(Object|string)} options If string, means order.
|
||||
* @param {string=} options.order 'preorder' or 'postorder'
|
||||
* @param {string=} options.attr 'children' or 'viewChildren'
|
||||
* @param {Function} cb If in preorder and return false,
|
||||
* its subtree will not be visited.
|
||||
* @param {Object} [context]
|
||||
*/
|
||||
eachNode: function (options, cb, context) {
|
||||
if (typeof options === 'function') {
|
||||
context = cb;
|
||||
cb = options;
|
||||
options = null;
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
if (zrUtil.isString(options)) {
|
||||
options = {order: options};
|
||||
}
|
||||
|
||||
var order = options.order || 'preorder';
|
||||
var children = this[options.attr || 'children'];
|
||||
|
||||
var suppressVisitSub;
|
||||
order === 'preorder' && (suppressVisitSub = cb.call(context, this));
|
||||
|
||||
for (var i = 0; !suppressVisitSub && i < children.length; i++) {
|
||||
children[i].eachNode(options, cb, context);
|
||||
}
|
||||
|
||||
order === 'postorder' && cb.call(context, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update depth and height of this subtree.
|
||||
*
|
||||
* @param {number} depth
|
||||
*/
|
||||
updateDepthAndHeight: function (depth) {
|
||||
var height = 0;
|
||||
this.depth = depth;
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
child.updateDepthAndHeight(depth + 1);
|
||||
if (child.height > height) {
|
||||
height = child.height;
|
||||
}
|
||||
}
|
||||
this.height = height + 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* @return {module:echarts/data/Tree~TreeNode}
|
||||
*/
|
||||
getNodeById: function (id) {
|
||||
if (this.getId() === id) {
|
||||
return this;
|
||||
}
|
||||
for (var i = 0, children = this.children, len = children.length; i < len; i++) {
|
||||
var res = children[i].getNodeById(id);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {module:echarts/data/Tree~TreeNode} node
|
||||
* @return {boolean}
|
||||
*/
|
||||
contains: function (node) {
|
||||
if (node === this) {
|
||||
return true;
|
||||
}
|
||||
for (var i = 0, children = this.children, len = children.length; i < len; i++) {
|
||||
var res = children[i].contains(node);
|
||||
if (res) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {boolean} includeSelf Default false.
|
||||
* @return {Array.<module:echarts/data/Tree~TreeNode>} order: [root, child, grandchild, ...]
|
||||
*/
|
||||
getAncestors: function (includeSelf) {
|
||||
var ancestors = [];
|
||||
var node = includeSelf ? this : this.parentNode;
|
||||
while (node) {
|
||||
ancestors.push(node);
|
||||
node = node.parentNode;
|
||||
}
|
||||
ancestors.reverse();
|
||||
return ancestors;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string|Array=} [dimension='value'] Default 'value'. can be 0, 1, 2, 3
|
||||
* @return {number} Value.
|
||||
*/
|
||||
getValue: function (dimension) {
|
||||
var data = this.hostTree.data;
|
||||
return data.get(data.getDimension(dimension || 'value'), this.dataIndex);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Object} layout
|
||||
* @param {boolean=} [merge=false]
|
||||
*/
|
||||
setLayout: function (layout, merge) {
|
||||
this.dataIndex >= 0
|
||||
&& this.hostTree.data.setItemLayout(this.dataIndex, layout, merge);
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {Object} layout
|
||||
*/
|
||||
getLayout: function () {
|
||||
return this.hostTree.data.getItemLayout(this.dataIndex);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @return {module:echarts/model/Model}
|
||||
*/
|
||||
getModel: function (path) {
|
||||
if (this.dataIndex < 0) {
|
||||
return;
|
||||
}
|
||||
var hostTree = this.hostTree;
|
||||
var itemModel = hostTree.data.getItemModel(this.dataIndex);
|
||||
var levelModel = this.getLevelModel();
|
||||
|
||||
return itemModel.getModel(path, (levelModel || hostTree.hostModel).getModel(path));
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {module:echarts/model/Model}
|
||||
*/
|
||||
getLevelModel: function () {
|
||||
return (this.hostTree.levelModels || [])[this.depth];
|
||||
},
|
||||
|
||||
/**
|
||||
* @example
|
||||
* setItemVisual('color', color);
|
||||
* setItemVisual({
|
||||
* 'color': color
|
||||
* });
|
||||
*/
|
||||
setVisual: function (key, value) {
|
||||
this.dataIndex >= 0
|
||||
&& this.hostTree.data.setItemVisual(this.dataIndex, key, value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get item visual
|
||||
*/
|
||||
getVisual: function (key, ignoreParent) {
|
||||
return this.hostTree.data.getItemVisual(this.dataIndex, key, ignoreParent);
|
||||
},
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @return {number}
|
||||
*/
|
||||
getRawIndex: function () {
|
||||
return this.hostTree.data.getRawIndex(this.dataIndex);
|
||||
},
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @return {string}
|
||||
*/
|
||||
getId: function () {
|
||||
return this.hostTree.data.getId(this.dataIndex);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @alias module:echarts/data/Tree
|
||||
* @param {module:echarts/model/Model} hostModel
|
||||
* @param {Array.<Object>} levelOptions
|
||||
*/
|
||||
function Tree(hostModel, levelOptions) {
|
||||
/**
|
||||
* @type {module:echarts/data/Tree~TreeNode}
|
||||
* @readOnly
|
||||
*/
|
||||
this.root;
|
||||
|
||||
/**
|
||||
* @type {module:echarts/data/List}
|
||||
* @readOnly
|
||||
*/
|
||||
this.data;
|
||||
|
||||
/**
|
||||
* Index of each item is the same as the raw index of coresponding list item.
|
||||
* @private
|
||||
* @type {Array.<module:echarts/data/Tree~TreeNode}
|
||||
*/
|
||||
this._nodes = [];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @readOnly
|
||||
* @type {module:echarts/model/Model}
|
||||
*/
|
||||
this.hostModel = hostModel;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @readOnly
|
||||
* @type {Array.<module:echarts/model/Model}
|
||||
*/
|
||||
this.levelModels = zrUtil.map(levelOptions || [], function (levelDefine) {
|
||||
return new Model(levelDefine, hostModel, hostModel.ecModel);
|
||||
});
|
||||
}
|
||||
|
||||
Tree.prototype = {
|
||||
|
||||
constructor: Tree,
|
||||
|
||||
type: 'tree',
|
||||
|
||||
/**
|
||||
* Travel this subtree (include this node).
|
||||
* Usage:
|
||||
* node.eachNode(function () { ... }); // preorder
|
||||
* node.eachNode('preorder', function () { ... }); // preorder
|
||||
* node.eachNode('postorder', function () { ... }); // postorder
|
||||
* node.eachNode(
|
||||
* {order: 'postorder', attr: 'viewChildren'},
|
||||
* function () { ... }
|
||||
* ); // postorder
|
||||
*
|
||||
* @param {(Object|string)} options If string, means order.
|
||||
* @param {string=} options.order 'preorder' or 'postorder'
|
||||
* @param {string=} options.attr 'children' or 'viewChildren'
|
||||
* @param {Function} cb
|
||||
* @param {Object} [context]
|
||||
*/
|
||||
eachNode: function(options, cb, context) {
|
||||
this.root.eachNode(options, cb, context);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} dataIndex
|
||||
* @return {module:echarts/data/Tree~TreeNode}
|
||||
*/
|
||||
getNodeByDataIndex: function (dataIndex) {
|
||||
var rawIndex = this.data.getRawIndex(dataIndex);
|
||||
return this._nodes[rawIndex];
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @return {module:echarts/data/Tree~TreeNode}
|
||||
*/
|
||||
getNodeByName: function (name) {
|
||||
return this.root.getNodeByName(name);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update item available by list,
|
||||
* when list has been performed options like 'filterSelf' or 'map'.
|
||||
*/
|
||||
update: function () {
|
||||
var data = this.data;
|
||||
var nodes = this._nodes;
|
||||
|
||||
for (var i = 0, len = nodes.length; i < len; i++) {
|
||||
nodes[i].dataIndex = -1;
|
||||
}
|
||||
|
||||
for (var i = 0, len = data.count(); i < len; i++) {
|
||||
nodes[data.getRawIndex(i)].dataIndex = i;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all layouts
|
||||
*/
|
||||
clearLayouts: function () {
|
||||
this.data.clearItemLayouts();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* data node format:
|
||||
* {
|
||||
* name: ...
|
||||
* value: ...
|
||||
* children: [
|
||||
* {
|
||||
* name: ...
|
||||
* value: ...
|
||||
* children: ...
|
||||
* },
|
||||
* ...
|
||||
* ]
|
||||
* }
|
||||
*
|
||||
* @static
|
||||
* @param {Objec} dataRoot Root node.
|
||||
* @param {module:echarts/model/Model} hostModel
|
||||
* @param {Array.<Object>} levelOptions
|
||||
* @return module:echarts/data/Tree
|
||||
*/
|
||||
Tree.createTree = function (dataRoot, hostModel, levelOptions) {
|
||||
|
||||
var tree = new Tree(hostModel, levelOptions);
|
||||
var listData = [];
|
||||
|
||||
buildHierarchy(dataRoot);
|
||||
|
||||
function buildHierarchy(dataNode, parentNode) {
|
||||
listData.push(dataNode);
|
||||
|
||||
var node = new TreeNode(dataNode.name, tree);
|
||||
parentNode
|
||||
? addChild(node, parentNode)
|
||||
: (tree.root = node);
|
||||
|
||||
tree._nodes.push(node);
|
||||
|
||||
var children = dataNode.children;
|
||||
if (children) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
buildHierarchy(children[i], node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tree.root.updateDepthAndHeight(0);
|
||||
|
||||
var dimensions = completeDimensions([{name: 'value'}], listData);
|
||||
var list = new List(dimensions, hostModel);
|
||||
list.initData(listData);
|
||||
|
||||
linkList({
|
||||
mainData: list,
|
||||
struct: tree,
|
||||
structAttr: 'tree'
|
||||
});
|
||||
|
||||
tree.update();
|
||||
|
||||
return tree;
|
||||
};
|
||||
|
||||
/**
|
||||
* It is needed to consider the mess of 'list', 'hostModel' when creating a TreeNote,
|
||||
* so this function is not ready and not necessary to be public.
|
||||
*
|
||||
* @param {(module:echarts/data/Tree~TreeNode|Object)} child
|
||||
*/
|
||||
function addChild(child, node) {
|
||||
var children = node.children;
|
||||
if (child.parentNode === node) {
|
||||
return;
|
||||
}
|
||||
|
||||
children.push(child);
|
||||
child.parentNode = node;
|
||||
}
|
||||
|
||||
return Tree;
|
||||
});
|
||||
65
vendors/echarts/src/data/helper/completeDimensions.js
vendored
Normal file
65
vendors/echarts/src/data/helper/completeDimensions.js
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Complete dimensions by data (guess dimension).
|
||||
*/
|
||||
define(function (require) {
|
||||
|
||||
var zrUtil = require('zrender/core/util');
|
||||
|
||||
/**
|
||||
* Complete the dimensions array guessed from the data structure.
|
||||
* @param {Array.<string>} dimensions Necessary dimensions, like ['x', 'y']
|
||||
* @param {Array} data Data list. [[1, 2, 3], [2, 3, 4]]
|
||||
* @param {Array.<string>} defaultNames Default names to fill not necessary dimensions, like ['value']
|
||||
* @param {string} extraPrefix Prefix of name when filling the left dimensions.
|
||||
* @return {Array.<string>}
|
||||
*/
|
||||
function completeDimensions(dimensions, data, defaultNames, extraPrefix) {
|
||||
if (!data) {
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
var value0 = retrieveValue(data[0]);
|
||||
var dimSize = zrUtil.isArray(value0) && value0.length || 1;
|
||||
|
||||
defaultNames = defaultNames || [];
|
||||
extraPrefix = extraPrefix || 'extra';
|
||||
for (var i = 0; i < dimSize; i++) {
|
||||
if (!dimensions[i]) {
|
||||
var name = defaultNames[i] || (extraPrefix + (i - defaultNames.length));
|
||||
dimensions[i] = guessOrdinal(data, i)
|
||||
? {type: 'ordinal', name: name}
|
||||
: name;
|
||||
}
|
||||
}
|
||||
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
// The rule should not be complex, otherwise user might not
|
||||
// be able to known where the data is wrong.
|
||||
function guessOrdinal(data, dimIndex) {
|
||||
for (var i = 0, len = data.length; i < len; i++) {
|
||||
var value = retrieveValue(data[i]);
|
||||
|
||||
if (!zrUtil.isArray(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var value = value[dimIndex];
|
||||
if (value != null && isFinite(value)) {
|
||||
return false;
|
||||
}
|
||||
else if (zrUtil.isString(value) && value !== '-') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function retrieveValue(o) {
|
||||
return zrUtil.isArray(o) ? o : zrUtil.isObject(o) ? o.value: o;
|
||||
}
|
||||
|
||||
return completeDimensions;
|
||||
|
||||
});
|
||||
133
vendors/echarts/src/data/helper/linkList.js
vendored
Normal file
133
vendors/echarts/src/data/helper/linkList.js
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Link lists and struct (graph or tree)
|
||||
*/
|
||||
define(function (require) {
|
||||
|
||||
var zrUtil = require('zrender/core/util');
|
||||
var each = zrUtil.each;
|
||||
|
||||
var DATAS = '\0__link_datas';
|
||||
var MAIN_DATA = '\0__link_mainData';
|
||||
|
||||
// Caution:
|
||||
// In most case, either list or its shallow clones (see list.cloneShallow)
|
||||
// is active in echarts process. So considering heap memory consumption,
|
||||
// we do not clone tree or graph, but share them among list and its shallow clones.
|
||||
// But in some rare case, we have to keep old list (like do animation in chart). So
|
||||
// please take care that both the old list and the new list share the same tree/graph.
|
||||
|
||||
/**
|
||||
* @param {Object} opt
|
||||
* @param {module:echarts/data/List} opt.mainData
|
||||
* @param {Object} [opt.struct] For example, instance of Graph or Tree.
|
||||
* @param {string} [opt.structAttr] designation: list[structAttr] = struct;
|
||||
* @param {Object} [opt.datas] {dataType: data},
|
||||
* like: {node: nodeList, edge: edgeList}.
|
||||
* Should contain mainData.
|
||||
* @param {Object} [opt.datasAttr] {dataType: attr},
|
||||
* designation: struct[datasAttr[dataType]] = list;
|
||||
*/
|
||||
function linkList(opt) {
|
||||
var mainData = opt.mainData;
|
||||
var datas = opt.datas;
|
||||
|
||||
if (!datas) {
|
||||
datas = {main: mainData};
|
||||
opt.datasAttr = {main: 'data'};
|
||||
}
|
||||
opt.datas = opt.mainData = null;
|
||||
|
||||
linkAll(mainData, datas, opt);
|
||||
|
||||
// Porxy data original methods.
|
||||
each(datas, function (data) {
|
||||
each(mainData.TRANSFERABLE_METHODS, function (methodName) {
|
||||
data.wrapMethod(methodName, zrUtil.curry(transferInjection, opt));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Beyond transfer, additional features should be added to `cloneShallow`.
|
||||
mainData.wrapMethod('cloneShallow', zrUtil.curry(cloneShallowInjection, opt));
|
||||
|
||||
// Only mainData trigger change, because struct.update may trigger
|
||||
// another changable methods, which may bring about dead lock.
|
||||
each(mainData.CHANGABLE_METHODS, function (methodName) {
|
||||
mainData.wrapMethod(methodName, zrUtil.curry(changeInjection, opt));
|
||||
});
|
||||
|
||||
// Make sure datas contains mainData.
|
||||
zrUtil.assert(datas[mainData.dataType] === mainData);
|
||||
}
|
||||
|
||||
function transferInjection(opt, res) {
|
||||
if (isMainData(this)) {
|
||||
// Transfer datas to new main data.
|
||||
var datas = zrUtil.extend({}, this[DATAS]);
|
||||
datas[this.dataType] = res;
|
||||
linkAll(res, datas, opt);
|
||||
}
|
||||
else {
|
||||
// Modify the reference in main data to point newData.
|
||||
linkSingle(res, this.dataType, this[MAIN_DATA], opt);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
function changeInjection(opt, res) {
|
||||
opt.struct && opt.struct.update(this);
|
||||
return res;
|
||||
}
|
||||
|
||||
function cloneShallowInjection(opt, res) {
|
||||
// cloneShallow, which brings about some fragilities, may be inappropriate
|
||||
// to be exposed as an API. So for implementation simplicity we can make
|
||||
// the restriction that cloneShallow of not-mainData should not be invoked
|
||||
// outside, but only be invoked here.
|
||||
each(res[DATAS], function (data, dataType) {
|
||||
data !== res && linkSingle(data.cloneShallow(), dataType, res, opt);
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supplement method to List.
|
||||
*
|
||||
* @public
|
||||
* @param {string} [dataType] If not specified, return mainData.
|
||||
* @return {module:echarts/data/List}
|
||||
*/
|
||||
function getLinkedData(dataType) {
|
||||
var mainData = this[MAIN_DATA];
|
||||
return (dataType == null || mainData == null)
|
||||
? mainData
|
||||
: mainData[DATAS][dataType];
|
||||
}
|
||||
|
||||
function isMainData(data) {
|
||||
return data[MAIN_DATA] === data;
|
||||
}
|
||||
|
||||
function linkAll(mainData, datas, opt) {
|
||||
mainData[DATAS] = {};
|
||||
each(datas, function (data, dataType) {
|
||||
linkSingle(data, dataType, mainData, opt);
|
||||
});
|
||||
}
|
||||
|
||||
function linkSingle(data, dataType, mainData, opt) {
|
||||
mainData[DATAS][dataType] = data;
|
||||
data[MAIN_DATA] = mainData;
|
||||
data.dataType = dataType;
|
||||
|
||||
if (opt.struct) {
|
||||
data[opt.structAttr] = opt.struct;
|
||||
opt.struct[opt.datasAttr[dataType]] = data;
|
||||
}
|
||||
|
||||
// Supplement method.
|
||||
data.getLinkedData = getLinkedData;
|
||||
}
|
||||
|
||||
return linkList;
|
||||
});
|
||||
Reference in New Issue
Block a user