3311 changed files with 669702 additions and 0 deletions
@ -0,0 +1 @@ |
|||
module.exports={A:{D:{"1":"TB UB qB VB rB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R S T U V W X Y Z a d e f g h i j k l m n o p b H tB 8B 9B","2":"0 1 2 3 4 5 6 7 8 9 I q J D E F A B C K L G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB"},L:{"1":"H"},B:{"1":"P Q R S T U V W X Y Z a d e f g h i j k l m n o p b H","2":"C K L G M N O"},C:{"1":"0 1 2 3 4 5 6 7 8 9 J D E F A B C K L G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB qB VB rB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R sB S T U V W X Y Z a d e f g h i j k l m n o p b H tB","2":"5B pB I q 6B 7B"},M:{"1":"b"},A:{"2":"J D E F A B 4B"},F:{"1":"GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R sB S T U V W X Y Z a","2":"0 1 2 3 4 5 6 7 8 9 F B C G M N O r s t u v w x y z AB BB CB DB EB FB IC JC KC LC mB 2B MC nB"},K:{"1":"c","2":"A B C mB 2B nB"},E:{"2":"I q J D AC uB BC CC DC HC","33":"E F A B C K L G EC vB mB nB wB FC GC xB yB zB 0B oB 1B"},G:{"2":"uB NC 3B OC PC QC","33":"E RC SC TC UC VC WC XC YC ZC aC bC cC dC eC fC gC xB yB zB 0B oB 1B"},P:{"1":"rC sC tC vB uC vC wC xC yC oB zC 0C","2":"I pC qC"},I:{"1":"H","2":"pB I iC jC kC lC 3B mC nC"}},B:6,C:"text-decoration shorthand property"}; |
|||
@ -0,0 +1 @@ |
|||
module.exports={A:{A:{"1":"B","2":"J D E 4B","8":"F A"},B:{"1":"C K L G M N O P Q R S T U V W X Y Z a d e f g h i j k l m n o p b H"},C:{"1":"0 1 2 3 4 5 6 7 8 9 L G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB qB VB rB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R sB S T U V W X Y Z a d e f g h i j k l m n o p b H tB","2":"5B pB I q J D E F A B C K 6B 7B"},D:{"1":"0 1 2 3 4 5 6 7 8 9 z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB qB VB rB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R S T U V W X Y Z a d e f g h i j k l m n o p b H tB 8B 9B","2":"I q J D E F A B C K L G M N","33":"O r s t u v w x y"},E:{"1":"D E F A B C K L G CC DC EC vB mB nB wB FC GC xB yB zB 0B oB 1B HC","2":"I q AC uB BC","33":"J"},F:{"1":"0 1 2 3 4 5 6 7 8 9 G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R sB S T U V W X Y Z a","2":"F B C IC JC KC LC mB 2B MC nB"},G:{"1":"E QC RC SC TC UC VC WC XC YC ZC aC bC cC dC eC fC gC xB yB zB 0B oB 1B","2":"uB NC 3B OC","33":"PC"},H:{"2":"hC"},I:{"1":"H mC nC","2":"pB iC jC kC","8":"I lC 3B"},J:{"1":"A","2":"D"},K:{"1":"c","2":"A B C mB 2B nB"},L:{"1":"H"},M:{"1":"b"},N:{"1":"B","8":"A"},O:{"1":"oC"},P:{"1":"I pC qC rC sC tC vB uC vC wC xC yC oB zC 0C"},Q:{"1":"wB"},R:{"1":"1C"},S:{"1":"2C"}},B:1,C:"Mutation Observer"}; |
|||
@ -0,0 +1 @@ |
|||
module.exports={A:{A:{"1":"E F A B","2":"4B","8":"J D"},B:{"1":"C K L G M N O P Q R S T U V W X Y Z a d e f g h i j k l m n o p b H"},C:{"1":"0 1 2 3 4 5 6 7 8 9 I q J D E F A B C K L G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB qB VB rB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R sB S T U V W X Y Z a d e f g h i j k l m n o p b H tB 6B 7B","4":"5B pB"},D:{"1":"0 1 2 3 4 5 6 7 8 9 I q J D E F A B C K L G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB qB VB rB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R S T U V W X Y Z a d e f g h i j k l m n o p b H tB 8B 9B"},E:{"1":"I q J D E F A B C K L G BC CC DC EC vB mB nB wB FC GC xB yB zB 0B oB 1B HC","2":"AC uB"},F:{"1":"0 1 2 3 4 5 6 7 8 9 B C G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R sB S T U V W X Y Z a KC LC mB 2B MC nB","2":"F IC JC"},G:{"1":"E uB NC 3B OC PC QC RC SC TC UC VC WC XC YC ZC aC bC cC dC eC fC gC xB yB zB 0B oB 1B"},H:{"2":"hC"},I:{"1":"pB I H iC jC kC lC 3B mC nC"},J:{"1":"D A"},K:{"1":"B C c mB 2B nB","2":"A"},L:{"1":"H"},M:{"1":"b"},N:{"1":"A B"},O:{"1":"oC"},P:{"1":"I pC qC rC sC tC vB uC vC wC xC yC oB zC 0C"},Q:{"1":"wB"},R:{"1":"1C"},S:{"1":"2C"}},B:1,C:"Web Storage - name/value pairs"}; |
|||
@ -0,0 +1 @@ |
|||
module.exports={A:{A:{"2":"J D E F A B 4B"},B:{"2":"C K L G M N O","194":"P Q R S T U","260":"V W X Y Z a d e f g h i j k l m n o p b H"},C:{"2":"0 1 2 3 4 5 6 7 8 9 5B pB I q J D E F A B C K L G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB qB VB rB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R sB S T U V W X Y Z a d e f g h i j k l m n o p b H tB 6B 7B"},D:{"2":"0 1 2 3 4 5 6 7 8 9 I q J D E F A B C K L G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB qB VB rB WB XB c YB ZB aB bB cB dB eB fB gB","194":"hB iB jB kB lB P Q R S T U","260":"V W X Y Z a d e f g h i j k l m n o p b H tB 8B 9B"},E:{"2":"I q J D E F A B C K L G AC uB BC CC DC EC vB mB nB wB FC GC","516":"xB yB zB 0B oB 1B HC"},F:{"2":"0 1 2 3 4 5 6 7 8 9 F B C G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB IC JC KC LC mB 2B MC nB","194":"WB XB c YB ZB aB bB cB dB eB","260":"fB gB hB iB jB kB lB P Q R sB S T U V W X Y Z a"},G:{"2":"E uB NC 3B OC PC QC RC SC TC UC VC WC XC YC ZC aC bC cC dC eC fC gC","516":"xB yB zB 0B oB 1B"},H:{"2":"hC"},I:{"2":"pB I H iC jC kC lC 3B mC nC"},J:{"2":"D A"},K:{"2":"A B C c mB 2B nB"},L:{"2":"H"},M:{"2":"b"},N:{"2":"A B"},O:{"2":"oC"},P:{"2":"I pC qC rC sC tC vB uC vC wC xC yC oB zC 0C"},Q:{"2":"wB"},R:{"2":"1C"},S:{"2":"2C"}},B:7,C:"File System Access API"}; |
|||
@ -0,0 +1 @@ |
|||
module.exports={A:{A:{"1":"F A B","2":"J D E 4B"},B:{"1":"C K L G M N O P Q R S T U V W X Y Z a d e f g h i j k l m n o p b H"},C:{"1":"0 1 2 3 4 5 6 7 8 9 D E F A B C K L G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB qB VB rB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R sB S T U V W X Y Z a d e f g h i j k l m n o p b H tB","2":"5B pB I q J 6B 7B"},D:{"1":"0 1 2 3 4 5 6 7 8 9 K L G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB qB VB rB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R S T U V W X Y Z a d e f g h i j k l m n o p b H tB 8B 9B","2":"I q","33":"J D E F A B C"},E:{"1":"E F A B C K L G EC vB mB nB wB FC GC xB yB zB 0B oB 1B HC","2":"I q J D AC uB BC CC DC"},F:{"1":"0 1 2 3 4 5 6 7 8 9 G M N O r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB c YB ZB aB bB cB dB eB fB gB hB iB jB kB lB P Q R sB S T U V W X Y Z a","2":"F B C IC JC KC LC mB 2B MC nB"},G:{"1":"E SC TC UC VC WC XC YC ZC aC bC cC dC eC fC gC xB yB zB 0B oB 1B","2":"uB NC 3B OC PC QC RC"},H:{"2":"hC"},I:{"1":"I H lC 3B mC nC","2":"pB iC jC kC"},J:{"1":"A","2":"D"},K:{"1":"c","2":"A B C mB 2B nB"},L:{"1":"H"},M:{"1":"b"},N:{"1":"A B"},O:{"1":"oC"},P:{"1":"I pC qC rC sC tC vB uC vC wC xC yC oB zC 0C"},Q:{"1":"wB"},R:{"1":"1C"},S:{"1":"2C"}},B:2,C:"Navigation Timing API"}; |
|||
@ -0,0 +1,478 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 * as zrUtil from 'zrender/lib/core/util.js'; // id may be function name of Object, add a prefix to avoid this problem.
|
|||
|
|||
function generateNodeKey(id) { |
|||
return '_EC_' + id; |
|||
} |
|||
|
|||
var Graph = |
|||
/** @class */ |
|||
function () { |
|||
function Graph(directed) { |
|||
this.type = 'graph'; |
|||
this.nodes = []; |
|||
this.edges = []; |
|||
this._nodesMap = {}; |
|||
/** |
|||
* @type {Object.<string, module:echarts/data/Graph.Edge>} |
|||
* @private |
|||
*/ |
|||
|
|||
this._edgesMap = {}; |
|||
this._directed = directed || false; |
|||
} |
|||
/** |
|||
* If is directed graph |
|||
*/ |
|||
|
|||
|
|||
Graph.prototype.isDirected = function () { |
|||
return this._directed; |
|||
}; |
|||
|
|||
; |
|||
/** |
|||
* Add a new node |
|||
*/ |
|||
|
|||
Graph.prototype.addNode = function (id, dataIndex) { |
|||
id = id == null ? '' + dataIndex : '' + id; |
|||
var nodesMap = this._nodesMap; |
|||
|
|||
if (nodesMap[generateNodeKey(id)]) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
console.error('Graph nodes have duplicate name or id'); |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
var node = new GraphNode(id, dataIndex); |
|||
node.hostGraph = this; |
|||
this.nodes.push(node); |
|||
nodesMap[generateNodeKey(id)] = node; |
|||
return node; |
|||
}; |
|||
|
|||
; |
|||
/** |
|||
* Get node by data index |
|||
*/ |
|||
|
|||
Graph.prototype.getNodeByIndex = function (dataIndex) { |
|||
var rawIdx = this.data.getRawIndex(dataIndex); |
|||
return this.nodes[rawIdx]; |
|||
}; |
|||
|
|||
; |
|||
/** |
|||
* Get node by id |
|||
*/ |
|||
|
|||
Graph.prototype.getNodeById = function (id) { |
|||
return this._nodesMap[generateNodeKey(id)]; |
|||
}; |
|||
|
|||
; |
|||
/** |
|||
* Add a new edge |
|||
*/ |
|||
|
|||
Graph.prototype.addEdge = function (n1, n2, dataIndex) { |
|||
var nodesMap = this._nodesMap; |
|||
var edgesMap = this._edgesMap; // PNEDING
|
|||
|
|||
if (zrUtil.isNumber(n1)) { |
|||
n1 = this.nodes[n1]; |
|||
} |
|||
|
|||
if (zrUtil.isNumber(n2)) { |
|||
n2 = this.nodes[n2]; |
|||
} |
|||
|
|||
if (!(n1 instanceof GraphNode)) { |
|||
n1 = nodesMap[generateNodeKey(n1)]; |
|||
} |
|||
|
|||
if (!(n2 instanceof GraphNode)) { |
|||
n2 = nodesMap[generateNodeKey(n2)]; |
|||
} |
|||
|
|||
if (!n1 || !n2) { |
|||
return; |
|||
} |
|||
|
|||
var key = n1.id + '-' + n2.id; |
|||
var edge = new GraphEdge(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 |
|||
*/ |
|||
|
|||
Graph.prototype.getEdgeByIndex = function (dataIndex) { |
|||
var rawIdx = this.edgeData.getRawIndex(dataIndex); |
|||
return this.edges[rawIdx]; |
|||
}; |
|||
|
|||
; |
|||
/** |
|||
* Get edge by two linked nodes |
|||
*/ |
|||
|
|||
Graph.prototype.getEdge = function (n1, n2) { |
|||
if (n1 instanceof GraphNode) { |
|||
n1 = n1.id; |
|||
} |
|||
|
|||
if (n2 instanceof GraphNode) { |
|||
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 |
|||
*/ |
|||
|
|||
Graph.prototype.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 |
|||
*/ |
|||
|
|||
Graph.prototype.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 |
|||
* Return true to stop traversing |
|||
*/ |
|||
|
|||
Graph.prototype.breadthFirstTraverse = function (cb, startNode, direction, context) { |
|||
if (!(startNode instanceof GraphNode)) { |
|||
startNode = this._nodesMap[generateNodeKey(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(context, otherNode, currentNode)) { |
|||
// Stop traversing
|
|||
return; |
|||
} |
|||
|
|||
queue.push(otherNode); |
|||
otherNode.__visited = true; |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
|
|||
; // TODO
|
|||
// depthFirstTraverse(
|
|||
// cb, startNode, direction, context
|
|||
// ) {
|
|||
// };
|
|||
// Filter update
|
|||
|
|||
Graph.prototype.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} |
|||
*/ |
|||
|
|||
Graph.prototype.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; |
|||
}; |
|||
|
|||
; |
|||
return Graph; |
|||
}(); |
|||
|
|||
var GraphNode = |
|||
/** @class */ |
|||
function () { |
|||
function GraphNode(id, dataIndex) { |
|||
this.inEdges = []; |
|||
this.outEdges = []; |
|||
this.edges = []; |
|||
this.dataIndex = -1; |
|||
this.id = id == null ? '' : id; |
|||
this.dataIndex = dataIndex == null ? -1 : dataIndex; |
|||
} |
|||
/** |
|||
* @return {number} |
|||
*/ |
|||
|
|||
|
|||
GraphNode.prototype.degree = function () { |
|||
return this.edges.length; |
|||
}; |
|||
/** |
|||
* @return {number} |
|||
*/ |
|||
|
|||
|
|||
GraphNode.prototype.inDegree = function () { |
|||
return this.inEdges.length; |
|||
}; |
|||
/** |
|||
* @return {number} |
|||
*/ |
|||
|
|||
|
|||
GraphNode.prototype.outDegree = function () { |
|||
return this.outEdges.length; |
|||
}; |
|||
|
|||
GraphNode.prototype.getModel = function (path) { |
|||
if (this.dataIndex < 0) { |
|||
return; |
|||
} |
|||
|
|||
var graph = this.hostGraph; |
|||
var itemModel = graph.data.getItemModel(this.dataIndex); |
|||
return itemModel.getModel(path); |
|||
}; |
|||
|
|||
GraphNode.prototype.getAdjacentDataIndices = function () { |
|||
var dataIndices = { |
|||
edge: [], |
|||
node: [] |
|||
}; |
|||
|
|||
for (var i = 0; i < this.edges.length; i++) { |
|||
var adjacentEdge = this.edges[i]; |
|||
|
|||
if (adjacentEdge.dataIndex < 0) { |
|||
continue; |
|||
} |
|||
|
|||
dataIndices.edge.push(adjacentEdge.dataIndex); |
|||
dataIndices.node.push(adjacentEdge.node1.dataIndex, adjacentEdge.node2.dataIndex); |
|||
} |
|||
|
|||
return dataIndices; |
|||
}; |
|||
|
|||
return GraphNode; |
|||
}(); |
|||
|
|||
var GraphEdge = |
|||
/** @class */ |
|||
function () { |
|||
function GraphEdge(n1, n2, dataIndex) { |
|||
this.dataIndex = -1; |
|||
this.node1 = n1; |
|||
this.node2 = n2; |
|||
this.dataIndex = dataIndex == null ? -1 : dataIndex; |
|||
} // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|||
|
|||
|
|||
GraphEdge.prototype.getModel = function (path) { |
|||
if (this.dataIndex < 0) { |
|||
return; |
|||
} |
|||
|
|||
var graph = this.hostGraph; |
|||
var itemModel = graph.edgeData.getItemModel(this.dataIndex); |
|||
return itemModel.getModel(path); |
|||
}; |
|||
|
|||
GraphEdge.prototype.getAdjacentDataIndices = function () { |
|||
return { |
|||
edge: [this.dataIndex], |
|||
node: [this.node1.dataIndex, this.node2.dataIndex] |
|||
}; |
|||
}; |
|||
|
|||
return GraphEdge; |
|||
}(); |
|||
|
|||
function createGraphDataProxyMixin(hostName, dataName) { |
|||
return { |
|||
/** |
|||
* @param Default 'value'. can be 'a', 'b', 'c', 'd', 'e'. |
|||
*/ |
|||
getValue: function (dimension) { |
|||
var data = this[hostName][dataName]; |
|||
return data.getStore().get(data.getDimensionIndex(dimension || 'value'), this.dataIndex); |
|||
}, |
|||
// TODO: TYPE stricter type.
|
|||
setVisual: function (key, value) { |
|||
this.dataIndex >= 0 && this[hostName][dataName].setItemVisual(this.dataIndex, key, value); |
|||
}, |
|||
getVisual: function (key) { |
|||
return this[hostName][dataName].getItemVisual(this.dataIndex, key); |
|||
}, |
|||
setLayout: function (layout, merge) { |
|||
this.dataIndex >= 0 && this[hostName][dataName].setItemLayout(this.dataIndex, layout, merge); |
|||
}, |
|||
getLayout: function () { |
|||
return this[hostName][dataName].getItemLayout(this.dataIndex); |
|||
}, |
|||
getGraphicEl: function () { |
|||
return this[hostName][dataName].getItemGraphicEl(this.dataIndex); |
|||
}, |
|||
getRawIndex: function () { |
|||
return this[hostName][dataName].getRawIndex(this.dataIndex); |
|||
} |
|||
}; |
|||
} |
|||
|
|||
; |
|||
; |
|||
; |
|||
zrUtil.mixin(GraphNode, createGraphDataProxyMixin('hostGraph', 'data')); |
|||
zrUtil.mixin(GraphEdge, createGraphDataProxyMixin('hostGraph', 'edgeData')); |
|||
export default Graph; |
|||
export { GraphNode, GraphEdge }; |
|||
@ -0,0 +1,141 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { createHashMap, isObject, map, isString } from 'zrender/lib/core/util.js'; |
|||
var uidBase = 0; |
|||
|
|||
var OrdinalMeta = |
|||
/** @class */ |
|||
function () { |
|||
function OrdinalMeta(opt) { |
|||
this.categories = opt.categories || []; |
|||
this._needCollect = opt.needCollect; |
|||
this._deduplication = opt.deduplication; |
|||
this.uid = ++uidBase; |
|||
} |
|||
|
|||
OrdinalMeta.createByAxisModel = function (axisModel) { |
|||
var option = axisModel.option; |
|||
var data = option.data; |
|||
var categories = data && map(data, getName); |
|||
return new OrdinalMeta({ |
|||
categories: categories, |
|||
needCollect: !categories, |
|||
// deduplication is default in axis.
|
|||
deduplication: option.dedplication !== false |
|||
}); |
|||
}; |
|||
|
|||
; |
|||
|
|||
OrdinalMeta.prototype.getOrdinal = function (category) { |
|||
// @ts-ignore
|
|||
return this._getOrCreateMap().get(category); |
|||
}; |
|||
/** |
|||
* @return The ordinal. If not found, return NaN. |
|||
*/ |
|||
|
|||
|
|||
OrdinalMeta.prototype.parseAndCollect = function (category) { |
|||
var index; |
|||
var needCollect = this._needCollect; // The value of category dim can be the index of the given category set.
|
|||
// This feature is only supported when !needCollect, because we should
|
|||
// consider a common case: a value is 2017, which is a number but is
|
|||
// expected to be tread as a category. This case usually happen in dataset,
|
|||
// where it happent to be no need of the index feature.
|
|||
|
|||
if (!isString(category) && !needCollect) { |
|||
return category; |
|||
} // Optimize for the scenario:
|
|||
// category is ['2012-01-01', '2012-01-02', ...], where the input
|
|||
// data has been ensured not duplicate and is large data.
|
|||
// Notice, if a dataset dimension provide categroies, usually echarts
|
|||
// should remove duplication except user tell echarts dont do that
|
|||
// (set axis.deduplication = false), because echarts do not know whether
|
|||
// the values in the category dimension has duplication (consider the
|
|||
// parallel-aqi example)
|
|||
|
|||
|
|||
if (needCollect && !this._deduplication) { |
|||
index = this.categories.length; |
|||
this.categories[index] = category; |
|||
return index; |
|||
} |
|||
|
|||
var map = this._getOrCreateMap(); // @ts-ignore
|
|||
|
|||
|
|||
index = map.get(category); |
|||
|
|||
if (index == null) { |
|||
if (needCollect) { |
|||
index = this.categories.length; |
|||
this.categories[index] = category; // @ts-ignore
|
|||
|
|||
map.set(category, index); |
|||
} else { |
|||
index = NaN; |
|||
} |
|||
} |
|||
|
|||
return index; |
|||
}; // Consider big data, do not create map until needed.
|
|||
|
|||
|
|||
OrdinalMeta.prototype._getOrCreateMap = function () { |
|||
return this._map || (this._map = createHashMap(this.categories)); |
|||
}; |
|||
|
|||
return OrdinalMeta; |
|||
}(); |
|||
|
|||
function getName(obj) { |
|||
if (isObject(obj) && obj.value != null) { |
|||
return obj.value; |
|||
} else { |
|||
return obj + ''; |
|||
} |
|||
} |
|||
|
|||
export default OrdinalMeta; |
|||
File diff suppressed because it is too large
@ -0,0 +1,97 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 * as zrUtil from 'zrender/lib/core/util.js'; |
|||
|
|||
var SeriesDimensionDefine = |
|||
/** @class */ |
|||
function () { |
|||
/** |
|||
* @param opt All of the fields will be shallow copied. |
|||
*/ |
|||
function SeriesDimensionDefine(opt) { |
|||
/** |
|||
* The format of `otherDims` is: |
|||
* ```js
|
|||
* { |
|||
* tooltip?: number |
|||
* label?: number |
|||
* itemName?: number |
|||
* seriesName?: number |
|||
* } |
|||
* ``` |
|||
* |
|||
* A `series.encode` can specified these fields: |
|||
* ```js
|
|||
* encode: { |
|||
* // "3, 1, 5" is the index of data dimension.
|
|||
* tooltip: [3, 1, 5], |
|||
* label: [0, 3], |
|||
* ... |
|||
* } |
|||
* ``` |
|||
* `otherDims` is the parse result of the `series.encode` above, like: |
|||
* ```js
|
|||
* // Suppose the index of this data dimension is `3`.
|
|||
* this.otherDims = { |
|||
* // `3` is at the index `0` of the `encode.tooltip`
|
|||
* tooltip: 0, |
|||
* // `3` is at the index `1` of the `encode.label`
|
|||
* label: 1 |
|||
* }; |
|||
* ``` |
|||
* |
|||
* This prop should never be `null`/`undefined` after initialized. |
|||
*/ |
|||
this.otherDims = {}; |
|||
|
|||
if (opt != null) { |
|||
zrUtil.extend(this, opt); |
|||
} |
|||
} |
|||
|
|||
return SeriesDimensionDefine; |
|||
}(); |
|||
|
|||
; |
|||
export default SeriesDimensionDefine; |
|||
@ -0,0 +1,333 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { isTypedArray, clone, createHashMap, isArray, isObject, isArrayLike, hasOwn, assert, each, map, isNumber, isString } from 'zrender/lib/core/util.js'; |
|||
import { SOURCE_FORMAT_ORIGINAL, SERIES_LAYOUT_BY_COLUMN, SOURCE_FORMAT_UNKNOWN, SOURCE_FORMAT_KEYED_COLUMNS, SOURCE_FORMAT_TYPED_ARRAY, SOURCE_FORMAT_ARRAY_ROWS, SOURCE_FORMAT_OBJECT_ROWS, SERIES_LAYOUT_BY_ROW } from '../util/types.js'; |
|||
import { getDataItemValue } from '../util/model.js'; |
|||
import { BE_ORDINAL, guessOrdinal } from './helper/sourceHelper.js'; |
|||
; // @inner
|
|||
|
|||
var SourceImpl = |
|||
/** @class */ |
|||
function () { |
|||
function SourceImpl(fields) { |
|||
this.data = fields.data || (fields.sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS ? {} : []); |
|||
this.sourceFormat = fields.sourceFormat || SOURCE_FORMAT_UNKNOWN; // Visit config
|
|||
|
|||
this.seriesLayoutBy = fields.seriesLayoutBy || SERIES_LAYOUT_BY_COLUMN; |
|||
this.startIndex = fields.startIndex || 0; |
|||
this.dimensionsDetectedCount = fields.dimensionsDetectedCount; |
|||
this.metaRawOption = fields.metaRawOption; |
|||
var dimensionsDefine = this.dimensionsDefine = fields.dimensionsDefine; |
|||
|
|||
if (dimensionsDefine) { |
|||
for (var i = 0; i < dimensionsDefine.length; i++) { |
|||
var dim = dimensionsDefine[i]; |
|||
|
|||
if (dim.type == null) { |
|||
if (guessOrdinal(this, i) === BE_ORDINAL.Must) { |
|||
dim.type = 'ordinal'; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return SourceImpl; |
|||
}(); |
|||
|
|||
export function isSourceInstance(val) { |
|||
return val instanceof SourceImpl; |
|||
} |
|||
/** |
|||
* Create a source from option. |
|||
* NOTE: Created source is immutable. Don't change any properties in it. |
|||
*/ |
|||
|
|||
export function createSource(sourceData, thisMetaRawOption, // can be null. If not provided, auto detect it from `sourceData`.
|
|||
sourceFormat) { |
|||
sourceFormat = sourceFormat || detectSourceFormat(sourceData); |
|||
var seriesLayoutBy = thisMetaRawOption.seriesLayoutBy; |
|||
var determined = determineSourceDimensions(sourceData, sourceFormat, seriesLayoutBy, thisMetaRawOption.sourceHeader, thisMetaRawOption.dimensions); |
|||
var source = new SourceImpl({ |
|||
data: sourceData, |
|||
sourceFormat: sourceFormat, |
|||
seriesLayoutBy: seriesLayoutBy, |
|||
dimensionsDefine: determined.dimensionsDefine, |
|||
startIndex: determined.startIndex, |
|||
dimensionsDetectedCount: determined.dimensionsDetectedCount, |
|||
metaRawOption: clone(thisMetaRawOption) |
|||
}); |
|||
return source; |
|||
} |
|||
/** |
|||
* Wrap original series data for some compatibility cases. |
|||
*/ |
|||
|
|||
export function createSourceFromSeriesDataOption(data) { |
|||
return new SourceImpl({ |
|||
data: data, |
|||
sourceFormat: isTypedArray(data) ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL |
|||
}); |
|||
} |
|||
/** |
|||
* Clone source but excludes source data. |
|||
*/ |
|||
|
|||
export function cloneSourceShallow(source) { |
|||
return new SourceImpl({ |
|||
data: source.data, |
|||
sourceFormat: source.sourceFormat, |
|||
seriesLayoutBy: source.seriesLayoutBy, |
|||
dimensionsDefine: clone(source.dimensionsDefine), |
|||
startIndex: source.startIndex, |
|||
dimensionsDetectedCount: source.dimensionsDetectedCount |
|||
}); |
|||
} |
|||
/** |
|||
* Note: An empty array will be detected as `SOURCE_FORMAT_ARRAY_ROWS`. |
|||
*/ |
|||
|
|||
export function detectSourceFormat(data) { |
|||
var sourceFormat = SOURCE_FORMAT_UNKNOWN; |
|||
|
|||
if (isTypedArray(data)) { |
|||
sourceFormat = SOURCE_FORMAT_TYPED_ARRAY; |
|||
} else if (isArray(data)) { |
|||
// FIXME Whether tolerate null in top level array?
|
|||
if (data.length === 0) { |
|||
sourceFormat = SOURCE_FORMAT_ARRAY_ROWS; |
|||
} |
|||
|
|||
for (var i = 0, len = data.length; i < len; i++) { |
|||
var item = data[i]; |
|||
|
|||
if (item == null) { |
|||
continue; |
|||
} else if (isArray(item)) { |
|||
sourceFormat = SOURCE_FORMAT_ARRAY_ROWS; |
|||
break; |
|||
} else if (isObject(item)) { |
|||
sourceFormat = SOURCE_FORMAT_OBJECT_ROWS; |
|||
break; |
|||
} |
|||
} |
|||
} else if (isObject(data)) { |
|||
for (var key in data) { |
|||
if (hasOwn(data, key) && isArrayLike(data[key])) { |
|||
sourceFormat = SOURCE_FORMAT_KEYED_COLUMNS; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return sourceFormat; |
|||
} |
|||
/** |
|||
* Determine the source definitions from data standalone dimensions definitions |
|||
* are not specified. |
|||
*/ |
|||
|
|||
function determineSourceDimensions(data, sourceFormat, seriesLayoutBy, sourceHeader, // standalone raw dimensions definition, like:
|
|||
// {
|
|||
// dimensions: ['aa', 'bb', { name: 'cc', type: 'time' }]
|
|||
// }
|
|||
// in `dataset` or `series`
|
|||
dimensionsDefine) { |
|||
var dimensionsDetectedCount; |
|||
var startIndex; // PEDING: could data be null/undefined here?
|
|||
// currently, if `dataset.source` not specified, error thrown.
|
|||
// if `series.data` not specified, nothing rendered without error thrown.
|
|||
// Should test these cases.
|
|||
|
|||
if (!data) { |
|||
return { |
|||
dimensionsDefine: normalizeDimensionsOption(dimensionsDefine), |
|||
startIndex: startIndex, |
|||
dimensionsDetectedCount: dimensionsDetectedCount |
|||
}; |
|||
} |
|||
|
|||
if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) { |
|||
var dataArrayRows = data; // Rule: Most of the first line are string: it is header.
|
|||
// Caution: consider a line with 5 string and 1 number,
|
|||
// it still can not be sure it is a head, because the
|
|||
// 5 string may be 5 values of category columns.
|
|||
|
|||
if (sourceHeader === 'auto' || sourceHeader == null) { |
|||
arrayRowsTravelFirst(function (val) { |
|||
// '-' is regarded as null/undefined.
|
|||
if (val != null && val !== '-') { |
|||
if (isString(val)) { |
|||
startIndex == null && (startIndex = 1); |
|||
} else { |
|||
startIndex = 0; |
|||
} |
|||
} // 10 is an experience number, avoid long loop.
|
|||
|
|||
}, seriesLayoutBy, dataArrayRows, 10); |
|||
} else { |
|||
startIndex = isNumber(sourceHeader) ? sourceHeader : sourceHeader ? 1 : 0; |
|||
} |
|||
|
|||
if (!dimensionsDefine && startIndex === 1) { |
|||
dimensionsDefine = []; |
|||
arrayRowsTravelFirst(function (val, index) { |
|||
dimensionsDefine[index] = val != null ? val + '' : ''; |
|||
}, seriesLayoutBy, dataArrayRows, Infinity); |
|||
} |
|||
|
|||
dimensionsDetectedCount = dimensionsDefine ? dimensionsDefine.length : seriesLayoutBy === SERIES_LAYOUT_BY_ROW ? dataArrayRows.length : dataArrayRows[0] ? dataArrayRows[0].length : null; |
|||
} else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) { |
|||
if (!dimensionsDefine) { |
|||
dimensionsDefine = objectRowsCollectDimensions(data); |
|||
} |
|||
} else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) { |
|||
if (!dimensionsDefine) { |
|||
dimensionsDefine = []; |
|||
each(data, function (colArr, key) { |
|||
dimensionsDefine.push(key); |
|||
}); |
|||
} |
|||
} else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) { |
|||
var value0 = getDataItemValue(data[0]); |
|||
dimensionsDetectedCount = isArray(value0) && value0.length || 1; |
|||
} else if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(!!dimensionsDefine, 'dimensions must be given if data is TypedArray.'); |
|||
} |
|||
} |
|||
|
|||
return { |
|||
startIndex: startIndex, |
|||
dimensionsDefine: normalizeDimensionsOption(dimensionsDefine), |
|||
dimensionsDetectedCount: dimensionsDetectedCount |
|||
}; |
|||
} |
|||
|
|||
function objectRowsCollectDimensions(data) { |
|||
var firstIndex = 0; |
|||
var obj; |
|||
|
|||
while (firstIndex < data.length && !(obj = data[firstIndex++])) {} // jshint ignore: line
|
|||
|
|||
|
|||
if (obj) { |
|||
var dimensions_1 = []; |
|||
each(obj, function (value, key) { |
|||
dimensions_1.push(key); |
|||
}); |
|||
return dimensions_1; |
|||
} |
|||
} // Consider dimensions defined like ['A', 'price', 'B', 'price', 'C', 'price'],
|
|||
// which is reasonable. But dimension name is duplicated.
|
|||
// Returns undefined or an array contains only object without null/undefiend or string.
|
|||
|
|||
|
|||
function normalizeDimensionsOption(dimensionsDefine) { |
|||
if (!dimensionsDefine) { |
|||
// The meaning of null/undefined is different from empty array.
|
|||
return; |
|||
} |
|||
|
|||
var nameMap = createHashMap(); |
|||
return map(dimensionsDefine, function (rawItem, index) { |
|||
rawItem = isObject(rawItem) ? rawItem : { |
|||
name: rawItem |
|||
}; // Other fields will be discarded.
|
|||
|
|||
var item = { |
|||
name: rawItem.name, |
|||
displayName: rawItem.displayName, |
|||
type: rawItem.type |
|||
}; // User can set null in dimensions.
|
|||
// We dont auto specify name, othewise a given name may
|
|||
// cause it be refered unexpectedly.
|
|||
|
|||
if (item.name == null) { |
|||
return item; |
|||
} // Also consider number form like 2012.
|
|||
|
|||
|
|||
item.name += ''; // User may also specify displayName.
|
|||
// displayName will always exists except user not
|
|||
// specified or dim name is not specified or detected.
|
|||
// (A auto generated dim name will not be used as
|
|||
// displayName).
|
|||
|
|||
if (item.displayName == null) { |
|||
item.displayName = item.name; |
|||
} |
|||
|
|||
var exist = nameMap.get(item.name); |
|||
|
|||
if (!exist) { |
|||
nameMap.set(item.name, { |
|||
count: 1 |
|||
}); |
|||
} else { |
|||
item.name += '-' + exist.count++; |
|||
} |
|||
|
|||
return item; |
|||
}); |
|||
} |
|||
|
|||
function arrayRowsTravelFirst(cb, seriesLayoutBy, data, maxLoop) { |
|||
if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) { |
|||
for (var i = 0; i < data.length && i < maxLoop; i++) { |
|||
cb(data[i] ? data[i][0] : null, i); |
|||
} |
|||
} else { |
|||
var value0 = data[0] || []; |
|||
|
|||
for (var i = 0; i < value0.length && i < maxLoop; i++) { |
|||
cb(value0[i], i); |
|||
} |
|||
} |
|||
} |
|||
|
|||
export function shouldRetrieveDataByName(source) { |
|||
var sourceFormat = source.sourceFormat; |
|||
return sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS; |
|||
} |
|||
@ -0,0 +1,436 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Tree data structure |
|||
*/ |
|||
import * as zrUtil from 'zrender/lib/core/util.js'; |
|||
import linkSeriesData from './helper/linkSeriesData.js'; |
|||
import SeriesData from './SeriesData.js'; |
|||
import prepareSeriesDataSchema from './helper/createDimensions.js'; |
|||
import { convertOptionIdName } from '../util/model.js'; |
|||
|
|||
var TreeNode = |
|||
/** @class */ |
|||
function () { |
|||
function TreeNode(name, hostTree) { |
|||
this.depth = 0; |
|||
this.height = 0; |
|||
/** |
|||
* 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. |
|||
*/ |
|||
|
|||
this.dataIndex = -1; |
|||
this.children = []; |
|||
this.viewChildren = []; |
|||
this.isExpand = false; |
|||
this.name = name || ''; |
|||
this.hostTree = hostTree; |
|||
} |
|||
/** |
|||
* The node is removed. |
|||
*/ |
|||
|
|||
|
|||
TreeNode.prototype.isRemoved = function () { |
|||
return this.dataIndex < 0; |
|||
}; |
|||
|
|||
TreeNode.prototype.eachNode = function (options, cb, context) { |
|||
if (zrUtil.isFunction(options)) { |
|||
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. |
|||
*/ |
|||
|
|||
|
|||
TreeNode.prototype.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; |
|||
}; |
|||
|
|||
TreeNode.prototype.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; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
TreeNode.prototype.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 includeSelf Default false. |
|||
* @return order: [root, child, grandchild, ...] |
|||
*/ |
|||
|
|||
|
|||
TreeNode.prototype.getAncestors = function (includeSelf) { |
|||
var ancestors = []; |
|||
var node = includeSelf ? this : this.parentNode; |
|||
|
|||
while (node) { |
|||
ancestors.push(node); |
|||
node = node.parentNode; |
|||
} |
|||
|
|||
ancestors.reverse(); |
|||
return ancestors; |
|||
}; |
|||
|
|||
TreeNode.prototype.getAncestorsIndices = function () { |
|||
var indices = []; |
|||
var currNode = this; |
|||
|
|||
while (currNode) { |
|||
indices.push(currNode.dataIndex); |
|||
currNode = currNode.parentNode; |
|||
} |
|||
|
|||
indices.reverse(); |
|||
return indices; |
|||
}; |
|||
|
|||
TreeNode.prototype.getDescendantIndices = function () { |
|||
var indices = []; |
|||
this.eachNode(function (childNode) { |
|||
indices.push(childNode.dataIndex); |
|||
}); |
|||
return indices; |
|||
}; |
|||
|
|||
TreeNode.prototype.getValue = function (dimension) { |
|||
var data = this.hostTree.data; |
|||
return data.getStore().get(data.getDimensionIndex(dimension || 'value'), this.dataIndex); |
|||
}; |
|||
|
|||
TreeNode.prototype.setLayout = function (layout, merge) { |
|||
this.dataIndex >= 0 && this.hostTree.data.setItemLayout(this.dataIndex, layout, merge); |
|||
}; |
|||
/** |
|||
* @return {Object} layout |
|||
*/ |
|||
|
|||
|
|||
TreeNode.prototype.getLayout = function () { |
|||
return this.hostTree.data.getItemLayout(this.dataIndex); |
|||
}; // @depcrecated
|
|||
// getModel<T = unknown, S extends keyof T = keyof T>(path: S): Model<T[S]>
|
|||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|||
|
|||
|
|||
TreeNode.prototype.getModel = function (path) { |
|||
if (this.dataIndex < 0) { |
|||
return; |
|||
} |
|||
|
|||
var hostTree = this.hostTree; |
|||
var itemModel = hostTree.data.getItemModel(this.dataIndex); |
|||
return itemModel.getModel(path); |
|||
}; // TODO: TYPE More specific model
|
|||
|
|||
|
|||
TreeNode.prototype.getLevelModel = function () { |
|||
return (this.hostTree.levelModels || [])[this.depth]; |
|||
}; |
|||
|
|||
TreeNode.prototype.setVisual = function (key, value) { |
|||
this.dataIndex >= 0 && this.hostTree.data.setItemVisual(this.dataIndex, key, value); |
|||
}; |
|||
/** |
|||
* Get item visual |
|||
* FIXME: make return type better |
|||
*/ |
|||
|
|||
|
|||
TreeNode.prototype.getVisual = function (key) { |
|||
return this.hostTree.data.getItemVisual(this.dataIndex, key); |
|||
}; |
|||
|
|||
TreeNode.prototype.getRawIndex = function () { |
|||
return this.hostTree.data.getRawIndex(this.dataIndex); |
|||
}; |
|||
|
|||
TreeNode.prototype.getId = function () { |
|||
return this.hostTree.data.getId(this.dataIndex); |
|||
}; |
|||
/** |
|||
* index in parent's children |
|||
*/ |
|||
|
|||
|
|||
TreeNode.prototype.getChildIndex = function () { |
|||
if (this.parentNode) { |
|||
var children = this.parentNode.children; |
|||
|
|||
for (var i = 0; i < children.length; ++i) { |
|||
if (children[i] === this) { |
|||
return i; |
|||
} |
|||
} |
|||
|
|||
return -1; |
|||
} |
|||
|
|||
return -1; |
|||
}; |
|||
/** |
|||
* if this is an ancestor of another node |
|||
* |
|||
* @param node another node |
|||
* @return if is ancestor |
|||
*/ |
|||
|
|||
|
|||
TreeNode.prototype.isAncestorOf = function (node) { |
|||
var parent = node.parentNode; |
|||
|
|||
while (parent) { |
|||
if (parent === this) { |
|||
return true; |
|||
} |
|||
|
|||
parent = parent.parentNode; |
|||
} |
|||
|
|||
return false; |
|||
}; |
|||
/** |
|||
* if this is an descendant of another node |
|||
* |
|||
* @param node another node |
|||
* @return if is descendant |
|||
*/ |
|||
|
|||
|
|||
TreeNode.prototype.isDescendantOf = function (node) { |
|||
return node !== this && node.isAncestorOf(this); |
|||
}; |
|||
|
|||
return TreeNode; |
|||
}(); |
|||
|
|||
export { TreeNode }; |
|||
; |
|||
|
|||
var Tree = |
|||
/** @class */ |
|||
function () { |
|||
function Tree(hostModel) { |
|||
this.type = 'tree'; |
|||
this._nodes = []; |
|||
this.hostModel = hostModel; |
|||
} |
|||
|
|||
Tree.prototype.eachNode = function (options, cb, context) { |
|||
this.root.eachNode(options, cb, context); |
|||
}; |
|||
|
|||
Tree.prototype.getNodeByDataIndex = function (dataIndex) { |
|||
var rawIndex = this.data.getRawIndex(dataIndex); |
|||
return this._nodes[rawIndex]; |
|||
}; |
|||
|
|||
Tree.prototype.getNodeById = function (name) { |
|||
return this.root.getNodeById(name); |
|||
}; |
|||
/** |
|||
* Update item available by list, |
|||
* when list has been performed options like 'filterSelf' or 'map'. |
|||
*/ |
|||
|
|||
|
|||
Tree.prototype.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 |
|||
*/ |
|||
|
|||
|
|||
Tree.prototype.clearLayouts = function () { |
|||
this.data.clearItemLayouts(); |
|||
}; |
|||
/** |
|||
* data node format: |
|||
* { |
|||
* name: ... |
|||
* value: ... |
|||
* children: [ |
|||
* { |
|||
* name: ... |
|||
* value: ... |
|||
* children: ... |
|||
* }, |
|||
* ... |
|||
* ] |
|||
* } |
|||
*/ |
|||
|
|||
|
|||
Tree.createTree = function (dataRoot, hostModel, beforeLink) { |
|||
var tree = new Tree(hostModel); |
|||
var listData = []; |
|||
var dimMax = 1; |
|||
buildHierarchy(dataRoot); |
|||
|
|||
function buildHierarchy(dataNode, parentNode) { |
|||
var value = dataNode.value; |
|||
dimMax = Math.max(dimMax, zrUtil.isArray(value) ? value.length : 1); |
|||
listData.push(dataNode); |
|||
var node = new TreeNode(convertOptionIdName(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 = prepareSeriesDataSchema(listData, { |
|||
coordDimensions: ['value'], |
|||
dimensionsCount: dimMax |
|||
}).dimensions; |
|||
var list = new SeriesData(dimensions, hostModel); |
|||
list.initData(listData); |
|||
beforeLink && beforeLink(list); |
|||
linkSeriesData({ |
|||
mainData: list, |
|||
struct: tree, |
|||
structAttr: 'tree' |
|||
}); |
|||
tree.update(); |
|||
return tree; |
|||
}; |
|||
|
|||
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. |
|||
*/ |
|||
|
|||
|
|||
function addChild(child, node) { |
|||
var children = node.children; |
|||
|
|||
if (child.parentNode === node) { |
|||
return; |
|||
} |
|||
|
|||
children.push(child); |
|||
child.parentNode = node; |
|||
} |
|||
|
|||
export default Tree; |
|||
@ -0,0 +1,254 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { createHashMap, isObject, retrieve2 } from 'zrender/lib/core/util.js'; |
|||
import { makeInner } from '../../util/model.js'; |
|||
import { shouldRetrieveDataByName } from '../Source.js'; |
|||
var inner = makeInner(); |
|||
var dimTypeShort = { |
|||
float: 'f', |
|||
int: 'i', |
|||
ordinal: 'o', |
|||
number: 'n', |
|||
time: 't' |
|||
}; |
|||
/** |
|||
* Represents the dimension requirement of a series. |
|||
* |
|||
* NOTICE: |
|||
* When there are too many dimensions in dataset and many series, only the used dimensions |
|||
* (i.e., used by coord sys and declared in `series.encode`) are add to `dimensionDefineList`. |
|||
* But users may query data by other unused dimension names. |
|||
* In this case, users can only query data if and only if they have defined dimension names |
|||
* via ec option, so we provide `getDimensionIndexFromSource`, which only query them from |
|||
* `source` dimensions. |
|||
*/ |
|||
|
|||
var SeriesDataSchema = |
|||
/** @class */ |
|||
function () { |
|||
function SeriesDataSchema(opt) { |
|||
this.dimensions = opt.dimensions; |
|||
this._dimOmitted = opt.dimensionOmitted; |
|||
this.source = opt.source; |
|||
this._fullDimCount = opt.fullDimensionCount; |
|||
|
|||
this._updateDimOmitted(opt.dimensionOmitted); |
|||
} |
|||
|
|||
SeriesDataSchema.prototype.isDimensionOmitted = function () { |
|||
return this._dimOmitted; |
|||
}; |
|||
|
|||
SeriesDataSchema.prototype._updateDimOmitted = function (dimensionOmitted) { |
|||
this._dimOmitted = dimensionOmitted; |
|||
|
|||
if (!dimensionOmitted) { |
|||
return; |
|||
} |
|||
|
|||
if (!this._dimNameMap) { |
|||
this._dimNameMap = ensureSourceDimNameMap(this.source); |
|||
} |
|||
}; |
|||
/** |
|||
* @caution Can only be used when `dimensionOmitted: true`. |
|||
* |
|||
* Get index by user defined dimension name (i.e., not internal generate name). |
|||
* That is, get index from `dimensionsDefine`. |
|||
* If no `dimensionsDefine`, or no name get, return -1. |
|||
*/ |
|||
|
|||
|
|||
SeriesDataSchema.prototype.getSourceDimensionIndex = function (dimName) { |
|||
return retrieve2(this._dimNameMap.get(dimName), -1); |
|||
}; |
|||
/** |
|||
* @caution Can only be used when `dimensionOmitted: true`. |
|||
* |
|||
* Notice: may return `null`/`undefined` if user not specify dimension names. |
|||
*/ |
|||
|
|||
|
|||
SeriesDataSchema.prototype.getSourceDimension = function (dimIndex) { |
|||
var dimensionsDefine = this.source.dimensionsDefine; |
|||
|
|||
if (dimensionsDefine) { |
|||
return dimensionsDefine[dimIndex]; |
|||
} |
|||
}; |
|||
|
|||
SeriesDataSchema.prototype.makeStoreSchema = function () { |
|||
var dimCount = this._fullDimCount; |
|||
var willRetrieveDataByName = shouldRetrieveDataByName(this.source); |
|||
var makeHashStrict = !shouldOmitUnusedDimensions(dimCount); // If source don't have dimensions or series don't omit unsed dimensions.
|
|||
// Generate from seriesDimList directly
|
|||
|
|||
var dimHash = ''; |
|||
var dims = []; |
|||
|
|||
for (var fullDimIdx = 0, seriesDimIdx = 0; fullDimIdx < dimCount; fullDimIdx++) { |
|||
var property = void 0; |
|||
var type = void 0; |
|||
var ordinalMeta = void 0; |
|||
var seriesDimDef = this.dimensions[seriesDimIdx]; // The list has been sorted by `storeDimIndex` asc.
|
|||
|
|||
if (seriesDimDef && seriesDimDef.storeDimIndex === fullDimIdx) { |
|||
property = willRetrieveDataByName ? seriesDimDef.name : null; |
|||
type = seriesDimDef.type; |
|||
ordinalMeta = seriesDimDef.ordinalMeta; |
|||
seriesDimIdx++; |
|||
} else { |
|||
var sourceDimDef = this.getSourceDimension(fullDimIdx); |
|||
|
|||
if (sourceDimDef) { |
|||
property = willRetrieveDataByName ? sourceDimDef.name : null; |
|||
type = sourceDimDef.type; |
|||
} |
|||
} |
|||
|
|||
dims.push({ |
|||
property: property, |
|||
type: type, |
|||
ordinalMeta: ordinalMeta |
|||
}); // If retrieving data by index,
|
|||
// use <index, type, ordinalMeta> to determine whether data can be shared.
|
|||
// (Becuase in this case there might be no dimension name defined in dataset, but indices always exists).
|
|||
// (indices are always 0, 1, 2, ..., so we can ignore them to shorten the hash).
|
|||
// Otherwise if retrieving data by property name (like `data: [{aa: 123, bb: 765}, ...]`),
|
|||
// use <property, type, ordinalMeta> in hash.
|
|||
|
|||
if (willRetrieveDataByName && property != null // For data stack, we have make sure each series has its own dim on this store.
|
|||
// So we do not add property to hash to make sure they can share this store.
|
|||
&& (!seriesDimDef || !seriesDimDef.isCalculationCoord)) { |
|||
dimHash += makeHashStrict // Use escape character '`' in case that property name contains '$'.
|
|||
? property.replace(/\`/g, '`1').replace(/\$/g, '`2') // For better performance, when there are large dimensions, tolerant this defects that hardly meet.
|
|||
: property; |
|||
} |
|||
|
|||
dimHash += '$'; |
|||
dimHash += dimTypeShort[type] || 'f'; |
|||
|
|||
if (ordinalMeta) { |
|||
dimHash += ordinalMeta.uid; |
|||
} |
|||
|
|||
dimHash += '$'; |
|||
} // Source from endpoint(usually series) will be read differently
|
|||
// when seriesLayoutBy or startIndex(which is affected by sourceHeader) are different.
|
|||
// So we use this three props as key.
|
|||
|
|||
|
|||
var source = this.source; |
|||
var hash = [source.seriesLayoutBy, source.startIndex, dimHash].join('$$'); |
|||
return { |
|||
dimensions: dims, |
|||
hash: hash |
|||
}; |
|||
}; |
|||
|
|||
SeriesDataSchema.prototype.makeOutputDimensionNames = function () { |
|||
var result = []; |
|||
|
|||
for (var fullDimIdx = 0, seriesDimIdx = 0; fullDimIdx < this._fullDimCount; fullDimIdx++) { |
|||
var name_1 = void 0; |
|||
var seriesDimDef = this.dimensions[seriesDimIdx]; // The list has been sorted by `storeDimIndex` asc.
|
|||
|
|||
if (seriesDimDef && seriesDimDef.storeDimIndex === fullDimIdx) { |
|||
if (!seriesDimDef.isCalculationCoord) { |
|||
name_1 = seriesDimDef.name; |
|||
} |
|||
|
|||
seriesDimIdx++; |
|||
} else { |
|||
var sourceDimDef = this.getSourceDimension(fullDimIdx); |
|||
|
|||
if (sourceDimDef) { |
|||
name_1 = sourceDimDef.name; |
|||
} |
|||
} |
|||
|
|||
result.push(name_1); |
|||
} |
|||
|
|||
return result; |
|||
}; |
|||
|
|||
SeriesDataSchema.prototype.appendCalculationDimension = function (dimDef) { |
|||
this.dimensions.push(dimDef); |
|||
dimDef.isCalculationCoord = true; |
|||
this._fullDimCount++; // If append dimension on a data store, consider the store
|
|||
// might be shared by different series, series dimensions not
|
|||
// really map to store dimensions.
|
|||
|
|||
this._updateDimOmitted(true); |
|||
}; |
|||
|
|||
return SeriesDataSchema; |
|||
}(); |
|||
|
|||
export { SeriesDataSchema }; |
|||
export function isSeriesDataSchema(schema) { |
|||
return schema instanceof SeriesDataSchema; |
|||
} |
|||
export function createDimNameMap(dimsDef) { |
|||
var dataDimNameMap = createHashMap(); |
|||
|
|||
for (var i = 0; i < (dimsDef || []).length; i++) { |
|||
var dimDefItemRaw = dimsDef[i]; |
|||
var userDimName = isObject(dimDefItemRaw) ? dimDefItemRaw.name : dimDefItemRaw; |
|||
|
|||
if (userDimName != null && dataDimNameMap.get(userDimName) == null) { |
|||
dataDimNameMap.set(userDimName, i); |
|||
} |
|||
} |
|||
|
|||
return dataDimNameMap; |
|||
} |
|||
export function ensureSourceDimNameMap(source) { |
|||
var innerSource = inner(source); |
|||
return innerSource.dimNameMap || (innerSource.dimNameMap = createDimNameMap(source.dimensionsDefine)); |
|||
} |
|||
export function shouldOmitUnusedDimensions(dimCount) { |
|||
return dimCount > 30; |
|||
} |
|||
@ -0,0 +1,364 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { VISUAL_DIMENSIONS } from '../../util/types.js'; |
|||
import SeriesDimensionDefine from '../SeriesDimensionDefine.js'; |
|||
import { createHashMap, defaults, each, extend, isObject, isString } from 'zrender/lib/core/util.js'; |
|||
import { createSourceFromSeriesDataOption, isSourceInstance } from '../Source.js'; |
|||
import { CtorInt32Array } from '../DataStore.js'; |
|||
import { normalizeToArray } from '../../util/model.js'; |
|||
import { BE_ORDINAL, guessOrdinal } from './sourceHelper.js'; |
|||
import { createDimNameMap, ensureSourceDimNameMap, SeriesDataSchema, shouldOmitUnusedDimensions } from './SeriesDataSchema.js'; |
|||
/** |
|||
* For outside usage compat (like echarts-gl are using it). |
|||
*/ |
|||
|
|||
export function createDimensions(source, opt) { |
|||
return prepareSeriesDataSchema(source, opt).dimensions; |
|||
} |
|||
/** |
|||
* This method builds the relationship between: |
|||
* + "what the coord sys or series requires (see `coordDimensions`)", |
|||
* + "what the user defines (in `encode` and `dimensions`, see `opt.dimensionsDefine` and `opt.encodeDefine`)" |
|||
* + "what the data source provids (see `source`)". |
|||
* |
|||
* Some guess strategy will be adapted if user does not define something. |
|||
* If no 'value' dimension specified, the first no-named dimension will be |
|||
* named as 'value'. |
|||
* |
|||
* @return The results are always sorted by `storeDimIndex` asc. |
|||
*/ |
|||
|
|||
export default function prepareSeriesDataSchema( // TODO: TYPE completeDimensions type
|
|||
source, opt) { |
|||
if (!isSourceInstance(source)) { |
|||
source = createSourceFromSeriesDataOption(source); |
|||
} |
|||
|
|||
opt = opt || {}; |
|||
var sysDims = opt.coordDimensions || []; |
|||
var dimsDef = opt.dimensionsDefine || source.dimensionsDefine || []; |
|||
var coordDimNameMap = createHashMap(); |
|||
var resultList = []; |
|||
var dimCount = getDimCount(source, sysDims, dimsDef, opt.dimensionsCount); // Try to ignore unsed dimensions if sharing a high dimension datastore
|
|||
// 30 is an experience value.
|
|||
|
|||
var omitUnusedDimensions = opt.canOmitUnusedDimensions && shouldOmitUnusedDimensions(dimCount); |
|||
var isUsingSourceDimensionsDef = dimsDef === source.dimensionsDefine; |
|||
var dataDimNameMap = isUsingSourceDimensionsDef ? ensureSourceDimNameMap(source) : createDimNameMap(dimsDef); |
|||
var encodeDef = opt.encodeDefine; |
|||
|
|||
if (!encodeDef && opt.encodeDefaulter) { |
|||
encodeDef = opt.encodeDefaulter(source, dimCount); |
|||
} |
|||
|
|||
var encodeDefMap = createHashMap(encodeDef); |
|||
var indicesMap = new CtorInt32Array(dimCount); |
|||
|
|||
for (var i = 0; i < indicesMap.length; i++) { |
|||
indicesMap[i] = -1; |
|||
} |
|||
|
|||
function getResultItem(dimIdx) { |
|||
var idx = indicesMap[dimIdx]; |
|||
|
|||
if (idx < 0) { |
|||
var dimDefItemRaw = dimsDef[dimIdx]; |
|||
var dimDefItem = isObject(dimDefItemRaw) ? dimDefItemRaw : { |
|||
name: dimDefItemRaw |
|||
}; |
|||
var resultItem = new SeriesDimensionDefine(); |
|||
var userDimName = dimDefItem.name; |
|||
|
|||
if (userDimName != null && dataDimNameMap.get(userDimName) != null) { |
|||
// Only if `series.dimensions` is defined in option
|
|||
// displayName, will be set, and dimension will be diplayed vertically in
|
|||
// tooltip by default.
|
|||
resultItem.name = resultItem.displayName = userDimName; |
|||
} |
|||
|
|||
dimDefItem.type != null && (resultItem.type = dimDefItem.type); |
|||
dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName); |
|||
var newIdx = resultList.length; |
|||
indicesMap[dimIdx] = newIdx; |
|||
resultItem.storeDimIndex = dimIdx; |
|||
resultList.push(resultItem); |
|||
return resultItem; |
|||
} |
|||
|
|||
return resultList[idx]; |
|||
} |
|||
|
|||
if (!omitUnusedDimensions) { |
|||
for (var i = 0; i < dimCount; i++) { |
|||
getResultItem(i); |
|||
} |
|||
} // Set `coordDim` and `coordDimIndex` by `encodeDefMap` and normalize `encodeDefMap`.
|
|||
|
|||
|
|||
encodeDefMap.each(function (dataDimsRaw, coordDim) { |
|||
var dataDims = normalizeToArray(dataDimsRaw).slice(); // Note: It is allowed that `dataDims.length` is `0`, e.g., options is
|
|||
// `{encode: {x: -1, y: 1}}`. Should not filter anything in
|
|||
// this case.
|
|||
|
|||
if (dataDims.length === 1 && !isString(dataDims[0]) && dataDims[0] < 0) { |
|||
encodeDefMap.set(coordDim, false); |
|||
return; |
|||
} |
|||
|
|||
var validDataDims = encodeDefMap.set(coordDim, []); |
|||
each(dataDims, function (resultDimIdxOrName, idx) { |
|||
// The input resultDimIdx can be dim name or index.
|
|||
var resultDimIdx = isString(resultDimIdxOrName) ? dataDimNameMap.get(resultDimIdxOrName) : resultDimIdxOrName; |
|||
|
|||
if (resultDimIdx != null && resultDimIdx < dimCount) { |
|||
validDataDims[idx] = resultDimIdx; |
|||
applyDim(getResultItem(resultDimIdx), coordDim, idx); |
|||
} |
|||
}); |
|||
}); // Apply templetes and default order from `sysDims`.
|
|||
|
|||
var availDimIdx = 0; |
|||
each(sysDims, function (sysDimItemRaw) { |
|||
var coordDim; |
|||
var sysDimItemDimsDef; |
|||
var sysDimItemOtherDims; |
|||
var sysDimItem; |
|||
|
|||
if (isString(sysDimItemRaw)) { |
|||
coordDim = sysDimItemRaw; |
|||
sysDimItem = {}; |
|||
} else { |
|||
sysDimItem = sysDimItemRaw; |
|||
coordDim = sysDimItem.name; |
|||
var ordinalMeta = sysDimItem.ordinalMeta; |
|||
sysDimItem.ordinalMeta = null; |
|||
sysDimItem = extend({}, sysDimItem); |
|||
sysDimItem.ordinalMeta = ordinalMeta; // `coordDimIndex` should not be set directly.
|
|||
|
|||
sysDimItemDimsDef = sysDimItem.dimsDef; |
|||
sysDimItemOtherDims = sysDimItem.otherDims; |
|||
sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex = sysDimItem.dimsDef = sysDimItem.otherDims = null; |
|||
} |
|||
|
|||
var dataDims = encodeDefMap.get(coordDim); // negative resultDimIdx means no need to mapping.
|
|||
|
|||
if (dataDims === false) { |
|||
return; |
|||
} |
|||
|
|||
dataDims = normalizeToArray(dataDims); // dimensions provides default dim sequences.
|
|||
|
|||
if (!dataDims.length) { |
|||
for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) { |
|||
while (availDimIdx < dimCount && getResultItem(availDimIdx).coordDim != null) { |
|||
availDimIdx++; |
|||
} |
|||
|
|||
availDimIdx < dimCount && dataDims.push(availDimIdx++); |
|||
} |
|||
} // Apply templates.
|
|||
|
|||
|
|||
each(dataDims, function (resultDimIdx, coordDimIndex) { |
|||
var resultItem = getResultItem(resultDimIdx); // Coordinate system has a higher priority on dim type than source.
|
|||
|
|||
if (isUsingSourceDimensionsDef && sysDimItem.type != null) { |
|||
resultItem.type = sysDimItem.type; |
|||
} |
|||
|
|||
applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex); |
|||
|
|||
if (resultItem.name == null && sysDimItemDimsDef) { |
|||
var sysDimItemDimsDefItem = sysDimItemDimsDef[coordDimIndex]; |
|||
!isObject(sysDimItemDimsDefItem) && (sysDimItemDimsDefItem = { |
|||
name: sysDimItemDimsDefItem |
|||
}); |
|||
resultItem.name = resultItem.displayName = sysDimItemDimsDefItem.name; |
|||
resultItem.defaultTooltip = sysDimItemDimsDefItem.defaultTooltip; |
|||
} // FIXME refactor, currently only used in case: {otherDims: {tooltip: false}}
|
|||
|
|||
|
|||
sysDimItemOtherDims && defaults(resultItem.otherDims, sysDimItemOtherDims); |
|||
}); |
|||
}); |
|||
|
|||
function applyDim(resultItem, coordDim, coordDimIndex) { |
|||
if (VISUAL_DIMENSIONS.get(coordDim) != null) { |
|||
resultItem.otherDims[coordDim] = coordDimIndex; |
|||
} else { |
|||
resultItem.coordDim = coordDim; |
|||
resultItem.coordDimIndex = coordDimIndex; |
|||
coordDimNameMap.set(coordDim, true); |
|||
} |
|||
} // Make sure the first extra dim is 'value'.
|
|||
|
|||
|
|||
var generateCoord = opt.generateCoord; |
|||
var generateCoordCount = opt.generateCoordCount; |
|||
var fromZero = generateCoordCount != null; |
|||
generateCoordCount = generateCoord ? generateCoordCount || 1 : 0; |
|||
var extra = generateCoord || 'value'; |
|||
|
|||
function ifNoNameFillWithCoordName(resultItem) { |
|||
if (resultItem.name == null) { |
|||
// Duplication will be removed in the next step.
|
|||
resultItem.name = resultItem.coordDim; |
|||
} |
|||
} // Set dim `name` and other `coordDim` and other props.
|
|||
|
|||
|
|||
if (!omitUnusedDimensions) { |
|||
for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) { |
|||
var resultItem = getResultItem(resultDimIdx); |
|||
var coordDim = resultItem.coordDim; |
|||
|
|||
if (coordDim == null) { |
|||
// TODO no need to generate coordDim for isExtraCoord?
|
|||
resultItem.coordDim = genCoordDimName(extra, coordDimNameMap, fromZero); |
|||
resultItem.coordDimIndex = 0; // Series specified generateCoord is using out.
|
|||
|
|||
if (!generateCoord || generateCoordCount <= 0) { |
|||
resultItem.isExtraCoord = true; |
|||
} |
|||
|
|||
generateCoordCount--; |
|||
} |
|||
|
|||
ifNoNameFillWithCoordName(resultItem); |
|||
|
|||
if (resultItem.type == null && (guessOrdinal(source, resultDimIdx) === BE_ORDINAL.Must // Consider the case:
|
|||
// {
|
|||
// dataset: {source: [
|
|||
// ['2001', 123],
|
|||
// ['2002', 456],
|
|||
// ...
|
|||
// ['The others', 987],
|
|||
// ]},
|
|||
// series: {type: 'pie'}
|
|||
// }
|
|||
// The first colum should better be treated as a "ordinal" although it
|
|||
// might not able to be detected as an "ordinal" by `guessOrdinal`.
|
|||
|| resultItem.isExtraCoord && (resultItem.otherDims.itemName != null || resultItem.otherDims.seriesName != null))) { |
|||
resultItem.type = 'ordinal'; |
|||
} |
|||
} |
|||
} else { |
|||
each(resultList, function (resultItem) { |
|||
// PENDING: guessOrdinal or let user specify type: 'ordinal' manually?
|
|||
ifNoNameFillWithCoordName(resultItem); |
|||
}); // Sort dimensions: there are some rule that use the last dim as label,
|
|||
// and for some latter travel process easier.
|
|||
|
|||
resultList.sort(function (item0, item1) { |
|||
return item0.storeDimIndex - item1.storeDimIndex; |
|||
}); |
|||
} |
|||
|
|||
removeDuplication(resultList); |
|||
return new SeriesDataSchema({ |
|||
source: source, |
|||
dimensions: resultList, |
|||
fullDimensionCount: dimCount, |
|||
dimensionOmitted: omitUnusedDimensions |
|||
}); |
|||
} |
|||
|
|||
function removeDuplication(result) { |
|||
var duplicationMap = createHashMap(); |
|||
|
|||
for (var i = 0; i < result.length; i++) { |
|||
var dim = result[i]; |
|||
var dimOriginalName = dim.name; |
|||
var count = duplicationMap.get(dimOriginalName) || 0; |
|||
|
|||
if (count > 0) { |
|||
// Starts from 0.
|
|||
dim.name = dimOriginalName + (count - 1); |
|||
} |
|||
|
|||
count++; |
|||
duplicationMap.set(dimOriginalName, count); |
|||
} |
|||
} // ??? TODO
|
|||
// Originally detect dimCount by data[0]. Should we
|
|||
// optimize it to only by sysDims and dimensions and encode.
|
|||
// So only necessary dims will be initialized.
|
|||
// But
|
|||
// (1) custom series should be considered. where other dims
|
|||
// may be visited.
|
|||
// (2) sometimes user need to calcualte bubble size or use visualMap
|
|||
// on other dimensions besides coordSys needed.
|
|||
// So, dims that is not used by system, should be shared in data store?
|
|||
|
|||
|
|||
function getDimCount(source, sysDims, dimsDef, optDimCount) { |
|||
// Note that the result dimCount should not small than columns count
|
|||
// of data, otherwise `dataDimNameMap` checking will be incorrect.
|
|||
var dimCount = Math.max(source.dimensionsDetectedCount || 1, sysDims.length, dimsDef.length, optDimCount || 0); |
|||
each(sysDims, function (sysDimItem) { |
|||
var sysDimItemDimsDef; |
|||
|
|||
if (isObject(sysDimItem) && (sysDimItemDimsDef = sysDimItem.dimsDef)) { |
|||
dimCount = Math.max(dimCount, sysDimItemDimsDef.length); |
|||
} |
|||
}); |
|||
return dimCount; |
|||
} |
|||
|
|||
function genCoordDimName(name, map, fromZero) { |
|||
var mapData = map.data; |
|||
|
|||
if (fromZero || mapData.hasOwnProperty(name)) { |
|||
var i = 0; |
|||
|
|||
while (mapData.hasOwnProperty(name + i)) { |
|||
i++; |
|||
} |
|||
|
|||
name += i; |
|||
} |
|||
|
|||
map.set(name, true); |
|||
return name; |
|||
} |
|||
@ -0,0 +1,407 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
var _a, _b, _c; // TODO
|
|||
// ??? refactor? check the outer usage of data provider.
|
|||
// merge with defaultDimValueGetter?
|
|||
|
|||
|
|||
import { isTypedArray, extend, assert, each, isObject, bind } from 'zrender/lib/core/util.js'; |
|||
import { getDataItemValue } from '../../util/model.js'; |
|||
import { createSourceFromSeriesDataOption, isSourceInstance } from '../Source.js'; |
|||
import { SOURCE_FORMAT_ORIGINAL, SOURCE_FORMAT_OBJECT_ROWS, SOURCE_FORMAT_KEYED_COLUMNS, SOURCE_FORMAT_TYPED_ARRAY, SOURCE_FORMAT_ARRAY_ROWS, SERIES_LAYOUT_BY_COLUMN, SERIES_LAYOUT_BY_ROW } from '../../util/types.js'; |
|||
var providerMethods; |
|||
var mountMethods; |
|||
/** |
|||
* If normal array used, mutable chunk size is supported. |
|||
* If typed array used, chunk size must be fixed. |
|||
*/ |
|||
|
|||
var DefaultDataProvider = |
|||
/** @class */ |
|||
function () { |
|||
function DefaultDataProvider(sourceParam, dimSize) { |
|||
// let source: Source;
|
|||
var source = !isSourceInstance(sourceParam) ? createSourceFromSeriesDataOption(sourceParam) : sourceParam; // declare source is Source;
|
|||
|
|||
this._source = source; |
|||
var data = this._data = source.data; // Typed array. TODO IE10+?
|
|||
|
|||
if (source.sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (dimSize == null) { |
|||
throw new Error('Typed array data must specify dimension size'); |
|||
} |
|||
} |
|||
|
|||
this._offset = 0; |
|||
this._dimSize = dimSize; |
|||
this._data = data; |
|||
} |
|||
|
|||
mountMethods(this, data, source); |
|||
} |
|||
|
|||
DefaultDataProvider.prototype.getSource = function () { |
|||
return this._source; |
|||
}; |
|||
|
|||
DefaultDataProvider.prototype.count = function () { |
|||
return 0; |
|||
}; |
|||
|
|||
DefaultDataProvider.prototype.getItem = function (idx, out) { |
|||
return; |
|||
}; |
|||
|
|||
DefaultDataProvider.prototype.appendData = function (newData) {}; |
|||
|
|||
DefaultDataProvider.prototype.clean = function () {}; |
|||
|
|||
DefaultDataProvider.protoInitialize = function () { |
|||
// PENDING: To avoid potential incompat (e.g., prototype
|
|||
// is visited somewhere), still init them on prototype.
|
|||
var proto = DefaultDataProvider.prototype; |
|||
proto.pure = false; |
|||
proto.persistent = true; |
|||
}(); |
|||
|
|||
DefaultDataProvider.internalField = function () { |
|||
var _a; |
|||
|
|||
mountMethods = function (provider, data, source) { |
|||
var sourceFormat = source.sourceFormat; |
|||
var seriesLayoutBy = source.seriesLayoutBy; |
|||
var startIndex = source.startIndex; |
|||
var dimsDef = source.dimensionsDefine; |
|||
var methods = providerMethods[getMethodMapKey(sourceFormat, seriesLayoutBy)]; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(methods, 'Invalide sourceFormat: ' + sourceFormat); |
|||
} |
|||
|
|||
extend(provider, methods); |
|||
|
|||
if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) { |
|||
provider.getItem = getItemForTypedArray; |
|||
provider.count = countForTypedArray; |
|||
provider.fillStorage = fillStorageForTypedArray; |
|||
} else { |
|||
var rawItemGetter = getRawSourceItemGetter(sourceFormat, seriesLayoutBy); |
|||
provider.getItem = bind(rawItemGetter, null, data, startIndex, dimsDef); |
|||
var rawCounter = getRawSourceDataCounter(sourceFormat, seriesLayoutBy); |
|||
provider.count = bind(rawCounter, null, data, startIndex, dimsDef); |
|||
} |
|||
}; |
|||
|
|||
var getItemForTypedArray = function (idx, out) { |
|||
idx = idx - this._offset; |
|||
out = out || []; |
|||
var data = this._data; |
|||
var dimSize = this._dimSize; |
|||
var offset = dimSize * idx; |
|||
|
|||
for (var i = 0; i < dimSize; i++) { |
|||
out[i] = data[offset + i]; |
|||
} |
|||
|
|||
return out; |
|||
}; |
|||
|
|||
var fillStorageForTypedArray = function (start, end, storage, extent) { |
|||
var data = this._data; |
|||
var dimSize = this._dimSize; |
|||
|
|||
for (var dim = 0; dim < dimSize; dim++) { |
|||
var dimExtent = extent[dim]; |
|||
var min = dimExtent[0] == null ? Infinity : dimExtent[0]; |
|||
var max = dimExtent[1] == null ? -Infinity : dimExtent[1]; |
|||
var count = end - start; |
|||
var arr = storage[dim]; |
|||
|
|||
for (var i = 0; i < count; i++) { |
|||
// appendData with TypedArray will always do replace in provider.
|
|||
var val = data[i * dimSize + dim]; |
|||
arr[start + i] = val; |
|||
val < min && (min = val); |
|||
val > max && (max = val); |
|||
} |
|||
|
|||
dimExtent[0] = min; |
|||
dimExtent[1] = max; |
|||
} |
|||
}; |
|||
|
|||
var countForTypedArray = function () { |
|||
return this._data ? this._data.length / this._dimSize : 0; |
|||
}; |
|||
|
|||
providerMethods = (_a = {}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = { |
|||
pure: true, |
|||
appendData: appendDataSimply |
|||
}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = { |
|||
pure: true, |
|||
appendData: function () { |
|||
throw new Error('Do not support appendData when set seriesLayoutBy: "row".'); |
|||
} |
|||
}, _a[SOURCE_FORMAT_OBJECT_ROWS] = { |
|||
pure: true, |
|||
appendData: appendDataSimply |
|||
}, _a[SOURCE_FORMAT_KEYED_COLUMNS] = { |
|||
pure: true, |
|||
appendData: function (newData) { |
|||
var data = this._data; |
|||
each(newData, function (newCol, key) { |
|||
var oldCol = data[key] || (data[key] = []); |
|||
|
|||
for (var i = 0; i < (newCol || []).length; i++) { |
|||
oldCol.push(newCol[i]); |
|||
} |
|||
}); |
|||
} |
|||
}, _a[SOURCE_FORMAT_ORIGINAL] = { |
|||
appendData: appendDataSimply |
|||
}, _a[SOURCE_FORMAT_TYPED_ARRAY] = { |
|||
persistent: false, |
|||
pure: true, |
|||
appendData: function (newData) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(isTypedArray(newData), 'Added data must be TypedArray if data in initialization is TypedArray'); |
|||
} |
|||
|
|||
this._data = newData; |
|||
}, |
|||
// Clean self if data is already used.
|
|||
clean: function () { |
|||
// PENDING
|
|||
this._offset += this.count(); |
|||
this._data = null; |
|||
} |
|||
}, _a); |
|||
|
|||
function appendDataSimply(newData) { |
|||
for (var i = 0; i < newData.length; i++) { |
|||
this._data.push(newData[i]); |
|||
} |
|||
} |
|||
}(); |
|||
|
|||
return DefaultDataProvider; |
|||
}(); |
|||
|
|||
export { DefaultDataProvider }; |
|||
|
|||
var getItemSimply = function (rawData, startIndex, dimsDef, idx) { |
|||
return rawData[idx]; |
|||
}; |
|||
|
|||
var rawSourceItemGetterMap = (_a = {}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef, idx) { |
|||
return rawData[idx + startIndex]; |
|||
}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef, idx, out) { |
|||
idx += startIndex; |
|||
var item = out || []; |
|||
var data = rawData; |
|||
|
|||
for (var i = 0; i < data.length; i++) { |
|||
var row = data[i]; |
|||
item[i] = row ? row[idx] : null; |
|||
} |
|||
|
|||
return item; |
|||
}, _a[SOURCE_FORMAT_OBJECT_ROWS] = getItemSimply, _a[SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef, idx, out) { |
|||
var item = out || []; |
|||
|
|||
for (var i = 0; i < dimsDef.length; i++) { |
|||
var dimName = dimsDef[i].name; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (dimName == null) { |
|||
throw new Error(); |
|||
} |
|||
} |
|||
|
|||
var col = rawData[dimName]; |
|||
item[i] = col ? col[idx] : null; |
|||
} |
|||
|
|||
return item; |
|||
}, _a[SOURCE_FORMAT_ORIGINAL] = getItemSimply, _a); |
|||
export function getRawSourceItemGetter(sourceFormat, seriesLayoutBy) { |
|||
var method = rawSourceItemGetterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)]; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(method, 'Do not support get item on "' + sourceFormat + '", "' + seriesLayoutBy + '".'); |
|||
} |
|||
|
|||
return method; |
|||
} |
|||
|
|||
var countSimply = function (rawData, startIndex, dimsDef) { |
|||
return rawData.length; |
|||
}; |
|||
|
|||
var rawSourceDataCounterMap = (_b = {}, _b[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef) { |
|||
return Math.max(0, rawData.length - startIndex); |
|||
}, _b[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef) { |
|||
var row = rawData[0]; |
|||
return row ? Math.max(0, row.length - startIndex) : 0; |
|||
}, _b[SOURCE_FORMAT_OBJECT_ROWS] = countSimply, _b[SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef) { |
|||
var dimName = dimsDef[0].name; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (dimName == null) { |
|||
throw new Error(); |
|||
} |
|||
} |
|||
|
|||
var col = rawData[dimName]; |
|||
return col ? col.length : 0; |
|||
}, _b[SOURCE_FORMAT_ORIGINAL] = countSimply, _b); |
|||
export function getRawSourceDataCounter(sourceFormat, seriesLayoutBy) { |
|||
var method = rawSourceDataCounterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)]; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(method, 'Do not suppport count on "' + sourceFormat + '", "' + seriesLayoutBy + '".'); |
|||
} |
|||
|
|||
return method; |
|||
} |
|||
|
|||
var getRawValueSimply = function (dataItem, dimIndex, property) { |
|||
return dataItem[dimIndex]; |
|||
}; |
|||
|
|||
var rawSourceValueGetterMap = (_c = {}, _c[SOURCE_FORMAT_ARRAY_ROWS] = getRawValueSimply, _c[SOURCE_FORMAT_OBJECT_ROWS] = function (dataItem, dimIndex, property) { |
|||
return dataItem[property]; |
|||
}, _c[SOURCE_FORMAT_KEYED_COLUMNS] = getRawValueSimply, _c[SOURCE_FORMAT_ORIGINAL] = function (dataItem, dimIndex, property) { |
|||
// FIXME: In some case (markpoint in geo (geo-map.html)),
|
|||
// dataItem is {coord: [...]}
|
|||
var value = getDataItemValue(dataItem); |
|||
return !(value instanceof Array) ? value : value[dimIndex]; |
|||
}, _c[SOURCE_FORMAT_TYPED_ARRAY] = getRawValueSimply, _c); |
|||
export function getRawSourceValueGetter(sourceFormat) { |
|||
var method = rawSourceValueGetterMap[sourceFormat]; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(method, 'Do not suppport get value on "' + sourceFormat + '".'); |
|||
} |
|||
|
|||
return method; |
|||
} |
|||
|
|||
function getMethodMapKey(sourceFormat, seriesLayoutBy) { |
|||
return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS ? sourceFormat + '_' + seriesLayoutBy : sourceFormat; |
|||
} // ??? FIXME can these logic be more neat: getRawValue, getRawDataItem,
|
|||
// Consider persistent.
|
|||
// Caution: why use raw value to display on label or tooltip?
|
|||
// A reason is to avoid format. For example time value we do not know
|
|||
// how to format is expected. More over, if stack is used, calculated
|
|||
// value may be 0.91000000001, which have brings trouble to display.
|
|||
// TODO: consider how to treat null/undefined/NaN when display?
|
|||
|
|||
|
|||
export function retrieveRawValue(data, dataIndex, // If dimIndex is null/undefined, return OptionDataItem.
|
|||
// Otherwise, return OptionDataValue.
|
|||
dim) { |
|||
if (!data) { |
|||
return; |
|||
} // Consider data may be not persistent.
|
|||
|
|||
|
|||
var dataItem = data.getRawDataItem(dataIndex); |
|||
|
|||
if (dataItem == null) { |
|||
return; |
|||
} |
|||
|
|||
var store = data.getStore(); |
|||
var sourceFormat = store.getSource().sourceFormat; |
|||
|
|||
if (dim != null) { |
|||
var dimIndex = data.getDimensionIndex(dim); |
|||
var property = store.getDimensionProperty(dimIndex); |
|||
return getRawSourceValueGetter(sourceFormat)(dataItem, dimIndex, property); |
|||
} else { |
|||
var result = dataItem; |
|||
|
|||
if (sourceFormat === SOURCE_FORMAT_ORIGINAL) { |
|||
result = getDataItemValue(dataItem); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
/** |
|||
* Compatible with some cases (in pie, map) like: |
|||
* data: [{name: 'xx', value: 5, selected: true}, ...] |
|||
* where only sourceFormat is 'original' and 'objectRows' supported. |
|||
* |
|||
* // TODO
|
|||
* Supported detail options in data item when using 'arrayRows'. |
|||
* |
|||
* @param data |
|||
* @param dataIndex |
|||
* @param attr like 'selected' |
|||
*/ |
|||
|
|||
export function retrieveRawAttr(data, dataIndex, attr) { |
|||
if (!data) { |
|||
return; |
|||
} |
|||
|
|||
var sourceFormat = data.getStore().getSource().sourceFormat; |
|||
|
|||
if (sourceFormat !== SOURCE_FORMAT_ORIGINAL && sourceFormat !== SOURCE_FORMAT_OBJECT_ROWS) { |
|||
return; |
|||
} |
|||
|
|||
var dataItem = data.getRawDataItem(dataIndex); |
|||
|
|||
if (sourceFormat === SOURCE_FORMAT_ORIGINAL && !isObject(dataItem)) { |
|||
dataItem = null; |
|||
} |
|||
|
|||
if (dataItem) { |
|||
return dataItem[attr]; |
|||
} |
|||
} |
|||
@ -0,0 +1,192 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { each, isString } from 'zrender/lib/core/util.js'; |
|||
import { isSeriesDataSchema } from './SeriesDataSchema.js'; |
|||
/** |
|||
* Note that it is too complicated to support 3d stack by value |
|||
* (have to create two-dimension inverted index), so in 3d case |
|||
* we just support that stacked by index. |
|||
* |
|||
* @param seriesModel |
|||
* @param dimensionsInput The same as the input of <module:echarts/data/SeriesData>. |
|||
* The input will be modified. |
|||
* @param opt |
|||
* @param opt.stackedCoordDimension Specify a coord dimension if needed. |
|||
* @param opt.byIndex=false |
|||
* @return calculationInfo |
|||
* { |
|||
* stackedDimension: string |
|||
* stackedByDimension: string |
|||
* isStackedByIndex: boolean |
|||
* stackedOverDimension: string |
|||
* stackResultDimension: string |
|||
* } |
|||
*/ |
|||
|
|||
export function enableDataStack(seriesModel, dimensionsInput, opt) { |
|||
opt = opt || {}; |
|||
var byIndex = opt.byIndex; |
|||
var stackedCoordDimension = opt.stackedCoordDimension; |
|||
var dimensionDefineList; |
|||
var schema; |
|||
var store; |
|||
|
|||
if (isLegacyDimensionsInput(dimensionsInput)) { |
|||
dimensionDefineList = dimensionsInput; |
|||
} else { |
|||
schema = dimensionsInput.schema; |
|||
dimensionDefineList = schema.dimensions; |
|||
store = dimensionsInput.store; |
|||
} // Compatibal: when `stack` is set as '', do not stack.
|
|||
|
|||
|
|||
var mayStack = !!(seriesModel && seriesModel.get('stack')); |
|||
var stackedByDimInfo; |
|||
var stackedDimInfo; |
|||
var stackResultDimension; |
|||
var stackedOverDimension; |
|||
each(dimensionDefineList, function (dimensionInfo, index) { |
|||
if (isString(dimensionInfo)) { |
|||
dimensionDefineList[index] = dimensionInfo = { |
|||
name: dimensionInfo |
|||
}; |
|||
} |
|||
|
|||
if (mayStack && !dimensionInfo.isExtraCoord) { |
|||
// Find the first ordinal dimension as the stackedByDimInfo.
|
|||
if (!byIndex && !stackedByDimInfo && dimensionInfo.ordinalMeta) { |
|||
stackedByDimInfo = dimensionInfo; |
|||
} // Find the first stackable dimension as the stackedDimInfo.
|
|||
|
|||
|
|||
if (!stackedDimInfo && dimensionInfo.type !== 'ordinal' && dimensionInfo.type !== 'time' && (!stackedCoordDimension || stackedCoordDimension === dimensionInfo.coordDim)) { |
|||
stackedDimInfo = dimensionInfo; |
|||
} |
|||
} |
|||
}); |
|||
|
|||
if (stackedDimInfo && !byIndex && !stackedByDimInfo) { |
|||
// Compatible with previous design, value axis (time axis) only stack by index.
|
|||
// It may make sense if the user provides elaborately constructed data.
|
|||
byIndex = true; |
|||
} // Add stack dimension, they can be both calculated by coordinate system in `unionExtent`.
|
|||
// That put stack logic in List is for using conveniently in echarts extensions, but it
|
|||
// might not be a good way.
|
|||
|
|||
|
|||
if (stackedDimInfo) { |
|||
// Use a weird name that not duplicated with other names.
|
|||
// Also need to use seriesModel.id as postfix because different
|
|||
// series may share same data store. The stack dimension needs to be distinguished.
|
|||
stackResultDimension = '__\0ecstackresult_' + seriesModel.id; |
|||
stackedOverDimension = '__\0ecstackedover_' + seriesModel.id; // Create inverted index to fast query index by value.
|
|||
|
|||
if (stackedByDimInfo) { |
|||
stackedByDimInfo.createInvertedIndices = true; |
|||
} |
|||
|
|||
var stackedDimCoordDim_1 = stackedDimInfo.coordDim; |
|||
var stackedDimType = stackedDimInfo.type; |
|||
var stackedDimCoordIndex_1 = 0; |
|||
each(dimensionDefineList, function (dimensionInfo) { |
|||
if (dimensionInfo.coordDim === stackedDimCoordDim_1) { |
|||
stackedDimCoordIndex_1++; |
|||
} |
|||
}); |
|||
var stackedOverDimensionDefine = { |
|||
name: stackResultDimension, |
|||
coordDim: stackedDimCoordDim_1, |
|||
coordDimIndex: stackedDimCoordIndex_1, |
|||
type: stackedDimType, |
|||
isExtraCoord: true, |
|||
isCalculationCoord: true, |
|||
storeDimIndex: dimensionDefineList.length |
|||
}; |
|||
var stackResultDimensionDefine = { |
|||
name: stackedOverDimension, |
|||
// This dimension contains stack base (generally, 0), so do not set it as
|
|||
// `stackedDimCoordDim` to avoid extent calculation, consider log scale.
|
|||
coordDim: stackedOverDimension, |
|||
coordDimIndex: stackedDimCoordIndex_1 + 1, |
|||
type: stackedDimType, |
|||
isExtraCoord: true, |
|||
isCalculationCoord: true, |
|||
storeDimIndex: dimensionDefineList.length + 1 |
|||
}; |
|||
|
|||
if (schema) { |
|||
if (store) { |
|||
stackedOverDimensionDefine.storeDimIndex = store.ensureCalculationDimension(stackedOverDimension, stackedDimType); |
|||
stackResultDimensionDefine.storeDimIndex = store.ensureCalculationDimension(stackResultDimension, stackedDimType); |
|||
} |
|||
|
|||
schema.appendCalculationDimension(stackedOverDimensionDefine); |
|||
schema.appendCalculationDimension(stackResultDimensionDefine); |
|||
} else { |
|||
dimensionDefineList.push(stackedOverDimensionDefine); |
|||
dimensionDefineList.push(stackResultDimensionDefine); |
|||
} |
|||
} |
|||
|
|||
return { |
|||
stackedDimension: stackedDimInfo && stackedDimInfo.name, |
|||
stackedByDimension: stackedByDimInfo && stackedByDimInfo.name, |
|||
isStackedByIndex: byIndex, |
|||
stackedOverDimension: stackedOverDimension, |
|||
stackResultDimension: stackResultDimension |
|||
}; |
|||
} |
|||
|
|||
function isLegacyDimensionsInput(dimensionsInput) { |
|||
return !isSeriesDataSchema(dimensionsInput.schema); |
|||
} |
|||
|
|||
export function isDimensionStacked(data, stackedDim) { |
|||
// Each single series only maps to one pair of axis. So we do not need to
|
|||
// check stackByDim, whatever stacked by a dimension or stacked by index.
|
|||
return !!stackedDim && stackedDim === data.getCalculationInfo('stackedDimension'); |
|||
} |
|||
export function getStackedDimension(data, targetDim) { |
|||
return isDimensionStacked(data, targetDim) ? data.getCalculationInfo('stackResultDimension') : targetDim; |
|||
} |
|||
@ -0,0 +1,271 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { parseDate, numericToNumber } from '../../util/number.js'; |
|||
import { createHashMap, trim, hasOwn, isString, isNumber } from 'zrender/lib/core/util.js'; |
|||
import { throwError } from '../../util/log.js'; |
|||
/** |
|||
* Convert raw the value in to inner value in List. |
|||
* |
|||
* [Performance sensitive] |
|||
* |
|||
* [Caution]: this is the key logic of user value parser. |
|||
* For backward compatibiliy, do not modify it until have to! |
|||
*/ |
|||
|
|||
export function parseDataValue(value, // For high performance, do not omit the second param.
|
|||
opt) { |
|||
// Performance sensitive.
|
|||
var dimType = opt && opt.type; |
|||
|
|||
if (dimType === 'ordinal') { |
|||
// If given value is a category string
|
|||
return value; |
|||
} |
|||
|
|||
if (dimType === 'time' // spead up when using timestamp
|
|||
&& !isNumber(value) && value != null && value !== '-') { |
|||
value = +parseDate(value); |
|||
} // dimType defaults 'number'.
|
|||
// If dimType is not ordinal and value is null or undefined or NaN or '-',
|
|||
// parse to NaN.
|
|||
// number-like string (like ' 123 ') can be converted to a number.
|
|||
// where null/undefined or other string will be converted to NaN.
|
|||
|
|||
|
|||
return value == null || value === '' ? NaN // If string (like '-'), using '+' parse to NaN
|
|||
// If object, also parse to NaN
|
|||
: +value; |
|||
} |
|||
; |
|||
var valueParserMap = createHashMap({ |
|||
'number': function (val) { |
|||
// Do not use `numericToNumber` here. We have by defualt `numericToNumber`.
|
|||
// Here the number parser can have loose rule:
|
|||
// enable to cut suffix: "120px" => 120, "14%" => 14.
|
|||
return parseFloat(val); |
|||
}, |
|||
'time': function (val) { |
|||
// return timestamp.
|
|||
return +parseDate(val); |
|||
}, |
|||
'trim': function (val) { |
|||
return isString(val) ? trim(val) : val; |
|||
} |
|||
}); |
|||
export function getRawValueParser(type) { |
|||
return valueParserMap.get(type); |
|||
} |
|||
var ORDER_COMPARISON_OP_MAP = { |
|||
lt: function (lval, rval) { |
|||
return lval < rval; |
|||
}, |
|||
lte: function (lval, rval) { |
|||
return lval <= rval; |
|||
}, |
|||
gt: function (lval, rval) { |
|||
return lval > rval; |
|||
}, |
|||
gte: function (lval, rval) { |
|||
return lval >= rval; |
|||
} |
|||
}; |
|||
|
|||
var FilterOrderComparator = |
|||
/** @class */ |
|||
function () { |
|||
function FilterOrderComparator(op, rval) { |
|||
if (!isNumber(rval)) { |
|||
var errMsg = ''; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'rvalue of "<", ">", "<=", ">=" can only be number in filter.'; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} |
|||
|
|||
this._opFn = ORDER_COMPARISON_OP_MAP[op]; |
|||
this._rvalFloat = numericToNumber(rval); |
|||
} // Performance sensitive.
|
|||
|
|||
|
|||
FilterOrderComparator.prototype.evaluate = function (lval) { |
|||
// Most cases is 'number', and typeof maybe 10 times faseter than parseFloat.
|
|||
return isNumber(lval) ? this._opFn(lval, this._rvalFloat) : this._opFn(numericToNumber(lval), this._rvalFloat); |
|||
}; |
|||
|
|||
return FilterOrderComparator; |
|||
}(); |
|||
|
|||
var SortOrderComparator = |
|||
/** @class */ |
|||
function () { |
|||
/** |
|||
* @param order by defualt: 'asc' |
|||
* @param incomparable by defualt: Always on the tail. |
|||
* That is, if 'asc' => 'max', if 'desc' => 'min' |
|||
* See the definition of "incomparable" in [SORT_COMPARISON_RULE] |
|||
*/ |
|||
function SortOrderComparator(order, incomparable) { |
|||
var isDesc = order === 'desc'; |
|||
this._resultLT = isDesc ? 1 : -1; |
|||
|
|||
if (incomparable == null) { |
|||
incomparable = isDesc ? 'min' : 'max'; |
|||
} |
|||
|
|||
this._incomparable = incomparable === 'min' ? -Infinity : Infinity; |
|||
} // See [SORT_COMPARISON_RULE].
|
|||
// Performance sensitive.
|
|||
|
|||
|
|||
SortOrderComparator.prototype.evaluate = function (lval, rval) { |
|||
// Most cases is 'number', and typeof maybe 10 times faseter than parseFloat.
|
|||
var lvalFloat = isNumber(lval) ? lval : numericToNumber(lval); |
|||
var rvalFloat = isNumber(rval) ? rval : numericToNumber(rval); |
|||
var lvalNotNumeric = isNaN(lvalFloat); |
|||
var rvalNotNumeric = isNaN(rvalFloat); |
|||
|
|||
if (lvalNotNumeric) { |
|||
lvalFloat = this._incomparable; |
|||
} |
|||
|
|||
if (rvalNotNumeric) { |
|||
rvalFloat = this._incomparable; |
|||
} |
|||
|
|||
if (lvalNotNumeric && rvalNotNumeric) { |
|||
var lvalIsStr = isString(lval); |
|||
var rvalIsStr = isString(rval); |
|||
|
|||
if (lvalIsStr) { |
|||
lvalFloat = rvalIsStr ? lval : 0; |
|||
} |
|||
|
|||
if (rvalIsStr) { |
|||
rvalFloat = lvalIsStr ? rval : 0; |
|||
} |
|||
} |
|||
|
|||
return lvalFloat < rvalFloat ? this._resultLT : lvalFloat > rvalFloat ? -this._resultLT : 0; |
|||
}; |
|||
|
|||
return SortOrderComparator; |
|||
}(); |
|||
|
|||
export { SortOrderComparator }; |
|||
|
|||
var FilterEqualityComparator = |
|||
/** @class */ |
|||
function () { |
|||
function FilterEqualityComparator(isEq, rval) { |
|||
this._rval = rval; |
|||
this._isEQ = isEq; |
|||
this._rvalTypeof = typeof rval; |
|||
this._rvalFloat = numericToNumber(rval); |
|||
} // Performance sensitive.
|
|||
|
|||
|
|||
FilterEqualityComparator.prototype.evaluate = function (lval) { |
|||
var eqResult = lval === this._rval; |
|||
|
|||
if (!eqResult) { |
|||
var lvalTypeof = typeof lval; |
|||
|
|||
if (lvalTypeof !== this._rvalTypeof && (lvalTypeof === 'number' || this._rvalTypeof === 'number')) { |
|||
eqResult = numericToNumber(lval) === this._rvalFloat; |
|||
} |
|||
} |
|||
|
|||
return this._isEQ ? eqResult : !eqResult; |
|||
}; |
|||
|
|||
return FilterEqualityComparator; |
|||
}(); |
|||
/** |
|||
* [FILTER_COMPARISON_RULE] |
|||
* `lt`|`lte`|`gt`|`gte`: |
|||
* + rval must be a number. And lval will be converted to number (`numericToNumber`) to compare. |
|||
* `eq`: |
|||
* + If same type, compare with `===`. |
|||
* + If there is one number, convert to number (`numericToNumber`) to compare. |
|||
* + Else return `false`. |
|||
* `ne`: |
|||
* + Not `eq`. |
|||
* |
|||
* |
|||
* [SORT_COMPARISON_RULE] |
|||
* All the values are grouped into three categories: |
|||
* + "numeric" (number and numeric string) |
|||
* + "non-numeric-string" (string that excluding numeric string) |
|||
* + "others" |
|||
* "numeric" vs "numeric": values are ordered by number order. |
|||
* "non-numeric-string" vs "non-numeric-string": values are ordered by ES spec (#sec-abstract-relational-comparison). |
|||
* "others" vs "others": do not change order (always return 0). |
|||
* "numeric" vs "non-numeric-string": "non-numeric-string" is treated as "incomparable". |
|||
* "number" vs "others": "others" is treated as "incomparable". |
|||
* "non-numeric-string" vs "others": "others" is treated as "incomparable". |
|||
* "incomparable" will be seen as -Infinity or Infinity (depends on the settings). |
|||
* MEMO: |
|||
* non-numeric string sort make sence when need to put the items with the same tag together. |
|||
* But if we support string sort, we still need to avoid the misleading like `'2' > '12'`, |
|||
* So we treat "numeric-string" sorted by number order rather than string comparison. |
|||
* |
|||
* |
|||
* [CHECK_LIST_OF_THE_RULE_DESIGN] |
|||
* + Do not support string comparison until required. And also need to |
|||
* void the misleading of "2" > "12". |
|||
* + Should avoid the misleading case: |
|||
* `" 22 " gte "22"` is `true` but `" 22 " eq "22"` is `false`. |
|||
* + JS bad case should be avoided: null <= 0, [] <= 0, ' ' <= 0, ... |
|||
* + Only "numeric" can be converted to comparable number, otherwise converted to NaN. |
|||
* See `util/number.ts#numericToNumber`. |
|||
* |
|||
* @return If `op` is not `RelationalOperator`, return null; |
|||
*/ |
|||
|
|||
|
|||
export function createFilterComparator(op, rval) { |
|||
return op === 'eq' || op === 'ne' ? new FilterEqualityComparator(op === 'eq', rval) : hasOwn(ORDER_COMPARISON_OP_MAP, op) ? new FilterOrderComparator(op, rval) : null; |
|||
} |
|||
@ -0,0 +1,194 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { each, createHashMap, assert, map } from 'zrender/lib/core/util.js'; |
|||
import { VISUAL_DIMENSIONS } from '../../util/types.js'; |
|||
|
|||
var DimensionUserOuput = |
|||
/** @class */ |
|||
function () { |
|||
function DimensionUserOuput(encode, dimRequest) { |
|||
this._encode = encode; |
|||
this._schema = dimRequest; |
|||
} |
|||
|
|||
DimensionUserOuput.prototype.get = function () { |
|||
return { |
|||
// Do not generate full dimension name until fist used.
|
|||
fullDimensions: this._getFullDimensionNames(), |
|||
encode: this._encode |
|||
}; |
|||
}; |
|||
/** |
|||
* Get all data store dimension names. |
|||
* Theoretically a series data store is defined both by series and used dataset (if any). |
|||
* If some dimensions are omitted for performance reason in `this.dimensions`, |
|||
* the dimension name may not be auto-generated if user does not specify a dimension name. |
|||
* In this case, the dimension name is `null`/`undefined`. |
|||
*/ |
|||
|
|||
|
|||
DimensionUserOuput.prototype._getFullDimensionNames = function () { |
|||
if (!this._cachedDimNames) { |
|||
this._cachedDimNames = this._schema ? this._schema.makeOutputDimensionNames() : []; |
|||
} |
|||
|
|||
return this._cachedDimNames; |
|||
}; |
|||
|
|||
return DimensionUserOuput; |
|||
}(); |
|||
|
|||
; |
|||
export function summarizeDimensions(data, schema) { |
|||
var summary = {}; |
|||
var encode = summary.encode = {}; |
|||
var notExtraCoordDimMap = createHashMap(); |
|||
var defaultedLabel = []; |
|||
var defaultedTooltip = []; |
|||
var userOutputEncode = {}; |
|||
each(data.dimensions, function (dimName) { |
|||
var dimItem = data.getDimensionInfo(dimName); |
|||
var coordDim = dimItem.coordDim; |
|||
|
|||
if (coordDim) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(VISUAL_DIMENSIONS.get(coordDim) == null); |
|||
} |
|||
|
|||
var coordDimIndex = dimItem.coordDimIndex; |
|||
getOrCreateEncodeArr(encode, coordDim)[coordDimIndex] = dimName; |
|||
|
|||
if (!dimItem.isExtraCoord) { |
|||
notExtraCoordDimMap.set(coordDim, 1); // Use the last coord dim (and label friendly) as default label,
|
|||
// because when dataset is used, it is hard to guess which dimension
|
|||
// can be value dimension. If both show x, y on label is not look good,
|
|||
// and conventionally y axis is focused more.
|
|||
|
|||
if (mayLabelDimType(dimItem.type)) { |
|||
defaultedLabel[0] = dimName; |
|||
} // User output encode do not contain generated coords.
|
|||
// And it only has index. User can use index to retrieve value from the raw item array.
|
|||
|
|||
|
|||
getOrCreateEncodeArr(userOutputEncode, coordDim)[coordDimIndex] = data.getDimensionIndex(dimItem.name); |
|||
} |
|||
|
|||
if (dimItem.defaultTooltip) { |
|||
defaultedTooltip.push(dimName); |
|||
} |
|||
} |
|||
|
|||
VISUAL_DIMENSIONS.each(function (v, otherDim) { |
|||
var encodeArr = getOrCreateEncodeArr(encode, otherDim); |
|||
var dimIndex = dimItem.otherDims[otherDim]; |
|||
|
|||
if (dimIndex != null && dimIndex !== false) { |
|||
encodeArr[dimIndex] = dimItem.name; |
|||
} |
|||
}); |
|||
}); |
|||
var dataDimsOnCoord = []; |
|||
var encodeFirstDimNotExtra = {}; |
|||
notExtraCoordDimMap.each(function (v, coordDim) { |
|||
var dimArr = encode[coordDim]; |
|||
encodeFirstDimNotExtra[coordDim] = dimArr[0]; // Not necessary to remove duplicate, because a data
|
|||
// dim canot on more than one coordDim.
|
|||
|
|||
dataDimsOnCoord = dataDimsOnCoord.concat(dimArr); |
|||
}); |
|||
summary.dataDimsOnCoord = dataDimsOnCoord; |
|||
summary.dataDimIndicesOnCoord = map(dataDimsOnCoord, function (dimName) { |
|||
return data.getDimensionInfo(dimName).storeDimIndex; |
|||
}); |
|||
summary.encodeFirstDimNotExtra = encodeFirstDimNotExtra; |
|||
var encodeLabel = encode.label; // FIXME `encode.label` is not recommanded, because formatter can not be set
|
|||
// in this way. Use label.formatter instead. May be remove this approach someday.
|
|||
|
|||
if (encodeLabel && encodeLabel.length) { |
|||
defaultedLabel = encodeLabel.slice(); |
|||
} |
|||
|
|||
var encodeTooltip = encode.tooltip; |
|||
|
|||
if (encodeTooltip && encodeTooltip.length) { |
|||
defaultedTooltip = encodeTooltip.slice(); |
|||
} else if (!defaultedTooltip.length) { |
|||
defaultedTooltip = defaultedLabel.slice(); |
|||
} |
|||
|
|||
encode.defaultedLabel = defaultedLabel; |
|||
encode.defaultedTooltip = defaultedTooltip; |
|||
summary.userOutput = new DimensionUserOuput(userOutputEncode, schema); |
|||
return summary; |
|||
} |
|||
|
|||
function getOrCreateEncodeArr(encode, dim) { |
|||
if (!encode.hasOwnProperty(dim)) { |
|||
encode[dim] = []; |
|||
} |
|||
|
|||
return encode[dim]; |
|||
} // FIXME:TS should be type `AxisType`
|
|||
|
|||
|
|||
export function getDimensionTypeByAxis(axisType) { |
|||
return axisType === 'category' ? 'ordinal' : axisType === 'time' ? 'time' : 'float'; |
|||
} |
|||
|
|||
function mayLabelDimType(dimType) { |
|||
// In most cases, ordinal and time do not suitable for label.
|
|||
// Ordinal info can be displayed on axis. Time is too long.
|
|||
return !(dimType === 'ordinal' || dimType === 'time'); |
|||
} // function findTheLastDimMayLabel(data) {
|
|||
// // Get last value dim
|
|||
// let dimensions = data.dimensions.slice();
|
|||
// let valueType;
|
|||
// let valueDim;
|
|||
// while (dimensions.length && (
|
|||
// valueDim = dimensions.pop(),
|
|||
// valueType = data.getDimensionInfo(valueDim).type,
|
|||
// valueType === 'ordinal' || valueType === 'time'
|
|||
// )) {} // jshint ignore:line
|
|||
// return valueDim;
|
|||
// }
|
|||
@ -0,0 +1,46 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
// TODO: this module is only for compatibility with echarts-gl
|
|||
import linkSeriesData from './linkSeriesData.js'; |
|||
export default linkSeriesData; |
|||
@ -0,0 +1,168 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Link lists and struct (graph or tree) |
|||
*/ |
|||
import { curry, each, assert, extend, map, keys } from 'zrender/lib/core/util.js'; |
|||
import { makeInner } from '../../util/model.js'; |
|||
var inner = makeInner(); |
|||
|
|||
function linkSeriesData(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, curry(transferInjection, opt)); |
|||
}); |
|||
}); // Beyond transfer, additional features should be added to `cloneShallow`.
|
|||
|
|||
mainData.wrapMethod('cloneShallow', 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, curry(changeInjection, opt)); |
|||
}); // Make sure datas contains mainData.
|
|||
|
|||
assert(datas[mainData.dataType] === mainData); |
|||
} |
|||
|
|||
function transferInjection(opt, res) { |
|||
if (isMainData(this)) { |
|||
// Transfer datas to new main data.
|
|||
var datas = extend({}, inner(this).datas); |
|||
datas[this.dataType] = res; |
|||
linkAll(res, datas, opt); |
|||
} else { |
|||
// Modify the reference in main data to point newData.
|
|||
linkSingle(res, this.dataType, inner(this).mainData, opt); |
|||
} |
|||
|
|||
return res; |
|||
} |
|||
|
|||
function changeInjection(opt, res) { |
|||
opt.struct && opt.struct.update(); |
|||
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(inner(res).datas, function (data, dataType) { |
|||
data !== res && linkSingle(data.cloneShallow(), dataType, res, opt); |
|||
}); |
|||
return res; |
|||
} |
|||
/** |
|||
* Supplement method to List. |
|||
* |
|||
* @public |
|||
* @param [dataType] If not specified, return mainData. |
|||
*/ |
|||
|
|||
|
|||
function getLinkedData(dataType) { |
|||
var mainData = inner(this).mainData; |
|||
return dataType == null || mainData == null ? mainData : inner(mainData).datas[dataType]; |
|||
} |
|||
/** |
|||
* Get list of all linked data |
|||
*/ |
|||
|
|||
|
|||
function getLinkedDataAll() { |
|||
var mainData = inner(this).mainData; |
|||
return mainData == null ? [{ |
|||
data: mainData |
|||
}] : map(keys(inner(mainData).datas), function (type) { |
|||
return { |
|||
type: type, |
|||
data: inner(mainData).datas[type] |
|||
}; |
|||
}); |
|||
} |
|||
|
|||
function isMainData(data) { |
|||
return inner(data).mainData === data; |
|||
} |
|||
|
|||
function linkAll(mainData, datas, opt) { |
|||
inner(mainData).datas = {}; |
|||
each(datas, function (data, dataType) { |
|||
linkSingle(data, dataType, mainData, opt); |
|||
}); |
|||
} |
|||
|
|||
function linkSingle(data, dataType, mainData, opt) { |
|||
inner(mainData).datas[dataType] = data; |
|||
inner(data).mainData = mainData; |
|||
data.dataType = dataType; |
|||
|
|||
if (opt.struct) { |
|||
data[opt.structAttr] = opt.struct; |
|||
opt.struct[opt.datasAttr[dataType]] = data; |
|||
} // Supplement method.
|
|||
|
|||
|
|||
data.getLinkedData = getLinkedData; |
|||
data.getLinkedDataAll = getLinkedDataAll; |
|||
} |
|||
|
|||
export default linkSeriesData; |
|||
@ -0,0 +1,397 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { makeInner, getDataItemValue, queryReferringComponents, SINGLE_REFERRING } from '../../util/model.js'; |
|||
import { createHashMap, each, isArray, isString, isObject, isTypedArray } from 'zrender/lib/core/util.js'; |
|||
import { SOURCE_FORMAT_ORIGINAL, SOURCE_FORMAT_ARRAY_ROWS, SOURCE_FORMAT_OBJECT_ROWS, SERIES_LAYOUT_BY_ROW, SOURCE_FORMAT_KEYED_COLUMNS } from '../../util/types.js'; // The result of `guessOrdinal`.
|
|||
|
|||
export var BE_ORDINAL = { |
|||
Must: 1, |
|||
Might: 2, |
|||
Not: 3 // Other cases
|
|||
|
|||
}; |
|||
var innerGlobalModel = makeInner(); |
|||
/** |
|||
* MUST be called before mergeOption of all series. |
|||
*/ |
|||
|
|||
export function resetSourceDefaulter(ecModel) { |
|||
// `datasetMap` is used to make default encode.
|
|||
innerGlobalModel(ecModel).datasetMap = createHashMap(); |
|||
} |
|||
/** |
|||
* [The strategy of the arrengment of data dimensions for dataset]: |
|||
* "value way": all axes are non-category axes. So series one by one take |
|||
* several (the number is coordSysDims.length) dimensions from dataset. |
|||
* The result of data arrengment of data dimensions like: |
|||
* | ser0_x | ser0_y | ser1_x | ser1_y | ser2_x | ser2_y | |
|||
* "category way": at least one axis is category axis. So the the first data |
|||
* dimension is always mapped to the first category axis and shared by |
|||
* all of the series. The other data dimensions are taken by series like |
|||
* "value way" does. |
|||
* The result of data arrengment of data dimensions like: |
|||
* | ser_shared_x | ser0_y | ser1_y | ser2_y | |
|||
* |
|||
* @return encode Never be `null/undefined`. |
|||
*/ |
|||
|
|||
export function makeSeriesEncodeForAxisCoordSys(coordDimensions, seriesModel, source) { |
|||
var encode = {}; |
|||
var datasetModel = querySeriesUpstreamDatasetModel(seriesModel); // Currently only make default when using dataset, util more reqirements occur.
|
|||
|
|||
if (!datasetModel || !coordDimensions) { |
|||
return encode; |
|||
} |
|||
|
|||
var encodeItemName = []; |
|||
var encodeSeriesName = []; |
|||
var ecModel = seriesModel.ecModel; |
|||
var datasetMap = innerGlobalModel(ecModel).datasetMap; |
|||
var key = datasetModel.uid + '_' + source.seriesLayoutBy; |
|||
var baseCategoryDimIndex; |
|||
var categoryWayValueDimStart; |
|||
coordDimensions = coordDimensions.slice(); |
|||
each(coordDimensions, function (coordDimInfoLoose, coordDimIdx) { |
|||
var coordDimInfo = isObject(coordDimInfoLoose) ? coordDimInfoLoose : coordDimensions[coordDimIdx] = { |
|||
name: coordDimInfoLoose |
|||
}; |
|||
|
|||
if (coordDimInfo.type === 'ordinal' && baseCategoryDimIndex == null) { |
|||
baseCategoryDimIndex = coordDimIdx; |
|||
categoryWayValueDimStart = getDataDimCountOnCoordDim(coordDimInfo); |
|||
} |
|||
|
|||
encode[coordDimInfo.name] = []; |
|||
}); |
|||
var datasetRecord = datasetMap.get(key) || datasetMap.set(key, { |
|||
categoryWayDim: categoryWayValueDimStart, |
|||
valueWayDim: 0 |
|||
}); // TODO
|
|||
// Auto detect first time axis and do arrangement.
|
|||
|
|||
each(coordDimensions, function (coordDimInfo, coordDimIdx) { |
|||
var coordDimName = coordDimInfo.name; |
|||
var count = getDataDimCountOnCoordDim(coordDimInfo); // In value way.
|
|||
|
|||
if (baseCategoryDimIndex == null) { |
|||
var start = datasetRecord.valueWayDim; |
|||
pushDim(encode[coordDimName], start, count); |
|||
pushDim(encodeSeriesName, start, count); |
|||
datasetRecord.valueWayDim += count; // ??? TODO give a better default series name rule?
|
|||
// especially when encode x y specified.
|
|||
// consider: when mutiple series share one dimension
|
|||
// category axis, series name should better use
|
|||
// the other dimsion name. On the other hand, use
|
|||
// both dimensions name.
|
|||
} // In category way, the first category axis.
|
|||
else if (baseCategoryDimIndex === coordDimIdx) { |
|||
pushDim(encode[coordDimName], 0, count); |
|||
pushDim(encodeItemName, 0, count); |
|||
} // In category way, the other axis.
|
|||
else { |
|||
var start = datasetRecord.categoryWayDim; |
|||
pushDim(encode[coordDimName], start, count); |
|||
pushDim(encodeSeriesName, start, count); |
|||
datasetRecord.categoryWayDim += count; |
|||
} |
|||
}); |
|||
|
|||
function pushDim(dimIdxArr, idxFrom, idxCount) { |
|||
for (var i = 0; i < idxCount; i++) { |
|||
dimIdxArr.push(idxFrom + i); |
|||
} |
|||
} |
|||
|
|||
function getDataDimCountOnCoordDim(coordDimInfo) { |
|||
var dimsDef = coordDimInfo.dimsDef; |
|||
return dimsDef ? dimsDef.length : 1; |
|||
} |
|||
|
|||
encodeItemName.length && (encode.itemName = encodeItemName); |
|||
encodeSeriesName.length && (encode.seriesName = encodeSeriesName); |
|||
return encode; |
|||
} |
|||
/** |
|||
* Work for data like [{name: ..., value: ...}, ...]. |
|||
* |
|||
* @return encode Never be `null/undefined`. |
|||
*/ |
|||
|
|||
export function makeSeriesEncodeForNameBased(seriesModel, source, dimCount) { |
|||
var encode = {}; |
|||
var datasetModel = querySeriesUpstreamDatasetModel(seriesModel); // Currently only make default when using dataset, util more reqirements occur.
|
|||
|
|||
if (!datasetModel) { |
|||
return encode; |
|||
} |
|||
|
|||
var sourceFormat = source.sourceFormat; |
|||
var dimensionsDefine = source.dimensionsDefine; |
|||
var potentialNameDimIndex; |
|||
|
|||
if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) { |
|||
each(dimensionsDefine, function (dim, idx) { |
|||
if ((isObject(dim) ? dim.name : dim) === 'name') { |
|||
potentialNameDimIndex = idx; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
var idxResult = function () { |
|||
var idxRes0 = {}; |
|||
var idxRes1 = {}; |
|||
var guessRecords = []; // 5 is an experience value.
|
|||
|
|||
for (var i = 0, len = Math.min(5, dimCount); i < len; i++) { |
|||
var guessResult = doGuessOrdinal(source.data, sourceFormat, source.seriesLayoutBy, dimensionsDefine, source.startIndex, i); |
|||
guessRecords.push(guessResult); |
|||
var isPureNumber = guessResult === BE_ORDINAL.Not; // [Strategy of idxRes0]: find the first BE_ORDINAL.Not as the value dim,
|
|||
// and then find a name dim with the priority:
|
|||
// "BE_ORDINAL.Might|BE_ORDINAL.Must" > "other dim" > "the value dim itself".
|
|||
|
|||
if (isPureNumber && idxRes0.v == null && i !== potentialNameDimIndex) { |
|||
idxRes0.v = i; |
|||
} |
|||
|
|||
if (idxRes0.n == null || idxRes0.n === idxRes0.v || !isPureNumber && guessRecords[idxRes0.n] === BE_ORDINAL.Not) { |
|||
idxRes0.n = i; |
|||
} |
|||
|
|||
if (fulfilled(idxRes0) && guessRecords[idxRes0.n] !== BE_ORDINAL.Not) { |
|||
return idxRes0; |
|||
} // [Strategy of idxRes1]: if idxRes0 not satisfied (that is, no BE_ORDINAL.Not),
|
|||
// find the first BE_ORDINAL.Might as the value dim,
|
|||
// and then find a name dim with the priority:
|
|||
// "other dim" > "the value dim itself".
|
|||
// That is for backward compat: number-like (e.g., `'3'`, `'55'`) can be
|
|||
// treated as number.
|
|||
|
|||
|
|||
if (!isPureNumber) { |
|||
if (guessResult === BE_ORDINAL.Might && idxRes1.v == null && i !== potentialNameDimIndex) { |
|||
idxRes1.v = i; |
|||
} |
|||
|
|||
if (idxRes1.n == null || idxRes1.n === idxRes1.v) { |
|||
idxRes1.n = i; |
|||
} |
|||
} |
|||
} |
|||
|
|||
function fulfilled(idxResult) { |
|||
return idxResult.v != null && idxResult.n != null; |
|||
} |
|||
|
|||
return fulfilled(idxRes0) ? idxRes0 : fulfilled(idxRes1) ? idxRes1 : null; |
|||
}(); |
|||
|
|||
if (idxResult) { |
|||
encode.value = [idxResult.v]; // `potentialNameDimIndex` has highest priority.
|
|||
|
|||
var nameDimIndex = potentialNameDimIndex != null ? potentialNameDimIndex : idxResult.n; // By default, label use itemName in charts.
|
|||
// So we dont set encodeLabel here.
|
|||
|
|||
encode.itemName = [nameDimIndex]; |
|||
encode.seriesName = [nameDimIndex]; |
|||
} |
|||
|
|||
return encode; |
|||
} |
|||
/** |
|||
* @return If return null/undefined, indicate that should not use datasetModel. |
|||
*/ |
|||
|
|||
export function querySeriesUpstreamDatasetModel(seriesModel) { |
|||
// Caution: consider the scenario:
|
|||
// A dataset is declared and a series is not expected to use the dataset,
|
|||
// and at the beginning `setOption({series: { noData })` (just prepare other
|
|||
// option but no data), then `setOption({series: {data: [...]}); In this case,
|
|||
// the user should set an empty array to avoid that dataset is used by default.
|
|||
var thisData = seriesModel.get('data', true); |
|||
|
|||
if (!thisData) { |
|||
return queryReferringComponents(seriesModel.ecModel, 'dataset', { |
|||
index: seriesModel.get('datasetIndex', true), |
|||
id: seriesModel.get('datasetId', true) |
|||
}, SINGLE_REFERRING).models[0]; |
|||
} |
|||
} |
|||
/** |
|||
* @return Always return an array event empty. |
|||
*/ |
|||
|
|||
export function queryDatasetUpstreamDatasetModels(datasetModel) { |
|||
// Only these attributes declared, we by defualt reference to `datasetIndex: 0`.
|
|||
// Otherwise, no reference.
|
|||
if (!datasetModel.get('transform', true) && !datasetModel.get('fromTransformResult', true)) { |
|||
return []; |
|||
} |
|||
|
|||
return queryReferringComponents(datasetModel.ecModel, 'dataset', { |
|||
index: datasetModel.get('fromDatasetIndex', true), |
|||
id: datasetModel.get('fromDatasetId', true) |
|||
}, SINGLE_REFERRING).models; |
|||
} |
|||
/** |
|||
* The rule should not be complex, otherwise user might not |
|||
* be able to known where the data is wrong. |
|||
* The code is ugly, but how to make it neat? |
|||
*/ |
|||
|
|||
export function guessOrdinal(source, dimIndex) { |
|||
return doGuessOrdinal(source.data, source.sourceFormat, source.seriesLayoutBy, source.dimensionsDefine, source.startIndex, dimIndex); |
|||
} // dimIndex may be overflow source data.
|
|||
// return {BE_ORDINAL}
|
|||
|
|||
function doGuessOrdinal(data, sourceFormat, seriesLayoutBy, dimensionsDefine, startIndex, dimIndex) { |
|||
var result; // Experience value.
|
|||
|
|||
var maxLoop = 5; |
|||
|
|||
if (isTypedArray(data)) { |
|||
return BE_ORDINAL.Not; |
|||
} // When sourceType is 'objectRows' or 'keyedColumns', dimensionsDefine
|
|||
// always exists in source.
|
|||
|
|||
|
|||
var dimName; |
|||
var dimType; |
|||
|
|||
if (dimensionsDefine) { |
|||
var dimDefItem = dimensionsDefine[dimIndex]; |
|||
|
|||
if (isObject(dimDefItem)) { |
|||
dimName = dimDefItem.name; |
|||
dimType = dimDefItem.type; |
|||
} else if (isString(dimDefItem)) { |
|||
dimName = dimDefItem; |
|||
} |
|||
} |
|||
|
|||
if (dimType != null) { |
|||
return dimType === 'ordinal' ? BE_ORDINAL.Must : BE_ORDINAL.Not; |
|||
} |
|||
|
|||
if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) { |
|||
var dataArrayRows = data; |
|||
|
|||
if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) { |
|||
var sample = dataArrayRows[dimIndex]; |
|||
|
|||
for (var i = 0; i < (sample || []).length && i < maxLoop; i++) { |
|||
if ((result = detectValue(sample[startIndex + i])) != null) { |
|||
return result; |
|||
} |
|||
} |
|||
} else { |
|||
for (var i = 0; i < dataArrayRows.length && i < maxLoop; i++) { |
|||
var row = dataArrayRows[startIndex + i]; |
|||
|
|||
if (row && (result = detectValue(row[dimIndex])) != null) { |
|||
return result; |
|||
} |
|||
} |
|||
} |
|||
} else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) { |
|||
var dataObjectRows = data; |
|||
|
|||
if (!dimName) { |
|||
return BE_ORDINAL.Not; |
|||
} |
|||
|
|||
for (var i = 0; i < dataObjectRows.length && i < maxLoop; i++) { |
|||
var item = dataObjectRows[i]; |
|||
|
|||
if (item && (result = detectValue(item[dimName])) != null) { |
|||
return result; |
|||
} |
|||
} |
|||
} else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) { |
|||
var dataKeyedColumns = data; |
|||
|
|||
if (!dimName) { |
|||
return BE_ORDINAL.Not; |
|||
} |
|||
|
|||
var sample = dataKeyedColumns[dimName]; |
|||
|
|||
if (!sample || isTypedArray(sample)) { |
|||
return BE_ORDINAL.Not; |
|||
} |
|||
|
|||
for (var i = 0; i < sample.length && i < maxLoop; i++) { |
|||
if ((result = detectValue(sample[i])) != null) { |
|||
return result; |
|||
} |
|||
} |
|||
} else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) { |
|||
var dataOriginal = data; |
|||
|
|||
for (var i = 0; i < dataOriginal.length && i < maxLoop; i++) { |
|||
var item = dataOriginal[i]; |
|||
var val = getDataItemValue(item); |
|||
|
|||
if (!isArray(val)) { |
|||
return BE_ORDINAL.Not; |
|||
} |
|||
|
|||
if ((result = detectValue(val[dimIndex])) != null) { |
|||
return result; |
|||
} |
|||
} |
|||
} |
|||
|
|||
function detectValue(val) { |
|||
var beStr = isString(val); // Consider usage convenience, '1', '2' will be treated as "number".
|
|||
// `isFinit('')` get `true`.
|
|||
|
|||
if (val != null && isFinite(val) && val !== '') { |
|||
return beStr ? BE_ORDINAL.Might : BE_ORDINAL.Not; |
|||
} else if (beStr && val !== '-') { |
|||
return BE_ORDINAL.Must; |
|||
} |
|||
} |
|||
|
|||
return BE_ORDINAL.Not; |
|||
} |
|||
@ -0,0 +1,475 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { setAsPrimitive, map, isTypedArray, assert, each, retrieve2 } from 'zrender/lib/core/util.js'; |
|||
import { createSource, cloneSourceShallow } from '../Source.js'; |
|||
import { SOURCE_FORMAT_TYPED_ARRAY, SOURCE_FORMAT_ORIGINAL } from '../../util/types.js'; |
|||
import { querySeriesUpstreamDatasetModel, queryDatasetUpstreamDatasetModels } from './sourceHelper.js'; |
|||
import { applyDataTransform } from './transform.js'; |
|||
import DataStore from '../DataStore.js'; |
|||
import { DefaultDataProvider } from './dataProvider.js'; |
|||
/** |
|||
* [REQUIREMENT_MEMO]: |
|||
* (0) `metaRawOption` means `dimensions`/`sourceHeader`/`seriesLayoutBy` in raw option. |
|||
* (1) Keep support the feature: `metaRawOption` can be specified both on `series` and |
|||
* `root-dataset`. Them on `series` has higher priority. |
|||
* (2) Do not support to set `metaRawOption` on a `non-root-dataset`, because it might |
|||
* confuse users: whether those props indicate how to visit the upstream source or visit |
|||
* the transform result source, and some transforms has nothing to do with these props, |
|||
* and some transforms might have multiple upstream. |
|||
* (3) Transforms should specify `metaRawOption` in each output, just like they can be |
|||
* declared in `root-dataset`. |
|||
* (4) At present only support visit source in `SERIES_LAYOUT_BY_COLUMN` in transforms. |
|||
* That is for reducing complexity in transfroms. |
|||
* PENDING: Whether to provide transposition transform? |
|||
* |
|||
* [IMPLEMENTAION_MEMO]: |
|||
* "sourceVisitConfig" are calculated from `metaRawOption` and `data`. |
|||
* They will not be calculated until `source` is about to be visited (to prevent from |
|||
* duplicate calcuation). `source` is visited only in series and input to transforms. |
|||
* |
|||
* [DIMENSION_INHERIT_RULE]: |
|||
* By default the dimensions are inherited from ancestors, unless a transform return |
|||
* a new dimensions definition. |
|||
* Consider the case: |
|||
* ```js
|
|||
* dataset: [{ |
|||
* source: [ ['Product', 'Sales', 'Prise'], ['Cookies', 321, 44.21], ...] |
|||
* }, { |
|||
* transform: { type: 'filter', ... } |
|||
* }] |
|||
* dataset: [{ |
|||
* dimension: ['Product', 'Sales', 'Prise'], |
|||
* source: [ ['Cookies', 321, 44.21], ...] |
|||
* }, { |
|||
* transform: { type: 'filter', ... } |
|||
* }] |
|||
* ``` |
|||
* The two types of option should have the same behavior after transform. |
|||
* |
|||
* |
|||
* [SCENARIO]: |
|||
* (1) Provide source data directly: |
|||
* ```js
|
|||
* series: { |
|||
* encode: {...}, |
|||
* dimensions: [...] |
|||
* seriesLayoutBy: 'row', |
|||
* data: [[...]] |
|||
* } |
|||
* ``` |
|||
* (2) Series refer to dataset. |
|||
* ```js
|
|||
* series: [{ |
|||
* encode: {...} |
|||
* // Ignore datasetIndex means `datasetIndex: 0`
|
|||
* // and the dimensions defination in dataset is used
|
|||
* }, { |
|||
* encode: {...}, |
|||
* seriesLayoutBy: 'column', |
|||
* datasetIndex: 1 |
|||
* }] |
|||
* ``` |
|||
* (3) dataset transform |
|||
* ```js
|
|||
* dataset: [{ |
|||
* source: [...] |
|||
* }, { |
|||
* source: [...] |
|||
* }, { |
|||
* // By default from 0.
|
|||
* transform: { type: 'filter', config: {...} } |
|||
* }, { |
|||
* // Piped.
|
|||
* transform: [ |
|||
* { type: 'filter', config: {...} }, |
|||
* { type: 'sort', config: {...} } |
|||
* ] |
|||
* }, { |
|||
* id: 'regressionData', |
|||
* fromDatasetIndex: 1, |
|||
* // Third-party transform
|
|||
* transform: { type: 'ecStat:regression', config: {...} } |
|||
* }, { |
|||
* // retrieve the extra result.
|
|||
* id: 'regressionFormula', |
|||
* fromDatasetId: 'regressionData', |
|||
* fromTransformResult: 1 |
|||
* }] |
|||
* ``` |
|||
*/ |
|||
|
|||
var SourceManager = |
|||
/** @class */ |
|||
function () { |
|||
function SourceManager(sourceHost) { |
|||
// Cached source. Do not repeat calculating if not dirty.
|
|||
this._sourceList = []; |
|||
this._storeList = []; // version sign of each upstream source manager.
|
|||
|
|||
this._upstreamSignList = []; |
|||
this._versionSignBase = 0; |
|||
this._dirty = true; |
|||
this._sourceHost = sourceHost; |
|||
} |
|||
/** |
|||
* Mark dirty. |
|||
*/ |
|||
|
|||
|
|||
SourceManager.prototype.dirty = function () { |
|||
this._setLocalSource([], []); |
|||
|
|||
this._storeList = []; |
|||
this._dirty = true; |
|||
}; |
|||
|
|||
SourceManager.prototype._setLocalSource = function (sourceList, upstreamSignList) { |
|||
this._sourceList = sourceList; |
|||
this._upstreamSignList = upstreamSignList; |
|||
this._versionSignBase++; |
|||
|
|||
if (this._versionSignBase > 9e10) { |
|||
this._versionSignBase = 0; |
|||
} |
|||
}; |
|||
/** |
|||
* For detecting whether the upstream source is dirty, so that |
|||
* the local cached source (in `_sourceList`) should be discarded. |
|||
*/ |
|||
|
|||
|
|||
SourceManager.prototype._getVersionSign = function () { |
|||
return this._sourceHost.uid + '_' + this._versionSignBase; |
|||
}; |
|||
/** |
|||
* Always return a source instance. Otherwise throw error. |
|||
*/ |
|||
|
|||
|
|||
SourceManager.prototype.prepareSource = function () { |
|||
// For the case that call `setOption` multiple time but no data changed,
|
|||
// cache the result source to prevent from repeating transform.
|
|||
if (this._isDirty()) { |
|||
this._createSource(); |
|||
|
|||
this._dirty = false; |
|||
} |
|||
}; |
|||
|
|||
SourceManager.prototype._createSource = function () { |
|||
this._setLocalSource([], []); |
|||
|
|||
var sourceHost = this._sourceHost; |
|||
|
|||
var upSourceMgrList = this._getUpstreamSourceManagers(); |
|||
|
|||
var hasUpstream = !!upSourceMgrList.length; |
|||
var resultSourceList; |
|||
var upstreamSignList; |
|||
|
|||
if (isSeries(sourceHost)) { |
|||
var seriesModel = sourceHost; |
|||
var data = void 0; |
|||
var sourceFormat = void 0; |
|||
var upSource = void 0; // Has upstream dataset
|
|||
|
|||
if (hasUpstream) { |
|||
var upSourceMgr = upSourceMgrList[0]; |
|||
upSourceMgr.prepareSource(); |
|||
upSource = upSourceMgr.getSource(); |
|||
data = upSource.data; |
|||
sourceFormat = upSource.sourceFormat; |
|||
upstreamSignList = [upSourceMgr._getVersionSign()]; |
|||
} // Series data is from own.
|
|||
else { |
|||
data = seriesModel.get('data', true); |
|||
sourceFormat = isTypedArray(data) ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL; |
|||
upstreamSignList = []; |
|||
} // See [REQUIREMENT_MEMO], merge settings on series and parent dataset if it is root.
|
|||
|
|||
|
|||
var newMetaRawOption = this._getSourceMetaRawOption() || {}; |
|||
var upMetaRawOption = upSource && upSource.metaRawOption || {}; |
|||
var seriesLayoutBy = retrieve2(newMetaRawOption.seriesLayoutBy, upMetaRawOption.seriesLayoutBy) || null; |
|||
var sourceHeader = retrieve2(newMetaRawOption.sourceHeader, upMetaRawOption.sourceHeader); // Note here we should not use `upSource.dimensionsDefine`. Consider the case:
|
|||
// `upSource.dimensionsDefine` is detected by `seriesLayoutBy: 'column'`,
|
|||
// but series need `seriesLayoutBy: 'row'`.
|
|||
|
|||
var dimensions = retrieve2(newMetaRawOption.dimensions, upMetaRawOption.dimensions); // We share source with dataset as much as possible
|
|||
// to avoid extra memroy cost of high dimensional data.
|
|||
|
|||
var needsCreateSource = seriesLayoutBy !== upMetaRawOption.seriesLayoutBy || !!sourceHeader !== !!upMetaRawOption.sourceHeader || dimensions; |
|||
resultSourceList = needsCreateSource ? [createSource(data, { |
|||
seriesLayoutBy: seriesLayoutBy, |
|||
sourceHeader: sourceHeader, |
|||
dimensions: dimensions |
|||
}, sourceFormat)] : []; |
|||
} else { |
|||
var datasetModel = sourceHost; // Has upstream dataset.
|
|||
|
|||
if (hasUpstream) { |
|||
var result = this._applyTransform(upSourceMgrList); |
|||
|
|||
resultSourceList = result.sourceList; |
|||
upstreamSignList = result.upstreamSignList; |
|||
} // Is root dataset.
|
|||
else { |
|||
var sourceData = datasetModel.get('source', true); |
|||
resultSourceList = [createSource(sourceData, this._getSourceMetaRawOption(), null)]; |
|||
upstreamSignList = []; |
|||
} |
|||
} |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(resultSourceList && upstreamSignList); |
|||
} |
|||
|
|||
this._setLocalSource(resultSourceList, upstreamSignList); |
|||
}; |
|||
|
|||
SourceManager.prototype._applyTransform = function (upMgrList) { |
|||
var datasetModel = this._sourceHost; |
|||
var transformOption = datasetModel.get('transform', true); |
|||
var fromTransformResult = datasetModel.get('fromTransformResult', true); |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(fromTransformResult != null || transformOption != null); |
|||
} |
|||
|
|||
if (fromTransformResult != null) { |
|||
var errMsg = ''; |
|||
|
|||
if (upMgrList.length !== 1) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'When using `fromTransformResult`, there should be only one upstream dataset'; |
|||
} |
|||
|
|||
doThrow(errMsg); |
|||
} |
|||
} |
|||
|
|||
var sourceList; |
|||
var upSourceList = []; |
|||
var upstreamSignList = []; |
|||
each(upMgrList, function (upMgr) { |
|||
upMgr.prepareSource(); |
|||
var upSource = upMgr.getSource(fromTransformResult || 0); |
|||
var errMsg = ''; |
|||
|
|||
if (fromTransformResult != null && !upSource) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'Can not retrieve result by `fromTransformResult`: ' + fromTransformResult; |
|||
} |
|||
|
|||
doThrow(errMsg); |
|||
} |
|||
|
|||
upSourceList.push(upSource); |
|||
upstreamSignList.push(upMgr._getVersionSign()); |
|||
}); |
|||
|
|||
if (transformOption) { |
|||
sourceList = applyDataTransform(transformOption, upSourceList, { |
|||
datasetIndex: datasetModel.componentIndex |
|||
}); |
|||
} else if (fromTransformResult != null) { |
|||
sourceList = [cloneSourceShallow(upSourceList[0])]; |
|||
} |
|||
|
|||
return { |
|||
sourceList: sourceList, |
|||
upstreamSignList: upstreamSignList |
|||
}; |
|||
}; |
|||
|
|||
SourceManager.prototype._isDirty = function () { |
|||
if (this._dirty) { |
|||
return true; |
|||
} // All sourceList is from the some upsteam.
|
|||
|
|||
|
|||
var upSourceMgrList = this._getUpstreamSourceManagers(); |
|||
|
|||
for (var i = 0; i < upSourceMgrList.length; i++) { |
|||
var upSrcMgr = upSourceMgrList[i]; |
|||
|
|||
if ( // Consider the case that there is ancestor diry, call it recursively.
|
|||
// The performance is probably not an issue because usually the chain is not long.
|
|||
upSrcMgr._isDirty() || this._upstreamSignList[i] !== upSrcMgr._getVersionSign()) { |
|||
return true; |
|||
} |
|||
} |
|||
}; |
|||
/** |
|||
* @param sourceIndex By defualt 0, means "main source". |
|||
* Most cases there is only one source. |
|||
*/ |
|||
|
|||
|
|||
SourceManager.prototype.getSource = function (sourceIndex) { |
|||
sourceIndex = sourceIndex || 0; |
|||
var source = this._sourceList[sourceIndex]; |
|||
|
|||
if (!source) { |
|||
// Series may share source instance with dataset.
|
|||
var upSourceMgrList = this._getUpstreamSourceManagers(); |
|||
|
|||
return upSourceMgrList[0] && upSourceMgrList[0].getSource(sourceIndex); |
|||
} |
|||
|
|||
return source; |
|||
}; |
|||
/** |
|||
* |
|||
* Get a data store which can be shared across series. |
|||
* Only available for series. |
|||
* |
|||
* @param seriesDimRequest Dimensions that are generated in series. |
|||
* Should have been sorted by `storeDimIndex` asc. |
|||
*/ |
|||
|
|||
|
|||
SourceManager.prototype.getSharedDataStore = function (seriesDimRequest) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(isSeries(this._sourceHost), 'Can only call getDataStore on series source manager.'); |
|||
} |
|||
|
|||
var schema = seriesDimRequest.makeStoreSchema(); |
|||
return this._innerGetDataStore(schema.dimensions, seriesDimRequest.source, schema.hash); |
|||
}; |
|||
|
|||
SourceManager.prototype._innerGetDataStore = function (storeDims, seriesSource, sourceReadKey) { |
|||
// TODO Can use other sourceIndex?
|
|||
var sourceIndex = 0; |
|||
var storeList = this._storeList; |
|||
var cachedStoreMap = storeList[sourceIndex]; |
|||
|
|||
if (!cachedStoreMap) { |
|||
cachedStoreMap = storeList[sourceIndex] = {}; |
|||
} |
|||
|
|||
var cachedStore = cachedStoreMap[sourceReadKey]; |
|||
|
|||
if (!cachedStore) { |
|||
var upSourceMgr = this._getUpstreamSourceManagers()[0]; |
|||
|
|||
if (isSeries(this._sourceHost) && upSourceMgr) { |
|||
cachedStore = upSourceMgr._innerGetDataStore(storeDims, seriesSource, sourceReadKey); |
|||
} else { |
|||
cachedStore = new DataStore(); // Always create store from source of series.
|
|||
|
|||
cachedStore.initData(new DefaultDataProvider(seriesSource, storeDims.length), storeDims); |
|||
} |
|||
|
|||
cachedStoreMap[sourceReadKey] = cachedStore; |
|||
} |
|||
|
|||
return cachedStore; |
|||
}; |
|||
/** |
|||
* PEDING: Is it fast enough? |
|||
* If no upstream, return empty array. |
|||
*/ |
|||
|
|||
|
|||
SourceManager.prototype._getUpstreamSourceManagers = function () { |
|||
// Always get the relationship from the raw option.
|
|||
// Do not cache the link of the dependency graph, so that
|
|||
// no need to update them when change happen.
|
|||
var sourceHost = this._sourceHost; |
|||
|
|||
if (isSeries(sourceHost)) { |
|||
var datasetModel = querySeriesUpstreamDatasetModel(sourceHost); |
|||
return !datasetModel ? [] : [datasetModel.getSourceManager()]; |
|||
} else { |
|||
return map(queryDatasetUpstreamDatasetModels(sourceHost), function (datasetModel) { |
|||
return datasetModel.getSourceManager(); |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
SourceManager.prototype._getSourceMetaRawOption = function () { |
|||
var sourceHost = this._sourceHost; |
|||
var seriesLayoutBy; |
|||
var sourceHeader; |
|||
var dimensions; |
|||
|
|||
if (isSeries(sourceHost)) { |
|||
seriesLayoutBy = sourceHost.get('seriesLayoutBy', true); |
|||
sourceHeader = sourceHost.get('sourceHeader', true); |
|||
dimensions = sourceHost.get('dimensions', true); |
|||
} // See [REQUIREMENT_MEMO], `non-root-dataset` do not support them.
|
|||
else if (!this._getUpstreamSourceManagers().length) { |
|||
var model = sourceHost; |
|||
seriesLayoutBy = model.get('seriesLayoutBy', true); |
|||
sourceHeader = model.get('sourceHeader', true); |
|||
dimensions = model.get('dimensions', true); |
|||
} |
|||
|
|||
return { |
|||
seriesLayoutBy: seriesLayoutBy, |
|||
sourceHeader: sourceHeader, |
|||
dimensions: dimensions |
|||
}; |
|||
}; |
|||
|
|||
return SourceManager; |
|||
}(); |
|||
|
|||
export { SourceManager }; // Call this method after `super.init` and `super.mergeOption` to
|
|||
// disable the transform merge, but do not disable transfrom clone from rawOption.
|
|||
|
|||
export function disableTransformOptionMerge(datasetModel) { |
|||
var transformOption = datasetModel.option.transform; |
|||
transformOption && setAsPrimitive(datasetModel.option.transform); |
|||
} |
|||
|
|||
function isSeries(sourceHost) { |
|||
// Avoid circular dependency with Series.ts
|
|||
return sourceHost.mainType === 'series'; |
|||
} |
|||
|
|||
function doThrow(errMsg) { |
|||
throw new Error(errMsg); |
|||
} |
|||
@ -0,0 +1,499 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { SERIES_LAYOUT_BY_COLUMN, SOURCE_FORMAT_OBJECT_ROWS, SOURCE_FORMAT_ARRAY_ROWS } from '../../util/types.js'; |
|||
import { normalizeToArray } from '../../util/model.js'; |
|||
import { createHashMap, bind, each, hasOwn, map, clone, isObject, extend, isNumber } from 'zrender/lib/core/util.js'; |
|||
import { getRawSourceItemGetter, getRawSourceDataCounter, getRawSourceValueGetter } from './dataProvider.js'; |
|||
import { parseDataValue } from './dataValueHelper.js'; |
|||
import { log, makePrintable, throwError } from '../../util/log.js'; |
|||
import { createSource, detectSourceFormat } from '../Source.js'; |
|||
/** |
|||
* TODO: disable writable. |
|||
* This structure will be exposed to users. |
|||
*/ |
|||
|
|||
var ExternalSource = |
|||
/** @class */ |
|||
function () { |
|||
function ExternalSource() {} |
|||
|
|||
ExternalSource.prototype.getRawData = function () { |
|||
// Only built-in transform available.
|
|||
throw new Error('not supported'); |
|||
}; |
|||
|
|||
ExternalSource.prototype.getRawDataItem = function (dataIndex) { |
|||
// Only built-in transform available.
|
|||
throw new Error('not supported'); |
|||
}; |
|||
|
|||
ExternalSource.prototype.cloneRawData = function () { |
|||
return; |
|||
}; |
|||
/** |
|||
* @return If dimension not found, return null/undefined. |
|||
*/ |
|||
|
|||
|
|||
ExternalSource.prototype.getDimensionInfo = function (dim) { |
|||
return; |
|||
}; |
|||
/** |
|||
* dimensions defined if and only if either: |
|||
* (a) dataset.dimensions are declared. |
|||
* (b) dataset data include dimensions definitions in data (detected or via specified `sourceHeader`). |
|||
* If dimensions are defined, `dimensionInfoAll` is corresponding to |
|||
* the defined dimensions. |
|||
* Otherwise, `dimensionInfoAll` is determined by data columns. |
|||
* @return Always return an array (even empty array). |
|||
*/ |
|||
|
|||
|
|||
ExternalSource.prototype.cloneAllDimensionInfo = function () { |
|||
return; |
|||
}; |
|||
|
|||
ExternalSource.prototype.count = function () { |
|||
return; |
|||
}; |
|||
/** |
|||
* Only support by dimension index. |
|||
* No need to support by dimension name in transform function, |
|||
* becuase transform function is not case-specific, no need to use name literally. |
|||
*/ |
|||
|
|||
|
|||
ExternalSource.prototype.retrieveValue = function (dataIndex, dimIndex) { |
|||
return; |
|||
}; |
|||
|
|||
ExternalSource.prototype.retrieveValueFromItem = function (dataItem, dimIndex) { |
|||
return; |
|||
}; |
|||
|
|||
ExternalSource.prototype.convertValue = function (rawVal, dimInfo) { |
|||
return parseDataValue(rawVal, dimInfo); |
|||
}; |
|||
|
|||
return ExternalSource; |
|||
}(); |
|||
|
|||
export { ExternalSource }; |
|||
|
|||
function createExternalSource(internalSource, externalTransform) { |
|||
var extSource = new ExternalSource(); |
|||
var data = internalSource.data; |
|||
var sourceFormat = extSource.sourceFormat = internalSource.sourceFormat; |
|||
var sourceHeaderCount = internalSource.startIndex; |
|||
var errMsg = ''; |
|||
|
|||
if (internalSource.seriesLayoutBy !== SERIES_LAYOUT_BY_COLUMN) { |
|||
// For the logic simplicity in transformer, only 'culumn' is
|
|||
// supported in data transform. Otherwise, the `dimensionsDefine`
|
|||
// might be detected by 'row', which probably confuses users.
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = '`seriesLayoutBy` of upstream dataset can only be "column" in data transform.'; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} // [MEMO]
|
|||
// Create a new dimensions structure for exposing.
|
|||
// Do not expose all dimension info to users directly.
|
|||
// Becuase the dimension is probably auto detected from data and not might reliable.
|
|||
// Should not lead the transformers to think that is relialbe and return it.
|
|||
// See [DIMENSION_INHERIT_RULE] in `sourceManager.ts`.
|
|||
|
|||
|
|||
var dimensions = []; |
|||
var dimsByName = {}; |
|||
var dimsDef = internalSource.dimensionsDefine; |
|||
|
|||
if (dimsDef) { |
|||
each(dimsDef, function (dimDef, idx) { |
|||
var name = dimDef.name; |
|||
var dimDefExt = { |
|||
index: idx, |
|||
name: name, |
|||
displayName: dimDef.displayName |
|||
}; |
|||
dimensions.push(dimDefExt); // Users probably not sepcify dimension name. For simplicity, data transform
|
|||
// do not generate dimension name.
|
|||
|
|||
if (name != null) { |
|||
// Dimension name should not be duplicated.
|
|||
// For simplicity, data transform forbid name duplication, do not generate
|
|||
// new name like module `completeDimensions.ts` did, but just tell users.
|
|||
var errMsg_1 = ''; |
|||
|
|||
if (hasOwn(dimsByName, name)) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg_1 = 'dimension name "' + name + '" duplicated.'; |
|||
} |
|||
|
|||
throwError(errMsg_1); |
|||
} |
|||
|
|||
dimsByName[name] = dimDefExt; |
|||
} |
|||
}); |
|||
} // If dimension definitions are not defined and can not be detected.
|
|||
// e.g., pure data `[[11, 22], ...]`.
|
|||
else { |
|||
for (var i = 0; i < internalSource.dimensionsDetectedCount || 0; i++) { |
|||
// Do not generete name or anything others. The consequence process in
|
|||
// `transform` or `series` probably have there own name generation strategry.
|
|||
dimensions.push({ |
|||
index: i |
|||
}); |
|||
} |
|||
} // Implement public methods:
|
|||
|
|||
|
|||
var rawItemGetter = getRawSourceItemGetter(sourceFormat, SERIES_LAYOUT_BY_COLUMN); |
|||
|
|||
if (externalTransform.__isBuiltIn) { |
|||
extSource.getRawDataItem = function (dataIndex) { |
|||
return rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex); |
|||
}; |
|||
|
|||
extSource.getRawData = bind(getRawData, null, internalSource); |
|||
} |
|||
|
|||
extSource.cloneRawData = bind(cloneRawData, null, internalSource); |
|||
var rawCounter = getRawSourceDataCounter(sourceFormat, SERIES_LAYOUT_BY_COLUMN); |
|||
extSource.count = bind(rawCounter, null, data, sourceHeaderCount, dimensions); |
|||
var rawValueGetter = getRawSourceValueGetter(sourceFormat); |
|||
|
|||
extSource.retrieveValue = function (dataIndex, dimIndex) { |
|||
var rawItem = rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex); |
|||
return retrieveValueFromItem(rawItem, dimIndex); |
|||
}; |
|||
|
|||
var retrieveValueFromItem = extSource.retrieveValueFromItem = function (dataItem, dimIndex) { |
|||
if (dataItem == null) { |
|||
return; |
|||
} |
|||
|
|||
var dimDef = dimensions[dimIndex]; // When `dimIndex` is `null`, `rawValueGetter` return the whole item.
|
|||
|
|||
if (dimDef) { |
|||
return rawValueGetter(dataItem, dimIndex, dimDef.name); |
|||
} |
|||
}; |
|||
|
|||
extSource.getDimensionInfo = bind(getDimensionInfo, null, dimensions, dimsByName); |
|||
extSource.cloneAllDimensionInfo = bind(cloneAllDimensionInfo, null, dimensions); |
|||
return extSource; |
|||
} |
|||
|
|||
function getRawData(upstream) { |
|||
var sourceFormat = upstream.sourceFormat; |
|||
|
|||
if (!isSupportedSourceFormat(sourceFormat)) { |
|||
var errMsg = ''; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = '`getRawData` is not supported in source format ' + sourceFormat; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} |
|||
|
|||
return upstream.data; |
|||
} |
|||
|
|||
function cloneRawData(upstream) { |
|||
var sourceFormat = upstream.sourceFormat; |
|||
var data = upstream.data; |
|||
|
|||
if (!isSupportedSourceFormat(sourceFormat)) { |
|||
var errMsg = ''; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = '`cloneRawData` is not supported in source format ' + sourceFormat; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} |
|||
|
|||
if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) { |
|||
var result = []; |
|||
|
|||
for (var i = 0, len = data.length; i < len; i++) { |
|||
// Not strictly clone for performance
|
|||
result.push(data[i].slice()); |
|||
} |
|||
|
|||
return result; |
|||
} else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) { |
|||
var result = []; |
|||
|
|||
for (var i = 0, len = data.length; i < len; i++) { |
|||
// Not strictly clone for performance
|
|||
result.push(extend({}, data[i])); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
|
|||
function getDimensionInfo(dimensions, dimsByName, dim) { |
|||
if (dim == null) { |
|||
return; |
|||
} // Keep the same logic as `List::getDimension` did.
|
|||
|
|||
|
|||
if (isNumber(dim) // If being a number-like string but not being defined a dimension name.
|
|||
|| !isNaN(dim) && !hasOwn(dimsByName, dim)) { |
|||
return dimensions[dim]; |
|||
} else if (hasOwn(dimsByName, dim)) { |
|||
return dimsByName[dim]; |
|||
} |
|||
} |
|||
|
|||
function cloneAllDimensionInfo(dimensions) { |
|||
return clone(dimensions); |
|||
} |
|||
|
|||
var externalTransformMap = createHashMap(); |
|||
export function registerExternalTransform(externalTransform) { |
|||
externalTransform = clone(externalTransform); |
|||
var type = externalTransform.type; |
|||
var errMsg = ''; |
|||
|
|||
if (!type) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'Must have a `type` when `registerTransform`.'; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} |
|||
|
|||
var typeParsed = type.split(':'); |
|||
|
|||
if (typeParsed.length !== 2) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'Name must include namespace like "ns:regression".'; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} // Namespace 'echarts:xxx' is official namespace, where the transforms should
|
|||
// be called directly via 'xxx' rather than 'echarts:xxx'.
|
|||
|
|||
|
|||
var isBuiltIn = false; |
|||
|
|||
if (typeParsed[0] === 'echarts') { |
|||
type = typeParsed[1]; |
|||
isBuiltIn = true; |
|||
} |
|||
|
|||
externalTransform.__isBuiltIn = isBuiltIn; |
|||
externalTransformMap.set(type, externalTransform); |
|||
} |
|||
export function applyDataTransform(rawTransOption, sourceList, infoForPrint) { |
|||
var pipedTransOption = normalizeToArray(rawTransOption); |
|||
var pipeLen = pipedTransOption.length; |
|||
var errMsg = ''; |
|||
|
|||
if (!pipeLen) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'If `transform` declared, it should at least contain one transform.'; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} |
|||
|
|||
for (var i = 0, len = pipeLen; i < len; i++) { |
|||
var transOption = pipedTransOption[i]; |
|||
sourceList = applySingleDataTransform(transOption, sourceList, infoForPrint, pipeLen === 1 ? null : i); // piped transform only support single input, except the fist one.
|
|||
// piped transform only support single output, except the last one.
|
|||
|
|||
if (i !== len - 1) { |
|||
sourceList.length = Math.max(sourceList.length, 1); |
|||
} |
|||
} |
|||
|
|||
return sourceList; |
|||
} |
|||
|
|||
function applySingleDataTransform(transOption, upSourceList, infoForPrint, // If `pipeIndex` is null/undefined, no piped transform.
|
|||
pipeIndex) { |
|||
var errMsg = ''; |
|||
|
|||
if (!upSourceList.length) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'Must have at least one upstream dataset.'; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} |
|||
|
|||
if (!isObject(transOption)) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'transform declaration must be an object rather than ' + typeof transOption + '.'; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} |
|||
|
|||
var transType = transOption.type; |
|||
var externalTransform = externalTransformMap.get(transType); |
|||
|
|||
if (!externalTransform) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'Can not find transform on type "' + transType + '".'; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} // Prepare source
|
|||
|
|||
|
|||
var extUpSourceList = map(upSourceList, function (upSource) { |
|||
return createExternalSource(upSource, externalTransform); |
|||
}); |
|||
var resultList = normalizeToArray(externalTransform.transform({ |
|||
upstream: extUpSourceList[0], |
|||
upstreamList: extUpSourceList, |
|||
config: clone(transOption.config) |
|||
})); |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (transOption.print) { |
|||
var printStrArr = map(resultList, function (extSource) { |
|||
var pipeIndexStr = pipeIndex != null ? ' === pipe index: ' + pipeIndex : ''; |
|||
return ['=== dataset index: ' + infoForPrint.datasetIndex + pipeIndexStr + ' ===', '- transform result data:', makePrintable(extSource.data), '- transform result dimensions:', makePrintable(extSource.dimensions)].join('\n'); |
|||
}).join('\n'); |
|||
log(printStrArr); |
|||
} |
|||
} |
|||
|
|||
return map(resultList, function (result, resultIndex) { |
|||
var errMsg = ''; |
|||
|
|||
if (!isObject(result)) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'A transform should not return some empty results.'; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} |
|||
|
|||
if (!result.data) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'Transform result data should be not be null or undefined'; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} |
|||
|
|||
var sourceFormat = detectSourceFormat(result.data); |
|||
|
|||
if (!isSupportedSourceFormat(sourceFormat)) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
errMsg = 'Transform result data should be array rows or object rows.'; |
|||
} |
|||
|
|||
throwError(errMsg); |
|||
} |
|||
|
|||
var resultMetaRawOption; |
|||
var firstUpSource = upSourceList[0]; |
|||
/** |
|||
* Intuitively, the end users known the content of the original `dataset.source`, |
|||
* calucating the transform result in mind. |
|||
* Suppose the original `dataset.source` is: |
|||
* ```js
|
|||
* [ |
|||
* ['product', '2012', '2013', '2014', '2015'], |
|||
* ['AAA', 41.1, 30.4, 65.1, 53.3], |
|||
* ['BBB', 86.5, 92.1, 85.7, 83.1], |
|||
* ['CCC', 24.1, 67.2, 79.5, 86.4] |
|||
* ] |
|||
* ``` |
|||
* The dimension info have to be detected from the source data. |
|||
* Some of the transformers (like filter, sort) will follow the dimension info |
|||
* of upstream, while others use new dimensions (like aggregate). |
|||
* Transformer can output a field `dimensions` to define the its own output dimensions. |
|||
* We also allow transformers to ignore the output `dimensions` field, and |
|||
* inherit the upstream dimensions definition. It can reduce the burden of handling |
|||
* dimensions in transformers. |
|||
* |
|||
* See also [DIMENSION_INHERIT_RULE] in `sourceManager.ts`. |
|||
*/ |
|||
|
|||
if (firstUpSource && resultIndex === 0 // If transformer returns `dimensions`, it means that the transformer has different
|
|||
// dimensions definitions. We do not inherit anything from upstream.
|
|||
&& !result.dimensions) { |
|||
var startIndex = firstUpSource.startIndex; // We copy the header of upstream to the result becuase:
|
|||
// (1) The returned data always does not contain header line and can not be used
|
|||
// as dimension-detection. In this case we can not use "detected dimensions" of
|
|||
// upstream directly, because it might be detected based on different `seriesLayoutBy`.
|
|||
// (2) We should support that the series read the upstream source in `seriesLayoutBy: 'row'`.
|
|||
// So the original detected header should be add to the result, otherwise they can not be read.
|
|||
|
|||
if (startIndex) { |
|||
result.data = firstUpSource.data.slice(0, startIndex).concat(result.data); |
|||
} |
|||
|
|||
resultMetaRawOption = { |
|||
seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN, |
|||
sourceHeader: startIndex, |
|||
dimensions: firstUpSource.metaRawOption.dimensions |
|||
}; |
|||
} else { |
|||
resultMetaRawOption = { |
|||
seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN, |
|||
sourceHeader: 0, |
|||
dimensions: result.dimensions |
|||
}; |
|||
} |
|||
|
|||
return createSource(result.data, resultMetaRawOption, null); |
|||
}); |
|||
} |
|||
|
|||
function isSupportedSourceFormat(sourceFormat) { |
|||
return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS || sourceFormat === SOURCE_FORMAT_OBJECT_ROWS; |
|||
} |
|||
@ -0,0 +1,67 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export * from './export/core.js'; |
|||
import { use } from './extension.js'; |
|||
import { init } from './core/echarts.js'; |
|||
import { install as CanvasRenderer } from './renderer/installCanvasRenderer.js'; |
|||
import { install as DatasetComponent } from './component/dataset/install.js'; // Default to have canvas renderer and dataset for compitatble reason.
|
|||
|
|||
use([CanvasRenderer, DatasetComponent]); // TODO: Compatitable with the following code
|
|||
// import echarts from 'echarts/lib/echarts.js'
|
|||
|
|||
export default { |
|||
init: function () { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
/* eslint-disable-next-line */ |
|||
console.error("\"import echarts from 'echarts/lib/echarts.js'\" is not supported anymore. Use \"import * as echarts from 'echarts/lib/echarts.js'\" instead;"); |
|||
} // @ts-ignore
|
|||
|
|||
|
|||
return init.apply(null, arguments); |
|||
} |
|||
}; // Import label layout by default.
|
|||
// TODO remove
|
|||
|
|||
import { installLabelLayout } from './label/installLabelLayout.js'; |
|||
use(installLabelLayout); |
|||
@ -0,0 +1,46 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
// This file is for providing types when import whole module.
|
|||
export * from './core.js'; |
|||
export * from './option.js'; |
|||
@ -0,0 +1,114 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
// These APIs are for more advanced usages
|
|||
// For example extend charts and components, creating graphic elements, formatting.
|
|||
import ComponentModel from '../model/Component.js'; |
|||
import ComponentView from '../view/Component.js'; |
|||
import SeriesModel from '../model/Series.js'; |
|||
import ChartView from '../view/Chart.js'; |
|||
import SeriesData from '../data/SeriesData.js'; |
|||
import * as zrender_1 from 'zrender/lib/zrender.js'; |
|||
export { zrender_1 as zrender }; |
|||
import * as matrix_1 from 'zrender/lib/core/matrix.js'; |
|||
export { matrix_1 as matrix }; |
|||
import * as vector_1 from 'zrender/lib/core/vector.js'; |
|||
export { vector_1 as vector }; |
|||
import * as zrUtil_1 from 'zrender/lib/core/util.js'; |
|||
export { zrUtil_1 as zrUtil }; |
|||
import * as color_1 from 'zrender/lib/tool/color.js'; |
|||
export { color_1 as color }; |
|||
export { throttle } from '../util/throttle.js'; |
|||
import * as helper_1 from './api/helper.js'; |
|||
export { helper_1 as helper }; |
|||
export { use } from '../extension.js'; |
|||
export { setPlatformAPI } from 'zrender/lib/core/platform.js'; //////////////// Helper Methods /////////////////////
|
|||
|
|||
export { default as parseGeoJSON } from '../coord/geo/parseGeoJson.js'; |
|||
export { default as parseGeoJson } from '../coord/geo/parseGeoJson.js'; |
|||
import * as number_1 from './api/number.js'; |
|||
export { number_1 as number }; |
|||
import * as time_1 from './api/time.js'; |
|||
export { time_1 as time }; |
|||
import * as graphic_1 from './api/graphic.js'; |
|||
export { graphic_1 as graphic }; |
|||
import * as format_1 from './api/format.js'; |
|||
export { format_1 as format }; |
|||
import * as util_1 from './api/util.js'; |
|||
export { util_1 as util }; |
|||
export { default as env } from 'zrender/lib/core/env.js'; //////////////// Export for Exension Usage ////////////////
|
|||
// export {SeriesData};
|
|||
|
|||
export { SeriesData as List }; // TODO: Compatitable with exists echarts-gl code
|
|||
|
|||
export { default as Model } from '../model/Model.js'; |
|||
export { default as Axis } from '../coord/Axis.js'; |
|||
export { ComponentModel, ComponentView, SeriesModel, ChartView }; // Only for GL
|
|||
|
|||
export { brushSingle as innerDrawElementOnCanvas } from 'zrender/lib/canvas/graphic.js'; //////////////// Deprecated Extension Methods ////////////////
|
|||
// Should use `ComponentModel.extend` or `class XXXX extend ComponentModel` to create class.
|
|||
// Then use `registerComponentModel` in `install` parameter when `use` this extension. For example:
|
|||
// class Bar3DModel extends ComponentModel {}
|
|||
// export function install(registers) { regsiters.registerComponentModel(Bar3DModel); }
|
|||
// echarts.use(install);
|
|||
|
|||
export function extendComponentModel(proto) { |
|||
var Model = ComponentModel.extend(proto); |
|||
ComponentModel.registerClass(Model); |
|||
return Model; |
|||
} |
|||
export function extendComponentView(proto) { |
|||
var View = ComponentView.extend(proto); |
|||
ComponentView.registerClass(View); |
|||
return View; |
|||
} |
|||
export function extendSeriesModel(proto) { |
|||
var Model = SeriesModel.extend(proto); |
|||
SeriesModel.registerClass(Model); |
|||
return Model; |
|||
} |
|||
export function extendChartView(proto) { |
|||
var View = ChartView.extend(proto); |
|||
ChartView.registerClass(View); |
|||
return View; |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export { addCommas, toCamelCase, normalizeCssArray, encodeHTML, formatTpl, getTooltipMarker, formatTime, capitalFirst, truncateText, getTextRect } from '../../util/format.js'; |
|||
@ -0,0 +1,44 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export { extendShape, extendPath, makePath, makeImage, mergePath, resizePath, createIcon, updateProps, initProps, getTransform, clipPointsByRect, clipRectByRect, registerShape, getShapeClass, Group, Image, Text, Circle, Ellipse, Sector, Ring, Polygon, Polyline, Rect, Line, BezierCurve, Arc, IncrementalDisplayable, CompoundPath, LinearGradient, RadialGradient, BoundingRect } from '../../util/graphic.js'; |
|||
@ -0,0 +1,133 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* This module exposes helper functions for developing extensions. |
|||
*/ |
|||
import * as zrUtil from 'zrender/lib/core/util.js'; |
|||
import createSeriesData from '../../chart/helper/createSeriesData.js'; // import createGraphFromNodeEdge from './chart/helper/createGraphFromNodeEdge.js';
|
|||
|
|||
import * as axisHelper from '../../coord/axisHelper.js'; |
|||
import { AxisModelCommonMixin } from '../../coord/axisModelCommonMixin.js'; |
|||
import Model from '../../model/Model.js'; |
|||
import { getLayoutRect } from '../../util/layout.js'; |
|||
import { enableDataStack, isDimensionStacked, getStackedDimension } from '../../data/helper/dataStackHelper.js'; |
|||
import { getECData } from '../../util/innerStore.js'; |
|||
import { createTextStyle as innerCreateTextStyle } from '../../label/labelStyle.js'; |
|||
/** |
|||
* Create a muti dimension List structure from seriesModel. |
|||
*/ |
|||
|
|||
export function createList(seriesModel) { |
|||
return createSeriesData(null, seriesModel); |
|||
} // export function createGraph(seriesModel) {
|
|||
// let nodes = seriesModel.get('data');
|
|||
// let links = seriesModel.get('links');
|
|||
// return createGraphFromNodeEdge(nodes, links, seriesModel);
|
|||
// }
|
|||
|
|||
export { getLayoutRect }; |
|||
export { createDimensions } from '../../data/helper/createDimensions.js'; |
|||
export var dataStack = { |
|||
isDimensionStacked: isDimensionStacked, |
|||
enableDataStack: enableDataStack, |
|||
getStackedDimension: getStackedDimension |
|||
}; |
|||
/** |
|||
* Create a symbol element with given symbol configuration: shape, x, y, width, height, color |
|||
* @param {string} symbolDesc |
|||
* @param {number} x |
|||
* @param {number} y |
|||
* @param {number} w |
|||
* @param {number} h |
|||
* @param {string} color |
|||
*/ |
|||
|
|||
export { createSymbol } from '../../util/symbol.js'; |
|||
/** |
|||
* Create scale |
|||
* @param {Array.<number>} dataExtent |
|||
* @param {Object|module:echarts/Model} option If `optoin.type` |
|||
* is secified, it can only be `'value'` currently. |
|||
*/ |
|||
|
|||
export function createScale(dataExtent, option) { |
|||
var axisModel = option; |
|||
|
|||
if (!(option instanceof Model)) { |
|||
axisModel = new Model(option); // FIXME
|
|||
// Currently AxisModelCommonMixin has nothing to do with the
|
|||
// the requirements of `axisHelper.createScaleByModel`. For
|
|||
// example the method `getCategories` and `getOrdinalMeta`
|
|||
// are required for `'category'` axis, and ecModel are required
|
|||
// for `'time'` axis. But occationally echarts-gl happened
|
|||
// to only use `'value'` axis.
|
|||
// zrUtil.mixin(axisModel, AxisModelCommonMixin);
|
|||
} |
|||
|
|||
var scale = axisHelper.createScaleByModel(axisModel); |
|||
scale.setExtent(dataExtent[0], dataExtent[1]); |
|||
axisHelper.niceScaleExtent(scale, axisModel); |
|||
return scale; |
|||
} |
|||
/** |
|||
* Mixin common methods to axis model, |
|||
* |
|||
* Inlcude methods |
|||
* `getFormattedLabels() => Array.<string>` |
|||
* `getCategories() => Array.<string>` |
|||
* `getMin(origin: boolean) => number` |
|||
* `getMax(origin: boolean) => number` |
|||
* `getNeedCrossZero() => boolean` |
|||
*/ |
|||
|
|||
export function mixinAxisModelCommonMethods(Model) { |
|||
zrUtil.mixin(Model, AxisModelCommonMixin); |
|||
} |
|||
export { getECData }; |
|||
export { enableHoverEmphasis } from '../../util/states.js'; |
|||
export function createTextStyle(textStyleModel, opts) { |
|||
opts = opts || {}; |
|||
return innerCreateTextStyle(textStyleModel, null, null, opts.state !== 'normal'); |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export { linearMap, round, asc, getPrecision, getPrecisionSafe, getPixelPrecision, getPercentWithPrecision, MAX_SAFE_INTEGER, remRadian, isRadianAroundZero, parseDate, quantity, quantityExponent, nice, quantile, reformIntervals, isNumeric, numericToNumber } from '../../util/number.js'; |
|||
@ -0,0 +1,45 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export { parseDate as parse } from '../../util/number.js'; |
|||
export { format } from '../../util/time.js'; |
|||
@ -0,0 +1,44 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export { map, each, indexOf, inherits, reduce, filter, bind, curry, isArray, isString, isObject, isFunction, extend, defaults, clone, merge } from 'zrender/lib/core/util.js'; |
|||
@ -0,0 +1,70 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
// In somehow. If we export like
|
|||
// export * as LineChart './chart/line/install'
|
|||
// The exported code will be transformed to
|
|||
// import * as LineChart_1 './chart/line/install'; export {LineChart_1 as LineChart};
|
|||
// Treeshaking in webpack will not work even if we configured sideEffects to false in package.json
|
|||
export { install as LineChart } from '../chart/line/install.js'; |
|||
export { install as BarChart } from '../chart/bar/install.js'; |
|||
export { install as PieChart } from '../chart/pie/install.js'; |
|||
export { install as ScatterChart } from '../chart/scatter/install.js'; |
|||
export { install as RadarChart } from '../chart/radar/install.js'; |
|||
export { install as MapChart } from '../chart/map/install.js'; |
|||
export { install as TreeChart } from '../chart/tree/install.js'; |
|||
export { install as TreemapChart } from '../chart/treemap/install.js'; |
|||
export { install as GraphChart } from '../chart/graph/install.js'; |
|||
export { install as GaugeChart } from '../chart/gauge/install.js'; |
|||
export { install as FunnelChart } from '../chart/funnel/install.js'; |
|||
export { install as ParallelChart } from '../chart/parallel/install.js'; |
|||
export { install as SankeyChart } from '../chart/sankey/install.js'; |
|||
export { install as BoxplotChart } from '../chart/boxplot/install.js'; |
|||
export { install as CandlestickChart } from '../chart/candlestick/install.js'; |
|||
export { install as EffectScatterChart } from '../chart/effectScatter/install.js'; |
|||
export { install as LinesChart } from '../chart/lines/install.js'; |
|||
export { install as HeatmapChart } from '../chart/heatmap/install.js'; |
|||
export { install as PictorialBarChart } from '../chart/bar/installPictorialBar.js'; |
|||
export { install as ThemeRiverChart } from '../chart/themeRiver/install.js'; |
|||
export { install as SunburstChart } from '../chart/sunburst/install.js'; |
|||
export { install as CustomChart } from '../chart/custom/install.js'; |
|||
@ -0,0 +1,73 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export { install as GridSimpleComponent } from '../component/grid/installSimple.js'; |
|||
export { install as GridComponent } from '../component/grid/install.js'; |
|||
export { install as PolarComponent } from '../component/polar/install.js'; |
|||
export { install as RadarComponent } from '../component/radar/install.js'; |
|||
export { install as GeoComponent } from '../component/geo/install.js'; |
|||
export { install as SingleAxisComponent } from '../component/singleAxis/install.js'; |
|||
export { install as ParallelComponent } from '../component/parallel/install.js'; |
|||
export { install as CalendarComponent } from '../component/calendar/install.js'; |
|||
export { install as GraphicComponent } from '../component/graphic/install.js'; |
|||
export { install as ToolboxComponent } from '../component/toolbox/install.js'; |
|||
export { install as TooltipComponent } from '../component/tooltip/install.js'; |
|||
export { install as AxisPointerComponent } from '../component/axisPointer/install.js'; |
|||
export { install as BrushComponent } from '../component/brush/install.js'; |
|||
export { install as TitleComponent } from '../component/title/install.js'; |
|||
export { install as TimelineComponent } from '../component/timeline/install.js'; |
|||
export { install as MarkPointComponent } from '../component/marker/installMarkPoint.js'; |
|||
export { install as MarkLineComponent } from '../component/marker/installMarkLine.js'; |
|||
export { install as MarkAreaComponent } from '../component/marker/installMarkArea.js'; |
|||
export { install as LegendComponent } from '../component/legend/install.js'; |
|||
export { install as LegendScrollComponent } from '../component/legend/installLegendScroll.js'; |
|||
export { install as LegendPlainComponent } from '../component/legend/installLegendPlain.js'; |
|||
export { install as DataZoomComponent } from '../component/dataZoom/install.js'; |
|||
export { install as DataZoomInsideComponent } from '../component/dataZoom/installDataZoomInside.js'; |
|||
export { install as DataZoomSliderComponent } from '../component/dataZoom/installDataZoomSlider.js'; |
|||
export { install as VisualMapComponent } from '../component/visualMap/install.js'; |
|||
export { install as VisualMapContinuousComponent } from '../component/visualMap/installVisualMapContinuous.js'; |
|||
export { install as VisualMapPiecewiseComponent } from '../component/visualMap/installVisualMapPiecewise.js'; |
|||
export { install as AriaComponent } from '../component/aria/install.js'; |
|||
export { install as TransformComponent } from '../component/transform/install.js'; |
|||
export { install as DatasetComponent } from '../component/dataset/install.js'; |
|||
@ -0,0 +1,51 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
// Core API from echarts/src/echarts
|
|||
export * from '../core/echarts.js'; |
|||
export * from './api.js'; |
|||
import { use } from '../extension.js'; // Import label layout by default.
|
|||
// TODO will be treeshaked.
|
|||
|
|||
import { installLabelLayout } from '../label/installLabelLayout.js'; |
|||
use(installLabelLayout); |
|||
@ -0,0 +1,46 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
// Module that exports complex but fancy features.
|
|||
export { installUniversalTransition as UniversalTransition } from '../animation/universalTransition.js'; |
|||
export { installLabelLayout as LabelLayout } from '../label/installLabelLayout.js'; |
|||
@ -0,0 +1,44 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export {}; |
|||
@ -0,0 +1,45 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export { install as SVGRenderer } from '../renderer/installSVGRenderer.js'; |
|||
export { install as CanvasRenderer } from '../renderer/installCanvasRenderer.js'; |
|||
@ -0,0 +1,114 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { registerPreprocessor, registerProcessor, registerPostInit, registerPostUpdate, registerAction, registerCoordinateSystem, registerLayout, registerVisual, registerTransform, registerLoading, registerMap, registerUpdateLifecycle, PRIORITY } from './core/echarts.js'; |
|||
import ComponentView from './view/Component.js'; |
|||
import ChartView from './view/Chart.js'; |
|||
import ComponentModel from './model/Component.js'; |
|||
import SeriesModel from './model/Series.js'; |
|||
import { isFunction, indexOf, isArray, each } from 'zrender/lib/core/util.js'; |
|||
import { registerImpl } from './core/impl.js'; |
|||
import { registerPainter } from 'zrender/lib/zrender.js'; |
|||
var extensions = []; |
|||
var extensionRegisters = { |
|||
registerPreprocessor: registerPreprocessor, |
|||
registerProcessor: registerProcessor, |
|||
registerPostInit: registerPostInit, |
|||
registerPostUpdate: registerPostUpdate, |
|||
registerUpdateLifecycle: registerUpdateLifecycle, |
|||
registerAction: registerAction, |
|||
registerCoordinateSystem: registerCoordinateSystem, |
|||
registerLayout: registerLayout, |
|||
registerVisual: registerVisual, |
|||
registerTransform: registerTransform, |
|||
registerLoading: registerLoading, |
|||
registerMap: registerMap, |
|||
registerImpl: registerImpl, |
|||
PRIORITY: PRIORITY, |
|||
ComponentModel: ComponentModel, |
|||
ComponentView: ComponentView, |
|||
SeriesModel: SeriesModel, |
|||
ChartView: ChartView, |
|||
// TODO Use ComponentModel and SeriesModel instead of Constructor
|
|||
registerComponentModel: function (ComponentModelClass) { |
|||
ComponentModel.registerClass(ComponentModelClass); |
|||
}, |
|||
registerComponentView: function (ComponentViewClass) { |
|||
ComponentView.registerClass(ComponentViewClass); |
|||
}, |
|||
registerSeriesModel: function (SeriesModelClass) { |
|||
SeriesModel.registerClass(SeriesModelClass); |
|||
}, |
|||
registerChartView: function (ChartViewClass) { |
|||
ChartView.registerClass(ChartViewClass); |
|||
}, |
|||
registerSubTypeDefaulter: function (componentType, defaulter) { |
|||
ComponentModel.registerSubTypeDefaulter(componentType, defaulter); |
|||
}, |
|||
registerPainter: function (painterType, PainterCtor) { |
|||
registerPainter(painterType, PainterCtor); |
|||
} |
|||
}; |
|||
export function use(ext) { |
|||
if (isArray(ext)) { |
|||
// use([ChartLine, ChartBar]);
|
|||
each(ext, function (singleExt) { |
|||
use(singleExt); |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
if (indexOf(extensions, ext) >= 0) { |
|||
return; |
|||
} |
|||
|
|||
extensions.push(ext); |
|||
|
|||
if (isFunction(ext)) { |
|||
ext = { |
|||
install: ext |
|||
}; |
|||
} |
|||
|
|||
ext.install(extensionRegisters); |
|||
} |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: Czech. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec'], |
|||
monthAbbr: ['Led', 'Úno', 'Bře', 'Dub', 'Kvě', 'Čvn', 'Čvc', 'Srp', 'Zář', 'Říj', 'Lis', 'Pro'], |
|||
dayOfWeek: ['Neděle', 'Pondělí', 'Úterý', 'Středa', 'Čtvrtek', 'Pátek', 'Sobota'], |
|||
dayOfWeekAbbr: ['Ne', 'Po', 'Út', 'St', 'Čt', 'Pá', 'So'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Vše', |
|||
inverse: 'Inv' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Obdélníkový výběr', |
|||
polygon: 'Lasso výběr', |
|||
lineX: 'Horizontální výběr', |
|||
lineY: 'Vertikální výběr', |
|||
keep: 'Ponechat výběr', |
|||
clear: 'Zrušit výběr' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Data', |
|||
lang: ['Data', 'Zavřít', 'Obnovit'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Přiblížit', |
|||
back: 'Oddálit' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Změnit na Spojnicový graf', |
|||
bar: 'Změnit na Sloupcový graf', |
|||
stack: 'Plošný', |
|||
tiled: 'Tile' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Obnovit' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Uložit jako obrázek', |
|||
lang: ['Obrázek uložte pravým kliknutím'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: 'Výsečový graf', |
|||
bar: 'Sloupcový graf', |
|||
line: 'Spojnicový graf', |
|||
scatter: 'XY bodový graf', |
|||
effectScatter: 'Effect XY bodový graf', |
|||
radar: 'Paprskový graf', |
|||
tree: 'Strom', |
|||
treemap: 'Stromová mapa', |
|||
boxplot: 'Krabicový graf', |
|||
candlestick: 'Burzovní graf', |
|||
k: 'K spojnicový graf', |
|||
heatmap: 'Teplotní mapa', |
|||
map: 'Mapa', |
|||
parallel: 'Rovnoběžné souřadnice', |
|||
lines: 'Spojnicový graf', |
|||
graph: 'Graf vztahů', |
|||
sankey: 'Sankeyův diagram', |
|||
funnel: 'Trychtýř (Funnel)', |
|||
gauge: 'Indikátor', |
|||
pictorialBar: 'Obrázkový sloupcový graf', |
|||
themeRiver: 'Theme River Map', |
|||
sunburst: 'Vícevrstvý prstencový graf' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'Toto je graf o "{title}"', |
|||
withoutTitle: 'Toto je graf' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: '{seriesName} s typem {seriesType}.', |
|||
withoutName: ' s typem {seriesType}.' |
|||
}, |
|||
multiple: { |
|||
prefix: '. Obsahuje {seriesCount} řad.', |
|||
withName: ' Řada {seriesId} je typu {seriesType} repreyentující {seriesName}.', |
|||
withoutName: ' Řada {seriesId} je typu {seriesType}.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'Všechna data jsou: ', |
|||
partialData: 'První {displayCnt} položky jsou: ', |
|||
withName: 'data pro {name} jsou {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ', ', |
|||
end: '. ' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: German. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'], |
|||
monthAbbr: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'], |
|||
dayOfWeek: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'], |
|||
dayOfWeekAbbr: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Alle', |
|||
inverse: 'Invertiert' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Box Auswahl', |
|||
polygon: 'Lasso Auswahl', |
|||
lineX: 'Horizontale Auswahl', |
|||
lineY: 'Vertikale Auswahl', |
|||
keep: 'Bereich Auswahl', |
|||
clear: 'Auswahl zurücksetzen' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Daten Ansicht', |
|||
lang: ['Daten Ansicht', 'Schließen', 'Aktualisieren'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Zoom', |
|||
back: 'Zoom zurücksetzen' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Zu Liniendiagramm wechseln', |
|||
bar: 'Zu Balkendiagramm wechseln', |
|||
stack: 'Stapel', |
|||
tiled: 'Kachel' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Wiederherstellen' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Als Bild speichern', |
|||
lang: ['Rechtsklick zum Speichern des Bildes'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: 'Tortendiagramm', |
|||
bar: 'Balkendiagramm', |
|||
line: 'Liniendiagramm', |
|||
scatter: 'Streudiagramm', |
|||
effectScatter: 'Welligkeits-Streudiagramm', |
|||
radar: 'Radar-Karte', |
|||
tree: 'Baum', |
|||
treemap: 'Baumkarte', |
|||
boxplot: 'Boxplot', |
|||
candlestick: 'Kerzenständer', |
|||
k: 'K Liniendiagramm', |
|||
heatmap: 'Heatmap', |
|||
map: 'Karte', |
|||
parallel: 'Parallele Koordinatenkarte', |
|||
lines: 'Liniendiagramm', |
|||
graph: 'Beziehungsgrafik', |
|||
sankey: 'Sankey-Diagramm', |
|||
funnel: 'Trichterdiagramm', |
|||
gauge: 'Meßanzeige', |
|||
pictorialBar: 'Bildlicher Balken', |
|||
themeRiver: 'Thematische Flusskarte', |
|||
sunburst: 'Sonnenausbruch' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'Dies ist ein Diagramm über "{title}"', |
|||
withoutTitle: 'Dies ist ein Diagramm' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: ' mit Typ {seriesType} namens {seriesName}.', |
|||
withoutName: ' mit Typ {seriesType}.' |
|||
}, |
|||
multiple: { |
|||
prefix: '. Es besteht aus {seriesCount} Serienzählung.', |
|||
withName: ' Die Serie {seriesId} ist ein {seriesType} welcher {seriesName} darstellt.', |
|||
withoutName: ' Die {seriesId}-Reihe ist ein {seriesType}.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'Die Daten sind wie folgt: ', |
|||
partialData: 'Die ersten {displayCnt} Elemente sind: ', |
|||
withName: 'die Daten für {name} sind {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ',', |
|||
end: '.' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: English. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], |
|||
monthAbbr: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], |
|||
dayOfWeek: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], |
|||
dayOfWeekAbbr: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'All', |
|||
inverse: 'Inv' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Box Select', |
|||
polygon: 'Lasso Select', |
|||
lineX: 'Horizontally Select', |
|||
lineY: 'Vertically Select', |
|||
keep: 'Keep Selections', |
|||
clear: 'Clear Selections' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Data View', |
|||
lang: ['Data View', 'Close', 'Refresh'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Zoom', |
|||
back: 'Zoom Reset' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Switch to Line Chart', |
|||
bar: 'Switch to Bar Chart', |
|||
stack: 'Stack', |
|||
tiled: 'Tile' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Restore' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Save as Image', |
|||
lang: ['Right Click to Save Image'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: 'Pie chart', |
|||
bar: 'Bar chart', |
|||
line: 'Line chart', |
|||
scatter: 'Scatter plot', |
|||
effectScatter: 'Ripple scatter plot', |
|||
radar: 'Radar chart', |
|||
tree: 'Tree', |
|||
treemap: 'Treemap', |
|||
boxplot: 'Boxplot', |
|||
candlestick: 'Candlestick', |
|||
k: 'K line chart', |
|||
heatmap: 'Heat map', |
|||
map: 'Map', |
|||
parallel: 'Parallel coordinate map', |
|||
lines: 'Line graph', |
|||
graph: 'Relationship graph', |
|||
sankey: 'Sankey diagram', |
|||
funnel: 'Funnel chart', |
|||
gauge: 'Gauge', |
|||
pictorialBar: 'Pictorial bar', |
|||
themeRiver: 'Theme River Map', |
|||
sunburst: 'Sunburst' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'This is a chart about "{title}"', |
|||
withoutTitle: 'This is a chart' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: ' with type {seriesType} named {seriesName}.', |
|||
withoutName: ' with type {seriesType}.' |
|||
}, |
|||
multiple: { |
|||
prefix: '. It consists of {seriesCount} series count.', |
|||
withName: ' The {seriesId} series is a {seriesType} representing {seriesName}.', |
|||
withoutName: ' The {seriesId} series is a {seriesType}.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'The data is as follows: ', |
|||
partialData: 'The first {displayCnt} items are: ', |
|||
withName: 'the data for {name} is {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ', ', |
|||
end: '. ' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,94 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'], |
|||
monthAbbr: ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic'], |
|||
dayOfWeek: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado'], |
|||
dayOfWeekAbbr: ['dom', 'lun', 'mar', 'mie', 'jue', 'vie', 'sáb'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Todas', |
|||
inverse: 'Inversa' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Selección de cuadro', |
|||
polygon: 'Selección de lazo', |
|||
lineX: 'Seleccionar horizontalmente', |
|||
lineY: 'Seleccionar verticalmente', |
|||
keep: 'Mantener selección', |
|||
clear: 'Despejar selecciones' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Ver datos', |
|||
lang: ['Ver datos', 'Cerrar', 'Actualizar'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Zoom', |
|||
back: 'Restablecer zoom' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Cambiar a gráfico de líneas', |
|||
bar: 'Cambiar a gráfico de barras', |
|||
stack: 'Pila', |
|||
tiled: 'Teja' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Restaurar' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Guardar como imagen', |
|||
lang: ['Clic derecho para guardar imagen'] |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,94 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['tammikuuta', 'helmikuuta', 'maaliskuuta', 'huhtikuuta', 'toukokuuta', 'kesäkuuta', 'heinäkuuta', 'elokuuta', 'syyskuuta', 'lokakuuta', 'marraskuuta', 'joulukuuta'], |
|||
monthAbbr: ['tammik', 'helmik', 'maalisk', 'huhtik', 'toukok', 'kesäk', 'heinäk', 'elok', 'syysk', 'lokak', 'marrask', 'jouluk'], |
|||
dayOfWeek: ['sunnuntaina', 'maanantaina', 'tiistaina', 'keskiviikkona', 'torstaina', 'perjantaina', 'lauantaina'], |
|||
dayOfWeekAbbr: ['su', 'ma', 'ti', 'ke', 'to', 'pe', 'la'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Kaikki', |
|||
inverse: 'Käänteinen' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Laatikko valinta', |
|||
polygon: 'Lasso valinta', |
|||
lineX: 'Vaakataso valinta', |
|||
lineY: 'Pysty valinta', |
|||
keep: 'Pidä valinta', |
|||
clear: 'Poista valinta' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Data näkymä', |
|||
lang: ['Data näkymä', 'Sulje', 'Päivitä'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Zoomaa', |
|||
back: 'Zoomin nollaus' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Vaihda Viivakaavioon', |
|||
bar: 'Vaihda palkkikaavioon', |
|||
stack: 'Pinoa', |
|||
tiled: 'Erottele' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Palauta' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Tallenna kuvana', |
|||
lang: ['Paina oikeaa hiirennappia tallentaaksesi kuva'] |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: Français. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'], |
|||
monthAbbr: ['Jan', 'Fév', 'Mars', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sept', 'Oct', 'Nov', 'Déc'], |
|||
dayOfWeek: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'], |
|||
dayOfWeekAbbr: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Tout', |
|||
inverse: 'Inverse' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Sélection rectangulaire', |
|||
polygon: 'Sélection au lasso', |
|||
lineX: 'Sélectionner horizontalement', |
|||
lineY: 'Sélectionner verticalement', |
|||
keep: 'Garder la sélection', |
|||
clear: 'Effacer la sélection' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Visualisation des données', |
|||
lang: ['Visualisation des données', 'Fermer', 'Rafraîchir'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Zoom', |
|||
back: 'Zoom Remise à zéro' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Changer pour Ligne', |
|||
bar: 'Changer pour Histogramme', |
|||
stack: 'Superposition', |
|||
tiled: 'Tuile' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Restaurer' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Sauvegarder l\'image', |
|||
lang: ['Clic droit pour sauvegarder l\'image'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: 'Camembert', |
|||
bar: 'Histogramme', |
|||
line: 'Ligne', |
|||
scatter: 'Nuage de points', |
|||
effectScatter: 'Nuage de points stylisé', |
|||
radar: 'Radar', |
|||
tree: 'Arbre', |
|||
treemap: 'Treemap', |
|||
boxplot: 'Boîte à moustaches', |
|||
candlestick: 'Chandelier', |
|||
k: 'Linéaire K', |
|||
heatmap: 'Carte de fréquentation', |
|||
map: 'Carte', |
|||
parallel: 'Données parallèles', |
|||
lines: 'Lignes', |
|||
graph: 'Graphe', |
|||
sankey: 'Sankey', |
|||
funnel: 'Entonnoir', |
|||
gauge: 'Jauge', |
|||
pictorialBar: 'Barres à images', |
|||
themeRiver: 'Stream Graph', |
|||
sunburst: 'Sunburst' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'Cette carte est intitulée "{title}"', |
|||
withoutTitle: 'C\'est une carte' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: ' Avec le type de {seriesType} qui s\'appelle {seriesName}.', |
|||
withoutName: ' Avec le type de {seriesType}.' |
|||
}, |
|||
multiple: { |
|||
prefix: ' Elle comprend {seriesCount} séries.', |
|||
withName: ' La série {seriesId} représente {seriesName} de {seriesType}.', |
|||
withoutName: ' La série {seriesId} est un/une {seriesType}.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'Les données sont: ', |
|||
partialData: 'Les premiers {displayCnt} éléments sont : ', |
|||
withName: 'Les données pour {name} sont {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ', ', |
|||
end: '. ' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: Italian. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'], |
|||
monthAbbr: ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'], |
|||
dayOfWeek: ['Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato'], |
|||
dayOfWeekAbbr: ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Tutti', |
|||
inverse: 'Inverso' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Selezione rettangolare', |
|||
polygon: 'Selezione lazo', |
|||
lineX: 'Selezione orizzontale', |
|||
lineY: 'Selezione verticale', |
|||
keep: 'Mantieni selezione', |
|||
clear: 'Rimuovi selezione' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Visualizzazione dati', |
|||
lang: ['Visualizzazione dati', 'Chiudi', 'Aggiorna'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Zoom', |
|||
back: 'Resetta zoom' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Passa al grafico a linee', |
|||
bar: 'Passa al grafico a barre', |
|||
stack: 'Pila', |
|||
tiled: 'Piastrella' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Ripristina' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Salva come immagine', |
|||
lang: ['Tasto destro per salvare l\'immagine'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: 'Grafico a torta', |
|||
bar: 'Grafico a barre', |
|||
line: 'Grafico a linee', |
|||
scatter: 'Grafico a dispersione', |
|||
effectScatter: 'Ripple scatter plot', |
|||
radar: 'Grafico radar', |
|||
tree: 'Albero', |
|||
treemap: 'Treemap', |
|||
boxplot: 'Diagramma a scatola e baffi', |
|||
candlestick: 'Candlestick', |
|||
k: 'K line chart', |
|||
heatmap: 'Mappa di calore', |
|||
map: 'Mappa', |
|||
parallel: 'Grafico a coordinate parallele', |
|||
lines: 'Grafico a linee', |
|||
graph: 'Diagramma delle relazioni', |
|||
sankey: 'Diagramma di Sankey', |
|||
funnel: 'Grafico a imbuto', |
|||
gauge: 'Gauge', |
|||
pictorialBar: 'Pictorial bar', |
|||
themeRiver: 'Theme River Map', |
|||
sunburst: 'Radiale' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'Questo è un grafico su "{title}"', |
|||
withoutTitle: 'Questo è un grafico' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: ' con il tipo {seriesType} denominato {seriesName}.', |
|||
withoutName: ' con il tipo {seriesType}.' |
|||
}, |
|||
multiple: { |
|||
prefix: '. È composto da {seriesCount} serie.', |
|||
withName: ' La {seriesId} serie è un {seriesType} denominata {seriesName}.', |
|||
withoutName: ' la {seriesId} serie è un {seriesType}.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'I dati sono come segue: ', |
|||
partialData: 'I primi {displayCnt} elementi sono: ', |
|||
withName: 'il dato per {name} è {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ', ', |
|||
end: '. ' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: Japanese. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'], |
|||
monthAbbr: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], |
|||
dayOfWeek: ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'], |
|||
dayOfWeekAbbr: ['日', '月', '火', '水', '木', '金', '土'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'すべてを選択', |
|||
inverse: '選択範囲を反転' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: '矩形選択', |
|||
polygon: 'なげなわ選択', |
|||
lineX: '横方向に選択', |
|||
lineY: '縦方向に選択', |
|||
keep: '選択範囲を維持', |
|||
clear: '選択範囲をクリア' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'データビュー', |
|||
lang: ['データビュー', '閉じる', 'リロード'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'ズーム', |
|||
back: 'リセット' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: '折れ線に切り替え', |
|||
bar: '棒に切り替え', |
|||
stack: '積み上げに切り替え', |
|||
tiled: 'タイル状に切り替え' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: '復元' |
|||
}, |
|||
saveAsImage: { |
|||
title: '図として保存', |
|||
lang: ['右クリックして図を保存'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: '円グラフ', |
|||
bar: '棒グラフ', |
|||
line: '折れ線グラフ', |
|||
scatter: '散布図', |
|||
effectScatter: 'エフェクト散布図', |
|||
radar: 'レーダーチャート', |
|||
tree: '階層グラフ', |
|||
treemap: 'ツリーマップ', |
|||
boxplot: '箱ひげ図', |
|||
candlestick: 'Kチャート', |
|||
k: 'Kチャート', |
|||
heatmap: 'ヒートマップ', |
|||
map: '地図', |
|||
parallel: 'パラレルチャート', |
|||
lines: 'ラインチャート', |
|||
graph: '相関図', |
|||
sankey: 'サンキーダイアグラム', |
|||
funnel: 'ファネルグラフ', |
|||
gauge: 'ゲージ', |
|||
pictorialBar: '絵入り棒グラフ', |
|||
themeRiver: 'テーマリバー', |
|||
sunburst: 'サンバースト' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'これは「{title}」に関するチャートです。', |
|||
withoutTitle: 'これはチャートで、' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: 'チャートのタイプは{seriesType}で、{seriesName}を示しています。', |
|||
withoutName: 'チャートのタイプは{seriesType}です。' |
|||
}, |
|||
multiple: { |
|||
prefix: '{seriesCount}つのチャートシリーズによって構成されています。', |
|||
withName: '{seriesId}番目のシリーズは{seriesName}を示した{seriesType}で、', |
|||
withoutName: '{seriesId}番目のシリーズは{seriesType}で、', |
|||
separator: { |
|||
middle: ';', |
|||
end: '。' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'データは:', |
|||
partialData: 'その内、{displayCnt}番目までは:', |
|||
withName: '{name}のデータは{value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: '、', |
|||
end: '' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: Korean. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'], |
|||
monthAbbr: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'], |
|||
dayOfWeek: ['일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일'], |
|||
dayOfWeekAbbr: ['일', '월', '화', '수', '목', '금', '토'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: '모두 선택', |
|||
inverse: '선택 범위 반전' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: '사각형 선택', |
|||
polygon: '올가미 선택', |
|||
lineX: '수평 선택', |
|||
lineY: '수직 선택', |
|||
keep: '선택 유지', |
|||
clear: '선택 지우기' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: '날짜 보기', |
|||
lang: ['날짜 보기', '닫기', '새로 고침'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: '확대/축소', |
|||
back: '확대/축소 초기화' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: '꺽은선 그래프로 변경', |
|||
bar: '막대 그래프로 변경', |
|||
stack: '스택', |
|||
tiled: '타일' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: '복구' |
|||
}, |
|||
saveAsImage: { |
|||
title: '이미지로 저장', |
|||
lang: ['이미지를 저장하려면 마우스 오른쪽 버튼을 클릭하세요.'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: '원 그래프', |
|||
bar: '막대 그래프', |
|||
line: '꺽은선 그래프', |
|||
scatter: '산점도', |
|||
effectScatter: '물결 효과 산점도', |
|||
radar: '방사형 그래프', |
|||
tree: '트리', |
|||
treemap: '트리맵', |
|||
boxplot: '상자 수염 그래프', |
|||
candlestick: '캔들스틱 차트', |
|||
k: 'K 라인 차트', |
|||
heatmap: '히트 맵', |
|||
map: '지도', |
|||
parallel: '평행 좌표 맵', |
|||
lines: '선', |
|||
graph: '관계 그래프', |
|||
sankey: '산키 다이어그램', |
|||
funnel: '깔때기형 그래프', |
|||
gauge: '계기', |
|||
pictorialBar: '픽토그램 차트', |
|||
themeRiver: '스트림 그래프', |
|||
sunburst: '선버스트 차트' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: '"{title}"에 대한 차트입니다.', |
|||
withoutTitle: '차트입니다.' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: ' 차트 유형은 {seriesType}이며 {seriesName}을 표시합니다.', |
|||
withoutName: ' 차트 유형은 {seriesType}입니다.' |
|||
}, |
|||
multiple: { |
|||
prefix: '. {seriesCount} 하나의 차트 시리즈로 구성됩니다.', |
|||
withName: ' {seriesId}번째 시리즈는 {seriesName}을 나타내는 {seriesType} representing.', |
|||
withoutName: ' {seriesId}번째 시리즈는 {seriesType}입니다.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: '데이터: ', |
|||
partialData: '첫번째 {displayCnt} 아이템: ', |
|||
withName: '{name}의 데이터는 {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ', ', |
|||
end: '. ' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: Polish |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień'], |
|||
monthAbbr: ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'], |
|||
dayOfWeek: ['Niedziela', 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota'], |
|||
dayOfWeekAbbr: ['Nie', 'Pon', 'Wto', 'Śro', 'Czw', 'Pią', 'Sob'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Wszystko', |
|||
inverse: 'Odwróć' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Zaznaczenie prostokątne', |
|||
polygon: 'Zaznaczanie lasso', |
|||
lineX: 'Zaznaczenie poziome', |
|||
lineY: 'Zaznaczenie pionowe', |
|||
keep: 'Zachowaj zaznaczenie', |
|||
clear: 'Wyczyść zaznaczenie' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Widok danych', |
|||
lang: ['Widok danych', 'Zamknij', 'Odśwież'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Przybliżenie', |
|||
back: 'Resetuj przybliżenie' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Przełącz na wykres liniowy', |
|||
bar: 'Przełącz na wykres słupkowy', |
|||
stack: 'Przełącz na wykres słupkowy skumulowany', |
|||
tiled: 'Przełącz na kafelki' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Przywróć' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Zapisz jako obrazek', |
|||
lang: ['Kliknij prawym klawiszem myszy aby zapisać'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: 'Wykres kołowy', |
|||
bar: 'Wykres słupkowy', |
|||
line: 'Wykres liniowy', |
|||
scatter: 'Wykres punktowy', |
|||
effectScatter: 'Wykres punktowy z efektem falowania', |
|||
radar: 'Wykres radarowy', |
|||
tree: 'Drzewo', |
|||
treemap: 'Mapa drzewa', |
|||
boxplot: 'Wykres pudełkowy', |
|||
candlestick: 'Wykres świecowy', |
|||
k: 'Wykres linii K', |
|||
heatmap: 'Mapa ciepła', |
|||
map: 'Mapa', |
|||
parallel: 'Wykres współrzędnych równoległych', |
|||
lines: 'Diagram linii', |
|||
graph: 'Graf relacji', |
|||
sankey: 'Wykres Sankeya', |
|||
funnel: 'Wykres lejkowy', |
|||
gauge: 'Wykres zegarowy', |
|||
pictorialBar: 'Wykres słupkowy obrazkowy', |
|||
themeRiver: 'Wykres rzeki tematycznej', |
|||
sunburst: 'Wykres hierarchiczny słonecznikowy' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'To jest wykres dotyczący "{title}"', |
|||
withoutTitle: 'To jest wykres' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: ' typu {seriesType} nazwana {seriesName}.', |
|||
withoutName: ' typu {seriesType}.' |
|||
}, |
|||
multiple: { |
|||
prefix: '. Składający się z {seriesCount} serii danych.', |
|||
withName: ' Seria danych {seriesId} jest serią typu {seriesType} przedstawiającą {seriesName}.', |
|||
withoutName: ' Seria danych {seriesId} jest serią typu {seriesType}.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'Dane są następujące: ', |
|||
partialData: 'Pierwszych {displayCnt} elementów to: ', |
|||
withName: 'dane dla {name} to {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ', ', |
|||
end: '. ' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: Portuguese (Brazil). |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'], |
|||
monthAbbr: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'], |
|||
dayOfWeek: ['Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado'], |
|||
dayOfWeekAbbr: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Todas', |
|||
inverse: 'Inv' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Seleção retangular', |
|||
polygon: 'Seleção em laço', |
|||
lineX: 'Selecionar horizontalmente', |
|||
lineY: 'Selecionar verticalmente', |
|||
keep: 'Manter seleções', |
|||
clear: 'Limpar seleções' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Exibição de dados', |
|||
lang: ['Exibição de dados', 'Fechar', 'Atualizar'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Zoom', |
|||
back: 'Restaurar Zoom' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Trocar para gráfico de linhas', |
|||
bar: 'Trocar para gráfico de barras', |
|||
stack: 'Empilhar', |
|||
tiled: 'Tile' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Restore' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Salvar como imagem', |
|||
lang: ['Clique com o botão direito para salvar imagem'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: 'Gráfico de pizza', |
|||
bar: 'Gráfico de barras', |
|||
line: 'Gráfico de linhas', |
|||
scatter: 'Gráfico de dispersão', |
|||
effectScatter: 'Gráfico de dispersão ondulado', |
|||
radar: 'Gráfico radar', |
|||
tree: 'Árvore', |
|||
treemap: 'Treemap', |
|||
boxplot: 'Boxplot', |
|||
candlestick: 'Candlestick', |
|||
k: 'Gráfico K line', |
|||
heatmap: 'Mapa de calor', |
|||
map: 'Mapa', |
|||
parallel: 'Coordenadas paralelas', |
|||
lines: 'Gráfico de linhas', |
|||
graph: 'Relationship graph', |
|||
sankey: 'Gráfico Sankey', |
|||
funnel: 'Gráfico de funil', |
|||
gauge: 'Gauge', |
|||
pictorialBar: 'Pictorial bar', |
|||
themeRiver: 'Theme River Map', |
|||
sunburst: 'Sunburst' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'Este é um gráfico entitulado "{title}"', |
|||
withoutTitle: 'Este é um gráfico' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: ' do tipo {seriesType} nomeada/nomeado como {seriesName}.', |
|||
withoutName: ' do tipo {seriesType}.' |
|||
}, |
|||
multiple: { |
|||
prefix: '. Consiste de {seriesCount} séries.', |
|||
withName: ' A {seriesId} série é um/uma {seriesType} representando {seriesName}.', |
|||
withoutName: ' A {seriesId} series é um/uma {seriesType}.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'Os dados são: ', |
|||
partialData: 'As primeiros {displayCnt} itens são: ', |
|||
withName: 'os dados para {name} são {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ', ', |
|||
end: '. ' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: Romanian. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['ianuarie', 'februarie', 'martie', 'aprilie', 'mai', 'iunie', 'iulie', 'august', 'septembrie', 'octombrie', 'noiembrie', 'decembrie'], |
|||
monthAbbr: ['ian.', 'febr.', 'mart.', 'apr.', 'mai', 'iun.', 'iul.', 'aug.', 'sept.', 'oct.', 'nov.', 'dec.'], |
|||
dayOfWeek: ['Duminică', 'Luni', 'Marți', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă'], |
|||
dayOfWeekAbbr: ['du.', 'lu.', 'ma.', 'mi.', 'jo.', 'vi.', 'sâ.'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Toate', |
|||
inverse: 'Inversează' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Selecție dreptunghiulară', |
|||
polygon: 'Selecție lasso', |
|||
lineX: 'Selecție orizontală', |
|||
lineY: 'Selecție verticală', |
|||
keep: 'Păstrează selecția', |
|||
clear: 'Șterge selecția' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Vizualizarea datelor', |
|||
lang: ['Vizualizarea datelor', 'Închide', 'Reîmprospătează'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Zoom', |
|||
back: 'Resetează zoom' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Comută la diagramă cu linii', |
|||
bar: 'Comută la diagramă cu bare', |
|||
stack: 'Suprapune', |
|||
tiled: 'Alătură' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Resetează' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Salvează ca imagine', |
|||
lang: ['Clic dreapta pentru a salva ca imagine'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: 'Diagramă radială', |
|||
bar: 'Diagramă cu bare', |
|||
line: 'Diagramă cu linii', |
|||
scatter: 'Diagramă de dispersie', |
|||
effectScatter: 'Diagramă de dispersie stilizată', |
|||
radar: 'Diagramă radar', |
|||
tree: 'Arbore', |
|||
treemap: 'Hartă de arbori', |
|||
boxplot: 'Diagramă boxbare', |
|||
candlestick: 'Diagramă bursieră', |
|||
k: 'Diagramă cu linii K', |
|||
heatmap: 'Hartă termografică', |
|||
map: 'Hartă', |
|||
parallel: 'Hartă de coordonate paralele', |
|||
lines: 'Linii', |
|||
graph: 'Graf', |
|||
sankey: 'Diagramă Sankey', |
|||
funnel: 'Diagramă pâlnie', |
|||
gauge: 'Calibru', |
|||
pictorialBar: 'Diagramă cu bare picturale', |
|||
themeRiver: 'Streamgraph', |
|||
sunburst: 'Diagramă rază de soare' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'Aceasta este o diagrmă despre "{title}"', |
|||
withoutTitle: 'Aceasta este o diagramă' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: ' de tipul {seriesType} denumită {seriesName}.', |
|||
withoutName: ' de tipul {seriesType}.' |
|||
}, |
|||
multiple: { |
|||
prefix: '. Este alcătuită din {seriesCount} serii.', |
|||
withName: ' Seria {seriesId} este de tipul {seriesType} și reprezintă {seriesName}.', |
|||
withoutName: ' Seria {seriesId} este de tipul {seriesType}.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'Datele sunt: ', |
|||
partialData: 'Primele {displayCnt} elemente sunt: ', |
|||
withName: 'datele pentru {name} sunt {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ', ', |
|||
end: '. ' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: Russian. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'], |
|||
monthAbbr: ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июн', 'Июл', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'], |
|||
dayOfWeek: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'], |
|||
dayOfWeekAbbr: ['вс', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Всё', |
|||
inverse: 'Обратить' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Выделить область', |
|||
polygon: 'Инструмент «Лассо»', |
|||
lineX: 'Горизонтальное выделение', |
|||
lineY: 'Вертикальное выделение', |
|||
keep: 'Оставить выбранное', |
|||
clear: 'Очистить выбранное' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Данные', |
|||
lang: ['Данные', 'Закрыть', 'Обновить'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Увеличить', |
|||
back: 'Сбросить увеличение' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Переключиться на линейный график', |
|||
bar: 'Переключиться на столбчатую диаграмму', |
|||
stack: 'Стопка', |
|||
tiled: 'Плитка' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Восстановить' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Сохранить картинку', |
|||
lang: ['Правый клик, чтобы сохранить картинку'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: 'Круговая диаграмма', |
|||
bar: 'Столбчатая диаграмма', |
|||
line: 'Линейный график', |
|||
scatter: 'Точечная диаграмма', |
|||
effectScatter: 'Точечная диаграмма с волнами', |
|||
radar: 'Лепестковая диаграмма', |
|||
tree: 'Дерево', |
|||
treemap: 'Плоское дерево', |
|||
boxplot: 'Ящик с усами', |
|||
candlestick: 'Свечной график', |
|||
k: 'График К-линий', |
|||
heatmap: 'Тепловая карта', |
|||
map: 'Карта', |
|||
parallel: 'Диаграмма параллельных координат', |
|||
lines: 'Линейный граф', |
|||
graph: 'Граф отношений', |
|||
sankey: 'Диаграмма Санкей', |
|||
funnel: 'Воронкообразная диаграмма', |
|||
gauge: 'Шкала', |
|||
pictorialBar: 'Столбец-картинка', |
|||
themeRiver: 'Тематическая река', |
|||
sunburst: 'Солнечные лучи' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'Это график, показывающий "{title}"', |
|||
withoutTitle: 'Это график' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: ' с типом {seriesType} и именем {seriesName}.', |
|||
withoutName: ' с типом {seriesType}.' |
|||
}, |
|||
multiple: { |
|||
prefix: '. Он состоит из {seriesCount} серий.', |
|||
withName: ' Серия {seriesId} имеет тип {seriesType} и показывает {seriesName}.', |
|||
withoutName: ' Серия {seriesId} имеет тип {seriesType}.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'Данные таковы: ', |
|||
partialData: 'Первые {displayCnt} элементов: ', |
|||
withName: 'значение для {name} — {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ', ', |
|||
end: '. ' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: Slovenian. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['Januar', 'Februar', 'Marec', 'April', 'Maj', 'Junij', 'Julij', 'Avgust', 'September', 'Oktober', 'November', 'December'], |
|||
monthAbbr: ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Avg', 'Sep', 'Okt', 'Nov', 'Dec'], |
|||
dayOfWeek: ['Nedelja', 'Ponedeljek', 'Torek', 'Sreda', 'Četrtek', 'Petek', 'Sobota'], |
|||
dayOfWeekAbbr: ['Ned', 'Pon', 'Tor', 'Sre', 'Čet', 'Pet', 'Sob'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Vsi', |
|||
inverse: 'Obratno' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Izbor s pravokotnikom', |
|||
polygon: 'Izbor z lasom', |
|||
lineX: 'Vodoravni izbor', |
|||
lineY: 'Navpični izbor', |
|||
keep: 'Ohrani izbor', |
|||
clear: 'Počisti izbor' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Pogled podatkov', |
|||
lang: ['Pogled podatkov', 'Zapri', 'Osveži'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Približaj', |
|||
back: 'Povrni velikost' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Preklopi na črtni grafikon', |
|||
bar: 'Preklopi na stolpčni grafikon', |
|||
stack: 'Naloži', |
|||
tiled: 'Drug ob drugem' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Povrni' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Shrani kot sliko', |
|||
lang: ['Z desnim klikom shrani sliko'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: 'Tortni grafikon', |
|||
bar: 'Stolpčni grafikon', |
|||
line: 'Črtni grafikon', |
|||
scatter: 'Raztreseni grafikon', |
|||
effectScatter: 'Raztreseni grafikon z efektom', |
|||
radar: 'Radarski grafikon', |
|||
tree: 'Drevo', |
|||
treemap: 'Drevesna struktura', |
|||
boxplot: 'Boxplot grafikon', |
|||
candlestick: 'Svečni grafikon', |
|||
k: 'K line grafikon', |
|||
heatmap: 'Toplotni zemljevid', |
|||
map: 'Zemljevid', |
|||
parallel: 'Zemljevid vzporednih koordinat', |
|||
lines: 'Črtni grafikon', |
|||
graph: 'Grafikon razmerij', |
|||
sankey: 'Sankey grafikon', |
|||
funnel: 'Lijakasti grafikon', |
|||
gauge: 'Števec', |
|||
pictorialBar: 'Stolpčni grafikon s podobo', |
|||
themeRiver: 'Tematski rečni grafikon', |
|||
sunburst: 'Večnivojski tortni grafikon' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'To je grafikon z naslovom "{title}"', |
|||
withoutTitle: 'To je grafikon' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: ' tipa {seriesType} imenovan {seriesName}.', |
|||
withoutName: ' tipa {seriesType}.' |
|||
}, |
|||
multiple: { |
|||
prefix: '. Sestavljen iz {seriesCount} nizov.', |
|||
withName: ' Niz {seriesId} je tipa {seriesType} z nazivom {seriesName}.', |
|||
withoutName: ' Niz {seriesId} je tipa {seriesType}.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'Podatki so naslednji: ', |
|||
partialData: 'Prvih {displayCnt} elementov je: ', |
|||
withName: 'podatek za {name} je {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ', ', |
|||
end: '. ' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,94 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'], |
|||
monthAbbr: ['ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.'], |
|||
dayOfWeek: ['วันอาทิตย์', 'วันจันทร์', 'วันอังคาร', 'วันพุธ', 'วันพฤหัสบดี', 'วันศุกร์', 'วันเสาร์'], |
|||
dayOfWeekAbbr: ['อา.', 'จ.', 'อ.', 'พ.', 'พฤ.', 'ศ.', 'ส.'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'ทั้งหมด', |
|||
inverse: 'ผกผัน' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'ตัวเลือกแบบกล่อง', |
|||
polygon: 'ตัวเลือกแบบบ่วงบาศ', |
|||
lineX: 'ตัวเลือกแบบแนวนอน', |
|||
lineY: 'ตัวเลือกแบบแนวตั้ง', |
|||
keep: 'บันทึกตัวเลือก', |
|||
clear: 'ล้างตัวเลือก' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'มุมมองข้อมูล', |
|||
lang: ['มุมมองข้อมูล', 'ปิด', 'รีเฟรช'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'ซูม', |
|||
back: 'ตั้งซูมใหม่' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'สวิตซ์แบบแผนภาพเส้น', |
|||
bar: 'สวิตซ์แบบแผนภาพแท่ง', |
|||
stack: 'กองไว้', |
|||
tiled: 'แยกไว้' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'ตั้งค่าใหม่' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'บันทึกไปยังรูปภาพ', |
|||
lang: ['คลิกขวาเพื่อบันทึกรูปภาพ'] |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,156 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Language: Ukrainian. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['Січень', 'Лютий', 'Березень', 'Квітень', 'Травень', 'Червень', 'Липень', 'Серпень', 'Вересень', 'Жовтень', 'Листопад', 'Грудень'], |
|||
monthAbbr: ['Січ', 'Лют', 'Бер', 'Кві', 'Тра', 'Чер', 'Лип', 'Сер', 'Вер', 'Жов', 'Лис', 'Гру'], |
|||
dayOfWeek: ['Неділя', 'Понеділок', 'Вівторок', 'Середа', 'Четвер', 'П\'ятниця', 'Субота'], |
|||
dayOfWeekAbbr: ['нд', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: 'Все', |
|||
inverse: 'Обернути' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: 'Выділити область', |
|||
polygon: 'Інструмент «Ласо»', |
|||
lineX: 'Горизонтальне виділення', |
|||
lineY: 'Вертикальне виділення', |
|||
keep: 'Залишити обране', |
|||
clear: 'Очистити обране' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: 'Дані', |
|||
lang: ['Дані', 'Закрити', 'Оновити'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: 'Збільшити', |
|||
back: 'Скасувати збільшення' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: 'Переключитися на лінійний графік', |
|||
bar: 'Переключитися на стовпчикову діаграму', |
|||
stack: 'Стопка', |
|||
tiled: 'Плитка' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: 'Відновити' |
|||
}, |
|||
saveAsImage: { |
|||
title: 'Зберегти зображення', |
|||
lang: ['Правий клік, щоб зберегти зображення'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: 'Кругова діаграма', |
|||
bar: 'Стовпчикова діаграма', |
|||
line: 'Лінійний графік', |
|||
scatter: 'Точкова діаграма', |
|||
effectScatter: 'Точкова діаграма з хвилями', |
|||
radar: 'Пелюсткова діаграма', |
|||
tree: 'Дерево', |
|||
treemap: 'Пласке дерево', |
|||
boxplot: 'Ящик з вусами', |
|||
candlestick: 'Свічний графік', |
|||
k: 'Графік К-ліній', |
|||
heatmap: 'Теплова мапа', |
|||
map: 'Мапа', |
|||
parallel: 'Діаграма паралельних координат', |
|||
lines: 'Лінійний граф', |
|||
graph: 'Граф отношений', |
|||
sankey: 'Діаграма Санкей', |
|||
funnel: 'Воронкообразна діаграма', |
|||
gauge: 'Шкала', |
|||
pictorialBar: 'Стовпчик-картинка', |
|||
themeRiver: 'Тематична ріка', |
|||
sunburst: 'Сонячне проміння' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: 'Це графік, що відрображує "{title}"', |
|||
withoutTitle: 'Це графік' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: ' з типом {seriesType} та іменем {seriesName}.', |
|||
withoutName: ' з типом {seriesType}.' |
|||
}, |
|||
multiple: { |
|||
prefix: '. Він складається з {seriesCount} серій.', |
|||
withName: ' Серія {seriesId} має тип {seriesType} та відображає {seriesName}.', |
|||
withoutName: ' Серія {seriesId} має тип {seriesType}.', |
|||
separator: { |
|||
middle: '', |
|||
end: '' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: 'Дані такі: ', |
|||
partialData: 'Перші {displayCnt} елементів: ', |
|||
withName: 'значення для {name} — {value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ', ', |
|||
end: '. ' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,152 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export default { |
|||
time: { |
|||
month: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'], |
|||
monthAbbr: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], |
|||
dayOfWeek: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'], |
|||
dayOfWeekAbbr: ['日', '一', '二', '三', '四', '五', '六'] |
|||
}, |
|||
legend: { |
|||
selector: { |
|||
all: '全选', |
|||
inverse: '反选' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
brush: { |
|||
title: { |
|||
rect: '矩形选择', |
|||
polygon: '圈选', |
|||
lineX: '横向选择', |
|||
lineY: '纵向选择', |
|||
keep: '保持选择', |
|||
clear: '清除选择' |
|||
} |
|||
}, |
|||
dataView: { |
|||
title: '数据视图', |
|||
lang: ['数据视图', '关闭', '刷新'] |
|||
}, |
|||
dataZoom: { |
|||
title: { |
|||
zoom: '区域缩放', |
|||
back: '区域缩放还原' |
|||
} |
|||
}, |
|||
magicType: { |
|||
title: { |
|||
line: '切换为折线图', |
|||
bar: '切换为柱状图', |
|||
stack: '切换为堆叠', |
|||
tiled: '切换为平铺' |
|||
} |
|||
}, |
|||
restore: { |
|||
title: '还原' |
|||
}, |
|||
saveAsImage: { |
|||
title: '保存为图片', |
|||
lang: ['右键另存为图片'] |
|||
} |
|||
}, |
|||
series: { |
|||
typeNames: { |
|||
pie: '饼图', |
|||
bar: '柱状图', |
|||
line: '折线图', |
|||
scatter: '散点图', |
|||
effectScatter: '涟漪散点图', |
|||
radar: '雷达图', |
|||
tree: '树图', |
|||
treemap: '矩形树图', |
|||
boxplot: '箱型图', |
|||
candlestick: 'K线图', |
|||
k: 'K线图', |
|||
heatmap: '热力图', |
|||
map: '地图', |
|||
parallel: '平行坐标图', |
|||
lines: '线图', |
|||
graph: '关系图', |
|||
sankey: '桑基图', |
|||
funnel: '漏斗图', |
|||
gauge: '仪表盘图', |
|||
pictorialBar: '象形柱图', |
|||
themeRiver: '主题河流图', |
|||
sunburst: '旭日图' |
|||
} |
|||
}, |
|||
aria: { |
|||
general: { |
|||
withTitle: '这是一个关于“{title}”的图表。', |
|||
withoutTitle: '这是一个图表,' |
|||
}, |
|||
series: { |
|||
single: { |
|||
prefix: '', |
|||
withName: '图表类型是{seriesType},表示{seriesName}。', |
|||
withoutName: '图表类型是{seriesType}。' |
|||
}, |
|||
multiple: { |
|||
prefix: '它由{seriesCount}个图表系列组成。', |
|||
withName: '第{seriesId}个系列是一个表示{seriesName}的{seriesType},', |
|||
withoutName: '第{seriesId}个系列是一个{seriesType},', |
|||
separator: { |
|||
middle: ';', |
|||
end: '。' |
|||
} |
|||
} |
|||
}, |
|||
data: { |
|||
allData: '其数据是——', |
|||
partialData: '其中,前{displayCnt}项是——', |
|||
withName: '{name}的数据是{value}', |
|||
withoutName: '{value}', |
|||
separator: { |
|||
middle: ',', |
|||
end: '' |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
@ -0,0 +1,494 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
// TODO: move labels out of viewport.
|
|||
import { BoundingRect, updateProps, initProps, isElementRemoved } from '../util/graphic.js'; |
|||
import { getECData } from '../util/innerStore.js'; |
|||
import { parsePercent } from '../util/number.js'; |
|||
import Transformable from 'zrender/lib/core/Transformable.js'; |
|||
import { updateLabelLinePoints, setLabelLineStyle, getLabelLineStatesModels } from './labelGuideHelper.js'; |
|||
import { makeInner } from '../util/model.js'; |
|||
import { retrieve2, each, keys, isFunction, filter, indexOf } from 'zrender/lib/core/util.js'; |
|||
import { prepareLayoutList, hideOverlap, shiftLayoutOnX, shiftLayoutOnY } from './labelLayoutHelper.js'; |
|||
import { labelInner, animateLabelValue } from './labelStyle.js'; |
|||
|
|||
function cloneArr(points) { |
|||
if (points) { |
|||
var newPoints = []; |
|||
|
|||
for (var i = 0; i < points.length; i++) { |
|||
newPoints.push(points[i].slice()); |
|||
} |
|||
|
|||
return newPoints; |
|||
} |
|||
} |
|||
|
|||
function prepareLayoutCallbackParams(labelItem, hostEl) { |
|||
var label = labelItem.label; |
|||
var labelLine = hostEl && hostEl.getTextGuideLine(); |
|||
return { |
|||
dataIndex: labelItem.dataIndex, |
|||
dataType: labelItem.dataType, |
|||
seriesIndex: labelItem.seriesModel.seriesIndex, |
|||
text: labelItem.label.style.text, |
|||
rect: labelItem.hostRect, |
|||
labelRect: labelItem.rect, |
|||
// x: labelAttr.x,
|
|||
// y: labelAttr.y,
|
|||
align: label.style.align, |
|||
verticalAlign: label.style.verticalAlign, |
|||
labelLinePoints: cloneArr(labelLine && labelLine.shape.points) |
|||
}; |
|||
} |
|||
|
|||
var LABEL_OPTION_TO_STYLE_KEYS = ['align', 'verticalAlign', 'width', 'height', 'fontSize']; |
|||
var dummyTransformable = new Transformable(); |
|||
var labelLayoutInnerStore = makeInner(); |
|||
var labelLineAnimationStore = makeInner(); |
|||
|
|||
function extendWithKeys(target, source, keys) { |
|||
for (var i = 0; i < keys.length; i++) { |
|||
var key = keys[i]; |
|||
|
|||
if (source[key] != null) { |
|||
target[key] = source[key]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
var LABEL_LAYOUT_PROPS = ['x', 'y', 'rotation']; |
|||
|
|||
var LabelManager = |
|||
/** @class */ |
|||
function () { |
|||
function LabelManager() { |
|||
this._labelList = []; |
|||
this._chartViewList = []; |
|||
} |
|||
|
|||
LabelManager.prototype.clearLabels = function () { |
|||
this._labelList = []; |
|||
this._chartViewList = []; |
|||
}; |
|||
/** |
|||
* Add label to manager |
|||
*/ |
|||
|
|||
|
|||
LabelManager.prototype._addLabel = function (dataIndex, dataType, seriesModel, label, layoutOption) { |
|||
var labelStyle = label.style; |
|||
var hostEl = label.__hostTarget; |
|||
var textConfig = hostEl.textConfig || {}; // TODO: If label is in other state.
|
|||
|
|||
var labelTransform = label.getComputedTransform(); |
|||
var labelRect = label.getBoundingRect().plain(); |
|||
BoundingRect.applyTransform(labelRect, labelRect, labelTransform); |
|||
|
|||
if (labelTransform) { |
|||
dummyTransformable.setLocalTransform(labelTransform); |
|||
} else { |
|||
// Identity transform.
|
|||
dummyTransformable.x = dummyTransformable.y = dummyTransformable.rotation = dummyTransformable.originX = dummyTransformable.originY = 0; |
|||
dummyTransformable.scaleX = dummyTransformable.scaleY = 1; |
|||
} |
|||
|
|||
var host = label.__hostTarget; |
|||
var hostRect; |
|||
|
|||
if (host) { |
|||
hostRect = host.getBoundingRect().plain(); |
|||
var transform = host.getComputedTransform(); |
|||
BoundingRect.applyTransform(hostRect, hostRect, transform); |
|||
} |
|||
|
|||
var labelGuide = hostRect && host.getTextGuideLine(); |
|||
|
|||
this._labelList.push({ |
|||
label: label, |
|||
labelLine: labelGuide, |
|||
seriesModel: seriesModel, |
|||
dataIndex: dataIndex, |
|||
dataType: dataType, |
|||
layoutOption: layoutOption, |
|||
computedLayoutOption: null, |
|||
rect: labelRect, |
|||
hostRect: hostRect, |
|||
// Label with lower priority will be hidden when overlapped
|
|||
// Use rect size as default priority
|
|||
priority: hostRect ? hostRect.width * hostRect.height : 0, |
|||
// Save default label attributes.
|
|||
// For restore if developers want get back to default value in callback.
|
|||
defaultAttr: { |
|||
ignore: label.ignore, |
|||
labelGuideIgnore: labelGuide && labelGuide.ignore, |
|||
x: dummyTransformable.x, |
|||
y: dummyTransformable.y, |
|||
scaleX: dummyTransformable.scaleX, |
|||
scaleY: dummyTransformable.scaleY, |
|||
rotation: dummyTransformable.rotation, |
|||
style: { |
|||
x: labelStyle.x, |
|||
y: labelStyle.y, |
|||
align: labelStyle.align, |
|||
verticalAlign: labelStyle.verticalAlign, |
|||
width: labelStyle.width, |
|||
height: labelStyle.height, |
|||
fontSize: labelStyle.fontSize |
|||
}, |
|||
cursor: label.cursor, |
|||
attachedPos: textConfig.position, |
|||
attachedRot: textConfig.rotation |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
LabelManager.prototype.addLabelsOfSeries = function (chartView) { |
|||
var _this = this; |
|||
|
|||
this._chartViewList.push(chartView); |
|||
|
|||
var seriesModel = chartView.__model; |
|||
var layoutOption = seriesModel.get('labelLayout'); |
|||
/** |
|||
* Ignore layouting if it's not specified anything. |
|||
*/ |
|||
|
|||
if (!(isFunction(layoutOption) || keys(layoutOption).length)) { |
|||
return; |
|||
} |
|||
|
|||
chartView.group.traverse(function (child) { |
|||
if (child.ignore) { |
|||
return true; // Stop traverse descendants.
|
|||
} // Only support label being hosted on graphic elements.
|
|||
|
|||
|
|||
var textEl = child.getTextContent(); |
|||
var ecData = getECData(child); // Can only attach the text on the element with dataIndex
|
|||
|
|||
if (textEl && !textEl.disableLabelLayout) { |
|||
_this._addLabel(ecData.dataIndex, ecData.dataType, seriesModel, textEl, layoutOption); |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
LabelManager.prototype.updateLayoutConfig = function (api) { |
|||
var width = api.getWidth(); |
|||
var height = api.getHeight(); |
|||
|
|||
function createDragHandler(el, labelLineModel) { |
|||
return function () { |
|||
updateLabelLinePoints(el, labelLineModel); |
|||
}; |
|||
} |
|||
|
|||
for (var i = 0; i < this._labelList.length; i++) { |
|||
var labelItem = this._labelList[i]; |
|||
var label = labelItem.label; |
|||
var hostEl = label.__hostTarget; |
|||
var defaultLabelAttr = labelItem.defaultAttr; |
|||
var layoutOption = void 0; // TODO A global layout option?
|
|||
|
|||
if (isFunction(labelItem.layoutOption)) { |
|||
layoutOption = labelItem.layoutOption(prepareLayoutCallbackParams(labelItem, hostEl)); |
|||
} else { |
|||
layoutOption = labelItem.layoutOption; |
|||
} |
|||
|
|||
layoutOption = layoutOption || {}; |
|||
labelItem.computedLayoutOption = layoutOption; |
|||
var degreeToRadian = Math.PI / 180; // TODO hostEl should always exists.
|
|||
// Or label should not have parent because the x, y is all in global space.
|
|||
|
|||
if (hostEl) { |
|||
hostEl.setTextConfig({ |
|||
// Force to set local false.
|
|||
local: false, |
|||
// Ignore position and rotation config on the host el if x or y is changed.
|
|||
position: layoutOption.x != null || layoutOption.y != null ? null : defaultLabelAttr.attachedPos, |
|||
// Ignore rotation config on the host el if rotation is changed.
|
|||
rotation: layoutOption.rotate != null ? layoutOption.rotate * degreeToRadian : defaultLabelAttr.attachedRot, |
|||
offset: [layoutOption.dx || 0, layoutOption.dy || 0] |
|||
}); |
|||
} |
|||
|
|||
var needsUpdateLabelLine = false; |
|||
|
|||
if (layoutOption.x != null) { |
|||
// TODO width of chart view.
|
|||
label.x = parsePercent(layoutOption.x, width); |
|||
label.setStyle('x', 0); // Ignore movement in style. TODO: origin.
|
|||
|
|||
needsUpdateLabelLine = true; |
|||
} else { |
|||
label.x = defaultLabelAttr.x; |
|||
label.setStyle('x', defaultLabelAttr.style.x); |
|||
} |
|||
|
|||
if (layoutOption.y != null) { |
|||
// TODO height of chart view.
|
|||
label.y = parsePercent(layoutOption.y, height); |
|||
label.setStyle('y', 0); // Ignore movement in style.
|
|||
|
|||
needsUpdateLabelLine = true; |
|||
} else { |
|||
label.y = defaultLabelAttr.y; |
|||
label.setStyle('y', defaultLabelAttr.style.y); |
|||
} |
|||
|
|||
if (layoutOption.labelLinePoints) { |
|||
var guideLine = hostEl.getTextGuideLine(); |
|||
|
|||
if (guideLine) { |
|||
guideLine.setShape({ |
|||
points: layoutOption.labelLinePoints |
|||
}); // Not update
|
|||
|
|||
needsUpdateLabelLine = false; |
|||
} |
|||
} |
|||
|
|||
var labelLayoutStore = labelLayoutInnerStore(label); |
|||
labelLayoutStore.needsUpdateLabelLine = needsUpdateLabelLine; |
|||
label.rotation = layoutOption.rotate != null ? layoutOption.rotate * degreeToRadian : defaultLabelAttr.rotation; |
|||
label.scaleX = defaultLabelAttr.scaleX; |
|||
label.scaleY = defaultLabelAttr.scaleY; |
|||
|
|||
for (var k = 0; k < LABEL_OPTION_TO_STYLE_KEYS.length; k++) { |
|||
var key = LABEL_OPTION_TO_STYLE_KEYS[k]; |
|||
label.setStyle(key, layoutOption[key] != null ? layoutOption[key] : defaultLabelAttr.style[key]); |
|||
} |
|||
|
|||
if (layoutOption.draggable) { |
|||
label.draggable = true; |
|||
label.cursor = 'move'; |
|||
|
|||
if (hostEl) { |
|||
var hostModel = labelItem.seriesModel; |
|||
|
|||
if (labelItem.dataIndex != null) { |
|||
var data = labelItem.seriesModel.getData(labelItem.dataType); |
|||
hostModel = data.getItemModel(labelItem.dataIndex); |
|||
} |
|||
|
|||
label.on('drag', createDragHandler(hostEl, hostModel.getModel('labelLine'))); |
|||
} |
|||
} else { |
|||
// TODO Other drag functions?
|
|||
label.off('drag'); |
|||
label.cursor = defaultLabelAttr.cursor; |
|||
} |
|||
} |
|||
}; |
|||
|
|||
LabelManager.prototype.layout = function (api) { |
|||
var width = api.getWidth(); |
|||
var height = api.getHeight(); |
|||
var labelList = prepareLayoutList(this._labelList); |
|||
var labelsNeedsAdjustOnX = filter(labelList, function (item) { |
|||
return item.layoutOption.moveOverlap === 'shiftX'; |
|||
}); |
|||
var labelsNeedsAdjustOnY = filter(labelList, function (item) { |
|||
return item.layoutOption.moveOverlap === 'shiftY'; |
|||
}); |
|||
shiftLayoutOnX(labelsNeedsAdjustOnX, 0, width); |
|||
shiftLayoutOnY(labelsNeedsAdjustOnY, 0, height); |
|||
var labelsNeedsHideOverlap = filter(labelList, function (item) { |
|||
return item.layoutOption.hideOverlap; |
|||
}); |
|||
hideOverlap(labelsNeedsHideOverlap); |
|||
}; |
|||
/** |
|||
* Process all labels. Not only labels with layoutOption. |
|||
*/ |
|||
|
|||
|
|||
LabelManager.prototype.processLabelsOverall = function () { |
|||
var _this = this; |
|||
|
|||
each(this._chartViewList, function (chartView) { |
|||
var seriesModel = chartView.__model; |
|||
var ignoreLabelLineUpdate = chartView.ignoreLabelLineUpdate; |
|||
var animationEnabled = seriesModel.isAnimationEnabled(); |
|||
chartView.group.traverse(function (child) { |
|||
if (child.ignore && !child.forceLabelAnimation) { |
|||
return true; // Stop traverse descendants.
|
|||
} |
|||
|
|||
var needsUpdateLabelLine = !ignoreLabelLineUpdate; |
|||
var label = child.getTextContent(); |
|||
|
|||
if (!needsUpdateLabelLine && label) { |
|||
needsUpdateLabelLine = labelLayoutInnerStore(label).needsUpdateLabelLine; |
|||
} |
|||
|
|||
if (needsUpdateLabelLine) { |
|||
_this._updateLabelLine(child, seriesModel); |
|||
} |
|||
|
|||
if (animationEnabled) { |
|||
_this._animateLabels(child, seriesModel); |
|||
} |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
LabelManager.prototype._updateLabelLine = function (el, seriesModel) { |
|||
// Only support label being hosted on graphic elements.
|
|||
var textEl = el.getTextContent(); // Update label line style.
|
|||
|
|||
var ecData = getECData(el); |
|||
var dataIndex = ecData.dataIndex; // Only support labelLine on the labels represent data.
|
|||
|
|||
if (textEl && dataIndex != null) { |
|||
var data = seriesModel.getData(ecData.dataType); |
|||
var itemModel = data.getItemModel(dataIndex); |
|||
var defaultStyle = {}; |
|||
var visualStyle = data.getItemVisual(dataIndex, 'style'); |
|||
var visualType = data.getVisual('drawType'); // Default to be same with main color
|
|||
|
|||
defaultStyle.stroke = visualStyle[visualType]; |
|||
var labelLineModel = itemModel.getModel('labelLine'); |
|||
setLabelLineStyle(el, getLabelLineStatesModels(itemModel), defaultStyle); |
|||
updateLabelLinePoints(el, labelLineModel); |
|||
} |
|||
}; |
|||
|
|||
LabelManager.prototype._animateLabels = function (el, seriesModel) { |
|||
var textEl = el.getTextContent(); |
|||
var guideLine = el.getTextGuideLine(); // Animate
|
|||
|
|||
if (textEl // `forceLabelAnimation` has the highest priority
|
|||
&& (el.forceLabelAnimation || !textEl.ignore && !textEl.invisible && !el.disableLabelAnimation && !isElementRemoved(el))) { |
|||
var layoutStore = labelLayoutInnerStore(textEl); |
|||
var oldLayout = layoutStore.oldLayout; |
|||
var ecData = getECData(el); |
|||
var dataIndex = ecData.dataIndex; |
|||
var newProps = { |
|||
x: textEl.x, |
|||
y: textEl.y, |
|||
rotation: textEl.rotation |
|||
}; |
|||
var data = seriesModel.getData(ecData.dataType); |
|||
|
|||
if (!oldLayout) { |
|||
textEl.attr(newProps); // Disable fade in animation if value animation is enabled.
|
|||
|
|||
if (!labelInner(textEl).valueAnimation) { |
|||
var oldOpacity = retrieve2(textEl.style.opacity, 1); // Fade in animation
|
|||
|
|||
textEl.style.opacity = 0; |
|||
initProps(textEl, { |
|||
style: { |
|||
opacity: oldOpacity |
|||
} |
|||
}, seriesModel, dataIndex); |
|||
} |
|||
} else { |
|||
textEl.attr(oldLayout); // Make sure the animation from is in the right status.
|
|||
|
|||
var prevStates = el.prevStates; |
|||
|
|||
if (prevStates) { |
|||
if (indexOf(prevStates, 'select') >= 0) { |
|||
textEl.attr(layoutStore.oldLayoutSelect); |
|||
} |
|||
|
|||
if (indexOf(prevStates, 'emphasis') >= 0) { |
|||
textEl.attr(layoutStore.oldLayoutEmphasis); |
|||
} |
|||
} |
|||
|
|||
updateProps(textEl, newProps, seriesModel, dataIndex); |
|||
} |
|||
|
|||
layoutStore.oldLayout = newProps; |
|||
|
|||
if (textEl.states.select) { |
|||
var layoutSelect = layoutStore.oldLayoutSelect = {}; |
|||
extendWithKeys(layoutSelect, newProps, LABEL_LAYOUT_PROPS); |
|||
extendWithKeys(layoutSelect, textEl.states.select, LABEL_LAYOUT_PROPS); |
|||
} |
|||
|
|||
if (textEl.states.emphasis) { |
|||
var layoutEmphasis = layoutStore.oldLayoutEmphasis = {}; |
|||
extendWithKeys(layoutEmphasis, newProps, LABEL_LAYOUT_PROPS); |
|||
extendWithKeys(layoutEmphasis, textEl.states.emphasis, LABEL_LAYOUT_PROPS); |
|||
} |
|||
|
|||
animateLabelValue(textEl, dataIndex, data, seriesModel, seriesModel); |
|||
} |
|||
|
|||
if (guideLine && !guideLine.ignore && !guideLine.invisible) { |
|||
var layoutStore = labelLineAnimationStore(guideLine); |
|||
var oldLayout = layoutStore.oldLayout; |
|||
var newLayout = { |
|||
points: guideLine.shape.points |
|||
}; |
|||
|
|||
if (!oldLayout) { |
|||
guideLine.setShape(newLayout); |
|||
guideLine.style.strokePercent = 0; |
|||
initProps(guideLine, { |
|||
style: { |
|||
strokePercent: 1 |
|||
} |
|||
}, seriesModel); |
|||
} else { |
|||
guideLine.attr({ |
|||
shape: oldLayout |
|||
}); |
|||
updateProps(guideLine, { |
|||
shape: newLayout |
|||
}, seriesModel); |
|||
} |
|||
|
|||
layoutStore.oldLayout = newLayout; |
|||
} |
|||
}; |
|||
|
|||
return LabelManager; |
|||
}(); |
|||
|
|||
export default LabelManager; |
|||
@ -0,0 +1,67 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { makeInner } from '../util/model.js'; |
|||
import LabelManager from './LabelManager.js'; |
|||
var getLabelManager = makeInner(); |
|||
export function installLabelLayout(registers) { |
|||
registers.registerUpdateLifecycle('series:beforeupdate', function (ecModel, api, params) { |
|||
// TODO api provide an namespace that can save stuff per instance
|
|||
var labelManager = getLabelManager(api).labelManager; |
|||
|
|||
if (!labelManager) { |
|||
labelManager = getLabelManager(api).labelManager = new LabelManager(); |
|||
} |
|||
|
|||
labelManager.clearLabels(); |
|||
}); |
|||
registers.registerUpdateLifecycle('series:layoutlabels', function (ecModel, api, params) { |
|||
var labelManager = getLabelManager(api).labelManager; |
|||
params.updatedSeries.forEach(function (series) { |
|||
labelManager.addLabelsOfSeries(api.getViewOfSeriesModel(series)); |
|||
}); |
|||
labelManager.updateLayoutConfig(api); |
|||
labelManager.layout(api); |
|||
labelManager.processLabelsOverall(); |
|||
}); |
|||
} |
|||
@ -0,0 +1,627 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { Point, Path, Polyline } from '../util/graphic.js'; |
|||
import PathProxy from 'zrender/lib/core/PathProxy.js'; |
|||
import { normalizeRadian } from 'zrender/lib/contain/util.js'; |
|||
import { cubicProjectPoint, quadraticProjectPoint } from 'zrender/lib/core/curve.js'; |
|||
import { defaults, retrieve2 } from 'zrender/lib/core/util.js'; |
|||
import { invert } from 'zrender/lib/core/matrix.js'; |
|||
import * as vector from 'zrender/lib/core/vector.js'; |
|||
import { DISPLAY_STATES, SPECIAL_STATES } from '../util/states.js'; |
|||
var PI2 = Math.PI * 2; |
|||
var CMD = PathProxy.CMD; |
|||
var DEFAULT_SEARCH_SPACE = ['top', 'right', 'bottom', 'left']; |
|||
|
|||
function getCandidateAnchor(pos, distance, rect, outPt, outDir) { |
|||
var width = rect.width; |
|||
var height = rect.height; |
|||
|
|||
switch (pos) { |
|||
case 'top': |
|||
outPt.set(rect.x + width / 2, rect.y - distance); |
|||
outDir.set(0, -1); |
|||
break; |
|||
|
|||
case 'bottom': |
|||
outPt.set(rect.x + width / 2, rect.y + height + distance); |
|||
outDir.set(0, 1); |
|||
break; |
|||
|
|||
case 'left': |
|||
outPt.set(rect.x - distance, rect.y + height / 2); |
|||
outDir.set(-1, 0); |
|||
break; |
|||
|
|||
case 'right': |
|||
outPt.set(rect.x + width + distance, rect.y + height / 2); |
|||
outDir.set(1, 0); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
function projectPointToArc(cx, cy, r, startAngle, endAngle, anticlockwise, x, y, out) { |
|||
x -= cx; |
|||
y -= cy; |
|||
var d = Math.sqrt(x * x + y * y); |
|||
x /= d; |
|||
y /= d; // Intersect point.
|
|||
|
|||
var ox = x * r + cx; |
|||
var oy = y * r + cy; |
|||
|
|||
if (Math.abs(startAngle - endAngle) % PI2 < 1e-4) { |
|||
// Is a circle
|
|||
out[0] = ox; |
|||
out[1] = oy; |
|||
return d - r; |
|||
} |
|||
|
|||
if (anticlockwise) { |
|||
var tmp = startAngle; |
|||
startAngle = normalizeRadian(endAngle); |
|||
endAngle = normalizeRadian(tmp); |
|||
} else { |
|||
startAngle = normalizeRadian(startAngle); |
|||
endAngle = normalizeRadian(endAngle); |
|||
} |
|||
|
|||
if (startAngle > endAngle) { |
|||
endAngle += PI2; |
|||
} |
|||
|
|||
var angle = Math.atan2(y, x); |
|||
|
|||
if (angle < 0) { |
|||
angle += PI2; |
|||
} |
|||
|
|||
if (angle >= startAngle && angle <= endAngle || angle + PI2 >= startAngle && angle + PI2 <= endAngle) { |
|||
// Project point is on the arc.
|
|||
out[0] = ox; |
|||
out[1] = oy; |
|||
return d - r; |
|||
} |
|||
|
|||
var x1 = r * Math.cos(startAngle) + cx; |
|||
var y1 = r * Math.sin(startAngle) + cy; |
|||
var x2 = r * Math.cos(endAngle) + cx; |
|||
var y2 = r * Math.sin(endAngle) + cy; |
|||
var d1 = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y); |
|||
var d2 = (x2 - x) * (x2 - x) + (y2 - y) * (y2 - y); |
|||
|
|||
if (d1 < d2) { |
|||
out[0] = x1; |
|||
out[1] = y1; |
|||
return Math.sqrt(d1); |
|||
} else { |
|||
out[0] = x2; |
|||
out[1] = y2; |
|||
return Math.sqrt(d2); |
|||
} |
|||
} |
|||
|
|||
function projectPointToLine(x1, y1, x2, y2, x, y, out, limitToEnds) { |
|||
var dx = x - x1; |
|||
var dy = y - y1; |
|||
var dx1 = x2 - x1; |
|||
var dy1 = y2 - y1; |
|||
var lineLen = Math.sqrt(dx1 * dx1 + dy1 * dy1); |
|||
dx1 /= lineLen; |
|||
dy1 /= lineLen; // dot product
|
|||
|
|||
var projectedLen = dx * dx1 + dy * dy1; |
|||
var t = projectedLen / lineLen; |
|||
|
|||
if (limitToEnds) { |
|||
t = Math.min(Math.max(t, 0), 1); |
|||
} |
|||
|
|||
t *= lineLen; |
|||
var ox = out[0] = x1 + t * dx1; |
|||
var oy = out[1] = y1 + t * dy1; |
|||
return Math.sqrt((ox - x) * (ox - x) + (oy - y) * (oy - y)); |
|||
} |
|||
|
|||
function projectPointToRect(x1, y1, width, height, x, y, out) { |
|||
if (width < 0) { |
|||
x1 = x1 + width; |
|||
width = -width; |
|||
} |
|||
|
|||
if (height < 0) { |
|||
y1 = y1 + height; |
|||
height = -height; |
|||
} |
|||
|
|||
var x2 = x1 + width; |
|||
var y2 = y1 + height; |
|||
var ox = out[0] = Math.min(Math.max(x, x1), x2); |
|||
var oy = out[1] = Math.min(Math.max(y, y1), y2); |
|||
return Math.sqrt((ox - x) * (ox - x) + (oy - y) * (oy - y)); |
|||
} |
|||
|
|||
var tmpPt = []; |
|||
|
|||
function nearestPointOnRect(pt, rect, out) { |
|||
var dist = projectPointToRect(rect.x, rect.y, rect.width, rect.height, pt.x, pt.y, tmpPt); |
|||
out.set(tmpPt[0], tmpPt[1]); |
|||
return dist; |
|||
} |
|||
/** |
|||
* Calculate min distance corresponding point. |
|||
* This method won't evaluate if point is in the path. |
|||
*/ |
|||
|
|||
|
|||
function nearestPointOnPath(pt, path, out) { |
|||
var xi = 0; |
|||
var yi = 0; |
|||
var x0 = 0; |
|||
var y0 = 0; |
|||
var x1; |
|||
var y1; |
|||
var minDist = Infinity; |
|||
var data = path.data; |
|||
var x = pt.x; |
|||
var y = pt.y; |
|||
|
|||
for (var i = 0; i < data.length;) { |
|||
var cmd = data[i++]; |
|||
|
|||
if (i === 1) { |
|||
xi = data[i]; |
|||
yi = data[i + 1]; |
|||
x0 = xi; |
|||
y0 = yi; |
|||
} |
|||
|
|||
var d = minDist; |
|||
|
|||
switch (cmd) { |
|||
case CMD.M: |
|||
// moveTo 命令重新创建一个新的 subpath, 并且更新新的起点
|
|||
// 在 closePath 的时候使用
|
|||
x0 = data[i++]; |
|||
y0 = data[i++]; |
|||
xi = x0; |
|||
yi = y0; |
|||
break; |
|||
|
|||
case CMD.L: |
|||
d = projectPointToLine(xi, yi, data[i], data[i + 1], x, y, tmpPt, true); |
|||
xi = data[i++]; |
|||
yi = data[i++]; |
|||
break; |
|||
|
|||
case CMD.C: |
|||
d = cubicProjectPoint(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], x, y, tmpPt); |
|||
xi = data[i++]; |
|||
yi = data[i++]; |
|||
break; |
|||
|
|||
case CMD.Q: |
|||
d = quadraticProjectPoint(xi, yi, data[i++], data[i++], data[i], data[i + 1], x, y, tmpPt); |
|||
xi = data[i++]; |
|||
yi = data[i++]; |
|||
break; |
|||
|
|||
case CMD.A: |
|||
// TODO Arc 判断的开销比较大
|
|||
var cx = data[i++]; |
|||
var cy = data[i++]; |
|||
var rx = data[i++]; |
|||
var ry = data[i++]; |
|||
var theta = data[i++]; |
|||
var dTheta = data[i++]; // TODO Arc 旋转
|
|||
|
|||
i += 1; |
|||
var anticlockwise = !!(1 - data[i++]); |
|||
x1 = Math.cos(theta) * rx + cx; |
|||
y1 = Math.sin(theta) * ry + cy; // 不是直接使用 arc 命令
|
|||
|
|||
if (i <= 1) { |
|||
// 第一个命令起点还未定义
|
|||
x0 = x1; |
|||
y0 = y1; |
|||
} // zr 使用scale来模拟椭圆, 这里也对x做一定的缩放
|
|||
|
|||
|
|||
var _x = (x - cx) * ry / rx + cx; |
|||
|
|||
d = projectPointToArc(cx, cy, ry, theta, theta + dTheta, anticlockwise, _x, y, tmpPt); |
|||
xi = Math.cos(theta + dTheta) * rx + cx; |
|||
yi = Math.sin(theta + dTheta) * ry + cy; |
|||
break; |
|||
|
|||
case CMD.R: |
|||
x0 = xi = data[i++]; |
|||
y0 = yi = data[i++]; |
|||
var width = data[i++]; |
|||
var height = data[i++]; |
|||
d = projectPointToRect(x0, y0, width, height, x, y, tmpPt); |
|||
break; |
|||
|
|||
case CMD.Z: |
|||
d = projectPointToLine(xi, yi, x0, y0, x, y, tmpPt, true); |
|||
xi = x0; |
|||
yi = y0; |
|||
break; |
|||
} |
|||
|
|||
if (d < minDist) { |
|||
minDist = d; |
|||
out.set(tmpPt[0], tmpPt[1]); |
|||
} |
|||
} |
|||
|
|||
return minDist; |
|||
} // Temporal varible for intermediate usage.
|
|||
|
|||
|
|||
var pt0 = new Point(); |
|||
var pt1 = new Point(); |
|||
var pt2 = new Point(); |
|||
var dir = new Point(); |
|||
var dir2 = new Point(); |
|||
/** |
|||
* Calculate a proper guide line based on the label position and graphic element definition |
|||
* @param label |
|||
* @param labelRect |
|||
* @param target |
|||
* @param targetRect |
|||
*/ |
|||
|
|||
export function updateLabelLinePoints(target, labelLineModel) { |
|||
if (!target) { |
|||
return; |
|||
} |
|||
|
|||
var labelLine = target.getTextGuideLine(); |
|||
var label = target.getTextContent(); // Needs to create text guide in each charts.
|
|||
|
|||
if (!(label && labelLine)) { |
|||
return; |
|||
} |
|||
|
|||
var labelGuideConfig = target.textGuideLineConfig || {}; |
|||
var points = [[0, 0], [0, 0], [0, 0]]; |
|||
var searchSpace = labelGuideConfig.candidates || DEFAULT_SEARCH_SPACE; |
|||
var labelRect = label.getBoundingRect().clone(); |
|||
labelRect.applyTransform(label.getComputedTransform()); |
|||
var minDist = Infinity; |
|||
var anchorPoint = labelGuideConfig.anchor; |
|||
var targetTransform = target.getComputedTransform(); |
|||
var targetInversedTransform = targetTransform && invert([], targetTransform); |
|||
var len = labelLineModel.get('length2') || 0; |
|||
|
|||
if (anchorPoint) { |
|||
pt2.copy(anchorPoint); |
|||
} |
|||
|
|||
for (var i = 0; i < searchSpace.length; i++) { |
|||
var candidate = searchSpace[i]; |
|||
getCandidateAnchor(candidate, 0, labelRect, pt0, dir); |
|||
Point.scaleAndAdd(pt1, pt0, dir, len); // Transform to target coord space.
|
|||
|
|||
pt1.transform(targetInversedTransform); // Note: getBoundingRect will ensure the `path` being created.
|
|||
|
|||
var boundingRect = target.getBoundingRect(); |
|||
var dist = anchorPoint ? anchorPoint.distance(pt1) : target instanceof Path ? nearestPointOnPath(pt1, target.path, pt2) : nearestPointOnRect(pt1, boundingRect, pt2); // TODO pt2 is in the path
|
|||
|
|||
if (dist < minDist) { |
|||
minDist = dist; // Transform back to global space.
|
|||
|
|||
pt1.transform(targetTransform); |
|||
pt2.transform(targetTransform); |
|||
pt2.toArray(points[0]); |
|||
pt1.toArray(points[1]); |
|||
pt0.toArray(points[2]); |
|||
} |
|||
} |
|||
|
|||
limitTurnAngle(points, labelLineModel.get('minTurnAngle')); |
|||
labelLine.setShape({ |
|||
points: points |
|||
}); |
|||
} // Temporal variable for the limitTurnAngle function
|
|||
|
|||
var tmpArr = []; |
|||
var tmpProjPoint = new Point(); |
|||
/** |
|||
* Reduce the line segment attached to the label to limit the turn angle between two segments. |
|||
* @param linePoints |
|||
* @param minTurnAngle Radian of minimum turn angle. 0 - 180 |
|||
*/ |
|||
|
|||
export function limitTurnAngle(linePoints, minTurnAngle) { |
|||
if (!(minTurnAngle <= 180 && minTurnAngle > 0)) { |
|||
return; |
|||
} |
|||
|
|||
minTurnAngle = minTurnAngle / 180 * Math.PI; // The line points can be
|
|||
// /pt1----pt2 (label)
|
|||
// /
|
|||
// pt0/
|
|||
|
|||
pt0.fromArray(linePoints[0]); |
|||
pt1.fromArray(linePoints[1]); |
|||
pt2.fromArray(linePoints[2]); |
|||
Point.sub(dir, pt0, pt1); |
|||
Point.sub(dir2, pt2, pt1); |
|||
var len1 = dir.len(); |
|||
var len2 = dir2.len(); |
|||
|
|||
if (len1 < 1e-3 || len2 < 1e-3) { |
|||
return; |
|||
} |
|||
|
|||
dir.scale(1 / len1); |
|||
dir2.scale(1 / len2); |
|||
var angleCos = dir.dot(dir2); |
|||
var minTurnAngleCos = Math.cos(minTurnAngle); |
|||
|
|||
if (minTurnAngleCos < angleCos) { |
|||
// Smaller than minTurnAngle
|
|||
// Calculate project point of pt0 on pt1-pt2
|
|||
var d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false); |
|||
tmpProjPoint.fromArray(tmpArr); // Calculate new projected length with limited minTurnAngle and get the new connect point
|
|||
|
|||
tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI - minTurnAngle)); // Limit the new calculated connect point between pt1 and pt2.
|
|||
|
|||
var t = pt2.x !== pt1.x ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x) : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y); |
|||
|
|||
if (isNaN(t)) { |
|||
return; |
|||
} |
|||
|
|||
if (t < 0) { |
|||
Point.copy(tmpProjPoint, pt1); |
|||
} else if (t > 1) { |
|||
Point.copy(tmpProjPoint, pt2); |
|||
} |
|||
|
|||
tmpProjPoint.toArray(linePoints[1]); |
|||
} |
|||
} |
|||
/** |
|||
* Limit the angle of line and the surface |
|||
* @param maxSurfaceAngle Radian of minimum turn angle. 0 - 180. 0 is same direction to normal. 180 is opposite |
|||
*/ |
|||
|
|||
export function limitSurfaceAngle(linePoints, surfaceNormal, maxSurfaceAngle) { |
|||
if (!(maxSurfaceAngle <= 180 && maxSurfaceAngle > 0)) { |
|||
return; |
|||
} |
|||
|
|||
maxSurfaceAngle = maxSurfaceAngle / 180 * Math.PI; |
|||
pt0.fromArray(linePoints[0]); |
|||
pt1.fromArray(linePoints[1]); |
|||
pt2.fromArray(linePoints[2]); |
|||
Point.sub(dir, pt1, pt0); |
|||
Point.sub(dir2, pt2, pt1); |
|||
var len1 = dir.len(); |
|||
var len2 = dir2.len(); |
|||
|
|||
if (len1 < 1e-3 || len2 < 1e-3) { |
|||
return; |
|||
} |
|||
|
|||
dir.scale(1 / len1); |
|||
dir2.scale(1 / len2); |
|||
var angleCos = dir.dot(surfaceNormal); |
|||
var maxSurfaceAngleCos = Math.cos(maxSurfaceAngle); |
|||
|
|||
if (angleCos < maxSurfaceAngleCos) { |
|||
// Calculate project point of pt0 on pt1-pt2
|
|||
var d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false); |
|||
tmpProjPoint.fromArray(tmpArr); |
|||
var HALF_PI = Math.PI / 2; |
|||
var angle2 = Math.acos(dir2.dot(surfaceNormal)); |
|||
var newAngle = HALF_PI + angle2 - maxSurfaceAngle; |
|||
|
|||
if (newAngle >= HALF_PI) { |
|||
// parallel
|
|||
Point.copy(tmpProjPoint, pt2); |
|||
} else { |
|||
// Calculate new projected length with limited minTurnAngle and get the new connect point
|
|||
tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI / 2 - newAngle)); // Limit the new calculated connect point between pt1 and pt2.
|
|||
|
|||
var t = pt2.x !== pt1.x ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x) : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y); |
|||
|
|||
if (isNaN(t)) { |
|||
return; |
|||
} |
|||
|
|||
if (t < 0) { |
|||
Point.copy(tmpProjPoint, pt1); |
|||
} else if (t > 1) { |
|||
Point.copy(tmpProjPoint, pt2); |
|||
} |
|||
} |
|||
|
|||
tmpProjPoint.toArray(linePoints[1]); |
|||
} |
|||
} |
|||
|
|||
function setLabelLineState(labelLine, ignore, stateName, stateModel) { |
|||
var isNormal = stateName === 'normal'; |
|||
var stateObj = isNormal ? labelLine : labelLine.ensureState(stateName); // Make sure display.
|
|||
|
|||
stateObj.ignore = ignore; // Set smooth
|
|||
|
|||
var smooth = stateModel.get('smooth'); |
|||
|
|||
if (smooth && smooth === true) { |
|||
smooth = 0.3; |
|||
} |
|||
|
|||
stateObj.shape = stateObj.shape || {}; |
|||
|
|||
if (smooth > 0) { |
|||
stateObj.shape.smooth = smooth; |
|||
} |
|||
|
|||
var styleObj = stateModel.getModel('lineStyle').getLineStyle(); |
|||
isNormal ? labelLine.useStyle(styleObj) : stateObj.style = styleObj; |
|||
} |
|||
|
|||
function buildLabelLinePath(path, shape) { |
|||
var smooth = shape.smooth; |
|||
var points = shape.points; |
|||
|
|||
if (!points) { |
|||
return; |
|||
} |
|||
|
|||
path.moveTo(points[0][0], points[0][1]); |
|||
|
|||
if (smooth > 0 && points.length >= 3) { |
|||
var len1 = vector.dist(points[0], points[1]); |
|||
var len2 = vector.dist(points[1], points[2]); |
|||
|
|||
if (!len1 || !len2) { |
|||
path.lineTo(points[1][0], points[1][1]); |
|||
path.lineTo(points[2][0], points[2][1]); |
|||
return; |
|||
} |
|||
|
|||
var moveLen = Math.min(len1, len2) * smooth; |
|||
var midPoint0 = vector.lerp([], points[1], points[0], moveLen / len1); |
|||
var midPoint2 = vector.lerp([], points[1], points[2], moveLen / len2); |
|||
var midPoint1 = vector.lerp([], midPoint0, midPoint2, 0.5); |
|||
path.bezierCurveTo(midPoint0[0], midPoint0[1], midPoint0[0], midPoint0[1], midPoint1[0], midPoint1[1]); |
|||
path.bezierCurveTo(midPoint2[0], midPoint2[1], midPoint2[0], midPoint2[1], points[2][0], points[2][1]); |
|||
} else { |
|||
for (var i = 1; i < points.length; i++) { |
|||
path.lineTo(points[i][0], points[i][1]); |
|||
} |
|||
} |
|||
} |
|||
/** |
|||
* Create a label line if necessary and set it's style. |
|||
*/ |
|||
|
|||
|
|||
export function setLabelLineStyle(targetEl, statesModels, defaultStyle) { |
|||
var labelLine = targetEl.getTextGuideLine(); |
|||
var label = targetEl.getTextContent(); |
|||
|
|||
if (!label) { |
|||
// Not show label line if there is no label.
|
|||
if (labelLine) { |
|||
targetEl.removeTextGuideLine(); |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
var normalModel = statesModels.normal; |
|||
var showNormal = normalModel.get('show'); |
|||
var labelIgnoreNormal = label.ignore; |
|||
|
|||
for (var i = 0; i < DISPLAY_STATES.length; i++) { |
|||
var stateName = DISPLAY_STATES[i]; |
|||
var stateModel = statesModels[stateName]; |
|||
var isNormal = stateName === 'normal'; |
|||
|
|||
if (stateModel) { |
|||
var stateShow = stateModel.get('show'); |
|||
var isLabelIgnored = isNormal ? labelIgnoreNormal : retrieve2(label.states[stateName] && label.states[stateName].ignore, labelIgnoreNormal); |
|||
|
|||
if (isLabelIgnored // Not show when label is not shown in this state.
|
|||
|| !retrieve2(stateShow, showNormal) // Use normal state by default if not set.
|
|||
) { |
|||
var stateObj = isNormal ? labelLine : labelLine && labelLine.states[stateName]; |
|||
|
|||
if (stateObj) { |
|||
stateObj.ignore = true; |
|||
} |
|||
|
|||
continue; |
|||
} // Create labelLine if not exists
|
|||
|
|||
|
|||
if (!labelLine) { |
|||
labelLine = new Polyline(); |
|||
targetEl.setTextGuideLine(labelLine); // Reset state of normal because it's new created.
|
|||
// NOTE: NORMAL should always been the first!
|
|||
|
|||
if (!isNormal && (labelIgnoreNormal || !showNormal)) { |
|||
setLabelLineState(labelLine, true, 'normal', statesModels.normal); |
|||
} // Use same state proxy.
|
|||
|
|||
|
|||
if (targetEl.stateProxy) { |
|||
labelLine.stateProxy = targetEl.stateProxy; |
|||
} |
|||
} |
|||
|
|||
setLabelLineState(labelLine, false, stateName, stateModel); |
|||
} |
|||
} |
|||
|
|||
if (labelLine) { |
|||
defaults(labelLine.style, defaultStyle); // Not fill.
|
|||
|
|||
labelLine.style.fill = null; |
|||
var showAbove = normalModel.get('showAbove'); |
|||
var labelLineConfig = targetEl.textGuideLineConfig = targetEl.textGuideLineConfig || {}; |
|||
labelLineConfig.showAbove = showAbove || false; // Custom the buildPath.
|
|||
|
|||
labelLine.buildPath = buildLabelLinePath; |
|||
} |
|||
} |
|||
export function getLabelLineStatesModels(itemModel, labelLineName) { |
|||
labelLineName = labelLineName || 'labelLine'; |
|||
var statesModels = { |
|||
normal: itemModel.getModel(labelLineName) |
|||
}; |
|||
|
|||
for (var i = 0; i < SPECIAL_STATES.length; i++) { |
|||
var stateName = SPECIAL_STATES[i]; |
|||
statesModels[stateName] = itemModel.getModel([stateName, labelLineName]); |
|||
} |
|||
|
|||
return statesModels; |
|||
} |
|||
@ -0,0 +1,343 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { BoundingRect, OrientedBoundingRect } from '../util/graphic.js'; |
|||
export function prepareLayoutList(input) { |
|||
var list = []; |
|||
|
|||
for (var i = 0; i < input.length; i++) { |
|||
var rawItem = input[i]; |
|||
|
|||
if (rawItem.defaultAttr.ignore) { |
|||
continue; |
|||
} |
|||
|
|||
var label = rawItem.label; |
|||
var transform = label.getComputedTransform(); // NOTE: Get bounding rect after getComputedTransform, or label may not been updated by the host el.
|
|||
|
|||
var localRect = label.getBoundingRect(); |
|||
var isAxisAligned = !transform || transform[1] < 1e-5 && transform[2] < 1e-5; |
|||
var minMargin = label.style.margin || 0; |
|||
var globalRect = localRect.clone(); |
|||
globalRect.applyTransform(transform); |
|||
globalRect.x -= minMargin / 2; |
|||
globalRect.y -= minMargin / 2; |
|||
globalRect.width += minMargin; |
|||
globalRect.height += minMargin; |
|||
var obb = isAxisAligned ? new OrientedBoundingRect(localRect, transform) : null; |
|||
list.push({ |
|||
label: label, |
|||
labelLine: rawItem.labelLine, |
|||
rect: globalRect, |
|||
localRect: localRect, |
|||
obb: obb, |
|||
priority: rawItem.priority, |
|||
defaultAttr: rawItem.defaultAttr, |
|||
layoutOption: rawItem.computedLayoutOption, |
|||
axisAligned: isAxisAligned, |
|||
transform: transform |
|||
}); |
|||
} |
|||
|
|||
return list; |
|||
} |
|||
|
|||
function shiftLayout(list, xyDim, sizeDim, minBound, maxBound, balanceShift) { |
|||
var len = list.length; |
|||
|
|||
if (len < 2) { |
|||
return; |
|||
} |
|||
|
|||
list.sort(function (a, b) { |
|||
return a.rect[xyDim] - b.rect[xyDim]; |
|||
}); |
|||
var lastPos = 0; |
|||
var delta; |
|||
var adjusted = false; |
|||
var shifts = []; |
|||
var totalShifts = 0; |
|||
|
|||
for (var i = 0; i < len; i++) { |
|||
var item = list[i]; |
|||
var rect = item.rect; |
|||
delta = rect[xyDim] - lastPos; |
|||
|
|||
if (delta < 0) { |
|||
// shiftForward(i, len, -delta);
|
|||
rect[xyDim] -= delta; |
|||
item.label[xyDim] -= delta; |
|||
adjusted = true; |
|||
} |
|||
|
|||
var shift = Math.max(-delta, 0); |
|||
shifts.push(shift); |
|||
totalShifts += shift; |
|||
lastPos = rect[xyDim] + rect[sizeDim]; |
|||
} |
|||
|
|||
if (totalShifts > 0 && balanceShift) { |
|||
// Shift back to make the distribution more equally.
|
|||
shiftList(-totalShifts / len, 0, len); |
|||
} // TODO bleedMargin?
|
|||
|
|||
|
|||
var first = list[0]; |
|||
var last = list[len - 1]; |
|||
var minGap; |
|||
var maxGap; |
|||
updateMinMaxGap(); // If ends exceed two bounds, squeeze at most 80%, then take the gap of two bounds.
|
|||
|
|||
minGap < 0 && squeezeGaps(-minGap, 0.8); |
|||
maxGap < 0 && squeezeGaps(maxGap, 0.8); |
|||
updateMinMaxGap(); |
|||
takeBoundsGap(minGap, maxGap, 1); |
|||
takeBoundsGap(maxGap, minGap, -1); // Handle bailout when there is not enough space.
|
|||
|
|||
updateMinMaxGap(); |
|||
|
|||
if (minGap < 0) { |
|||
squeezeWhenBailout(-minGap); |
|||
} |
|||
|
|||
if (maxGap < 0) { |
|||
squeezeWhenBailout(maxGap); |
|||
} |
|||
|
|||
function updateMinMaxGap() { |
|||
minGap = first.rect[xyDim] - minBound; |
|||
maxGap = maxBound - last.rect[xyDim] - last.rect[sizeDim]; |
|||
} |
|||
|
|||
function takeBoundsGap(gapThisBound, gapOtherBound, moveDir) { |
|||
if (gapThisBound < 0) { |
|||
// Move from other gap if can.
|
|||
var moveFromMaxGap = Math.min(gapOtherBound, -gapThisBound); |
|||
|
|||
if (moveFromMaxGap > 0) { |
|||
shiftList(moveFromMaxGap * moveDir, 0, len); |
|||
var remained = moveFromMaxGap + gapThisBound; |
|||
|
|||
if (remained < 0) { |
|||
squeezeGaps(-remained * moveDir, 1); |
|||
} |
|||
} else { |
|||
squeezeGaps(-gapThisBound * moveDir, 1); |
|||
} |
|||
} |
|||
} |
|||
|
|||
function shiftList(delta, start, end) { |
|||
if (delta !== 0) { |
|||
adjusted = true; |
|||
} |
|||
|
|||
for (var i = start; i < end; i++) { |
|||
var item = list[i]; |
|||
var rect = item.rect; |
|||
rect[xyDim] += delta; |
|||
item.label[xyDim] += delta; |
|||
} |
|||
} // Squeeze gaps if the labels exceed margin.
|
|||
|
|||
|
|||
function squeezeGaps(delta, maxSqeezePercent) { |
|||
var gaps = []; |
|||
var totalGaps = 0; |
|||
|
|||
for (var i = 1; i < len; i++) { |
|||
var prevItemRect = list[i - 1].rect; |
|||
var gap = Math.max(list[i].rect[xyDim] - prevItemRect[xyDim] - prevItemRect[sizeDim], 0); |
|||
gaps.push(gap); |
|||
totalGaps += gap; |
|||
} |
|||
|
|||
if (!totalGaps) { |
|||
return; |
|||
} |
|||
|
|||
var squeezePercent = Math.min(Math.abs(delta) / totalGaps, maxSqeezePercent); |
|||
|
|||
if (delta > 0) { |
|||
for (var i = 0; i < len - 1; i++) { |
|||
// Distribute the shift delta to all gaps.
|
|||
var movement = gaps[i] * squeezePercent; // Forward
|
|||
|
|||
shiftList(movement, 0, i + 1); |
|||
} |
|||
} else { |
|||
// Backward
|
|||
for (var i = len - 1; i > 0; i--) { |
|||
// Distribute the shift delta to all gaps.
|
|||
var movement = gaps[i - 1] * squeezePercent; |
|||
shiftList(-movement, i, len); |
|||
} |
|||
} |
|||
} |
|||
/** |
|||
* Squeeze to allow overlap if there is no more space available. |
|||
* Let other overlapping strategy like hideOverlap do the job instead of keep exceeding the bounds. |
|||
*/ |
|||
|
|||
|
|||
function squeezeWhenBailout(delta) { |
|||
var dir = delta < 0 ? -1 : 1; |
|||
delta = Math.abs(delta); |
|||
var moveForEachLabel = Math.ceil(delta / (len - 1)); |
|||
|
|||
for (var i = 0; i < len - 1; i++) { |
|||
if (dir > 0) { |
|||
// Forward
|
|||
shiftList(moveForEachLabel, 0, i + 1); |
|||
} else { |
|||
// Backward
|
|||
shiftList(-moveForEachLabel, len - i - 1, len); |
|||
} |
|||
|
|||
delta -= moveForEachLabel; |
|||
|
|||
if (delta <= 0) { |
|||
return; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return adjusted; |
|||
} |
|||
/** |
|||
* Adjust labels on x direction to avoid overlap. |
|||
*/ |
|||
|
|||
|
|||
export function shiftLayoutOnX(list, leftBound, rightBound, // If average the shifts on all labels and add them to 0
|
|||
// TODO: Not sure if should enable it.
|
|||
// Pros: The angle of lines will distribute more equally
|
|||
// Cons: In some layout. It may not what user wanted. like in pie. the label of last sector is usually changed unexpectedly.
|
|||
balanceShift) { |
|||
return shiftLayout(list, 'x', 'width', leftBound, rightBound, balanceShift); |
|||
} |
|||
/** |
|||
* Adjust labels on y direction to avoid overlap. |
|||
*/ |
|||
|
|||
export function shiftLayoutOnY(list, topBound, bottomBound, // If average the shifts on all labels and add them to 0
|
|||
balanceShift) { |
|||
return shiftLayout(list, 'y', 'height', topBound, bottomBound, balanceShift); |
|||
} |
|||
export function hideOverlap(labelList) { |
|||
var displayedLabels = []; // TODO, render overflow visible first, put in the displayedLabels.
|
|||
|
|||
labelList.sort(function (a, b) { |
|||
return b.priority - a.priority; |
|||
}); |
|||
var globalRect = new BoundingRect(0, 0, 0, 0); |
|||
|
|||
function hideEl(el) { |
|||
if (!el.ignore) { |
|||
// Show on emphasis.
|
|||
var emphasisState = el.ensureState('emphasis'); |
|||
|
|||
if (emphasisState.ignore == null) { |
|||
emphasisState.ignore = false; |
|||
} |
|||
} |
|||
|
|||
el.ignore = true; |
|||
} |
|||
|
|||
for (var i = 0; i < labelList.length; i++) { |
|||
var labelItem = labelList[i]; |
|||
var isAxisAligned = labelItem.axisAligned; |
|||
var localRect = labelItem.localRect; |
|||
var transform = labelItem.transform; |
|||
var label = labelItem.label; |
|||
var labelLine = labelItem.labelLine; |
|||
globalRect.copy(labelItem.rect); // Add a threshold because layout may be aligned precisely.
|
|||
|
|||
globalRect.width -= 0.1; |
|||
globalRect.height -= 0.1; |
|||
globalRect.x += 0.05; |
|||
globalRect.y += 0.05; |
|||
var obb = labelItem.obb; |
|||
var overlapped = false; |
|||
|
|||
for (var j = 0; j < displayedLabels.length; j++) { |
|||
var existsTextCfg = displayedLabels[j]; // Fast rejection.
|
|||
|
|||
if (!globalRect.intersect(existsTextCfg.rect)) { |
|||
continue; |
|||
} |
|||
|
|||
if (isAxisAligned && existsTextCfg.axisAligned) { |
|||
// Is overlapped
|
|||
overlapped = true; |
|||
break; |
|||
} |
|||
|
|||
if (!existsTextCfg.obb) { |
|||
// If self is not axis aligned. But other is.
|
|||
existsTextCfg.obb = new OrientedBoundingRect(existsTextCfg.localRect, existsTextCfg.transform); |
|||
} |
|||
|
|||
if (!obb) { |
|||
// If self is axis aligned. But other is not.
|
|||
obb = new OrientedBoundingRect(localRect, transform); |
|||
} |
|||
|
|||
if (obb.intersect(existsTextCfg.obb)) { |
|||
overlapped = true; |
|||
break; |
|||
} |
|||
} // TODO Callback to determine if this overlap should be handled?
|
|||
|
|||
|
|||
if (overlapped) { |
|||
hideEl(label); |
|||
labelLine && hideEl(labelLine); |
|||
} else { |
|||
label.attr('ignore', labelItem.defaultAttr.ignore); |
|||
labelLine && labelLine.attr('ignore', labelItem.defaultAttr.labelGuideIgnore); |
|||
displayedLabels.push(labelItem); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,569 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 ZRText from 'zrender/lib/graphic/Text.js'; |
|||
import { isFunction, retrieve2, extend, keys, trim } from 'zrender/lib/core/util.js'; |
|||
import { SPECIAL_STATES, DISPLAY_STATES } from '../util/states.js'; |
|||
import { deprecateReplaceLog } from '../util/log.js'; |
|||
import { makeInner, interpolateRawValues } from '../util/model.js'; |
|||
import { initProps, updateProps } from '../util/graphic.js'; |
|||
var EMPTY_OBJ = {}; |
|||
export function setLabelText(label, labelTexts) { |
|||
for (var i = 0; i < SPECIAL_STATES.length; i++) { |
|||
var stateName = SPECIAL_STATES[i]; |
|||
var text = labelTexts[stateName]; |
|||
var state = label.ensureState(stateName); |
|||
state.style = state.style || {}; |
|||
state.style.text = text; |
|||
} |
|||
|
|||
var oldStates = label.currentStates.slice(); |
|||
label.clearStates(true); |
|||
label.setStyle({ |
|||
text: labelTexts.normal |
|||
}); |
|||
label.useStates(oldStates, true); |
|||
} |
|||
|
|||
function getLabelText(opt, stateModels, interpolatedValue) { |
|||
var labelFetcher = opt.labelFetcher; |
|||
var labelDataIndex = opt.labelDataIndex; |
|||
var labelDimIndex = opt.labelDimIndex; |
|||
var normalModel = stateModels.normal; |
|||
var baseText; |
|||
|
|||
if (labelFetcher) { |
|||
baseText = labelFetcher.getFormattedLabel(labelDataIndex, 'normal', null, labelDimIndex, normalModel && normalModel.get('formatter'), interpolatedValue != null ? { |
|||
interpolatedValue: interpolatedValue |
|||
} : null); |
|||
} |
|||
|
|||
if (baseText == null) { |
|||
baseText = isFunction(opt.defaultText) ? opt.defaultText(labelDataIndex, opt, interpolatedValue) : opt.defaultText; |
|||
} |
|||
|
|||
var statesText = { |
|||
normal: baseText |
|||
}; |
|||
|
|||
for (var i = 0; i < SPECIAL_STATES.length; i++) { |
|||
var stateName = SPECIAL_STATES[i]; |
|||
var stateModel = stateModels[stateName]; |
|||
statesText[stateName] = retrieve2(labelFetcher ? labelFetcher.getFormattedLabel(labelDataIndex, stateName, null, labelDimIndex, stateModel && stateModel.get('formatter')) : null, baseText); |
|||
} |
|||
|
|||
return statesText; |
|||
} |
|||
|
|||
function setLabelStyle(targetEl, labelStatesModels, opt, stateSpecified // TODO specified position?
|
|||
) { |
|||
opt = opt || EMPTY_OBJ; |
|||
var isSetOnText = targetEl instanceof ZRText; |
|||
var needsCreateText = false; |
|||
|
|||
for (var i = 0; i < DISPLAY_STATES.length; i++) { |
|||
var stateModel = labelStatesModels[DISPLAY_STATES[i]]; |
|||
|
|||
if (stateModel && stateModel.getShallow('show')) { |
|||
needsCreateText = true; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
var textContent = isSetOnText ? targetEl : targetEl.getTextContent(); |
|||
|
|||
if (needsCreateText) { |
|||
if (!isSetOnText) { |
|||
// Reuse the previous
|
|||
if (!textContent) { |
|||
textContent = new ZRText(); |
|||
targetEl.setTextContent(textContent); |
|||
} // Use same state proxy
|
|||
|
|||
|
|||
if (targetEl.stateProxy) { |
|||
textContent.stateProxy = targetEl.stateProxy; |
|||
} |
|||
} |
|||
|
|||
var labelStatesTexts = getLabelText(opt, labelStatesModels); |
|||
var normalModel = labelStatesModels.normal; |
|||
var showNormal = !!normalModel.getShallow('show'); |
|||
var normalStyle = createTextStyle(normalModel, stateSpecified && stateSpecified.normal, opt, false, !isSetOnText); |
|||
normalStyle.text = labelStatesTexts.normal; |
|||
|
|||
if (!isSetOnText) { |
|||
// Always create new
|
|||
targetEl.setTextConfig(createTextConfig(normalModel, opt, false)); |
|||
} |
|||
|
|||
for (var i = 0; i < SPECIAL_STATES.length; i++) { |
|||
var stateName = SPECIAL_STATES[i]; |
|||
var stateModel = labelStatesModels[stateName]; |
|||
|
|||
if (stateModel) { |
|||
var stateObj = textContent.ensureState(stateName); |
|||
var stateShow = !!retrieve2(stateModel.getShallow('show'), showNormal); |
|||
|
|||
if (stateShow !== showNormal) { |
|||
stateObj.ignore = !stateShow; |
|||
} |
|||
|
|||
stateObj.style = createTextStyle(stateModel, stateSpecified && stateSpecified[stateName], opt, true, !isSetOnText); |
|||
stateObj.style.text = labelStatesTexts[stateName]; |
|||
|
|||
if (!isSetOnText) { |
|||
var targetElEmphasisState = targetEl.ensureState(stateName); |
|||
targetElEmphasisState.textConfig = createTextConfig(stateModel, opt, true); |
|||
} |
|||
} |
|||
} // PENDING: if there is many requirements that emphasis position
|
|||
// need to be different from normal position, we might consider
|
|||
// auto slient is those cases.
|
|||
|
|||
|
|||
textContent.silent = !!normalModel.getShallow('silent'); // Keep x and y
|
|||
|
|||
if (textContent.style.x != null) { |
|||
normalStyle.x = textContent.style.x; |
|||
} |
|||
|
|||
if (textContent.style.y != null) { |
|||
normalStyle.y = textContent.style.y; |
|||
} |
|||
|
|||
textContent.ignore = !showNormal; // Always create new style.
|
|||
|
|||
textContent.useStyle(normalStyle); |
|||
textContent.dirty(); |
|||
|
|||
if (opt.enableTextSetter) { |
|||
labelInner(textContent).setLabelText = function (interpolatedValue) { |
|||
var labelStatesTexts = getLabelText(opt, labelStatesModels, interpolatedValue); |
|||
setLabelText(textContent, labelStatesTexts); |
|||
}; |
|||
} |
|||
} else if (textContent) { |
|||
// Not display rich text.
|
|||
textContent.ignore = true; |
|||
} |
|||
|
|||
targetEl.dirty(); |
|||
} |
|||
|
|||
export { setLabelStyle }; |
|||
export function getLabelStatesModels(itemModel, labelName) { |
|||
labelName = labelName || 'label'; |
|||
var statesModels = { |
|||
normal: itemModel.getModel(labelName) |
|||
}; |
|||
|
|||
for (var i = 0; i < SPECIAL_STATES.length; i++) { |
|||
var stateName = SPECIAL_STATES[i]; |
|||
statesModels[stateName] = itemModel.getModel([stateName, labelName]); |
|||
} |
|||
|
|||
return statesModels; |
|||
} |
|||
/** |
|||
* Set basic textStyle properties. |
|||
*/ |
|||
|
|||
export function createTextStyle(textStyleModel, specifiedTextStyle, // Fixed style in the code. Can't be set by model.
|
|||
opt, isNotNormal, isAttached // If text is attached on an element. If so, auto color will handling in zrender.
|
|||
) { |
|||
var textStyle = {}; |
|||
setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached); |
|||
specifiedTextStyle && extend(textStyle, specifiedTextStyle); // textStyle.host && textStyle.host.dirty && textStyle.host.dirty(false);
|
|||
|
|||
return textStyle; |
|||
} |
|||
export function createTextConfig(textStyleModel, opt, isNotNormal) { |
|||
opt = opt || {}; |
|||
var textConfig = {}; |
|||
var labelPosition; |
|||
var labelRotate = textStyleModel.getShallow('rotate'); |
|||
var labelDistance = retrieve2(textStyleModel.getShallow('distance'), isNotNormal ? null : 5); |
|||
var labelOffset = textStyleModel.getShallow('offset'); |
|||
labelPosition = textStyleModel.getShallow('position') || (isNotNormal ? null : 'inside'); // 'outside' is not a valid zr textPostion value, but used
|
|||
// in bar series, and magric type should be considered.
|
|||
|
|||
labelPosition === 'outside' && (labelPosition = opt.defaultOutsidePosition || 'top'); |
|||
|
|||
if (labelPosition != null) { |
|||
textConfig.position = labelPosition; |
|||
} |
|||
|
|||
if (labelOffset != null) { |
|||
textConfig.offset = labelOffset; |
|||
} |
|||
|
|||
if (labelRotate != null) { |
|||
labelRotate *= Math.PI / 180; |
|||
textConfig.rotation = labelRotate; |
|||
} |
|||
|
|||
if (labelDistance != null) { |
|||
textConfig.distance = labelDistance; |
|||
} // fill and auto is determined by the color of path fill if it's not specified by developers.
|
|||
|
|||
|
|||
textConfig.outsideFill = textStyleModel.get('color') === 'inherit' ? opt.inheritColor || null : 'auto'; |
|||
return textConfig; |
|||
} |
|||
/** |
|||
* The uniform entry of set text style, that is, retrieve style definitions |
|||
* from `model` and set to `textStyle` object. |
|||
* |
|||
* Never in merge mode, but in overwrite mode, that is, all of the text style |
|||
* properties will be set. (Consider the states of normal and emphasis and |
|||
* default value can be adopted, merge would make the logic too complicated |
|||
* to manage.) |
|||
*/ |
|||
|
|||
function setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached) { |
|||
// Consider there will be abnormal when merge hover style to normal style if given default value.
|
|||
opt = opt || EMPTY_OBJ; |
|||
var ecModel = textStyleModel.ecModel; |
|||
var globalTextStyle = ecModel && ecModel.option.textStyle; // Consider case:
|
|||
// {
|
|||
// data: [{
|
|||
// value: 12,
|
|||
// label: {
|
|||
// rich: {
|
|||
// // no 'a' here but using parent 'a'.
|
|||
// }
|
|||
// }
|
|||
// }],
|
|||
// rich: {
|
|||
// a: { ... }
|
|||
// }
|
|||
// }
|
|||
|
|||
var richItemNames = getRichItemNames(textStyleModel); |
|||
var richResult; |
|||
|
|||
if (richItemNames) { |
|||
richResult = {}; |
|||
|
|||
for (var name_1 in richItemNames) { |
|||
if (richItemNames.hasOwnProperty(name_1)) { |
|||
// Cascade is supported in rich.
|
|||
var richTextStyle = textStyleModel.getModel(['rich', name_1]); // In rich, never `disableBox`.
|
|||
// FIXME: consider `label: {formatter: '{a|xx}', color: 'blue', rich: {a: {}}}`,
|
|||
// the default color `'blue'` will not be adopted if no color declared in `rich`.
|
|||
// That might confuses users. So probably we should put `textStyleModel` as the
|
|||
// root ancestor of the `richTextStyle`. But that would be a break change.
|
|||
|
|||
setTokenTextStyle(richResult[name_1] = {}, richTextStyle, globalTextStyle, opt, isNotNormal, isAttached, false, true); |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (richResult) { |
|||
textStyle.rich = richResult; |
|||
} |
|||
|
|||
var overflow = textStyleModel.get('overflow'); |
|||
|
|||
if (overflow) { |
|||
textStyle.overflow = overflow; |
|||
} |
|||
|
|||
var margin = textStyleModel.get('minMargin'); |
|||
|
|||
if (margin != null) { |
|||
textStyle.margin = margin; |
|||
} |
|||
|
|||
setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, true, false); |
|||
} // Consider case:
|
|||
// {
|
|||
// data: [{
|
|||
// value: 12,
|
|||
// label: {
|
|||
// rich: {
|
|||
// // no 'a' here but using parent 'a'.
|
|||
// }
|
|||
// }
|
|||
// }],
|
|||
// rich: {
|
|||
// a: { ... }
|
|||
// }
|
|||
// }
|
|||
// TODO TextStyleModel
|
|||
|
|||
|
|||
function getRichItemNames(textStyleModel) { |
|||
// Use object to remove duplicated names.
|
|||
var richItemNameMap; |
|||
|
|||
while (textStyleModel && textStyleModel !== textStyleModel.ecModel) { |
|||
var rich = (textStyleModel.option || EMPTY_OBJ).rich; |
|||
|
|||
if (rich) { |
|||
richItemNameMap = richItemNameMap || {}; |
|||
var richKeys = keys(rich); |
|||
|
|||
for (var i = 0; i < richKeys.length; i++) { |
|||
var richKey = richKeys[i]; |
|||
richItemNameMap[richKey] = 1; |
|||
} |
|||
} |
|||
|
|||
textStyleModel = textStyleModel.parentModel; |
|||
} |
|||
|
|||
return richItemNameMap; |
|||
} |
|||
|
|||
var TEXT_PROPS_WITH_GLOBAL = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY']; |
|||
var TEXT_PROPS_SELF = ['align', 'lineHeight', 'width', 'height', 'tag', 'verticalAlign']; |
|||
var TEXT_PROPS_BOX = ['padding', 'borderWidth', 'borderRadius', 'borderDashOffset', 'backgroundColor', 'borderColor', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY']; |
|||
|
|||
function setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, isBlock, inRich) { |
|||
// In merge mode, default value should not be given.
|
|||
globalTextStyle = !isNotNormal && globalTextStyle || EMPTY_OBJ; |
|||
var inheritColor = opt && opt.inheritColor; |
|||
var fillColor = textStyleModel.getShallow('color'); |
|||
var strokeColor = textStyleModel.getShallow('textBorderColor'); |
|||
var opacity = retrieve2(textStyleModel.getShallow('opacity'), globalTextStyle.opacity); |
|||
|
|||
if (fillColor === 'inherit' || fillColor === 'auto') { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (fillColor === 'auto') { |
|||
deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\''); |
|||
} |
|||
} |
|||
|
|||
if (inheritColor) { |
|||
fillColor = inheritColor; |
|||
} else { |
|||
fillColor = null; |
|||
} |
|||
} |
|||
|
|||
if (strokeColor === 'inherit' || strokeColor === 'auto') { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (strokeColor === 'auto') { |
|||
deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\''); |
|||
} |
|||
} |
|||
|
|||
if (inheritColor) { |
|||
strokeColor = inheritColor; |
|||
} else { |
|||
strokeColor = null; |
|||
} |
|||
} |
|||
|
|||
if (!isAttached) { |
|||
// Only use default global textStyle.color if text is individual.
|
|||
// Otherwise it will use the strategy of attached text color because text may be on a path.
|
|||
fillColor = fillColor || globalTextStyle.color; |
|||
strokeColor = strokeColor || globalTextStyle.textBorderColor; |
|||
} |
|||
|
|||
if (fillColor != null) { |
|||
textStyle.fill = fillColor; |
|||
} |
|||
|
|||
if (strokeColor != null) { |
|||
textStyle.stroke = strokeColor; |
|||
} |
|||
|
|||
var textBorderWidth = retrieve2(textStyleModel.getShallow('textBorderWidth'), globalTextStyle.textBorderWidth); |
|||
|
|||
if (textBorderWidth != null) { |
|||
textStyle.lineWidth = textBorderWidth; |
|||
} |
|||
|
|||
var textBorderType = retrieve2(textStyleModel.getShallow('textBorderType'), globalTextStyle.textBorderType); |
|||
|
|||
if (textBorderType != null) { |
|||
textStyle.lineDash = textBorderType; |
|||
} |
|||
|
|||
var textBorderDashOffset = retrieve2(textStyleModel.getShallow('textBorderDashOffset'), globalTextStyle.textBorderDashOffset); |
|||
|
|||
if (textBorderDashOffset != null) { |
|||
textStyle.lineDashOffset = textBorderDashOffset; |
|||
} |
|||
|
|||
if (!isNotNormal && opacity == null && !inRich) { |
|||
opacity = opt && opt.defaultOpacity; |
|||
} |
|||
|
|||
if (opacity != null) { |
|||
textStyle.opacity = opacity; |
|||
} // TODO
|
|||
|
|||
|
|||
if (!isNotNormal && !isAttached) { |
|||
// Set default finally.
|
|||
if (textStyle.fill == null && opt.inheritColor) { |
|||
textStyle.fill = opt.inheritColor; |
|||
} |
|||
} // Do not use `getFont` here, because merge should be supported, where
|
|||
// part of these properties may be changed in emphasis style, and the
|
|||
// others should remain their original value got from normal style.
|
|||
|
|||
|
|||
for (var i = 0; i < TEXT_PROPS_WITH_GLOBAL.length; i++) { |
|||
var key = TEXT_PROPS_WITH_GLOBAL[i]; |
|||
var val = retrieve2(textStyleModel.getShallow(key), globalTextStyle[key]); |
|||
|
|||
if (val != null) { |
|||
textStyle[key] = val; |
|||
} |
|||
} |
|||
|
|||
for (var i = 0; i < TEXT_PROPS_SELF.length; i++) { |
|||
var key = TEXT_PROPS_SELF[i]; |
|||
var val = textStyleModel.getShallow(key); |
|||
|
|||
if (val != null) { |
|||
textStyle[key] = val; |
|||
} |
|||
} |
|||
|
|||
if (textStyle.verticalAlign == null) { |
|||
var baseline = textStyleModel.getShallow('baseline'); |
|||
|
|||
if (baseline != null) { |
|||
textStyle.verticalAlign = baseline; |
|||
} |
|||
} |
|||
|
|||
if (!isBlock || !opt.disableBox) { |
|||
for (var i = 0; i < TEXT_PROPS_BOX.length; i++) { |
|||
var key = TEXT_PROPS_BOX[i]; |
|||
var val = textStyleModel.getShallow(key); |
|||
|
|||
if (val != null) { |
|||
textStyle[key] = val; |
|||
} |
|||
} |
|||
|
|||
var borderType = textStyleModel.getShallow('borderType'); |
|||
|
|||
if (borderType != null) { |
|||
textStyle.borderDash = borderType; |
|||
} |
|||
|
|||
if ((textStyle.backgroundColor === 'auto' || textStyle.backgroundColor === 'inherit') && inheritColor) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (textStyle.backgroundColor === 'auto') { |
|||
deprecateReplaceLog('backgroundColor: \'auto\'', 'backgroundColor: \'inherit\''); |
|||
} |
|||
} |
|||
|
|||
textStyle.backgroundColor = inheritColor; |
|||
} |
|||
|
|||
if ((textStyle.borderColor === 'auto' || textStyle.borderColor === 'inherit') && inheritColor) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (textStyle.borderColor === 'auto') { |
|||
deprecateReplaceLog('borderColor: \'auto\'', 'borderColor: \'inherit\''); |
|||
} |
|||
} |
|||
|
|||
textStyle.borderColor = inheritColor; |
|||
} |
|||
} |
|||
} |
|||
|
|||
export function getFont(opt, ecModel) { |
|||
var gTextStyleModel = ecModel && ecModel.getModel('textStyle'); |
|||
return trim([// FIXME in node-canvas fontWeight is before fontStyle
|
|||
opt.fontStyle || gTextStyleModel && gTextStyleModel.getShallow('fontStyle') || '', opt.fontWeight || gTextStyleModel && gTextStyleModel.getShallow('fontWeight') || '', (opt.fontSize || gTextStyleModel && gTextStyleModel.getShallow('fontSize') || 12) + 'px', opt.fontFamily || gTextStyleModel && gTextStyleModel.getShallow('fontFamily') || 'sans-serif'].join(' ')); |
|||
} |
|||
export var labelInner = makeInner(); |
|||
export function setLabelValueAnimation(label, labelStatesModels, value, getDefaultText) { |
|||
if (!label) { |
|||
return; |
|||
} |
|||
|
|||
var obj = labelInner(label); |
|||
obj.prevValue = obj.value; |
|||
obj.value = value; |
|||
var normalLabelModel = labelStatesModels.normal; |
|||
obj.valueAnimation = normalLabelModel.get('valueAnimation'); |
|||
|
|||
if (obj.valueAnimation) { |
|||
obj.precision = normalLabelModel.get('precision'); |
|||
obj.defaultInterpolatedText = getDefaultText; |
|||
obj.statesModels = labelStatesModels; |
|||
} |
|||
} |
|||
export function animateLabelValue(textEl, dataIndex, data, animatableModel, labelFetcher) { |
|||
var labelInnerStore = labelInner(textEl); |
|||
|
|||
if (!labelInnerStore.valueAnimation || labelInnerStore.prevValue === labelInnerStore.value) { |
|||
// Value not changed, no new label animation
|
|||
return; |
|||
} |
|||
|
|||
var defaultInterpolatedText = labelInnerStore.defaultInterpolatedText; // Consider the case that being animating, do not use the `obj.value`,
|
|||
// Otherwise it will jump to the `obj.value` when this new animation started.
|
|||
|
|||
var currValue = retrieve2(labelInnerStore.interpolatedValue, labelInnerStore.prevValue); |
|||
var targetValue = labelInnerStore.value; |
|||
|
|||
function during(percent) { |
|||
var interpolated = interpolateRawValues(data, labelInnerStore.precision, currValue, targetValue, percent); |
|||
labelInnerStore.interpolatedValue = percent === 1 ? null : interpolated; |
|||
var labelText = getLabelText({ |
|||
labelDataIndex: dataIndex, |
|||
labelFetcher: labelFetcher, |
|||
defaultText: defaultInterpolatedText ? defaultInterpolatedText(interpolated) : interpolated + '' |
|||
}, labelInnerStore.statesModels, interpolated); |
|||
setLabelText(textEl, labelText); |
|||
} |
|||
|
|||
textEl.percent = 0; |
|||
(labelInnerStore.prevValue == null ? initProps : updateProps)(textEl, { |
|||
// percent is used to prevent animation from being aborted #15916
|
|||
percent: 1 |
|||
}, animatableModel, dataIndex, null, during); |
|||
} |
|||
@ -0,0 +1,224 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { calculateTextPosition } from 'zrender/lib/contain/text.js'; |
|||
import { isArray, isNumber } from 'zrender/lib/core/util.js'; |
|||
export function createSectorCalculateTextPosition(positionMapping, opts) { |
|||
opts = opts || {}; |
|||
var isRoundCap = opts.isRoundCap; |
|||
return function (out, opts, boundingRect) { |
|||
var textPosition = opts.position; |
|||
|
|||
if (!textPosition || textPosition instanceof Array) { |
|||
return calculateTextPosition(out, opts, boundingRect); |
|||
} |
|||
|
|||
var mappedSectorPosition = positionMapping(textPosition); |
|||
var distance = opts.distance != null ? opts.distance : 5; |
|||
var sector = this.shape; |
|||
var cx = sector.cx; |
|||
var cy = sector.cy; |
|||
var r = sector.r; |
|||
var r0 = sector.r0; |
|||
var middleR = (r + r0) / 2; |
|||
var startAngle = sector.startAngle; |
|||
var endAngle = sector.endAngle; |
|||
var middleAngle = (startAngle + endAngle) / 2; |
|||
var extraDist = isRoundCap ? Math.abs(r - r0) / 2 : 0; |
|||
var mathCos = Math.cos; |
|||
var mathSin = Math.sin; // base position: top-left
|
|||
|
|||
var x = cx + r * mathCos(startAngle); |
|||
var y = cy + r * mathSin(startAngle); |
|||
var textAlign = 'left'; |
|||
var textVerticalAlign = 'top'; |
|||
|
|||
switch (mappedSectorPosition) { |
|||
case 'startArc': |
|||
x = cx + (r0 - distance) * mathCos(middleAngle); |
|||
y = cy + (r0 - distance) * mathSin(middleAngle); |
|||
textAlign = 'center'; |
|||
textVerticalAlign = 'top'; |
|||
break; |
|||
|
|||
case 'insideStartArc': |
|||
x = cx + (r0 + distance) * mathCos(middleAngle); |
|||
y = cy + (r0 + distance) * mathSin(middleAngle); |
|||
textAlign = 'center'; |
|||
textVerticalAlign = 'bottom'; |
|||
break; |
|||
|
|||
case 'startAngle': |
|||
x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, distance + extraDist, false); |
|||
y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, distance + extraDist, false); |
|||
textAlign = 'right'; |
|||
textVerticalAlign = 'middle'; |
|||
break; |
|||
|
|||
case 'insideStartAngle': |
|||
x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, -distance + extraDist, false); |
|||
y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, -distance + extraDist, false); |
|||
textAlign = 'left'; |
|||
textVerticalAlign = 'middle'; |
|||
break; |
|||
|
|||
case 'middle': |
|||
x = cx + middleR * mathCos(middleAngle); |
|||
y = cy + middleR * mathSin(middleAngle); |
|||
textAlign = 'center'; |
|||
textVerticalAlign = 'middle'; |
|||
break; |
|||
|
|||
case 'endArc': |
|||
x = cx + (r + distance) * mathCos(middleAngle); |
|||
y = cy + (r + distance) * mathSin(middleAngle); |
|||
textAlign = 'center'; |
|||
textVerticalAlign = 'bottom'; |
|||
break; |
|||
|
|||
case 'insideEndArc': |
|||
x = cx + (r - distance) * mathCos(middleAngle); |
|||
y = cy + (r - distance) * mathSin(middleAngle); |
|||
textAlign = 'center'; |
|||
textVerticalAlign = 'top'; |
|||
break; |
|||
|
|||
case 'endAngle': |
|||
x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, distance + extraDist, true); |
|||
y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, distance + extraDist, true); |
|||
textAlign = 'left'; |
|||
textVerticalAlign = 'middle'; |
|||
break; |
|||
|
|||
case 'insideEndAngle': |
|||
x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, -distance + extraDist, true); |
|||
y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, -distance + extraDist, true); |
|||
textAlign = 'right'; |
|||
textVerticalAlign = 'middle'; |
|||
break; |
|||
|
|||
default: |
|||
return calculateTextPosition(out, opts, boundingRect); |
|||
} |
|||
|
|||
out = out || {}; |
|||
out.x = x; |
|||
out.y = y; |
|||
out.align = textAlign; |
|||
out.verticalAlign = textVerticalAlign; |
|||
return out; |
|||
}; |
|||
} |
|||
export function setSectorTextRotation(sector, textPosition, positionMapping, rotateType) { |
|||
if (isNumber(rotateType)) { |
|||
// user-set rotation
|
|||
sector.setTextConfig({ |
|||
rotation: rotateType |
|||
}); |
|||
return; |
|||
} else if (isArray(textPosition)) { |
|||
// user-set position, use 0 as auto rotation
|
|||
sector.setTextConfig({ |
|||
rotation: 0 |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
var shape = sector.shape; |
|||
var startAngle = shape.clockwise ? shape.startAngle : shape.endAngle; |
|||
var endAngle = shape.clockwise ? shape.endAngle : shape.startAngle; |
|||
var middleAngle = (startAngle + endAngle) / 2; |
|||
var anchorAngle; |
|||
var mappedSectorPosition = positionMapping(textPosition); |
|||
|
|||
switch (mappedSectorPosition) { |
|||
case 'startArc': |
|||
case 'insideStartArc': |
|||
case 'middle': |
|||
case 'insideEndArc': |
|||
case 'endArc': |
|||
anchorAngle = middleAngle; |
|||
break; |
|||
|
|||
case 'startAngle': |
|||
case 'insideStartAngle': |
|||
anchorAngle = startAngle; |
|||
break; |
|||
|
|||
case 'endAngle': |
|||
case 'insideEndAngle': |
|||
anchorAngle = endAngle; |
|||
break; |
|||
|
|||
default: |
|||
sector.setTextConfig({ |
|||
rotation: 0 |
|||
}); |
|||
return; |
|||
} |
|||
|
|||
var rotate = Math.PI * 1.5 - anchorAngle; |
|||
/** |
|||
* TODO: labels with rotate > Math.PI / 2 should be rotate another |
|||
* half round flipped to increase readability. However, only middle |
|||
* position supports this for now, because in other positions, the |
|||
* anchor point is not at the center of the text, so the positions |
|||
* after rotating is not as expected. |
|||
*/ |
|||
|
|||
if (mappedSectorPosition === 'middle' && rotate > Math.PI / 2 && rotate < Math.PI * 1.5) { |
|||
rotate -= Math.PI; |
|||
} |
|||
|
|||
sector.setTextConfig({ |
|||
rotation: rotate |
|||
}); |
|||
} |
|||
|
|||
function adjustAngleDistanceX(angle, distance, isEnd) { |
|||
return distance * Math.sin(angle) * (isEnd ? -1 : 1); |
|||
} |
|||
|
|||
function adjustAngleDistanceY(angle, distance, isEnd) { |
|||
return distance * Math.cos(angle) * (isEnd ? 1 : -1); |
|||
} |
|||
@ -0,0 +1,538 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { each, defaults, keys } from 'zrender/lib/core/util.js'; |
|||
import { parsePercent } from '../util/number.js'; |
|||
import { isDimensionStacked } from '../data/helper/dataStackHelper.js'; |
|||
import createRenderPlanner from '../chart/helper/createRenderPlanner.js'; |
|||
import { createFloat32Array } from '../util/vendor.js'; |
|||
var STACK_PREFIX = '__ec_stack_'; |
|||
|
|||
function getSeriesStackId(seriesModel) { |
|||
return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex; |
|||
} |
|||
|
|||
function getAxisKey(axis) { |
|||
return axis.dim + axis.index; |
|||
} |
|||
/** |
|||
* @return {Object} {width, offset, offsetCenter} If axis.type is not 'category', return undefined. |
|||
*/ |
|||
|
|||
|
|||
export function getLayoutOnAxis(opt) { |
|||
var params = []; |
|||
var baseAxis = opt.axis; |
|||
var axisKey = 'axis0'; |
|||
|
|||
if (baseAxis.type !== 'category') { |
|||
return; |
|||
} |
|||
|
|||
var bandWidth = baseAxis.getBandWidth(); |
|||
|
|||
for (var i = 0; i < opt.count || 0; i++) { |
|||
params.push(defaults({ |
|||
bandWidth: bandWidth, |
|||
axisKey: axisKey, |
|||
stackId: STACK_PREFIX + i |
|||
}, opt)); |
|||
} |
|||
|
|||
var widthAndOffsets = doCalBarWidthAndOffset(params); |
|||
var result = []; |
|||
|
|||
for (var i = 0; i < opt.count; i++) { |
|||
var item = widthAndOffsets[axisKey][STACK_PREFIX + i]; |
|||
item.offsetCenter = item.offset + item.width / 2; |
|||
result.push(item); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
export function prepareLayoutBarSeries(seriesType, ecModel) { |
|||
var seriesModels = []; |
|||
ecModel.eachSeriesByType(seriesType, function (seriesModel) { |
|||
// Check series coordinate, do layout for cartesian2d only
|
|||
if (isOnCartesian(seriesModel)) { |
|||
seriesModels.push(seriesModel); |
|||
} |
|||
}); |
|||
return seriesModels; |
|||
} |
|||
/** |
|||
* Map from (baseAxis.dim + '_' + baseAxis.index) to min gap of two adjacent |
|||
* values. |
|||
* This works for time axes, value axes, and log axes. |
|||
* For a single time axis, return value is in the form like |
|||
* {'x_0': [1000000]}. |
|||
* The value of 1000000 is in milliseconds. |
|||
*/ |
|||
|
|||
function getValueAxesMinGaps(barSeries) { |
|||
/** |
|||
* Map from axis.index to values. |
|||
* For a single time axis, axisValues is in the form like |
|||
* {'x_0': [1495555200000, 1495641600000, 1495728000000]}. |
|||
* Items in axisValues[x], e.g. 1495555200000, are time values of all |
|||
* series. |
|||
*/ |
|||
var axisValues = {}; |
|||
each(barSeries, function (seriesModel) { |
|||
var cartesian = seriesModel.coordinateSystem; |
|||
var baseAxis = cartesian.getBaseAxis(); |
|||
|
|||
if (baseAxis.type !== 'time' && baseAxis.type !== 'value') { |
|||
return; |
|||
} |
|||
|
|||
var data = seriesModel.getData(); |
|||
var key = baseAxis.dim + '_' + baseAxis.index; |
|||
var dimIdx = data.getDimensionIndex(data.mapDimension(baseAxis.dim)); |
|||
var store = data.getStore(); |
|||
|
|||
for (var i = 0, cnt = store.count(); i < cnt; ++i) { |
|||
var value = store.get(dimIdx, i); |
|||
|
|||
if (!axisValues[key]) { |
|||
// No previous data for the axis
|
|||
axisValues[key] = [value]; |
|||
} else { |
|||
// No value in previous series
|
|||
axisValues[key].push(value); |
|||
} // Ignore duplicated time values in the same axis
|
|||
|
|||
} |
|||
}); |
|||
var axisMinGaps = {}; |
|||
|
|||
for (var key in axisValues) { |
|||
if (axisValues.hasOwnProperty(key)) { |
|||
var valuesInAxis = axisValues[key]; |
|||
|
|||
if (valuesInAxis) { |
|||
// Sort axis values into ascending order to calculate gaps
|
|||
valuesInAxis.sort(function (a, b) { |
|||
return a - b; |
|||
}); |
|||
var min = null; |
|||
|
|||
for (var j = 1; j < valuesInAxis.length; ++j) { |
|||
var delta = valuesInAxis[j] - valuesInAxis[j - 1]; |
|||
|
|||
if (delta > 0) { |
|||
// Ignore 0 delta because they are of the same axis value
|
|||
min = min === null ? delta : Math.min(min, delta); |
|||
} |
|||
} // Set to null if only have one data
|
|||
|
|||
|
|||
axisMinGaps[key] = min; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return axisMinGaps; |
|||
} |
|||
|
|||
export function makeColumnLayout(barSeries) { |
|||
var axisMinGaps = getValueAxesMinGaps(barSeries); |
|||
var seriesInfoList = []; |
|||
each(barSeries, function (seriesModel) { |
|||
var cartesian = seriesModel.coordinateSystem; |
|||
var baseAxis = cartesian.getBaseAxis(); |
|||
var axisExtent = baseAxis.getExtent(); |
|||
var bandWidth; |
|||
|
|||
if (baseAxis.type === 'category') { |
|||
bandWidth = baseAxis.getBandWidth(); |
|||
} else if (baseAxis.type === 'value' || baseAxis.type === 'time') { |
|||
var key = baseAxis.dim + '_' + baseAxis.index; |
|||
var minGap = axisMinGaps[key]; |
|||
var extentSpan = Math.abs(axisExtent[1] - axisExtent[0]); |
|||
var scale = baseAxis.scale.getExtent(); |
|||
var scaleSpan = Math.abs(scale[1] - scale[0]); |
|||
bandWidth = minGap ? extentSpan / scaleSpan * minGap : extentSpan; // When there is only one data value
|
|||
} else { |
|||
var data = seriesModel.getData(); |
|||
bandWidth = Math.abs(axisExtent[1] - axisExtent[0]) / data.count(); |
|||
} |
|||
|
|||
var barWidth = parsePercent(seriesModel.get('barWidth'), bandWidth); |
|||
var barMaxWidth = parsePercent(seriesModel.get('barMaxWidth'), bandWidth); |
|||
var barMinWidth = parsePercent( // barMinWidth by default is 0.5 / 1 in cartesian. Because in value axis,
|
|||
// the auto-calculated bar width might be less than 0.5 / 1.
|
|||
seriesModel.get('barMinWidth') || (isInLargeMode(seriesModel) ? 0.5 : 1), bandWidth); |
|||
var barGap = seriesModel.get('barGap'); |
|||
var barCategoryGap = seriesModel.get('barCategoryGap'); |
|||
seriesInfoList.push({ |
|||
bandWidth: bandWidth, |
|||
barWidth: barWidth, |
|||
barMaxWidth: barMaxWidth, |
|||
barMinWidth: barMinWidth, |
|||
barGap: barGap, |
|||
barCategoryGap: barCategoryGap, |
|||
axisKey: getAxisKey(baseAxis), |
|||
stackId: getSeriesStackId(seriesModel) |
|||
}); |
|||
}); |
|||
return doCalBarWidthAndOffset(seriesInfoList); |
|||
} |
|||
|
|||
function doCalBarWidthAndOffset(seriesInfoList) { |
|||
// Columns info on each category axis. Key is cartesian name
|
|||
var columnsMap = {}; |
|||
each(seriesInfoList, function (seriesInfo, idx) { |
|||
var axisKey = seriesInfo.axisKey; |
|||
var bandWidth = seriesInfo.bandWidth; |
|||
var columnsOnAxis = columnsMap[axisKey] || { |
|||
bandWidth: bandWidth, |
|||
remainedWidth: bandWidth, |
|||
autoWidthCount: 0, |
|||
categoryGap: null, |
|||
gap: '20%', |
|||
stacks: {} |
|||
}; |
|||
var stacks = columnsOnAxis.stacks; |
|||
columnsMap[axisKey] = columnsOnAxis; |
|||
var stackId = seriesInfo.stackId; |
|||
|
|||
if (!stacks[stackId]) { |
|||
columnsOnAxis.autoWidthCount++; |
|||
} |
|||
|
|||
stacks[stackId] = stacks[stackId] || { |
|||
width: 0, |
|||
maxWidth: 0 |
|||
}; // Caution: In a single coordinate system, these barGrid attributes
|
|||
// will be shared by series. Consider that they have default values,
|
|||
// only the attributes set on the last series will work.
|
|||
// Do not change this fact unless there will be a break change.
|
|||
|
|||
var barWidth = seriesInfo.barWidth; |
|||
|
|||
if (barWidth && !stacks[stackId].width) { |
|||
// See #6312, do not restrict width.
|
|||
stacks[stackId].width = barWidth; |
|||
barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth); |
|||
columnsOnAxis.remainedWidth -= barWidth; |
|||
} |
|||
|
|||
var barMaxWidth = seriesInfo.barMaxWidth; |
|||
barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth); |
|||
var barMinWidth = seriesInfo.barMinWidth; |
|||
barMinWidth && (stacks[stackId].minWidth = barMinWidth); |
|||
var barGap = seriesInfo.barGap; |
|||
barGap != null && (columnsOnAxis.gap = barGap); |
|||
var barCategoryGap = seriesInfo.barCategoryGap; |
|||
barCategoryGap != null && (columnsOnAxis.categoryGap = barCategoryGap); |
|||
}); |
|||
var result = {}; |
|||
each(columnsMap, function (columnsOnAxis, coordSysName) { |
|||
result[coordSysName] = {}; |
|||
var stacks = columnsOnAxis.stacks; |
|||
var bandWidth = columnsOnAxis.bandWidth; |
|||
var categoryGapPercent = columnsOnAxis.categoryGap; |
|||
|
|||
if (categoryGapPercent == null) { |
|||
var columnCount = keys(stacks).length; // More columns in one group
|
|||
// the spaces between group is smaller. Or the column will be too thin.
|
|||
|
|||
categoryGapPercent = Math.max(35 - columnCount * 4, 15) + '%'; |
|||
} |
|||
|
|||
var categoryGap = parsePercent(categoryGapPercent, bandWidth); |
|||
var barGapPercent = parsePercent(columnsOnAxis.gap, 1); |
|||
var remainedWidth = columnsOnAxis.remainedWidth; |
|||
var autoWidthCount = columnsOnAxis.autoWidthCount; |
|||
var autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent); |
|||
autoWidth = Math.max(autoWidth, 0); // Find if any auto calculated bar exceeded maxBarWidth
|
|||
|
|||
each(stacks, function (column) { |
|||
var maxWidth = column.maxWidth; |
|||
var minWidth = column.minWidth; |
|||
|
|||
if (!column.width) { |
|||
var finalWidth = autoWidth; |
|||
|
|||
if (maxWidth && maxWidth < finalWidth) { |
|||
finalWidth = Math.min(maxWidth, remainedWidth); |
|||
} // `minWidth` has higher priority. `minWidth` decide that wheter the
|
|||
// bar is able to be visible. So `minWidth` should not be restricted
|
|||
// by `maxWidth` or `remainedWidth` (which is from `bandWidth`). In
|
|||
// the extreme cases for `value` axis, bars are allowed to overlap
|
|||
// with each other if `minWidth` specified.
|
|||
|
|||
|
|||
if (minWidth && minWidth > finalWidth) { |
|||
finalWidth = minWidth; |
|||
} |
|||
|
|||
if (finalWidth !== autoWidth) { |
|||
column.width = finalWidth; |
|||
remainedWidth -= finalWidth + barGapPercent * finalWidth; |
|||
autoWidthCount--; |
|||
} |
|||
} else { |
|||
// `barMinWidth/barMaxWidth` has higher priority than `barWidth`, as
|
|||
// CSS does. Becuase barWidth can be a percent value, where
|
|||
// `barMaxWidth` can be used to restrict the final width.
|
|||
var finalWidth = column.width; |
|||
|
|||
if (maxWidth) { |
|||
finalWidth = Math.min(finalWidth, maxWidth); |
|||
} // `minWidth` has higher priority, as described above
|
|||
|
|||
|
|||
if (minWidth) { |
|||
finalWidth = Math.max(finalWidth, minWidth); |
|||
} |
|||
|
|||
column.width = finalWidth; |
|||
remainedWidth -= finalWidth + barGapPercent * finalWidth; |
|||
autoWidthCount--; |
|||
} |
|||
}); // Recalculate width again
|
|||
|
|||
autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent); |
|||
autoWidth = Math.max(autoWidth, 0); |
|||
var widthSum = 0; |
|||
var lastColumn; |
|||
each(stacks, function (column, idx) { |
|||
if (!column.width) { |
|||
column.width = autoWidth; |
|||
} |
|||
|
|||
lastColumn = column; |
|||
widthSum += column.width * (1 + barGapPercent); |
|||
}); |
|||
|
|||
if (lastColumn) { |
|||
widthSum -= lastColumn.width * barGapPercent; |
|||
} |
|||
|
|||
var offset = -widthSum / 2; |
|||
each(stacks, function (column, stackId) { |
|||
result[coordSysName][stackId] = result[coordSysName][stackId] || { |
|||
bandWidth: bandWidth, |
|||
offset: offset, |
|||
width: column.width |
|||
}; |
|||
offset += column.width * (1 + barGapPercent); |
|||
}); |
|||
}); |
|||
return result; |
|||
} |
|||
|
|||
function retrieveColumnLayout(barWidthAndOffset, axis, seriesModel) { |
|||
if (barWidthAndOffset && axis) { |
|||
var result = barWidthAndOffset[getAxisKey(axis)]; |
|||
|
|||
if (result != null && seriesModel != null) { |
|||
return result[getSeriesStackId(seriesModel)]; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
} |
|||
|
|||
export { retrieveColumnLayout }; |
|||
export function layout(seriesType, ecModel) { |
|||
var seriesModels = prepareLayoutBarSeries(seriesType, ecModel); |
|||
var barWidthAndOffset = makeColumnLayout(seriesModels); |
|||
each(seriesModels, function (seriesModel) { |
|||
var data = seriesModel.getData(); |
|||
var cartesian = seriesModel.coordinateSystem; |
|||
var baseAxis = cartesian.getBaseAxis(); |
|||
var stackId = getSeriesStackId(seriesModel); |
|||
var columnLayoutInfo = barWidthAndOffset[getAxisKey(baseAxis)][stackId]; |
|||
var columnOffset = columnLayoutInfo.offset; |
|||
var columnWidth = columnLayoutInfo.width; |
|||
data.setLayout({ |
|||
bandWidth: columnLayoutInfo.bandWidth, |
|||
offset: columnOffset, |
|||
size: columnWidth |
|||
}); |
|||
}); |
|||
} // TODO: Do not support stack in large mode yet.
|
|||
|
|||
export function createProgressiveLayout(seriesType) { |
|||
return { |
|||
seriesType: seriesType, |
|||
plan: createRenderPlanner(), |
|||
reset: function (seriesModel) { |
|||
if (!isOnCartesian(seriesModel)) { |
|||
return; |
|||
} |
|||
|
|||
var data = seriesModel.getData(); |
|||
var cartesian = seriesModel.coordinateSystem; |
|||
var baseAxis = cartesian.getBaseAxis(); |
|||
var valueAxis = cartesian.getOtherAxis(baseAxis); |
|||
var valueDimIdx = data.getDimensionIndex(data.mapDimension(valueAxis.dim)); |
|||
var baseDimIdx = data.getDimensionIndex(data.mapDimension(baseAxis.dim)); |
|||
var drawBackground = seriesModel.get('showBackground', true); |
|||
var valueDim = data.mapDimension(valueAxis.dim); |
|||
var stackResultDim = data.getCalculationInfo('stackResultDimension'); |
|||
var stacked = isDimensionStacked(data, valueDim) && !!data.getCalculationInfo('stackedOnSeries'); |
|||
var isValueAxisH = valueAxis.isHorizontal(); |
|||
var valueAxisStart = getValueAxisStart(baseAxis, valueAxis); |
|||
var isLarge = isInLargeMode(seriesModel); |
|||
var barMinHeight = seriesModel.get('barMinHeight') || 0; |
|||
var stackedDimIdx = stackResultDim && data.getDimensionIndex(stackResultDim); // Layout info.
|
|||
|
|||
var columnWidth = data.getLayout('size'); |
|||
var columnOffset = data.getLayout('offset'); |
|||
return { |
|||
progress: function (params, data) { |
|||
var count = params.count; |
|||
var largePoints = isLarge && createFloat32Array(count * 3); |
|||
var largeBackgroundPoints = isLarge && drawBackground && createFloat32Array(count * 3); |
|||
var largeDataIndices = isLarge && createFloat32Array(count); |
|||
var coordLayout = cartesian.master.getRect(); |
|||
var bgSize = isValueAxisH ? coordLayout.width : coordLayout.height; |
|||
var dataIndex; |
|||
var store = data.getStore(); |
|||
var idxOffset = 0; |
|||
|
|||
while ((dataIndex = params.next()) != null) { |
|||
var value = store.get(stacked ? stackedDimIdx : valueDimIdx, dataIndex); |
|||
var baseValue = store.get(baseDimIdx, dataIndex); |
|||
var baseCoord = valueAxisStart; |
|||
var startValue = void 0; // Because of the barMinHeight, we can not use the value in
|
|||
// stackResultDimension directly.
|
|||
|
|||
if (stacked) { |
|||
startValue = +value - store.get(valueDimIdx, dataIndex); |
|||
} |
|||
|
|||
var x = void 0; |
|||
var y = void 0; |
|||
var width = void 0; |
|||
var height = void 0; |
|||
|
|||
if (isValueAxisH) { |
|||
var coord = cartesian.dataToPoint([value, baseValue]); |
|||
|
|||
if (stacked) { |
|||
var startCoord = cartesian.dataToPoint([startValue, baseValue]); |
|||
baseCoord = startCoord[0]; |
|||
} |
|||
|
|||
x = baseCoord; |
|||
y = coord[1] + columnOffset; |
|||
width = coord[0] - baseCoord; |
|||
height = columnWidth; |
|||
|
|||
if (Math.abs(width) < barMinHeight) { |
|||
width = (width < 0 ? -1 : 1) * barMinHeight; |
|||
} |
|||
} else { |
|||
var coord = cartesian.dataToPoint([baseValue, value]); |
|||
|
|||
if (stacked) { |
|||
var startCoord = cartesian.dataToPoint([baseValue, startValue]); |
|||
baseCoord = startCoord[1]; |
|||
} |
|||
|
|||
x = coord[0] + columnOffset; |
|||
y = baseCoord; |
|||
width = columnWidth; |
|||
height = coord[1] - baseCoord; |
|||
|
|||
if (Math.abs(height) < barMinHeight) { |
|||
// Include zero to has a positive bar
|
|||
height = (height <= 0 ? -1 : 1) * barMinHeight; |
|||
} |
|||
} |
|||
|
|||
if (!isLarge) { |
|||
data.setItemLayout(dataIndex, { |
|||
x: x, |
|||
y: y, |
|||
width: width, |
|||
height: height |
|||
}); |
|||
} else { |
|||
largePoints[idxOffset] = x; |
|||
largePoints[idxOffset + 1] = y; |
|||
largePoints[idxOffset + 2] = isValueAxisH ? width : height; |
|||
|
|||
if (largeBackgroundPoints) { |
|||
largeBackgroundPoints[idxOffset] = isValueAxisH ? coordLayout.x : x; |
|||
largeBackgroundPoints[idxOffset + 1] = isValueAxisH ? y : coordLayout.y; |
|||
largeBackgroundPoints[idxOffset + 2] = bgSize; |
|||
} |
|||
|
|||
largeDataIndices[dataIndex] = dataIndex; |
|||
} |
|||
|
|||
idxOffset += 3; |
|||
} |
|||
|
|||
if (isLarge) { |
|||
data.setLayout({ |
|||
largePoints: largePoints, |
|||
largeDataIndices: largeDataIndices, |
|||
largeBackgroundPoints: largeBackgroundPoints, |
|||
valueAxisHorizontal: isValueAxisH |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
}; |
|||
} |
|||
|
|||
function isOnCartesian(seriesModel) { |
|||
return seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d'; |
|||
} |
|||
|
|||
function isInLargeMode(seriesModel) { |
|||
return seriesModel.pipelineContext && seriesModel.pipelineContext.large; |
|||
} // See cases in `test/bar-start.html` and `#7412`, `#8747`.
|
|||
|
|||
|
|||
function getValueAxisStart(baseAxis, valueAxis) { |
|||
return valueAxis.toGlobalCoord(valueAxis.dataToCoord(valueAxis.type === 'log' ? 1 : 0)); |
|||
} |
|||
@ -0,0 +1,282 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 * as zrUtil from 'zrender/lib/core/util.js'; |
|||
import { parsePercent } from '../util/number.js'; |
|||
import { isDimensionStacked } from '../data/helper/dataStackHelper.js'; |
|||
|
|||
function getSeriesStackId(seriesModel) { |
|||
return seriesModel.get('stack') || '__ec_stack_' + seriesModel.seriesIndex; |
|||
} |
|||
|
|||
function getAxisKey(polar, axis) { |
|||
return axis.dim + polar.model.componentIndex; |
|||
} |
|||
|
|||
function barLayoutPolar(seriesType, ecModel, api) { |
|||
var lastStackCoords = {}; |
|||
var barWidthAndOffset = calRadialBar(zrUtil.filter(ecModel.getSeriesByType(seriesType), function (seriesModel) { |
|||
return !ecModel.isSeriesFiltered(seriesModel) && seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'polar'; |
|||
})); |
|||
ecModel.eachSeriesByType(seriesType, function (seriesModel) { |
|||
// Check series coordinate, do layout for polar only
|
|||
if (seriesModel.coordinateSystem.type !== 'polar') { |
|||
return; |
|||
} |
|||
|
|||
var data = seriesModel.getData(); |
|||
var polar = seriesModel.coordinateSystem; |
|||
var baseAxis = polar.getBaseAxis(); |
|||
var axisKey = getAxisKey(polar, baseAxis); |
|||
var stackId = getSeriesStackId(seriesModel); |
|||
var columnLayoutInfo = barWidthAndOffset[axisKey][stackId]; |
|||
var columnOffset = columnLayoutInfo.offset; |
|||
var columnWidth = columnLayoutInfo.width; |
|||
var valueAxis = polar.getOtherAxis(baseAxis); |
|||
var cx = seriesModel.coordinateSystem.cx; |
|||
var cy = seriesModel.coordinateSystem.cy; |
|||
var barMinHeight = seriesModel.get('barMinHeight') || 0; |
|||
var barMinAngle = seriesModel.get('barMinAngle') || 0; |
|||
lastStackCoords[stackId] = lastStackCoords[stackId] || []; |
|||
var valueDim = data.mapDimension(valueAxis.dim); |
|||
var baseDim = data.mapDimension(baseAxis.dim); |
|||
var stacked = isDimensionStacked(data, valueDim |
|||
/*, baseDim*/ |
|||
); |
|||
var clampLayout = baseAxis.dim !== 'radius' || !seriesModel.get('roundCap', true); |
|||
var valueAxisStart = valueAxis.dataToCoord(0); |
|||
|
|||
for (var idx = 0, len = data.count(); idx < len; idx++) { |
|||
var value = data.get(valueDim, idx); |
|||
var baseValue = data.get(baseDim, idx); |
|||
var sign = value >= 0 ? 'p' : 'n'; |
|||
var baseCoord = valueAxisStart; // Because of the barMinHeight, we can not use the value in
|
|||
// stackResultDimension directly.
|
|||
// Only ordinal axis can be stacked.
|
|||
|
|||
if (stacked) { |
|||
if (!lastStackCoords[stackId][baseValue]) { |
|||
lastStackCoords[stackId][baseValue] = { |
|||
p: valueAxisStart, |
|||
n: valueAxisStart // Negative stack
|
|||
|
|||
}; |
|||
} // Should also consider #4243
|
|||
|
|||
|
|||
baseCoord = lastStackCoords[stackId][baseValue][sign]; |
|||
} |
|||
|
|||
var r0 = void 0; |
|||
var r = void 0; |
|||
var startAngle = void 0; |
|||
var endAngle = void 0; // radial sector
|
|||
|
|||
if (valueAxis.dim === 'radius') { |
|||
var radiusSpan = valueAxis.dataToCoord(value) - valueAxisStart; |
|||
var angle = baseAxis.dataToCoord(baseValue); |
|||
|
|||
if (Math.abs(radiusSpan) < barMinHeight) { |
|||
radiusSpan = (radiusSpan < 0 ? -1 : 1) * barMinHeight; |
|||
} |
|||
|
|||
r0 = baseCoord; |
|||
r = baseCoord + radiusSpan; |
|||
startAngle = angle - columnOffset; |
|||
endAngle = startAngle - columnWidth; |
|||
stacked && (lastStackCoords[stackId][baseValue][sign] = r); |
|||
} // tangential sector
|
|||
else { |
|||
var angleSpan = valueAxis.dataToCoord(value, clampLayout) - valueAxisStart; |
|||
var radius = baseAxis.dataToCoord(baseValue); |
|||
|
|||
if (Math.abs(angleSpan) < barMinAngle) { |
|||
angleSpan = (angleSpan < 0 ? -1 : 1) * barMinAngle; |
|||
} |
|||
|
|||
r0 = radius + columnOffset; |
|||
r = r0 + columnWidth; |
|||
startAngle = baseCoord; |
|||
endAngle = baseCoord + angleSpan; // if the previous stack is at the end of the ring,
|
|||
// add a round to differentiate it from origin
|
|||
// let extent = angleAxis.getExtent();
|
|||
// let stackCoord = angle;
|
|||
// if (stackCoord === extent[0] && value > 0) {
|
|||
// stackCoord = extent[1];
|
|||
// }
|
|||
// else if (stackCoord === extent[1] && value < 0) {
|
|||
// stackCoord = extent[0];
|
|||
// }
|
|||
|
|||
stacked && (lastStackCoords[stackId][baseValue][sign] = endAngle); |
|||
} |
|||
|
|||
data.setItemLayout(idx, { |
|||
cx: cx, |
|||
cy: cy, |
|||
r0: r0, |
|||
r: r, |
|||
// Consider that positive angle is anti-clockwise,
|
|||
// while positive radian of sector is clockwise
|
|||
startAngle: -startAngle * Math.PI / 180, |
|||
endAngle: -endAngle * Math.PI / 180, |
|||
|
|||
/** |
|||
* Keep the same logic with bar in catesion: use end value to |
|||
* control direction. Notice that if clockwise is true (by |
|||
* default), the sector will always draw clockwisely, no matter |
|||
* whether endAngle is greater or less than startAngle. |
|||
*/ |
|||
clockwise: startAngle >= endAngle |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
/** |
|||
* Calculate bar width and offset for radial bar charts |
|||
*/ |
|||
|
|||
|
|||
function calRadialBar(barSeries) { |
|||
// Columns info on each category axis. Key is polar name
|
|||
var columnsMap = {}; |
|||
zrUtil.each(barSeries, function (seriesModel, idx) { |
|||
var data = seriesModel.getData(); |
|||
var polar = seriesModel.coordinateSystem; |
|||
var baseAxis = polar.getBaseAxis(); |
|||
var axisKey = getAxisKey(polar, baseAxis); |
|||
var axisExtent = baseAxis.getExtent(); |
|||
var bandWidth = baseAxis.type === 'category' ? baseAxis.getBandWidth() : Math.abs(axisExtent[1] - axisExtent[0]) / data.count(); |
|||
var columnsOnAxis = columnsMap[axisKey] || { |
|||
bandWidth: bandWidth, |
|||
remainedWidth: bandWidth, |
|||
autoWidthCount: 0, |
|||
categoryGap: '20%', |
|||
gap: '30%', |
|||
stacks: {} |
|||
}; |
|||
var stacks = columnsOnAxis.stacks; |
|||
columnsMap[axisKey] = columnsOnAxis; |
|||
var stackId = getSeriesStackId(seriesModel); |
|||
|
|||
if (!stacks[stackId]) { |
|||
columnsOnAxis.autoWidthCount++; |
|||
} |
|||
|
|||
stacks[stackId] = stacks[stackId] || { |
|||
width: 0, |
|||
maxWidth: 0 |
|||
}; |
|||
var barWidth = parsePercent(seriesModel.get('barWidth'), bandWidth); |
|||
var barMaxWidth = parsePercent(seriesModel.get('barMaxWidth'), bandWidth); |
|||
var barGap = seriesModel.get('barGap'); |
|||
var barCategoryGap = seriesModel.get('barCategoryGap'); |
|||
|
|||
if (barWidth && !stacks[stackId].width) { |
|||
barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth); |
|||
stacks[stackId].width = barWidth; |
|||
columnsOnAxis.remainedWidth -= barWidth; |
|||
} |
|||
|
|||
barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth); |
|||
barGap != null && (columnsOnAxis.gap = barGap); |
|||
barCategoryGap != null && (columnsOnAxis.categoryGap = barCategoryGap); |
|||
}); |
|||
var result = {}; |
|||
zrUtil.each(columnsMap, function (columnsOnAxis, coordSysName) { |
|||
result[coordSysName] = {}; |
|||
var stacks = columnsOnAxis.stacks; |
|||
var bandWidth = columnsOnAxis.bandWidth; |
|||
var categoryGap = parsePercent(columnsOnAxis.categoryGap, bandWidth); |
|||
var barGapPercent = parsePercent(columnsOnAxis.gap, 1); |
|||
var remainedWidth = columnsOnAxis.remainedWidth; |
|||
var autoWidthCount = columnsOnAxis.autoWidthCount; |
|||
var autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent); |
|||
autoWidth = Math.max(autoWidth, 0); // Find if any auto calculated bar exceeded maxBarWidth
|
|||
|
|||
zrUtil.each(stacks, function (column, stack) { |
|||
var maxWidth = column.maxWidth; |
|||
|
|||
if (maxWidth && maxWidth < autoWidth) { |
|||
maxWidth = Math.min(maxWidth, remainedWidth); |
|||
|
|||
if (column.width) { |
|||
maxWidth = Math.min(maxWidth, column.width); |
|||
} |
|||
|
|||
remainedWidth -= maxWidth; |
|||
column.width = maxWidth; |
|||
autoWidthCount--; |
|||
} |
|||
}); // Recalculate width again
|
|||
|
|||
autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent); |
|||
autoWidth = Math.max(autoWidth, 0); |
|||
var widthSum = 0; |
|||
var lastColumn; |
|||
zrUtil.each(stacks, function (column, idx) { |
|||
if (!column.width) { |
|||
column.width = autoWidth; |
|||
} |
|||
|
|||
lastColumn = column; |
|||
widthSum += column.width * (1 + barGapPercent); |
|||
}); |
|||
|
|||
if (lastColumn) { |
|||
widthSum -= lastColumn.width * barGapPercent; |
|||
} |
|||
|
|||
var offset = -widthSum / 2; |
|||
zrUtil.each(stacks, function (column, stackId) { |
|||
result[coordSysName][stackId] = result[coordSysName][stackId] || { |
|||
offset: offset, |
|||
width: column.width |
|||
}; |
|||
offset += column.width * (1 + barGapPercent); |
|||
}); |
|||
}); |
|||
return result; |
|||
} |
|||
|
|||
export default barLayoutPolar; |
|||
@ -0,0 +1,114 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { map } from 'zrender/lib/core/util.js'; |
|||
import createRenderPlanner from '../chart/helper/createRenderPlanner.js'; |
|||
import { isDimensionStacked } from '../data/helper/dataStackHelper.js'; |
|||
import { createFloat32Array } from '../util/vendor.js'; |
|||
export default function pointsLayout(seriesType, forceStoreInTypedArray) { |
|||
return { |
|||
seriesType: seriesType, |
|||
plan: createRenderPlanner(), |
|||
reset: function (seriesModel) { |
|||
var data = seriesModel.getData(); |
|||
var coordSys = seriesModel.coordinateSystem; |
|||
var pipelineContext = seriesModel.pipelineContext; |
|||
var useTypedArray = forceStoreInTypedArray || pipelineContext.large; |
|||
|
|||
if (!coordSys) { |
|||
return; |
|||
} |
|||
|
|||
var dims = map(coordSys.dimensions, function (dim) { |
|||
return data.mapDimension(dim); |
|||
}).slice(0, 2); |
|||
var dimLen = dims.length; |
|||
var stackResultDim = data.getCalculationInfo('stackResultDimension'); |
|||
|
|||
if (isDimensionStacked(data, dims[0])) { |
|||
dims[0] = stackResultDim; |
|||
} |
|||
|
|||
if (isDimensionStacked(data, dims[1])) { |
|||
dims[1] = stackResultDim; |
|||
} |
|||
|
|||
var store = data.getStore(); |
|||
var dimIdx0 = data.getDimensionIndex(dims[0]); |
|||
var dimIdx1 = data.getDimensionIndex(dims[1]); |
|||
return dimLen && { |
|||
progress: function (params, data) { |
|||
var segCount = params.end - params.start; |
|||
var points = useTypedArray && createFloat32Array(segCount * dimLen); |
|||
var tmpIn = []; |
|||
var tmpOut = []; |
|||
|
|||
for (var i = params.start, offset = 0; i < params.end; i++) { |
|||
var point = void 0; |
|||
|
|||
if (dimLen === 1) { |
|||
var x = store.get(dimIdx0, i); // NOTE: Make sure the second parameter is null to use default strategy.
|
|||
|
|||
point = coordSys.dataToPoint(x, null, tmpOut); |
|||
} else { |
|||
tmpIn[0] = store.get(dimIdx0, i); |
|||
tmpIn[1] = store.get(dimIdx1, i); // Let coordinate system to handle the NaN data.
|
|||
|
|||
point = coordSys.dataToPoint(tmpIn, null, tmpOut); |
|||
} |
|||
|
|||
if (useTypedArray) { |
|||
points[offset++] = point[0]; |
|||
points[offset++] = point[1]; |
|||
} else { |
|||
data.setItemLayout(i, point.slice()); |
|||
} |
|||
} |
|||
|
|||
useTypedArray && data.setLayout('points', points); |
|||
} |
|||
}; |
|||
} |
|||
}; |
|||
} |
|||
; |
|||
@ -0,0 +1,125 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { extend, each, isArray, isString } from 'zrender/lib/core/util.js'; |
|||
import { deprecateReplaceLog, deprecateLog } from '../util/log.js'; |
|||
import { queryDataIndex } from '../util/model.js'; // Legacy data selection action.
|
|||
// Inlucdes: pieSelect, pieUnSelect, pieToggleSelect, mapSelect, mapUnSelect, mapToggleSelect
|
|||
|
|||
export function createLegacyDataSelectAction(seriesType, ecRegisterAction) { |
|||
function getSeriesIndices(ecModel, payload) { |
|||
var seriesIndices = []; |
|||
ecModel.eachComponent({ |
|||
mainType: 'series', |
|||
subType: seriesType, |
|||
query: payload |
|||
}, function (seriesModel) { |
|||
seriesIndices.push(seriesModel.seriesIndex); |
|||
}); |
|||
return seriesIndices; |
|||
} |
|||
|
|||
each([[seriesType + 'ToggleSelect', 'toggleSelect'], [seriesType + 'Select', 'select'], [seriesType + 'UnSelect', 'unselect']], function (eventsMap) { |
|||
ecRegisterAction(eventsMap[0], function (payload, ecModel, api) { |
|||
payload = extend({}, payload); |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog(payload.type, eventsMap[1]); |
|||
} |
|||
|
|||
api.dispatchAction(extend(payload, { |
|||
type: eventsMap[1], |
|||
seriesIndex: getSeriesIndices(ecModel, payload) |
|||
})); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
function handleSeriesLegacySelectEvents(type, eventPostfix, ecIns, ecModel, payload) { |
|||
var legacyEventName = type + eventPostfix; |
|||
|
|||
if (!ecIns.isSilent(legacyEventName)) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateLog("event " + legacyEventName + " is deprecated."); |
|||
} |
|||
|
|||
ecModel.eachComponent({ |
|||
mainType: 'series', |
|||
subType: 'pie' |
|||
}, function (seriesModel) { |
|||
var seriesIndex = seriesModel.seriesIndex; |
|||
var selectedMap = seriesModel.option.selectedMap; |
|||
var selected = payload.selected; |
|||
|
|||
for (var i = 0; i < selected.length; i++) { |
|||
if (selected[i].seriesIndex === seriesIndex) { |
|||
var data = seriesModel.getData(); |
|||
var dataIndex = queryDataIndex(data, payload.fromActionPayload); |
|||
ecIns.trigger(legacyEventName, { |
|||
type: legacyEventName, |
|||
seriesId: seriesModel.id, |
|||
name: isArray(dataIndex) ? data.getName(dataIndex[0]) : data.getName(dataIndex), |
|||
selected: isString(selectedMap) ? selectedMap : extend({}, selectedMap) |
|||
}); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
export function handleLegacySelectEvents(messageCenter, ecIns, api) { |
|||
messageCenter.on('selectchanged', function (params) { |
|||
var ecModel = api.getModel(); |
|||
|
|||
if (params.isFromClick) { |
|||
handleSeriesLegacySelectEvents('map', 'selectchanged', ecIns, ecModel, params); |
|||
handleSeriesLegacySelectEvents('pie', 'selectchanged', ecIns, ecModel, params); |
|||
} else if (params.fromAction === 'select') { |
|||
handleSeriesLegacySelectEvents('map', 'selected', ecIns, ecModel, params); |
|||
handleSeriesLegacySelectEvents('pie', 'selected', ecIns, ecModel, params); |
|||
} else if (params.fromAction === 'unselect') { |
|||
handleSeriesLegacySelectEvents('map', 'unselected', ecIns, ecModel, params); |
|||
handleSeriesLegacySelectEvents('pie', 'unselected', ecIns, ecModel, params); |
|||
} |
|||
}); |
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { Text } from '../util/graphic.js'; |
|||
export function getTextRect(text, font, align, verticalAlign, padding, rich, truncate, lineHeight) { |
|||
var textEl = new Text({ |
|||
style: { |
|||
text: text, |
|||
font: font, |
|||
align: align, |
|||
verticalAlign: verticalAlign, |
|||
padding: padding, |
|||
rich: rich, |
|||
overflow: truncate ? 'truncate' : null, |
|||
lineHeight: lineHeight |
|||
} |
|||
}); |
|||
return textEl.getBoundingRect(); |
|||
} |
|||
@ -0,0 +1,162 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 * as zrUtil from 'zrender/lib/core/util.js'; |
|||
import * as graphic from '../util/graphic.js'; |
|||
var PI = Math.PI; |
|||
/** |
|||
* @param {module:echarts/ExtensionAPI} api |
|||
* @param {Object} [opts] |
|||
* @param {string} [opts.text] |
|||
* @param {string} [opts.color] |
|||
* @param {string} [opts.textColor] |
|||
* @return {module:zrender/Element} |
|||
*/ |
|||
|
|||
export default function defaultLoading(api, opts) { |
|||
opts = opts || {}; |
|||
zrUtil.defaults(opts, { |
|||
text: 'loading', |
|||
textColor: '#000', |
|||
fontSize: 12, |
|||
fontWeight: 'normal', |
|||
fontStyle: 'normal', |
|||
fontFamily: 'sans-serif', |
|||
maskColor: 'rgba(255, 255, 255, 0.8)', |
|||
showSpinner: true, |
|||
color: '#5470c6', |
|||
spinnerRadius: 10, |
|||
lineWidth: 5, |
|||
zlevel: 0 |
|||
}); |
|||
var group = new graphic.Group(); |
|||
var mask = new graphic.Rect({ |
|||
style: { |
|||
fill: opts.maskColor |
|||
}, |
|||
zlevel: opts.zlevel, |
|||
z: 10000 |
|||
}); |
|||
group.add(mask); |
|||
var textContent = new graphic.Text({ |
|||
style: { |
|||
text: opts.text, |
|||
fill: opts.textColor, |
|||
fontSize: opts.fontSize, |
|||
fontWeight: opts.fontWeight, |
|||
fontStyle: opts.fontStyle, |
|||
fontFamily: opts.fontFamily |
|||
}, |
|||
zlevel: opts.zlevel, |
|||
z: 10001 |
|||
}); |
|||
var labelRect = new graphic.Rect({ |
|||
style: { |
|||
fill: 'none' |
|||
}, |
|||
textContent: textContent, |
|||
textConfig: { |
|||
position: 'right', |
|||
distance: 10 |
|||
}, |
|||
zlevel: opts.zlevel, |
|||
z: 10001 |
|||
}); |
|||
group.add(labelRect); |
|||
var arc; |
|||
|
|||
if (opts.showSpinner) { |
|||
arc = new graphic.Arc({ |
|||
shape: { |
|||
startAngle: -PI / 2, |
|||
endAngle: -PI / 2 + 0.1, |
|||
r: opts.spinnerRadius |
|||
}, |
|||
style: { |
|||
stroke: opts.color, |
|||
lineCap: 'round', |
|||
lineWidth: opts.lineWidth |
|||
}, |
|||
zlevel: opts.zlevel, |
|||
z: 10001 |
|||
}); |
|||
arc.animateShape(true).when(1000, { |
|||
endAngle: PI * 3 / 2 |
|||
}).start('circularInOut'); |
|||
arc.animateShape(true).when(1000, { |
|||
startAngle: PI * 3 / 2 |
|||
}).delay(300).start('circularInOut'); |
|||
group.add(arc); |
|||
} // Inject resize
|
|||
|
|||
|
|||
group.resize = function () { |
|||
var textWidth = textContent.getBoundingRect().width; |
|||
var r = opts.showSpinner ? opts.spinnerRadius : 0; // cx = (containerWidth - arcDiameter - textDistance - textWidth) / 2
|
|||
// textDistance needs to be calculated when both animation and text exist
|
|||
|
|||
var cx = (api.getWidth() - r * 2 - (opts.showSpinner && textWidth ? 10 : 0) - textWidth) / 2 - (opts.showSpinner && textWidth ? 0 : 5 + textWidth / 2) // only show the text
|
|||
+ (opts.showSpinner ? 0 : textWidth / 2) // only show the spinner
|
|||
+ (textWidth ? 0 : r); |
|||
var cy = api.getHeight() / 2; |
|||
opts.showSpinner && arc.setShape({ |
|||
cx: cx, |
|||
cy: cy |
|||
}); |
|||
labelRect.setShape({ |
|||
x: cx - r, |
|||
y: cy - r, |
|||
width: r * 2, |
|||
height: r * 2 |
|||
}); |
|||
mask.setShape({ |
|||
x: 0, |
|||
y: 0, |
|||
width: api.getWidth(), |
|||
height: api.getHeight() |
|||
}); |
|||
}; |
|||
|
|||
group.resize(); |
|||
return group; |
|||
} |
|||
@ -0,0 +1,266 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { __extends } from "tslib"; |
|||
import * as zrUtil from 'zrender/lib/core/util.js'; |
|||
import Model from './Model.js'; |
|||
import * as componentUtil from '../util/component.js'; |
|||
import { enableClassManagement, parseClassType, isExtendedClass, mountExtend } from '../util/clazz.js'; |
|||
import { makeInner, queryReferringComponents } from '../util/model.js'; |
|||
import * as layout from '../util/layout.js'; |
|||
var inner = makeInner(); |
|||
|
|||
var ComponentModel = |
|||
/** @class */ |
|||
function (_super) { |
|||
__extends(ComponentModel, _super); |
|||
|
|||
function ComponentModel(option, parentModel, ecModel) { |
|||
var _this = _super.call(this, option, parentModel, ecModel) || this; |
|||
|
|||
_this.uid = componentUtil.getUID('ec_cpt_model'); |
|||
return _this; |
|||
} |
|||
|
|||
ComponentModel.prototype.init = function (option, parentModel, ecModel) { |
|||
this.mergeDefaultAndTheme(option, ecModel); |
|||
}; |
|||
|
|||
ComponentModel.prototype.mergeDefaultAndTheme = function (option, ecModel) { |
|||
var layoutMode = layout.fetchLayoutMode(this); |
|||
var inputPositionParams = layoutMode ? layout.getLayoutParams(option) : {}; |
|||
var themeModel = ecModel.getTheme(); |
|||
zrUtil.merge(option, themeModel.get(this.mainType)); |
|||
zrUtil.merge(option, this.getDefaultOption()); |
|||
|
|||
if (layoutMode) { |
|||
layout.mergeLayoutParam(option, inputPositionParams, layoutMode); |
|||
} |
|||
}; |
|||
|
|||
ComponentModel.prototype.mergeOption = function (option, ecModel) { |
|||
zrUtil.merge(this.option, option, true); |
|||
var layoutMode = layout.fetchLayoutMode(this); |
|||
|
|||
if (layoutMode) { |
|||
layout.mergeLayoutParam(this.option, option, layoutMode); |
|||
} |
|||
}; |
|||
/** |
|||
* Called immediately after `init` or `mergeOption` of this instance called. |
|||
*/ |
|||
|
|||
|
|||
ComponentModel.prototype.optionUpdated = function (newCptOption, isInit) {}; |
|||
/** |
|||
* [How to declare defaultOption]: |
|||
* |
|||
* (A) If using class declaration in typescript (since echarts 5): |
|||
* ```ts
|
|||
* import {ComponentOption} from '../model/option.js'; |
|||
* export interface XxxOption extends ComponentOption { |
|||
* aaa: number |
|||
* } |
|||
* export class XxxModel extends Component { |
|||
* static type = 'xxx'; |
|||
* static defaultOption: XxxOption = { |
|||
* aaa: 123 |
|||
* } |
|||
* } |
|||
* Component.registerClass(XxxModel); |
|||
* ``` |
|||
* ```ts
|
|||
* import {inheritDefaultOption} from '../util/component.js'; |
|||
* import {XxxModel, XxxOption} from './XxxModel.js'; |
|||
* export interface XxxSubOption extends XxxOption { |
|||
* bbb: number |
|||
* } |
|||
* class XxxSubModel extends XxxModel { |
|||
* static defaultOption: XxxSubOption = inheritDefaultOption(XxxModel.defaultOption, { |
|||
* bbb: 456 |
|||
* }) |
|||
* fn() { |
|||
* let opt = this.getDefaultOption(); |
|||
* // opt is {aaa: 123, bbb: 456}
|
|||
* } |
|||
* } |
|||
* ``` |
|||
* |
|||
* (B) If using class extend (previous approach in echarts 3 & 4): |
|||
* ```js
|
|||
* let XxxComponent = Component.extend({ |
|||
* defaultOption: { |
|||
* xx: 123 |
|||
* } |
|||
* }) |
|||
* ``` |
|||
* ```js
|
|||
* let XxxSubComponent = XxxComponent.extend({ |
|||
* defaultOption: { |
|||
* yy: 456 |
|||
* }, |
|||
* fn: function () { |
|||
* let opt = this.getDefaultOption(); |
|||
* // opt is {xx: 123, yy: 456}
|
|||
* } |
|||
* }) |
|||
* ``` |
|||
*/ |
|||
|
|||
|
|||
ComponentModel.prototype.getDefaultOption = function () { |
|||
var ctor = this.constructor; // If using class declaration, it is different to travel super class
|
|||
// in legacy env and auto merge defaultOption. So if using class
|
|||
// declaration, defaultOption should be merged manually.
|
|||
|
|||
if (!isExtendedClass(ctor)) { |
|||
// When using ts class, defaultOption must be declared as static.
|
|||
return ctor.defaultOption; |
|||
} // FIXME: remove this approach?
|
|||
|
|||
|
|||
var fields = inner(this); |
|||
|
|||
if (!fields.defaultOption) { |
|||
var optList = []; |
|||
var clz = ctor; |
|||
|
|||
while (clz) { |
|||
var opt = clz.prototype.defaultOption; |
|||
opt && optList.push(opt); |
|||
clz = clz.superClass; |
|||
} |
|||
|
|||
var defaultOption = {}; |
|||
|
|||
for (var i = optList.length - 1; i >= 0; i--) { |
|||
defaultOption = zrUtil.merge(defaultOption, optList[i], true); |
|||
} |
|||
|
|||
fields.defaultOption = defaultOption; |
|||
} |
|||
|
|||
return fields.defaultOption; |
|||
}; |
|||
/** |
|||
* Notice: always force to input param `useDefault` in case that forget to consider it. |
|||
* The same behavior as `modelUtil.parseFinder`. |
|||
* |
|||
* @param useDefault In many cases like series refer axis and axis refer grid, |
|||
* If axis index / axis id not specified, use the first target as default. |
|||
* In other cases like dataZoom refer axis, if not specified, measn no refer. |
|||
*/ |
|||
|
|||
|
|||
ComponentModel.prototype.getReferringComponents = function (mainType, opt) { |
|||
var indexKey = mainType + 'Index'; |
|||
var idKey = mainType + 'Id'; |
|||
return queryReferringComponents(this.ecModel, mainType, { |
|||
index: this.get(indexKey, true), |
|||
id: this.get(idKey, true) |
|||
}, opt); |
|||
}; |
|||
|
|||
ComponentModel.prototype.getBoxLayoutParams = function () { |
|||
// Consider itself having box layout configs.
|
|||
var boxLayoutModel = this; |
|||
return { |
|||
left: boxLayoutModel.get('left'), |
|||
top: boxLayoutModel.get('top'), |
|||
right: boxLayoutModel.get('right'), |
|||
bottom: boxLayoutModel.get('bottom'), |
|||
width: boxLayoutModel.get('width'), |
|||
height: boxLayoutModel.get('height') |
|||
}; |
|||
}; |
|||
/** |
|||
* Get key for zlevel. |
|||
* If developers don't configure zlevel. We will assign zlevel to series based on the key. |
|||
* For example, lines with trail effect and progressive series will in an individual zlevel. |
|||
*/ |
|||
|
|||
|
|||
ComponentModel.prototype.getZLevelKey = function () { |
|||
return ''; |
|||
}; |
|||
|
|||
ComponentModel.prototype.setZLevel = function (zlevel) { |
|||
this.option.zlevel = zlevel; |
|||
}; |
|||
|
|||
ComponentModel.protoInitialize = function () { |
|||
var proto = ComponentModel.prototype; |
|||
proto.type = 'component'; |
|||
proto.id = ''; |
|||
proto.name = ''; |
|||
proto.mainType = ''; |
|||
proto.subType = ''; |
|||
proto.componentIndex = 0; |
|||
}(); |
|||
|
|||
return ComponentModel; |
|||
}(Model); |
|||
|
|||
mountExtend(ComponentModel, Model); |
|||
enableClassManagement(ComponentModel); |
|||
componentUtil.enableSubTypeDefaulter(ComponentModel); |
|||
componentUtil.enableTopologicalTravel(ComponentModel, getDependencies); |
|||
|
|||
function getDependencies(componentType) { |
|||
var deps = []; |
|||
zrUtil.each(ComponentModel.getClassesByMainType(componentType), function (clz) { |
|||
deps = deps.concat(clz.dependencies || clz.prototype.dependencies || []); |
|||
}); // Ensure main type.
|
|||
|
|||
deps = zrUtil.map(deps, function (type) { |
|||
return parseClassType(type).main; |
|||
}); // Hack dataset for convenience.
|
|||
|
|||
if (componentType !== 'dataset' && zrUtil.indexOf(deps, 'dataset') <= 0) { |
|||
deps.unshift('dataset'); |
|||
} |
|||
|
|||
return deps; |
|||
} |
|||
|
|||
export default ComponentModel; |
|||
@ -0,0 +1,861 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { __extends } from "tslib"; |
|||
/** |
|||
* Caution: If the mechanism should be changed some day, these cases |
|||
* should be considered: |
|||
* |
|||
* (1) In `merge option` mode, if using the same option to call `setOption` |
|||
* many times, the result should be the same (try our best to ensure that). |
|||
* (2) In `merge option` mode, if a component has no id/name specified, it |
|||
* will be merged by index, and the result sequence of the components is |
|||
* consistent to the original sequence. |
|||
* (3) In `replaceMerge` mode, keep the result sequence of the components is |
|||
* consistent to the original sequence, even though there might result in "hole". |
|||
* (4) `reset` feature (in toolbox). Find detailed info in comments about |
|||
* `mergeOption` in module:echarts/model/OptionManager. |
|||
*/ |
|||
|
|||
import { each, filter, isArray, isObject, isString, createHashMap, assert, clone, merge, extend, mixin, isFunction } from 'zrender/lib/core/util.js'; |
|||
import * as modelUtil from '../util/model.js'; |
|||
import Model from './Model.js'; |
|||
import ComponentModel from './Component.js'; |
|||
import globalDefault from './globalDefault.js'; |
|||
import { resetSourceDefaulter } from '../data/helper/sourceHelper.js'; |
|||
import { concatInternalOptions } from './internalComponentCreator.js'; |
|||
import { PaletteMixin } from './mixin/palette.js'; |
|||
import { error, warn } from '../util/log.js'; // -----------------------
|
|||
// Internal method names:
|
|||
// -----------------------
|
|||
|
|||
var reCreateSeriesIndices; |
|||
var assertSeriesInitialized; |
|||
var initBase; |
|||
var OPTION_INNER_KEY = '\0_ec_inner'; |
|||
var OPTION_INNER_VALUE = 1; |
|||
var BUITIN_COMPONENTS_MAP = { |
|||
grid: 'GridComponent', |
|||
polar: 'PolarComponent', |
|||
geo: 'GeoComponent', |
|||
singleAxis: 'SingleAxisComponent', |
|||
parallel: 'ParallelComponent', |
|||
calendar: 'CalendarComponent', |
|||
graphic: 'GraphicComponent', |
|||
toolbox: 'ToolboxComponent', |
|||
tooltip: 'TooltipComponent', |
|||
axisPointer: 'AxisPointerComponent', |
|||
brush: 'BrushComponent', |
|||
title: 'TitleComponent', |
|||
timeline: 'TimelineComponent', |
|||
markPoint: 'MarkPointComponent', |
|||
markLine: 'MarkLineComponent', |
|||
markArea: 'MarkAreaComponent', |
|||
legend: 'LegendComponent', |
|||
dataZoom: 'DataZoomComponent', |
|||
visualMap: 'VisualMapComponent', |
|||
// aria: 'AriaComponent',
|
|||
// dataset: 'DatasetComponent',
|
|||
// Dependencies
|
|||
xAxis: 'GridComponent', |
|||
yAxis: 'GridComponent', |
|||
angleAxis: 'PolarComponent', |
|||
radiusAxis: 'PolarComponent' |
|||
}; |
|||
var BUILTIN_CHARTS_MAP = { |
|||
line: 'LineChart', |
|||
bar: 'BarChart', |
|||
pie: 'PieChart', |
|||
scatter: 'ScatterChart', |
|||
radar: 'RadarChart', |
|||
map: 'MapChart', |
|||
tree: 'TreeChart', |
|||
treemap: 'TreemapChart', |
|||
graph: 'GraphChart', |
|||
gauge: 'GaugeChart', |
|||
funnel: 'FunnelChart', |
|||
parallel: 'ParallelChart', |
|||
sankey: 'SankeyChart', |
|||
boxplot: 'BoxplotChart', |
|||
candlestick: 'CandlestickChart', |
|||
effectScatter: 'EffectScatterChart', |
|||
lines: 'LinesChart', |
|||
heatmap: 'HeatmapChart', |
|||
pictorialBar: 'PictorialBarChart', |
|||
themeRiver: 'ThemeRiverChart', |
|||
sunburst: 'SunburstChart', |
|||
custom: 'CustomChart' |
|||
}; |
|||
var componetsMissingLogPrinted = {}; |
|||
|
|||
function checkMissingComponents(option) { |
|||
each(option, function (componentOption, mainType) { |
|||
if (!ComponentModel.hasClass(mainType)) { |
|||
var componentImportName = BUITIN_COMPONENTS_MAP[mainType]; |
|||
|
|||
if (componentImportName && !componetsMissingLogPrinted[componentImportName]) { |
|||
error("Component " + mainType + " is used but not imported.\nimport { " + componentImportName + " } from 'echarts/components';\necharts.use([" + componentImportName + "]);"); |
|||
componetsMissingLogPrinted[componentImportName] = true; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
var GlobalModel = |
|||
/** @class */ |
|||
function (_super) { |
|||
__extends(GlobalModel, _super); |
|||
|
|||
function GlobalModel() { |
|||
return _super !== null && _super.apply(this, arguments) || this; |
|||
} |
|||
|
|||
GlobalModel.prototype.init = function (option, parentModel, ecModel, theme, locale, optionManager) { |
|||
theme = theme || {}; |
|||
this.option = null; // Mark as not initialized.
|
|||
|
|||
this._theme = new Model(theme); |
|||
this._locale = new Model(locale); |
|||
this._optionManager = optionManager; |
|||
}; |
|||
|
|||
GlobalModel.prototype.setOption = function (option, opts, optionPreprocessorFuncs) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(option != null, 'option is null/undefined'); |
|||
assert(option[OPTION_INNER_KEY] !== OPTION_INNER_VALUE, 'please use chart.getOption()'); |
|||
} |
|||
|
|||
var innerOpt = normalizeSetOptionInput(opts); |
|||
|
|||
this._optionManager.setOption(option, optionPreprocessorFuncs, innerOpt); |
|||
|
|||
this._resetOption(null, innerOpt); |
|||
}; |
|||
/** |
|||
* @param type null/undefined: reset all. |
|||
* 'recreate': force recreate all. |
|||
* 'timeline': only reset timeline option |
|||
* 'media': only reset media query option |
|||
* @return Whether option changed. |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.resetOption = function (type, opt) { |
|||
return this._resetOption(type, normalizeSetOptionInput(opt)); |
|||
}; |
|||
|
|||
GlobalModel.prototype._resetOption = function (type, opt) { |
|||
var optionChanged = false; |
|||
var optionManager = this._optionManager; |
|||
|
|||
if (!type || type === 'recreate') { |
|||
var baseOption = optionManager.mountOption(type === 'recreate'); |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
checkMissingComponents(baseOption); |
|||
} |
|||
|
|||
if (!this.option || type === 'recreate') { |
|||
initBase(this, baseOption); |
|||
} else { |
|||
this.restoreData(); |
|||
|
|||
this._mergeOption(baseOption, opt); |
|||
} |
|||
|
|||
optionChanged = true; |
|||
} |
|||
|
|||
if (type === 'timeline' || type === 'media') { |
|||
this.restoreData(); |
|||
} // By design, if `setOption(option2)` at the second time, and `option2` is a `ECUnitOption`,
|
|||
// it should better not have the same props with `MediaUnit['option']`.
|
|||
// Becuase either `option2` or `MediaUnit['option']` will be always merged to "current option"
|
|||
// rather than original "baseOption". If they both override a prop, the result might be
|
|||
// unexpected when media state changed after `setOption` called.
|
|||
// If we really need to modify a props in each `MediaUnit['option']`, use the full version
|
|||
// (`{baseOption, media}`) in `setOption`.
|
|||
// For `timeline`, the case is the same.
|
|||
|
|||
|
|||
if (!type || type === 'recreate' || type === 'timeline') { |
|||
var timelineOption = optionManager.getTimelineOption(this); |
|||
|
|||
if (timelineOption) { |
|||
optionChanged = true; |
|||
|
|||
this._mergeOption(timelineOption, opt); |
|||
} |
|||
} |
|||
|
|||
if (!type || type === 'recreate' || type === 'media') { |
|||
var mediaOptions = optionManager.getMediaOption(this); |
|||
|
|||
if (mediaOptions.length) { |
|||
each(mediaOptions, function (mediaOption) { |
|||
optionChanged = true; |
|||
|
|||
this._mergeOption(mediaOption, opt); |
|||
}, this); |
|||
} |
|||
} |
|||
|
|||
return optionChanged; |
|||
}; |
|||
|
|||
GlobalModel.prototype.mergeOption = function (option) { |
|||
this._mergeOption(option, null); |
|||
}; |
|||
|
|||
GlobalModel.prototype._mergeOption = function (newOption, opt) { |
|||
var option = this.option; |
|||
var componentsMap = this._componentsMap; |
|||
var componentsCount = this._componentsCount; |
|||
var newCmptTypes = []; |
|||
var newCmptTypeMap = createHashMap(); |
|||
var replaceMergeMainTypeMap = opt && opt.replaceMergeMainTypeMap; |
|||
resetSourceDefaulter(this); // If no component class, merge directly.
|
|||
// For example: color, animaiton options, etc.
|
|||
|
|||
each(newOption, function (componentOption, mainType) { |
|||
if (componentOption == null) { |
|||
return; |
|||
} |
|||
|
|||
if (!ComponentModel.hasClass(mainType)) { |
|||
// globalSettingTask.dirty();
|
|||
option[mainType] = option[mainType] == null ? clone(componentOption) : merge(option[mainType], componentOption, true); |
|||
} else if (mainType) { |
|||
newCmptTypes.push(mainType); |
|||
newCmptTypeMap.set(mainType, true); |
|||
} |
|||
}); |
|||
|
|||
if (replaceMergeMainTypeMap) { |
|||
// If there is a mainType `xxx` in `replaceMerge` but not declared in option,
|
|||
// we trade it as it is declared in option as `{xxx: []}`. Because:
|
|||
// (1) for normal merge, `{xxx: null/undefined}` are the same meaning as `{xxx: []}`.
|
|||
// (2) some preprocessor may convert some of `{xxx: null/undefined}` to `{xxx: []}`.
|
|||
replaceMergeMainTypeMap.each(function (val, mainTypeInReplaceMerge) { |
|||
if (ComponentModel.hasClass(mainTypeInReplaceMerge) && !newCmptTypeMap.get(mainTypeInReplaceMerge)) { |
|||
newCmptTypes.push(mainTypeInReplaceMerge); |
|||
newCmptTypeMap.set(mainTypeInReplaceMerge, true); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
ComponentModel.topologicalTravel(newCmptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this); |
|||
|
|||
function visitComponent(mainType) { |
|||
var newCmptOptionList = concatInternalOptions(this, mainType, modelUtil.normalizeToArray(newOption[mainType])); |
|||
var oldCmptList = componentsMap.get(mainType); |
|||
var mergeMode = // `!oldCmptList` means init. See the comment in `mappingToExists`
|
|||
!oldCmptList ? 'replaceAll' : replaceMergeMainTypeMap && replaceMergeMainTypeMap.get(mainType) ? 'replaceMerge' : 'normalMerge'; |
|||
var mappingResult = modelUtil.mappingToExists(oldCmptList, newCmptOptionList, mergeMode); // Set mainType and complete subType.
|
|||
|
|||
modelUtil.setComponentTypeToKeyInfo(mappingResult, mainType, ComponentModel); // Empty it before the travel, in order to prevent `this._componentsMap`
|
|||
// from being used in the `init`/`mergeOption`/`optionUpdated` of some
|
|||
// components, which is probably incorrect logic.
|
|||
|
|||
option[mainType] = null; |
|||
componentsMap.set(mainType, null); |
|||
componentsCount.set(mainType, 0); |
|||
var optionsByMainType = []; |
|||
var cmptsByMainType = []; |
|||
var cmptsCountByMainType = 0; |
|||
var tooltipExists; |
|||
var tooltipWarningLogged; |
|||
each(mappingResult, function (resultItem, index) { |
|||
var componentModel = resultItem.existing; |
|||
var newCmptOption = resultItem.newOption; |
|||
|
|||
if (!newCmptOption) { |
|||
if (componentModel) { |
|||
// Consider where is no new option and should be merged using {},
|
|||
// see removeEdgeAndAdd in topologicalTravel and
|
|||
// ComponentModel.getAllClassMainTypes.
|
|||
componentModel.mergeOption({}, this); |
|||
componentModel.optionUpdated({}, false); |
|||
} // If no both `resultItem.exist` and `resultItem.option`,
|
|||
// either it is in `replaceMerge` and not matched by any id,
|
|||
// or it has been removed in previous `replaceMerge` and left a "hole" in this component index.
|
|||
|
|||
} else { |
|||
var isSeriesType = mainType === 'series'; |
|||
var ComponentModelClass = ComponentModel.getClass(mainType, resultItem.keyInfo.subType, !isSeriesType // Give a more detailed warn later if series don't exists
|
|||
); |
|||
|
|||
if (!ComponentModelClass) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
var subType = resultItem.keyInfo.subType; |
|||
var seriesImportName = BUILTIN_CHARTS_MAP[subType]; |
|||
|
|||
if (!componetsMissingLogPrinted[subType]) { |
|||
componetsMissingLogPrinted[subType] = true; |
|||
|
|||
if (seriesImportName) { |
|||
error("Series " + subType + " is used but not imported.\nimport { " + seriesImportName + " } from 'echarts/charts';\necharts.use([" + seriesImportName + "]);"); |
|||
} else { |
|||
error("Unkown series " + subType); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return; |
|||
} // TODO Before multiple tooltips get supported, we do this check to avoid unexpected exception.
|
|||
|
|||
|
|||
if (mainType === 'tooltip') { |
|||
if (tooltipExists) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (!tooltipWarningLogged) { |
|||
warn('Currently only one tooltip component is allowed.'); |
|||
tooltipWarningLogged = true; |
|||
} |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
tooltipExists = true; |
|||
} |
|||
|
|||
if (componentModel && componentModel.constructor === ComponentModelClass) { |
|||
componentModel.name = resultItem.keyInfo.name; // componentModel.settingTask && componentModel.settingTask.dirty();
|
|||
|
|||
componentModel.mergeOption(newCmptOption, this); |
|||
componentModel.optionUpdated(newCmptOption, false); |
|||
} else { |
|||
// PENDING Global as parent ?
|
|||
var extraOpt = extend({ |
|||
componentIndex: index |
|||
}, resultItem.keyInfo); |
|||
componentModel = new ComponentModelClass(newCmptOption, this, this, extraOpt); // Assign `keyInfo`
|
|||
|
|||
extend(componentModel, extraOpt); |
|||
|
|||
if (resultItem.brandNew) { |
|||
componentModel.__requireNewView = true; |
|||
} |
|||
|
|||
componentModel.init(newCmptOption, this, this); // Call optionUpdated after init.
|
|||
// newCmptOption has been used as componentModel.option
|
|||
// and may be merged with theme and default, so pass null
|
|||
// to avoid confusion.
|
|||
|
|||
componentModel.optionUpdated(null, true); |
|||
} |
|||
} |
|||
|
|||
if (componentModel) { |
|||
optionsByMainType.push(componentModel.option); |
|||
cmptsByMainType.push(componentModel); |
|||
cmptsCountByMainType++; |
|||
} else { |
|||
// Always do assign to avoid elided item in array.
|
|||
optionsByMainType.push(void 0); |
|||
cmptsByMainType.push(void 0); |
|||
} |
|||
}, this); |
|||
option[mainType] = optionsByMainType; |
|||
componentsMap.set(mainType, cmptsByMainType); |
|||
componentsCount.set(mainType, cmptsCountByMainType); // Backup series for filtering.
|
|||
|
|||
if (mainType === 'series') { |
|||
reCreateSeriesIndices(this); |
|||
} |
|||
} // If no series declared, ensure `_seriesIndices` initialized.
|
|||
|
|||
|
|||
if (!this._seriesIndices) { |
|||
reCreateSeriesIndices(this); |
|||
} |
|||
}; |
|||
/** |
|||
* Get option for output (cloned option and inner info removed) |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.getOption = function () { |
|||
var option = clone(this.option); |
|||
each(option, function (optInMainType, mainType) { |
|||
if (ComponentModel.hasClass(mainType)) { |
|||
var opts = modelUtil.normalizeToArray(optInMainType); // Inner cmpts need to be removed.
|
|||
// Inner cmpts might not be at last since ec5.0, but still
|
|||
// compatible for users: if inner cmpt at last, splice the returned array.
|
|||
|
|||
var realLen = opts.length; |
|||
var metNonInner = false; |
|||
|
|||
for (var i = realLen - 1; i >= 0; i--) { |
|||
// Remove options with inner id.
|
|||
if (opts[i] && !modelUtil.isComponentIdInternal(opts[i])) { |
|||
metNonInner = true; |
|||
} else { |
|||
opts[i] = null; |
|||
!metNonInner && realLen--; |
|||
} |
|||
} |
|||
|
|||
opts.length = realLen; |
|||
option[mainType] = opts; |
|||
} |
|||
}); |
|||
delete option[OPTION_INNER_KEY]; |
|||
return option; |
|||
}; |
|||
|
|||
GlobalModel.prototype.getTheme = function () { |
|||
return this._theme; |
|||
}; |
|||
|
|||
GlobalModel.prototype.getLocaleModel = function () { |
|||
return this._locale; |
|||
}; |
|||
|
|||
GlobalModel.prototype.setUpdatePayload = function (payload) { |
|||
this._payload = payload; |
|||
}; |
|||
|
|||
GlobalModel.prototype.getUpdatePayload = function () { |
|||
return this._payload; |
|||
}; |
|||
/** |
|||
* @param idx If not specified, return the first one. |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.getComponent = function (mainType, idx) { |
|||
var list = this._componentsMap.get(mainType); |
|||
|
|||
if (list) { |
|||
var cmpt = list[idx || 0]; |
|||
|
|||
if (cmpt) { |
|||
return cmpt; |
|||
} else if (idx == null) { |
|||
for (var i = 0; i < list.length; i++) { |
|||
if (list[i]) { |
|||
return list[i]; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
/** |
|||
* @return Never be null/undefined. |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.queryComponents = function (condition) { |
|||
var mainType = condition.mainType; |
|||
|
|||
if (!mainType) { |
|||
return []; |
|||
} |
|||
|
|||
var index = condition.index; |
|||
var id = condition.id; |
|||
var name = condition.name; |
|||
|
|||
var cmpts = this._componentsMap.get(mainType); |
|||
|
|||
if (!cmpts || !cmpts.length) { |
|||
return []; |
|||
} |
|||
|
|||
var result; |
|||
|
|||
if (index != null) { |
|||
result = []; |
|||
each(modelUtil.normalizeToArray(index), function (idx) { |
|||
cmpts[idx] && result.push(cmpts[idx]); |
|||
}); |
|||
} else if (id != null) { |
|||
result = queryByIdOrName('id', id, cmpts); |
|||
} else if (name != null) { |
|||
result = queryByIdOrName('name', name, cmpts); |
|||
} else { |
|||
// Return all non-empty components in that mainType
|
|||
result = filter(cmpts, function (cmpt) { |
|||
return !!cmpt; |
|||
}); |
|||
} |
|||
|
|||
return filterBySubType(result, condition); |
|||
}; |
|||
/** |
|||
* The interface is different from queryComponents, |
|||
* which is convenient for inner usage. |
|||
* |
|||
* @usage |
|||
* let result = findComponents( |
|||
* {mainType: 'dataZoom', query: {dataZoomId: 'abc'}} |
|||
* ); |
|||
* let result = findComponents( |
|||
* {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}} |
|||
* ); |
|||
* let result = findComponents( |
|||
* {mainType: 'series', |
|||
* filter: function (model, index) {...}} |
|||
* ); |
|||
* // result like [component0, componnet1, ...]
|
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.findComponents = function (condition) { |
|||
var query = condition.query; |
|||
var mainType = condition.mainType; |
|||
var queryCond = getQueryCond(query); |
|||
var result = queryCond ? this.queryComponents(queryCond) // Retrieve all non-empty components.
|
|||
: filter(this._componentsMap.get(mainType), function (cmpt) { |
|||
return !!cmpt; |
|||
}); |
|||
return doFilter(filterBySubType(result, condition)); |
|||
|
|||
function getQueryCond(q) { |
|||
var indexAttr = mainType + 'Index'; |
|||
var idAttr = mainType + 'Id'; |
|||
var nameAttr = mainType + 'Name'; |
|||
return q && (q[indexAttr] != null || q[idAttr] != null || q[nameAttr] != null) ? { |
|||
mainType: mainType, |
|||
// subType will be filtered finally.
|
|||
index: q[indexAttr], |
|||
id: q[idAttr], |
|||
name: q[nameAttr] |
|||
} : null; |
|||
} |
|||
|
|||
function doFilter(res) { |
|||
return condition.filter ? filter(res, condition.filter) : res; |
|||
} |
|||
}; |
|||
|
|||
GlobalModel.prototype.eachComponent = function (mainType, cb, context) { |
|||
var componentsMap = this._componentsMap; |
|||
|
|||
if (isFunction(mainType)) { |
|||
var ctxForAll_1 = cb; |
|||
var cbForAll_1 = mainType; |
|||
componentsMap.each(function (cmpts, componentType) { |
|||
for (var i = 0; cmpts && i < cmpts.length; i++) { |
|||
var cmpt = cmpts[i]; |
|||
cmpt && cbForAll_1.call(ctxForAll_1, componentType, cmpt, cmpt.componentIndex); |
|||
} |
|||
}); |
|||
} else { |
|||
var cmpts = isString(mainType) ? componentsMap.get(mainType) : isObject(mainType) ? this.findComponents(mainType) : null; |
|||
|
|||
for (var i = 0; cmpts && i < cmpts.length; i++) { |
|||
var cmpt = cmpts[i]; |
|||
cmpt && cb.call(context, cmpt, cmpt.componentIndex); |
|||
} |
|||
} |
|||
}; |
|||
/** |
|||
* Get series list before filtered by name. |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.getSeriesByName = function (name) { |
|||
var nameStr = modelUtil.convertOptionIdName(name, null); |
|||
return filter(this._componentsMap.get('series'), function (oneSeries) { |
|||
return !!oneSeries && nameStr != null && oneSeries.name === nameStr; |
|||
}); |
|||
}; |
|||
/** |
|||
* Get series list before filtered by index. |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.getSeriesByIndex = function (seriesIndex) { |
|||
return this._componentsMap.get('series')[seriesIndex]; |
|||
}; |
|||
/** |
|||
* Get series list before filtered by type. |
|||
* FIXME: rename to getRawSeriesByType? |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.getSeriesByType = function (subType) { |
|||
return filter(this._componentsMap.get('series'), function (oneSeries) { |
|||
return !!oneSeries && oneSeries.subType === subType; |
|||
}); |
|||
}; |
|||
/** |
|||
* Get all series before filtered. |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.getSeries = function () { |
|||
return filter(this._componentsMap.get('series'), function (oneSeries) { |
|||
return !!oneSeries; |
|||
}); |
|||
}; |
|||
/** |
|||
* Count series before filtered. |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.getSeriesCount = function () { |
|||
return this._componentsCount.get('series'); |
|||
}; |
|||
/** |
|||
* After filtering, series may be different |
|||
* frome raw series. |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.eachSeries = function (cb, context) { |
|||
assertSeriesInitialized(this); |
|||
each(this._seriesIndices, function (rawSeriesIndex) { |
|||
var series = this._componentsMap.get('series')[rawSeriesIndex]; |
|||
|
|||
cb.call(context, series, rawSeriesIndex); |
|||
}, this); |
|||
}; |
|||
/** |
|||
* Iterate raw series before filtered. |
|||
* |
|||
* @param {Function} cb |
|||
* @param {*} context |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.eachRawSeries = function (cb, context) { |
|||
each(this._componentsMap.get('series'), function (series) { |
|||
series && cb.call(context, series, series.componentIndex); |
|||
}); |
|||
}; |
|||
/** |
|||
* After filtering, series may be different. |
|||
* frome raw series. |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.eachSeriesByType = function (subType, cb, context) { |
|||
assertSeriesInitialized(this); |
|||
each(this._seriesIndices, function (rawSeriesIndex) { |
|||
var series = this._componentsMap.get('series')[rawSeriesIndex]; |
|||
|
|||
if (series.subType === subType) { |
|||
cb.call(context, series, rawSeriesIndex); |
|||
} |
|||
}, this); |
|||
}; |
|||
/** |
|||
* Iterate raw series before filtered of given type. |
|||
*/ |
|||
|
|||
|
|||
GlobalModel.prototype.eachRawSeriesByType = function (subType, cb, context) { |
|||
return each(this.getSeriesByType(subType), cb, context); |
|||
}; |
|||
|
|||
GlobalModel.prototype.isSeriesFiltered = function (seriesModel) { |
|||
assertSeriesInitialized(this); |
|||
return this._seriesIndicesMap.get(seriesModel.componentIndex) == null; |
|||
}; |
|||
|
|||
GlobalModel.prototype.getCurrentSeriesIndices = function () { |
|||
return (this._seriesIndices || []).slice(); |
|||
}; |
|||
|
|||
GlobalModel.prototype.filterSeries = function (cb, context) { |
|||
assertSeriesInitialized(this); |
|||
var newSeriesIndices = []; |
|||
each(this._seriesIndices, function (seriesRawIdx) { |
|||
var series = this._componentsMap.get('series')[seriesRawIdx]; |
|||
|
|||
cb.call(context, series, seriesRawIdx) && newSeriesIndices.push(seriesRawIdx); |
|||
}, this); |
|||
this._seriesIndices = newSeriesIndices; |
|||
this._seriesIndicesMap = createHashMap(newSeriesIndices); |
|||
}; |
|||
|
|||
GlobalModel.prototype.restoreData = function (payload) { |
|||
reCreateSeriesIndices(this); |
|||
var componentsMap = this._componentsMap; |
|||
var componentTypes = []; |
|||
componentsMap.each(function (components, componentType) { |
|||
if (ComponentModel.hasClass(componentType)) { |
|||
componentTypes.push(componentType); |
|||
} |
|||
}); |
|||
ComponentModel.topologicalTravel(componentTypes, ComponentModel.getAllClassMainTypes(), function (componentType) { |
|||
each(componentsMap.get(componentType), function (component) { |
|||
if (component && (componentType !== 'series' || !isNotTargetSeries(component, payload))) { |
|||
component.restoreData(); |
|||
} |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
GlobalModel.internalField = function () { |
|||
reCreateSeriesIndices = function (ecModel) { |
|||
var seriesIndices = ecModel._seriesIndices = []; |
|||
each(ecModel._componentsMap.get('series'), function (series) { |
|||
// series may have been removed by `replaceMerge`.
|
|||
series && seriesIndices.push(series.componentIndex); |
|||
}); |
|||
ecModel._seriesIndicesMap = createHashMap(seriesIndices); |
|||
}; |
|||
|
|||
assertSeriesInitialized = function (ecModel) { |
|||
// Components that use _seriesIndices should depends on series component,
|
|||
// which make sure that their initialization is after series.
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (!ecModel._seriesIndices) { |
|||
throw new Error('Option should contains series.'); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
initBase = function (ecModel, baseOption) { |
|||
// Using OPTION_INNER_KEY to mark that this option can not be used outside,
|
|||
// i.e. `chart.setOption(chart.getModel().option);` is forbiden.
|
|||
ecModel.option = {}; |
|||
ecModel.option[OPTION_INNER_KEY] = OPTION_INNER_VALUE; // Init with series: [], in case of calling findSeries method
|
|||
// before series initialized.
|
|||
|
|||
ecModel._componentsMap = createHashMap({ |
|||
series: [] |
|||
}); |
|||
ecModel._componentsCount = createHashMap(); // If user spefied `option.aria`, aria will be enable. This detection should be
|
|||
// performed before theme and globalDefault merge.
|
|||
|
|||
var airaOption = baseOption.aria; |
|||
|
|||
if (isObject(airaOption) && airaOption.enabled == null) { |
|||
airaOption.enabled = true; |
|||
} |
|||
|
|||
mergeTheme(baseOption, ecModel._theme.option); // TODO Needs clone when merging to the unexisted property
|
|||
|
|||
merge(baseOption, globalDefault, false); |
|||
|
|||
ecModel._mergeOption(baseOption, null); |
|||
}; |
|||
}(); |
|||
|
|||
return GlobalModel; |
|||
}(Model); |
|||
|
|||
function isNotTargetSeries(seriesModel, payload) { |
|||
if (payload) { |
|||
var index = payload.seriesIndex; |
|||
var id = payload.seriesId; |
|||
var name_1 = payload.seriesName; |
|||
return index != null && seriesModel.componentIndex !== index || id != null && seriesModel.id !== id || name_1 != null && seriesModel.name !== name_1; |
|||
} |
|||
} |
|||
|
|||
function mergeTheme(option, theme) { |
|||
// PENDING
|
|||
// NOT use `colorLayer` in theme if option has `color`
|
|||
var notMergeColorLayer = option.color && !option.colorLayer; |
|||
each(theme, function (themeItem, name) { |
|||
if (name === 'colorLayer' && notMergeColorLayer) { |
|||
return; |
|||
} // If it is component model mainType, the model handles that merge later.
|
|||
// otherwise, merge them here.
|
|||
|
|||
|
|||
if (!ComponentModel.hasClass(name)) { |
|||
if (typeof themeItem === 'object') { |
|||
option[name] = !option[name] ? clone(themeItem) : merge(option[name], themeItem, false); |
|||
} else { |
|||
if (option[name] == null) { |
|||
option[name] = themeItem; |
|||
} |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function queryByIdOrName(attr, idOrName, cmpts) { |
|||
// Here is a break from echarts4: string and number are
|
|||
// treated as equal.
|
|||
if (isArray(idOrName)) { |
|||
var keyMap_1 = createHashMap(); |
|||
each(idOrName, function (idOrNameItem) { |
|||
if (idOrNameItem != null) { |
|||
var idName = modelUtil.convertOptionIdName(idOrNameItem, null); |
|||
idName != null && keyMap_1.set(idOrNameItem, true); |
|||
} |
|||
}); |
|||
return filter(cmpts, function (cmpt) { |
|||
return cmpt && keyMap_1.get(cmpt[attr]); |
|||
}); |
|||
} else { |
|||
var idName_1 = modelUtil.convertOptionIdName(idOrName, null); |
|||
return filter(cmpts, function (cmpt) { |
|||
return cmpt && idName_1 != null && cmpt[attr] === idName_1; |
|||
}); |
|||
} |
|||
} |
|||
|
|||
function filterBySubType(components, condition) { |
|||
// Using hasOwnProperty for restrict. Consider
|
|||
// subType is undefined in user payload.
|
|||
return condition.hasOwnProperty('subType') ? filter(components, function (cmpt) { |
|||
return cmpt && cmpt.subType === condition.subType; |
|||
}) : components; |
|||
} |
|||
|
|||
function normalizeSetOptionInput(opts) { |
|||
var replaceMergeMainTypeMap = createHashMap(); |
|||
opts && each(modelUtil.normalizeToArray(opts.replaceMerge), function (mainType) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
assert(ComponentModel.hasClass(mainType), '"' + mainType + '" is not valid component main type in "replaceMerge"'); |
|||
} |
|||
|
|||
replaceMergeMainTypeMap.set(mainType, true); |
|||
}); |
|||
return { |
|||
replaceMergeMainTypeMap: replaceMergeMainTypeMap |
|||
}; |
|||
} |
|||
|
|||
mixin(GlobalModel, PaletteMixin); |
|||
export default GlobalModel; |
|||
@ -0,0 +1,208 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 env from 'zrender/lib/core/env.js'; |
|||
import { enableClassExtend, enableClassCheck } from '../util/clazz.js'; |
|||
import { AreaStyleMixin } from './mixin/areaStyle.js'; |
|||
import TextStyleMixin from './mixin/textStyle.js'; |
|||
import { LineStyleMixin } from './mixin/lineStyle.js'; |
|||
import { ItemStyleMixin } from './mixin/itemStyle.js'; |
|||
import { mixin, clone, merge } from 'zrender/lib/core/util.js'; |
|||
|
|||
var Model = |
|||
/** @class */ |
|||
function () { |
|||
function Model(option, parentModel, ecModel) { |
|||
this.parentModel = parentModel; |
|||
this.ecModel = ecModel; |
|||
this.option = option; // Simple optimization
|
|||
// if (this.init) {
|
|||
// if (arguments.length <= 4) {
|
|||
// this.init(option, parentModel, ecModel, extraOpt);
|
|||
// }
|
|||
// else {
|
|||
// this.init.apply(this, arguments);
|
|||
// }
|
|||
// }
|
|||
} |
|||
|
|||
Model.prototype.init = function (option, parentModel, ecModel) { |
|||
var rest = []; |
|||
|
|||
for (var _i = 3; _i < arguments.length; _i++) { |
|||
rest[_i - 3] = arguments[_i]; |
|||
} |
|||
}; |
|||
/** |
|||
* Merge the input option to me. |
|||
*/ |
|||
|
|||
|
|||
Model.prototype.mergeOption = function (option, ecModel) { |
|||
merge(this.option, option, true); |
|||
}; // `path` can be 'a.b.c', so the return value type have to be `ModelOption`
|
|||
// TODO: TYPE strict key check?
|
|||
// get(path: string | string[], ignoreParent?: boolean): ModelOption;
|
|||
|
|||
|
|||
Model.prototype.get = function (path, ignoreParent) { |
|||
if (path == null) { |
|||
return this.option; |
|||
} |
|||
|
|||
return this._doGet(this.parsePath(path), !ignoreParent && this.parentModel); |
|||
}; |
|||
|
|||
Model.prototype.getShallow = function (key, ignoreParent) { |
|||
var option = this.option; |
|||
var val = option == null ? option : option[key]; |
|||
|
|||
if (val == null && !ignoreParent) { |
|||
var parentModel = this.parentModel; |
|||
|
|||
if (parentModel) { |
|||
// FIXME:TS do not know how to make it works
|
|||
val = parentModel.getShallow(key); |
|||
} |
|||
} |
|||
|
|||
return val; |
|||
}; // `path` can be 'a.b.c', so the return value type have to be `Model<ModelOption>`
|
|||
// getModel(path: string | string[], parentModel?: Model): Model;
|
|||
// TODO 'a.b.c' is deprecated
|
|||
|
|||
|
|||
Model.prototype.getModel = function (path, parentModel) { |
|||
var hasPath = path != null; |
|||
var pathFinal = hasPath ? this.parsePath(path) : null; |
|||
var obj = hasPath ? this._doGet(pathFinal) : this.option; |
|||
parentModel = parentModel || this.parentModel && this.parentModel.getModel(this.resolveParentPath(pathFinal)); |
|||
return new Model(obj, parentModel, this.ecModel); |
|||
}; |
|||
/** |
|||
* If model has option |
|||
*/ |
|||
|
|||
|
|||
Model.prototype.isEmpty = function () { |
|||
return this.option == null; |
|||
}; |
|||
|
|||
Model.prototype.restoreData = function () {}; // Pending
|
|||
|
|||
|
|||
Model.prototype.clone = function () { |
|||
var Ctor = this.constructor; |
|||
return new Ctor(clone(this.option)); |
|||
}; // setReadOnly(properties): void {
|
|||
// clazzUtil.setReadOnly(this, properties);
|
|||
// }
|
|||
// If path is null/undefined, return null/undefined.
|
|||
|
|||
|
|||
Model.prototype.parsePath = function (path) { |
|||
if (typeof path === 'string') { |
|||
return path.split('.'); |
|||
} |
|||
|
|||
return path; |
|||
}; // Resolve path for parent. Perhaps useful when parent use a different property.
|
|||
// Default to be a identity resolver.
|
|||
// Can be modified to a different resolver.
|
|||
|
|||
|
|||
Model.prototype.resolveParentPath = function (path) { |
|||
return path; |
|||
}; // FIXME:TS check whether put this method here
|
|||
|
|||
|
|||
Model.prototype.isAnimationEnabled = function () { |
|||
if (!env.node && this.option) { |
|||
if (this.option.animation != null) { |
|||
return !!this.option.animation; |
|||
} else if (this.parentModel) { |
|||
return this.parentModel.isAnimationEnabled(); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
Model.prototype._doGet = function (pathArr, parentModel) { |
|||
var obj = this.option; |
|||
|
|||
if (!pathArr) { |
|||
return obj; |
|||
} |
|||
|
|||
for (var i = 0; i < pathArr.length; i++) { |
|||
// Ignore empty
|
|||
if (!pathArr[i]) { |
|||
continue; |
|||
} // obj could be number/string/... (like 0)
|
|||
|
|||
|
|||
obj = obj && typeof obj === 'object' ? obj[pathArr[i]] : null; |
|||
|
|||
if (obj == null) { |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (obj == null && parentModel) { |
|||
obj = parentModel._doGet(this.resolveParentPath(pathArr), parentModel.parentModel); |
|||
} |
|||
|
|||
return obj; |
|||
}; |
|||
|
|||
return Model; |
|||
}(); |
|||
|
|||
; // Enable Model.extend.
|
|||
|
|||
enableClassExtend(Model); |
|||
enableClassCheck(Model); |
|||
mixin(Model, LineStyleMixin); |
|||
mixin(Model, ItemStyleMixin); |
|||
mixin(Model, AreaStyleMixin); |
|||
mixin(Model, TextStyleMixin); |
|||
export default Model; |
|||
@ -0,0 +1,491 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { normalizeToArray // , MappingExistingItem, setComponentTypeToKeyInfo, mappingToExists
|
|||
} from '../util/model.js'; |
|||
import { each, clone, map, isTypedArray, setAsPrimitive, isArray, isObject // , HashMap , createHashMap, extend, merge,
|
|||
} from 'zrender/lib/core/util.js'; |
|||
import { error } from '../util/log.js'; |
|||
var QUERY_REG = /^(min|max)?(.+)$/; // Key: mainType
|
|||
// type FakeComponentsMap = HashMap<(MappingExistingItem & { subType: string })[]>;
|
|||
|
|||
/** |
|||
* TERM EXPLANATIONS: |
|||
* See `ECOption` and `ECUnitOption` in `src/util/types.ts`. |
|||
*/ |
|||
|
|||
var OptionManager = |
|||
/** @class */ |
|||
function () { |
|||
// timeline.notMerge is not supported in ec3. Firstly there is rearly
|
|||
// case that notMerge is needed. Secondly supporting 'notMerge' requires
|
|||
// rawOption cloned and backuped when timeline changed, which does no
|
|||
// good to performance. What's more, that both timeline and setOption
|
|||
// method supply 'notMerge' brings complex and some problems.
|
|||
// Consider this case:
|
|||
// (step1) chart.setOption({timeline: {notMerge: false}, ...}, false);
|
|||
// (step2) chart.setOption({timeline: {notMerge: true}, ...}, false);
|
|||
function OptionManager(api) { |
|||
this._timelineOptions = []; |
|||
this._mediaList = []; |
|||
/** |
|||
* -1, means default. |
|||
* empty means no media. |
|||
*/ |
|||
|
|||
this._currentMediaIndices = []; |
|||
this._api = api; |
|||
} |
|||
|
|||
OptionManager.prototype.setOption = function (rawOption, optionPreprocessorFuncs, opt) { |
|||
if (rawOption) { |
|||
// That set dat primitive is dangerous if user reuse the data when setOption again.
|
|||
each(normalizeToArray(rawOption.series), function (series) { |
|||
series && series.data && isTypedArray(series.data) && setAsPrimitive(series.data); |
|||
}); |
|||
each(normalizeToArray(rawOption.dataset), function (dataset) { |
|||
dataset && dataset.source && isTypedArray(dataset.source) && setAsPrimitive(dataset.source); |
|||
}); |
|||
} // Caution: some series modify option data, if do not clone,
|
|||
// it should ensure that the repeat modify correctly
|
|||
// (create a new object when modify itself).
|
|||
|
|||
|
|||
rawOption = clone(rawOption); // FIXME
|
|||
// If some property is set in timeline options or media option but
|
|||
// not set in baseOption, a warning should be given.
|
|||
|
|||
var optionBackup = this._optionBackup; |
|||
var newParsedOption = parseRawOption(rawOption, optionPreprocessorFuncs, !optionBackup); |
|||
this._newBaseOption = newParsedOption.baseOption; // For setOption at second time (using merge mode);
|
|||
|
|||
if (optionBackup) { |
|||
// FIXME
|
|||
// the restore merge solution is essentially incorrect.
|
|||
// the mapping can not be 100% consistent with ecModel, which probably brings
|
|||
// potential bug!
|
|||
// The first merge is delayed, becuase in most cases, users do not call `setOption` twice.
|
|||
// let fakeCmptsMap = this._fakeCmptsMap;
|
|||
// if (!fakeCmptsMap) {
|
|||
// fakeCmptsMap = this._fakeCmptsMap = createHashMap();
|
|||
// mergeToBackupOption(fakeCmptsMap, null, optionBackup.baseOption, null);
|
|||
// }
|
|||
// mergeToBackupOption(
|
|||
// fakeCmptsMap, optionBackup.baseOption, newParsedOption.baseOption, opt
|
|||
// );
|
|||
// For simplicity, timeline options and media options do not support merge,
|
|||
// that is, if you `setOption` twice and both has timeline options, the latter
|
|||
// timeline opitons will not be merged to the formers, but just substitude them.
|
|||
if (newParsedOption.timelineOptions.length) { |
|||
optionBackup.timelineOptions = newParsedOption.timelineOptions; |
|||
} |
|||
|
|||
if (newParsedOption.mediaList.length) { |
|||
optionBackup.mediaList = newParsedOption.mediaList; |
|||
} |
|||
|
|||
if (newParsedOption.mediaDefault) { |
|||
optionBackup.mediaDefault = newParsedOption.mediaDefault; |
|||
} |
|||
} else { |
|||
this._optionBackup = newParsedOption; |
|||
} |
|||
}; |
|||
|
|||
OptionManager.prototype.mountOption = function (isRecreate) { |
|||
var optionBackup = this._optionBackup; |
|||
this._timelineOptions = optionBackup.timelineOptions; |
|||
this._mediaList = optionBackup.mediaList; |
|||
this._mediaDefault = optionBackup.mediaDefault; |
|||
this._currentMediaIndices = []; |
|||
return clone(isRecreate // this._optionBackup.baseOption, which is created at the first `setOption`
|
|||
// called, and is merged into every new option by inner method `mergeToBackupOption`
|
|||
// each time `setOption` called, can be only used in `isRecreate`, because
|
|||
// its reliability is under suspicion. In other cases option merge is
|
|||
// performed by `model.mergeOption`.
|
|||
? optionBackup.baseOption : this._newBaseOption); |
|||
}; |
|||
|
|||
OptionManager.prototype.getTimelineOption = function (ecModel) { |
|||
var option; |
|||
var timelineOptions = this._timelineOptions; |
|||
|
|||
if (timelineOptions.length) { |
|||
// getTimelineOption can only be called after ecModel inited,
|
|||
// so we can get currentIndex from timelineModel.
|
|||
var timelineModel = ecModel.getComponent('timeline'); |
|||
|
|||
if (timelineModel) { |
|||
option = clone( // FIXME:TS as TimelineModel or quivlant interface
|
|||
timelineOptions[timelineModel.getCurrentIndex()]); |
|||
} |
|||
} |
|||
|
|||
return option; |
|||
}; |
|||
|
|||
OptionManager.prototype.getMediaOption = function (ecModel) { |
|||
var ecWidth = this._api.getWidth(); |
|||
|
|||
var ecHeight = this._api.getHeight(); |
|||
|
|||
var mediaList = this._mediaList; |
|||
var mediaDefault = this._mediaDefault; |
|||
var indices = []; |
|||
var result = []; // No media defined.
|
|||
|
|||
if (!mediaList.length && !mediaDefault) { |
|||
return result; |
|||
} // Multi media may be applied, the latter defined media has higher priority.
|
|||
|
|||
|
|||
for (var i = 0, len = mediaList.length; i < len; i++) { |
|||
if (applyMediaQuery(mediaList[i].query, ecWidth, ecHeight)) { |
|||
indices.push(i); |
|||
} |
|||
} // FIXME
|
|||
// Whether mediaDefault should force users to provide? Otherwise
|
|||
// the change by media query can not be recorvered.
|
|||
|
|||
|
|||
if (!indices.length && mediaDefault) { |
|||
indices = [-1]; |
|||
} |
|||
|
|||
if (indices.length && !indicesEquals(indices, this._currentMediaIndices)) { |
|||
result = map(indices, function (index) { |
|||
return clone(index === -1 ? mediaDefault.option : mediaList[index].option); |
|||
}); |
|||
} // Otherwise return nothing.
|
|||
|
|||
|
|||
this._currentMediaIndices = indices; |
|||
return result; |
|||
}; |
|||
|
|||
return OptionManager; |
|||
}(); |
|||
/** |
|||
* [RAW_OPTION_PATTERNS] |
|||
* (Note: "series: []" represents all other props in `ECUnitOption`) |
|||
* |
|||
* (1) No prop "baseOption" declared: |
|||
* Root option is used as "baseOption" (except prop "options" and "media"). |
|||
* ```js
|
|||
* option = { |
|||
* series: [], |
|||
* timeline: {}, |
|||
* options: [], |
|||
* }; |
|||
* option = { |
|||
* series: [], |
|||
* media: {}, |
|||
* }; |
|||
* option = { |
|||
* series: [], |
|||
* timeline: {}, |
|||
* options: [], |
|||
* media: {}, |
|||
* } |
|||
* ``` |
|||
* |
|||
* (2) Prop "baseOption" declared: |
|||
* If "baseOption" declared, `ECUnitOption` props can only be declared |
|||
* inside "baseOption" except prop "timeline" (compat ec2). |
|||
* ```js
|
|||
* option = { |
|||
* baseOption: { |
|||
* timeline: {}, |
|||
* series: [], |
|||
* }, |
|||
* options: [] |
|||
* }; |
|||
* option = { |
|||
* baseOption: { |
|||
* series: [], |
|||
* }, |
|||
* media: [] |
|||
* }; |
|||
* option = { |
|||
* baseOption: { |
|||
* timeline: {}, |
|||
* series: [], |
|||
* }, |
|||
* options: [] |
|||
* media: [] |
|||
* }; |
|||
* option = { |
|||
* // ec3 compat ec2: allow (only) `timeline` declared
|
|||
* // outside baseOption. Keep this setting for compat.
|
|||
* timeline: {}, |
|||
* baseOption: { |
|||
* series: [], |
|||
* }, |
|||
* options: [], |
|||
* media: [] |
|||
* }; |
|||
* ``` |
|||
*/ |
|||
|
|||
|
|||
function parseRawOption( // `rawOption` May be modified
|
|||
rawOption, optionPreprocessorFuncs, isNew) { |
|||
var mediaList = []; |
|||
var mediaDefault; |
|||
var baseOption; |
|||
var declaredBaseOption = rawOption.baseOption; // Compatible with ec2, [RAW_OPTION_PATTERNS] above.
|
|||
|
|||
var timelineOnRoot = rawOption.timeline; |
|||
var timelineOptionsOnRoot = rawOption.options; |
|||
var mediaOnRoot = rawOption.media; |
|||
var hasMedia = !!rawOption.media; |
|||
var hasTimeline = !!(timelineOptionsOnRoot || timelineOnRoot || declaredBaseOption && declaredBaseOption.timeline); |
|||
|
|||
if (declaredBaseOption) { |
|||
baseOption = declaredBaseOption; // For merge option.
|
|||
|
|||
if (!baseOption.timeline) { |
|||
baseOption.timeline = timelineOnRoot; |
|||
} |
|||
} // For convenience, enable to use the root option as the `baseOption`:
|
|||
// `{ ...normalOptionProps, media: [{ ... }, { ... }] }`
|
|||
else { |
|||
if (hasTimeline || hasMedia) { |
|||
rawOption.options = rawOption.media = null; |
|||
} |
|||
|
|||
baseOption = rawOption; |
|||
} |
|||
|
|||
if (hasMedia) { |
|||
if (isArray(mediaOnRoot)) { |
|||
each(mediaOnRoot, function (singleMedia) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
// Real case of wrong config.
|
|||
if (singleMedia && !singleMedia.option && isObject(singleMedia.query) && isObject(singleMedia.query.option)) { |
|||
error('Illegal media option. Must be like { media: [ { query: {}, option: {} } ] }'); |
|||
} |
|||
} |
|||
|
|||
if (singleMedia && singleMedia.option) { |
|||
if (singleMedia.query) { |
|||
mediaList.push(singleMedia); |
|||
} else if (!mediaDefault) { |
|||
// Use the first media default.
|
|||
mediaDefault = singleMedia; |
|||
} |
|||
} |
|||
}); |
|||
} else { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
// Real case of wrong config.
|
|||
error('Illegal media option. Must be an array. Like { media: [ {...}, {...} ] }'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
doPreprocess(baseOption); |
|||
each(timelineOptionsOnRoot, function (option) { |
|||
return doPreprocess(option); |
|||
}); |
|||
each(mediaList, function (media) { |
|||
return doPreprocess(media.option); |
|||
}); |
|||
|
|||
function doPreprocess(option) { |
|||
each(optionPreprocessorFuncs, function (preProcess) { |
|||
preProcess(option, isNew); |
|||
}); |
|||
} |
|||
|
|||
return { |
|||
baseOption: baseOption, |
|||
timelineOptions: timelineOptionsOnRoot || [], |
|||
mediaDefault: mediaDefault, |
|||
mediaList: mediaList |
|||
}; |
|||
} |
|||
/** |
|||
* @see <http://www.w3.org/TR/css3-mediaqueries/#media1>
|
|||
* Support: width, height, aspectRatio |
|||
* Can use max or min as prefix. |
|||
*/ |
|||
|
|||
|
|||
function applyMediaQuery(query, ecWidth, ecHeight) { |
|||
var realMap = { |
|||
width: ecWidth, |
|||
height: ecHeight, |
|||
aspectratio: ecWidth / ecHeight // lowser case for convenientce.
|
|||
|
|||
}; |
|||
var applicatable = true; |
|||
each(query, function (value, attr) { |
|||
var matched = attr.match(QUERY_REG); |
|||
|
|||
if (!matched || !matched[1] || !matched[2]) { |
|||
return; |
|||
} |
|||
|
|||
var operator = matched[1]; |
|||
var realAttr = matched[2].toLowerCase(); |
|||
|
|||
if (!compare(realMap[realAttr], value, operator)) { |
|||
applicatable = false; |
|||
} |
|||
}); |
|||
return applicatable; |
|||
} |
|||
|
|||
function compare(real, expect, operator) { |
|||
if (operator === 'min') { |
|||
return real >= expect; |
|||
} else if (operator === 'max') { |
|||
return real <= expect; |
|||
} else { |
|||
// Equals
|
|||
return real === expect; |
|||
} |
|||
} |
|||
|
|||
function indicesEquals(indices1, indices2) { |
|||
// indices is always order by asc and has only finite number.
|
|||
return indices1.join(',') === indices2.join(','); |
|||
} |
|||
/** |
|||
* Consider case: |
|||
* `chart.setOption(opt1);` |
|||
* Then user do some interaction like dataZoom, dataView changing. |
|||
* `chart.setOption(opt2);` |
|||
* Then user press 'reset button' in toolbox. |
|||
* |
|||
* After doing that all of the interaction effects should be reset, the |
|||
* chart should be the same as the result of invoke |
|||
* `chart.setOption(opt1); chart.setOption(opt2);`. |
|||
* |
|||
* Although it is not able ensure that |
|||
* `chart.setOption(opt1); chart.setOption(opt2);` is equivalents to |
|||
* `chart.setOption(merge(opt1, opt2));` exactly, |
|||
* this might be the only simple way to implement that feature. |
|||
* |
|||
* MEMO: We've considered some other approaches: |
|||
* 1. Each model handle its self restoration but not uniform treatment. |
|||
* (Too complex in logic and error-prone) |
|||
* 2. Use a shadow ecModel. (Performace expensive) |
|||
* |
|||
* FIXME: A possible solution: |
|||
* Add a extra level of model for each component model. The inheritance chain would be: |
|||
* ecModel <- componentModel <- componentActionModel <- dataItemModel |
|||
* And all of the actions can only modify the `componentActionModel` rather than |
|||
* `componentModel`. `setOption` will only modify the `ecModel` and `componentModel`. |
|||
* When "resotre" action triggered, model from `componentActionModel` will be discarded |
|||
* instead of recreating the "ecModel" from the "_optionBackup". |
|||
*/ |
|||
// function mergeToBackupOption(
|
|||
// fakeCmptsMap: FakeComponentsMap,
|
|||
// // `tarOption` Can be null/undefined, means init
|
|||
// tarOption: ECUnitOption,
|
|||
// newOption: ECUnitOption,
|
|||
// // Can be null/undefined
|
|||
// opt: InnerSetOptionOpts
|
|||
// ): void {
|
|||
// newOption = newOption || {} as ECUnitOption;
|
|||
// const notInit = !!tarOption;
|
|||
// each(newOption, function (newOptsInMainType, mainType) {
|
|||
// if (newOptsInMainType == null) {
|
|||
// return;
|
|||
// }
|
|||
// if (!ComponentModel.hasClass(mainType)) {
|
|||
// if (tarOption) {
|
|||
// tarOption[mainType] = merge(tarOption[mainType], newOptsInMainType, true);
|
|||
// }
|
|||
// }
|
|||
// else {
|
|||
// const oldTarOptsInMainType = notInit ? normalizeToArray(tarOption[mainType]) : null;
|
|||
// const oldFakeCmptsInMainType = fakeCmptsMap.get(mainType) || [];
|
|||
// const resultTarOptsInMainType = notInit ? (tarOption[mainType] = [] as ComponentOption[]) : null;
|
|||
// const resultFakeCmptsInMainType = fakeCmptsMap.set(mainType, []);
|
|||
// const mappingResult = mappingToExists(
|
|||
// oldFakeCmptsInMainType,
|
|||
// normalizeToArray(newOptsInMainType),
|
|||
// (opt && opt.replaceMergeMainTypeMap.get(mainType)) ? 'replaceMerge' : 'normalMerge'
|
|||
// );
|
|||
// setComponentTypeToKeyInfo(mappingResult, mainType, ComponentModel as ComponentModelConstructor);
|
|||
// each(mappingResult, function (resultItem, index) {
|
|||
// // The same logic as `Global.ts#_mergeOption`.
|
|||
// let fakeCmpt = resultItem.existing;
|
|||
// const newOption = resultItem.newOption;
|
|||
// const keyInfo = resultItem.keyInfo;
|
|||
// let fakeCmptOpt;
|
|||
// if (!newOption) {
|
|||
// fakeCmptOpt = oldTarOptsInMainType[index];
|
|||
// }
|
|||
// else {
|
|||
// if (fakeCmpt && fakeCmpt.subType === keyInfo.subType) {
|
|||
// fakeCmpt.name = keyInfo.name;
|
|||
// if (notInit) {
|
|||
// fakeCmptOpt = merge(oldTarOptsInMainType[index], newOption, true);
|
|||
// }
|
|||
// }
|
|||
// else {
|
|||
// fakeCmpt = extend({}, keyInfo);
|
|||
// if (notInit) {
|
|||
// fakeCmptOpt = clone(newOption);
|
|||
// }
|
|||
// }
|
|||
// }
|
|||
// if (fakeCmpt) {
|
|||
// notInit && resultTarOptsInMainType.push(fakeCmptOpt);
|
|||
// resultFakeCmptsInMainType.push(fakeCmpt);
|
|||
// }
|
|||
// else {
|
|||
// notInit && resultTarOptsInMainType.push(void 0);
|
|||
// resultFakeCmptsInMainType.push(void 0);
|
|||
// }
|
|||
// });
|
|||
// }
|
|||
// });
|
|||
// }
|
|||
|
|||
|
|||
export default OptionManager; |
|||
@ -0,0 +1,652 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { __extends } from "tslib"; |
|||
import * as zrUtil from 'zrender/lib/core/util.js'; |
|||
import env from 'zrender/lib/core/env.js'; |
|||
import * as modelUtil from '../util/model.js'; |
|||
import ComponentModel from './Component.js'; |
|||
import { PaletteMixin } from './mixin/palette.js'; |
|||
import { DataFormatMixin } from '../model/mixin/dataFormat.js'; |
|||
import { getLayoutParams, mergeLayoutParam, fetchLayoutMode } from '../util/layout.js'; |
|||
import { createTask } from '../core/task.js'; |
|||
import { mountExtend } from '../util/clazz.js'; |
|||
import { SourceManager } from '../data/helper/sourceManager.js'; |
|||
import { defaultSeriesFormatTooltip } from '../component/tooltip/seriesFormatTooltip.js'; |
|||
var inner = modelUtil.makeInner(); |
|||
|
|||
function getSelectionKey(data, dataIndex) { |
|||
return data.getName(dataIndex) || data.getId(dataIndex); |
|||
} |
|||
|
|||
export var SERIES_UNIVERSAL_TRANSITION_PROP = '__universalTransitionEnabled'; |
|||
|
|||
var SeriesModel = |
|||
/** @class */ |
|||
function (_super) { |
|||
__extends(SeriesModel, _super); |
|||
|
|||
function SeriesModel() { |
|||
// [Caution]: Becuase this class or desecendants can be used as `XXX.extend(subProto)`,
|
|||
// the class members must not be initialized in constructor or declaration place.
|
|||
// Otherwise there is bad case:
|
|||
// class A {xxx = 1;}
|
|||
// enableClassExtend(A);
|
|||
// class B extends A {}
|
|||
// var C = B.extend({xxx: 5});
|
|||
// var c = new C();
|
|||
// console.log(c.xxx); // expect 5 but always 1.
|
|||
var _this = _super !== null && _super.apply(this, arguments) || this; // ---------------------------------------
|
|||
// Props about data selection
|
|||
// ---------------------------------------
|
|||
|
|||
|
|||
_this._selectedDataIndicesMap = {}; |
|||
return _this; |
|||
} |
|||
|
|||
SeriesModel.prototype.init = function (option, parentModel, ecModel) { |
|||
this.seriesIndex = this.componentIndex; |
|||
this.dataTask = createTask({ |
|||
count: dataTaskCount, |
|||
reset: dataTaskReset |
|||
}); |
|||
this.dataTask.context = { |
|||
model: this |
|||
}; |
|||
this.mergeDefaultAndTheme(option, ecModel); |
|||
var sourceManager = inner(this).sourceManager = new SourceManager(this); |
|||
sourceManager.prepareSource(); |
|||
var data = this.getInitialData(option, ecModel); |
|||
wrapData(data, this); |
|||
this.dataTask.context.data = data; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
zrUtil.assert(data, 'getInitialData returned invalid data.'); |
|||
} |
|||
|
|||
inner(this).dataBeforeProcessed = data; // If we reverse the order (make data firstly, and then make
|
|||
// dataBeforeProcessed by cloneShallow), cloneShallow will
|
|||
// cause data.graph.data !== data when using
|
|||
// module:echarts/data/Graph or module:echarts/data/Tree.
|
|||
// See module:echarts/data/helper/linkSeriesData
|
|||
// Theoretically, it is unreasonable to call `seriesModel.getData()` in the model
|
|||
// init or merge stage, because the data can be restored. So we do not `restoreData`
|
|||
// and `setData` here, which forbids calling `seriesModel.getData()` in this stage.
|
|||
// Call `seriesModel.getRawData()` instead.
|
|||
// this.restoreData();
|
|||
|
|||
autoSeriesName(this); |
|||
|
|||
this._initSelectedMapFromData(data); |
|||
}; |
|||
/** |
|||
* Util for merge default and theme to option |
|||
*/ |
|||
|
|||
|
|||
SeriesModel.prototype.mergeDefaultAndTheme = function (option, ecModel) { |
|||
var layoutMode = fetchLayoutMode(this); |
|||
var inputPositionParams = layoutMode ? getLayoutParams(option) : {}; // Backward compat: using subType on theme.
|
|||
// But if name duplicate between series subType
|
|||
// (for example: parallel) add component mainType,
|
|||
// add suffix 'Series'.
|
|||
|
|||
var themeSubType = this.subType; |
|||
|
|||
if (ComponentModel.hasClass(themeSubType)) { |
|||
themeSubType += 'Series'; |
|||
} |
|||
|
|||
zrUtil.merge(option, ecModel.getTheme().get(this.subType)); |
|||
zrUtil.merge(option, this.getDefaultOption()); // Default label emphasis `show`
|
|||
|
|||
modelUtil.defaultEmphasis(option, 'label', ['show']); |
|||
this.fillDataTextStyle(option.data); |
|||
|
|||
if (layoutMode) { |
|||
mergeLayoutParam(option, inputPositionParams, layoutMode); |
|||
} |
|||
}; |
|||
|
|||
SeriesModel.prototype.mergeOption = function (newSeriesOption, ecModel) { |
|||
// this.settingTask.dirty();
|
|||
newSeriesOption = zrUtil.merge(this.option, newSeriesOption, true); |
|||
this.fillDataTextStyle(newSeriesOption.data); |
|||
var layoutMode = fetchLayoutMode(this); |
|||
|
|||
if (layoutMode) { |
|||
mergeLayoutParam(this.option, newSeriesOption, layoutMode); |
|||
} |
|||
|
|||
var sourceManager = inner(this).sourceManager; |
|||
sourceManager.dirty(); |
|||
sourceManager.prepareSource(); |
|||
var data = this.getInitialData(newSeriesOption, ecModel); |
|||
wrapData(data, this); |
|||
this.dataTask.dirty(); |
|||
this.dataTask.context.data = data; |
|||
inner(this).dataBeforeProcessed = data; |
|||
autoSeriesName(this); |
|||
|
|||
this._initSelectedMapFromData(data); |
|||
}; |
|||
|
|||
SeriesModel.prototype.fillDataTextStyle = function (data) { |
|||
// Default data label emphasis `show`
|
|||
// FIXME Tree structure data ?
|
|||
// FIXME Performance ?
|
|||
if (data && !zrUtil.isTypedArray(data)) { |
|||
var props = ['show']; |
|||
|
|||
for (var i = 0; i < data.length; i++) { |
|||
if (data[i] && data[i].label) { |
|||
modelUtil.defaultEmphasis(data[i], 'label', props); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
/** |
|||
* Init a data structure from data related option in series |
|||
* Must be overriden. |
|||
*/ |
|||
|
|||
|
|||
SeriesModel.prototype.getInitialData = function (option, ecModel) { |
|||
return; |
|||
}; |
|||
/** |
|||
* Append data to list |
|||
*/ |
|||
|
|||
|
|||
SeriesModel.prototype.appendData = function (params) { |
|||
// FIXME ???
|
|||
// (1) If data from dataset, forbidden append.
|
|||
// (2) support append data of dataset.
|
|||
var data = this.getRawData(); |
|||
data.appendData(params.data); |
|||
}; |
|||
/** |
|||
* Consider some method like `filter`, `map` need make new data, |
|||
* We should make sure that `seriesModel.getData()` get correct |
|||
* data in the stream procedure. So we fetch data from upstream |
|||
* each time `task.perform` called. |
|||
*/ |
|||
|
|||
|
|||
SeriesModel.prototype.getData = function (dataType) { |
|||
var task = getCurrentTask(this); |
|||
|
|||
if (task) { |
|||
var data = task.context.data; |
|||
return dataType == null ? data : data.getLinkedData(dataType); |
|||
} else { |
|||
// When series is not alive (that may happen when click toolbox
|
|||
// restore or setOption with not merge mode), series data may
|
|||
// be still need to judge animation or something when graphic
|
|||
// elements want to know whether fade out.
|
|||
return inner(this).data; |
|||
} |
|||
}; |
|||
|
|||
SeriesModel.prototype.getAllData = function () { |
|||
var mainData = this.getData(); |
|||
return mainData && mainData.getLinkedDataAll ? mainData.getLinkedDataAll() : [{ |
|||
data: mainData |
|||
}]; |
|||
}; |
|||
|
|||
SeriesModel.prototype.setData = function (data) { |
|||
var task = getCurrentTask(this); |
|||
|
|||
if (task) { |
|||
var context = task.context; // Consider case: filter, data sample.
|
|||
// FIXME:TS never used, so comment it
|
|||
// if (context.data !== data && task.modifyOutputEnd) {
|
|||
// task.setOutputEnd(data.count());
|
|||
// }
|
|||
|
|||
context.outputData = data; // Caution: setData should update context.data,
|
|||
// Because getData may be called multiply in a
|
|||
// single stage and expect to get the data just
|
|||
// set. (For example, AxisProxy, x y both call
|
|||
// getData and setDate sequentially).
|
|||
// So the context.data should be fetched from
|
|||
// upstream each time when a stage starts to be
|
|||
// performed.
|
|||
|
|||
if (task !== this.dataTask) { |
|||
context.data = data; |
|||
} |
|||
} |
|||
|
|||
inner(this).data = data; |
|||
}; |
|||
|
|||
SeriesModel.prototype.getEncode = function () { |
|||
var encode = this.get('encode', true); |
|||
|
|||
if (encode) { |
|||
return zrUtil.createHashMap(encode); |
|||
} |
|||
}; |
|||
|
|||
SeriesModel.prototype.getSourceManager = function () { |
|||
return inner(this).sourceManager; |
|||
}; |
|||
|
|||
SeriesModel.prototype.getSource = function () { |
|||
return this.getSourceManager().getSource(); |
|||
}; |
|||
/** |
|||
* Get data before processed |
|||
*/ |
|||
|
|||
|
|||
SeriesModel.prototype.getRawData = function () { |
|||
return inner(this).dataBeforeProcessed; |
|||
}; |
|||
|
|||
SeriesModel.prototype.getColorBy = function () { |
|||
var colorBy = this.get('colorBy'); |
|||
return colorBy || 'series'; |
|||
}; |
|||
|
|||
SeriesModel.prototype.isColorBySeries = function () { |
|||
return this.getColorBy() === 'series'; |
|||
}; |
|||
/** |
|||
* Get base axis if has coordinate system and has axis. |
|||
* By default use coordSys.getBaseAxis(); |
|||
* Can be overrided for some chart. |
|||
* @return {type} description |
|||
*/ |
|||
|
|||
|
|||
SeriesModel.prototype.getBaseAxis = function () { |
|||
var coordSys = this.coordinateSystem; // @ts-ignore
|
|||
|
|||
return coordSys && coordSys.getBaseAxis && coordSys.getBaseAxis(); |
|||
}; |
|||
/** |
|||
* Default tooltip formatter |
|||
* |
|||
* @param dataIndex |
|||
* @param multipleSeries |
|||
* @param dataType |
|||
* @param renderMode valid values: 'html'(by default) and 'richText'. |
|||
* 'html' is used for rendering tooltip in extra DOM form, and the result |
|||
* string is used as DOM HTML content. |
|||
* 'richText' is used for rendering tooltip in rich text form, for those where |
|||
* DOM operation is not supported. |
|||
* @return formatted tooltip with `html` and `markers` |
|||
* Notice: The override method can also return string |
|||
*/ |
|||
|
|||
|
|||
SeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { |
|||
return defaultSeriesFormatTooltip({ |
|||
series: this, |
|||
dataIndex: dataIndex, |
|||
multipleSeries: multipleSeries |
|||
}); |
|||
}; |
|||
|
|||
SeriesModel.prototype.isAnimationEnabled = function () { |
|||
var ecModel = this.ecModel; // Disable animation if using echarts in node but not give ssr flag.
|
|||
// In ssr mode, renderToString will generate svg with css animation.
|
|||
|
|||
if (env.node && !(ecModel && ecModel.ssr)) { |
|||
return false; |
|||
} |
|||
|
|||
var animationEnabled = this.getShallow('animation'); |
|||
|
|||
if (animationEnabled) { |
|||
if (this.getData().count() > this.getShallow('animationThreshold')) { |
|||
animationEnabled = false; |
|||
} |
|||
} |
|||
|
|||
return !!animationEnabled; |
|||
}; |
|||
|
|||
SeriesModel.prototype.restoreData = function () { |
|||
this.dataTask.dirty(); |
|||
}; |
|||
|
|||
SeriesModel.prototype.getColorFromPalette = function (name, scope, requestColorNum) { |
|||
var ecModel = this.ecModel; // PENDING
|
|||
|
|||
var color = PaletteMixin.prototype.getColorFromPalette.call(this, name, scope, requestColorNum); |
|||
|
|||
if (!color) { |
|||
color = ecModel.getColorFromPalette(name, scope, requestColorNum); |
|||
} |
|||
|
|||
return color; |
|||
}; |
|||
/** |
|||
* Use `data.mapDimensionsAll(coordDim)` instead. |
|||
* @deprecated |
|||
*/ |
|||
|
|||
|
|||
SeriesModel.prototype.coordDimToDataDim = function (coordDim) { |
|||
return this.getRawData().mapDimensionsAll(coordDim); |
|||
}; |
|||
/** |
|||
* Get progressive rendering count each step |
|||
*/ |
|||
|
|||
|
|||
SeriesModel.prototype.getProgressive = function () { |
|||
return this.get('progressive'); |
|||
}; |
|||
/** |
|||
* Get progressive rendering count each step |
|||
*/ |
|||
|
|||
|
|||
SeriesModel.prototype.getProgressiveThreshold = function () { |
|||
return this.get('progressiveThreshold'); |
|||
}; // PENGING If selectedMode is null ?
|
|||
|
|||
|
|||
SeriesModel.prototype.select = function (innerDataIndices, dataType) { |
|||
this._innerSelect(this.getData(dataType), innerDataIndices); |
|||
}; |
|||
|
|||
SeriesModel.prototype.unselect = function (innerDataIndices, dataType) { |
|||
var selectedMap = this.option.selectedMap; |
|||
|
|||
if (!selectedMap) { |
|||
return; |
|||
} |
|||
|
|||
var selectedMode = this.option.selectedMode; |
|||
var data = this.getData(dataType); |
|||
|
|||
if (selectedMode === 'series' || selectedMap === 'all') { |
|||
this.option.selectedMap = {}; |
|||
this._selectedDataIndicesMap = {}; |
|||
return; |
|||
} |
|||
|
|||
for (var i = 0; i < innerDataIndices.length; i++) { |
|||
var dataIndex = innerDataIndices[i]; |
|||
var nameOrId = getSelectionKey(data, dataIndex); |
|||
selectedMap[nameOrId] = false; |
|||
this._selectedDataIndicesMap[nameOrId] = -1; |
|||
} |
|||
}; |
|||
|
|||
SeriesModel.prototype.toggleSelect = function (innerDataIndices, dataType) { |
|||
var tmpArr = []; |
|||
|
|||
for (var i = 0; i < innerDataIndices.length; i++) { |
|||
tmpArr[0] = innerDataIndices[i]; |
|||
this.isSelected(innerDataIndices[i], dataType) ? this.unselect(tmpArr, dataType) : this.select(tmpArr, dataType); |
|||
} |
|||
}; |
|||
|
|||
SeriesModel.prototype.getSelectedDataIndices = function () { |
|||
if (this.option.selectedMap === 'all') { |
|||
return [].slice.call(this.getData().getIndices()); |
|||
} |
|||
|
|||
var selectedDataIndicesMap = this._selectedDataIndicesMap; |
|||
var nameOrIds = zrUtil.keys(selectedDataIndicesMap); |
|||
var dataIndices = []; |
|||
|
|||
for (var i = 0; i < nameOrIds.length; i++) { |
|||
var dataIndex = selectedDataIndicesMap[nameOrIds[i]]; |
|||
|
|||
if (dataIndex >= 0) { |
|||
dataIndices.push(dataIndex); |
|||
} |
|||
} |
|||
|
|||
return dataIndices; |
|||
}; |
|||
|
|||
SeriesModel.prototype.isSelected = function (dataIndex, dataType) { |
|||
var selectedMap = this.option.selectedMap; |
|||
|
|||
if (!selectedMap) { |
|||
return false; |
|||
} |
|||
|
|||
var data = this.getData(dataType); |
|||
return (selectedMap === 'all' || selectedMap[getSelectionKey(data, dataIndex)]) && !data.getItemModel(dataIndex).get(['select', 'disabled']); |
|||
}; |
|||
|
|||
SeriesModel.prototype.isUniversalTransitionEnabled = function () { |
|||
if (this[SERIES_UNIVERSAL_TRANSITION_PROP]) { |
|||
return true; |
|||
} |
|||
|
|||
var universalTransitionOpt = this.option.universalTransition; // Quick reject
|
|||
|
|||
if (!universalTransitionOpt) { |
|||
return false; |
|||
} |
|||
|
|||
if (universalTransitionOpt === true) { |
|||
return true; |
|||
} // Can be simply 'universalTransition: true'
|
|||
|
|||
|
|||
return universalTransitionOpt && universalTransitionOpt.enabled; |
|||
}; |
|||
|
|||
SeriesModel.prototype._innerSelect = function (data, innerDataIndices) { |
|||
var _a, _b; |
|||
|
|||
var option = this.option; |
|||
var selectedMode = option.selectedMode; |
|||
var len = innerDataIndices.length; |
|||
|
|||
if (!selectedMode || !len) { |
|||
return; |
|||
} |
|||
|
|||
if (selectedMode === 'series') { |
|||
option.selectedMap = 'all'; |
|||
} else if (selectedMode === 'multiple') { |
|||
if (!zrUtil.isObject(option.selectedMap)) { |
|||
option.selectedMap = {}; |
|||
} |
|||
|
|||
var selectedMap = option.selectedMap; |
|||
|
|||
for (var i = 0; i < len; i++) { |
|||
var dataIndex = innerDataIndices[i]; // TODO diffrent types of data share same object.
|
|||
|
|||
var nameOrId = getSelectionKey(data, dataIndex); |
|||
selectedMap[nameOrId] = true; |
|||
this._selectedDataIndicesMap[nameOrId] = data.getRawIndex(dataIndex); |
|||
} |
|||
} else if (selectedMode === 'single' || selectedMode === true) { |
|||
var lastDataIndex = innerDataIndices[len - 1]; |
|||
var nameOrId = getSelectionKey(data, lastDataIndex); |
|||
option.selectedMap = (_a = {}, _a[nameOrId] = true, _a); |
|||
this._selectedDataIndicesMap = (_b = {}, _b[nameOrId] = data.getRawIndex(lastDataIndex), _b); |
|||
} |
|||
}; |
|||
|
|||
SeriesModel.prototype._initSelectedMapFromData = function (data) { |
|||
// Ignore select info in data if selectedMap exists.
|
|||
// NOTE It's only for legacy usage. edge data is not supported.
|
|||
if (this.option.selectedMap) { |
|||
return; |
|||
} |
|||
|
|||
var dataIndices = []; |
|||
|
|||
if (data.hasItemOption) { |
|||
data.each(function (idx) { |
|||
var rawItem = data.getRawDataItem(idx); |
|||
|
|||
if (rawItem && rawItem.selected) { |
|||
dataIndices.push(idx); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
if (dataIndices.length > 0) { |
|||
this._innerSelect(data, dataIndices); |
|||
} |
|||
}; // /**
|
|||
// * @see {module:echarts/stream/Scheduler}
|
|||
// */
|
|||
// abstract pipeTask: null
|
|||
|
|||
|
|||
SeriesModel.registerClass = function (clz) { |
|||
return ComponentModel.registerClass(clz); |
|||
}; |
|||
|
|||
SeriesModel.protoInitialize = function () { |
|||
var proto = SeriesModel.prototype; |
|||
proto.type = 'series.__base__'; |
|||
proto.seriesIndex = 0; |
|||
proto.ignoreStyleOnData = false; |
|||
proto.hasSymbolVisual = false; |
|||
proto.defaultSymbol = 'circle'; // Make sure the values can be accessed!
|
|||
|
|||
proto.visualStyleAccessPath = 'itemStyle'; |
|||
proto.visualDrawType = 'fill'; |
|||
}(); |
|||
|
|||
return SeriesModel; |
|||
}(ComponentModel); |
|||
|
|||
zrUtil.mixin(SeriesModel, DataFormatMixin); |
|||
zrUtil.mixin(SeriesModel, PaletteMixin); |
|||
mountExtend(SeriesModel, ComponentModel); |
|||
/** |
|||
* MUST be called after `prepareSource` called |
|||
* Here we need to make auto series, especially for auto legend. But we |
|||
* do not modify series.name in option to avoid side effects. |
|||
*/ |
|||
|
|||
function autoSeriesName(seriesModel) { |
|||
// User specified name has higher priority, otherwise it may cause
|
|||
// series can not be queried unexpectedly.
|
|||
var name = seriesModel.name; |
|||
|
|||
if (!modelUtil.isNameSpecified(seriesModel)) { |
|||
seriesModel.name = getSeriesAutoName(seriesModel) || name; |
|||
} |
|||
} |
|||
|
|||
function getSeriesAutoName(seriesModel) { |
|||
var data = seriesModel.getRawData(); |
|||
var dataDims = data.mapDimensionsAll('seriesName'); |
|||
var nameArr = []; |
|||
zrUtil.each(dataDims, function (dataDim) { |
|||
var dimInfo = data.getDimensionInfo(dataDim); |
|||
dimInfo.displayName && nameArr.push(dimInfo.displayName); |
|||
}); |
|||
return nameArr.join(' '); |
|||
} |
|||
|
|||
function dataTaskCount(context) { |
|||
return context.model.getRawData().count(); |
|||
} |
|||
|
|||
function dataTaskReset(context) { |
|||
var seriesModel = context.model; |
|||
seriesModel.setData(seriesModel.getRawData().cloneShallow()); |
|||
return dataTaskProgress; |
|||
} |
|||
|
|||
function dataTaskProgress(param, context) { |
|||
// Avoid repead cloneShallow when data just created in reset.
|
|||
if (context.outputData && param.end > context.outputData.count()) { |
|||
context.model.getRawData().cloneShallow(context.outputData); |
|||
} |
|||
} // TODO refactor
|
|||
|
|||
|
|||
function wrapData(data, seriesModel) { |
|||
zrUtil.each(zrUtil.concatArray(data.CHANGABLE_METHODS, data.DOWNSAMPLE_METHODS), function (methodName) { |
|||
data.wrapMethod(methodName, zrUtil.curry(onDataChange, seriesModel)); |
|||
}); |
|||
} |
|||
|
|||
function onDataChange(seriesModel, newList) { |
|||
var task = getCurrentTask(seriesModel); |
|||
|
|||
if (task) { |
|||
// Consider case: filter, selectRange
|
|||
task.setOutputEnd((newList || this).count()); |
|||
} |
|||
|
|||
return newList; |
|||
} |
|||
|
|||
function getCurrentTask(seriesModel) { |
|||
var scheduler = (seriesModel.ecModel || {}).scheduler; |
|||
var pipeline = scheduler && scheduler.getPipeline(seriesModel.uid); |
|||
|
|||
if (pipeline) { |
|||
// When pipline finished, the currrentTask keep the last
|
|||
// task (renderTask).
|
|||
var task = pipeline.currentTask; |
|||
|
|||
if (task) { |
|||
var agentStubMap = task.agentStubMap; |
|||
|
|||
if (agentStubMap) { |
|||
task = agentStubMap.get(seriesModel.uid); |
|||
} |
|||
} |
|||
|
|||
return task; |
|||
} |
|||
} |
|||
|
|||
export default SeriesModel; |
|||
@ -0,0 +1,132 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
var platform = ''; // Navigator not exists in node
|
|||
|
|||
if (typeof navigator !== 'undefined') { |
|||
/* global navigator */ |
|||
platform = navigator.platform || ''; |
|||
} |
|||
|
|||
var decalColor = 'rgba(0, 0, 0, 0.2)'; |
|||
export default { |
|||
darkMode: 'auto', |
|||
// backgroundColor: 'rgba(0,0,0,0)',
|
|||
colorBy: 'series', |
|||
color: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], |
|||
gradientColor: ['#f6efa6', '#d88273', '#bf444c'], |
|||
aria: { |
|||
decal: { |
|||
decals: [{ |
|||
color: decalColor, |
|||
dashArrayX: [1, 0], |
|||
dashArrayY: [2, 5], |
|||
symbolSize: 1, |
|||
rotation: Math.PI / 6 |
|||
}, { |
|||
color: decalColor, |
|||
symbol: 'circle', |
|||
dashArrayX: [[8, 8], [0, 8, 8, 0]], |
|||
dashArrayY: [6, 0], |
|||
symbolSize: 0.8 |
|||
}, { |
|||
color: decalColor, |
|||
dashArrayX: [1, 0], |
|||
dashArrayY: [4, 3], |
|||
rotation: -Math.PI / 4 |
|||
}, { |
|||
color: decalColor, |
|||
dashArrayX: [[6, 6], [0, 6, 6, 0]], |
|||
dashArrayY: [6, 0] |
|||
}, { |
|||
color: decalColor, |
|||
dashArrayX: [[1, 0], [1, 6]], |
|||
dashArrayY: [1, 0, 6, 0], |
|||
rotation: Math.PI / 4 |
|||
}, { |
|||
color: decalColor, |
|||
symbol: 'triangle', |
|||
dashArrayX: [[9, 9], [0, 9, 9, 0]], |
|||
dashArrayY: [7, 2], |
|||
symbolSize: 0.75 |
|||
}] |
|||
} |
|||
}, |
|||
// If xAxis and yAxis declared, grid is created by default.
|
|||
// grid: {},
|
|||
textStyle: { |
|||
// color: '#000',
|
|||
// decoration: 'none',
|
|||
// PENDING
|
|||
fontFamily: platform.match(/^Win/) ? 'Microsoft YaHei' : 'sans-serif', |
|||
// fontFamily: 'Arial, Verdana, sans-serif',
|
|||
fontSize: 12, |
|||
fontStyle: 'normal', |
|||
fontWeight: 'normal' |
|||
}, |
|||
// http://blogs.adobe.com/webplatform/2014/02/24/using-blend-modes-in-html-canvas/
|
|||
// https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
|
|||
// Default is source-over
|
|||
blendMode: null, |
|||
stateAnimation: { |
|||
duration: 300, |
|||
easing: 'cubicOut' |
|||
}, |
|||
animation: 'auto', |
|||
animationDuration: 1000, |
|||
animationDurationUpdate: 500, |
|||
animationEasing: 'cubicInOut', |
|||
animationEasingUpdate: 'cubicInOut', |
|||
animationThreshold: 2000, |
|||
// Configuration for progressive/incremental rendering
|
|||
progressiveThreshold: 3000, |
|||
progressive: 400, |
|||
// Threshold of if use single hover layer to optimize.
|
|||
// It is recommended that `hoverLayerThreshold` is equivalent to or less than
|
|||
// `progressiveThreshold`, otherwise hover will cause restart of progressive,
|
|||
// which is unexpected.
|
|||
// see example <echarts/test/heatmap-large.html>.
|
|||
hoverLayerThreshold: 3000, |
|||
// See: module:echarts/scale/Time
|
|||
useUTC: false |
|||
}; |
|||
@ -0,0 +1,71 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { createHashMap, assert } from 'zrender/lib/core/util.js'; |
|||
import { isComponentIdInternal } from '../util/model.js'; |
|||
var internalOptionCreatorMap = createHashMap(); |
|||
export function registerInternalOptionCreator(mainType, creator) { |
|||
assert(internalOptionCreatorMap.get(mainType) == null && creator); |
|||
internalOptionCreatorMap.set(mainType, creator); |
|||
} |
|||
export function concatInternalOptions(ecModel, mainType, newCmptOptionList) { |
|||
var internalOptionCreator = internalOptionCreatorMap.get(mainType); |
|||
|
|||
if (!internalOptionCreator) { |
|||
return newCmptOptionList; |
|||
} |
|||
|
|||
var internalOptions = internalOptionCreator(ecModel); |
|||
|
|||
if (!internalOptions) { |
|||
return newCmptOptionList; |
|||
} |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
for (var i = 0; i < internalOptions.length; i++) { |
|||
assert(isComponentIdInternal(internalOptions[i])); |
|||
} |
|||
} |
|||
|
|||
return newCmptOptionList.concat(internalOptions); |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 makeStyleMapper from './makeStyleMapper.js'; |
|||
export var AREA_STYLE_KEY_MAP = [['fill', 'color'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['opacity'], ['shadowColor'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
|
|||
// So do not transfer decal directly.
|
|||
]; |
|||
var getAreaStyle = makeStyleMapper(AREA_STYLE_KEY_MAP); |
|||
|
|||
var AreaStyleMixin = |
|||
/** @class */ |
|||
function () { |
|||
function AreaStyleMixin() {} |
|||
|
|||
AreaStyleMixin.prototype.getAreaStyle = function (excludes, includes) { |
|||
return getAreaStyle(this, excludes, includes); |
|||
}; |
|||
|
|||
return AreaStyleMixin; |
|||
}(); |
|||
|
|||
; |
|||
export { AreaStyleMixin }; |
|||
@ -0,0 +1,228 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 * as zrUtil from 'zrender/lib/core/util.js'; |
|||
import { retrieveRawValue } from '../../data/helper/dataProvider.js'; |
|||
import { formatTpl } from '../../util/format.js'; |
|||
import { error, makePrintable } from '../../util/log.js'; |
|||
var DIMENSION_LABEL_REG = /\{@(.+?)\}/g; |
|||
|
|||
var DataFormatMixin = |
|||
/** @class */ |
|||
function () { |
|||
function DataFormatMixin() {} |
|||
/** |
|||
* Get params for formatter |
|||
*/ |
|||
|
|||
|
|||
DataFormatMixin.prototype.getDataParams = function (dataIndex, dataType) { |
|||
var data = this.getData(dataType); |
|||
var rawValue = this.getRawValue(dataIndex, dataType); |
|||
var rawDataIndex = data.getRawIndex(dataIndex); |
|||
var name = data.getName(dataIndex); |
|||
var itemOpt = data.getRawDataItem(dataIndex); |
|||
var style = data.getItemVisual(dataIndex, 'style'); |
|||
var color = style && style[data.getItemVisual(dataIndex, 'drawType') || 'fill']; |
|||
var borderColor = style && style.stroke; |
|||
var mainType = this.mainType; |
|||
var isSeries = mainType === 'series'; |
|||
var userOutput = data.userOutput && data.userOutput.get(); |
|||
return { |
|||
componentType: mainType, |
|||
componentSubType: this.subType, |
|||
componentIndex: this.componentIndex, |
|||
seriesType: isSeries ? this.subType : null, |
|||
seriesIndex: this.seriesIndex, |
|||
seriesId: isSeries ? this.id : null, |
|||
seriesName: isSeries ? this.name : null, |
|||
name: name, |
|||
dataIndex: rawDataIndex, |
|||
data: itemOpt, |
|||
dataType: dataType, |
|||
value: rawValue, |
|||
color: color, |
|||
borderColor: borderColor, |
|||
dimensionNames: userOutput ? userOutput.fullDimensions : null, |
|||
encode: userOutput ? userOutput.encode : null, |
|||
// Param name list for mapping `a`, `b`, `c`, `d`, `e`
|
|||
$vars: ['seriesName', 'name', 'value'] |
|||
}; |
|||
}; |
|||
/** |
|||
* Format label |
|||
* @param dataIndex |
|||
* @param status 'normal' by default |
|||
* @param dataType |
|||
* @param labelDimIndex Only used in some chart that |
|||
* use formatter in different dimensions, like radar. |
|||
* @param formatter Formatter given outside. |
|||
* @return return null/undefined if no formatter |
|||
*/ |
|||
|
|||
|
|||
DataFormatMixin.prototype.getFormattedLabel = function (dataIndex, status, dataType, labelDimIndex, formatter, extendParams) { |
|||
status = status || 'normal'; |
|||
var data = this.getData(dataType); |
|||
var params = this.getDataParams(dataIndex, dataType); |
|||
|
|||
if (extendParams) { |
|||
params.value = extendParams.interpolatedValue; |
|||
} |
|||
|
|||
if (labelDimIndex != null && zrUtil.isArray(params.value)) { |
|||
params.value = params.value[labelDimIndex]; |
|||
} |
|||
|
|||
if (!formatter) { |
|||
var itemModel = data.getItemModel(dataIndex); // @ts-ignore
|
|||
|
|||
formatter = itemModel.get(status === 'normal' ? ['label', 'formatter'] : [status, 'label', 'formatter']); |
|||
} |
|||
|
|||
if (zrUtil.isFunction(formatter)) { |
|||
params.status = status; |
|||
params.dimensionIndex = labelDimIndex; |
|||
return formatter(params); |
|||
} else if (zrUtil.isString(formatter)) { |
|||
var str = formatTpl(formatter, params); // Support 'aaa{@[3]}bbb{@product}ccc'.
|
|||
// Do not support '}' in dim name util have to.
|
|||
|
|||
return str.replace(DIMENSION_LABEL_REG, function (origin, dimStr) { |
|||
var len = dimStr.length; |
|||
var dimLoose = dimStr; |
|||
|
|||
if (dimLoose.charAt(0) === '[' && dimLoose.charAt(len - 1) === ']') { |
|||
dimLoose = +dimLoose.slice(1, len - 1); // Also support: '[]' => 0
|
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (isNaN(dimLoose)) { |
|||
error("Invalide label formatter: @" + dimStr + ", only support @[0], @[1], @[2], ..."); |
|||
} |
|||
} |
|||
} |
|||
|
|||
var val = retrieveRawValue(data, dataIndex, dimLoose); |
|||
|
|||
if (extendParams && zrUtil.isArray(extendParams.interpolatedValue)) { |
|||
var dimIndex = data.getDimensionIndex(dimLoose); |
|||
|
|||
if (dimIndex >= 0) { |
|||
val = extendParams.interpolatedValue[dimIndex]; |
|||
} |
|||
} |
|||
|
|||
return val != null ? val + '' : ''; |
|||
}); |
|||
} |
|||
}; |
|||
/** |
|||
* Get raw value in option |
|||
*/ |
|||
|
|||
|
|||
DataFormatMixin.prototype.getRawValue = function (idx, dataType) { |
|||
return retrieveRawValue(this.getData(dataType), idx); |
|||
}; |
|||
/** |
|||
* Should be implemented. |
|||
* @param {number} dataIndex |
|||
* @param {boolean} [multipleSeries=false] |
|||
* @param {string} [dataType] |
|||
*/ |
|||
|
|||
|
|||
DataFormatMixin.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { |
|||
// Empty function
|
|||
return; |
|||
}; |
|||
|
|||
return DataFormatMixin; |
|||
}(); |
|||
|
|||
export { DataFormatMixin }; |
|||
; // PENDING: previously we accept this type when calling `formatTooltip`,
|
|||
// but guess little chance has been used outside. Do we need to backward
|
|||
// compat it?
|
|||
// type TooltipFormatResultLegacyObject = {
|
|||
// // `html` means the markup language text, either in 'html' or 'richText'.
|
|||
// // The name `html` is not appropriate becuase in 'richText' it is not a HTML
|
|||
// // string. But still support it for backward compat.
|
|||
// html: string;
|
|||
// markers: Dictionary<ColorString>;
|
|||
// };
|
|||
|
|||
/** |
|||
* For backward compat, normalize the return from `formatTooltip`. |
|||
*/ |
|||
|
|||
export function normalizeTooltipFormatResult(result) { |
|||
var markupText; // let markers: Dictionary<ColorString>;
|
|||
|
|||
var markupFragment; |
|||
|
|||
if (zrUtil.isObject(result)) { |
|||
if (result.type) { |
|||
markupFragment = result; |
|||
} else { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
console.warn('The return type of `formatTooltip` is not supported: ' + makePrintable(result)); |
|||
} |
|||
} // else {
|
|||
// markupText = (result as TooltipFormatResultLegacyObject).html;
|
|||
// markers = (result as TooltipFormatResultLegacyObject).markers;
|
|||
// if (markersExisting) {
|
|||
// markers = zrUtil.merge(markersExisting, markers);
|
|||
// }
|
|||
// }
|
|||
|
|||
} else { |
|||
markupText = result; |
|||
} |
|||
|
|||
return { |
|||
text: markupText, |
|||
// markers: markers || markersExisting,
|
|||
frag: markupFragment |
|||
}; |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 makeStyleMapper from './makeStyleMapper.js'; |
|||
export var ITEM_STYLE_KEY_MAP = [['fill', 'color'], ['stroke', 'borderColor'], ['lineWidth', 'borderWidth'], ['opacity'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'], ['lineDash', 'borderType'], ['lineDashOffset', 'borderDashOffset'], ['lineCap', 'borderCap'], ['lineJoin', 'borderJoin'], ['miterLimit', 'borderMiterLimit'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
|
|||
// So do not transfer decal directly.
|
|||
]; |
|||
var getItemStyle = makeStyleMapper(ITEM_STYLE_KEY_MAP); |
|||
|
|||
var ItemStyleMixin = |
|||
/** @class */ |
|||
function () { |
|||
function ItemStyleMixin() {} |
|||
|
|||
ItemStyleMixin.prototype.getItemStyle = function (excludes, includes) { |
|||
return getItemStyle(this, excludes, includes); |
|||
}; |
|||
|
|||
return ItemStyleMixin; |
|||
}(); |
|||
|
|||
export { ItemStyleMixin }; |
|||
@ -0,0 +1,63 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 makeStyleMapper from './makeStyleMapper.js'; |
|||
export var LINE_STYLE_KEY_MAP = [['lineWidth', 'width'], ['stroke', 'color'], ['opacity'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'], ['lineDash', 'type'], ['lineDashOffset', 'dashOffset'], ['lineCap', 'cap'], ['lineJoin', 'join'], ['miterLimit'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
|
|||
// So do not transfer decal directly.
|
|||
]; |
|||
var getLineStyle = makeStyleMapper(LINE_STYLE_KEY_MAP); |
|||
|
|||
var LineStyleMixin = |
|||
/** @class */ |
|||
function () { |
|||
function LineStyleMixin() {} |
|||
|
|||
LineStyleMixin.prototype.getLineStyle = function (excludes) { |
|||
return getLineStyle(this, excludes); |
|||
}; |
|||
|
|||
return LineStyleMixin; |
|||
}(); |
|||
|
|||
; |
|||
export { LineStyleMixin }; |
|||
@ -0,0 +1,76 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
// TODO Parse shadow style
|
|||
// TODO Only shallow path support
|
|||
import * as zrUtil from 'zrender/lib/core/util.js'; |
|||
export default function makeStyleMapper(properties, ignoreParent) { |
|||
// Normalize
|
|||
for (var i = 0; i < properties.length; i++) { |
|||
if (!properties[i][1]) { |
|||
properties[i][1] = properties[i][0]; |
|||
} |
|||
} |
|||
|
|||
ignoreParent = ignoreParent || false; |
|||
return function (model, excludes, includes) { |
|||
var style = {}; |
|||
|
|||
for (var i = 0; i < properties.length; i++) { |
|||
var propName = properties[i][1]; |
|||
|
|||
if (excludes && zrUtil.indexOf(excludes, propName) >= 0 || includes && zrUtil.indexOf(includes, propName) < 0) { |
|||
continue; |
|||
} |
|||
|
|||
var val = model.getShallow(propName, ignoreParent); |
|||
|
|||
if (val != null) { |
|||
style[properties[i][0]] = val; |
|||
} |
|||
} // TODO Text or image?
|
|||
|
|||
|
|||
return style; |
|||
}; |
|||
} |
|||
@ -0,0 +1,123 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { makeInner, normalizeToArray } from '../../util/model.js'; |
|||
var innerColor = makeInner(); |
|||
var innerDecal = makeInner(); |
|||
|
|||
var PaletteMixin = |
|||
/** @class */ |
|||
function () { |
|||
function PaletteMixin() {} |
|||
|
|||
PaletteMixin.prototype.getColorFromPalette = function (name, scope, requestNum) { |
|||
var defaultPalette = normalizeToArray(this.get('color', true)); |
|||
var layeredPalette = this.get('colorLayer', true); |
|||
return getFromPalette(this, innerColor, defaultPalette, layeredPalette, name, scope, requestNum); |
|||
}; |
|||
|
|||
PaletteMixin.prototype.clearColorPalette = function () { |
|||
clearPalette(this, innerColor); |
|||
}; |
|||
|
|||
return PaletteMixin; |
|||
}(); |
|||
|
|||
export function getDecalFromPalette(ecModel, name, scope, requestNum) { |
|||
var defaultDecals = normalizeToArray(ecModel.get(['aria', 'decal', 'decals'])); |
|||
return getFromPalette(ecModel, innerDecal, defaultDecals, null, name, scope, requestNum); |
|||
} |
|||
|
|||
function getNearestPalette(palettes, requestColorNum) { |
|||
var paletteNum = palettes.length; // TODO palettes must be in order
|
|||
|
|||
for (var i = 0; i < paletteNum; i++) { |
|||
if (palettes[i].length > requestColorNum) { |
|||
return palettes[i]; |
|||
} |
|||
} |
|||
|
|||
return palettes[paletteNum - 1]; |
|||
} |
|||
/** |
|||
* @param name MUST NOT be null/undefined. Otherwise call this function |
|||
* twise with the same parameters will get different result. |
|||
* @param scope default this. |
|||
* @return Can be null/undefined |
|||
*/ |
|||
|
|||
|
|||
function getFromPalette(that, inner, defaultPalette, layeredPalette, name, scope, requestNum) { |
|||
scope = scope || that; |
|||
var scopeFields = inner(scope); |
|||
var paletteIdx = scopeFields.paletteIdx || 0; |
|||
var paletteNameMap = scopeFields.paletteNameMap = scopeFields.paletteNameMap || {}; // Use `hasOwnProperty` to avoid conflict with Object.prototype.
|
|||
|
|||
if (paletteNameMap.hasOwnProperty(name)) { |
|||
return paletteNameMap[name]; |
|||
} |
|||
|
|||
var palette = requestNum == null || !layeredPalette ? defaultPalette : getNearestPalette(layeredPalette, requestNum); // In case can't find in layered color palette.
|
|||
|
|||
palette = palette || defaultPalette; |
|||
|
|||
if (!palette || !palette.length) { |
|||
return; |
|||
} |
|||
|
|||
var pickedPaletteItem = palette[paletteIdx]; |
|||
|
|||
if (name) { |
|||
paletteNameMap[name] = pickedPaletteItem; |
|||
} |
|||
|
|||
scopeFields.paletteIdx = (paletteIdx + 1) % palette.length; |
|||
return pickedPaletteItem; |
|||
} |
|||
|
|||
function clearPalette(that, inner) { |
|||
inner(that).paletteIdx = 0; |
|||
inner(that).paletteNameMap = {}; |
|||
} |
|||
|
|||
export { PaletteMixin }; |
|||
@ -0,0 +1,99 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { getFont } from '../../label/labelStyle.js'; |
|||
import ZRText from 'zrender/lib/graphic/Text.js'; |
|||
var PATH_COLOR = ['textStyle', 'color']; |
|||
var textStyleParams = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'padding', 'lineHeight', 'rich', 'width', 'height', 'overflow']; // TODO Performance improvement?
|
|||
|
|||
var tmpText = new ZRText(); |
|||
|
|||
var TextStyleMixin = |
|||
/** @class */ |
|||
function () { |
|||
function TextStyleMixin() {} |
|||
/** |
|||
* Get color property or get color from option.textStyle.color |
|||
*/ |
|||
// TODO Callback
|
|||
|
|||
|
|||
TextStyleMixin.prototype.getTextColor = function (isEmphasis) { |
|||
var ecModel = this.ecModel; |
|||
return this.getShallow('color') || (!isEmphasis && ecModel ? ecModel.get(PATH_COLOR) : null); |
|||
}; |
|||
/** |
|||
* Create font string from fontStyle, fontWeight, fontSize, fontFamily |
|||
* @return {string} |
|||
*/ |
|||
|
|||
|
|||
TextStyleMixin.prototype.getFont = function () { |
|||
return getFont({ |
|||
fontStyle: this.getShallow('fontStyle'), |
|||
fontWeight: this.getShallow('fontWeight'), |
|||
fontSize: this.getShallow('fontSize'), |
|||
fontFamily: this.getShallow('fontFamily') |
|||
}, this.ecModel); |
|||
}; |
|||
|
|||
TextStyleMixin.prototype.getTextRect = function (text) { |
|||
var style = { |
|||
text: text, |
|||
verticalAlign: this.getShallow('verticalAlign') || this.getShallow('baseline') |
|||
}; |
|||
|
|||
for (var i = 0; i < textStyleParams.length; i++) { |
|||
style[textStyleParams[i]] = this.getShallow(textStyleParams[i]); |
|||
} |
|||
|
|||
tmpText.useStyle(style); |
|||
tmpText.update(); |
|||
return tmpText.getBoundingRect(); |
|||
}; |
|||
|
|||
return TextStyleMixin; |
|||
}(); |
|||
|
|||
; |
|||
export default TextStyleMixin; |
|||
@ -0,0 +1,198 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
/** |
|||
* Helper for model references. |
|||
* There are many manners to refer axis/coordSys. |
|||
*/ |
|||
// TODO
|
|||
// merge relevant logic to this file?
|
|||
// check: "modelHelper" of tooltip and "BrushTargetManager".
|
|||
import { createHashMap, retrieve, each } from 'zrender/lib/core/util.js'; |
|||
import { SINGLE_REFERRING } from '../util/model.js'; |
|||
/** |
|||
* @class |
|||
* For example: |
|||
* { |
|||
* coordSysName: 'cartesian2d', |
|||
* coordSysDims: ['x', 'y', ...], |
|||
* axisMap: HashMap({ |
|||
* x: xAxisModel, |
|||
* y: yAxisModel |
|||
* }), |
|||
* categoryAxisMap: HashMap({ |
|||
* x: xAxisModel, |
|||
* y: undefined |
|||
* }), |
|||
* // The index of the first category axis in `coordSysDims`.
|
|||
* // `null/undefined` means no category axis exists.
|
|||
* firstCategoryDimIndex: 1, |
|||
* // To replace user specified encode.
|
|||
* } |
|||
*/ |
|||
|
|||
var CoordSysInfo = |
|||
/** @class */ |
|||
function () { |
|||
function CoordSysInfo(coordSysName) { |
|||
this.coordSysDims = []; |
|||
this.axisMap = createHashMap(); |
|||
this.categoryAxisMap = createHashMap(); |
|||
this.coordSysName = coordSysName; |
|||
} |
|||
|
|||
return CoordSysInfo; |
|||
}(); |
|||
|
|||
export function getCoordSysInfoBySeries(seriesModel) { |
|||
var coordSysName = seriesModel.get('coordinateSystem'); |
|||
var result = new CoordSysInfo(coordSysName); |
|||
var fetch = fetchers[coordSysName]; |
|||
|
|||
if (fetch) { |
|||
fetch(seriesModel, result, result.axisMap, result.categoryAxisMap); |
|||
return result; |
|||
} |
|||
} |
|||
var fetchers = { |
|||
cartesian2d: function (seriesModel, result, axisMap, categoryAxisMap) { |
|||
var xAxisModel = seriesModel.getReferringComponents('xAxis', SINGLE_REFERRING).models[0]; |
|||
var yAxisModel = seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[0]; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (!xAxisModel) { |
|||
throw new Error('xAxis "' + retrieve(seriesModel.get('xAxisIndex'), seriesModel.get('xAxisId'), 0) + '" not found'); |
|||
} |
|||
|
|||
if (!yAxisModel) { |
|||
throw new Error('yAxis "' + retrieve(seriesModel.get('xAxisIndex'), seriesModel.get('yAxisId'), 0) + '" not found'); |
|||
} |
|||
} |
|||
|
|||
result.coordSysDims = ['x', 'y']; |
|||
axisMap.set('x', xAxisModel); |
|||
axisMap.set('y', yAxisModel); |
|||
|
|||
if (isCategory(xAxisModel)) { |
|||
categoryAxisMap.set('x', xAxisModel); |
|||
result.firstCategoryDimIndex = 0; |
|||
} |
|||
|
|||
if (isCategory(yAxisModel)) { |
|||
categoryAxisMap.set('y', yAxisModel); |
|||
result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1); |
|||
} |
|||
}, |
|||
singleAxis: function (seriesModel, result, axisMap, categoryAxisMap) { |
|||
var singleAxisModel = seriesModel.getReferringComponents('singleAxis', SINGLE_REFERRING).models[0]; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (!singleAxisModel) { |
|||
throw new Error('singleAxis should be specified.'); |
|||
} |
|||
} |
|||
|
|||
result.coordSysDims = ['single']; |
|||
axisMap.set('single', singleAxisModel); |
|||
|
|||
if (isCategory(singleAxisModel)) { |
|||
categoryAxisMap.set('single', singleAxisModel); |
|||
result.firstCategoryDimIndex = 0; |
|||
} |
|||
}, |
|||
polar: function (seriesModel, result, axisMap, categoryAxisMap) { |
|||
var polarModel = seriesModel.getReferringComponents('polar', SINGLE_REFERRING).models[0]; |
|||
var radiusAxisModel = polarModel.findAxisModel('radiusAxis'); |
|||
var angleAxisModel = polarModel.findAxisModel('angleAxis'); |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (!angleAxisModel) { |
|||
throw new Error('angleAxis option not found'); |
|||
} |
|||
|
|||
if (!radiusAxisModel) { |
|||
throw new Error('radiusAxis option not found'); |
|||
} |
|||
} |
|||
|
|||
result.coordSysDims = ['radius', 'angle']; |
|||
axisMap.set('radius', radiusAxisModel); |
|||
axisMap.set('angle', angleAxisModel); |
|||
|
|||
if (isCategory(radiusAxisModel)) { |
|||
categoryAxisMap.set('radius', radiusAxisModel); |
|||
result.firstCategoryDimIndex = 0; |
|||
} |
|||
|
|||
if (isCategory(angleAxisModel)) { |
|||
categoryAxisMap.set('angle', angleAxisModel); |
|||
result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1); |
|||
} |
|||
}, |
|||
geo: function (seriesModel, result, axisMap, categoryAxisMap) { |
|||
result.coordSysDims = ['lng', 'lat']; |
|||
}, |
|||
parallel: function (seriesModel, result, axisMap, categoryAxisMap) { |
|||
var ecModel = seriesModel.ecModel; |
|||
var parallelModel = ecModel.getComponent('parallel', seriesModel.get('parallelIndex')); |
|||
var coordSysDims = result.coordSysDims = parallelModel.dimensions.slice(); |
|||
each(parallelModel.parallelAxisIndex, function (axisIndex, index) { |
|||
var axisModel = ecModel.getComponent('parallelAxis', axisIndex); |
|||
var axisDim = coordSysDims[index]; |
|||
axisMap.set(axisDim, axisModel); |
|||
|
|||
if (isCategory(axisModel)) { |
|||
categoryAxisMap.set(axisDim, axisModel); |
|||
|
|||
if (result.firstCategoryDimIndex == null) { |
|||
result.firstCategoryDimIndex = index; |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
function isCategory(axisModel) { |
|||
return axisModel.get('type') === 'category'; |
|||
} |
|||
@ -0,0 +1,305 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { each, isArray, isObject, isTypedArray, defaults } from 'zrender/lib/core/util.js'; |
|||
import compatStyle from './helper/compatStyle.js'; |
|||
import { normalizeToArray } from '../util/model.js'; |
|||
import { deprecateLog, deprecateReplaceLog } from '../util/log.js'; |
|||
|
|||
function get(opt, path) { |
|||
var pathArr = path.split(','); |
|||
var obj = opt; |
|||
|
|||
for (var i = 0; i < pathArr.length; i++) { |
|||
obj = obj && obj[pathArr[i]]; |
|||
|
|||
if (obj == null) { |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return obj; |
|||
} |
|||
|
|||
function set(opt, path, val, overwrite) { |
|||
var pathArr = path.split(','); |
|||
var obj = opt; |
|||
var key; |
|||
var i = 0; |
|||
|
|||
for (; i < pathArr.length - 1; i++) { |
|||
key = pathArr[i]; |
|||
|
|||
if (obj[key] == null) { |
|||
obj[key] = {}; |
|||
} |
|||
|
|||
obj = obj[key]; |
|||
} |
|||
|
|||
if (overwrite || obj[pathArr[i]] == null) { |
|||
obj[pathArr[i]] = val; |
|||
} |
|||
} |
|||
|
|||
function compatLayoutProperties(option) { |
|||
option && each(LAYOUT_PROPERTIES, function (prop) { |
|||
if (prop[0] in option && !(prop[1] in option)) { |
|||
option[prop[1]] = option[prop[0]]; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
var LAYOUT_PROPERTIES = [['x', 'left'], ['y', 'top'], ['x2', 'right'], ['y2', 'bottom']]; |
|||
var COMPATITABLE_COMPONENTS = ['grid', 'geo', 'parallel', 'legend', 'toolbox', 'title', 'visualMap', 'dataZoom', 'timeline']; |
|||
var BAR_ITEM_STYLE_MAP = [['borderRadius', 'barBorderRadius'], ['borderColor', 'barBorderColor'], ['borderWidth', 'barBorderWidth']]; |
|||
|
|||
function compatBarItemStyle(option) { |
|||
var itemStyle = option && option.itemStyle; |
|||
|
|||
if (itemStyle) { |
|||
for (var i = 0; i < BAR_ITEM_STYLE_MAP.length; i++) { |
|||
var oldName = BAR_ITEM_STYLE_MAP[i][1]; |
|||
var newName = BAR_ITEM_STYLE_MAP[i][0]; |
|||
|
|||
if (itemStyle[oldName] != null) { |
|||
itemStyle[newName] = itemStyle[oldName]; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog(oldName, newName); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
function compatPieLabel(option) { |
|||
if (!option) { |
|||
return; |
|||
} |
|||
|
|||
if (option.alignTo === 'edge' && option.margin != null && option.edgeDistance == null) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog('label.margin', 'label.edgeDistance', 'pie'); |
|||
} |
|||
|
|||
option.edgeDistance = option.margin; |
|||
} |
|||
} |
|||
|
|||
function compatSunburstState(option) { |
|||
if (!option) { |
|||
return; |
|||
} |
|||
|
|||
if (option.downplay && !option.blur) { |
|||
option.blur = option.downplay; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog('downplay', 'blur', 'sunburst'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
function compatGraphFocus(option) { |
|||
if (!option) { |
|||
return; |
|||
} |
|||
|
|||
if (option.focusNodeAdjacency != null) { |
|||
option.emphasis = option.emphasis || {}; |
|||
|
|||
if (option.emphasis.focus == null) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog('focusNodeAdjacency', 'emphasis: { focus: \'adjacency\'}', 'graph/sankey'); |
|||
} |
|||
|
|||
option.emphasis.focus = 'adjacency'; |
|||
} |
|||
} |
|||
} |
|||
|
|||
function traverseTree(data, cb) { |
|||
if (data) { |
|||
for (var i = 0; i < data.length; i++) { |
|||
cb(data[i]); |
|||
data[i] && traverseTree(data[i].children, cb); |
|||
} |
|||
} |
|||
} |
|||
|
|||
export default function globalBackwardCompat(option, isTheme) { |
|||
compatStyle(option, isTheme); // Make sure series array for model initialization.
|
|||
|
|||
option.series = normalizeToArray(option.series); |
|||
each(option.series, function (seriesOpt) { |
|||
if (!isObject(seriesOpt)) { |
|||
return; |
|||
} |
|||
|
|||
var seriesType = seriesOpt.type; |
|||
|
|||
if (seriesType === 'line') { |
|||
if (seriesOpt.clipOverflow != null) { |
|||
seriesOpt.clip = seriesOpt.clipOverflow; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog('clipOverflow', 'clip', 'line'); |
|||
} |
|||
} |
|||
} else if (seriesType === 'pie' || seriesType === 'gauge') { |
|||
if (seriesOpt.clockWise != null) { |
|||
seriesOpt.clockwise = seriesOpt.clockWise; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog('clockWise', 'clockwise'); |
|||
} |
|||
} |
|||
|
|||
compatPieLabel(seriesOpt.label); |
|||
var data = seriesOpt.data; |
|||
|
|||
if (data && !isTypedArray(data)) { |
|||
for (var i = 0; i < data.length; i++) { |
|||
compatPieLabel(data[i]); |
|||
} |
|||
} |
|||
|
|||
if (seriesOpt.hoverOffset != null) { |
|||
seriesOpt.emphasis = seriesOpt.emphasis || {}; |
|||
|
|||
if (seriesOpt.emphasis.scaleSize = null) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog('hoverOffset', 'emphasis.scaleSize'); |
|||
} |
|||
|
|||
seriesOpt.emphasis.scaleSize = seriesOpt.hoverOffset; |
|||
} |
|||
} |
|||
} else if (seriesType === 'gauge') { |
|||
var pointerColor = get(seriesOpt, 'pointer.color'); |
|||
pointerColor != null && set(seriesOpt, 'itemStyle.color', pointerColor); |
|||
} else if (seriesType === 'bar') { |
|||
compatBarItemStyle(seriesOpt); |
|||
compatBarItemStyle(seriesOpt.backgroundStyle); |
|||
compatBarItemStyle(seriesOpt.emphasis); |
|||
var data = seriesOpt.data; |
|||
|
|||
if (data && !isTypedArray(data)) { |
|||
for (var i = 0; i < data.length; i++) { |
|||
if (typeof data[i] === 'object') { |
|||
compatBarItemStyle(data[i]); |
|||
compatBarItemStyle(data[i] && data[i].emphasis); |
|||
} |
|||
} |
|||
} |
|||
} else if (seriesType === 'sunburst') { |
|||
var highlightPolicy = seriesOpt.highlightPolicy; |
|||
|
|||
if (highlightPolicy) { |
|||
seriesOpt.emphasis = seriesOpt.emphasis || {}; |
|||
|
|||
if (!seriesOpt.emphasis.focus) { |
|||
seriesOpt.emphasis.focus = highlightPolicy; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog('highlightPolicy', 'emphasis.focus', 'sunburst'); |
|||
} |
|||
} |
|||
} |
|||
|
|||
compatSunburstState(seriesOpt); |
|||
traverseTree(seriesOpt.data, compatSunburstState); |
|||
} else if (seriesType === 'graph' || seriesType === 'sankey') { |
|||
compatGraphFocus(seriesOpt); // TODO nodes, edges?
|
|||
} else if (seriesType === 'map') { |
|||
if (seriesOpt.mapType && !seriesOpt.map) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog('mapType', 'map', 'map'); |
|||
} |
|||
|
|||
seriesOpt.map = seriesOpt.mapType; |
|||
} |
|||
|
|||
if (seriesOpt.mapLocation) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateLog('`mapLocation` is not used anymore.'); |
|||
} |
|||
|
|||
defaults(seriesOpt, seriesOpt.mapLocation); |
|||
} |
|||
} |
|||
|
|||
if (seriesOpt.hoverAnimation != null) { |
|||
seriesOpt.emphasis = seriesOpt.emphasis || {}; |
|||
|
|||
if (seriesOpt.emphasis && seriesOpt.emphasis.scale == null) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog('hoverAnimation', 'emphasis.scale'); |
|||
} |
|||
|
|||
seriesOpt.emphasis.scale = seriesOpt.hoverAnimation; |
|||
} |
|||
} |
|||
|
|||
compatLayoutProperties(seriesOpt); |
|||
}); // dataRange has changed to visualMap
|
|||
|
|||
if (option.dataRange) { |
|||
option.visualMap = option.dataRange; |
|||
} |
|||
|
|||
each(COMPATITABLE_COMPONENTS, function (componentName) { |
|||
var options = option[componentName]; |
|||
|
|||
if (options) { |
|||
if (!isArray(options)) { |
|||
options = [options]; |
|||
} |
|||
|
|||
each(options, function (option) { |
|||
compatLayoutProperties(option); |
|||
}); |
|||
} |
|||
}); |
|||
} |
|||
@ -0,0 +1,379 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 * as zrUtil from 'zrender/lib/core/util.js'; |
|||
import * as modelUtil from '../../util/model.js'; |
|||
import { deprecateLog, deprecateReplaceLog } from '../../util/log.js'; |
|||
var each = zrUtil.each; |
|||
var isObject = zrUtil.isObject; |
|||
var POSSIBLE_STYLES = ['areaStyle', 'lineStyle', 'nodeStyle', 'linkStyle', 'chordStyle', 'label', 'labelLine']; |
|||
|
|||
function compatEC2ItemStyle(opt) { |
|||
var itemStyleOpt = opt && opt.itemStyle; |
|||
|
|||
if (!itemStyleOpt) { |
|||
return; |
|||
} |
|||
|
|||
for (var i = 0, len = POSSIBLE_STYLES.length; i < len; i++) { |
|||
var styleName = POSSIBLE_STYLES[i]; |
|||
var normalItemStyleOpt = itemStyleOpt.normal; |
|||
var emphasisItemStyleOpt = itemStyleOpt.emphasis; |
|||
|
|||
if (normalItemStyleOpt && normalItemStyleOpt[styleName]) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog("itemStyle.normal." + styleName, styleName); |
|||
} |
|||
|
|||
opt[styleName] = opt[styleName] || {}; |
|||
|
|||
if (!opt[styleName].normal) { |
|||
opt[styleName].normal = normalItemStyleOpt[styleName]; |
|||
} else { |
|||
zrUtil.merge(opt[styleName].normal, normalItemStyleOpt[styleName]); |
|||
} |
|||
|
|||
normalItemStyleOpt[styleName] = null; |
|||
} |
|||
|
|||
if (emphasisItemStyleOpt && emphasisItemStyleOpt[styleName]) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateReplaceLog("itemStyle.emphasis." + styleName, "emphasis." + styleName); |
|||
} |
|||
|
|||
opt[styleName] = opt[styleName] || {}; |
|||
|
|||
if (!opt[styleName].emphasis) { |
|||
opt[styleName].emphasis = emphasisItemStyleOpt[styleName]; |
|||
} else { |
|||
zrUtil.merge(opt[styleName].emphasis, emphasisItemStyleOpt[styleName]); |
|||
} |
|||
|
|||
emphasisItemStyleOpt[styleName] = null; |
|||
} |
|||
} |
|||
} |
|||
|
|||
function convertNormalEmphasis(opt, optType, useExtend) { |
|||
if (opt && opt[optType] && (opt[optType].normal || opt[optType].emphasis)) { |
|||
var normalOpt = opt[optType].normal; |
|||
var emphasisOpt = opt[optType].emphasis; |
|||
|
|||
if (normalOpt) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
// eslint-disable-next-line max-len
|
|||
deprecateLog("'normal' hierarchy in " + optType + " has been removed since 4.0. All style properties are configured in " + optType + " directly now."); |
|||
} // Timeline controlStyle has other properties besides normal and emphasis
|
|||
|
|||
|
|||
if (useExtend) { |
|||
opt[optType].normal = opt[optType].emphasis = null; |
|||
zrUtil.defaults(opt[optType], normalOpt); |
|||
} else { |
|||
opt[optType] = normalOpt; |
|||
} |
|||
} |
|||
|
|||
if (emphasisOpt) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateLog(optType + ".emphasis has been changed to emphasis." + optType + " since 4.0"); |
|||
} |
|||
|
|||
opt.emphasis = opt.emphasis || {}; |
|||
opt.emphasis[optType] = emphasisOpt; // Also compat the case user mix the style and focus together in ec3 style
|
|||
// for example: { itemStyle: { normal: {}, emphasis: {focus, shadowBlur} } }
|
|||
|
|||
if (emphasisOpt.focus) { |
|||
opt.emphasis.focus = emphasisOpt.focus; |
|||
} |
|||
|
|||
if (emphasisOpt.blurScope) { |
|||
opt.emphasis.blurScope = emphasisOpt.blurScope; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
function removeEC3NormalStatus(opt) { |
|||
convertNormalEmphasis(opt, 'itemStyle'); |
|||
convertNormalEmphasis(opt, 'lineStyle'); |
|||
convertNormalEmphasis(opt, 'areaStyle'); |
|||
convertNormalEmphasis(opt, 'label'); |
|||
convertNormalEmphasis(opt, 'labelLine'); // treemap
|
|||
|
|||
convertNormalEmphasis(opt, 'upperLabel'); // graph
|
|||
|
|||
convertNormalEmphasis(opt, 'edgeLabel'); |
|||
} |
|||
|
|||
function compatTextStyle(opt, propName) { |
|||
// Check whether is not object (string\null\undefined ...)
|
|||
var labelOptSingle = isObject(opt) && opt[propName]; |
|||
var textStyle = isObject(labelOptSingle) && labelOptSingle.textStyle; |
|||
|
|||
if (textStyle) { |
|||
if (process.env.NODE_ENV !== 'production') { |
|||
// eslint-disable-next-line max-len
|
|||
deprecateLog("textStyle hierarchy in " + propName + " has been removed since 4.0. All textStyle properties are configured in " + propName + " directly now."); |
|||
} |
|||
|
|||
for (var i = 0, len = modelUtil.TEXT_STYLE_OPTIONS.length; i < len; i++) { |
|||
var textPropName = modelUtil.TEXT_STYLE_OPTIONS[i]; |
|||
|
|||
if (textStyle.hasOwnProperty(textPropName)) { |
|||
labelOptSingle[textPropName] = textStyle[textPropName]; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
function compatEC3CommonStyles(opt) { |
|||
if (opt) { |
|||
removeEC3NormalStatus(opt); |
|||
compatTextStyle(opt, 'label'); |
|||
opt.emphasis && compatTextStyle(opt.emphasis, 'label'); |
|||
} |
|||
} |
|||
|
|||
function processSeries(seriesOpt) { |
|||
if (!isObject(seriesOpt)) { |
|||
return; |
|||
} |
|||
|
|||
compatEC2ItemStyle(seriesOpt); |
|||
removeEC3NormalStatus(seriesOpt); |
|||
compatTextStyle(seriesOpt, 'label'); // treemap
|
|||
|
|||
compatTextStyle(seriesOpt, 'upperLabel'); // graph
|
|||
|
|||
compatTextStyle(seriesOpt, 'edgeLabel'); |
|||
|
|||
if (seriesOpt.emphasis) { |
|||
compatTextStyle(seriesOpt.emphasis, 'label'); // treemap
|
|||
|
|||
compatTextStyle(seriesOpt.emphasis, 'upperLabel'); // graph
|
|||
|
|||
compatTextStyle(seriesOpt.emphasis, 'edgeLabel'); |
|||
} |
|||
|
|||
var markPoint = seriesOpt.markPoint; |
|||
|
|||
if (markPoint) { |
|||
compatEC2ItemStyle(markPoint); |
|||
compatEC3CommonStyles(markPoint); |
|||
} |
|||
|
|||
var markLine = seriesOpt.markLine; |
|||
|
|||
if (markLine) { |
|||
compatEC2ItemStyle(markLine); |
|||
compatEC3CommonStyles(markLine); |
|||
} |
|||
|
|||
var markArea = seriesOpt.markArea; |
|||
|
|||
if (markArea) { |
|||
compatEC3CommonStyles(markArea); |
|||
} |
|||
|
|||
var data = seriesOpt.data; // Break with ec3: if `setOption` again, there may be no `type` in option,
|
|||
// then the backward compat based on option type will not be performed.
|
|||
|
|||
if (seriesOpt.type === 'graph') { |
|||
data = data || seriesOpt.nodes; |
|||
var edgeData = seriesOpt.links || seriesOpt.edges; |
|||
|
|||
if (edgeData && !zrUtil.isTypedArray(edgeData)) { |
|||
for (var i = 0; i < edgeData.length; i++) { |
|||
compatEC3CommonStyles(edgeData[i]); |
|||
} |
|||
} |
|||
|
|||
zrUtil.each(seriesOpt.categories, function (opt) { |
|||
removeEC3NormalStatus(opt); |
|||
}); |
|||
} |
|||
|
|||
if (data && !zrUtil.isTypedArray(data)) { |
|||
for (var i = 0; i < data.length; i++) { |
|||
compatEC3CommonStyles(data[i]); |
|||
} |
|||
} // mark point data
|
|||
|
|||
|
|||
markPoint = seriesOpt.markPoint; |
|||
|
|||
if (markPoint && markPoint.data) { |
|||
var mpData = markPoint.data; |
|||
|
|||
for (var i = 0; i < mpData.length; i++) { |
|||
compatEC3CommonStyles(mpData[i]); |
|||
} |
|||
} // mark line data
|
|||
|
|||
|
|||
markLine = seriesOpt.markLine; |
|||
|
|||
if (markLine && markLine.data) { |
|||
var mlData = markLine.data; |
|||
|
|||
for (var i = 0; i < mlData.length; i++) { |
|||
if (zrUtil.isArray(mlData[i])) { |
|||
compatEC3CommonStyles(mlData[i][0]); |
|||
compatEC3CommonStyles(mlData[i][1]); |
|||
} else { |
|||
compatEC3CommonStyles(mlData[i]); |
|||
} |
|||
} |
|||
} // Series
|
|||
|
|||
|
|||
if (seriesOpt.type === 'gauge') { |
|||
compatTextStyle(seriesOpt, 'axisLabel'); |
|||
compatTextStyle(seriesOpt, 'title'); |
|||
compatTextStyle(seriesOpt, 'detail'); |
|||
} else if (seriesOpt.type === 'treemap') { |
|||
convertNormalEmphasis(seriesOpt.breadcrumb, 'itemStyle'); |
|||
zrUtil.each(seriesOpt.levels, function (opt) { |
|||
removeEC3NormalStatus(opt); |
|||
}); |
|||
} else if (seriesOpt.type === 'tree') { |
|||
removeEC3NormalStatus(seriesOpt.leaves); |
|||
} // sunburst starts from ec4, so it does not need to compat levels.
|
|||
|
|||
} |
|||
|
|||
function toArr(o) { |
|||
return zrUtil.isArray(o) ? o : o ? [o] : []; |
|||
} |
|||
|
|||
function toObj(o) { |
|||
return (zrUtil.isArray(o) ? o[0] : o) || {}; |
|||
} |
|||
|
|||
export default function globalCompatStyle(option, isTheme) { |
|||
each(toArr(option.series), function (seriesOpt) { |
|||
isObject(seriesOpt) && processSeries(seriesOpt); |
|||
}); |
|||
var axes = ['xAxis', 'yAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'parallelAxis', 'radar']; |
|||
isTheme && axes.push('valueAxis', 'categoryAxis', 'logAxis', 'timeAxis'); |
|||
each(axes, function (axisName) { |
|||
each(toArr(option[axisName]), function (axisOpt) { |
|||
if (axisOpt) { |
|||
compatTextStyle(axisOpt, 'axisLabel'); |
|||
compatTextStyle(axisOpt.axisPointer, 'label'); |
|||
} |
|||
}); |
|||
}); |
|||
each(toArr(option.parallel), function (parallelOpt) { |
|||
var parallelAxisDefault = parallelOpt && parallelOpt.parallelAxisDefault; |
|||
compatTextStyle(parallelAxisDefault, 'axisLabel'); |
|||
compatTextStyle(parallelAxisDefault && parallelAxisDefault.axisPointer, 'label'); |
|||
}); |
|||
each(toArr(option.calendar), function (calendarOpt) { |
|||
convertNormalEmphasis(calendarOpt, 'itemStyle'); |
|||
compatTextStyle(calendarOpt, 'dayLabel'); |
|||
compatTextStyle(calendarOpt, 'monthLabel'); |
|||
compatTextStyle(calendarOpt, 'yearLabel'); |
|||
}); // radar.name.textStyle
|
|||
|
|||
each(toArr(option.radar), function (radarOpt) { |
|||
compatTextStyle(radarOpt, 'name'); // Use axisName instead of name because component has name property
|
|||
|
|||
if (radarOpt.name && radarOpt.axisName == null) { |
|||
radarOpt.axisName = radarOpt.name; |
|||
delete radarOpt.name; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateLog('name property in radar component has been changed to axisName'); |
|||
} |
|||
} |
|||
|
|||
if (radarOpt.nameGap != null && radarOpt.axisNameGap == null) { |
|||
radarOpt.axisNameGap = radarOpt.nameGap; |
|||
delete radarOpt.nameGap; |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
deprecateLog('nameGap property in radar component has been changed to axisNameGap'); |
|||
} |
|||
} |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
each(radarOpt.indicator, function (indicatorOpt) { |
|||
if (indicatorOpt.text) { |
|||
deprecateReplaceLog('text', 'name', 'radar.indicator'); |
|||
} |
|||
}); |
|||
} |
|||
}); |
|||
each(toArr(option.geo), function (geoOpt) { |
|||
if (isObject(geoOpt)) { |
|||
compatEC3CommonStyles(geoOpt); |
|||
each(toArr(geoOpt.regions), function (regionObj) { |
|||
compatEC3CommonStyles(regionObj); |
|||
}); |
|||
} |
|||
}); |
|||
each(toArr(option.timeline), function (timelineOpt) { |
|||
compatEC3CommonStyles(timelineOpt); |
|||
convertNormalEmphasis(timelineOpt, 'label'); |
|||
convertNormalEmphasis(timelineOpt, 'itemStyle'); |
|||
convertNormalEmphasis(timelineOpt, 'controlStyle', true); |
|||
var data = timelineOpt.data; |
|||
zrUtil.isArray(data) && zrUtil.each(data, function (item) { |
|||
if (zrUtil.isObject(item)) { |
|||
convertNormalEmphasis(item, 'label'); |
|||
convertNormalEmphasis(item, 'itemStyle'); |
|||
} |
|||
}); |
|||
}); |
|||
each(toArr(option.toolbox), function (toolboxOpt) { |
|||
convertNormalEmphasis(toolboxOpt, 'iconStyle'); |
|||
each(toolboxOpt.feature, function (featureOpt) { |
|||
convertNormalEmphasis(featureOpt, 'iconStyle'); |
|||
}); |
|||
}); |
|||
compatTextStyle(toObj(option.axisPointer), 'label'); |
|||
compatTextStyle(toObj(option.tooltip).axisPointer, 'label'); // Clean logs
|
|||
// storedLogs = {};
|
|||
} |
|||
@ -0,0 +1,71 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
export default function dataFilter(seriesType) { |
|||
return { |
|||
seriesType: seriesType, |
|||
reset: function (seriesModel, ecModel) { |
|||
var legendModels = ecModel.findComponents({ |
|||
mainType: 'legend' |
|||
}); |
|||
|
|||
if (!legendModels || !legendModels.length) { |
|||
return; |
|||
} |
|||
|
|||
var data = seriesModel.getData(); |
|||
data.filterSelf(function (idx) { |
|||
var name = data.getName(idx); // If in any legend component the status is not selected.
|
|||
|
|||
for (var i = 0; i < legendModels.length; i++) { |
|||
// @ts-ignore FIXME: LegendModel
|
|||
if (!legendModels[i].isSelected(name)) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
}); |
|||
} |
|||
}; |
|||
} |
|||
@ -0,0 +1,142 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { isFunction, isString } from 'zrender/lib/core/util.js'; |
|||
var samplers = { |
|||
average: function (frame) { |
|||
var sum = 0; |
|||
var count = 0; |
|||
|
|||
for (var i = 0; i < frame.length; i++) { |
|||
if (!isNaN(frame[i])) { |
|||
sum += frame[i]; |
|||
count++; |
|||
} |
|||
} // Return NaN if count is 0
|
|||
|
|||
|
|||
return count === 0 ? NaN : sum / count; |
|||
}, |
|||
sum: function (frame) { |
|||
var sum = 0; |
|||
|
|||
for (var i = 0; i < frame.length; i++) { |
|||
// Ignore NaN
|
|||
sum += frame[i] || 0; |
|||
} |
|||
|
|||
return sum; |
|||
}, |
|||
max: function (frame) { |
|||
var max = -Infinity; |
|||
|
|||
for (var i = 0; i < frame.length; i++) { |
|||
frame[i] > max && (max = frame[i]); |
|||
} // NaN will cause illegal axis extent.
|
|||
|
|||
|
|||
return isFinite(max) ? max : NaN; |
|||
}, |
|||
min: function (frame) { |
|||
var min = Infinity; |
|||
|
|||
for (var i = 0; i < frame.length; i++) { |
|||
frame[i] < min && (min = frame[i]); |
|||
} // NaN will cause illegal axis extent.
|
|||
|
|||
|
|||
return isFinite(min) ? min : NaN; |
|||
}, |
|||
// TODO
|
|||
// Median
|
|||
nearest: function (frame) { |
|||
return frame[0]; |
|||
} |
|||
}; |
|||
|
|||
var indexSampler = function (frame) { |
|||
return Math.round(frame.length / 2); |
|||
}; |
|||
|
|||
export default function dataSample(seriesType) { |
|||
return { |
|||
seriesType: seriesType, |
|||
// FIXME:TS never used, so comment it
|
|||
// modifyOutputEnd: true,
|
|||
reset: function (seriesModel, ecModel, api) { |
|||
var data = seriesModel.getData(); |
|||
var sampling = seriesModel.get('sampling'); |
|||
var coordSys = seriesModel.coordinateSystem; |
|||
var count = data.count(); // Only cartesian2d support down sampling. Disable it when there is few data.
|
|||
|
|||
if (count > 10 && coordSys.type === 'cartesian2d' && sampling) { |
|||
var baseAxis = coordSys.getBaseAxis(); |
|||
var valueAxis = coordSys.getOtherAxis(baseAxis); |
|||
var extent = baseAxis.getExtent(); |
|||
var dpr = api.getDevicePixelRatio(); // Coordinste system has been resized
|
|||
|
|||
var size = Math.abs(extent[1] - extent[0]) * (dpr || 1); |
|||
var rate = Math.round(count / size); |
|||
|
|||
if (isFinite(rate) && rate > 1) { |
|||
if (sampling === 'lttb') { |
|||
seriesModel.setData(data.lttbDownSample(data.mapDimension(valueAxis.dim), 1 / rate)); |
|||
} |
|||
|
|||
var sampler = void 0; |
|||
|
|||
if (isString(sampling)) { |
|||
sampler = samplers[sampling]; |
|||
} else if (isFunction(sampling)) { |
|||
sampler = sampling; |
|||
} |
|||
|
|||
if (sampler) { |
|||
// Only support sample the first dim mapped from value axis.
|
|||
seriesModel.setData(data.downSample(data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
@ -0,0 +1,141 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { createHashMap, each } from 'zrender/lib/core/util.js'; |
|||
import { addSafe } from '../util/number.js'; // (1) [Caution]: the logic is correct based on the premises:
|
|||
// data processing stage is blocked in stream.
|
|||
// See <module:echarts/stream/Scheduler#performDataProcessorTasks>
|
|||
// (2) Only register once when import repeatedly.
|
|||
// Should be executed after series is filtered and before stack calculation.
|
|||
|
|||
export default function dataStack(ecModel) { |
|||
var stackInfoMap = createHashMap(); |
|||
ecModel.eachSeries(function (seriesModel) { |
|||
var stack = seriesModel.get('stack'); // Compatible: when `stack` is set as '', do not stack.
|
|||
|
|||
if (stack) { |
|||
var stackInfoList = stackInfoMap.get(stack) || stackInfoMap.set(stack, []); |
|||
var data = seriesModel.getData(); |
|||
var stackInfo = { |
|||
// Used for calculate axis extent automatically.
|
|||
// TODO: Type getCalculationInfo return more specific type?
|
|||
stackResultDimension: data.getCalculationInfo('stackResultDimension'), |
|||
stackedOverDimension: data.getCalculationInfo('stackedOverDimension'), |
|||
stackedDimension: data.getCalculationInfo('stackedDimension'), |
|||
stackedByDimension: data.getCalculationInfo('stackedByDimension'), |
|||
isStackedByIndex: data.getCalculationInfo('isStackedByIndex'), |
|||
data: data, |
|||
seriesModel: seriesModel |
|||
}; // If stacked on axis that do not support data stack.
|
|||
|
|||
if (!stackInfo.stackedDimension || !(stackInfo.isStackedByIndex || stackInfo.stackedByDimension)) { |
|||
return; |
|||
} |
|||
|
|||
stackInfoList.length && data.setCalculationInfo('stackedOnSeries', stackInfoList[stackInfoList.length - 1].seriesModel); |
|||
stackInfoList.push(stackInfo); |
|||
} |
|||
}); |
|||
stackInfoMap.each(calculateStack); |
|||
} |
|||
|
|||
function calculateStack(stackInfoList) { |
|||
each(stackInfoList, function (targetStackInfo, idxInStack) { |
|||
var resultVal = []; |
|||
var resultNaN = [NaN, NaN]; |
|||
var dims = [targetStackInfo.stackResultDimension, targetStackInfo.stackedOverDimension]; |
|||
var targetData = targetStackInfo.data; |
|||
var isStackedByIndex = targetStackInfo.isStackedByIndex; |
|||
var stackStrategy = targetStackInfo.seriesModel.get('stackStrategy') || 'samesign'; // Should not write on raw data, because stack series model list changes
|
|||
// depending on legend selection.
|
|||
|
|||
targetData.modify(dims, function (v0, v1, dataIndex) { |
|||
var sum = targetData.get(targetStackInfo.stackedDimension, dataIndex); // Consider `connectNulls` of line area, if value is NaN, stackedOver
|
|||
// should also be NaN, to draw a appropriate belt area.
|
|||
|
|||
if (isNaN(sum)) { |
|||
return resultNaN; |
|||
} |
|||
|
|||
var byValue; |
|||
var stackedDataRawIndex; |
|||
|
|||
if (isStackedByIndex) { |
|||
stackedDataRawIndex = targetData.getRawIndex(dataIndex); |
|||
} else { |
|||
byValue = targetData.get(targetStackInfo.stackedByDimension, dataIndex); |
|||
} // If stackOver is NaN, chart view will render point on value start.
|
|||
|
|||
|
|||
var stackedOver = NaN; |
|||
|
|||
for (var j = idxInStack - 1; j >= 0; j--) { |
|||
var stackInfo = stackInfoList[j]; // Has been optimized by inverted indices on `stackedByDimension`.
|
|||
|
|||
if (!isStackedByIndex) { |
|||
stackedDataRawIndex = stackInfo.data.rawIndexOf(stackInfo.stackedByDimension, byValue); |
|||
} |
|||
|
|||
if (stackedDataRawIndex >= 0) { |
|||
var val = stackInfo.data.getByRawIndex(stackInfo.stackResultDimension, stackedDataRawIndex); // Considering positive stack, negative stack and empty data
|
|||
|
|||
if (stackStrategy === 'all' // single stack group
|
|||
|| stackStrategy === 'positive' && val > 0 || stackStrategy === 'negative' && val < 0 || stackStrategy === 'samesign' && sum >= 0 && val > 0 // All positive stack
|
|||
|| stackStrategy === 'samesign' && sum <= 0 && val < 0 // All negative stack
|
|||
) { |
|||
// The sum has to be very small to be affected by the
|
|||
// floating arithmetic problem. An incorrect result will probably
|
|||
// cause axis min/max to be filtered incorrectly.
|
|||
sum = addSafe(sum, val); |
|||
stackedOver = val; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
resultVal[0] = sum; |
|||
resultVal[1] = stackedOver; |
|||
return resultVal; |
|||
}); |
|||
}); |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { isNumber } from 'zrender/lib/core/util.js'; |
|||
export default function negativeDataFilter(seriesType) { |
|||
return { |
|||
seriesType: seriesType, |
|||
reset: function (seriesModel, ecModel) { |
|||
var data = seriesModel.getData(); |
|||
data.filterSelf(function (idx) { |
|||
// handle negative value condition
|
|||
var valueDim = data.mapDimension('value'); |
|||
var curValue = data.get(valueDim, idx); |
|||
|
|||
if (isNumber(curValue) && !isNaN(curValue) && curValue < 0) { |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
}); |
|||
} |
|||
}; |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 CanvasPainter from 'zrender/lib/canvas/Painter.js'; |
|||
export function install(registers) { |
|||
registers.registerPainter('canvas', CanvasPainter); |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 SVGPainter from 'zrender/lib/svg/Painter.js'; |
|||
export function install(registers) { |
|||
registers.registerPainter('svg', SVGPainter); |
|||
} |
|||
@ -0,0 +1,316 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { __extends } from "tslib"; |
|||
import * as numberUtil from '../util/number.js'; |
|||
import * as formatUtil from '../util/format.js'; |
|||
import Scale from './Scale.js'; |
|||
import * as helper from './helper.js'; |
|||
var roundNumber = numberUtil.round; |
|||
|
|||
var IntervalScale = |
|||
/** @class */ |
|||
function (_super) { |
|||
__extends(IntervalScale, _super); |
|||
|
|||
function IntervalScale() { |
|||
var _this = _super !== null && _super.apply(this, arguments) || this; |
|||
|
|||
_this.type = 'interval'; // Step is calculated in adjustExtent.
|
|||
|
|||
_this._interval = 0; |
|||
_this._intervalPrecision = 2; |
|||
return _this; |
|||
} |
|||
|
|||
IntervalScale.prototype.parse = function (val) { |
|||
return val; |
|||
}; |
|||
|
|||
IntervalScale.prototype.contain = function (val) { |
|||
return helper.contain(val, this._extent); |
|||
}; |
|||
|
|||
IntervalScale.prototype.normalize = function (val) { |
|||
return helper.normalize(val, this._extent); |
|||
}; |
|||
|
|||
IntervalScale.prototype.scale = function (val) { |
|||
return helper.scale(val, this._extent); |
|||
}; |
|||
|
|||
IntervalScale.prototype.setExtent = function (start, end) { |
|||
var thisExtent = this._extent; // start,end may be a Number like '25',so...
|
|||
|
|||
if (!isNaN(start)) { |
|||
thisExtent[0] = parseFloat(start); |
|||
} |
|||
|
|||
if (!isNaN(end)) { |
|||
thisExtent[1] = parseFloat(end); |
|||
} |
|||
}; |
|||
|
|||
IntervalScale.prototype.unionExtent = function (other) { |
|||
var extent = this._extent; |
|||
other[0] < extent[0] && (extent[0] = other[0]); |
|||
other[1] > extent[1] && (extent[1] = other[1]); // unionExtent may called by it's sub classes
|
|||
|
|||
this.setExtent(extent[0], extent[1]); |
|||
}; |
|||
|
|||
IntervalScale.prototype.getInterval = function () { |
|||
return this._interval; |
|||
}; |
|||
|
|||
IntervalScale.prototype.setInterval = function (interval) { |
|||
this._interval = interval; // Dropped auto calculated niceExtent and use user setted extent
|
|||
// We assume user wan't to set both interval, min, max to get a better result
|
|||
|
|||
this._niceExtent = this._extent.slice(); |
|||
this._intervalPrecision = helper.getIntervalPrecision(interval); |
|||
}; |
|||
/** |
|||
* @param expandToNicedExtent Whether expand the ticks to niced extent. |
|||
*/ |
|||
|
|||
|
|||
IntervalScale.prototype.getTicks = function (expandToNicedExtent) { |
|||
var interval = this._interval; |
|||
var extent = this._extent; |
|||
var niceTickExtent = this._niceExtent; |
|||
var intervalPrecision = this._intervalPrecision; |
|||
var ticks = []; // If interval is 0, return [];
|
|||
|
|||
if (!interval) { |
|||
return ticks; |
|||
} // Consider this case: using dataZoom toolbox, zoom and zoom.
|
|||
|
|||
|
|||
var safeLimit = 10000; |
|||
|
|||
if (extent[0] < niceTickExtent[0]) { |
|||
if (expandToNicedExtent) { |
|||
ticks.push({ |
|||
value: roundNumber(niceTickExtent[0] - interval, intervalPrecision) |
|||
}); |
|||
} else { |
|||
ticks.push({ |
|||
value: extent[0] |
|||
}); |
|||
} |
|||
} |
|||
|
|||
var tick = niceTickExtent[0]; |
|||
|
|||
while (tick <= niceTickExtent[1]) { |
|||
ticks.push({ |
|||
value: tick |
|||
}); // Avoid rounding error
|
|||
|
|||
tick = roundNumber(tick + interval, intervalPrecision); |
|||
|
|||
if (tick === ticks[ticks.length - 1].value) { |
|||
// Consider out of safe float point, e.g.,
|
|||
// -3711126.9907707 + 2e-10 === -3711126.9907707
|
|||
break; |
|||
} |
|||
|
|||
if (ticks.length > safeLimit) { |
|||
return []; |
|||
} |
|||
} // Consider this case: the last item of ticks is smaller
|
|||
// than niceTickExtent[1] and niceTickExtent[1] === extent[1].
|
|||
|
|||
|
|||
var lastNiceTick = ticks.length ? ticks[ticks.length - 1].value : niceTickExtent[1]; |
|||
|
|||
if (extent[1] > lastNiceTick) { |
|||
if (expandToNicedExtent) { |
|||
ticks.push({ |
|||
value: roundNumber(lastNiceTick + interval, intervalPrecision) |
|||
}); |
|||
} else { |
|||
ticks.push({ |
|||
value: extent[1] |
|||
}); |
|||
} |
|||
} |
|||
|
|||
return ticks; |
|||
}; |
|||
|
|||
IntervalScale.prototype.getMinorTicks = function (splitNumber) { |
|||
var ticks = this.getTicks(true); |
|||
var minorTicks = []; |
|||
var extent = this.getExtent(); |
|||
|
|||
for (var i = 1; i < ticks.length; i++) { |
|||
var nextTick = ticks[i]; |
|||
var prevTick = ticks[i - 1]; |
|||
var count = 0; |
|||
var minorTicksGroup = []; |
|||
var interval = nextTick.value - prevTick.value; |
|||
var minorInterval = interval / splitNumber; |
|||
|
|||
while (count < splitNumber - 1) { |
|||
var minorTick = roundNumber(prevTick.value + (count + 1) * minorInterval); // For the first and last interval. The count may be less than splitNumber.
|
|||
|
|||
if (minorTick > extent[0] && minorTick < extent[1]) { |
|||
minorTicksGroup.push(minorTick); |
|||
} |
|||
|
|||
count++; |
|||
} |
|||
|
|||
minorTicks.push(minorTicksGroup); |
|||
} |
|||
|
|||
return minorTicks; |
|||
}; |
|||
/** |
|||
* @param opt.precision If 'auto', use nice presision. |
|||
* @param opt.pad returns 1.50 but not 1.5 if precision is 2. |
|||
*/ |
|||
|
|||
|
|||
IntervalScale.prototype.getLabel = function (data, opt) { |
|||
if (data == null) { |
|||
return ''; |
|||
} |
|||
|
|||
var precision = opt && opt.precision; |
|||
|
|||
if (precision == null) { |
|||
precision = numberUtil.getPrecision(data.value) || 0; |
|||
} else if (precision === 'auto') { |
|||
// Should be more precise then tick.
|
|||
precision = this._intervalPrecision; |
|||
} // (1) If `precision` is set, 12.005 should be display as '12.00500'.
|
|||
// (2) Use roundNumber (toFixed) to avoid scientific notation like '3.5e-7'.
|
|||
|
|||
|
|||
var dataNum = roundNumber(data.value, precision, true); |
|||
return formatUtil.addCommas(dataNum); |
|||
}; |
|||
/** |
|||
* @param splitNumber By default `5`. |
|||
*/ |
|||
|
|||
|
|||
IntervalScale.prototype.calcNiceTicks = function (splitNumber, minInterval, maxInterval) { |
|||
splitNumber = splitNumber || 5; |
|||
var extent = this._extent; |
|||
var span = extent[1] - extent[0]; |
|||
|
|||
if (!isFinite(span)) { |
|||
return; |
|||
} // User may set axis min 0 and data are all negative
|
|||
// FIXME If it needs to reverse ?
|
|||
|
|||
|
|||
if (span < 0) { |
|||
span = -span; |
|||
extent.reverse(); |
|||
} |
|||
|
|||
var result = helper.intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval); |
|||
this._intervalPrecision = result.intervalPrecision; |
|||
this._interval = result.interval; |
|||
this._niceExtent = result.niceTickExtent; |
|||
}; |
|||
|
|||
IntervalScale.prototype.calcNiceExtent = function (opt) { |
|||
var extent = this._extent; // If extent start and end are same, expand them
|
|||
|
|||
if (extent[0] === extent[1]) { |
|||
if (extent[0] !== 0) { |
|||
// Expand extent
|
|||
// Note that extents can be both negative. See #13154
|
|||
var expandSize = Math.abs(extent[0]); // In the fowllowing case
|
|||
// Axis has been fixed max 100
|
|||
// Plus data are all 100 and axis extent are [100, 100].
|
|||
// Extend to the both side will cause expanded max is larger than fixed max.
|
|||
// So only expand to the smaller side.
|
|||
|
|||
if (!opt.fixMax) { |
|||
extent[1] += expandSize / 2; |
|||
extent[0] -= expandSize / 2; |
|||
} else { |
|||
extent[0] -= expandSize / 2; |
|||
} |
|||
} else { |
|||
extent[1] = 1; |
|||
} |
|||
} |
|||
|
|||
var span = extent[1] - extent[0]; // If there are no data and extent are [Infinity, -Infinity]
|
|||
|
|||
if (!isFinite(span)) { |
|||
extent[0] = 0; |
|||
extent[1] = 1; |
|||
} |
|||
|
|||
this.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval); // let extent = this._extent;
|
|||
|
|||
var interval = this._interval; |
|||
|
|||
if (!opt.fixMin) { |
|||
extent[0] = roundNumber(Math.floor(extent[0] / interval) * interval); |
|||
} |
|||
|
|||
if (!opt.fixMax) { |
|||
extent[1] = roundNumber(Math.ceil(extent[1] / interval) * interval); |
|||
} |
|||
}; |
|||
|
|||
IntervalScale.prototype.setNiceExtent = function (min, max) { |
|||
this._niceExtent = [min, max]; |
|||
}; |
|||
|
|||
IntervalScale.type = 'interval'; |
|||
return IntervalScale; |
|||
}(Scale); |
|||
|
|||
Scale.registerClass(IntervalScale); |
|||
export default IntervalScale; |
|||
@ -0,0 +1,206 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { __extends } from "tslib"; |
|||
import * as zrUtil from 'zrender/lib/core/util.js'; |
|||
import Scale from './Scale.js'; |
|||
import * as numberUtil from '../util/number.js'; |
|||
import * as scaleHelper from './helper.js'; // Use some method of IntervalScale
|
|||
|
|||
import IntervalScale from './Interval.js'; |
|||
var scaleProto = Scale.prototype; // FIXME:TS refactor: not good to call it directly with `this`?
|
|||
|
|||
var intervalScaleProto = IntervalScale.prototype; |
|||
var roundingErrorFix = numberUtil.round; |
|||
var mathFloor = Math.floor; |
|||
var mathCeil = Math.ceil; |
|||
var mathPow = Math.pow; |
|||
var mathLog = Math.log; |
|||
|
|||
var LogScale = |
|||
/** @class */ |
|||
function (_super) { |
|||
__extends(LogScale, _super); |
|||
|
|||
function LogScale() { |
|||
var _this = _super !== null && _super.apply(this, arguments) || this; |
|||
|
|||
_this.type = 'log'; |
|||
_this.base = 10; |
|||
_this._originalScale = new IntervalScale(); // FIXME:TS actually used by `IntervalScale`
|
|||
|
|||
_this._interval = 0; |
|||
return _this; |
|||
} |
|||
/** |
|||
* @param Whether expand the ticks to niced extent. |
|||
*/ |
|||
|
|||
|
|||
LogScale.prototype.getTicks = function (expandToNicedExtent) { |
|||
var originalScale = this._originalScale; |
|||
var extent = this._extent; |
|||
var originalExtent = originalScale.getExtent(); |
|||
var ticks = intervalScaleProto.getTicks.call(this, expandToNicedExtent); |
|||
return zrUtil.map(ticks, function (tick) { |
|||
var val = tick.value; |
|||
var powVal = numberUtil.round(mathPow(this.base, val)); // Fix #4158
|
|||
|
|||
powVal = val === extent[0] && this._fixMin ? fixRoundingError(powVal, originalExtent[0]) : powVal; |
|||
powVal = val === extent[1] && this._fixMax ? fixRoundingError(powVal, originalExtent[1]) : powVal; |
|||
return { |
|||
value: powVal |
|||
}; |
|||
}, this); |
|||
}; |
|||
|
|||
LogScale.prototype.setExtent = function (start, end) { |
|||
var base = mathLog(this.base); // log(-Infinity) is NaN, so safe guard here
|
|||
|
|||
start = mathLog(Math.max(0, start)) / base; |
|||
end = mathLog(Math.max(0, end)) / base; |
|||
intervalScaleProto.setExtent.call(this, start, end); |
|||
}; |
|||
/** |
|||
* @return {number} end |
|||
*/ |
|||
|
|||
|
|||
LogScale.prototype.getExtent = function () { |
|||
var base = this.base; |
|||
var extent = scaleProto.getExtent.call(this); |
|||
extent[0] = mathPow(base, extent[0]); |
|||
extent[1] = mathPow(base, extent[1]); // Fix #4158
|
|||
|
|||
var originalScale = this._originalScale; |
|||
var originalExtent = originalScale.getExtent(); |
|||
this._fixMin && (extent[0] = fixRoundingError(extent[0], originalExtent[0])); |
|||
this._fixMax && (extent[1] = fixRoundingError(extent[1], originalExtent[1])); |
|||
return extent; |
|||
}; |
|||
|
|||
LogScale.prototype.unionExtent = function (extent) { |
|||
this._originalScale.unionExtent(extent); |
|||
|
|||
var base = this.base; |
|||
extent[0] = mathLog(extent[0]) / mathLog(base); |
|||
extent[1] = mathLog(extent[1]) / mathLog(base); |
|||
scaleProto.unionExtent.call(this, extent); |
|||
}; |
|||
|
|||
LogScale.prototype.unionExtentFromData = function (data, dim) { |
|||
// TODO
|
|||
// filter value that <= 0
|
|||
this.unionExtent(data.getApproximateExtent(dim)); |
|||
}; |
|||
/** |
|||
* Update interval and extent of intervals for nice ticks |
|||
* @param approxTickNum default 10 Given approx tick number |
|||
*/ |
|||
|
|||
|
|||
LogScale.prototype.calcNiceTicks = function (approxTickNum) { |
|||
approxTickNum = approxTickNum || 10; |
|||
var extent = this._extent; |
|||
var span = extent[1] - extent[0]; |
|||
|
|||
if (span === Infinity || span <= 0) { |
|||
return; |
|||
} |
|||
|
|||
var interval = numberUtil.quantity(span); |
|||
var err = approxTickNum / span * interval; // Filter ticks to get closer to the desired count.
|
|||
|
|||
if (err <= 0.5) { |
|||
interval *= 10; |
|||
} // Interval should be integer
|
|||
|
|||
|
|||
while (!isNaN(interval) && Math.abs(interval) < 1 && Math.abs(interval) > 0) { |
|||
interval *= 10; |
|||
} |
|||
|
|||
var niceExtent = [numberUtil.round(mathCeil(extent[0] / interval) * interval), numberUtil.round(mathFloor(extent[1] / interval) * interval)]; |
|||
this._interval = interval; |
|||
this._niceExtent = niceExtent; |
|||
}; |
|||
|
|||
LogScale.prototype.calcNiceExtent = function (opt) { |
|||
intervalScaleProto.calcNiceExtent.call(this, opt); |
|||
this._fixMin = opt.fixMin; |
|||
this._fixMax = opt.fixMax; |
|||
}; |
|||
|
|||
LogScale.prototype.parse = function (val) { |
|||
return val; |
|||
}; |
|||
|
|||
LogScale.prototype.contain = function (val) { |
|||
val = mathLog(val) / mathLog(this.base); |
|||
return scaleHelper.contain(val, this._extent); |
|||
}; |
|||
|
|||
LogScale.prototype.normalize = function (val) { |
|||
val = mathLog(val) / mathLog(this.base); |
|||
return scaleHelper.normalize(val, this._extent); |
|||
}; |
|||
|
|||
LogScale.prototype.scale = function (val) { |
|||
val = scaleHelper.scale(val, this._extent); |
|||
return mathPow(this.base, val); |
|||
}; |
|||
|
|||
LogScale.type = 'log'; |
|||
return LogScale; |
|||
}(Scale); |
|||
|
|||
var proto = LogScale.prototype; |
|||
proto.getMinorTicks = intervalScaleProto.getMinorTicks; |
|||
proto.getLabel = intervalScaleProto.getLabel; |
|||
|
|||
function fixRoundingError(val, originalVal) { |
|||
return roundingErrorFix(val, numberUtil.getPrecision(originalVal)); |
|||
} |
|||
|
|||
Scale.registerClass(LogScale); |
|||
export default LogScale; |
|||
@ -0,0 +1,255 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { __extends } from "tslib"; |
|||
/** |
|||
* Linear continuous scale |
|||
* http://en.wikipedia.org/wiki/Level_of_measurement
|
|||
*/ |
|||
// FIXME only one data
|
|||
|
|||
import Scale from './Scale.js'; |
|||
import OrdinalMeta from '../data/OrdinalMeta.js'; |
|||
import * as scaleHelper from './helper.js'; |
|||
import { isArray, map, isObject, isString } from 'zrender/lib/core/util.js'; |
|||
|
|||
var OrdinalScale = |
|||
/** @class */ |
|||
function (_super) { |
|||
__extends(OrdinalScale, _super); |
|||
|
|||
function OrdinalScale(setting) { |
|||
var _this = _super.call(this, setting) || this; |
|||
|
|||
_this.type = 'ordinal'; |
|||
|
|||
var ordinalMeta = _this.getSetting('ordinalMeta'); // Caution: Should not use instanceof, consider ec-extensions using
|
|||
// import approach to get OrdinalMeta class.
|
|||
|
|||
|
|||
if (!ordinalMeta) { |
|||
ordinalMeta = new OrdinalMeta({}); |
|||
} |
|||
|
|||
if (isArray(ordinalMeta)) { |
|||
ordinalMeta = new OrdinalMeta({ |
|||
categories: map(ordinalMeta, function (item) { |
|||
return isObject(item) ? item.value : item; |
|||
}) |
|||
}); |
|||
} |
|||
|
|||
_this._ordinalMeta = ordinalMeta; |
|||
_this._extent = _this.getSetting('extent') || [0, ordinalMeta.categories.length - 1]; |
|||
return _this; |
|||
} |
|||
|
|||
OrdinalScale.prototype.parse = function (val) { |
|||
// Caution: Math.round(null) will return `0` rather than `NaN`
|
|||
if (val == null) { |
|||
return NaN; |
|||
} |
|||
|
|||
return isString(val) ? this._ordinalMeta.getOrdinal(val) // val might be float.
|
|||
: Math.round(val); |
|||
}; |
|||
|
|||
OrdinalScale.prototype.contain = function (rank) { |
|||
rank = this.parse(rank); |
|||
return scaleHelper.contain(rank, this._extent) && this._ordinalMeta.categories[rank] != null; |
|||
}; |
|||
/** |
|||
* Normalize given rank or name to linear [0, 1] |
|||
* @param val raw ordinal number. |
|||
* @return normalized value in [0, 1]. |
|||
*/ |
|||
|
|||
|
|||
OrdinalScale.prototype.normalize = function (val) { |
|||
val = this._getTickNumber(this.parse(val)); |
|||
return scaleHelper.normalize(val, this._extent); |
|||
}; |
|||
/** |
|||
* @param val normalized value in [0, 1]. |
|||
* @return raw ordinal number. |
|||
*/ |
|||
|
|||
|
|||
OrdinalScale.prototype.scale = function (val) { |
|||
val = Math.round(scaleHelper.scale(val, this._extent)); |
|||
return this.getRawOrdinalNumber(val); |
|||
}; |
|||
|
|||
OrdinalScale.prototype.getTicks = function () { |
|||
var ticks = []; |
|||
var extent = this._extent; |
|||
var rank = extent[0]; |
|||
|
|||
while (rank <= extent[1]) { |
|||
ticks.push({ |
|||
value: rank |
|||
}); |
|||
rank++; |
|||
} |
|||
|
|||
return ticks; |
|||
}; |
|||
|
|||
OrdinalScale.prototype.getMinorTicks = function (splitNumber) { |
|||
// Not support.
|
|||
return; |
|||
}; |
|||
/** |
|||
* @see `Ordinal['_ordinalNumbersByTick']` |
|||
*/ |
|||
|
|||
|
|||
OrdinalScale.prototype.setSortInfo = function (info) { |
|||
if (info == null) { |
|||
this._ordinalNumbersByTick = this._ticksByOrdinalNumber = null; |
|||
return; |
|||
} |
|||
|
|||
var infoOrdinalNumbers = info.ordinalNumbers; |
|||
var ordinalsByTick = this._ordinalNumbersByTick = []; |
|||
var ticksByOrdinal = this._ticksByOrdinalNumber = []; // Unnecessary support negative tick in `realtimeSort`.
|
|||
|
|||
var tickNum = 0; |
|||
var allCategoryLen = this._ordinalMeta.categories.length; |
|||
|
|||
for (var len = Math.min(allCategoryLen, infoOrdinalNumbers.length); tickNum < len; ++tickNum) { |
|||
var ordinalNumber = infoOrdinalNumbers[tickNum]; |
|||
ordinalsByTick[tickNum] = ordinalNumber; |
|||
ticksByOrdinal[ordinalNumber] = tickNum; |
|||
} // Handle that `series.data` only covers part of the `axis.category.data`.
|
|||
|
|||
|
|||
var unusedOrdinal = 0; |
|||
|
|||
for (; tickNum < allCategoryLen; ++tickNum) { |
|||
while (ticksByOrdinal[unusedOrdinal] != null) { |
|||
unusedOrdinal++; |
|||
} |
|||
|
|||
; |
|||
ordinalsByTick.push(unusedOrdinal); |
|||
ticksByOrdinal[unusedOrdinal] = tickNum; |
|||
} |
|||
}; |
|||
|
|||
OrdinalScale.prototype._getTickNumber = function (ordinal) { |
|||
var ticksByOrdinalNumber = this._ticksByOrdinalNumber; // also support ordinal out of range of `ordinalMeta.categories.length`,
|
|||
// where ordinal numbers are used as tick value directly.
|
|||
|
|||
return ticksByOrdinalNumber && ordinal >= 0 && ordinal < ticksByOrdinalNumber.length ? ticksByOrdinalNumber[ordinal] : ordinal; |
|||
}; |
|||
/** |
|||
* @usage |
|||
* ```js
|
|||
* const ordinalNumber = ordinalScale.getRawOrdinalNumber(tickVal); |
|||
* |
|||
* // case0
|
|||
* const rawOrdinalValue = axisModel.getCategories()[ordinalNumber]; |
|||
* // case1
|
|||
* const rawOrdinalValue = this._ordinalMeta.categories[ordinalNumber]; |
|||
* // case2
|
|||
* const coord = axis.dataToCoord(ordinalNumber); |
|||
* ``` |
|||
* |
|||
* @param {OrdinalNumber} tickNumber index of display |
|||
*/ |
|||
|
|||
|
|||
OrdinalScale.prototype.getRawOrdinalNumber = function (tickNumber) { |
|||
var ordinalNumbersByTick = this._ordinalNumbersByTick; // tickNumber may be out of range, e.g., when axis max is larger than `ordinalMeta.categories.length`.,
|
|||
// where ordinal numbers are used as tick value directly.
|
|||
|
|||
return ordinalNumbersByTick && tickNumber >= 0 && tickNumber < ordinalNumbersByTick.length ? ordinalNumbersByTick[tickNumber] : tickNumber; |
|||
}; |
|||
/** |
|||
* Get item on tick |
|||
*/ |
|||
|
|||
|
|||
OrdinalScale.prototype.getLabel = function (tick) { |
|||
if (!this.isBlank()) { |
|||
var ordinalNumber = this.getRawOrdinalNumber(tick.value); |
|||
var cateogry = this._ordinalMeta.categories[ordinalNumber]; // Note that if no data, ordinalMeta.categories is an empty array.
|
|||
// Return empty if it's not exist.
|
|||
|
|||
return cateogry == null ? '' : cateogry + ''; |
|||
} |
|||
}; |
|||
|
|||
OrdinalScale.prototype.count = function () { |
|||
return this._extent[1] - this._extent[0] + 1; |
|||
}; |
|||
|
|||
OrdinalScale.prototype.unionExtentFromData = function (data, dim) { |
|||
this.unionExtent(data.getApproximateExtent(dim)); |
|||
}; |
|||
/** |
|||
* @override |
|||
* If value is in extent range |
|||
*/ |
|||
|
|||
|
|||
OrdinalScale.prototype.isInExtentRange = function (value) { |
|||
value = this._getTickNumber(value); |
|||
return this._extent[0] <= value && this._extent[1] >= value; |
|||
}; |
|||
|
|||
OrdinalScale.prototype.getOrdinalMeta = function () { |
|||
return this._ordinalMeta; |
|||
}; |
|||
|
|||
OrdinalScale.prototype.calcNiceTicks = function () {}; |
|||
|
|||
OrdinalScale.prototype.calcNiceExtent = function () {}; |
|||
|
|||
OrdinalScale.type = 'ordinal'; |
|||
return OrdinalScale; |
|||
}(Scale); |
|||
|
|||
Scale.registerClass(OrdinalScale); |
|||
export default OrdinalScale; |
|||
@ -0,0 +1,133 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 * as clazzUtil from '../util/clazz.js'; |
|||
|
|||
var Scale = |
|||
/** @class */ |
|||
function () { |
|||
function Scale(setting) { |
|||
this._setting = setting || {}; |
|||
this._extent = [Infinity, -Infinity]; |
|||
} |
|||
|
|||
Scale.prototype.getSetting = function (name) { |
|||
return this._setting[name]; |
|||
}; |
|||
/** |
|||
* Set extent from data |
|||
*/ |
|||
|
|||
|
|||
Scale.prototype.unionExtent = function (other) { |
|||
var extent = this._extent; |
|||
other[0] < extent[0] && (extent[0] = other[0]); |
|||
other[1] > extent[1] && (extent[1] = other[1]); // not setExtent because in log axis it may transformed to power
|
|||
// this.setExtent(extent[0], extent[1]);
|
|||
}; |
|||
/** |
|||
* Set extent from data |
|||
*/ |
|||
|
|||
|
|||
Scale.prototype.unionExtentFromData = function (data, dim) { |
|||
this.unionExtent(data.getApproximateExtent(dim)); |
|||
}; |
|||
/** |
|||
* Get extent |
|||
* |
|||
* Extent is always in increase order. |
|||
*/ |
|||
|
|||
|
|||
Scale.prototype.getExtent = function () { |
|||
return this._extent.slice(); |
|||
}; |
|||
/** |
|||
* Set extent |
|||
*/ |
|||
|
|||
|
|||
Scale.prototype.setExtent = function (start, end) { |
|||
var thisExtent = this._extent; |
|||
|
|||
if (!isNaN(start)) { |
|||
thisExtent[0] = start; |
|||
} |
|||
|
|||
if (!isNaN(end)) { |
|||
thisExtent[1] = end; |
|||
} |
|||
}; |
|||
/** |
|||
* If value is in extent range |
|||
*/ |
|||
|
|||
|
|||
Scale.prototype.isInExtentRange = function (value) { |
|||
return this._extent[0] <= value && this._extent[1] >= value; |
|||
}; |
|||
/** |
|||
* When axis extent depends on data and no data exists, |
|||
* axis ticks should not be drawn, which is named 'blank'. |
|||
*/ |
|||
|
|||
|
|||
Scale.prototype.isBlank = function () { |
|||
return this._isBlank; |
|||
}; |
|||
/** |
|||
* When axis extent depends on data and no data exists, |
|||
* axis ticks should not be drawn, which is named 'blank'. |
|||
*/ |
|||
|
|||
|
|||
Scale.prototype.setBlank = function (isBlank) { |
|||
this._isBlank = isBlank; |
|||
}; |
|||
|
|||
return Scale; |
|||
}(); |
|||
|
|||
clazzUtil.enableClassManagement(Scale); |
|||
export default Scale; |
|||
@ -0,0 +1,605 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { __extends } from "tslib"; |
|||
/* |
|||
* A third-party license is embeded for some of the code in this file: |
|||
* The "scaleLevels" was originally copied from "d3.js" with some |
|||
* modifications made for this project. |
|||
* (See more details in the comment on the definition of "scaleLevels" below.) |
|||
* The use of the source code of this file is also subject to the terms |
|||
* and consitions of the license of "d3.js" (BSD-3Clause, see |
|||
* </licenses/LICENSE-d3>). |
|||
*/ |
|||
// [About UTC and local time zone]:
|
|||
// In most cases, `number.parseDate` will treat input data string as local time
|
|||
// (except time zone is specified in time string). And `format.formateTime` returns
|
|||
// local time by default. option.useUTC is false by default. This design have
|
|||
// concidered these common case:
|
|||
// (1) Time that is persistent in server is in UTC, but it is needed to be diplayed
|
|||
// in local time by default.
|
|||
// (2) By default, the input data string (e.g., '2011-01-02') should be displayed
|
|||
// as its original time, without any time difference.
|
|||
|
|||
import * as numberUtil from '../util/number.js'; |
|||
import { ONE_SECOND, ONE_MINUTE, ONE_HOUR, ONE_DAY, ONE_YEAR, format, leveledFormat, getUnitValue, timeUnits, fullLeveledFormatter, getPrimaryTimeUnit, isPrimaryTimeUnit, getDefaultFormatPrecisionOfInterval, fullYearGetterName, monthSetterName, fullYearSetterName, dateSetterName, hoursGetterName, hoursSetterName, minutesSetterName, secondsSetterName, millisecondsSetterName, monthGetterName, dateGetterName, minutesGetterName, secondsGetterName, millisecondsGetterName } from '../util/time.js'; |
|||
import * as scaleHelper from './helper.js'; |
|||
import IntervalScale from './Interval.js'; |
|||
import Scale from './Scale.js'; |
|||
import { warn } from '../util/log.js'; |
|||
import { filter, isNumber, map } from 'zrender/lib/core/util.js'; // FIXME 公用?
|
|||
|
|||
var bisect = function (a, x, lo, hi) { |
|||
while (lo < hi) { |
|||
var mid = lo + hi >>> 1; |
|||
|
|||
if (a[mid][1] < x) { |
|||
lo = mid + 1; |
|||
} else { |
|||
hi = mid; |
|||
} |
|||
} |
|||
|
|||
return lo; |
|||
}; |
|||
|
|||
var TimeScale = |
|||
/** @class */ |
|||
function (_super) { |
|||
__extends(TimeScale, _super); |
|||
|
|||
function TimeScale(settings) { |
|||
var _this = _super.call(this, settings) || this; |
|||
|
|||
_this.type = 'time'; |
|||
return _this; |
|||
} |
|||
/** |
|||
* Get label is mainly for other components like dataZoom, tooltip. |
|||
*/ |
|||
|
|||
|
|||
TimeScale.prototype.getLabel = function (tick) { |
|||
var useUTC = this.getSetting('useUTC'); |
|||
return format(tick.value, fullLeveledFormatter[getDefaultFormatPrecisionOfInterval(getPrimaryTimeUnit(this._minLevelUnit))] || fullLeveledFormatter.second, useUTC, this.getSetting('locale')); |
|||
}; |
|||
|
|||
TimeScale.prototype.getFormattedLabel = function (tick, idx, labelFormatter) { |
|||
var isUTC = this.getSetting('useUTC'); |
|||
var lang = this.getSetting('locale'); |
|||
return leveledFormat(tick, idx, labelFormatter, lang, isUTC); |
|||
}; |
|||
/** |
|||
* @override |
|||
*/ |
|||
|
|||
|
|||
TimeScale.prototype.getTicks = function () { |
|||
var interval = this._interval; |
|||
var extent = this._extent; |
|||
var ticks = []; // If interval is 0, return [];
|
|||
|
|||
if (!interval) { |
|||
return ticks; |
|||
} |
|||
|
|||
ticks.push({ |
|||
value: extent[0], |
|||
level: 0 |
|||
}); |
|||
var useUTC = this.getSetting('useUTC'); |
|||
var innerTicks = getIntervalTicks(this._minLevelUnit, this._approxInterval, useUTC, extent); |
|||
ticks = ticks.concat(innerTicks); |
|||
ticks.push({ |
|||
value: extent[1], |
|||
level: 0 |
|||
}); |
|||
return ticks; |
|||
}; |
|||
|
|||
TimeScale.prototype.calcNiceExtent = function (opt) { |
|||
var extent = this._extent; // If extent start and end are same, expand them
|
|||
|
|||
if (extent[0] === extent[1]) { |
|||
// Expand extent
|
|||
extent[0] -= ONE_DAY; |
|||
extent[1] += ONE_DAY; |
|||
} // If there are no data and extent are [Infinity, -Infinity]
|
|||
|
|||
|
|||
if (extent[1] === -Infinity && extent[0] === Infinity) { |
|||
var d = new Date(); |
|||
extent[1] = +new Date(d.getFullYear(), d.getMonth(), d.getDate()); |
|||
extent[0] = extent[1] - ONE_DAY; |
|||
} |
|||
|
|||
this.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval); |
|||
}; |
|||
|
|||
TimeScale.prototype.calcNiceTicks = function (approxTickNum, minInterval, maxInterval) { |
|||
approxTickNum = approxTickNum || 10; |
|||
var extent = this._extent; |
|||
var span = extent[1] - extent[0]; |
|||
this._approxInterval = span / approxTickNum; |
|||
|
|||
if (minInterval != null && this._approxInterval < minInterval) { |
|||
this._approxInterval = minInterval; |
|||
} |
|||
|
|||
if (maxInterval != null && this._approxInterval > maxInterval) { |
|||
this._approxInterval = maxInterval; |
|||
} |
|||
|
|||
var scaleIntervalsLen = scaleIntervals.length; |
|||
var idx = Math.min(bisect(scaleIntervals, this._approxInterval, 0, scaleIntervalsLen), scaleIntervalsLen - 1); // Interval that can be used to calculate ticks
|
|||
|
|||
this._interval = scaleIntervals[idx][1]; // Min level used when picking ticks from top down.
|
|||
// We check one more level to avoid the ticks are to sparse in some case.
|
|||
|
|||
this._minLevelUnit = scaleIntervals[Math.max(idx - 1, 0)][0]; |
|||
}; |
|||
|
|||
TimeScale.prototype.parse = function (val) { |
|||
// val might be float.
|
|||
return isNumber(val) ? val : +numberUtil.parseDate(val); |
|||
}; |
|||
|
|||
TimeScale.prototype.contain = function (val) { |
|||
return scaleHelper.contain(this.parse(val), this._extent); |
|||
}; |
|||
|
|||
TimeScale.prototype.normalize = function (val) { |
|||
return scaleHelper.normalize(this.parse(val), this._extent); |
|||
}; |
|||
|
|||
TimeScale.prototype.scale = function (val) { |
|||
return scaleHelper.scale(val, this._extent); |
|||
}; |
|||
|
|||
TimeScale.type = 'time'; |
|||
return TimeScale; |
|||
}(IntervalScale); |
|||
/** |
|||
* This implementation was originally copied from "d3.js" |
|||
* <https://github.com/d3/d3/blob/b516d77fb8566b576088e73410437494717ada26/src/time/scale.js>
|
|||
* with some modifications made for this program. |
|||
* See the license statement at the head of this file. |
|||
*/ |
|||
|
|||
|
|||
var scaleIntervals = [// Format interval
|
|||
['second', ONE_SECOND], ['minute', ONE_MINUTE], ['hour', ONE_HOUR], ['quarter-day', ONE_HOUR * 6], ['half-day', ONE_HOUR * 12], ['day', ONE_DAY * 1.2], ['half-week', ONE_DAY * 3.5], ['week', ONE_DAY * 7], ['month', ONE_DAY * 31], ['quarter', ONE_DAY * 95], ['half-year', ONE_YEAR / 2], ['year', ONE_YEAR] // 1Y
|
|||
]; |
|||
|
|||
function isUnitValueSame(unit, valueA, valueB, isUTC) { |
|||
var dateA = numberUtil.parseDate(valueA); |
|||
var dateB = numberUtil.parseDate(valueB); |
|||
|
|||
var isSame = function (unit) { |
|||
return getUnitValue(dateA, unit, isUTC) === getUnitValue(dateB, unit, isUTC); |
|||
}; |
|||
|
|||
var isSameYear = function () { |
|||
return isSame('year'); |
|||
}; // const isSameHalfYear = () => isSameYear() && isSame('half-year');
|
|||
// const isSameQuater = () => isSameYear() && isSame('quarter');
|
|||
|
|||
|
|||
var isSameMonth = function () { |
|||
return isSameYear() && isSame('month'); |
|||
}; |
|||
|
|||
var isSameDay = function () { |
|||
return isSameMonth() && isSame('day'); |
|||
}; // const isSameHalfDay = () => isSameDay() && isSame('half-day');
|
|||
|
|||
|
|||
var isSameHour = function () { |
|||
return isSameDay() && isSame('hour'); |
|||
}; |
|||
|
|||
var isSameMinute = function () { |
|||
return isSameHour() && isSame('minute'); |
|||
}; |
|||
|
|||
var isSameSecond = function () { |
|||
return isSameMinute() && isSame('second'); |
|||
}; |
|||
|
|||
var isSameMilliSecond = function () { |
|||
return isSameSecond() && isSame('millisecond'); |
|||
}; |
|||
|
|||
switch (unit) { |
|||
case 'year': |
|||
return isSameYear(); |
|||
|
|||
case 'month': |
|||
return isSameMonth(); |
|||
|
|||
case 'day': |
|||
return isSameDay(); |
|||
|
|||
case 'hour': |
|||
return isSameHour(); |
|||
|
|||
case 'minute': |
|||
return isSameMinute(); |
|||
|
|||
case 'second': |
|||
return isSameSecond(); |
|||
|
|||
case 'millisecond': |
|||
return isSameMilliSecond(); |
|||
} |
|||
} // const primaryUnitGetters = {
|
|||
// year: fullYearGetterName(),
|
|||
// month: monthGetterName(),
|
|||
// day: dateGetterName(),
|
|||
// hour: hoursGetterName(),
|
|||
// minute: minutesGetterName(),
|
|||
// second: secondsGetterName(),
|
|||
// millisecond: millisecondsGetterName()
|
|||
// };
|
|||
// const primaryUnitUTCGetters = {
|
|||
// year: fullYearGetterName(true),
|
|||
// month: monthGetterName(true),
|
|||
// day: dateGetterName(true),
|
|||
// hour: hoursGetterName(true),
|
|||
// minute: minutesGetterName(true),
|
|||
// second: secondsGetterName(true),
|
|||
// millisecond: millisecondsGetterName(true)
|
|||
// };
|
|||
// function moveTick(date: Date, unitName: TimeUnit, step: number, isUTC: boolean) {
|
|||
// step = step || 1;
|
|||
// switch (getPrimaryTimeUnit(unitName)) {
|
|||
// case 'year':
|
|||
// date[fullYearSetterName(isUTC)](date[fullYearGetterName(isUTC)]() + step);
|
|||
// break;
|
|||
// case 'month':
|
|||
// date[monthSetterName(isUTC)](date[monthGetterName(isUTC)]() + step);
|
|||
// break;
|
|||
// case 'day':
|
|||
// date[dateSetterName(isUTC)](date[dateGetterName(isUTC)]() + step);
|
|||
// break;
|
|||
// case 'hour':
|
|||
// date[hoursSetterName(isUTC)](date[hoursGetterName(isUTC)]() + step);
|
|||
// break;
|
|||
// case 'minute':
|
|||
// date[minutesSetterName(isUTC)](date[minutesGetterName(isUTC)]() + step);
|
|||
// break;
|
|||
// case 'second':
|
|||
// date[secondsSetterName(isUTC)](date[secondsGetterName(isUTC)]() + step);
|
|||
// break;
|
|||
// case 'millisecond':
|
|||
// date[millisecondsSetterName(isUTC)](date[millisecondsGetterName(isUTC)]() + step);
|
|||
// break;
|
|||
// }
|
|||
// return date.getTime();
|
|||
// }
|
|||
// const DATE_INTERVALS = [[8, 7.5], [4, 3.5], [2, 1.5]];
|
|||
// const MONTH_INTERVALS = [[6, 5.5], [3, 2.5], [2, 1.5]];
|
|||
// const MINUTES_SECONDS_INTERVALS = [[30, 30], [20, 20], [15, 15], [10, 10], [5, 5], [2, 2]];
|
|||
|
|||
|
|||
function getDateInterval(approxInterval, daysInMonth) { |
|||
approxInterval /= ONE_DAY; |
|||
return approxInterval > 16 ? 16 // Math.floor(daysInMonth / 2) + 1 // In this case we only want one tick betwen two month.
|
|||
: approxInterval > 7.5 ? 7 // TODO week 7 or day 8?
|
|||
: approxInterval > 3.5 ? 4 : approxInterval > 1.5 ? 2 : 1; |
|||
} |
|||
|
|||
function getMonthInterval(approxInterval) { |
|||
var APPROX_ONE_MONTH = 30 * ONE_DAY; |
|||
approxInterval /= APPROX_ONE_MONTH; |
|||
return approxInterval > 6 ? 6 : approxInterval > 3 ? 3 : approxInterval > 2 ? 2 : 1; |
|||
} |
|||
|
|||
function getHourInterval(approxInterval) { |
|||
approxInterval /= ONE_HOUR; |
|||
return approxInterval > 12 ? 12 : approxInterval > 6 ? 6 : approxInterval > 3.5 ? 4 : approxInterval > 2 ? 2 : 1; |
|||
} |
|||
|
|||
function getMinutesAndSecondsInterval(approxInterval, isMinutes) { |
|||
approxInterval /= isMinutes ? ONE_MINUTE : ONE_SECOND; |
|||
return approxInterval > 30 ? 30 : approxInterval > 20 ? 20 : approxInterval > 15 ? 15 : approxInterval > 10 ? 10 : approxInterval > 5 ? 5 : approxInterval > 2 ? 2 : 1; |
|||
} |
|||
|
|||
function getMillisecondsInterval(approxInterval) { |
|||
return numberUtil.nice(approxInterval, true); |
|||
} |
|||
|
|||
function getFirstTimestampOfUnit(date, unitName, isUTC) { |
|||
var outDate = new Date(date); |
|||
|
|||
switch (getPrimaryTimeUnit(unitName)) { |
|||
case 'year': |
|||
case 'month': |
|||
outDate[monthSetterName(isUTC)](0); |
|||
|
|||
case 'day': |
|||
outDate[dateSetterName(isUTC)](1); |
|||
|
|||
case 'hour': |
|||
outDate[hoursSetterName(isUTC)](0); |
|||
|
|||
case 'minute': |
|||
outDate[minutesSetterName(isUTC)](0); |
|||
|
|||
case 'second': |
|||
outDate[secondsSetterName(isUTC)](0); |
|||
outDate[millisecondsSetterName(isUTC)](0); |
|||
} |
|||
|
|||
return outDate.getTime(); |
|||
} |
|||
|
|||
function getIntervalTicks(bottomUnitName, approxInterval, isUTC, extent) { |
|||
var safeLimit = 10000; |
|||
var unitNames = timeUnits; |
|||
var iter = 0; |
|||
|
|||
function addTicksInSpan(interval, minTimestamp, maxTimestamp, getMethodName, setMethodName, isDate, out) { |
|||
var date = new Date(minTimestamp); |
|||
var dateTime = minTimestamp; |
|||
var d = date[getMethodName](); // if (isDate) {
|
|||
// d -= 1; // Starts with 0; PENDING
|
|||
// }
|
|||
|
|||
while (dateTime < maxTimestamp && dateTime <= extent[1]) { |
|||
out.push({ |
|||
value: dateTime |
|||
}); |
|||
d += interval; |
|||
date[setMethodName](d); |
|||
dateTime = date.getTime(); |
|||
} // This extra tick is for calcuating ticks of next level. Will not been added to the final result
|
|||
|
|||
|
|||
out.push({ |
|||
value: dateTime, |
|||
notAdd: true |
|||
}); |
|||
} |
|||
|
|||
function addLevelTicks(unitName, lastLevelTicks, levelTicks) { |
|||
var newAddedTicks = []; |
|||
var isFirstLevel = !lastLevelTicks.length; |
|||
|
|||
if (isUnitValueSame(getPrimaryTimeUnit(unitName), extent[0], extent[1], isUTC)) { |
|||
return; |
|||
} |
|||
|
|||
if (isFirstLevel) { |
|||
lastLevelTicks = [{ |
|||
// TODO Optimize. Not include so may ticks.
|
|||
value: getFirstTimestampOfUnit(new Date(extent[0]), unitName, isUTC) |
|||
}, { |
|||
value: extent[1] |
|||
}]; |
|||
} |
|||
|
|||
for (var i = 0; i < lastLevelTicks.length - 1; i++) { |
|||
var startTick = lastLevelTicks[i].value; |
|||
var endTick = lastLevelTicks[i + 1].value; |
|||
|
|||
if (startTick === endTick) { |
|||
continue; |
|||
} |
|||
|
|||
var interval = void 0; |
|||
var getterName = void 0; |
|||
var setterName = void 0; |
|||
var isDate = false; |
|||
|
|||
switch (unitName) { |
|||
case 'year': |
|||
interval = Math.max(1, Math.round(approxInterval / ONE_DAY / 365)); |
|||
getterName = fullYearGetterName(isUTC); |
|||
setterName = fullYearSetterName(isUTC); |
|||
break; |
|||
|
|||
case 'half-year': |
|||
case 'quarter': |
|||
case 'month': |
|||
interval = getMonthInterval(approxInterval); |
|||
getterName = monthGetterName(isUTC); |
|||
setterName = monthSetterName(isUTC); |
|||
break; |
|||
|
|||
case 'week': // PENDING If week is added. Ignore day.
|
|||
|
|||
case 'half-week': |
|||
case 'day': |
|||
interval = getDateInterval(approxInterval, 31); // Use 32 days and let interval been 16
|
|||
|
|||
getterName = dateGetterName(isUTC); |
|||
setterName = dateSetterName(isUTC); |
|||
isDate = true; |
|||
break; |
|||
|
|||
case 'half-day': |
|||
case 'quarter-day': |
|||
case 'hour': |
|||
interval = getHourInterval(approxInterval); |
|||
getterName = hoursGetterName(isUTC); |
|||
setterName = hoursSetterName(isUTC); |
|||
break; |
|||
|
|||
case 'minute': |
|||
interval = getMinutesAndSecondsInterval(approxInterval, true); |
|||
getterName = minutesGetterName(isUTC); |
|||
setterName = minutesSetterName(isUTC); |
|||
break; |
|||
|
|||
case 'second': |
|||
interval = getMinutesAndSecondsInterval(approxInterval, false); |
|||
getterName = secondsGetterName(isUTC); |
|||
setterName = secondsSetterName(isUTC); |
|||
break; |
|||
|
|||
case 'millisecond': |
|||
interval = getMillisecondsInterval(approxInterval); |
|||
getterName = millisecondsGetterName(isUTC); |
|||
setterName = millisecondsSetterName(isUTC); |
|||
break; |
|||
} |
|||
|
|||
addTicksInSpan(interval, startTick, endTick, getterName, setterName, isDate, newAddedTicks); |
|||
|
|||
if (unitName === 'year' && levelTicks.length > 1 && i === 0) { |
|||
// Add nearest years to the left extent.
|
|||
levelTicks.unshift({ |
|||
value: levelTicks[0].value - interval |
|||
}); |
|||
} |
|||
} |
|||
|
|||
for (var i = 0; i < newAddedTicks.length; i++) { |
|||
levelTicks.push(newAddedTicks[i]); |
|||
} // newAddedTicks.length && console.log(unitName, newAddedTicks);
|
|||
|
|||
|
|||
return newAddedTicks; |
|||
} |
|||
|
|||
var levelsTicks = []; |
|||
var currentLevelTicks = []; |
|||
var tickCount = 0; |
|||
var lastLevelTickCount = 0; |
|||
|
|||
for (var i = 0; i < unitNames.length && iter++ < safeLimit; ++i) { |
|||
var primaryTimeUnit = getPrimaryTimeUnit(unitNames[i]); |
|||
|
|||
if (!isPrimaryTimeUnit(unitNames[i])) { |
|||
// TODO
|
|||
continue; |
|||
} |
|||
|
|||
addLevelTicks(unitNames[i], levelsTicks[levelsTicks.length - 1] || [], currentLevelTicks); |
|||
var nextPrimaryTimeUnit = unitNames[i + 1] ? getPrimaryTimeUnit(unitNames[i + 1]) : null; |
|||
|
|||
if (primaryTimeUnit !== nextPrimaryTimeUnit) { |
|||
if (currentLevelTicks.length) { |
|||
lastLevelTickCount = tickCount; // Remove the duplicate so the tick count can be precisely.
|
|||
|
|||
currentLevelTicks.sort(function (a, b) { |
|||
return a.value - b.value; |
|||
}); |
|||
var levelTicksRemoveDuplicated = []; |
|||
|
|||
for (var i_1 = 0; i_1 < currentLevelTicks.length; ++i_1) { |
|||
var tickValue = currentLevelTicks[i_1].value; |
|||
|
|||
if (i_1 === 0 || currentLevelTicks[i_1 - 1].value !== tickValue) { |
|||
levelTicksRemoveDuplicated.push(currentLevelTicks[i_1]); |
|||
|
|||
if (tickValue >= extent[0] && tickValue <= extent[1]) { |
|||
tickCount++; |
|||
} |
|||
} |
|||
} |
|||
|
|||
var targetTickNum = (extent[1] - extent[0]) / approxInterval; // Added too much in this level and not too less in last level
|
|||
|
|||
if (tickCount > targetTickNum * 1.5 && lastLevelTickCount > targetTickNum / 1.5) { |
|||
break; |
|||
} // Only treat primary time unit as one level.
|
|||
|
|||
|
|||
levelsTicks.push(levelTicksRemoveDuplicated); |
|||
|
|||
if (tickCount > targetTickNum || bottomUnitName === unitNames[i]) { |
|||
break; |
|||
} |
|||
} // Reset if next unitName is primary
|
|||
|
|||
|
|||
currentLevelTicks = []; |
|||
} |
|||
} |
|||
|
|||
if (process.env.NODE_ENV !== 'production') { |
|||
if (iter >= safeLimit) { |
|||
warn('Exceed safe limit.'); |
|||
} |
|||
} |
|||
|
|||
var levelsTicksInExtent = filter(map(levelsTicks, function (levelTicks) { |
|||
return filter(levelTicks, function (tick) { |
|||
return tick.value >= extent[0] && tick.value <= extent[1] && !tick.notAdd; |
|||
}); |
|||
}), function (levelTicks) { |
|||
return levelTicks.length > 0; |
|||
}); |
|||
var ticks = []; |
|||
var maxLevel = levelsTicksInExtent.length - 1; |
|||
|
|||
for (var i = 0; i < levelsTicksInExtent.length; ++i) { |
|||
var levelTicks = levelsTicksInExtent[i]; |
|||
|
|||
for (var k = 0; k < levelTicks.length; ++k) { |
|||
ticks.push({ |
|||
value: levelTicks[k].value, |
|||
level: maxLevel - i |
|||
}); |
|||
} |
|||
} |
|||
|
|||
ticks.sort(function (a, b) { |
|||
return a.value - b.value; |
|||
}); // Remove duplicates
|
|||
|
|||
var result = []; |
|||
|
|||
for (var i = 0; i < ticks.length; ++i) { |
|||
if (i === 0 || ticks[i].value !== ticks[i - 1].value) { |
|||
result.push(ticks[i]); |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
Scale.registerClass(TimeScale); |
|||
export default TimeScale; |
|||
@ -0,0 +1,133 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 { getPrecision, round, nice, quantityExponent } from '../util/number.js'; |
|||
export function isValueNice(val) { |
|||
var exp10 = Math.pow(10, quantityExponent(Math.abs(val))); |
|||
var f = Math.abs(val / exp10); |
|||
return f === 0 || f === 1 || f === 2 || f === 3 || f === 5; |
|||
} |
|||
export function isIntervalOrLogScale(scale) { |
|||
return scale.type === 'interval' || scale.type === 'log'; |
|||
} |
|||
/** |
|||
* @param extent Both extent[0] and extent[1] should be valid number. |
|||
* Should be extent[0] < extent[1]. |
|||
* @param splitNumber splitNumber should be >= 1. |
|||
*/ |
|||
|
|||
export function intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval) { |
|||
var result = {}; |
|||
var span = extent[1] - extent[0]; |
|||
var interval = result.interval = nice(span / splitNumber, true); |
|||
|
|||
if (minInterval != null && interval < minInterval) { |
|||
interval = result.interval = minInterval; |
|||
} |
|||
|
|||
if (maxInterval != null && interval > maxInterval) { |
|||
interval = result.interval = maxInterval; |
|||
} // Tow more digital for tick.
|
|||
|
|||
|
|||
var precision = result.intervalPrecision = getIntervalPrecision(interval); // Niced extent inside original extent
|
|||
|
|||
var niceTickExtent = result.niceTickExtent = [round(Math.ceil(extent[0] / interval) * interval, precision), round(Math.floor(extent[1] / interval) * interval, precision)]; |
|||
fixExtent(niceTickExtent, extent); |
|||
return result; |
|||
} |
|||
export function increaseInterval(interval) { |
|||
var exp10 = Math.pow(10, quantityExponent(interval)); // Increase interval
|
|||
|
|||
var f = interval / exp10; |
|||
|
|||
if (!f) { |
|||
f = 1; |
|||
} else if (f === 2) { |
|||
f = 3; |
|||
} else if (f === 3) { |
|||
f = 5; |
|||
} else { |
|||
// f is 1 or 5
|
|||
f *= 2; |
|||
} |
|||
|
|||
return round(f * exp10); |
|||
} |
|||
/** |
|||
* @return interval precision |
|||
*/ |
|||
|
|||
export function getIntervalPrecision(interval) { |
|||
// Tow more digital for tick.
|
|||
return getPrecision(interval) + 2; |
|||
} |
|||
|
|||
function clamp(niceTickExtent, idx, extent) { |
|||
niceTickExtent[idx] = Math.max(Math.min(niceTickExtent[idx], extent[1]), extent[0]); |
|||
} // In some cases (e.g., splitNumber is 1), niceTickExtent may be out of extent.
|
|||
|
|||
|
|||
export function fixExtent(niceTickExtent, extent) { |
|||
!isFinite(niceTickExtent[0]) && (niceTickExtent[0] = extent[0]); |
|||
!isFinite(niceTickExtent[1]) && (niceTickExtent[1] = extent[1]); |
|||
clamp(niceTickExtent, 0, extent); |
|||
clamp(niceTickExtent, 1, extent); |
|||
|
|||
if (niceTickExtent[0] > niceTickExtent[1]) { |
|||
niceTickExtent[0] = niceTickExtent[1]; |
|||
} |
|||
} |
|||
export function contain(val, extent) { |
|||
return val >= extent[0] && val <= extent[1]; |
|||
} |
|||
export function normalize(val, extent) { |
|||
if (extent[1] === extent[0]) { |
|||
return 0.5; |
|||
} |
|||
|
|||
return (val - extent[0]) / (extent[1] - extent[0]); |
|||
} |
|||
export function scale(val, extent) { |
|||
return val * (extent[1] - extent[0]) + extent[0]; |
|||
} |
|||
@ -0,0 +1,224 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
var contrastColor = '#B9B8CE'; |
|||
var backgroundColor = '#100C2A'; |
|||
|
|||
var axisCommon = function () { |
|||
return { |
|||
axisLine: { |
|||
lineStyle: { |
|||
color: contrastColor |
|||
} |
|||
}, |
|||
splitLine: { |
|||
lineStyle: { |
|||
color: '#484753' |
|||
} |
|||
}, |
|||
splitArea: { |
|||
areaStyle: { |
|||
color: ['rgba(255,255,255,0.02)', 'rgba(255,255,255,0.05)'] |
|||
} |
|||
}, |
|||
minorSplitLine: { |
|||
lineStyle: { |
|||
color: '#20203B' |
|||
} |
|||
} |
|||
}; |
|||
}; |
|||
|
|||
var colorPalette = ['#4992ff', '#7cffb2', '#fddd60', '#ff6e76', '#58d9f9', '#05c091', '#ff8a45', '#8d48e3', '#dd79ff']; |
|||
var theme = { |
|||
darkMode: true, |
|||
color: colorPalette, |
|||
backgroundColor: backgroundColor, |
|||
axisPointer: { |
|||
lineStyle: { |
|||
color: '#817f91' |
|||
}, |
|||
crossStyle: { |
|||
color: '#817f91' |
|||
}, |
|||
label: { |
|||
// TODO Contrast of label backgorundColor
|
|||
color: '#fff' |
|||
} |
|||
}, |
|||
legend: { |
|||
textStyle: { |
|||
color: contrastColor |
|||
} |
|||
}, |
|||
textStyle: { |
|||
color: contrastColor |
|||
}, |
|||
title: { |
|||
textStyle: { |
|||
color: '#EEF1FA' |
|||
}, |
|||
subtextStyle: { |
|||
color: '#B9B8CE' |
|||
} |
|||
}, |
|||
toolbox: { |
|||
iconStyle: { |
|||
borderColor: contrastColor |
|||
} |
|||
}, |
|||
dataZoom: { |
|||
borderColor: '#71708A', |
|||
textStyle: { |
|||
color: contrastColor |
|||
}, |
|||
brushStyle: { |
|||
color: 'rgba(135,163,206,0.3)' |
|||
}, |
|||
handleStyle: { |
|||
color: '#353450', |
|||
borderColor: '#C5CBE3' |
|||
}, |
|||
moveHandleStyle: { |
|||
color: '#B0B6C3', |
|||
opacity: 0.3 |
|||
}, |
|||
fillerColor: 'rgba(135,163,206,0.2)', |
|||
emphasis: { |
|||
handleStyle: { |
|||
borderColor: '#91B7F2', |
|||
color: '#4D587D' |
|||
}, |
|||
moveHandleStyle: { |
|||
color: '#636D9A', |
|||
opacity: 0.7 |
|||
} |
|||
}, |
|||
dataBackground: { |
|||
lineStyle: { |
|||
color: '#71708A', |
|||
width: 1 |
|||
}, |
|||
areaStyle: { |
|||
color: '#71708A' |
|||
} |
|||
}, |
|||
selectedDataBackground: { |
|||
lineStyle: { |
|||
color: '#87A3CE' |
|||
}, |
|||
areaStyle: { |
|||
color: '#87A3CE' |
|||
} |
|||
} |
|||
}, |
|||
visualMap: { |
|||
textStyle: { |
|||
color: contrastColor |
|||
} |
|||
}, |
|||
timeline: { |
|||
lineStyle: { |
|||
color: contrastColor |
|||
}, |
|||
label: { |
|||
color: contrastColor |
|||
}, |
|||
controlStyle: { |
|||
color: contrastColor, |
|||
borderColor: contrastColor |
|||
} |
|||
}, |
|||
calendar: { |
|||
itemStyle: { |
|||
color: backgroundColor |
|||
}, |
|||
dayLabel: { |
|||
color: contrastColor |
|||
}, |
|||
monthLabel: { |
|||
color: contrastColor |
|||
}, |
|||
yearLabel: { |
|||
color: contrastColor |
|||
} |
|||
}, |
|||
timeAxis: axisCommon(), |
|||
logAxis: axisCommon(), |
|||
valueAxis: axisCommon(), |
|||
categoryAxis: axisCommon(), |
|||
line: { |
|||
symbol: 'circle' |
|||
}, |
|||
graph: { |
|||
color: colorPalette |
|||
}, |
|||
gauge: { |
|||
title: { |
|||
color: contrastColor |
|||
}, |
|||
axisLine: { |
|||
lineStyle: { |
|||
color: [[1, 'rgba(207,212,219,0.2)']] |
|||
} |
|||
}, |
|||
axisLabel: { |
|||
color: contrastColor |
|||
}, |
|||
detail: { |
|||
color: '#EEF1FA' |
|||
} |
|||
}, |
|||
candlestick: { |
|||
itemStyle: { |
|||
color: '#f64e56', |
|||
color0: '#54ea92', |
|||
borderColor: '#f64e56', |
|||
borderColor0: '#54ea92' // borderColor: '#ca2824',
|
|||
// borderColor0: '#09a443'
|
|||
|
|||
} |
|||
} |
|||
}; |
|||
theme.categoryAxis.splitLine.show = false; |
|||
export default theme; |
|||
@ -0,0 +1,48 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
var colorAll = ['#37A2DA', '#32C5E9', '#67E0E3', '#9FE6B8', '#FFDB5C', '#ff9f7f', '#fb7293', '#E062AE', '#E690D1', '#e7bcf3', '#9d96f5', '#8378EA', '#96BFFF']; |
|||
export default { |
|||
color: colorAll, |
|||
colorLayer: [['#37A2DA', '#ffd85c', '#fd7b5f'], ['#37A2DA', '#67E0E3', '#FFDB5C', '#ff9f7f', '#E062AE', '#9d96f5'], ['#37A2DA', '#32C5E9', '#9FE6B8', '#FFDB5C', '#ff9f7f', '#fb7293', '#e7bcf3', '#8378EA', '#96BFFF'], colorAll] |
|||
}; |
|||
@ -0,0 +1,160 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 * as zrUtil from 'zrender/lib/core/util.js'; |
|||
import { parseClassType } from './clazz.js'; |
|||
/** |
|||
* Usage of query: |
|||
* `chart.on('click', query, handler);` |
|||
* The `query` can be: |
|||
* + The component type query string, only `mainType` or `mainType.subType`, |
|||
* like: 'xAxis', 'series', 'xAxis.category' or 'series.line'. |
|||
* + The component query object, like: |
|||
* `{seriesIndex: 2}`, `{seriesName: 'xx'}`, `{seriesId: 'some'}`, |
|||
* `{xAxisIndex: 2}`, `{xAxisName: 'xx'}`, `{xAxisId: 'some'}`. |
|||
* + The data query object, like: |
|||
* `{dataIndex: 123}`, `{dataType: 'link'}`, `{name: 'some'}`. |
|||
* + The other query object (cmponent customized query), like: |
|||
* `{element: 'some'}` (only available in custom series). |
|||
* |
|||
* Caveat: If a prop in the `query` object is `null/undefined`, it is the |
|||
* same as there is no such prop in the `query` object. |
|||
*/ |
|||
|
|||
var ECEventProcessor = |
|||
/** @class */ |
|||
function () { |
|||
function ECEventProcessor() {} |
|||
|
|||
ECEventProcessor.prototype.normalizeQuery = function (query) { |
|||
var cptQuery = {}; |
|||
var dataQuery = {}; |
|||
var otherQuery = {}; // `query` is `mainType` or `mainType.subType` of component.
|
|||
|
|||
if (zrUtil.isString(query)) { |
|||
var condCptType = parseClassType(query); // `.main` and `.sub` may be ''.
|
|||
|
|||
cptQuery.mainType = condCptType.main || null; |
|||
cptQuery.subType = condCptType.sub || null; |
|||
} // `query` is an object, convert to {mainType, index, name, id}.
|
|||
else { |
|||
// `xxxIndex`, `xxxName`, `xxxId`, `name`, `dataIndex`, `dataType` is reserved,
|
|||
// can not be used in `compomentModel.filterForExposedEvent`.
|
|||
var suffixes_1 = ['Index', 'Name', 'Id']; |
|||
var dataKeys_1 = { |
|||
name: 1, |
|||
dataIndex: 1, |
|||
dataType: 1 |
|||
}; |
|||
zrUtil.each(query, function (val, key) { |
|||
var reserved = false; |
|||
|
|||
for (var i = 0; i < suffixes_1.length; i++) { |
|||
var propSuffix = suffixes_1[i]; |
|||
var suffixPos = key.lastIndexOf(propSuffix); |
|||
|
|||
if (suffixPos > 0 && suffixPos === key.length - propSuffix.length) { |
|||
var mainType = key.slice(0, suffixPos); // Consider `dataIndex`.
|
|||
|
|||
if (mainType !== 'data') { |
|||
cptQuery.mainType = mainType; |
|||
cptQuery[propSuffix.toLowerCase()] = val; |
|||
reserved = true; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (dataKeys_1.hasOwnProperty(key)) { |
|||
dataQuery[key] = val; |
|||
reserved = true; |
|||
} |
|||
|
|||
if (!reserved) { |
|||
otherQuery[key] = val; |
|||
} |
|||
}); |
|||
} |
|||
|
|||
return { |
|||
cptQuery: cptQuery, |
|||
dataQuery: dataQuery, |
|||
otherQuery: otherQuery |
|||
}; |
|||
}; |
|||
|
|||
ECEventProcessor.prototype.filter = function (eventType, query) { |
|||
// They should be assigned before each trigger call.
|
|||
var eventInfo = this.eventInfo; |
|||
|
|||
if (!eventInfo) { |
|||
return true; |
|||
} |
|||
|
|||
var targetEl = eventInfo.targetEl; |
|||
var packedEvent = eventInfo.packedEvent; |
|||
var model = eventInfo.model; |
|||
var view = eventInfo.view; // For event like 'globalout'.
|
|||
|
|||
if (!model || !view) { |
|||
return true; |
|||
} |
|||
|
|||
var cptQuery = query.cptQuery; |
|||
var dataQuery = query.dataQuery; |
|||
return check(cptQuery, model, 'mainType') && check(cptQuery, model, 'subType') && check(cptQuery, model, 'index', 'componentIndex') && check(cptQuery, model, 'name') && check(cptQuery, model, 'id') && check(dataQuery, packedEvent, 'name') && check(dataQuery, packedEvent, 'dataIndex') && check(dataQuery, packedEvent, 'dataType') && (!view.filterForExposedEvent || view.filterForExposedEvent(eventType, query.otherQuery, targetEl, packedEvent)); |
|||
|
|||
function check(query, host, prop, propOnHost) { |
|||
return query[prop] == null || host[propOnHost || prop] === query[prop]; |
|||
} |
|||
}; |
|||
|
|||
ECEventProcessor.prototype.afterTrigger = function () { |
|||
// Make sure the eventInfo wont be used in next trigger.
|
|||
this.eventInfo = null; |
|||
}; |
|||
|
|||
return ECEventProcessor; |
|||
}(); |
|||
|
|||
export { ECEventProcessor }; |
|||
; |
|||
@ -0,0 +1,305 @@ |
|||
|
|||
/* |
|||
* 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. |
|||
*/ |
|||
|
|||
|
|||
/** |
|||
* AUTO-GENERATED FILE. DO NOT MODIFY. |
|||
*/ |
|||
|
|||
/* |
|||
* 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 quickSelect from './quickSelect.js'; |
|||
|
|||
var KDTreeNode = |
|||
/** @class */ |
|||
function () { |
|||
function KDTreeNode(axis, data) { |
|||
this.axis = axis; |
|||
this.data = data; |
|||
} |
|||
|
|||
return KDTreeNode; |
|||
}(); |
|||
/** |
|||
* @constructor |
|||
* @alias module:echarts/data/KDTree |
|||
* @param {Array} points List of points. |
|||
* each point needs an array property to repesent the actual data |
|||
* @param {Number} [dimension] |
|||
* Point dimension. |
|||
* Default will use the first point's length as dimensiont |
|||
*/ |
|||
|
|||
|
|||
var KDTree = |
|||
/** @class */ |
|||
function () { |
|||
function KDTree(points, dimension) { |
|||
// Use one stack to avoid allocation
|
|||
// each time searching the nearest point
|
|||
this._stack = []; // Again avoid allocating a new array
|
|||
// each time searching nearest N points
|
|||
|
|||
this._nearstNList = []; |
|||
|
|||
if (!points.length) { |
|||
return; |
|||
} |
|||
|
|||
if (!dimension) { |
|||
dimension = points[0].array.length; |
|||
} |
|||
|
|||
this.dimension = dimension; |
|||
this.root = this._buildTree(points, 0, points.length - 1, 0); |
|||
} |
|||
/** |
|||
* Resursively build the tree |
|||
*/ |
|||
|
|||
|
|||
KDTree.prototype._buildTree = function (points, left, right, axis) { |
|||
if (right < left) { |
|||
return null; |
|||
} |
|||
|
|||
var medianIndex = Math.floor((left + right) / 2); |
|||
medianIndex = quickSelect(points, left, right, medianIndex, function (a, b) { |
|||
return a.array[axis] - b.array[axis]; |
|||
}); |
|||
var median = points[medianIndex]; |
|||
var node = new KDTreeNode(axis, median); |
|||
axis = (axis + 1) % this.dimension; |
|||
|
|||
if (right > left) { |
|||
node.left = this._buildTree(points, left, medianIndex - 1, axis); |
|||
node.right = this._buildTree(points, medianIndex + 1, right, axis); |
|||
} |
|||
|
|||
return node; |
|||
}; |
|||
|
|||
; |
|||
/** |
|||
* Find nearest point |
|||
* @param target Target point |
|||
* @param squaredDistance Squared distance function |
|||
* @return Nearest point |
|||
*/ |
|||
|
|||
KDTree.prototype.nearest = function (target, squaredDistance) { |
|||
var curr = this.root; |
|||
var stack = this._stack; |
|||
var idx = 0; |
|||
var minDist = Infinity; |
|||
var nearestNode = null; |
|||
|
|||
if (curr.data !== target) { |
|||
minDist = squaredDistance(curr.data, target); |
|||
nearestNode = curr; |
|||
} |
|||
|
|||
if (target.array[curr.axis] < curr.data.array[curr.axis]) { |
|||
// Left first
|
|||
curr.right && (stack[idx++] = curr.right); |
|||
curr.left && (stack[idx++] = curr.left); |
|||
} else { |
|||
// Right first
|
|||
curr.left && (stack[idx++] = curr.left); |
|||
curr.right && (stack[idx++] = curr.right); |
|||
} |
|||
|
|||
while (idx--) { |
|||
curr = stack[idx]; |
|||
var currDist = target.array[curr.axis] - curr.data.array[curr.axis]; |
|||
var isLeft = currDist < 0; |
|||
var needsCheckOtherSide = false; |
|||
currDist = currDist * currDist; // Intersecting right hyperplane with minDist hypersphere
|
|||
|
|||
if (currDist < minDist) { |
|||
currDist = squaredDistance(curr.data, target); |
|||
|
|||
if (currDist < minDist && curr.data !== target) { |
|||
minDist = currDist; |
|||
nearestNode = curr; |
|||
} |
|||
|
|||
needsCheckOtherSide = true; |
|||
} |
|||
|
|||
if (isLeft) { |
|||
if (needsCheckOtherSide) { |
|||
curr.right && (stack[idx++] = curr.right); |
|||
} // Search in the left area
|
|||
|
|||
|
|||
curr.left && (stack[idx++] = curr.left); |
|||
} else { |
|||
if (needsCheckOtherSide) { |
|||
curr.left && (stack[idx++] = curr.left); |
|||
} // Search the right area
|
|||
|
|||
|
|||
curr.right && (stack[idx++] = curr.right); |
|||
} |
|||
} |
|||
|
|||
return nearestNode.data; |
|||
}; |
|||
|
|||
; |
|||
|
|||
KDTree.prototype._addNearest = function (found, dist, node) { |
|||
var nearestNList = this._nearstNList; |
|||
var i = found - 1; // Insert to the right position
|
|||
// Sort from small to large
|
|||
|
|||
for (; i > 0; i--) { |
|||
if (dist >= nearestNList[i - 1].dist) { |
|||
break; |
|||
} else { |
|||
nearestNList[i].dist = nearestNList[i - 1].dist; |
|||
nearestNList[i].node = nearestNList[i - 1].node; |
|||
} |
|||
} |
|||
|
|||
nearestNList[i].dist = dist; |
|||
nearestNList[i].node = node; |
|||
}; |
|||
|
|||
; |
|||
/** |
|||
* Find nearest N points |
|||
* @param target Target point |
|||
* @param N |
|||
* @param squaredDistance Squared distance function |
|||
* @param output Output nearest N points |
|||
*/ |
|||
|
|||
KDTree.prototype.nearestN = function (target, N, squaredDistance, output) { |
|||
if (N <= 0) { |
|||
output.length = 0; |
|||
return output; |
|||
} |
|||
|
|||
var curr = this.root; |
|||
var stack = this._stack; |
|||
var idx = 0; |
|||
var nearestNList = this._nearstNList; |
|||
|
|||
for (var i = 0; i < N; i++) { |
|||
// Allocate
|
|||
if (!nearestNList[i]) { |
|||
nearestNList[i] = { |
|||
dist: 0, |
|||
node: null |
|||
}; |
|||
} |
|||
|
|||
nearestNList[i].dist = 0; |
|||
nearestNList[i].node = null; |
|||
} |
|||
|
|||
var currDist = squaredDistance(curr.data, target); |
|||
var found = 0; |
|||
|
|||
if (curr.data !== target) { |
|||
found++; |
|||
|
|||
this._addNearest(found, currDist, curr); |
|||
} |
|||
|
|||
if (target.array[curr.axis] < curr.data.array[curr.axis]) { |
|||
// Left first
|
|||
curr.right && (stack[idx++] = curr.right); |
|||
curr.left && (stack[idx++] = curr.left); |
|||
} else { |
|||
// Right first
|
|||
curr.left && (stack[idx++] = curr.left); |
|||
curr.right && (stack[idx++] = curr.right); |
|||
} |
|||
|
|||
while (idx--) { |
|||
curr = stack[idx]; |
|||
var currDist_1 = target.array[curr.axis] - curr.data.array[curr.axis]; |
|||
var isLeft = currDist_1 < 0; |
|||
var needsCheckOtherSide = false; |
|||
currDist_1 = currDist_1 * currDist_1; // Intersecting right hyperplane with minDist hypersphere
|
|||
|
|||
if (found < N || currDist_1 < nearestNList[found - 1].dist) { |
|||
currDist_1 = squaredDistance(curr.data, target); |
|||
|
|||
if ((found < N || currDist_1 < nearestNList[found - 1].dist) && curr.data !== target) { |
|||
if (found < N) { |
|||
found++; |
|||
} |
|||
|
|||
this._addNearest(found, currDist_1, curr); |
|||
} |
|||
|
|||
needsCheckOtherSide = true; |
|||
} |
|||
|
|||
if (isLeft) { |
|||
if (needsCheckOtherSide) { |
|||
curr.right && (stack[idx++] = curr.right); |
|||
} // Search in the left area
|
|||
|
|||
|
|||
curr.left && (stack[idx++] = curr.left); |
|||
} else { |
|||
if (needsCheckOtherSide) { |
|||
curr.left && (stack[idx++] = curr.left); |
|||
} // Search the right area
|
|||
|
|||
|
|||
curr.right && (stack[idx++] = curr.right); |
|||
} |
|||
} // Copy to output
|
|||
|
|||
|
|||
for (var i = 0; i < found; i++) { |
|||
output[i] = nearestNList[i].node.data; |
|||
} |
|||
|
|||
output.length = found; |
|||
return output; |
|||
}; |
|||
|
|||
return KDTree; |
|||
}(); |
|||
|
|||
export default KDTree; |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue