Browse Source

代码修改

yeshijie 7 years ago
parent
commit
21d636cbd0
17 changed files with 4752 additions and 0 deletions
  1. 488 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/data/Graph.js
  2. 247 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/data/KDTree.js
  3. 241 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/data/Tree.js
  4. 79 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/data/quickSelect.js
  5. 172 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layer/heatmap.js
  6. 145 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/Chord.js
  7. 415 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/EdgeBundling.js
  8. 248 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/Force.js
  9. 90 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/Tree.js
  10. 202 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/TreeMap.js
  11. 692 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/WordCloud.js
  12. 123 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/WordCloudRectZero.js
  13. 262 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/eventRiver.js
  14. 781 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/forceLayoutWorker.js
  15. 13 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/theme/default.js
  16. 297 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/theme/infographic.js
  17. 257 0
      patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/theme/macarons.js

+ 488 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/data/Graph.js

@ -0,0 +1,488 @@
/**
 * Graph data structure
 * 
 * @module echarts/data/Graph
 * @author Yi Shen(https://www.github.com/pissang)
 */
define(function(require) {
    var util = require('zrender/tool/util');
    'use strict';
    /**
     * @alias module:echarts/data/Graph
     * @constructor
     * @param {boolean} directed
     */
    var Graph = function(directed) {
        /**
         * 是否是有向图
         * @type {boolean}
         * @private
         */
        this._directed = directed || false;
        /**
         * @type {Array}
         */
        this.nodes = [];
        this.edges = [];
        this._nodesMap = {};
        this._edgesMap = {};
    };
    /**
     * 是否是有向图
     * @return {boolean}
     */
    Graph.prototype.isDirected = function () {
        return this._directed;
    };
    /**
     * 添加一个新的节点
     * @param {string} id 节点名称
     * @param {*} [data] 存储的数据
     */
    Graph.prototype.addNode = function (id, data) {
        if (this._nodesMap[id]) {
            return this._nodesMap[id];
        }
        var node = new Graph.Node(id, data);
        this.nodes.push(node);
        this._nodesMap[id] = node;
        return node;
    };
    
    /**
     * 获取节点
     * @param  {string} id
     * @return {module:echarts/data/Graph~Node}
     */
    Graph.prototype.getNodeById = function (id) {
        return this._nodesMap[id];
    };
    /**
     * 添加边
     * @param {string|module:echarts/data/Graph~Node} n1
     * @param {string|module:echarts/data/Graph~Node} n2
     * @param {*} data
     * @return {module:echarts/data/Graph~Edge}
     */
    Graph.prototype.addEdge = function (n1, n2, data) {
        if (typeof(n1) == 'string') {
            n1 = this._nodesMap[n1];
        }
        if (typeof(n2) == 'string') {
            n2 = this._nodesMap[n2];
        }
        if (!n1 || !n2) {
            return;
        }
        var key = n1.id + '-' + n2.id;
        if (this._edgesMap[key]) {
            return this._edgesMap[key];
        }
        var edge = new Graph.Edge(n1, n2, data);
        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);
        this._edgesMap[key] = edge;
        return edge;
    };
    /**
     * 移除边
     * @param  {module:echarts/data/Graph~Edge} edge
     */
    Graph.prototype.removeEdge = function (edge) {
        var n1 = edge.node1;
        var n2 = edge.node2;
        var key = n1.id + '-' + n2.id;
        if (this._directed) {
            n1.outEdges.splice(util.indexOf(n1.outEdges, edge), 1);
            n2.inEdges.splice(util.indexOf(n2.inEdges, edge), 1);   
        }
        n1.edges.splice(util.indexOf(n1.edges, edge), 1);
        if (n1 !== n2) {
            n2.edges.splice(util.indexOf(n2.edges, edge), 1);
        }
        delete this._edgesMap[key];
        this.edges.splice(util.indexOf(this.edges, edge), 1);
    };
    /**
     * 获取边
     * @param  {module:echarts/data/Graph~Node|string} n1
     * @param  {module:echarts/data/Graph~Node|string} n2
     * @return {module:echarts/data/Graph~Edge}
     */
    Graph.prototype.getEdge = function (n1, n2) {
        if (typeof(n1) !== 'string') {
            n1 = n1.id;
        }
        if (typeof(n2) !== 'string') {
            n2 = n2.id;
        }
        if (this._directed) {
            return this._edgesMap[n1 + '-' + n2];
        } else {
            return this._edgesMap[n1 + '-' + n2]
                || this._edgesMap[n2 + '-' + n1];
        }
    };
    /**
     * 移除节点(及其邻接边)
     * @param  {module:echarts/data/Graph~Node|string} node
     */
    Graph.prototype.removeNode = function (node) {
        if (typeof(node) === 'string') {
            node = this._nodesMap[node];
            if (!node) {
                return;
            }
        }
        delete this._nodesMap[node.id];
        this.nodes.splice(util.indexOf(this.nodes, node), 1);
        for (var i = 0; i < this.edges.length;) {
            var edge = this.edges[i];
            if (edge.node1 === node || edge.node2 === node) {
                this.removeEdge(edge);
            } else {
                i++;
            }
        }
    };
    /**
     * 遍历并且过滤指定的节点
     * @param  {Function} cb
     * @param  {*}   [context]
     */
     Graph.prototype.filterNode = function (cb, context) {
        var len = this.nodes.length;
        for (var i = 0; i < len;) {
            if (cb.call(context, this.nodes[i], i)) {
                i++;
            } else {
                this.removeNode(this.nodes[i]);
                len--;
            }
        }
     };
    /**
     * 遍历并且过滤指定的边
     * @param  {Function} cb
     * @param  {*}   [context]
     */
     Graph.prototype.filterEdge = function (cb, context) {
        var len = this.edges.length;
        for (var i = 0; i < len;) {
            if (cb.call(context, this.edges[i], i)) {
                i++;
            } else {
                this.removeEdge(this.edges[i]);
                len--;
            }
        }
     };
    /**
     * 线性遍历所有节点
     * @param  {Function} cb
     * @param  {*}   [context]
     */
    Graph.prototype.eachNode = function (cb, context) {
        var len = this.nodes.length;
        for (var i = 0; i < len; i++) {
            if (this.nodes[i]) {    // 可能在遍历过程中存在节点删除
                cb.call(context, this.nodes[i], i);
            }
        }
    };
    
    /**
     * 线性遍历所有边
     * @param  {Function} cb
     * @param  {*}   [context]
     */
    Graph.prototype.eachEdge = function (cb, context) {
        var len = this.edges.length;
        for (var i = 0; i < len; i++) {
            if (this.edges[i]) {    // 可能在遍历过程中存在边删除
                cb.call(context, this.edges[i], i);
            }
        }
    };
    
    /**
     * 清空图
     */
    Graph.prototype.clear = function() {
        this.nodes.length = 0;
        this.edges.length = 0;
        this._nodesMap = {};
        this._edgesMap = {};
    };
    
    /**
     * 广度优先遍历
     * @param {Function} cb
     * @param {module:echarts/data/Graph~Node} startNode 遍历起始节点
     * @param {string} [direction=none] none, in, out 指定遍历边
     * @param {*} [context] 回调函数调用context
     */
    Graph.prototype.breadthFirstTraverse = function (
        cb, startNode, direction, context
    ) {
        if (typeof(startNode) === 'string') {
            startNode = this._nodesMap[startNode];
        }
        if (!startNode) {
            return;
        }
        var edgeType = 'edges';
        if (direction === 'out') {
            edgeType = 'outEdges';
        } else if (direction === 'in') {
            edgeType = 'inEdges';
        }
        
        for (var i = 0; i < this.nodes.length; i++) {
            this.nodes[i].__visited = false;
        }
        if (cb.call(context, startNode, null)) {
            return;
        }
        var queue = [startNode];
        while (queue.length) {
            var currentNode = queue.shift();
            var edges = currentNode[edgeType];
            for (var i = 0; i < edges.length; i++) {
                var e = edges[i];
                var otherNode = e.node1 === currentNode 
                    ? e.node2 : e.node1;
                if (!otherNode.__visited) {
                    if (cb.call(otherNode, otherNode, currentNode)) {
                        // Stop traversing
                        return;
                    }
                    queue.push(otherNode);
                    otherNode.__visited = true;
                }
            }
        }
    };
    /**
     * 复制图
     */
    Graph.prototype.clone = function () {
        var graph = new Graph(this._directed);
        for (var i = 0; i < this.nodes.length; i++) {
            graph.addNode(this.nodes[i].id, this.nodes[i].data);
        }
        for (var i = 0; i < this.edges.length; i++) {
            var e = this.edges[i];
            graph.addEdge(e.node1.id, e.node2.id, e.data);
        }
        return graph;
    };
    /**
     * 图节点
     * @alias module:echarts/data/Graph~Node
     * @param {string} id
     * @param {*} [data]
     */
    var Node = function(id, data) {
        /**
         * 节点名称
         * @type {string}
         */
        this.id = id;
        /**
         * 节点存储的数据
         * @type {*}
         */
        this.data = data || null;
        /**
         * 入边,只在有向图上有效
         * @type {Array.<module:echarts/data/Graph~Edge>}
         */
        this.inEdges = [];
        /**
         * 出边,只在有向图上有效
         * @type {Array.<module:echarts/data/Graph~Edge>}
         */
        this.outEdges = [];
        /**
         * 邻接边
         * @type {Array.<module:echarts/data/Graph~Edge>}
         */
        this.edges = [];
    };
    
    /**
     * 度
     * @return {number}
     */
    Node.prototype.degree = function() {
        return this.edges.length; 
    };
    
    /**
     * 入度,只在有向图上有效
     * @return {number}
     */
    Node.prototype.inDegree = function() {
        return this.inEdges.length;
    };
    
    /**
     * 出度,只在有向图上有效
     * @return {number}
     */
    Node.prototype.outDegree = function() {
        return this.outEdges.length;
    };
    /**
     * 图边
     * @alias module:echarts/data/Graph~Edge
     * @param {module:echarts/data/Graph~Node} node1
     * @param {module:echarts/data/Graph~Node} node2
     * @param {extra} data
     */
    var Edge = function(node1, node2, data) {
        /**
         * 节点1,如果是有向图则为源节点
         * @type {module:echarts/data/Graph~Node}
         */
        this.node1 = node1;
        /**
         * 节点2,如果是有向图则为目标节点
         * @type {module:echarts/data/Graph~Node}
         */
        this.node2 = node2;
        /**
         * 边存储的数据
         * @type {*}
         */
        this.data = data || null;
    };
    Graph.Node = Node;
    Graph.Edge = Edge;
    /**
     * 从邻接矩阵生成
     * ```
     *        TARGET
     *    -1--2--3--4--5-
     *  1| x  x  x  x  x
     *  2| x  x  x  x  x
     *  3| x  x  x  x  x  SOURCE
     *  4| x  x  x  x  x
     *  5| x  x  x  x  x
     * ```
     * 节点的行列总和会被写到`node.data.value`
     * 对于有向图会计算每一行的和写到`node.data.outValue`,
     * 计算每一列的和写到`node.data.inValue`。
     * 边的权重会被然后写到`edge.data.weight`。
     * 
     * @method module:echarts/data/Graph.fromMatrix
     * @param {Array.<Object>} nodesData 节点信息,必须有`id`属性, 会保存到`node.data`中
     * @param {Array} matrix 邻接矩阵
     * @param {boolean} directed 是否是有向图
     * @return {module:echarts/data/Graph}
     */
    Graph.fromMatrix = function(nodesData, matrix, directed) {
        if (
            !matrix || !matrix.length
            || (matrix[0].length !== matrix.length)
            || (nodesData.length !== matrix.length)
        ) {
            // Not a valid data
            return;
        }
        var size = matrix.length;
        var graph = new Graph(directed);
        for (var i = 0; i < size; i++) {
            var node = graph.addNode(nodesData[i].id, nodesData[i]);
            // TODO
            // node.data已经有value的情况
            node.data.value = 0;
            if (directed) {
                node.data.outValue = node.data.inValue = 0;
            }
        }
        for (var i = 0; i < size; i++) {
            for (var j = 0; j < size; j++) {
                var item = matrix[i][j];
                if (directed) {
                    graph.nodes[i].data.outValue += item;
                    graph.nodes[j].data.inValue += item;
                }
                graph.nodes[i].data.value += item;
                graph.nodes[j].data.value += item;
            }
        }
        for (var i = 0; i < size; i++) {
            for (var j = i; j < size; j++) {
                var item = matrix[i][j];
                if (item === 0) {
                    continue;
                }
                var n1 = graph.nodes[i];
                var n2 = graph.nodes[j];
                var edge = graph.addEdge(n1, n2, {});
                edge.data.weight = item;
                if (i !== j) {
                    if (directed && matrix[j][i]) {
                        var inEdge = graph.addEdge(n2, n1, {});
                        inEdge.data.weight = matrix[j][i];
                    }
                }
            }
        }
        // console.log(graph.edges.map(function (e) {return e.node1.id + '-' + e.node2.id;}))
        return graph;
    };
    return Graph;
});

+ 247 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/data/KDTree.js

@ -0,0 +1,247 @@
/**
 * K-Dimension Tree
 *
 * @module echarts/data/KDTree
 * @author Yi Shen(https://github.com/pissang)
 */
define(function (require) {
    var quickSelect = require('./quickSelect');
    function Node(axis, data) {
        this.left = null;
        this.right = null;
        this.axis = axis;
        this.data = data;
    }
    /**
     * @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 = function (points, dimension) {
        if (!points.length) {
            return;
        }
        if (!dimension) {
            dimension = points[0].array.length;
        }
        this.dimension = dimension;
        this.root = this._buildTree(points, 0, points.length - 1, 0);
        // 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 = [];
    };
    /**
     * 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 Node(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  {Array} target Target point
     * @param  {Function} squaredDistance Squared distance function
     * @return {Array} 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;
        // Insert to the right position
        // Sort from small to large
        for (var i = found - 1; 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  {Array} target Target point
     * @param  {number} N
     * @param  {Function} squaredDistance Squared distance function
     * @param  {Array} [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] = {};
            }
            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 = 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 (found < N || currDist < nearestNList[found - 1].dist) {
                currDist = squaredDistance(curr.data, target);
                if (
                    (found < N || currDist < nearestNList[found - 1].dist)
                    && curr.data !== target
                ) {
                    if (found < N) {
                        found++;
                    }
                    this._addNearest(found, currDist, 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;
});

+ 241 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/data/Tree.js

@ -0,0 +1,241 @@
/**
 * Tree data structure
 * 
 * @module echarts/data/Tree
 * @author Yi Shen(https://www.github.com/pissang)
 */
define(function(require) {
    var zrUtil = require('zrender/tool/util');
    /**
     * @constructor module:echarts/data/Tree~TreeNode
     * @param {string} id Node ID
     * @param {Object} [data]
     */
    function TreeNode(id, data) {
        /**
         * @type {string}
         */
        this.id = id;
        /**
         * 节点的深度
         * @type {number}
         */
        this.depth = 0;
        /**
         * 以当前节点为根节点的子树的高度
         * @type {number}
         */
        this.height = 0;
        /**
         * 子节点列表
         * @type {Array.<module:echarts/data/Tree~TreeNode>}
         */
        this.children = [];
        /**
         * @type {module:echarts/data/Tree~TreeNode}
         */
        this.parent = null;
        /**
         * 存储的用户数据
         * @type {Object}
         */
        this.data = data || null;
    }
    /**
     * 添加子节点
     * @param {module:echarts/data/Tree~TreeNode} child
     */
    TreeNode.prototype.add = function (child) {
        var children = this.children;
        if (child.parent === this) {
            return;
        }
        children.push(child);
        child.parent = this;
    };
    /**
     * 移除子节点
     * @param {module:echarts/data/Tree~TreeNode} child
     */
    TreeNode.prototype.remove = function (child) {
        var children = this.children;
        var idx = zrUtil.indexOf(children, child);
        if (idx >= 0) {
            children.splice(idx, 1);
            child.parent = null;
        }
    };
    /**
     * 遍历当前节点及其所有子节点
     * @param  {Function} cb
     * @param  {Object}   [context]
     */
    TreeNode.prototype.traverse = function (cb, context) {
        cb.call(context, this);
        for (var i = 0; i < this.children.length; i++) {
            this.children[i].traverse(cb, context);
        }
    };
    /**
     * 更新当前树及所有子树的高度和深度
     * @param  {number} depth
     */
    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;
    };
    /**
     * @param  {string} id
     * @return module:echarts/data/Tree~TreeNode
     */
    TreeNode.prototype.getNodeById = function (id) {
        if (this.id === id) {
            return this;
        }
        for (var i = 0; i < this.children.length; i++) {
            var res = this.children[i].getNodeById(id);
            if (res) {
                return res;
            }
        }
    };
    /**
     * @constructor
     * @alias module:echarts/data/Tree
     * @param {string} id
     */
    function Tree(id) {
        /**
         * @type {module:echarts/data/Tree~TreeNode}
         */
        this.root = new TreeNode(id);
    }
    /**
     * 遍历树的所有子节点
     * @param  {Function} cb
     * @param  {Object}   [context]
     */
    Tree.prototype.traverse = function(cb, context) {
        this.root.traverse(cb, context);
    };
    /**
     * 生成子树
     * @param  {string} id 子树根节点 id
     * @return {module:echarts/data/Tree}
     */
    Tree.prototype.getSubTree = function(id) {
        var root = this.getNodeById(id);
        if (root) {
            var tree = new Tree(root.id);
            tree.root = root;
            return tree;
        }
    };
    /**
     * @param  {string} id
     * @return module:echarts/data/Tree~TreeNode
     */
    Tree.prototype.getNodeById = function (id) {
        return this.root.getNodeById(id);
    };
    /**
     * 从 option 里的 data 数据构建树
     * @param {string} id
     * @param {Array.<Object>} data
     * @return module:echarts/data/Tree
     */
    Tree.fromOptionData = function (id, data) {
        var tree = new Tree(id);
        var rootNode = tree.root;
        // Root node
        rootNode.data = {
            name: id,
            children: data
        };
        function buildHierarchy(dataNode, parentNode) {
            var node = new TreeNode(dataNode.name, dataNode);
            parentNode.add(node);
            // 遍历添加子节点
            var children = dataNode.children;
            if (children) {
                for (var i = 0; i < children.length; i++) {
                    buildHierarchy(children[i], node);
                }
            }
        }
        for (var i = 0; i < data.length; i++) {
            buildHierarchy(data[i], rootNode);
        }
        tree.root.updateDepthAndHeight(0);
        return tree;
    };
    // TODO
    Tree.fromGraph = function (graph) {
        function buildHierarchy(root) {
            var graphNode = graph.getNodeById(root.id);
            for (var i = 0; i < graphNode.outEdges.length; i++) {
                var edge = graphNode.outEdges[i];
                var childTreeNode = treeNodesMap[edge.node2.id];
                root.children.push(childTreeNode);
                buildHierarchy(childTreeNode);
            }
        }
        var treeMap = {};
        var treeNodesMap = {};
        for (var i = 0; i < graph.nodes.length; i++) {
            var node = graph.nodes[i];
            var treeNode;
            if (node.inDegree() === 0) {
                treeMap[node.id] = new Tree(node.id);
                treeNode = treeMap[node.id].root;
            } else {
                treeNode = new TreeNode(node.id);
            }
            treeNode.data = node.data;
            treeNodesMap[node.id] = treeNode;
        }
        var treeList = [];
        for (var id in treeMap) {
            buildHierarchy(treeMap[id].root);
            treeMap[id].root.updateDepthAndHeight(0);
            treeList.push(treeMap[id]);
        }
        return treeList;
    };
    return Tree;
});

+ 79 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/data/quickSelect.js

@ -0,0 +1,79 @@
/**
 * Quick select n-th element in an array.
 *
 * Note: it will change the elements placement in array.
 *
 * @module echarts/data/quickSelect
 * @author Yi Shen(https://github.com/pissang)
 */
define(function (require) {
    function defaultCompareFunc(a, b) {
        return a - b;
    }
    function swapElement(list, idx0, idx1) {
        var tmp = list[idx0];
        list[idx0] = list[idx1];
        list[idx1] = tmp;
    }
    function select(list, left, right, nth, compareFunc) {
        var pivotIdx = left;
        while (right > left) {
            var pivotIdx = Math.round((right + left) / 2);
            var pivotValue = list[pivotIdx];
            // Swap pivot to the end
            swapElement(list, pivotIdx, right);
            pivotIdx = left;
            for (var i = left; i <= right - 1; i++) {
                if (compareFunc(pivotValue, list[i]) >= 0) {
                    swapElement(list, i, pivotIdx);
                    pivotIdx++;
                }
            }
            swapElement(list, right, pivotIdx);
            if (pivotIdx === nth) {
                return pivotIdx;
            } else if (pivotIdx < nth) {
                left = pivotIdx + 1;
            } else {
                right = pivotIdx - 1;
            }
        }
        // Left == right
        return left;
    }
    /**
     * @alias module:echarts/data/quickSelect
     * @param {Array} list
     * @param {number} [left]
     * @param {number} [right]
     * @param {number} nth
     * @param {Function} [compareFunc]
     * @example
     *     var quickSelect = require('echarts/data/quickSelect');
     *     var list = [5, 2, 1, 4, 3]
     *     quickSelect(list, 3);
     *     quickSelect(list, 0, 3, 1, function (a, b) {return a - b});
     *
     * @return {number}
     */
    function quickSelect(list, left, right, nth, compareFunc) {
        if (arguments.length <= 3) {
            nth = left;
            if (arguments.length == 2) {
                compareFunc = defaultCompareFunc;
            } else {
                compareFunc = right;
            }
            left = 0;
            right = list.length - 1;
        }
        return select(list, left, right, nth, compareFunc);
    }
    
    return quickSelect;
});

+ 172 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layer/heatmap.js

@ -0,0 +1,172 @@
/**
 * @file defines echarts Heatmap Chart
 * @author Ovilia (me@zhangwenli.com)
 * Inspired by https://github.com/mourner/simpleheat
 *
 * @module
 */
define(function (require) {
    var defaultOptions = {
        blurSize: 30,
        // gradientColors is either shaped of ['blue', 'cyan', 'lime', 'yellow', 'red']
        // or [{
        //    offset: 0.2,
        //    color: 'blue'
        // }, {
        //    offset 0.8,
        //    color: 'cyan'
        // }]
        gradientColors: ['blue', 'cyan', 'lime', 'yellow', 'red'],
        minAlpha: 0.05,
        valueScale: 1,
        opacity: 1
    };
    var BRUSH_SIZE = 20;
    var GRADIENT_LEVELS = 256;
    /**
     * Heatmap Chart
     *
     * @class
     * @param {Object} opt options
     */
    function Heatmap(opt) {
        this.option = opt;
        if (opt) {
            for (var i in defaultOptions) {
                if (opt[i] !== undefined) {
                    this.option[i] = opt[i];
                } else {
                    this.option[i] = defaultOptions[i];
                }
            }
        } else {
            this.option = defaultOptions;
        }
    }
    Heatmap.prototype = {
        /**
         * Renders Heatmap and returns the rendered canvas
         * @param {Array} [x, y, value] array of data
         * @param {number} canvas width
         * @param {number} canvas height
         * @return {Object} rendered canvas
         */
        getCanvas: function(data, width, height) {
            var brush = this._getBrush();
            var gradient = this._getGradient();
            var r = BRUSH_SIZE + this.option.blurSize;
            var canvas = document.createElement('canvas');
            canvas.width = width;
            canvas.height = height;
            var ctx = canvas.getContext('2d');
            var len = data.length;
            for (var i = 0; i < len; ++i) {
                var p = data[i];
                var x = p[0];
                var y = p[1];
                var value = p[2];
                // calculate alpha using value
                var alpha = Math.min(1, Math.max(value * this.option.valueScale
                    || this.option.minAlpha, this.option.minAlpha));
                // draw with the circle brush with alpha
                ctx.globalAlpha = alpha;
                ctx.drawImage(brush, x - r, y - r);
            }
            // colorize the canvas using alpha value and set with gradient
            var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
            var pixels = imageData.data;
            var len = pixels.length / 4;
            while(len--) {
                var id = len * 4 + 3;
                var alpha = pixels[id] / 256;
                var colorOffset = Math.floor(alpha * (GRADIENT_LEVELS - 1));
                pixels[id - 3] = gradient[colorOffset * 4];     // red
                pixels[id - 2] = gradient[colorOffset * 4 + 1]; // green
                pixels[id - 1] = gradient[colorOffset * 4 + 2]; // blue
                pixels[id] *= this.option.opacity;              // alpha
            }
            ctx.putImageData(imageData, 0, 0);
            return canvas;
        },
        /**
         * get canvas of a black circle brush used for canvas to draw later
         * @private
         * @returns {Object} circle brush canvas
         */
        _getBrush: function() {
            if (!this._brushCanvas) {
                this._brushCanvas = document.createElement('canvas');
                // set brush size
                var r = BRUSH_SIZE + this.option.blurSize;
                var d = r * 2;
                this._brushCanvas.width = d;
                this._brushCanvas.height = d;
                var ctx = this._brushCanvas.getContext('2d');
                // in order to render shadow without the distinct circle,
                // draw the distinct circle in an invisible place,
                // and use shadowOffset to draw shadow in the center of the canvas
                ctx.shadowOffsetX = d;
                ctx.shadowBlur = this.option.blurSize;
                // draw the shadow in black, and use alpha and shadow blur to generate
                // color in color map
                ctx.shadowColor = 'black';
                // draw circle in the left to the canvas
                ctx.beginPath();
                ctx.arc(-r, r, BRUSH_SIZE, 0, Math.PI * 2, true);
                ctx.closePath();
                ctx.fill();
            }
            return this._brushCanvas;
        },
        /**
         * get gradient color map
         * @private
         * @returns {array} gradient color pixels
         */
        _getGradient: function() {
            if (!this._gradientPixels) {
                var levels = GRADIENT_LEVELS;
                var canvas = document.createElement('canvas');
                canvas.width = 1;
                canvas.height = levels;
                var ctx = canvas.getContext('2d');
                
                // add color to gradient stops
                var gradient = ctx.createLinearGradient(0, 0, 0, levels);
                var len = this.option.gradientColors.length;
                for (var i = 0; i < len; ++i) {
                    if (typeof this.option.gradientColors[i] === 'string') {
                        gradient.addColorStop((i + 1) / len,
                            this.option.gradientColors[i]);
                    } else {
                        gradient.addColorStop(this.option.gradientColors[i].offset,
                            this.option.gradientColors[i].color);
                    }
                }
                ctx.fillStyle = gradient;
                ctx.fillRect(0, 0, 1, levels);
                this._gradientPixels = ctx.getImageData(0, 0, 1, levels).data;
            }
            return this._gradientPixels;
        }
    };
    return Heatmap;
});

+ 145 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/Chord.js

@ -0,0 +1,145 @@
/**
 * Chord layout
 * @module echarts/layout/Chord
 * @author pissang(http://github.com/pissang)
 */
define(function (require) {
    var ChordLayout = function (opts) {
        opts = opts || {};
        /**
         * 是否排序组(即图的节点), 可以是`ascending`, `descending`, 或者为空不排序
         * @type {string}
         */
        this.sort = opts.sort || null;
        /**
         * 是否排序子组(即图中每个节点的邻接边), 可以是`ascending`, `descending`, 或者为空不排序
         * @type {string}
         */
        this.sortSub = opts.sortSub || null;
        this.padding = 0.05;
        this.startAngle = opts.startAngle || 0;
        this.clockWise = opts.clockWise == null ? false : opts.clockWise;
        this.center = opts.center || [0, 0];
        this.directed = true;
    };
    /**
     * 对指定的一个或多个 Graph 运行 chord 布局
     * 可以有多个 Graph, 后面几个 Graph 的节点是第一个 Graph 的节点的子集(ID一一对应)
     *
     * 布局结果保存在第一个 Graph 的每个节点的 layout.startAngle 和 layout.endAngle.
     * 以及每个图的边的 layout.startAngle 和 layout.endAngle
     * 
     * @param {Array.<module:echarts/data/Graph>|module:echarts/data/Graph} graphs
     */
    ChordLayout.prototype.run = function (graphs) {
        if (!(graphs instanceof Array)) {
            graphs = [graphs];
        }
        var gl = graphs.length;
        if (!gl) {
            return;
        }
        var graph0 = graphs[0];
        var nl = graph0.nodes.length;
        var groups = [];
        var sumSize = 0;
        // 使用第一个 graph 的节点
        for (var i = 0; i < nl; i++) {
            var g0node = graph0.nodes[i];
            var group = {
                size: 0,
                subGroups: [],
                node: g0node
            };
            groups.push(group);
            var sumWeight = 0;
            // 合并所有 Graph 的 边
            for (var k = 0; k < graphs.length; k++) {
                var graph = graphs[k];
                var node = graph.getNodeById(g0node.id);
                // 节点可能没有值被过滤掉了
                if (!node) {
                    continue;
                }
                group.size += node.layout.size;
                // PENDING
                var edges = this.directed ? node.outEdges : node.edges;
                for (var j = 0; j < edges.length; j++) {
                    var e = edges[j];
                    var w = e.layout.weight;
                    group.subGroups.push({
                        weight: w,
                        edge: e,
                        graph: graph
                    });
                    sumWeight += w;
                }
            }
            sumSize += group.size;
            // Sum sub group weights to group size
            var multiplier = group.size / sumWeight;
            for (var j = 0; j < group.subGroups.length; j++) {
                group.subGroups[j].weight *= multiplier;
            }
            if (this.sortSub === 'ascending') {
                group.subGroups.sort(compareSubGroups);
            }
            else if (this.sort === 'descending') {
                group.subGroups.sort(compareSubGroups);
                group.subGroups.reverse();
            }
        }
        if (this.sort === 'ascending') {
            groups.sort(compareGroups);
        }
        else if (this.sort === 'descending') {
            groups.sort(compareGroups);
            groups.reverse();
        }
        var multiplier = (Math.PI * 2 - this.padding * nl) / sumSize;
        var angle = this.startAngle;
        var sign = this.clockWise ? 1 : -1;
        // Calculate angles
        for (var i = 0; i < nl; i++) {
            var group = groups[i];
            group.node.layout.startAngle = angle;
            group.node.layout.endAngle = angle + sign * group.size * multiplier;
            group.node.layout.subGroups = [];
            for (var j = 0; j < group.subGroups.length; j++) {
                var subGroup = group.subGroups[j];
                subGroup.edge.layout.startAngle = angle;
                angle += sign * subGroup.weight * multiplier;
                subGroup.edge.layout.endAngle = angle;
            }
            angle = group.node.layout.endAngle + sign * this.padding;
        }
    };
    var compareSubGroups = function (a, b) {
        return a.weight - b.weight;
    };
    var compareGroups = function (a, b) {
        return a.size - b.size;
    };
    return ChordLayout;
});

+ 415 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/EdgeBundling.js

@ -0,0 +1,415 @@
/**
 * Edge bundling laytout
 *
 * Use MINGLE algorithm
 * Multilevel agglomerative edge bundling for visualizing large graphs
 *
 * @module echarts/layout/EdgeBundling
 */
define(function (require) {
    var KDTree = require('../data/KDTree');
    var vec2 = require('zrender/tool/vector');
    var v2Create = vec2.create;
    var v2DistSquare = vec2.distSquare;
    var v2Dist = vec2.dist;
    var v2Copy = vec2.copy;
    var v2Clone = vec2.clone;
    function squaredDistance(a, b) {
        a = a.array;
        b = b.array;
        var x = b[0] - a[0];
        var y = b[1] - a[1];
        var z = b[2] - a[2];
        var w = b[3] - a[3];
        return x * x + y * y + z * z + w * w;
    }
    function CoarsenedEdge(group) {
        this.points = [
            group.mp0, group.mp1
        ];
        this.group = group;
    }
    function Edge(edge) {
        var points = edge.points;
        // Sort on y
        if (
            points[0][1] < points[1][1]
            // If coarsened edge is flipped, the final composition of meet point
            // will be unordered
            || edge instanceof CoarsenedEdge
        ) {
            this.array = [points[0][0], points[0][1], points[1][0], points[1][1]];
            this._startPoint = points[0];
            this._endPoint = points[1];
        }
        else {
            this.array = [points[1][0], points[1][1], points[0][0], points[0][1]];
            this._startPoint = points[1];
            this._endPoint = points[0];
        }
        this.ink = v2Dist(points[0], points[1]);
        this.edge = edge;
        this.group = null;
    }
    Edge.prototype.getStartPoint = function () {
        return this._startPoint;
    };
    Edge.prototype.getEndPoint = function () {
        return this._endPoint;
    };
    function BundledEdgeGroup() {
        this.edgeList = [];
        this.mp0 = v2Create();
        this.mp1 = v2Create();
        this.ink = 0;
    }
    BundledEdgeGroup.prototype.addEdge = function (edge) {
        edge.group = this;
        this.edgeList.push(edge);
    };
    BundledEdgeGroup.prototype.removeEdge = function (edge) {
        edge.group = null;
        this.edgeList.splice(this.edgeList.indexOf(edge), 1);
    };
    /**
     * @constructor
     * @alias module:echarts/layout/EdgeBundling
     */
    function EdgeBundling() {
        this.maxNearestEdge = 6;
        this.maxTurningAngle = Math.PI / 4;
        this.maxIteration = 20;
    }
    EdgeBundling.prototype = {
        
        constructor: EdgeBundling,
        run: function (rawEdges) {
            var res = this._iterate(rawEdges);
            var nIterate = 0;
            while (nIterate++ < this.maxIteration) {
                var coarsenedEdges = [];
                for (var i = 0; i < res.groups.length; i++) {
                    coarsenedEdges.push(new CoarsenedEdge(res.groups[i]));
                }
                var newRes = this._iterate(coarsenedEdges);
                if (newRes.savedInk <= 0) {
                    break;
                } else {
                    res = newRes;
                }
            }
            // Get new edges
            var newEdges = [];
            function pointApproxEqual(p0, p1) {
                // Use Float32Array may affect the precision
                return v2DistSquare(p0, p1) < 1e-10;
            }
            // Clone all points to make sure all points in edge will not reference to the same array
            // And clean the duplicate points
            function cleanEdgePoints(edgePoints, rawEdgePoints) {
                var res = [];
                var off = 0;
                for (var i = 0; i < edgePoints.length; i++) {
                    if (! (off > 0 && pointApproxEqual(edgePoints[i], res[off - 1]))) {
                        res[off++] = v2Clone(edgePoints[i]);
                    }
                }
                // Edge has been reversed
                if (rawEdgePoints[0] && !pointApproxEqual(res[0], rawEdgePoints[0])) {
                    res = res.reverse();
                }
                return res;
            }
            var buildNewEdges = function (groups, fromEdgePoints) {
                var newEdgePoints;
                for (var i = 0; i < groups.length; i++) {
                    var group = groups[i];
                    if (
                        group.edgeList[0]
                        && (group.edgeList[0].edge instanceof CoarsenedEdge)
                    ) {
                        var newGroups = [];
                        for (var j = 0; j < group.edgeList.length; j++) {
                            newGroups.push(group.edgeList[j].edge.group);
                        }
                        if (! fromEdgePoints) {
                            newEdgePoints = [];
                        } else {
                            newEdgePoints = fromEdgePoints.slice();
                        }
                        newEdgePoints.unshift(group.mp0);
                        newEdgePoints.push(group.mp1);
                        buildNewEdges(newGroups, newEdgePoints);
                    } else {
                        // console.log(group.edgeList.length);
                        for (var j = 0; j < group.edgeList.length; j++) {
                            var edge = group.edgeList[j];
                            if (! fromEdgePoints) {
                                newEdgePoints = [];
                            } else {
                                newEdgePoints = fromEdgePoints.slice();
                            }
                            newEdgePoints.unshift(group.mp0);
                            newEdgePoints.push(group.mp1);
                            newEdgePoints.unshift(edge.getStartPoint());
                            newEdgePoints.push(edge.getEndPoint());
                            newEdges.push({
                                points: cleanEdgePoints(newEdgePoints, edge.edge.points),
                                rawEdge: edge.edge
                            });
                        }
                    }
                }
            };
            buildNewEdges(res.groups);
            return newEdges;
        },
        _iterate: function (rawEdges) {
            var edges = [];
            var groups = [];
            var totalSavedInk = 0;
            for (var i = 0; i < rawEdges.length; i++) {
                var edge = new Edge(rawEdges[i]);
                edges.push(edge);
            }
            var tree = new KDTree(edges, 4);
            var nearests = [];
            var _mp0 = v2Create();
            var _mp1 = v2Create();
            var _newGroupInk = 0;
            var mp0 = v2Create();
            var mp1 = v2Create();
            var newGroupInk = 0;
            for (var i = 0; i < edges.length; i++) {
                var edge = edges[i];
                if (edge.group) {
                    // Edge have been groupped
                    continue;
                }
                tree.nearestN(
                    edge, this.maxNearestEdge,
                    squaredDistance, nearests
                );
                var maxSavedInk = 0;
                var mostSavingInkEdge = null;
                var lastCheckedGroup = null;
                for (var j = 0; j < nearests.length; j++) {
                    var nearest = nearests[j];
                    var savedInk = 0;
                    if (nearest.group) {
                        if (nearest.group !== lastCheckedGroup) {
                            lastCheckedGroup = nearest.group;
                            _newGroupInk = this._calculateGroupEdgeInk(
                                nearest.group, edge, _mp0, _mp1
                            );
                            savedInk = nearest.group.ink + edge.ink - _newGroupInk;
                        }
                    }
                    else {
                        _newGroupInk = this._calculateEdgeEdgeInk(
                            edge, nearest, _mp0, _mp1
                        );
                        savedInk = nearest.ink + edge.ink - _newGroupInk;
                    }
                    if (savedInk > maxSavedInk) {
                        maxSavedInk = savedInk;
                        mostSavingInkEdge = nearest;
                        v2Copy(mp1, _mp1);
                        v2Copy(mp0, _mp0);
                        newGroupInk = _newGroupInk;
                    }
                }
                if (mostSavingInkEdge) {
                    totalSavedInk += maxSavedInk;
                    var group;
                    if (! mostSavingInkEdge.group) {
                        group = new BundledEdgeGroup();
                        groups.push(group);
                        group.addEdge(mostSavingInkEdge);
                    }
                    group = mostSavingInkEdge.group;
                    // Use the meet point and group ink calculated before
                    v2Copy(group.mp0, mp0);
                    v2Copy(group.mp1, mp1);
                    group.ink = newGroupInk;
                    mostSavingInkEdge.group.addEdge(edge);
                }
                else {
                    var group = new BundledEdgeGroup();
                    groups.push(group);
                    v2Copy(group.mp0, edge.getStartPoint());
                    v2Copy(group.mp1, edge.getEndPoint());
                    group.ink = edge.ink;
                    group.addEdge(edge);
                }
            }
            return {
                groups: groups,
                edges: edges,
                savedInk: totalSavedInk
            };
        },
        _calculateEdgeEdgeInk: (function () {
            var startPointSet = [];
            var endPointSet = [];
            return function (e0, e1, mp0, mp1) {
                startPointSet[0] = e0.getStartPoint();
                startPointSet[1] = e1.getStartPoint();
                endPointSet[0] = e0.getEndPoint();
                endPointSet[1] = e1.getEndPoint();
                this._calculateMeetPoints(
                    startPointSet, endPointSet, mp0, mp1
                );
                var ink = v2Dist(startPointSet[0], mp0)
                    + v2Dist(mp0, mp1)
                    + v2Dist(mp1, endPointSet[0])
                    + v2Dist(startPointSet[1], mp0)
                    + v2Dist(mp1, endPointSet[1]);
                return ink;
            };
        })(),
        _calculateGroupEdgeInk: function (group, edgeTryAdd, mp0, mp1) {
            var startPointSet = [];
            var endPointSet = [];
            for (var i = 0; i < group.edgeList.length; i++) {
                var edge = group.edgeList[i];
                startPointSet.push(edge.getStartPoint());
                endPointSet.push(edge.getEndPoint());
            }
            startPointSet.push(edgeTryAdd.getStartPoint());
            endPointSet.push(edgeTryAdd.getEndPoint());
            this._calculateMeetPoints(
                startPointSet, endPointSet, mp0, mp1
            );
            var ink = v2Dist(mp0, mp1);
            for (var i = 0; i < startPointSet.length; i++) {
                ink += v2Dist(startPointSet[i], mp0)
                    + v2Dist(endPointSet[i], mp1);
            }
            return ink;
        },
        /**
         * Calculating the meet points
         * @method
         * @param {Array} startPointSet Start points set of bundled edges
         * @param {Array} endPointSet End points set of bundled edges
         * @param {Array.<number>} mp0 Output meet point 0
         * @param {Array.<number>} mp1 Output meet point 1
         */
        _calculateMeetPoints: (function () {
            var cp0 = v2Create();
            var cp1 = v2Create();
            return function (startPointSet, endPointSet, mp0, mp1) {
                vec2.set(cp0, 0, 0);
                vec2.set(cp1, 0, 0);
                var len = startPointSet.length;
                // Calculate the centroid of start points set
                for (var i = 0; i < len; i++) {
                    vec2.add(cp0, cp0, startPointSet[i]);
                }
                vec2.scale(cp0, cp0, 1 / len);
                // Calculate the centroid of end points set
                len = endPointSet.length;
                for (var i = 0; i < len; i++) {
                    vec2.add(cp1, cp1, endPointSet[i]);
                }
                vec2.scale(cp1, cp1, 1 / len);
                this._limitTurningAngle(
                    startPointSet, cp0, cp1, mp0
                );
                this._limitTurningAngle(
                    endPointSet, cp1, cp0, mp1
                );
            };
        })(),
        _limitTurningAngle: (function () {
            var v10 = v2Create();
            var vTmp = v2Create();
            var project = v2Create();
            var tmpOut = v2Create();
            return function (pointSet, p0, p1, out) {
                // Limit the max turning angle
                var maxTurningAngleCos = Math.cos(this.maxTurningAngle);
                var maxTurningAngleTan = Math.tan(this.maxTurningAngle);
                vec2.sub(v10, p0, p1);
                vec2.normalize(v10, v10);
                // Simply copy the centroid point if no need to turn the angle
                vec2.copy(out, p0);
                var maxMovement = 0;
                for (var i = 0; i < pointSet.length; i++) {
                    var p = pointSet[i];
                    vec2.sub(vTmp, p, p0);
                    var len = vec2.len(vTmp);
                    vec2.scale(vTmp, vTmp, 1 / len);
                    var turningAngleCos = vec2.dot(vTmp, v10);
                    // Turning angle is to large
                    if (turningAngleCos < maxTurningAngleCos) {
                        // Calculat p's project point on vector p1-p0 
                        // and distance to the vector
                        vec2.scaleAndAdd(
                            project, p0, v10, len * turningAngleCos
                        );
                        var distance = v2Dist(project, p);
                        // Use the max turning angle to calculate the new meet point
                        var d = distance / maxTurningAngleTan;
                        vec2.scaleAndAdd(tmpOut, project, v10, -d);
                        var movement = v2DistSquare(tmpOut, p0);
                        if (movement > maxMovement) {
                            maxMovement = movement;
                            vec2.copy(out, tmpOut);
                        }
                    }
                }
            };
        })()
    };
    return EdgeBundling;
});

+ 248 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/Force.js

@ -0,0 +1,248 @@
/**
 * 力导向布局
 * @module echarts/layout/Force
 * @author pissang(http://github.com/pissang)
 */
define(function(require) {
    var ForceLayoutWorker = require('./forceLayoutWorker');
    var vec2 = require('zrender/tool/vector');
    var requestAnimationFrame = window.requestAnimationFrame
                                || window.msRequestAnimationFrame
                                || window.mozRequestAnimationFrame
                                || window.webkitRequestAnimationFrame
                                || function (func) {setTimeout(func, 16);};
    var ArrayCtor = typeof(Float32Array) == 'undefined' ? Array : Float32Array;
    var workerUrl;
    // function getToken() {
    //     return Math.round((new Date()).getTime() / 100) % 10000000;
    // }
    function createWorkerUrl() {
        if (
            typeof(Worker) !== 'undefined' &&
            typeof(Blob) !== 'undefined'
        ) {
            try {
                var blob = new Blob([ForceLayoutWorker.getWorkerCode()]);
                workerUrl = window.URL.createObjectURL(blob);   
            }
            catch (e) {
                workerUrl = '';
            }
        }
        return workerUrl;
    }
    var ForceLayout = function(opts) {
        if (typeof(workerUrl) === 'undefined') {
            createWorkerUrl();
        }
        opts = opts || {};
        // 配置项
        this.width = opts.width || 500;
        this.height = opts.height || 500;
        this.center = opts.center || [this.width / 2, this.height / 2];
        this.ratioScaling = opts.ratioScaling || false;
        this.scaling = opts.scaling || 1;
        this.gravity = typeof(opts.gravity) !== 'undefined'
                        ? opts.gravity : 1;
        this.large = opts.large || false;
        this.preventNodeOverlap = opts.preventNodeOverlap || false;
        this.preventNodeEdgeOverlap = opts.preventNodeEdgeOverlap || false;
        this.maxSpeedIncrease = opts.maxSpeedIncrease || 1;
        this.onupdate = opts.onupdate || function () {};
        this.temperature = opts.temperature || 1;
        this.coolDown = opts.coolDown || 0.99;
        this._layout = null;
        this._layoutWorker = null;
        var self = this;
        var _$onupdate = this._$onupdate;
        this._$onupdate = function(e) {
            _$onupdate.call(self, e);
        };
    };
    ForceLayout.prototype.updateConfig = function () {
        var width = this.width;
        var height = this.height;
        var size = Math.min(width, height);
        var config = {
            center: this.center,
            width: this.ratioScaling ? width : size,
            height: this.ratioScaling ? height : size,
            scaling: this.scaling || 1.0,
            gravity: this.gravity || 1.0,
            barnesHutOptimize: this.large,
            preventNodeOverlap: this.preventNodeOverlap,
            preventNodeEdgeOverlap: this.preventNodeEdgeOverlap,
            
            maxSpeedIncrease: this.maxSpeedIncrease
        };
        if (this._layoutWorker) {
            this._layoutWorker.postMessage({
                cmd: 'updateConfig',
                config: config
            });
        }
        else {
            for (var name in config) {
                this._layout[name] = config[name];
            }
        }
    };
    ForceLayout.prototype.init = function (graph, useWorker) {
        if (this._layoutWorker) {
            this._layoutWorker.terminate();
            this._layoutWorker = null;
        }
        if (workerUrl && useWorker) {
            try {
                if (!this._layoutWorker) {
                    this._layoutWorker = new Worker(workerUrl);
                    this._layoutWorker.onmessage = this._$onupdate;
                }
                this._layout = null;
            }
            catch (e) {    // IE10-11 will throw security error when using blog url
                this._layoutWorker = null;
                if (!this._layout) {
                    this._layout = new ForceLayoutWorker();
                }
            }
        }
        else {
            if (!this._layout) {
                this._layout = new ForceLayoutWorker();
            }
        }
        this.temperature = 1;
        this.graph = graph;
        // 节点数据
        var len = graph.nodes.length;
        var positionArr = new ArrayCtor(len * 2);
        var massArr = new ArrayCtor(len);
        var sizeArr = new ArrayCtor(len);
        for (var i = 0; i < len; i++) {
            var n = graph.nodes[i];
            positionArr[i * 2] = n.layout.position[0];
            positionArr[i * 2 + 1] = n.layout.position[1];
            massArr[i] = typeof(n.layout.mass) === 'undefined'
                ? 1 : n.layout.mass;
            sizeArr[i] = typeof(n.layout.size) === 'undefined'
                ? 1 : n.layout.size;
            n.layout.__index = i;
        }
        // 边数据
        len = graph.edges.length;
        var edgeArr = new ArrayCtor(len * 2);
        var edgeWeightArr = new ArrayCtor(len);
        for (var i = 0; i < len; i++) {
            var edge = graph.edges[i];
            edgeArr[i * 2] = edge.node1.layout.__index;
            edgeArr[i * 2 + 1] = edge.node2.layout.__index;
            edgeWeightArr[i] = edge.layout.weight || 1;
        }
        if (this._layoutWorker) {
            this._layoutWorker.postMessage({
                cmd: 'init',
                nodesPosition: positionArr,
                nodesMass: massArr,
                nodesSize: sizeArr,
                edges: edgeArr,
                edgesWeight: edgeWeightArr
            });
        }
        else {
            this._layout.initNodes(positionArr, massArr, sizeArr);
            this._layout.initEdges(edgeArr, edgeWeightArr);   
        }
        this.updateConfig();
    };
    ForceLayout.prototype.step = function (steps) {
        var nodes = this.graph.nodes;
        if (this._layoutWorker) {
            // Sync back
            var positionArr = new ArrayCtor(nodes.length * 2);
            for (var i = 0; i < nodes.length; i++) {
                var n = nodes[i];
                positionArr[i * 2] = n.layout.position[0];
                positionArr[i * 2 + 1] = n.layout.position[1];
            }
            this._layoutWorker.postMessage(positionArr.buffer, [positionArr.buffer]);
            this._layoutWorker.postMessage({
                cmd: 'update',
                steps: steps,
                temperature: this.temperature,
                coolDown: this.coolDown
            });
            for (var i = 0; i < steps; i++) {
                this.temperature *= this.coolDown;
            }
        }
        else {
            
            requestAnimationFrame(this._$onupdate);
            for (var i = 0; i < nodes.length; i++) {
                var n = nodes[i];
                vec2.copy(this._layout.nodes[i].position, n.layout.position);
            }
            for (var i = 0; i < steps; i++) {
                this._layout.temperature = this.temperature;
                this._layout.update();
                this.temperature *= this.coolDown;
            }
        }
    };
    ForceLayout.prototype._$onupdate = function (e) {
        if (this._layoutWorker) {
            var positionArr = new Float32Array(e.data);
            for (var i = 0; i < this.graph.nodes.length; i++) {
                var n = this.graph.nodes[i];
                n.layout.position[0] = positionArr[i * 2];
                n.layout.position[1] = positionArr[i * 2 + 1];
            }
            this.onupdate && this.onupdate();
        }
        else if (this._layout) {
            for (var i = 0; i < this.graph.nodes.length; i++) {
                var n = this.graph.nodes[i];
                vec2.copy(n.layout.position, this._layout.nodes[i].position);
            }
            this.onupdate && this.onupdate();
        }
    };
    ForceLayout.prototype.dispose = function() {
        if (this._layoutWorker) {
            this._layoutWorker.terminate();
        }
        this._layoutWorker = null;
        this._layout = null;
    };
    return ForceLayout;
});

+ 90 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/Tree.js

@ -0,0 +1,90 @@
/**
 * Tree layout
 * @module echarts/layout/Tree
 * @author pissang(http://github.com/pissang)
 */
define(function (require) {
    var vec2 = require('zrender/tool/vector');
    function TreeLayout(opts) {
        opts = opts || {};
        this.nodePadding = opts.nodePadding || 30;
        this.layerPadding = opts.layerPadding || 100;
        this._layerOffsets = [];
        this._layers = [];
    }
    TreeLayout.prototype.run = function (tree) {
        this._layerOffsets.length = 0;
        for (var i = 0; i < tree.root.height + 1; i++) {
            this._layerOffsets[i] = 0;
            this._layers[i] = [];
        }
        this._updateNodeXPosition(tree.root);
        var root = tree.root;
        this._updateNodeYPosition(root, 0, root.layout.height);
    };
    TreeLayout.prototype._updateNodeXPosition = function (node) {
        var minX = Infinity;
        var maxX = -Infinity;
        node.layout.position = node.layout.position || vec2.create();
        for (var i = 0; i < node.children.length; i++) {
            var child = node.children[i];
            this._updateNodeXPosition(child);
            var x = child.layout.position[0];
            if (x < minX) {
                minX = x;
            }
            if (x > maxX) {
                maxX = x;
            }
        }
        if (node.children.length > 0) {
            node.layout.position[0] = (minX + maxX) / 2;
        } else {
            node.layout.position[0] = 0;
        }
        var off = this._layerOffsets[node.depth] || 0;
        if (off > node.layout.position[0]) {
            var shift = off - node.layout.position[0];
            this._shiftSubtree(node, shift);
            for (var i = node.depth + 1; i < node.height + node.depth; i++) {
                this._layerOffsets[i] += shift;
            }
        }
        this._layerOffsets[node.depth] = node.layout.position[0] + node.layout.width + this.nodePadding;
        this._layers[node.depth].push(node);
    };
    TreeLayout.prototype._shiftSubtree = function (root, offset) {
        root.layout.position[0] += offset;
        for (var i = 0; i < root.children.length; i++) {
            this._shiftSubtree(root.children[i], offset);
        }
    };
    TreeLayout.prototype._updateNodeYPosition = function (node, y, prevLayerHeight) {
        node.layout.position[1] = y;
        var layerHeight = 0;
        for (var i = 0; i < node.children.length; i++) {
            layerHeight = Math.max(node.children[i].layout.height, layerHeight);
        }
        var layerPadding = this.layerPadding;
        if (typeof(layerPadding) === 'function') {
            layerPadding = layerPadding(node.depth);
        }
        for (var i = 0; i < node.children.length; i++) {
            this._updateNodeYPosition(node.children[i], y + layerPadding + prevLayerHeight, layerHeight);
        }
    };
    return TreeLayout;
});

+ 202 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/TreeMap.js

@ -0,0 +1,202 @@
/**
 * TreeMap layout
 * @module echarts/layout/TreeMap
 * @author loutongbing(loutongbing@126.com)
 */
define(function (require) {
    function TreeMapLayout(opts) {
        /**
         * areas 每个子矩形面积
         * x 父矩形横坐标
         * y 父矩形横坐标
         * width 父矩形宽
         * height 父矩形高
        */
        var row = {
            x: opts.x,
            y: opts.y,
            width: opts.width,
            height: opts.height
        };
        this.x = opts.x;
        this.y = opts.y;
        this.width = opts.width;
        this.height = opts.height;
    }
    TreeMapLayout.prototype.run = function (areas) {
        var out = [];
        this._squarify(areas, {
            x: this.x,
            y: this.y,
            width: this.width,
            height: this.height
        }, out);
        return out;
    };
    TreeMapLayout.prototype._squarify = function (areas, row, out) {
        var layoutDirection = 'VERTICAL';
        var width = row.width;
        var height = row.height;
        if (row.width < row.height) {
            layoutDirection = 'HORIZONTAL';
            width = row.height;
            height = row.width;
        }
        // 把考虑方向与位置的因素剥离出来,只考虑怎么排列,运行完毕之后再修正
        var shapeArr = this._getShapeListInAbstractRow(
            areas, width, height
        );
        // 首先换算出虚拟的x、y坐标
        for (var i = 0; i < shapeArr.length; i++) {
            shapeArr[i].x = 0;
            shapeArr[i].y = 0;
            for (var j = 0; j < i; j++) {
                shapeArr[i].y += shapeArr[j].height;
            }
        }
        var nextRow = {};
        // 根据虚拟的shapeArr计算真实的小矩形
        if (layoutDirection == 'VERTICAL') {
            for (var k = 0; k < shapeArr.length; k++) {
                out.push(
                    {
                        x: shapeArr[k].x + row.x,
                        y: shapeArr[k].y + row.y,
                        width: shapeArr[k].width,
                        height: shapeArr[k].height
                    }
                );
            }
            nextRow = {
                x: shapeArr[0].width + row.x,
                y: row.y,
                width: row.width - shapeArr[0].width,
                height: row.height
            };
        }
        else {
            for (var l = 0; l < shapeArr.length; l++) {
                out.push(
                    {
                        x: shapeArr[l].y + row.x,
                        y: shapeArr[l].x + row.y,
                        width: shapeArr[l].height,
                        height: shapeArr[l].width
                    }
                );
            }
            nextRow = {
                x: row.x,
                y: row.y + shapeArr[0].width,  // 注意是虚拟形状下的width
                width: row.width,
                height: row.height - shapeArr[0].width // 注意是虚拟形状下的width
            };
        }
        // 下一步的矩形数组要剔除已经填充过的矩形
        var nextAreaArr = areas.slice(shapeArr.length);
        if (nextAreaArr.length === 0) {
            return;
        }
        else {
            this._squarify(
                nextAreaArr,
                nextRow,
                out
            );
        }
    };
    TreeMapLayout.prototype._getShapeListInAbstractRow = function (
        areas,
        width,
        height
    ) {
        // 如果只剩下一个了,直接返回
        if (areas.length === 1) {
            return [
                {
                    width: width,
                    height: height
                }
            ];
        }
        // 填充进入的个数,从填充一个开始到填充所有小矩形,
        // 纵横比最优时break并保留结果
        for (var count = 1; count < areas.length; count++) {
            var shapeArr0 = this._placeFixedNumberRectangles(
                areas.slice(0, count),
                width,
                height
            );
            var shapeArr1 = this._placeFixedNumberRectangles(
                areas.slice(0, count + 1),
                width,
                height
            );
            if (this._isFirstBetter(shapeArr0, shapeArr1)) {
                return shapeArr0;
            }
        }
    };
    // 确定数量进行填充
    TreeMapLayout.prototype._placeFixedNumberRectangles = function (
        areaSubArr,
        width,
        height
    ) {
        var count = areaSubArr.length;
        // 声明返回值-每个矩形的形状(长宽)之数组
        // 例如:
        /*[
            {
                width: 11
                height: 12
            },
            {
                width: 11
                height: 22
            }
        ]*/
        var shapeArr = [];
        // 求出面积总和
        var sum = 0;
        for (var i = 0; i < areaSubArr.length; i++) {
            sum += areaSubArr[i];
        }
        var cellWidth = sum / height;
        for (var j = 0; j < count; j++) {
            var cellHeight = height * areaSubArr[j] / sum;
            shapeArr.push(
                {
                    width: cellWidth,
                    height: cellHeight
                }
            );
        }
        return shapeArr;
    };
    // 相邻的两种填充方式放进去,比较是不是前一个的纵横比较小
    TreeMapLayout.prototype._isFirstBetter = function (
        shapeArr0,
        shapeArr1
    ) {
        var ratio0 = shapeArr0[0].height / shapeArr0[0].width;
        ratio0 = (ratio0 > 1) ? 1 / ratio0 : ratio0;
        var ratio1 =  shapeArr1[0].height / shapeArr1[0].width;
        ratio1 = (ratio1 > 1) ? 1 / ratio1 : ratio1;
        if (Math.abs(ratio0 - 1) <= Math.abs(ratio1 - 1)) {
            return true;
        }
        return false;
    };
    return TreeMapLayout;
});

+ 692 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/WordCloud.js

@ -0,0 +1,692 @@
/**
 * @author clmtulip(车丽美, clmtulip@gmail.com) liyong(liyong1239@163.com)
 */
// Modified from d3-cloud
/*
Copyright (c) 2013, Jason Davies.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.
  * The name Jason Davies may not be used to endorse or promote products
    derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL JASON DAVIES BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
define(function (require) {
    var ZeroArray = require('../layout/WordCloudRectZero');
    var zrUtil = require('zrender/tool/util');
    function CloudLayout(option) {
        this._init(option);
    }
    CloudLayout.prototype = {
        /**
         * 启动计算过程
         */
        start: function () {
            var board = null;
            var maxWit = 0;
            var maxHit = 0;
            var maxArea = 0;
            var i = -1;
            var tags = [];
            var maxBounds = null; /*图片的最大可用边框*/
            // 根据配置 初始化 字符云数组
            var data = this.wordsdata;
            var dfop = this.defaultOption;
            var wordletype = dfop.wordletype;
            var size = dfop.size;
            var that = this;
            //得到 ZeroArray 传递过来的 初始值 和面积 最大宽度等值
            var zeroArrayObj = new ZeroArray({
                type: wordletype.type,
                width: size[0],
                height: size[1]
            });
            zeroArrayObj.calculate(function (options) {
                board = options.initarr;
                maxWit = options.maxWit;
                maxHit = options.maxHit;
                maxArea = options.area;
                maxBounds = options.imgboard;
                startStep();
            }, this);
            return this;
            function startStep() {
                that.totalArea = maxArea;
                //字体大小的确定,可配置,根据开关 确定是否要根据面积来定。。
                if (wordletype.autoSizeCal.enable) {
                    that._autoCalTextSize(data, maxArea, maxWit, maxHit, wordletype.autoSizeCal.minSize);
                }
                if (dfop.timer) {
                    clearInterval(dfop.timer);
                }
                dfop.timer = setInterval(step, 0);
                step();
            }
            function step() {
                var start = +new Date;
                var n = data.length;
                var d;
                while (+new Date - start < dfop.timeInterval && ++i < n && dfop.timer) {
                    d = data[i];
                    // x y 的初始值
                    d.x = size[0] >> 1;
                    d.y = size[1] >> 1;
                    //得到每个 标签所占用的具体的像素点 用 0 1 标记, 每32位作为一个数字
                    that._cloudSprite(d, data, i);
                    //place 放置每个字符, 成功后 以 event 事件通知
                    if (d.hasText && that._place(board, d, maxBounds)) {
                        tags.push(d);
                        //                        event.word(d);
                        // Temporary hack
                        d.x -= size[0] >> 1;
                        d.y -= size[1] >> 1;
                    }
                }
                //全部放置完成 停止cloud,并触发 'end'事件
                if (i >= n) {
                    that.stop();
                    that._fixTagPosition(tags);
                    dfop.endcallback(tags);
                }
            }
        },
        _fixTagPosition: function (tags) {
            var center = this.defaultOption.center;
            for (var i = 0, len = tags.length; i < len; i++) {
                tags[i].x += center[0];
                tags[i].y += center[1];
            }
        },
        /**
         * 停止计算过程
         */
        stop: function () {
            if (this.defaultOption.timer) {
                clearInterval(this.defaultOption.timer);
                this.defaultOption.timer = null;
            }
            return this;
        },
        /**
         * 计算结束后 执行V
         * @param v
         */
        end: function (v) {
            if (v) {
                this.defaultOption.endcallback = v;
            }
            return this;
        },
        /**
         * 初始化
         * @param option
         * @private
         */
        _init: function (option) {
            this.defaultOption = {};
            /*初始化属性*/
            this._initProperty(option);
            /*初始化方法*/
            this._initMethod(option);
            /*初始化 canvas 画板*/
            this._initCanvas();
            /*初始化数据*/
            this._initData(option.data);
        },
        _initData: function (datas) {
            var that = this;
            var thatop = that.defaultOption;
            this.wordsdata = datas.map(function (d, i) {
                d.text = thatop.text.call(that, d, i);
                d.font = thatop.font.call(that, d, i);
                d.style = thatop.fontStyle.call(that, d, i);
                d.weight = thatop.fontWeight.call(that, d, i);
                // 字体的旋转角度
                d.rotate = thatop.rotate.call(that, d, i);
                // 字体的大小 单位px
                d.size = ~~thatop.fontSize.call(that, d, i);
                // 字体间的间距
                d.padding = thatop.padding.call(that, d, i);
                return d;
            }).sort(function (a, b) {
                return b.value - a.value;
            });
        },
        /**
         * 默认函数的定义 及初始化过程
         * @private
         */
        _initMethod: function (option) {
            /*数据初始化中要用到的函数*/
            var dfop = this.defaultOption;
            dfop.text = (option.text) ? functor(option.text) : cloudText;
            dfop.font = (option.font) ? functor(option.font) : cloudFont;
            dfop.fontSize = (option.fontSize) ? functor(option.fontSize) : cloudFontSize;
            dfop.fontStyle = (option.fontStyle) ? functor(option.fontStyle) : cloudFontNormal;
            dfop.fontWeight = (option.fontWeight) ? functor(option.fontWeight) : cloudFontNormal;
            dfop.rotate = (option.rotate) ? newCloudRotate(option.rotate) : cloudRotate;
            dfop.padding = (option.padding) ? functor(option.padding) : cloudPadding;
            dfop.center = option.center;
            /*其它函数*/
            dfop.spiral = archimedeanSpiral;
            dfop.endcallback = function () {
            };
            dfop.rectangularSpiral = rectangularSpiral;
            dfop.archimedeanSpiral = archimedeanSpiral;
            function cloudText(d) {
                return d.name;
            }
            function cloudFont() {
                return "sans-serif";
            }
            function cloudFontNormal() {
                return "normal";
            }
            function cloudFontSize(d) {
                return d.value;
            }
            function cloudRotate() {
                return 0;
            }
            function newCloudRotate(rotate) {
                return function () {
                    return rotate[Math.round(Math.random() * (rotate.length - 1))]
                }
            }
            function cloudPadding() {
                return 0;
            }
            function archimedeanSpiral(size) {
                var e = size[0] / size[1];
                return function (t) {
                    return [
                            e * (t *= .1) * Math.cos(t),
                            t * Math.sin(t)
                    ];
                };
            }
            function rectangularSpiral(size) {
                var dy = 4;
                var dx = dy * size[0] / size[1];
                var x = 0;
                var y = 0;
                return function (t) {
                    var sign = t < 0 ? -1 : 1;
                    // See triangular numbers: T_n = n * (n + 1) / 2.
                    switch ((Math.sqrt(1 + 4 * sign * t) - sign) & 3) {
                        case 0:
                            x += dx;
                            break;
                        case 1:
                            y += dy;
                            break;
                        case 2:
                            x -= dx;
                            break;
                        default:
                            y -= dy;
                            break;
                    }
                    return [
                        x,
                        y
                    ];
                };
            }
            function functor(v) {
                return typeof v === "function" ? v : function () {
                    return v;
                };
            }
        },
        _initProperty: function (option) {
            var dfop = this.defaultOption;
            //默认值
            dfop.size = option.size || [
                256,
                256
            ];
            dfop.wordletype = option.wordletype;
            dfop.words = option.words || [];
            dfop.timeInterval = Infinity;
            dfop.timer = null;
            dfop.spirals = {
                archimedean: dfop.archimedeanSpiral,
                rectangular: dfop.rectangularSpiral
            };
            zrUtil.merge(dfop, {
                size: [
                    256,
                    256
                ],
                wordletype: {
                    type: 'RECT',
                    areaPresent: .058,
                    autoSizeCal: {
                        enable: true,
                        minSize: 12
                    }
                }
            });
        },
        _initCanvas: function () {
            var cloudRadians = Math.PI / 180;
            var cw = 1 << 11 >> 5;
            var ch = 1 << 11;
            var canvas;
            var ratio = 1;
            if (typeof document !== "undefined") {
                canvas = document.createElement("canvas");
                canvas.width = 1;
                canvas.height = 1;
                ratio = Math.sqrt(
                    canvas.getContext("2d")
                        .getImageData(0, 0, 1, 1)
                        .data.length >> 2
                );
                canvas.width = (cw << 5) / ratio;
                canvas.height = ch / ratio;
            }
            else {
                // Attempt to use node-canvas.
                canvas = new Canvas(cw << 5, ch);
            }
            var c = canvas.getContext("2d");
            c.fillStyle = c.strokeStyle = "red";
            c.textAlign = "center";
            this.defaultOption.c = c;
            this.defaultOption.cw = cw;
            this.defaultOption.ch = ch;
            this.defaultOption.ratio = ratio;
            this.defaultOption.cloudRadians = cloudRadians;
        },
        _cloudSprite: function (d, data, di) {
            if (d.sprite) {
                return;
            }
            var cw = this.defaultOption.cw;
            var ch = this.defaultOption.ch;
            var c = this.defaultOption.c;
            var ratio = this.defaultOption.ratio;
            var cloudRadians = this.defaultOption.cloudRadians;
            c.clearRect(0, 0, (cw << 5) / ratio, ch / ratio);
            var x = 0;
            var y = 0;
            var maxh = 0;
            var n = data.length;
            --di;
            while (++di < n) {
                d = data[di];
                c.save();
                c.font = d.style + " " + d.weight + " " + ~~((d.size + 1) / ratio) + "px " + d.font;
                //得到 字体 实际的 宽和高
                var w = c.measureText(d.text + "m").width * ratio;
                var h = d.size << 1;
                //得到 d 所占用的具体的宽度 和高度  并取整
                if (d.rotate) {
                    var sr = Math.sin(d.rotate * cloudRadians);
                    var cr = Math.cos(d.rotate * cloudRadians);
                    var wcr = w * cr;
                    var wsr = w * sr;
                    var hcr = h * cr;
                    var hsr = h * sr;
                    w = (Math.max(Math.abs(wcr + hsr), Math.abs(wcr - hsr)) + 0x1f) >> 5 << 5;
                    h = ~~Math.max(Math.abs(wsr + hcr), Math.abs(wsr - hcr));
                }
                else {
                    w = (w + 0x1f) >> 5 << 5;
                }
                if (h > maxh) {
                    maxh = h;
                }
                //如果 字体 超出了 宽度 换更远的一行。。。
                if (x + w >= (cw << 5)) {
                    x = 0;
                    y += maxh;
                    maxh = 0;
                }
                if (y + h >= ch) {
                    break;
                }
                c.translate((x + (w >> 1)) / ratio, (y + (h >> 1)) / ratio);
                if (d.rotate) {
                    c.rotate(d.rotate * cloudRadians);
                }
                c.fillText(d.text, 0, 0);
                if (d.padding) {
                    c.lineWidth = 2 * d.padding;
                    c.strokeText(d.text, 0, 0);
                }
                c.restore();
                d.width = w;
                d.height = h;
                // xoff  yoff 为 d在画板中的坐标位置
                d.xoff = x;
                d.yoff = y;
                d.x1 = w >> 1;
                d.y1 = h >> 1;
                d.x0 = -d.x1;
                d.y0 = -d.y1;
                d.hasText = true;
                x += w;
            }
            //得到 所在 区域的 像素值。。进而 确定 其 y的位置。。。
            var pixels = c.getImageData(0, 0, (cw << 5) / ratio, ch / ratio).data;
            var sprite = [];
            while (--di >= 0) {
                d = data[di];
                if (!d.hasText) {
                    continue;
                }
                var w = d.width;
                var w32 = w >> 5;
                var h = d.y1 - d.y0;
                // Zero the buffer
                for (var i = 0; i < h * w32; i++) {
                    sprite[i] = 0;
                }
                x = d.xoff;
                if (x == null) {
                    return;
                }
                y = d.yoff;
                var seen = 0;
                var seenRow = -1;
                for (var j = 0; j < h; j++) {
                    for (var i = 0; i < w; i++) {
                        var k = w32 * j + (i >> 5);
                        var m = pixels[((y + j) * (cw << 5) + (x + i)) << 2] ? 1 << (31 - (i % 32)) : 0;
                        sprite[k] |= m;
                        seen |= m;
                    }
                    if (seen) {
                        seenRow = j;
                    }
                    else {
                        d.y0++;
                        h--;
                        j--;
                        y++;
                    }
                }
                d.y1 = d.y0 + seenRow;
                d.sprite = sprite.slice(0, (d.y1 - d.y0) * w32);
            }
        },
        _place: function (board, tag, maxBounds) {
            /*判断目前面积总值 是否超过了阈值*/
            /*判断目前该值是否能够放的下*/
            var size = this.defaultOption.size;
            var perimeter = [
                    {x: 0, y: 0},
                    {x: size[0], y: size[1]}
                ];
            var startX = tag.x;
            var startY = tag.y;
            var maxDelta = Math.sqrt(size[0] * size[0] + size[1] * size[1]);
            var s = this.defaultOption.spiral(size);
            var dt = Math.random() < .5 ? 1 : -1;
            var t = -dt;
            var dxdy;
            var dx;
            var dy;
            while (dxdy = s(t += dt)) {
                dx = ~~dxdy[0];
                dy = ~~dxdy[1];
                //当dx dy 都大于 maxDelta 即超出了 画板范围, 停止 放置。。 该值舍弃
                if (Math.min(dx, dy) > maxDelta) {
                    break;
                }
                tag.x = startX + dx;
                tag.y = startY + dy;
                if (tag.x + tag.x0 < 0 || tag.y + tag.y0 < 0 ||
                    tag.x + tag.x1 > size[0] || tag.y + tag.y1 > size[1]) {
                    continue;
                }
                // TODO only check for collisions within current bounds.
                if (!cloudCollide(tag, board, size[0])) {
                    if (collideRects(tag, maxBounds)) {
                        var sprite = tag.sprite;
                        var w = tag.width >> 5;
                        var sw = size[0] >> 5;
                        var lx = tag.x - (w << 4);
                        var sx = lx & 0x7f;
                        var msx = 32 - sx;
                        var h = tag.y1 - tag.y0;
                        var x = (tag.y + tag.y0) * sw + (lx >> 5);// 计算其在画板的 横坐标的位置
                        var last;
                        //当 该 字能够被正确放置时, 根据该字体的范围 更改标志位范围
                        for (var j = 0; j < h; j++) {
                            last = 0;
                            for (var i = 0; i <= w; i++) {
                                board[x + i] |= (last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0);
                            }
                            x += sw;
                        }
                        delete tag.sprite;
                        return true;
                    }
                }
            }
            return false;
            function cloudCollide(tag, board, sw) {
                sw >>= 5;
                var sprite = tag.sprite;
                var w = tag.width >> 5;
                var lx = tag.x - (w << 4);
                var sx = lx & 0x7f;
                var msx = 32 - sx;
                var h = tag.y1 - tag.y0;
                var x = (tag.y + tag.y0) * sw + (lx >> 5);
                var last;
                for (var j = 0; j < h; j++) {
                    last = 0;
                    for (var i = 0; i <= w; i++) {
                        if (((last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0))
                            & board[x + i]) {
                            return true;
                        }
                    }
                    x += sw;
                }
                return false;
            }
            function collideRects(a, maxBounds) {
                return maxBounds.row[a.y] && maxBounds.cloumn[a.x]
                    && a.x >= maxBounds.row[a.y].start
                    && a.x <= maxBounds.row[a.y].end
                    && a.y >= maxBounds.cloumn[a.x].start
                    && a.y <= maxBounds.cloumn[a.x].end;
            }
        },
        _autoCalTextSize: function (data, shapeArea, maxwidth, maxheight, minSize) {
            //循环
            //面积 归一化
            //计算 每个字体的面积
            var sizesum = sum(data, function (k) {
                    return k.size;
                });
            var i = data.length;
            var maxareapre = .25; /*面积归一化后, 字体占总面积的最大百分比*/
            var minTextSize = minSize; /*字体所能缩放的最小大小。。如果字体面积 依旧无法满足上述约束, 字体将不会再缩小*/
            var cw = this.defaultOption.cw;
            var ch = this.defaultOption.ch;
            var c = this.defaultOption.c;
            var ratio = this.defaultOption.ratio;
            var cloudRadians = this.defaultOption.cloudRadians;
            var d;
            var dpre;
            while (i--) {
                d = data[i];
                dpre = d.size / sizesum;
                if (maxareapre) {
                    d.areapre = (dpre < maxareapre) ? dpre : maxareapre;
                }
                else {
                    d.areapre = dpre;
                }
                d.area = shapeArea * d.areapre;
                d.totalarea = shapeArea;
                measureTextWitHitByarea(d);
            }
            //根据面积 计算字体的 size
            //根据 最大宽度 和最大高度 重新检测 字体的size, 不符合条件 重新计算,若字体大小已经是 最小size,则 取消计算。。。
            function measureTextWitHitByarea(d) {
                c.clearRect(0, 0, (cw << 5) / ratio, ch / ratio);
                c.save();
                c.font = d.style + " " + d.weight + " " + ~~((d.size + 1) / ratio) + "px " + d.font;
                //得到 字体 实际的 宽和高
                var w = c.measureText(d.text + "m").width * ratio,
                    h = d.size << 1;
                //得到 d 所占用的具体的宽度 和高度  并取整
                w = (w + 0x1f) >> 5 << 5; //给定了一个最小值 1 即不会存在 宽度为0的情况
                c.restore();
                d.aw = w;
                d.ah = h;
                var k, rw, rh;
                //如果 有旋转  测试 旋转后的 宽和高 是否 超过了 最大的大小
                if (d.rotate) {
                    var sr = Math.sin(d.rotate * cloudRadians);
                    var cr = Math.cos(d.rotate * cloudRadians);
                    var wcr = w * cr;
                    var wsr = w * sr;
                    var hcr = h * cr;
                    var hsr = h * sr;
                    rw = (Math.max(Math.abs(wcr + hsr), Math.abs(wcr - hsr)) + 0x1f) >> 5 << 5;
                    rh = ~~Math.max(Math.abs(wsr + hcr), Math.abs(wsr - hcr));
                }
                //满足条件 不用继续调整的
                // size 为 最小, 或者面积在允许范围内 且 宽和高也在允许范围内
                if ((d.size <= minTextSize)
                    || (d.rotate && w * h <= d.area && rw <= maxwidth && rh <= maxheight)
                    || (w * h <= d.area && w <= maxwidth && h <= maxheight)) {
                    d.area = w * h;
                    return;
                }
                //如果 超过了 最大宽度 或最大高度。。 继续计算
                if (d.rotate && rw > maxwidth && rh > maxheight) {// 有旋转时,超过了 最大宽度和最大高度
                    k = Math.min(maxwidth / rw, maxheight / rh);
                }
                else if (w > maxwidth || h > maxheight) {// 无旋转时,超过了 最大宽度和最大高度
                    k = Math.min(maxwidth / w, maxheight / h);
                }
                else {                                // 当前 面积 大于 规定的面积时
                    k = Math.sqrt(d.area / (d.aw * d.ah));
                }
                d.size = ~~(k * d.size);
                if (d.size < minSize) {
                    d.size = minSize;
                    return;
                }
                return measureTextWitHitByarea(d);
            }
            function sum(dts, callback) {
                var j = dts.length;
                var ressum = 0;
                while (j--) {
                    ressum += callback(dts[j]);
                }
                return ressum;
            }
        }
    };
    return CloudLayout;
});

+ 123 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/WordCloudRectZero.js

@ -0,0 +1,123 @@
/**
 * @file    主要功能
 * @author  clmtulip(车丽美, clmtulip@gmail.com) liyong(liyong1239@163.com)
 */
define(function (require) {
    function ZeroArray(option) {
        this.defaultOption = {type: 'RECT'};
        this._init(option);
    }
    ZeroArray.prototype = {
        RECT: '_calculateRect',
        _init: function (option) {
            this._initOption(option);
            this._initCanvas();
        },
        _initOption: function (option) {
            for (k in option) {
                this.defaultOption[k] = option[k];
            }
        },
        _initCanvas: function () {
            var canvas = document.createElement("canvas");
            canvas.width = 1;
            canvas.height = 1;
            var ratio = Math.sqrt(canvas.getContext("2d").getImageData(0, 0, 1, 1).data.length >> 2);
            canvas.width = this.defaultOption.width;
            canvas.height = this.defaultOption.height;
            if (canvas.getContext) {
                var ctx = canvas.getContext('2d');
            }
            this.canvas = canvas;
            this.ctx = ctx;
            this.ratio = ratio;
        },
        /**执行计算, 并返回
         *
         * @param callback
         * 返回 {initarr, area, maxHit, maxWit} 给callback
         */
        calculate: function (callback, callbackObj) {
            var calType = this.defaultOption.type,
                calmethod = this[calType];
            this[calmethod].call(this, callback, callbackObj);
        },
        /**
         * callback 函数的 正确执行
         * @param result 计算后的结果,{initarr, area, maxHit, maxWit}
         * @param callback  计算成功之后的回调函数
         * @param callbackObj 回调函数的执行作用域
         * @private
         */
        _calculateReturn: function (result, callback, callbackObj) {
            callback.call(callbackObj, result);
        },
        _calculateRect: function (callback, callbackObj) {
            var result = {},
                width = this.defaultOption.width >> 5 << 5,
                height = this.defaultOption.height;
            // 初始化数组
            result.initarr = this._rectZeroArray(width * height);
            // 总面积
            result.area = width * height;
            // 最大高度
            result.maxHit = height;
            // 最大宽度
            result.maxWit = width;
            // 边界
            result.imgboard = this._rectBoard(width, height);
            this._calculateReturn(result, callback, callbackObj);
        },
        _rectBoard: function (width, height) {
            var row = [];
            for (var i = 0; i < height; i++) {
                row.push({
                    y: i,
                    start: 0,
                    end: width
                })
            }
            var cloumn = [];
            for (var i = 0; i < width; i++) {
                cloumn.push({
                    x: i,
                    start: 0,
                    end: height
                })
            }
            return {row: row, cloumn: cloumn};
        },
        _rectZeroArray: function (num) {
            var a = [],
                n = num,
                i = -1;
            while (++i < n) a[i] = 0;
            return a;
        }
    };
    return ZeroArray;
});

+ 262 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/eventRiver.js

@ -0,0 +1,262 @@
/**
 * eventRiver 布局算法
 * @module echarts/layout/eventRiver
 * @author clmtulip  (车丽美, clmtulip@gmail.com)
 */
define(function(require) {
    function eventRiverLayout(series, intervalX, area) {
        var space = 4;
        var scale = intervalX;
        function importanceSort(a, b) {
            var x = a.importance;
            var y = b.importance;
            return ((x > y) ? -1 : ((x < y) ? 1 : 0));
        }
        /**
         * 查询数组中元素的index
         */
        function indexOf(array, value) {
            if (array.indexOf) {
                return array.indexOf(value);
            }
            for (var i = 0, len = array.length; i < len; i++) {
                if (array[i] === value) {
                    return i;
                }
            }
            return -1;
        }
        // step 0. calculate event importance and sort descending
        for (var i = 0; i < series.length; i++) {
            for (var j = 0; j < series[i].data.length; j++) {
                if (series[i].data[j].weight == null) {
                    series[i].data[j].weight = 1;
                }
                var importance = 0;
                for (var k = 0; k < series[i].data[j].evolution.length; k++) {
                    importance += series[i].data[j].evolution[k].valueScale;
                }
                series[i].data[j].importance = importance * series[i].data[j].weight;
            }
            series[i].data.sort(importanceSort);
        }
        // step 1. 计算每个group的重要值importance,并按递减顺序排序
        for (var i = 0; i < series.length; i++) {
            if (series[i].weight == null) {
                series[i].weight = 1;
            }
            var importance = 0;
            for (var j = 0; j < series[i].data.length; j++) {
                importance += series[i].data[j].weight;
            }
            series[i].importance = importance * series[i].weight;
        }
        // 根据importance对groups进行递减排序
        series.sort(importanceSort);
        // step 3. set bubble positions in group order, then in event order
        // 找到包含所有事件的时间段,即最小和最大时间点
        var minTime = Number.MAX_VALUE;
        var maxTime = 0;
        for (var i = 0; i < series.length; i++) {
            for (var j = 0; j < series[i].data.length; j++) {
                for (var k = 0; k < series[i].data[j].evolution.length; k++) {
                    var time = series[i].data[j].evolution[k].timeScale;
                    minTime = Math.min(minTime, time);
                    maxTime = Math.max(maxTime, time);
                }
            }
        }
        //console.log('minTime: ' + minTime);
        //console.log('maxTime: ' + maxTime);
        // 时间范围 即 x轴显示的起始范围
        minTime = ~~minTime;
        maxTime = ~~maxTime;
        // 气泡之间的间隙
        var flagForOffset = (function () {
            var length = maxTime - minTime + 1 + (~~intervalX);
            if (length <= 0){
                return [0];
            }
            var result = [];
            while (length--){
                result.push(0);
            }
            return result;
        })();
        var flagForPos = flagForOffset.slice(0);
        var bubbleData = [];
        var totalMaxy = 0;
        var totalOffset = 0;
        for (var i = 0; i < series.length; i++) {
            for (var j = 0; j < series[i].data.length; j++) {
                var e = series[i].data[j];
                e.time = [];
                e.value = [];
                var tmp;
                var maxy = 0;
                for (var k = 0; k < series[i].data[j].evolution.length; k++) {
                    tmp = series[i].data[j].evolution[k];
                    e.time.push(tmp.timeScale);
                    e.value.push(tmp.valueScale);
                    maxy = Math.max(maxy, tmp.valueScale);
                }
                // 边界计算
                bubbleBound(e, intervalX, minTime);
                // 得到可以放置的位置
                e.y = findLocation(flagForPos, e, function (e, index){return e.ypx[index];});
                // 得到偏移量
                e._offset = findLocation(flagForOffset, e, function (){ return space;});
                totalMaxy = Math.max(totalMaxy, e.y + maxy);
                totalOffset = Math.max(totalOffset, e._offset);
                bubbleData.push(e);
            }
        }
        // 映射到显示区域内
        scaleY(bubbleData, area, totalMaxy, totalOffset);
    }
    /**
     * 映射到显示区域内
     */
    function scaleY(bubbleData, area, maxY, offset) {
        var height = area.height;
        var offsetScale = offset / height > 0.5 ? 0.5 : 1;
        var yBase = area.y;
        var yScale = (area.height - offset) / maxY;
        for (var i = 0, length = bubbleData.length; i < length; i++){
            var e = bubbleData[i];
            e.y = yBase + yScale * e.y + e._offset * offsetScale;
            delete e.time;
            delete e.value;
            delete e.xpx;
            delete e.ypx;
            delete e._offset;
            // 修改值域范围
            var evolutionList = e.evolution;
            for (var k = 0, klen = evolutionList.length; k < klen; k++) {
                evolutionList[k].valueScale *= yScale;
            }
        }
    }
    /**
     * 得到两点式的方程函数 y = k*x + b
     * @param {number} x0 起点横坐标
     * @param {number} y0 起点纵坐标
     * @param {number} x1 终点横坐标
     * @param {number} y1 终点纵坐标
     * @returns {Function} 输入为横坐标 返回纵坐标s
     */
    function line(x0, y0, x1, y1){
        // 横坐标相同,应该抛出错误
        if (x0 === x1) {
            throw new Error('x0 is equal with x1!!!');
        }
        // 纵坐标相同
        if (y0 === y1) {
            return function () {
                return y0;
            }
        }
        var k = (y0 - y1) / (x0 - x1);
        var b = (y1 * x0 - y0 * x1) / (x0 - x1);
        return function (x) {
            return k * x + b;
        }
    }
    /**
     * 计算当前气泡的值经过的边界
     * @param {object} e 气泡的值
     * @param {array} e.time 时间范围
     * @param {array} e.value 值域范围
     * @param {number} intervalX 气泡尾巴长度
     */
    function bubbleBound(e, intervalX, minX){
        var space = ~~intervalX;
        var length = e.time.length;
        e.xpx = [];
        e.ypx = [];
        var i = 0;
        var x0 = 0;
        var x1 = 0;
        var y0 = 0;
        var y1 = 0;
        var newline;
        for(; i < length; i++){
            x0 = ~~e.time[i];
            y0 = e.value[i] / 2;
            if (i === length - 1) {
                // i = length - 1  ~  += intervalX
                x1 = x0 + space;
                y1 = 0;
            } else {
                x1 = ~~(e.time[i + 1]);
                y1 = e.value[i + 1] / 2;
            }
            // to line
            newline = line(x0, y0, x1, y1);
            //
            for (var x = x0; x < x1; x++){
                e.xpx.push(x - minX);
                e.ypx.push(newline(x));
            }
        }
        e.xpx.push(x1 - minX);
        e.ypx.push(y1);
    }
    function findLocation(flags, e, yvalue){
        var pos = 0;
        var length = e.xpx.length;
        var i = 0;
        var y;
        for(; i < length; i++){
            y = yvalue(e, i);
            pos = Math.max(pos, y + flags[e.xpx[i]]);
        }
        // reset flags
        for(i = 0; i < length; i++){
            y = yvalue(e, i);
            flags[e.xpx[i]] = pos + y;
        }
        return pos;
    }
    return eventRiverLayout;
});

+ 781 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/layout/forceLayoutWorker.js

@ -0,0 +1,781 @@
// 1. Graph Drawing by Force-directed Placement
// 2. http://webatlas.fr/tempshare/ForceAtlas2_Paper.pdf
define(function __echartsForceLayoutWorker(require) {
    'use strict';
    var vec2;
    // In web worker
    var inWorker = typeof(window) === 'undefined' && typeof(require) === 'undefined';
    if (inWorker) {
        vec2 = {
            create: function(x, y) {
                var out = new Float32Array(2);
                out[0] = x || 0;
                out[1] = y || 0;
                return out;
            },
            dist: function(a, b) {
                var x = b[0] - a[0];
                var y = b[1] - a[1];
                return Math.sqrt(x*x + y*y);
            },
            len: function(a) {
                var x = a[0];
                var y = a[1];
                return Math.sqrt(x*x + y*y);
            },
            scaleAndAdd: function(out, a, b, scale) {
                out[0] = a[0] + b[0] * scale;
                out[1] = a[1] + b[1] * scale;
                return out;
            },
            scale: function(out, a, b) {
                out[0] = a[0] * b;
                out[1] = a[1] * b;
                return out;
            },
            add: function(out, a, b) {
                out[0] = a[0] + b[0];
                out[1] = a[1] + b[1];
                return out;
            },
            sub: function(out, a, b) {
                out[0] = a[0] - b[0];
                out[1] = a[1] - b[1];
                return out;
            },
            dot: function (v1, v2) {
                return v1[0] * v2[0] + v1[1] * v2[1];
            },
            normalize: function(out, a) {
                var x = a[0];
                var y = a[1];
                var len = x*x + y*y;
                if (len > 0) {
                    //TODO: evaluate use of glm_invsqrt here?
                    len = 1 / Math.sqrt(len);
                    out[0] = a[0] * len;
                    out[1] = a[1] * len;
                }
                return out;
            },
            negate: function(out, a) {
                out[0] = -a[0];
                out[1] = -a[1];
                return out;
            },
            copy: function(out, a) {
                out[0] = a[0];
                out[1] = a[1];
                return out;
            },
            set: function(out, x, y) {
                out[0] = x;
                out[1] = y;
                return out;
            }
        };
    }
    else {
        vec2 = require('zrender/tool/vector');
    }
    var ArrayCtor = typeof(Float32Array) == 'undefined' ? Array : Float32Array;
    /****************************
     * Class: Region
     ***************************/
    function Region() {
        this.subRegions = [];
        this.nSubRegions = 0;
        this.node = null;
        this.mass = 0;
        this.centerOfMass = null;
        this.bbox = new ArrayCtor(4);
        this.size = 0;
    }
    // Reset before update
    Region.prototype.beforeUpdate = function() {
        for (var i = 0; i < this.nSubRegions; i++) {
            this.subRegions[i].beforeUpdate();
        }
        this.mass = 0;
        if (this.centerOfMass) {
            this.centerOfMass[0] = 0;
            this.centerOfMass[1] = 0;
        }
        this.nSubRegions = 0;
        this.node = null;
    };
    // Clear after update
    Region.prototype.afterUpdate = function() {
        this.subRegions.length = this.nSubRegions;
        for (var i = 0; i < this.nSubRegions; i++) {
            this.subRegions[i].afterUpdate();
        }
    };
    Region.prototype.addNode = function(node) {
        if (this.nSubRegions === 0) {
            if (this.node == null) {
                this.node = node;
                return;
            }
            else {
                this._addNodeToSubRegion(this.node);
                this.node = null;
            }
        }
        this._addNodeToSubRegion(node);
        this._updateCenterOfMass(node);
    };
    Region.prototype.findSubRegion = function(x, y) {
        for (var i = 0; i < this.nSubRegions; i++) {
            var region = this.subRegions[i];
            if (region.contain(x, y)) {
                return region;
            }
        }
    };
    Region.prototype.contain = function(x, y) {
        return this.bbox[0] <= x
            && this.bbox[2] >= x
            && this.bbox[1] <= y
            && this.bbox[3] >= y;
    };
    Region.prototype.setBBox = function(minX, minY, maxX, maxY) {
        // Min
        this.bbox[0] = minX;
        this.bbox[1] = minY;
        // Max
        this.bbox[2] = maxX;
        this.bbox[3] = maxY;
        this.size = (maxX - minX + maxY - minY) / 2;
    };
    Region.prototype._newSubRegion = function() {
        var subRegion = this.subRegions[this.nSubRegions];
        if (!subRegion) {
            subRegion = new Region();
            this.subRegions[this.nSubRegions] = subRegion;
        }
        this.nSubRegions++;
        return subRegion;
    };
    Region.prototype._addNodeToSubRegion = function(node) {
        var subRegion = this.findSubRegion(node.position[0], node.position[1]);
        var bbox = this.bbox;
        if (!subRegion) {
            var cx = (bbox[0] + bbox[2]) / 2;
            var cy = (bbox[1] + bbox[3]) / 2;
            var w = (bbox[2] - bbox[0]) / 2;
            var h = (bbox[3] - bbox[1]) / 2;
            
            var xi = node.position[0] >= cx ? 1 : 0;
            var yi = node.position[1] >= cy ? 1 : 0;
            var subRegion = this._newSubRegion();
            // Min
            subRegion.setBBox(
                // Min
                xi * w + bbox[0],
                yi * h + bbox[1],
                // Max
                (xi + 1) * w + bbox[0],
                (yi + 1) * h + bbox[1]
            );
        }
        subRegion.addNode(node);
    };
    Region.prototype._updateCenterOfMass = function(node) {
        // Incrementally update
        if (this.centerOfMass == null) {
            this.centerOfMass = vec2.create();
        }
        var x = this.centerOfMass[0] * this.mass;
        var y = this.centerOfMass[1] * this.mass;
        x += node.position[0] * node.mass;
        y += node.position[1] * node.mass;
        this.mass += node.mass;
        this.centerOfMass[0] = x / this.mass;
        this.centerOfMass[1] = y / this.mass;
    };
    /****************************
     * Class: Graph Node
     ***************************/
    function GraphNode() {
        this.position = vec2.create();
        this.force = vec2.create();
        this.forcePrev = vec2.create();
        this.speed = vec2.create();
        this.speedPrev = vec2.create();
        // If repulsionByDegree is true
        //  mass = inDegree + outDegree + 1
        // Else
        //  mass is manually set
        this.mass = 1;
        this.inDegree = 0;
        this.outDegree = 0;
    }
    /****************************
     * Class: Graph Edge
     ***************************/
    function GraphEdge(node1, node2) {
        this.node1 = node1;
        this.node2 = node2;
        this.weight = 1;
    }
    /****************************
     * Class: ForceLayout
     ***************************/
    function ForceLayout() {
        this.barnesHutOptimize = false;
        this.barnesHutTheta = 1.5;
        this.repulsionByDegree = false;
        this.preventNodeOverlap = false;
        this.preventNodeEdgeOverlap = false;
        this.strongGravity = true;
        this.gravity = 1.0;
        this.scaling = 1.0;
        this.edgeWeightInfluence = 1.0;
        this.center = [0, 0];
        this.width = 500;
        this.height = 500;
        this.maxSpeedIncrease = 1;
        this.nodes = [];
        this.edges = [];
        this.bbox = new ArrayCtor(4);
        this._rootRegion = new Region();
        this._rootRegion.centerOfMass = vec2.create();
        this._massArr = null;
        this._k = 0;
    }
    ForceLayout.prototype.nodeToNodeRepulsionFactor = function (mass, d, k) {
        return k * k * mass / d;
    };
    ForceLayout.prototype.edgeToNodeRepulsionFactor = function (mass, d, k) {
        return k * mass / d;
    };
    ForceLayout.prototype.attractionFactor = function (w, d, k) {
        return w * d / k;
    };
    ForceLayout.prototype.initNodes = function(positionArr, massArr, sizeArr) {
        this.temperature = 1.0;
        var nNodes = positionArr.length / 2;
        this.nodes.length = 0;
        var haveSize = typeof(sizeArr) !== 'undefined';
        for (var i = 0; i < nNodes; i++) {
            var node = new GraphNode();
            node.position[0] = positionArr[i * 2];
            node.position[1] = positionArr[i * 2 + 1];
            node.mass = massArr[i];
            if (haveSize) {
                node.size = sizeArr[i];
            }
            this.nodes.push(node);
        }
        this._massArr = massArr;
        if (haveSize) {
            this._sizeArr = sizeArr;
        }
    };
    ForceLayout.prototype.initEdges = function(edgeArr, edgeWeightArr) {
        var nEdges = edgeArr.length / 2;
        this.edges.length = 0;
        var edgeHaveWeight = typeof(edgeWeightArr) !== 'undefined';
        for (var i = 0; i < nEdges; i++) {
            var sIdx = edgeArr[i * 2];
            var tIdx = edgeArr[i * 2 + 1];
            var sNode = this.nodes[sIdx];
            var tNode = this.nodes[tIdx];
            if (!sNode || !tNode) {
                continue;
            }
            sNode.outDegree++;
            tNode.inDegree++;
            var edge = new GraphEdge(sNode, tNode);
            if (edgeHaveWeight) {
                edge.weight = edgeWeightArr[i];
            }
            this.edges.push(edge);
        }
    };
    ForceLayout.prototype.update = function() {
        var nNodes = this.nodes.length;
        this.updateBBox();
        this._k = 0.4 * this.scaling * Math.sqrt(this.width * this.height / nNodes);
        if (this.barnesHutOptimize) {
            this._rootRegion.setBBox(
                this.bbox[0], this.bbox[1],
                this.bbox[2], this.bbox[3]
            );
            this._rootRegion.beforeUpdate();
            for (var i = 0; i < nNodes; i++) {
                this._rootRegion.addNode(this.nodes[i]);
            }
            this._rootRegion.afterUpdate();
        }
        else {
            // Update center of mass of whole graph
            var mass = 0;
            var centerOfMass = this._rootRegion.centerOfMass;
            vec2.set(centerOfMass, 0, 0);
            for (var i = 0; i < nNodes; i++) {
                var node = this.nodes[i];
                mass += node.mass;
                vec2.scaleAndAdd(centerOfMass, centerOfMass, node.position, node.mass);
            }
            if (mass > 0) {
                vec2.scale(centerOfMass, centerOfMass, 1 / mass);
            }
        }
        this.updateForce();
        this.updatePosition();
    };
    ForceLayout.prototype.updateForce = function () {
        var nNodes = this.nodes.length;
        // Reset forces
        for (var i = 0; i < nNodes; i++) {
            var node = this.nodes[i];
            vec2.copy(node.forcePrev, node.force);
            vec2.copy(node.speedPrev, node.speed);
            vec2.set(node.force, 0, 0);
        }
        this.updateNodeNodeForce();
        if (this.gravity > 0) {
            this.updateGravityForce();
        }
        this.updateEdgeForce();
        if (this.preventNodeEdgeOverlap) {
            this.updateNodeEdgeForce();
        }
    };
    ForceLayout.prototype.updatePosition = function () {
        var nNodes = this.nodes.length;
        // Apply forces
        // var speed = vec2.create();
        var v = vec2.create();
        for (var i = 0; i < nNodes; i++) {
            var node = this.nodes[i];
            var speed = node.speed;
            // var swing = vec2.dist(node.force, node.forcePrev);
            // // var swing = 30;
            // vec2.scale(node.force, node.force, 1 / (1 + Math.sqrt(swing)));
            vec2.scale(node.force, node.force, 1 / 30);
            // contraint force
            var df = vec2.len(node.force) + 0.1;
            var scale = Math.min(df, 500.0) / df;
            vec2.scale(node.force, node.force, scale);
            vec2.add(speed, speed, node.force);
            vec2.scale(speed, speed, this.temperature);
            // Prevent swinging
            // Limited the increase of speed up to 100% each step
            // TODO adjust by nodes number
            // TODO First iterate speed control
            vec2.sub(v, speed, node.speedPrev);
            var swing = vec2.len(v);
            if (swing > 0) {
                vec2.scale(v, v, 1 / swing);
                var base = vec2.len(node.speedPrev);
                if (base > 0) {
                    swing = Math.min(swing / base, this.maxSpeedIncrease) * base;
                    vec2.scaleAndAdd(speed, node.speedPrev, v, swing);
                }
            }
            // constraint speed
            var ds = vec2.len(speed);
            var scale = Math.min(ds, 100.0) / (ds + 0.1);
            vec2.scale(speed, speed, scale);
            vec2.add(node.position, node.position, speed);
        }
    };
    ForceLayout.prototype.updateNodeNodeForce = function () {
        var nNodes = this.nodes.length;
        // Compute forces
        // Repulsion
        for (var i = 0; i < nNodes; i++) {
            var na = this.nodes[i];
            if (this.barnesHutOptimize) {
                this.applyRegionToNodeRepulsion(this._rootRegion, na);
            }
            else {
                for (var j = i + 1; j < nNodes; j++) {
                    var nb = this.nodes[j];
                    this.applyNodeToNodeRepulsion(na, nb, false);
                }
            }
        }
    };
    ForceLayout.prototype.updateGravityForce = function () {
        for (var i = 0; i < this.nodes.length; i++) {
            this.applyNodeGravity(this.nodes[i]);
        }
    };
    ForceLayout.prototype.updateEdgeForce = function () {
        // Attraction
        for (var i = 0; i < this.edges.length; i++) {
            this.applyEdgeAttraction(this.edges[i]);
        }
    };
    ForceLayout.prototype.updateNodeEdgeForce = function () {
        for (var i = 0; i < this.nodes.length; i++) {
            for (var j = 0; j < this.edges.length; j++) {
                this.applyEdgeToNodeRepulsion(this.edges[j], this.nodes[i]);
            }
        }
    };
    ForceLayout.prototype.applyRegionToNodeRepulsion = (function() {
        var v = vec2.create();
        return function applyRegionToNodeRepulsion(region, node) {
            if (region.node) { // Region is a leaf 
                this.applyNodeToNodeRepulsion(region.node, node, true);
            }
            else {
                // Static region and node
                if (region.mass === 0 && node.mass === 0) {
                    return;
                }
                vec2.sub(v, node.position, region.centerOfMass);
                var d2 = v[0] * v[0] + v[1] * v[1];
                if (d2 > this.barnesHutTheta * region.size * region.size) {
                    var factor = this._k * this._k * (node.mass + region.mass) / (d2 + 1);
                    vec2.scaleAndAdd(node.force, node.force, v, factor * 2);
                }
                else {
                    for (var i = 0; i < region.nSubRegions; i++) {
                        this.applyRegionToNodeRepulsion(region.subRegions[i], node);
                    }
                }
            }
        };
    })();
    ForceLayout.prototype.applyNodeToNodeRepulsion = (function() {
        var v = vec2.create();
        return function applyNodeToNodeRepulsion(na, nb, oneWay) {
            if (na === nb) {
                return;
            }
            // Two static node
            if (na.mass === 0 && nb.mass === 0) {
                return;
            }
            
            vec2.sub(v, na.position, nb.position);
            var d2 = v[0] * v[0] + v[1] * v[1];
            // PENDING
            if (d2 === 0) {
                return;
            }
            var factor;
            var mass = na.mass + nb.mass;
            var d = Math.sqrt(d2);
            // Normalize v
            vec2.scale(v, v, 1 / d);
            if (this.preventNodeOverlap) {
                d = d - na.size - nb.size;
                if (d > 0) {
                    factor = this.nodeToNodeRepulsionFactor(
                        mass, d, this._k
                    );
                }
                else if (d <= 0) {
                    // A stronger repulsion if overlap
                    factor = this._k * this._k * 10 * mass;
                }
            }
            else {
                factor = this.nodeToNodeRepulsionFactor(
                    mass, d, this._k
                );
            }
            if (!oneWay) {
                vec2.scaleAndAdd(na.force, na.force, v, factor * 2);
            }
            vec2.scaleAndAdd(nb.force, nb.force, v, -factor * 2);
        };
    })();
    ForceLayout.prototype.applyEdgeAttraction = (function() {
        var v = vec2.create();
        return function applyEdgeAttraction(edge) {
            var na = edge.node1;
            var nb = edge.node2;
            vec2.sub(v, na.position, nb.position);
            var d = vec2.len(v);
            var w;
            if (this.edgeWeightInfluence === 0) {
                w = 1;
            }
            else if (this.edgeWeightInfluence == 1) {
                w = edge.weight;
            }
            else {
                w = Math.pow(edge.weight, this.edgeWeightInfluence);
            }
            var factor;
            if (this.preventOverlap) {
                d = d - na.size - nb.size;
                if (d <= 0) {
                    // No attraction
                    return;
                }
            }
            var factor = this.attractionFactor(w, d, this._k);
            vec2.scaleAndAdd(na.force, na.force, v, -factor);
            vec2.scaleAndAdd(nb.force, nb.force, v, factor);
        };
    })();
    ForceLayout.prototype.applyNodeGravity = (function() {
        var v = vec2.create();
        return function(node) {
            // PENDING Move to centerOfMass or [0, 0] ?
            // vec2.sub(v, this._rootRegion.centerOfMass, node.position);
            // vec2.negate(v, node.position);
            vec2.sub(v, this.center, node.position);
            if (this.width > this.height) {
                // Stronger gravity on y axis
                v[1] *= this.width / this.height;
            }
            else {
                // Stronger gravity on x axis
                v[0] *= this.height / this.width;
            }
            var d = vec2.len(v) / 100;
            
            if (this.strongGravity) {
                vec2.scaleAndAdd(node.force, node.force, v, d * this.gravity * node.mass);
            }
            else {
                vec2.scaleAndAdd(node.force, node.force, v, this.gravity * node.mass / (d + 1));
            }
        };
    })();
    ForceLayout.prototype.applyEdgeToNodeRepulsion = (function () {
        var v12 = vec2.create();
        var v13 = vec2.create();
        var p = vec2.create();
        return function (e, n3) {
            var n1 = e.node1;
            var n2 = e.node2;
            if (n1 === n3 || n2 === n3) {
                return;
            }
            vec2.sub(v12, n2.position, n1.position);
            vec2.sub(v13, n3.position, n1.position);
            var len12 = vec2.len(v12);
            vec2.scale(v12, v12, 1 / len12);
            var len = vec2.dot(v12, v13);
            // n3 can't project on line n1-n2
            if (len < 0 || len > len12) {
                return;
            }
            // Project point
            vec2.scaleAndAdd(p, n1.position, v12, len);
            // n3 distance to line n1-n2
            var dist = vec2.dist(p, n3.position) - n3.size;
            var factor = this.edgeToNodeRepulsionFactor(
                n3.mass, Math.max(dist, 0.1), 100
            );
            // Use v12 as normal vector
            vec2.sub(v12, n3.position, p);
            vec2.normalize(v12, v12);
            vec2.scaleAndAdd(n3.force, n3.force, v12, factor);
            // PENDING
            vec2.scaleAndAdd(n1.force, n1.force, v12, -factor);
            vec2.scaleAndAdd(n2.force, n2.force, v12, -factor);
        };
    })();
    ForceLayout.prototype.updateBBox = function() {
        var minX = Infinity;
        var minY = Infinity;
        var maxX = -Infinity;
        var maxY = -Infinity;
        for (var i = 0; i < this.nodes.length; i++) {
            var pos = this.nodes[i].position;
            minX = Math.min(minX, pos[0]);
            minY = Math.min(minY, pos[1]);
            maxX = Math.max(maxX, pos[0]);
            maxY = Math.max(maxY, pos[1]);
        }
        this.bbox[0] = minX;
        this.bbox[1] = minY;
        this.bbox[2] = maxX;
        this.bbox[3] = maxY;
    };
    ForceLayout.getWorkerCode = function() {
        var str = __echartsForceLayoutWorker.toString();
        return str.slice(str.indexOf('{') + 1, str.lastIndexOf('return'));
    };
    /****************************
     * Main process
     ***************************/
    /* jshint ignore:start */
    if (inWorker) {
        var forceLayout = null;
        
        self.onmessage = function(e) {
            // Position read back
            if (e.data instanceof ArrayBuffer) {
                if (!forceLayout) return;
                var positionArr = new Float32Array(e.data);
                var nNodes = positionArr.length / 2;
                for (var i = 0; i < nNodes; i++) {
                    var node = forceLayout.nodes[i];
                    node.position[0] = positionArr[i * 2];
                    node.position[1] = positionArr[i * 2 + 1];
                }
                return;
            }
            switch(e.data.cmd) {
                case 'init':
                    if (!forceLayout) {
                        forceLayout = new ForceLayout();
                    }
                    forceLayout.initNodes(e.data.nodesPosition, e.data.nodesMass, e.data.nodesSize);
                    forceLayout.initEdges(e.data.edges, e.data.edgesWeight);
                    break;
                case 'updateConfig':
                    if (forceLayout) {
                        for (var name in e.data.config) {
                            forceLayout[name] = e.data.config[name];
                        }
                    }
                    break;
                case 'update':
                    var steps = e.data.steps;
                    if (forceLayout) {
                        var nNodes = forceLayout.nodes.length;
                        var positionArr = new Float32Array(nNodes * 2);
                        forceLayout.temperature = e.data.temperature;
                        for (var i = 0; i < steps; i++) {
                            forceLayout.update();
                            forceLayout.temperature *= e.data.coolDown;
                        }
                        // Callback
                        for (var i = 0; i < nNodes; i++) {
                            var node = forceLayout.nodes[i];
                            positionArr[i * 2] = node.position[0];
                            positionArr[i * 2 + 1] = node.position[1];
                        }
                        self.postMessage(positionArr.buffer, [positionArr.buffer]);
                    }
                    else {
                        // Not initialzied yet
                        var emptyArr = new Float32Array();
                        // Post transfer object
                        self.postMessage(emptyArr.buffer, [emptyArr.buffer]);
                    }
                    break;
            }
        };
    }
    /* jshint ignore:end */
    return ForceLayout;
});

+ 13 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/theme/default.js

@ -0,0 +1,13 @@
/**
 * echarts默认主题,开发中
 *
 * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
 *
 */
define(function() {
    var config = {
    };
    return config;
});

+ 297 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/theme/infographic.js

@ -0,0 +1,297 @@
define(function() {
var theme = {
    // 默认色板
    color: [
        '#C1232B','#B5C334','#FCCE10','#E87C25','#27727B',
        '#FE8463','#9BCA63','#FAD860','#F3A43B','#60C0DD',
        '#D7504B','#C6E579','#F4E001','#F0805A','#26C0C0'
    ],
    // 图表标题
    title: {
        textStyle: {
            fontWeight: 'normal',
            color: '#27727B'          // 主标题文字颜色
        }
    },
    // 值域
    dataRange: {
        x:'right',
        y:'center',
        itemWidth: 5,
        itemHeight:25,
        color:['#C1232B','#FCCE10']
    },
    toolbox: {
        color : [
            '#C1232B','#B5C334','#FCCE10','#E87C25','#27727B',
            '#FE8463','#9BCA63','#FAD860','#F3A43B','#60C0DD'
        ],
        effectiveColor : '#ff4500'
    },
    // 提示框
    tooltip: {
        backgroundColor: 'rgba(50,50,50,0.5)',     // 提示背景颜色,默认为透明度为0.7的黑色
        axisPointer : {            // 坐标轴指示器,坐标轴触发有效
            type : 'line',         // 默认为直线,可选为:'line' | 'shadow'
            lineStyle : {          // 直线指示器样式设置
                color: '#27727B',
                type: 'dashed'
            },
            crossStyle: {
                color: '#27727B'
            },
            shadowStyle : {                     // 阴影指示器样式设置
                color: 'rgba(200,200,200,0.3)'
            }
        }
    },
    // 区域缩放控制器
    dataZoom: {
        dataBackgroundColor: 'rgba(181,195,52,0.3)',            // 数据背景颜色
        fillerColor: 'rgba(181,195,52,0.2)',   // 填充颜色
        handleColor: '#27727B'    // 手柄颜色
    },
    // 网格
    grid: {
        borderWidth:0
    },
    // 类目轴
    categoryAxis: {
        axisLine: {            // 坐标轴线
            lineStyle: {       // 属性lineStyle控制线条样式
                color: '#27727B'
            }
        },
        splitLine: {           // 分隔线
            show: false
        }
    },
    // 数值型坐标轴默认参数
    valueAxis: {
        axisLine: {            // 坐标轴线
            show: false
        },
        splitArea : {
            show: false
        },
        splitLine: {           // 分隔线
            lineStyle: {       // 属性lineStyle(详见lineStyle)控制线条样式
                color: ['#ccc'],
                type: 'dashed'
            }
        }
    },
    polar : {
        axisLine: {            // 坐标轴线
            lineStyle: {       // 属性lineStyle控制线条样式
                color: '#ddd'
            }
        },
        splitArea : {
            show : true,
            areaStyle : {
                color: ['rgba(250,250,250,0.2)','rgba(200,200,200,0.2)']
            }
        },
        splitLine : {
            lineStyle : {
                color : '#ddd'
            }
        }
    },
    timeline : {
        lineStyle : {
            color : '#27727B'
        },
        controlStyle : {
            normal : { color : '#27727B'},
            emphasis : { color : '#27727B'}
        },
        symbol : 'emptyCircle',
        symbolSize : 3
    },
    // 折线图默认参数
    line: {
        itemStyle: {
            normal: {
                borderWidth:2,
                borderColor:'#fff',
                lineStyle: {
                    width: 3
                }
            },
            emphasis: {
                borderWidth:0
            }
        },
        symbol: 'circle',  // 拐点图形类型
        symbolSize: 3.5           // 拐点图形大小
    },
    // K线图默认参数
    k: {
        itemStyle: {
            normal: {
                color: '#C1232B',       // 阳线填充颜色
                color0: '#B5C334',      // 阴线填充颜色
                lineStyle: {
                    width: 1,
                    color: '#C1232B',   // 阳线边框颜色
                    color0: '#B5C334'   // 阴线边框颜色
                }
            }
        }
    },
    // 散点图默认参数
    scatter: {
        itemStyle: {
            normal: {
                borderWidth:1,
                borderColor:'rgba(200,200,200,0.5)'
            },
            emphasis: {
                borderWidth:0
            }
        },
        symbol: 'star4',    // 图形类型
        symbolSize: 4        // 图形大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2
    },
    // 雷达图默认参数
    radar : {
        symbol: 'emptyCircle',    // 图形类型
        symbolSize:3
        //symbol: null,         // 拐点图形类型
        //symbolRotate : null,  // 图形旋转控制
    },
    map: {
        itemStyle: {
            normal: {
                areaStyle: {
                    color: '#ddd'
                },
                label: {
                    textStyle: {
                        color: '#C1232B'
                    }
                }
            },
            emphasis: {                 // 也是选中样式
                areaStyle: {
                    color: '#fe994e'
                },
                label: {
                    textStyle: {
                        color: 'rgb(100,0,0)'
                    }
                }
            }
        }
    },
    force : {
        itemStyle: {
            normal: {
                linkStyle : {
                    color : '#27727B'
                }
            }
        }
    },
    chord : {
        itemStyle : {
            normal : {
                borderWidth: 1,
                borderColor: 'rgba(128, 128, 128, 0.5)',
                chordStyle : {
                    lineStyle : {
                        color : 'rgba(128, 128, 128, 0.5)'
                    }
                }
            },
            emphasis : {
                borderWidth: 1,
                borderColor: 'rgba(128, 128, 128, 0.5)',
                chordStyle : {
                    lineStyle : {
                        color : 'rgba(128, 128, 128, 0.5)'
                    }
                }
            }
        }
    },
    gauge : {
        center:['50%','80%'],
        radius:'100%',
        startAngle: 180,
        endAngle : 0,
        axisLine: {            // 坐标轴线
            show: true,        // 默认显示,属性show控制显示与否
            lineStyle: {       // 属性lineStyle控制线条样式
                color: [[0.2, '#B5C334'],[0.8, '#27727B'],[1, '#C1232B']],
                width: '40%'
            }
        },
        axisTick: {            // 坐标轴小标记
            splitNumber: 2,   // 每份split细分多少段
            length: 5,        // 属性length控制线长
            lineStyle: {       // 属性lineStyle控制线条样式
                color: '#fff'
            }
        },
        axisLabel: {           // 坐标轴文本标签,详见axis.axisLabel
            textStyle: {       // 其余属性默认使用全局文本样式,详见TEXTSTYLE
                color: '#fff',
                fontWeight:'bolder'
            }
        },
        splitLine: {           // 分隔线
            length: '5%',         // 属性length控制线长
            lineStyle: {       // 属性lineStyle(详见lineStyle)控制线条样式
                color: '#fff'
            }
        },
        pointer : {
            width : '40%',
            length: '80%',
            color: '#fff'
        },
        title : {
          offsetCenter: [0, -20],       // x, y,单位px
          textStyle: {       // 其余属性默认使用全局文本样式,详见TEXTSTYLE
            color: 'auto',
            fontSize: 20
          }
        },
        detail : {
            offsetCenter: [0, 0],       // x, y,单位px
            textStyle: {       // 其余属性默认使用全局文本样式,详见TEXTSTYLE
                color: 'auto',
                fontSize: 40
            }
        }
    },
    textStyle: {
        fontFamily: '微软雅黑, Arial, Verdana, sans-serif'
    }
};
    return theme;
});

+ 257 - 0
patient-co-manage/redis-cache/src/main/webapp/static/develop/browser/lib/echarts-2.2.7/src/theme/macarons.js

@ -0,0 +1,257 @@
define(function() {
var theme = {
    // 默认色板
    color: [
        '#2ec7c9','#b6a2de','#5ab1ef','#ffb980','#d87a80',
        '#8d98b3','#e5cf0d','#97b552','#95706d','#dc69aa',
        '#07a2a4','#9a7fd1','#588dd5','#f5994e','#c05050',
        '#59678c','#c9ab00','#7eb00a','#6f5553','#c14089'
    ],
    // 图表标题
    title: {
        textStyle: {
            fontWeight: 'normal',
            color: '#008acd'          // 主标题文字颜色
        }
    },
    
    // 值域
    dataRange: {
        itemWidth: 15,
        color: ['#5ab1ef','#e0ffff']
    },
    // 工具箱
    toolbox: {
        color : ['#1e90ff', '#1e90ff', '#1e90ff', '#1e90ff'],
        effectiveColor : '#ff4500'
    },
    // 提示框
    tooltip: {
        backgroundColor: 'rgba(50,50,50,0.5)',     // 提示背景颜色,默认为透明度为0.7的黑色
        axisPointer : {            // 坐标轴指示器,坐标轴触发有效
            type : 'line',         // 默认为直线,可选为:'line' | 'shadow'
            lineStyle : {          // 直线指示器样式设置
                color: '#008acd'
            },
            crossStyle: {
                color: '#008acd'
            },
            shadowStyle : {                     // 阴影指示器样式设置
                color: 'rgba(200,200,200,0.2)'
            }
        }
    },
    // 区域缩放控制器
    dataZoom: {
        dataBackgroundColor: '#efefff',            // 数据背景颜色
        fillerColor: 'rgba(182,162,222,0.2)',   // 填充颜色
        handleColor: '#008acd'    // 手柄颜色
    },
    // 网格
    grid: {
        borderColor: '#eee'
    },
    // 类目轴
    categoryAxis: {
        axisLine: {            // 坐标轴线
            lineStyle: {       // 属性lineStyle控制线条样式
                color: '#008acd'
            }
        },
        splitLine: {           // 分隔线
            lineStyle: {       // 属性lineStyle(详见lineStyle)控制线条样式
                color: ['#eee']
            }
        }
    },
    // 数值型坐标轴默认参数
    valueAxis: {
        axisLine: {            // 坐标轴线
            lineStyle: {       // 属性lineStyle控制线条样式
                color: '#008acd'
            }
        },
        splitArea : {
            show : true,
            areaStyle : {
                color: ['rgba(250,250,250,0.1)','rgba(200,200,200,0.1)']
            }
        },
        splitLine: {           // 分隔线
            lineStyle: {       // 属性lineStyle(详见lineStyle)控制线条样式
                color: ['#eee']
            }
        }
    },
    polar : {
        axisLine: {            // 坐标轴线
            lineStyle: {       // 属性lineStyle控制线条样式
                color: '#ddd'
            }
        },
        splitArea : {
            show : true,
            areaStyle : {
                color: ['rgba(250,250,250,0.2)','rgba(200,200,200,0.2)']
            }
        },
        splitLine : {
            lineStyle : {
                color : '#ddd'
            }
        }
    },
    timeline : {
        lineStyle : {
            color : '#008acd'
        },
        controlStyle : {
            normal : { color : '#008acd'},
            emphasis : { color : '#008acd'}
        },
        symbol : 'emptyCircle',
        symbolSize : 3
    },
    // 柱形图默认参数
    bar: {
        itemStyle: {
            normal: {
                barBorderRadius: 5
            },
            emphasis: {
                barBorderRadius: 5
            }
        }
    },
    // 折线图默认参数
    line: {
        smooth : true,
        symbol: 'emptyCircle',  // 拐点图形类型
        symbolSize: 3           // 拐点图形大小
    },
    
    // K线图默认参数
    k: {
        itemStyle: {
            normal: {
                color: '#d87a80',       // 阳线填充颜色
                color0: '#2ec7c9',      // 阴线填充颜色
                lineStyle: {
                    color: '#d87a80',   // 阳线边框颜色
                    color0: '#2ec7c9'   // 阴线边框颜色
                }
            }
        }
    },
    
    // 散点图默认参数
    scatter: {
        symbol: 'circle',    // 图形类型
        symbolSize: 4        // 图形大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2
    },
    // 雷达图默认参数
    radar : {
        symbol: 'emptyCircle',    // 图形类型
        symbolSize:3
        //symbol: null,         // 拐点图形类型
        //symbolRotate : null,  // 图形旋转控制
    },
    map: {
        itemStyle: {
            normal: {
                areaStyle: {
                    color: '#ddd'
                },
                label: {
                    textStyle: {
                        color: '#d87a80'
                    }
                }
            },
            emphasis: {                 // 也是选中样式
                areaStyle: {
                    color: '#fe994e'
                }
            }
        }
    },
    
    force : {
        itemStyle: {
            normal: {
                linkStyle : {
                    color : '#1e90ff'
                }
            }
        }
    },
    chord : {
        itemStyle : {
            normal : {
                borderWidth: 1,
                borderColor: 'rgba(128, 128, 128, 0.5)',
                chordStyle : {
                    lineStyle : {
                        color : 'rgba(128, 128, 128, 0.5)'
                    }
                }
            },
            emphasis : {
                borderWidth: 1,
                borderColor: 'rgba(128, 128, 128, 0.5)',
                chordStyle : {
                    lineStyle : {
                        color : 'rgba(128, 128, 128, 0.5)'
                    }
                }
            }
        }
    },
    gauge : {
        axisLine: {            // 坐标轴线
            lineStyle: {       // 属性lineStyle控制线条样式
                color: [[0.2, '#2ec7c9'],[0.8, '#5ab1ef'],[1, '#d87a80']], 
                width: 10
            }
        },
        axisTick: {            // 坐标轴小标记
            splitNumber: 10,   // 每份split细分多少段
            length :15,        // 属性length控制线长
            lineStyle: {       // 属性lineStyle控制线条样式
                color: 'auto'
            }
        },
        splitLine: {           // 分隔线
            length :22,         // 属性length控制线长
            lineStyle: {       // 属性lineStyle(详见lineStyle)控制线条样式
                color: 'auto'
            }
        },
        pointer : {
            width : 5
        }
    },
    
    textStyle: {
        fontFamily: '微软雅黑, Arial, Verdana, sans-serif'
    }
};
    return theme;
});