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