├── .gitignore ├── LICENSE ├── README.md ├── app ├── __init__.py ├── monitors │ ├── HttpMonitor.py │ ├── RedisMonitor.py │ └── __init__.py ├── others │ ├── __init__.py │ └── tasks.py ├── static │ ├── res │ │ ├── css │ │ │ ├── RAEDME.md │ │ │ └── style.css │ │ ├── favicon.ico │ │ ├── img │ │ │ └── RAEDME.md │ │ ├── js │ │ │ ├── RAEDME.md │ │ │ ├── common.js │ │ │ ├── http_monitor.js │ │ │ ├── index.js │ │ │ └── redis_monitor.js │ │ └── lib │ │ │ ├── echarts │ │ │ ├── .DS_Store │ │ │ ├── chart │ │ │ │ ├── bar.js │ │ │ │ ├── chord.js │ │ │ │ ├── eventRiver.js │ │ │ │ ├── force.js │ │ │ │ ├── funnel.js │ │ │ │ ├── gauge.js │ │ │ │ ├── heatmap.js │ │ │ │ ├── k.js │ │ │ │ ├── line.js │ │ │ │ ├── map.js │ │ │ │ ├── pie.js │ │ │ │ ├── radar.js │ │ │ │ ├── scatter.js │ │ │ │ ├── tree.js │ │ │ │ ├── treemap.js │ │ │ │ ├── venn.js │ │ │ │ └── wordCloud.js │ │ │ ├── echarts-all.js │ │ │ └── echarts.js │ │ │ ├── jquery.min.js │ │ │ ├── md5.js │ │ │ └── simpleStorage.js │ ├── tmp │ │ └── RAEDME.md │ └── upload │ │ └── RAEDME.md ├── templates │ ├── http_monitor_page.html │ ├── index_page.html │ ├── redis_monitor_page.html │ └── tip.html ├── utils │ ├── CJsonEncoder.py │ ├── DateUtil.py │ ├── LogUtil.py │ ├── OtherUtil.py │ ├── PathUtil.py │ ├── RequestUtil.py │ ├── StringUtil.py │ ├── __init__.py │ └── jinja2_ex │ │ ├── __init__.py │ │ └── template_filter.py ├── views │ ├── __init__.py │ └── main_views.py └── wraps │ ├── __init__.py │ ├── allow_request_wrap.py │ ├── async_task_wrap.py │ ├── login_wrap.py │ ├── mysql_escape_warp.py │ ├── singleton_wrap.py │ └── trace_wrap.py ├── doc └── shot │ ├── shot_1.png │ ├── shot_2.png │ └── shot_3.png ├── requirements.txt └── run_monitor.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # PyInstaller 26 | # Usually these files are written by a python script from a template 27 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 28 | *.manifest 29 | *.spec 30 | 31 | # Installer logs 32 | pip-log.txt 33 | pip-delete-this-directory.txt 34 | 35 | # Unit test / coverage reports 36 | htmlcov/ 37 | .tox/ 38 | .coverage 39 | .coverage.* 40 | .cache 41 | nosetests.xml 42 | coverage.xml 43 | *,cover 44 | 45 | # Translations 46 | *.mo 47 | *.pot 48 | 49 | # Django stuff: 50 | *.log 51 | 52 | # Sphinx documentation 53 | docs/_build/ 54 | 55 | # PyBuilder 56 | target/ 57 | 58 | .project 59 | .pydevproject 60 | .settings/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Hust.cc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## redis-monitor ## 2 | 3 | 一个web可视化的redis监控程序 4 | 5 | ### Done ### 6 | 7 | 监控数据包括以下: 8 | 9 | - redis服务器信息,包括redis版本、上线时间、os系统信息等等 10 | - 实时的消息处理信息,例如处理command数量、连接总数量等 11 | - 联通时间动态图表 12 | - ops时间动态图表 13 | - 内存占用、cpu消耗实时动态图表 14 | 15 | 16 | ### TODO ### 17 | 18 | - #DONE @2015-09-02 优化监控程序连接redis的频率,可以做缓存处理,防止多个web端监控redis的时候,对redis造成压力 19 | - #DONE @2015-09-02 配置redis放到前端存储中(storage),不用到后台配置,这样可以形成一个平台式工具 20 | - 报警设置和提醒方式 21 | - 配置一个redis的时候,需要验证是否可以联通 22 | - 更多的redis信息以及不同redis兼容性测试 23 | 24 | 25 | ### Why ### 26 | 27 | redis监控程序很多,为什么还要自己做? 28 | 29 | 因为我找了很多网上推荐的程序,存在一些问题,导致我没有用起来,除了自己知识欠缺的问题,主要包括: 30 | 31 | 1. 配置麻烦,需要修改代码中的配置文件,而且太难找; 32 | 2. 版本不兼容,不记得是哪个项目,2.8可以跑起来,但是2.6完全直接启动出错,我也不知道怎么去修改,原谅我的无知; 33 | 3. 启动麻烦,需要启动两个东东,我也不知道为什么,可能是为了性能上的东西吧! 34 | 35 | 36 | ### screenshot ### 37 | 38 | ![shot_1](/doc/shot/shot_1.png) 39 | 40 | ![shot_2](/doc/shot/shot_2.png) 41 | 42 | ![shot_3](/doc/shot/shot_3.png) -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年6月16日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | from flask import Flask 8 | 9 | app = Flask(__name__) 10 | app.secret_key = 'your_session_key_redis_monitor' 11 | 12 | from app.views import main_views -------------------------------------------------------------------------------- /app/monitors/HttpMonitor.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年9月2日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | from app.wraps.singleton_wrap import singleton 8 | import hashlib 9 | import time 10 | import requests 11 | 12 | @singleton 13 | class HttpMonitor(object): 14 | ''' 15 | classdocs 16 | ''' 17 | 18 | 19 | def __init__(self, timeout = 3): 20 | ''' 21 | Constructor 22 | ''' 23 | self.timeout = timeout #数据过期时间 24 | self.servers = {} 25 | 26 | 27 | def _md5(self, s): 28 | ''' 29 | md5 30 | ''' 31 | m = hashlib.md5() 32 | m.update(s) 33 | return m.hexdigest().upper() 34 | 35 | #暂时不带参数 36 | def get_info(self, url, method = "GET", params = {}): 37 | method = method.upper() 38 | if url and method in ['GET', 'POST', 'PUT', 'DELETE']: 39 | key = self._md5(url + method) 40 | if key in self.servers.keys() and (time.time() - self.servers[key]['time'] < self.timeout): 41 | return self.servers[key]['info'] 42 | else: 43 | http_rst = {} 44 | #需要重新请求获得数据 45 | try: 46 | start = time.time() 47 | if method == "POST": 48 | r = requests.post(url, params = params) 49 | elif method == "GET": 50 | r = requests.get(url, params = params) 51 | elif method == "PUT": 52 | r = requests.put(url, params = params) 53 | elif method == "DELETE": 54 | r = requests.delete(url, params = params) 55 | 56 | end = time.time(); 57 | info = {} 58 | info['get_time'] = end - start 59 | info['encoding'] = r.encoding 60 | info['status_code'] = r.status_code 61 | info['connection'] = r.headers.get('connection', '') 62 | info['server'] = r.headers.get('server', '') 63 | 64 | http_rst['success'] = 1 65 | http_rst['data'] = info 66 | except: 67 | #连接失败 68 | http_rst['success'] = 0 69 | http_rst['data'] = 'error' 70 | 71 | #将获取的redis信息保存到内存中,缓存起来 72 | self.servers[key] = {} 73 | self.servers[key]['time'] = time.time() #更新时间 74 | self.servers[key]['info'] = http_rst 75 | 76 | return http_rst 77 | else: 78 | #如果host,port非法,则直接返回错误 79 | return {'success': 0, 'data': 'parameter error'} -------------------------------------------------------------------------------- /app/monitors/RedisMonitor.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年9月2日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | from app.wraps.singleton_wrap import singleton 8 | import hashlib 9 | import time 10 | import redis 11 | 12 | @singleton 13 | class RedisMonitor(object): 14 | ''' 15 | classdocs 16 | ''' 17 | def __init__(self, timeout = 1): 18 | ''' 19 | Constructor 20 | ''' 21 | self.timeout = timeout #数据过期时间 22 | self.servers = {} 23 | #{key:{time:wef, info:info}} 24 | 25 | 26 | def _md5(self, s): 27 | ''' 28 | md5 29 | ''' 30 | m = hashlib.md5() 31 | m.update(s) 32 | return m.hexdigest() 33 | 34 | def ping(self, host, port, password, charset = 'utf8'): 35 | if host and port: 36 | redis_rst = {} 37 | #需要重新请求获得数据 38 | try: 39 | r = redis.Redis(host = host, port = port, password = password, db = 0) 40 | r.info() 41 | 42 | redis_rst['success'] = 1 43 | redis_rst['data'] = 'ping success' 44 | except: 45 | redis_rst['success'] = 0 46 | redis_rst['data'] = 'ping error' 47 | 48 | return redis_rst 49 | else: 50 | #如果host,port非法,则直接返回错误 51 | return {'success': 0, 'data': 'parameter error'} 52 | 53 | def get_info(self, host, port, password, charset = 'utf8'): 54 | if host and port: 55 | key = self._md5(host + str(port)) 56 | #小于timeout,不用重新连接redis获取信息,直接拉缓存数据 57 | if key in self.servers.keys() and (time.time() - self.servers[key]['time'] < self.timeout): 58 | return self.servers[key]['info'] 59 | else: 60 | redis_rst = {} 61 | #需要重新请求获得数据 62 | try: 63 | start = time.time() 64 | r = redis.Redis(host = host, port = port, password = password, db = 0) 65 | info = r.info() 66 | end = time.time(); 67 | info['get_time'] = end - start 68 | 69 | redis_rst['success'] = 1 70 | redis_rst['data'] = info 71 | except: 72 | redis_rst['success'] = 0 73 | redis_rst['data'] = 'error' 74 | 75 | #将获取的redis信息保存到内存中,缓存起来 76 | self.servers[key] = {} 77 | self.servers[key]['time'] = time.time() #更新时间 78 | self.servers[key]['info'] = redis_rst 79 | 80 | return redis_rst 81 | else: 82 | #如果host,port非法,则直接返回错误 83 | return {'success': 0, 'data': 'parameter error'} -------------------------------------------------------------------------------- /app/monitors/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/monitors/__init__.py -------------------------------------------------------------------------------- /app/others/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/others/__init__.py -------------------------------------------------------------------------------- /app/others/tasks.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年6月16日 4 | all tasks 5 | @author: hzwangzhiwei 6 | ''' 7 | from app.wraps.async_task_wrap import async_task 8 | 9 | 10 | @async_task 11 | def count_to_10000(): 12 | ''' 13 | test async_task, count to 1w 14 | 注意:在uwsgi部署情况下,不能执行异步任务,所有任务在一次请求完成之后,全部释放 15 | ''' 16 | for i in xrange(10000): 17 | print i 18 | 19 | -------------------------------------------------------------------------------- /app/static/res/css/RAEDME.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/static/res/css/RAEDME.md -------------------------------------------------------------------------------- /app/static/res/css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "Courier New", "Microsoft YaHei", monospace, Consolas, "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", Monaco; 3 | font-size: 14px; 4 | text-align:left; 5 | background-color:#EBEBEB; 6 | margin:0px; 7 | } 8 | 9 | form { 10 | margin: 5px; 11 | } 12 | 13 | input[type=text] { 14 | width: 180px; 15 | } 16 | 17 | input[type=number] { 18 | width: 100px; 19 | } 20 | 21 | table { 22 | table-layout:fixed; 23 | word-wrap:break-word; 24 | } 25 | 26 | td { 27 | background-color: #FFFFCC; 28 | font-weight: bold; 29 | } 30 | 31 | th { 32 | background-color: #DDEEFF; 33 | } 34 | td,th { 35 | font-family: "Courier New", "Microsoft YaHei", monospace, Consolas, "Andale Mono", "Lucida Console", "Lucida Sans Typewriter", Monaco; 36 | font-size: 14px; 37 | } 38 | tr { 39 | line-height:10px; 40 | } 41 | tr.th_group { 42 | line-height:15px; 43 | } 44 | 45 | tr.th_group th { 46 | background-color: #88b9e5; 47 | text-align: center; 48 | font-size: 1.2em; 49 | } 50 | 51 | a { 52 | font-size: .95em; 53 | text-decoration: none; 54 | color: #435275 55 | } 56 | 57 | a:hover { 58 | color: #f77b6f; 59 | text-decoration:underline; 60 | } 61 | 62 | td { 63 | word-wrap:break-word; 64 | word-break:break-all; 65 | } 66 | #wrapper{ 67 | margin:auto; 68 | max-width:1280px; 69 | background-color:#FFF; 70 | padding:1em; 71 | width: 90%; 72 | webkit-box-shadow: #666 0px 0px 10px; 73 | -moz-box-shadow: #666 0px 0px 10px; 74 | box-shadow: #666 0px 0px 10px; 75 | } 76 | 77 | h1 { 78 | margin:20px 10px; 79 | font-size:20px; 80 | line-height:1.4em; 81 | margin-bottom:1em; 82 | word-wrap:break-word; 83 | } 84 | 85 | h2 { 86 | margin:40px 0 0 20px; 87 | font-size:16px; 88 | line-height:1.4em; 89 | word-wrap:break-word; 90 | } 91 | 92 | .breadcrumb { 93 | color:#999999; 94 | font-size:11px; 95 | margin-top:10px; 96 | margin-bottom:20px; 97 | margin-left: 10px; 98 | padding:0px; 99 | letter-spacing:1px; 100 | line-height:1.6em; 101 | } 102 | 103 | .footer { 104 | color:#999999; 105 | font-size:11px; 106 | margin: 10px auto; 107 | padding:0px; 108 | letter-spacing:1px; 109 | line-height:1.6em; 110 | text-align: center; 111 | } 112 | 113 | .breadcrumb a:link, .breadcrumb a:visited { 114 | color:#999999; 115 | } 116 | .breadcrumb a:hover { 117 | color:#333333; 118 | } 119 | 120 | 121 | ul{ 122 | display:inline-block; 123 | vertical-align:top; 124 | 125 | margin:0px; 126 | margin-top:1em; 127 | padding:0px; 128 | 129 | list-style:none; 130 | } 131 | 132 | li{ 133 | margin:0px; 134 | padding:0px; 135 | margin-top:20px; 136 | margin-right:7px; 137 | display:inline-block; 138 | } 139 | 140 | li a:link{ 141 | line-height:1.5em; 142 | text-decoration:none; 143 | background-color:#DDEEFF; 144 | margin:0px; 145 | padding:5px; 146 | padding-left:10px; 147 | padding-right:10px; 148 | border-radius:4px; 149 | } 150 | 151 | li a:hover{ 152 | background-color:#09C; 153 | color:#FFF; 154 | } 155 | 156 | .chart_div { 157 | width: 100%; 158 | height: 300px; 159 | } -------------------------------------------------------------------------------- /app/static/res/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/static/res/favicon.ico -------------------------------------------------------------------------------- /app/static/res/img/RAEDME.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/static/res/img/RAEDME.md -------------------------------------------------------------------------------- /app/static/res/js/RAEDME.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/static/res/js/RAEDME.md -------------------------------------------------------------------------------- /app/static/res/js/common.js: -------------------------------------------------------------------------------- 1 | var server_servers = []; //storeage中所有redis信息 2 | 3 | function sort_server_server() { 4 | server_servers = server_servers.sort(function (a, b) { 5 | return a['timestamp'] - b['timestamp']; 6 | }); 7 | } 8 | 9 | 10 | //md5,用于key值 11 | function _server_md5(server) { 12 | return hex_md5(server['type'] + server['host'] + server['port']); 13 | } 14 | 15 | function _valid_server_storage(server_info) { 16 | if (server_info.hasOwnProperty('host') && 17 | server_info.hasOwnProperty('port')) { 18 | return true; 19 | } 20 | return false; 21 | } 22 | 23 | function load_all_server_from_storage() { 24 | var keys = simpleStorage.index(); 25 | var len = keys.length; 26 | for(var i = 0; i < len; i ++) { 27 | var key = keys[i]; 28 | if (key.startWith('server_')) { 29 | var server_info = get_server(key); 30 | if (server_info) { 31 | server_servers.push(server_info); 32 | } 33 | } 34 | } 35 | sort_server_server(); 36 | } 37 | 38 | function get_server(key) { 39 | try { 40 | var server_info = simpleStorage.get(key); 41 | if (_valid_server_storage(server_info)) { 42 | return server_info; 43 | } 44 | } catch(E) { 45 | console.log(E); 46 | } 47 | //不合法的跳过,并且从storeage中删除 48 | simpleStorage.deleteKey(key); 49 | return false; 50 | } 51 | 52 | 53 | String.prototype.trim = function() {   54 | return this.replace(/(^\s*)|(\s*$)/g, "");   55 | }   56 | String.prototype.ltrim = function() {   57 | return this.replace(/(^\s*)/g, "");   58 | }   59 | String.prototype.rtrim = function() {   60 | return this.replace(/(\s*$)/g, "");   61 | } 62 | String.prototype.endWith = function(str) { 63 | if (str == null || str == "" || this.length == 0 || str.length > this.length) 64 | return false; 65 | if (this.substring(this.length - str.length) == str) 66 | return true; 67 | else 68 | return false; 69 | return true; 70 | } 71 | String.prototype.startWith = function(str) { 72 | if (str == null || str == "" || this.length == 0 || str.length > this.length) 73 | return false; 74 | if (this.substr(0, str.length) == str) 75 | return true; 76 | else 77 | return false; 78 | return true; 79 | } 80 | 81 | Date.prototype.Format = function (fmt) { //author: meizz 82 | var o = { 83 | "M+": this.getMonth() + 1, //月份 84 | "d+": this.getDate(), //日 85 | "h+": this.getHours(), //小时 86 | "m+": this.getMinutes(), //分 87 | "s+": this.getSeconds(), //秒 88 | "q+": Math.floor((this.getMonth() + 3) / 3), //季度 89 | "S": this.getMilliseconds() //毫秒 90 | }; 91 | if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 92 | for (var k in o) 93 | if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length))); 94 | return fmt; 95 | } -------------------------------------------------------------------------------- /app/static/res/js/http_monitor.js: -------------------------------------------------------------------------------- 1 | var intervalTime = 3000; //监控频率 2 | var is_start = true; //已经开始监控 3 | 4 | function monitor_task() { 5 | if (is_start) { 6 | get_server_data(); 7 | } 8 | else { 9 | setTimeout(monitor_task, intervalTime); 10 | } 11 | } 12 | 13 | function sec_2_hour(sec) { 14 | var h = parseInt(sec / 3600); 15 | var m = parseInt((sec - h * 3600) / 60) 16 | var s = sec - h * 3600 - m * 60; 17 | return h + ':' + m + ':' + s; 18 | } 19 | 20 | function fill_data_table(data) { 21 | var keys = ['status_code', 'http_length', 'encoding', 'connection', 'server'] 22 | var key = null; 23 | for (var i in keys) { 24 | key = keys[i]; 25 | $('#' + key).text(data[key]); 26 | } 27 | 28 | //遍历key中以db开头的,标示不同的数据库 29 | var html = ""; 30 | for (var key in data) { 31 | if (key.substring(0, 2) == 'db') { 32 | html = html + ''+key+''+data[key].keys+''+data[key].expires+''+data[key].avg_ttl+''; 33 | } 34 | } 35 | //删除已有的,append新增的 36 | $('tr.rb_td').remove(); 37 | $('#data_table tbody').append(html); 38 | } 39 | 40 | function do_server_status(data) { 41 | var x_date = (new Date()).toLocaleTimeString().replace(/^\D*/,''); 42 | if (data.success == 1) { 43 | fill_data_table(data.data); 44 | //update charts 45 | timechart.addData([ 46 | [ 47 | 0, // 系列索引 48 | data.data.get_time * 1000, 49 | false, 50 | false, 51 | x_date 52 | ] 53 | ]); 54 | } 55 | else { 56 | //填充空的数据 57 | timechart.addData([[0, 30000, false, false, x_date]]) 58 | } 59 | setTimeout(monitor_task, intervalTime); 60 | } 61 | 62 | function get_server_data() { 63 | var ajax = $.ajax({ 64 | type: "POST", 65 | url: '/server_information.json', 66 | timeout: 5000, 67 | data: {'type': server_info['type'], 'host': server_info['host'], 'port': server_info['port'], 'password': server_info['password']}, 68 | success: do_server_status, 69 | dataType: 'json', 70 | async: true, 71 | }); 72 | } 73 | 74 | 75 | //line图 76 | function get_line_option(text, subtext, legend, yAxis_name, y_format) { 77 | option = { 78 | title : { 79 | text: text, 80 | subtext: subtext 81 | }, 82 | tooltip : { 83 | trigger: 'axis' 84 | }, 85 | legend: { 86 | data:legend 87 | }, 88 | toolbox: { 89 | show : true, 90 | feature : { 91 | mark : {show: true}, 92 | dataView : {show: true, readOnly: false}, 93 | magicType : {show: true, type: ['line', 'bar']}, 94 | restore : {show: true}, 95 | saveAsImage : {show: true} 96 | } 97 | }, 98 | dataZoom : { 99 | show : false, 100 | start : 0, 101 | end : 100 102 | }, 103 | xAxis : [{ 104 | type : 'category', 105 | boundaryGap : true, 106 | data : (function (){ 107 | var now = new Date(); 108 | var res = []; 109 | var len = 100; 110 | while (len--) { 111 | res.unshift(now.toLocaleTimeString().replace(/^\D*/,'')); 112 | now = new Date(now - 2000); 113 | } 114 | return res; 115 | })() 116 | }], 117 | yAxis : [{ 118 | type : 'value', 119 | scale: true, 120 | name : yAxis_name, 121 | axisLabel : { 122 | formatter: '{value} ' + y_format 123 | } 124 | }], 125 | series : [] 126 | }; 127 | var tmp = null; 128 | var s = null; 129 | for (var i in legend) { 130 | tmp = legend[i]; 131 | s = { 132 | name:tmp, 133 | type:'line', 134 | data:(function (){ 135 | var res = []; 136 | var len = 100; 137 | while (len--) { 138 | res.push(0.0); 139 | } 140 | return res; 141 | })() 142 | } 143 | option.series.push(s); 144 | } 145 | return option; 146 | } 147 | 148 | //########################### 149 | var server_info; 150 | 151 | function get_server_key() { 152 | var server_md5 = $('#wrapper').attr('server_md5'); 153 | server_md5 = "server_" + server_md5; 154 | return server_md5; 155 | } 156 | 157 | function fill_page(key) { 158 | server_info = get_server(key); 159 | if (server_info) { 160 | $('.server_host_port').text(server_info['host'] + ':' + server_info['port']); 161 | 162 | //添加其他redis信息 163 | $('#other_server li').remove(); 164 | var server = null; 165 | var html = ''; 166 | for (var i in server_servers) { 167 | server = server_servers[i]; 168 | html = '
  • '+ server['host'] + ':' + server['port'] +'
  • '; 169 | $('#other_server').append(html); 170 | } 171 | } 172 | else { 173 | $('#wrapper').html('

    不存在这个Server实例。

    ') 174 | } 175 | } 176 | //########################### 177 | 178 | 179 | var echarts = null; 180 | 181 | var timechart = null; 182 | require.config({ 183 | paths: { 184 | echarts: '/static/res/lib/echarts/' 185 | } 186 | }); 187 | // 按需加载 188 | require([ 189 | 'echarts', 190 | 'echarts/chart/line', 191 | 'echarts/chart/bar', 192 | ], 193 | function(ec) { 194 | echarts = ec; 195 | 196 | timechart = draw_chart('time_chart', get_line_option('Http Server实时联通情况', '', ['连接耗时'], '时间', 'ms')); 197 | //开启监控 198 | load_all_server_from_storage(); //加载本地数据 199 | fill_page(get_server_key()); 200 | monitor_task(); 201 | } 202 | ); 203 | function draw_chart(e_id, option) { 204 | var eChart = echarts.init(document.getElementById(e_id)); 205 | eChart.setOption(option); 206 | return eChart 207 | } 208 | 209 | -------------------------------------------------------------------------------- /app/static/res/js/index.js: -------------------------------------------------------------------------------- 1 | function add_http_btn_click() { 2 | $('form input').attr("disabled","disabled"); 3 | 4 | var url = $('#new_http_url').val() || ''; 5 | 6 | var email = $('#new_email').val() || ''; 7 | 8 | if (url == '') { 9 | alert('Http Url地址不能为空!'); 10 | return ; 11 | } 12 | 13 | var server_info = {}; 14 | server_info['type'] = 'http'; 15 | server_info['host'] = url; 16 | server_info['port'] = '80'; 17 | server_info['email'] = email; 18 | server_info['time'] = new Date().Format("yyyy-MM-dd hh:mm:ss"); 19 | server_info['timestamp'] = Date.parse(new Date()); 20 | 21 | var key = 'server_' + _server_md5(server_info); 22 | simpleStorage.set(key, server_info, 0); 23 | server_servers.push(server_info); 24 | sort_server_server(); 25 | 26 | add_onerow_2_table(server_info); 27 | $('form')[1].reset(); 28 | 29 | $('form input').removeAttr("disabled"); 30 | } 31 | 32 | function add_demo_http_btn_click() { 33 | $('#new_http_url').val('http://www.atool.org/'); 34 | $('#new_http_email').val('不提醒'); 35 | add_http_btn_click(); 36 | } 37 | 38 | 39 | function add_demo_redis_btn_click() { 40 | $('#new_host').val('10.246.13.189'); 41 | $('#new_port').val(6379); 42 | $('#new_password').val(''); 43 | $('#new_email').val('不提醒'); 44 | add_redis_btn_click(); 45 | } 46 | 47 | function ping_redis(host, port, password, email) { 48 | // loading.show(); 49 | $('form input').attr("disabled","disabled"); 50 | var ajax = $.ajax({ 51 | type: "POST", 52 | url: '/redis_ping.json', 53 | data: {'host': host, 'port': port, 'password': password}, 54 | success: function(data) { 55 | if (data.success == 1) { 56 | var redis_info = {}; 57 | redis_info['type'] = 'redis'; 58 | redis_info['host'] = host; 59 | redis_info['port'] = port; 60 | redis_info['password'] = password; 61 | redis_info['email'] = email; 62 | redis_info['time'] = new Date().Format("yyyy-MM-dd hh:mm:ss"); 63 | redis_info['timestamp'] = Date.parse(new Date()); 64 | 65 | var key = 'server_' + _server_md5(redis_info); 66 | simpleStorage.set(key, redis_info, 0); 67 | server_servers.push(redis_info); 68 | sort_server_server(); 69 | 70 | add_onerow_2_table(redis_info); 71 | $('form')[0].reset(); 72 | $('form input').removeAttr("disabled"); 73 | // loading.hide(); 74 | } 75 | else { 76 | // loading.hide(); 77 | $('form input').removeAttr("disabled"); 78 | alert(data.data); 79 | } 80 | }, 81 | dataType: 'json', 82 | async: true, 83 | }); 84 | } 85 | 86 | 87 | //点击添加按钮 88 | function add_redis_btn_click() { 89 | var host = $('#new_host').val() || ''; 90 | var port = Number($('#new_port').val()) || 6379; 91 | var password = $('#new_password').val() || ''; 92 | 93 | var email = $('#new_email').val() || ''; 94 | 95 | if (host == '') { 96 | alert('redis 主机IP不能为空!'); 97 | return ; 98 | } 99 | 100 | ping_redis(host, port, password, email); 101 | } 102 | 103 | //删除server 104 | function del_server_btn_click(server_md5) { 105 | var server_key = 'server_' + server_md5 106 | simpleStorage.deleteKey(server_key); 107 | $('#' + server_md5).remove(); 108 | } 109 | 110 | 111 | //清空table信息 112 | function _flush_table() { 113 | $('#server_table tbody td').remove(); 114 | } 115 | 116 | //添加一行server信息 117 | function add_onerow_2_table(server) { 118 | var table = $('#server_table tbody tr:nth(0)'); 119 | var md5_key = _server_md5(server); 120 | //删除已经存在的tr 121 | $('#' + md5_key).remove(); 122 | var html = '' +server['type']+ '' + server['host'] + ':' + server['port'] + ' alert to ' + (server['email'] || 'nobody') + ''+server['time']+''; 123 | table.after(html); 124 | } 125 | 126 | //填充table信息 127 | function fill_server_table() { 128 | _flush_table(); 129 | var server = null; 130 | for (var i in server_servers) { 131 | server = server_servers[i]; 132 | add_onerow_2_table(server); 133 | } 134 | } 135 | load_all_server_from_storage(); 136 | fill_server_table(); -------------------------------------------------------------------------------- /app/static/res/js/redis_monitor.js: -------------------------------------------------------------------------------- 1 | var intervalTime = 1100; //监控频率 2 | var is_start = true; //已经开始监控 3 | 4 | function monitor_task() { 5 | if (is_start) { 6 | get_server_data(); 7 | } 8 | else { 9 | setTimeout(monitor_task, intervalTime); 10 | } 11 | } 12 | 13 | function sec_2_hour(sec) { 14 | var h = parseInt(sec / 3600); 15 | var m = parseInt((sec - h * 3600) / 60) 16 | var s = sec - h * 3600 - m * 60; 17 | return h + ':' + m + ':' + s; 18 | } 19 | 20 | function fill_data_table(data) { 21 | var keys = ['redis_version', 'os', 'process_id', 'uptime_in_seconds', 'connected_clients', 'blocked_clients', 22 | 'total_connections_received', 'total_commands_processed', 'instantaneous_ops_per_sec', 'rejected_connections', 'expired_keys', 'evicted_keys', 'keyspace_hits', 'keyspace_misses'] 23 | var key = null; 24 | for (var i in keys) { 25 | key = keys[i]; 26 | if (key == 'uptime_in_seconds') { 27 | $('#' + key).text(sec_2_hour(data[key])); 28 | } 29 | else { 30 | $('#' + key).text(data[key]); 31 | } 32 | } 33 | 34 | //遍历key中以db开头的,标示不同的数据库 35 | var html = ""; 36 | for (var key in data) { 37 | if (key.substring(0, 2) == 'db') { 38 | html = html + ''+key+''+data[key].keys+''+data[key].expires+''+data[key].avg_ttl+''; 39 | } 40 | } 41 | //删除已有的,append新增的 42 | $('tr.rb_td').remove(); 43 | $('#data_table tbody').append(html); 44 | } 45 | 46 | function do_server_status(data) { 47 | var x_date = (new Date()).toLocaleTimeString().replace(/^\D*/,''); 48 | if (data.success == 1) { 49 | fill_data_table(data.data); 50 | //update charts 51 | timechart.addData([ 52 | [ 53 | 0, // 系列索引 54 | data.data.get_time, 55 | false, 56 | false, 57 | x_date 58 | ] 59 | ]); 60 | opschart.addData([ 61 | [ 62 | 0, 63 | data.data.instantaneous_ops_per_sec, 64 | false, 65 | false, 66 | x_date 67 | ] 68 | ]); 69 | memchart.addData([ 70 | [ 71 | 0, 72 | (data.data.used_memory / 1024).toFixed(2), 73 | false, 74 | false, 75 | x_date 76 | ],[ 77 | 1, 78 | (data.data.used_memory_rss / 1024).toFixed(2), 79 | false, 80 | false, 81 | x_date 82 | ] 83 | ]); 84 | 85 | cpuchart.addData([ 86 | [ 87 | 0, 88 | data.data.used_cpu_sys, 89 | false, 90 | false, 91 | x_date 92 | ],[ 93 | 1, 94 | data.data.used_cpu_user, 95 | false, 96 | false, 97 | x_date 98 | ],[ 99 | 2, 100 | data.data.used_cpu_user_children, 101 | false, 102 | false, 103 | x_date 104 | ],[ 105 | 3, 106 | data.data.used_cpu_sys_children, 107 | false, 108 | false, 109 | x_date 110 | ] 111 | 112 | ]); 113 | } 114 | else { 115 | //填充空的数据 116 | timechart.addData([[0, 0, false, false, x_date ]]) 117 | opschart.addData([[0, 0, false, false, x_date ]]) 118 | memchart.addData([[0, 0, false, false, x_date ], [0, 0, false, false, x_date ]]) 119 | cpuchart.addData([[0, 0, false, false, x_date ], [1, 0, false, false, x_date ], [2, 0, false, false, x_date ], [3, 0, false, false, x_date ]]) 120 | } 121 | setTimeout(monitor_task, intervalTime); 122 | } 123 | 124 | function get_server_data() { 125 | var ajax = $.ajax({ 126 | type: "POST", 127 | url: '/server_information.json', 128 | timeout: 5000, 129 | data: {'type': 'redis', 'host': server_info['host'], 'port': server_info['port'], 'password': server_info['password']}, 130 | success: do_server_status, 131 | dataType: 'json', 132 | async: true, 133 | }); 134 | } 135 | 136 | 137 | //line图 138 | function get_line_option(text, subtext, legend, yAxis_name, y_format) { 139 | option = { 140 | title : { 141 | text: text, 142 | subtext: subtext 143 | }, 144 | tooltip : { 145 | trigger: 'axis' 146 | }, 147 | legend: { 148 | data:legend 149 | }, 150 | toolbox: { 151 | show : true, 152 | feature : { 153 | mark : {show: true}, 154 | dataView : {show: true, readOnly: false}, 155 | magicType : {show: true, type: ['line', 'bar']}, 156 | restore : {show: true}, 157 | saveAsImage : {show: true} 158 | } 159 | }, 160 | dataZoom : { 161 | show : false, 162 | start : 0, 163 | end : 100 164 | }, 165 | xAxis : [{ 166 | type : 'category', 167 | boundaryGap : true, 168 | data : (function (){ 169 | var now = new Date(); 170 | var res = []; 171 | var len = 100; 172 | while (len--) { 173 | res.unshift(now.toLocaleTimeString().replace(/^\D*/,'')); 174 | now = new Date(now - 2000); 175 | } 176 | return res; 177 | })() 178 | }], 179 | yAxis : [{ 180 | type : 'value', 181 | scale: true, 182 | name : yAxis_name, 183 | axisLabel : { 184 | formatter: '{value} ' + y_format 185 | } 186 | }], 187 | series : [] 188 | }; 189 | var tmp = null; 190 | var s = null; 191 | for (var i in legend) { 192 | tmp = legend[i]; 193 | s = { 194 | name:tmp, 195 | type:'line', 196 | data:(function (){ 197 | var res = []; 198 | var len = 100; 199 | while (len--) { 200 | res.push(0.0); 201 | } 202 | return res; 203 | })() 204 | } 205 | option.series.push(s); 206 | } 207 | return option; 208 | } 209 | 210 | //########################### 211 | var server_info; 212 | 213 | function get_server_key() { 214 | var server_md5 = $('#wrapper').attr('server_md5'); 215 | server_md5 = "server_" + server_md5; 216 | return server_md5; 217 | } 218 | 219 | function fill_page(key) { 220 | server_info = get_server(key); 221 | if (server_info) { 222 | $('.server_host_port').text(server_info['host'] + ':' + server_info['port']); 223 | 224 | //添加其他redis信息 225 | $('#other_server li').remove(); 226 | var server = null; 227 | var html = ''; 228 | for (var i in server_servers) { 229 | server = server_servers[i]; 230 | html = '
  • '+ server['host'] + ':' + server['port'] +'
  • '; 231 | $('#other_server').append(html); 232 | } 233 | } 234 | else { 235 | $('#wrapper').html('

    不存在这个Server实例。

    ') 236 | } 237 | } 238 | //########################### 239 | 240 | 241 | var echarts = null; 242 | 243 | var timechart = null; 244 | var opschart = null; 245 | var memchart = null; 246 | var cpuchart = null; 247 | require.config({ 248 | paths: { 249 | echarts: '/static/res/lib/echarts/' 250 | } 251 | }); 252 | // 按需加载 253 | require([ 254 | 'echarts', 255 | 'echarts/chart/line', 256 | 'echarts/chart/bar', 257 | ], 258 | function(ec) { 259 | echarts = ec; 260 | 261 | timechart = draw_chart('time_chart', get_line_option('Redis实时联通情况', '', ['连接耗时'], '时间', 'ms')); 262 | opschart = draw_chart('ops_chart', get_line_option('Redis每秒处理命令数', '', ['OPS'], '命令条数', '')); 263 | memchart = draw_chart('mem_chart', get_line_option('Redis内存实时占用情况', '', ['Redis内存占用', '系统分配内存'], '内存占用', ' Kb')); 264 | cpuchart = draw_chart('cpu_chart', get_line_option('Redis实时CPU占用情况', '', ['cpu_user', 'cpu_sys', 'cpu_user_children', 'cpu_sys_children'], 'CPU消耗', '')); 265 | //开启监控 266 | 267 | load_all_server_from_storage(); //加载本地数据 268 | fill_page(get_server_key()); 269 | monitor_task(); 270 | } 271 | ); 272 | function draw_chart(e_id, option) { 273 | var eChart = echarts.init(document.getElementById(e_id)); 274 | eChart.setOption(option); 275 | return eChart 276 | } 277 | 278 | -------------------------------------------------------------------------------- /app/static/res/lib/echarts/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/static/res/lib/echarts/.DS_Store -------------------------------------------------------------------------------- /app/static/res/lib/echarts/chart/bar.js: -------------------------------------------------------------------------------- 1 | define("echarts/chart/bar",["require","./base","zrender/shape/Rectangle","../component/axis","../component/grid","../component/dataZoom","../config","../util/ecData","zrender/tool/util","zrender/tool/color","../chart"],function(e){function t(e,t,n,a,o){i.call(this,e,t,n,a,o),this.refresh(a)}var i=e("./base"),n=e("zrender/shape/Rectangle");e("../component/axis"),e("../component/grid"),e("../component/dataZoom");var a=e("../config");a.bar={zlevel:0,z:2,clickable:!0,legendHoverLink:!0,xAxisIndex:0,yAxisIndex:0,barMinHeight:0,barGap:"30%",barCategoryGap:"20%",itemStyle:{normal:{barBorderColor:"#fff",barBorderRadius:0,barBorderWidth:0,label:{show:!1}},emphasis:{barBorderColor:"#fff",barBorderRadius:0,barBorderWidth:0,label:{show:!1}}}};var o=e("../util/ecData"),r=e("zrender/tool/util"),s=e("zrender/tool/color");return t.prototype={type:a.CHART_TYPE_BAR,_buildShape:function(){this._buildPosition()},_buildNormal:function(e,t,i,o,r){for(var s,l,h,d,c,m,p,u,V,U,g,f,y=this.series,b=i[0][0],_=y[b],x="horizontal"==r,k=this.component.xAxis,v=this.component.yAxis,L=x?k.getAxis(_.xAxisIndex):v.getAxis(_.yAxisIndex),w=this._mapSize(L,i),W=w.gap,X=w.barGap,I=w.barWidthMap,S=w.barMaxWidthMap,K=w.barWidth,C=w.barMinHeightMap,T=w.interval,E=this.deepQuery([this.ecTheme,a],"island.r"),z=0,A=t;A>z&&null!=L.getNameByIndex(z);z++){x?d=L.getCoordByIndex(z)-W/2:c=L.getCoordByIndex(z)+W/2;for(var M=0,F=i.length;F>M;M++){var J=y[i[M][0]].yAxisIndex||0,P=y[i[M][0]].xAxisIndex||0;s=x?v.getAxis(J):k.getAxis(P),p=m=V=u=s.getCoord(0);for(var O=0,D=i[M].length;D>O;O++)b=i[M][O],_=y[b],g=_.data[z],f=this.getDataFromOption(g,"-"),o[b]=o[b]||{min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY,sum:0,counter:0,average:0},h=Math.min(S[b]||Number.MAX_VALUE,I[b]||K),"-"!==f&&(f>0?(l=O>0?s.getCoordSize(f):x?p-s.getCoord(f):s.getCoord(f)-p,1===D&&C[b]>l&&(l=C[b]),x?(m-=l,c=m):(d=m,m+=l)):0>f?(l=O>0?s.getCoordSize(f):x?s.getCoord(f)-V:V-s.getCoord(f),1===D&&C[b]>l&&(l=C[b]),x?(c=u,u+=l):(u-=l,d=u)):(l=0,x?(m-=l,c=m):(d=m,m+=l)),o[b][z]=x?d+h/2:c-h/2,o[b].min>f&&(o[b].min=f,x?(o[b].minY=c,o[b].minX=o[b][z]):(o[b].minX=d+l,o[b].minY=o[b][z])),o[b].maxO;O++)b=i[M][O],_=y[b],g=_.data[z],f=this.getDataFromOption(g,"-"),h=Math.min(S[b]||Number.MAX_VALUE,I[b]||K),"-"==f&&this.deepQuery([g,_,this.option],"calculable")&&(x?(m-=E,c=m):(d=m,m+=E),U=this._getBarItem(b,z,L.getNameByIndex(z),d,c-(x?0:h),x?h:E,x?E:h,x?"vertical":"horizontal"),U.hoverable=!1,U.draggable=!1,U.style.lineWidth=1,U.style.brushType="stroke",U.style.strokeColor=_.calculableHolderColor||this.ecTheme.calculableHolderColor||a.calculableHolderColor,this.shapeList.push(new n(U)));x?d+=h+X:c-=h+X}}this._calculMarkMapXY(o,i,x?"y":"x")},_buildHorizontal:function(e,t,i,n){return this._buildNormal(e,t,i,n,"horizontal")},_buildVertical:function(e,t,i,n){return this._buildNormal(e,t,i,n,"vertical")},_buildOther:function(e,t,i,a){for(var o=this.series,r=0,s=i.length;s>r;r++)for(var l=0,h=i[r].length;h>l;l++){var d=i[r][l],c=o[d],m=c.xAxisIndex||0,p=this.component.xAxis.getAxis(m),u=p.getCoord(0),V=c.yAxisIndex||0,U=this.component.yAxis.getAxis(V),g=U.getCoord(0);a[d]=a[d]||{min0:Number.POSITIVE_INFINITY,min1:Number.POSITIVE_INFINITY,max0:Number.NEGATIVE_INFINITY,max1:Number.NEGATIVE_INFINITY,sum0:0,sum1:0,counter0:0,counter1:0,average0:0,average1:0};for(var f=0,y=c.data.length;y>f;f++){var b=c.data[f],_=this.getDataFromOption(b,"-");if(_ instanceof Array){var x,k,v=p.getCoord(_[0]),L=U.getCoord(_[1]),w=[b,c],W=this.deepQuery(w,"barWidth")||10,X=this.deepQuery(w,"barHeight");null!=X?(x="horizontal",_[0]>0?(W=v-u,v-=W):W=_[0]<0?u-v:0,k=this._getBarItem(d,f,_[0],v,L-X/2,W,X,x)):(x="vertical",_[1]>0?X=g-L:_[1]<0?(X=L-g,L-=X):X=0,k=this._getBarItem(d,f,_[0],v-W/2,L,W,X,x)),this.shapeList.push(new n(k)),v=p.getCoord(_[0]),L=U.getCoord(_[1]),a[d].min0>_[0]&&(a[d].min0=_[0],a[d].minY0=L,a[d].minX0=v),a[d].max0<_[0]&&(a[d].max0=_[0],a[d].maxY0=L,a[d].maxX0=v),a[d].sum0+=_[0],a[d].counter0++,a[d].min1>_[1]&&(a[d].min1=_[1],a[d].minY1=L,a[d].minX1=v),a[d].max1<_[1]&&(a[d].max1=_[1],a[d].maxY1=L,a[d].maxX1=v),a[d].sum1+=_[1],a[d].counter1++}}}this._calculMarkMapXY(a,i,"xy")},_mapSize:function(e,t,i){var n,a,o=this._findSpecialBarSzie(t,i),r=o.barWidthMap,s=o.barMaxWidthMap,l=o.barMinHeightMap,h=o.sBarWidthCounter,d=o.sBarWidthTotal,c=o.barGap,m=o.barCategoryGap,p=1;if(t.length!=h){if(i)n=e.getGap(),c=0,a=+(n/t.length).toFixed(2),0>=a&&(p=Math.floor(t.length/n),a=1);else if(n="string"==typeof m&&m.match(/%$/)?(e.getGap()*(100-parseFloat(m))/100).toFixed(2)-0:e.getGap()-m,"string"==typeof c&&c.match(/%$/)?(c=parseFloat(c)/100,a=+((n-d)/((t.length-1)*c+t.length-h)).toFixed(2),c=a*c):(c=parseFloat(c),a=+((n-d-c*(t.length-1))/(t.length-h)).toFixed(2)),0>=a)return this._mapSize(e,t,!0)}else if(n=h>1?"string"==typeof m&&m.match(/%$/)?+(e.getGap()*(100-parseFloat(m))/100).toFixed(2):e.getGap()-m:d,a=0,c=h>1?+((n-d)/(h-1)).toFixed(2):0,0>c)return this._mapSize(e,t,!0);return this._recheckBarMaxWidth(t,r,s,l,n,a,c,p)},_findSpecialBarSzie:function(e,t){for(var i,n,a,o,r=this.series,s={},l={},h={},d=0,c=0,m=0,p=e.length;p>m;m++)for(var u={barWidth:!1,barMaxWidth:!1},V=0,U=e[m].length;U>V;V++){var g=e[m][V],f=r[g];if(!t){if(u.barWidth)s[g]=i;else if(i=this.query(f,"barWidth"),null!=i){s[g]=i,c+=i,d++,u.barWidth=!0;for(var y=0,b=V;b>y;y++){var _=e[m][y];s[_]=i}}if(u.barMaxWidth)l[g]=n;else if(n=this.query(f,"barMaxWidth"),null!=n){l[g]=n,u.barMaxWidth=!0;for(var y=0,b=V;b>y;y++){var _=e[m][y];l[_]=n}}}h[g]=this.query(f,"barMinHeight"),a=null!=a?a:this.query(f,"barGap"),o=null!=o?o:this.query(f,"barCategoryGap")}return{barWidthMap:s,barMaxWidthMap:l,barMinHeightMap:h,sBarWidth:i,sBarMaxWidth:n,sBarWidthCounter:d,sBarWidthTotal:c,barGap:a,barCategoryGap:o}},_recheckBarMaxWidth:function(e,t,i,n,a,o,r,s){for(var l=0,h=e.length;h>l;l++){var d=e[l][0];i[d]&&i[d]0&&y.height>f&&y.width>f?(y.y+=f/2,y.height-=f,y.x+=f/2,y.width-=f):y.brushType="fill",d.highlightStyle.textColor=d.highlightStyle.color,d=this.addLabel(d,m,p,i,h);for(var b=[y,d.highlightStyle],_=0,x=b.length;x>_;_++){var k=b[_].textPosition;if("insideLeft"===k||"insideRight"===k||"insideTop"===k||"insideBottom"===k){var v=5;switch(k){case"insideLeft":b[_].textX=y.x+v,b[_].textY=y.y+y.height/2,b[_].textAlign="left",b[_].textBaseline="middle";break;case"insideRight":b[_].textX=y.x+y.width-v,b[_].textY=y.y+y.height/2,b[_].textAlign="right",b[_].textBaseline="middle";break;case"insideTop":b[_].textX=y.x+y.width/2,b[_].textY=y.y+v/2,b[_].textAlign="center",b[_].textBaseline="top";break;case"insideBottom":b[_].textX=y.x+y.width/2,b[_].textY=y.y+y.height-v/2,b[_].textAlign="center",b[_].textBaseline="bottom"}b[_].textPosition="specific",b[_].textColor=b[_].textColor||"#fff"}}return this.deepQuery([p,m,this.option],"calculable")&&(this.setCalculable(d),d.draggable=!0),o.pack(d,c[e],e,c[e].data[t],t,i),d},getMarkCoord:function(e,t){var i,n,a=this.series[e],o=this.xMarkMap[e],r=this.component.xAxis.getAxis(a.xAxisIndex),s=this.component.yAxis.getAxis(a.yAxisIndex);if(!t.type||"max"!==t.type&&"min"!==t.type&&"average"!==t.type)if(o.isHorizontal){i="string"==typeof t.xAxis&&r.getIndexByName?r.getIndexByName(t.xAxis):t.xAxis||0;var l=o[i];l=null!=l?l:"string"!=typeof t.xAxis&&r.getCoordByIndex?r.getCoordByIndex(t.xAxis||0):r.getCoord(t.xAxis||0),n=[l,s.getCoord(t.yAxis||0)]}else{i="string"==typeof t.yAxis&&s.getIndexByName?s.getIndexByName(t.yAxis):t.yAxis||0;var h=o[i];h=null!=h?h:"string"!=typeof t.yAxis&&s.getCoordByIndex?s.getCoordByIndex(t.yAxis||0):s.getCoord(t.yAxis||0),n=[r.getCoord(t.xAxis||0),h]}else{var d=null!=t.valueIndex?t.valueIndex:null!=o.maxX0?"1":"";n=[o[t.type+"X"+d],o[t.type+"Y"+d],o[t.type+"Line"+d],o[t.type+d]]}return n},refresh:function(e){e&&(this.option=e,this.series=e.series),this.backupShapeList(),this._buildShape()},addDataAnimation:function(e,t){function i(){V--,0===V&&t&&t()}for(var n=this.series,a={},r=0,s=e.length;s>r;r++)a[e[r][0]]=e[r];for(var l,h,d,c,m,p,u,V=0,r=this.shapeList.length-1;r>=0;r--)if(p=o.get(this.shapeList[r],"seriesIndex"),a[p]&&!a[p][3]&&"rectangle"===this.shapeList[r].type){if(u=o.get(this.shapeList[r],"dataIndex"),m=n[p],a[p][2]&&u===m.data.length-1){this.zr.delShape(this.shapeList[r].id);continue}if(!a[p][2]&&0===u){this.zr.delShape(this.shapeList[r].id);continue}"horizontal"===this.shapeList[r]._orient?(c=this.component.yAxis.getAxis(m.yAxisIndex||0).getGap(),d=a[p][2]?-c:c,l=0):(h=this.component.xAxis.getAxis(m.xAxisIndex||0).getGap(),l=a[p][2]?h:-h,d=0),this.shapeList[r].position=[0,0],V++,this.zr.animate(this.shapeList[r].id,"").when(this.query(this.option,"animationDurationUpdate"),{position:[l,d]}).done(i).start()}V||t&&t()}},r.inherits(t,i),e("../chart").define("bar",t),t}); -------------------------------------------------------------------------------- /app/static/res/lib/echarts/chart/chord.js: -------------------------------------------------------------------------------- 1 | define("echarts/chart/chord",["require","./base","zrender/shape/Text","zrender/shape/Line","zrender/shape/Sector","../util/shape/Ribbon","../util/shape/Icon","zrender/shape/BezierCurve","../config","../util/ecData","zrender/tool/util","zrender/tool/vector","../data/Graph","../layout/Chord","../chart"],function(e){"use strict";function t(e,t,n,a,o){i.call(this,e,t,n,a,o),this.scaleLineLength=4,this.scaleUnitAngle=4,this.refresh(a)}var i=e("./base"),n=e("zrender/shape/Text"),a=e("zrender/shape/Line"),o=e("zrender/shape/Sector"),r=e("../util/shape/Ribbon"),s=e("../util/shape/Icon"),l=e("zrender/shape/BezierCurve"),h=e("../config");h.chord={zlevel:0,z:2,clickable:!0,radius:["65%","75%"],center:["50%","50%"],padding:2,sort:"none",sortSub:"none",startAngle:90,clockWise:!0,ribbonType:!0,minRadius:10,maxRadius:20,symbol:"circle",showScale:!1,showScaleText:!1,itemStyle:{normal:{borderWidth:0,borderColor:"#000",label:{show:!0,rotate:!1,distance:5},chordStyle:{width:1,color:"black",borderWidth:1,borderColor:"#999",opacity:.5}},emphasis:{borderWidth:0,borderColor:"#000",chordStyle:{width:1,color:"black",borderWidth:1,borderColor:"#999"}}}};var d=e("../util/ecData"),c=e("zrender/tool/util"),p=e("zrender/tool/vector"),m=e("../data/Graph"),u=e("../layout/Chord");return t.prototype={type:h.CHART_TYPE_CHORD,_init:function(){var e=this.series;this.selectedMap={};for(var t={},i={},n=0,a=e.length;a>n;n++)if(e[n].type===this.type){var o=this.isSelected(e[n].name);this.selectedMap[e[n].name]=o,o&&this.buildMark(n),this.reformOption(e[n]),t[e[n].name]=e[n]}for(var n=0,a=e.length;a>n;n++)if(e[n].type===this.type)if(e[n].insertToSerie){var r=t[e[n].insertToSerie];e[n]._referenceSerie=r}else i[e[n].name]=[e[n]];for(var n=0,a=e.length;a>n;n++)if(e[n].type===this.type&&e[n].insertToSerie){for(var s=e[n]._referenceSerie;s&&s._referenceSerie;)s=s._referenceSerie;i[s.name]&&this.selectedMap[e[n].name]&&i[s.name].push(e[n])}for(var l in i)this._buildChords(i[l]);this.addShapeList()},_getNodeCategory:function(e,t){return e.categories&&e.categories[t.category||0]},_getNodeQueryTarget:function(e,t){var i=this._getNodeCategory(e,t);return[t,i,e]},_getEdgeQueryTarget:function(e,t,i){return i=i||"normal",[t.itemStyle&&t.itemStyle[i],e.itemStyle[i].chordStyle]},_buildChords:function(e){for(var t=[],i=e[0],n=function(e){return e.layout.size>0},a=function(e){return function(t){return e.getEdge(t.node2,t.node1)}},o=0;oa;a++){var r=n[a];if(r&&!r.ignore){var s=this._getNodeCategory(t,r),l=s?s.name:r.name;if(this.selectedMap[l]=this.isSelected(l),this.selectedMap[l]){var h=i.addNode(r.name,r);h.rawIndex=a}}}for(var a=0,o=e.links.length;o>a;a++){var d=e.links[a],c=d.source,p=d.target;"number"==typeof c&&(c=n[c],c&&(c=c.name)),"number"==typeof p&&(p=n[p],p&&(p=p.name));var u=i.addEdge(c,p,d);u&&(u.rawIndex=a)}return i.eachNode(function(e){var i=e.data.value;if(null==i)if(i=0,t.ribbonType)for(var n=0;n0&&(u.style.brushType="both"),u.highlightStyle.lineWidth>0&&(u.highlightStyle.brushType="both"),d.pack(u,e,t,i.data,i.rawIndex,i.id,i.category),this.shapeList.push(u),i.shape=u},this)},_buildNodeIcons:function(e,t,i,n){var a=this.parseCenter(this.zr,n.center),o=this.parseRadius(this.zr,n.radius),r=o[1];i.eachNode(function(i){var o=i.layout.startAngle,l=i.layout.endAngle,h=(o+l)/2,c=r*Math.cos(h),p=r*Math.sin(h),m=this._getNodeQueryTarget(n,i.data),u=this._getNodeCategory(n,i.data),g=this.deepQuery(m,"itemStyle.normal.color");g||(g=this.getColor(u?u.name:i.id));var V=new s({zlevel:e.zlevel,z:e.z+1,style:{x:-i.layout.size,y:-i.layout.size,width:2*i.layout.size,height:2*i.layout.size,iconType:this.deepQuery(m,"symbol"),color:g,brushType:"both",lineWidth:this.deepQuery(m,"itemStyle.normal.borderWidth"),strokeColor:this.deepQuery(m,"itemStyle.normal.borderColor")},highlightStyle:{color:this.deepQuery(m,"itemStyle.emphasis.color"),lineWidth:this.deepQuery(m,"itemStyle.emphasis.borderWidth"),strokeColor:this.deepQuery(m,"itemStyle.emphasis.borderColor")},clickable:n.clickable,position:[c+a[0],p+a[1]]});d.pack(V,e,t,i.data,i.rawIndex,i.id,i.category),this.shapeList.push(V),i.shape=V},this)},_buildLabels:function(e,t,i,a){var o=this.query(a,"itemStyle.normal.label.rotate"),r=this.query(a,"itemStyle.normal.label.distance"),s=this.parseCenter(this.zr,a.center),l=this.parseRadius(this.zr,a.radius),h=a.clockWise,d=h?1:-1;i.eachNode(function(t){var i=t.layout.startAngle/Math.PI*180*d,h=t.layout.endAngle/Math.PI*180*d,c=(i*-d+h*-d)/2;c%=360,0>c&&(c+=360);var m=90>=c||c>=270;c=c*Math.PI/180;var u=[Math.cos(c),-Math.sin(c)],g=0;g=a.ribbonType?a.showScaleText?35+r:r:r+t.layout.size;var V=p.scale([],u,l[1]+g);p.add(V,V,s);var y={zlevel:e.zlevel,z:e.z+1,hoverable:!1,style:{text:null==t.data.label?t.id:t.data.label,textAlign:m?"left":"right"}};o?(y.rotation=m?c:Math.PI+c,y.style.x=m?l[1]+g:-l[1]-g,y.style.y=0,y.position=s.slice()):(y.style.x=V[0],y.style.y=V[1]),y.style.color=this.deepQuery([t.data,a],"itemStyle.normal.label.textStyle.color")||"#000000",y.style.textFont=this.getFont(this.deepQuery([t.data,a],"itemStyle.normal.label.textStyle")),y=new n(y),this.shapeList.push(y),t.labelShape=y},this)},_buildRibbons:function(e,t,i,n){var a=e[t],o=this.parseCenter(this.zr,n.center),s=this.parseRadius(this.zr,n.radius);i.eachEdge(function(l,h){var c,p=i.getEdge(l.node2,l.node1);if(p&&!l.shape){if(p.shape)return void(l.shape=p.shape);var m=l.layout.startAngle/Math.PI*180,u=l.layout.endAngle/Math.PI*180,g=p.layout.startAngle/Math.PI*180,V=p.layout.endAngle/Math.PI*180;c=this.getColor(1===e.length?l.layout.weight<=p.layout.weight?l.node1.id:l.node2.id:a.name);var y,f,U=this._getEdgeQueryTarget(a,l.data),_=this._getEdgeQueryTarget(a,l.data,"emphasis"),b=new r({zlevel:a.zlevel,z:a.z,style:{x:o[0],y:o[1],r:s[0],source0:m,source1:u,target0:g,target1:V,brushType:"both",opacity:this.deepQuery(U,"opacity"),color:c,lineWidth:this.deepQuery(U,"borderWidth"),strokeColor:this.deepQuery(U,"borderColor"),clockWise:n.clockWise},clickable:n.clickable,highlightStyle:{brushType:"both",opacity:this.deepQuery(_,"opacity"),lineWidth:this.deepQuery(_,"borderWidth"),strokeColor:this.deepQuery(_,"borderColor")}});l.layout.weight<=p.layout.weight?(y=p.node1,f=p.node2):(y=l.node1,f=l.node2),d.pack(b,a,t,l.data,null==l.rawIndex?h:l.rawIndex,l.data.name||y.id+"-"+f.id,y.id,f.id),this.shapeList.push(b),l.shape=b}},this)},_buildEdgeCurves:function(e,t,i,n,a){var o=e[t],r=this.parseCenter(this.zr,n.center);i.eachEdge(function(e,i){var n=a.getNodeById(e.node1.id),s=a.getNodeById(e.node2.id),h=n.shape,c=s.shape,p=this._getEdgeQueryTarget(o,e.data),m=this._getEdgeQueryTarget(o,e.data,"emphasis"),u=new l({zlevel:o.zlevel,z:o.z,style:{xStart:h.position[0],yStart:h.position[1],xEnd:c.position[0],yEnd:c.position[1],cpX1:r[0],cpY1:r[1],lineWidth:this.deepQuery(p,"width"),strokeColor:this.deepQuery(p,"color"),opacity:this.deepQuery(p,"opacity")},highlightStyle:{lineWidth:this.deepQuery(m,"width"),strokeColor:this.deepQuery(m,"color"),opacity:this.deepQuery(m,"opacity")}});d.pack(u,o,t,e.data,null==e.rawIndex?i:e.rawIndex,e.data.name||e.node1.id+"-"+e.node2.id,e.node1.id,e.node2.id),this.shapeList.push(u),e.shape=u},this)},_buildScales:function(e,t,i){var o,r,s=e.clockWise,l=this.parseCenter(this.zr,e.center),h=this.parseRadius(this.zr,e.radius),d=s?1:-1,c=0,m=-(1/0);e.showScaleText&&(i.eachNode(function(e){var t=e.data.value;t>m&&(m=t),c+=t}),m>1e10?(o="b",r=1e-9):m>1e7?(o="m",r=1e-6):m>1e4?(o="k",r=.001):(o="",r=1));var u=c/(360-e.padding);i.eachNode(function(t){for(var i=t.layout.startAngle/Math.PI*180,c=t.layout.endAngle/Math.PI*180,m=i;;){if(s&&m>c||!s&&c>m)break;var g=m/180*Math.PI,V=[Math.cos(g),Math.sin(g)],y=p.scale([],V,h[1]+1);p.add(y,y,l);var f=p.scale([],V,h[1]+this.scaleLineLength);p.add(f,f,l);var U=new a({zlevel:e.zlevel,z:e.z-1,hoverable:!1,style:{xStart:y[0],yStart:y[1],xEnd:f[0],yEnd:f[1],lineCap:"round",brushType:"stroke",strokeColor:"#666",lineWidth:1}});this.shapeList.push(U),m+=d*this.scaleUnitAngle}if(e.showScaleText)for(var _=i,b=5*u*this.scaleUnitAngle,x=0;;){if(s&&_>c||!s&&c>_)break;var g=_;g%=360,0>g&&(g+=360);var k=90>=g||g>=270,v=new n({zlevel:e.zlevel,z:e.z-1,hoverable:!1,style:{x:k?h[1]+this.scaleLineLength+4:-h[1]-this.scaleLineLength-4,y:0,text:Math.round(10*x)/10+o,textAlign:k?"left":"right"},position:l.slice(),rotation:k?[-g/180*Math.PI,0,0]:[-(g+180)/180*Math.PI,0,0]});this.shapeList.push(v),x+=b*r,_+=d*this.scaleUnitAngle*5}},this)},refresh:function(e){if(e&&(this.option=e,this.series=e.series),this.legend=this.component.legend,this.legend)this.getColor=function(e){return this.legend.getColor(e)},this.isSelected=function(e){return this.legend.isSelected(e)};else{var t={},i=0;this.getColor=function(e){return t[e]?t[e]:(t[e]||(t[e]=this.zr.getColor(i++)),t[e])},this.isSelected=function(){return!0}}this.backupShapeList(),this._init()},reformOption:function(e){var t=c.merge;e=t(t(e||{},this.ecTheme.chord),h.chord),e.itemStyle.normal.label.textStyle=this.getTextStyle(e.itemStyle.normal.label.textStyle),this.z=e.z,this.zlevel=e.zlevel}},c.inherits(t,i),e("../chart").define("chord",t),t}),define("echarts/util/shape/Ribbon",["require","zrender/shape/Base","zrender/shape/util/PathProxy","zrender/tool/util","zrender/tool/area"],function(e){function t(e){i.call(this,e),this._pathProxy=new n}var i=e("zrender/shape/Base"),n=e("zrender/shape/util/PathProxy"),a=e("zrender/tool/util"),o=e("zrender/tool/area");return t.prototype={type:"ribbon",buildPath:function(e,t){var i=t.clockWise||!1,n=this._pathProxy;n.begin(e);var a=t.x,o=t.y,r=t.r,s=t.source0/180*Math.PI,l=t.source1/180*Math.PI,h=t.target0/180*Math.PI,d=t.target1/180*Math.PI,c=a+Math.cos(s)*r,p=o+Math.sin(s)*r,m=a+Math.cos(l)*r,u=o+Math.sin(l)*r,g=a+Math.cos(h)*r,V=o+Math.sin(h)*r,y=a+Math.cos(d)*r,f=o+Math.sin(d)*r;n.moveTo(c,p),n.arc(a,o,t.r,s,l,!i),n.bezierCurveTo(.7*(a-m)+m,.7*(o-u)+u,.7*(a-g)+g,.7*(o-V)+V,g,V),(t.source0!==t.target0||t.source1!==t.target1)&&(n.arc(a,o,t.r,h,d,!i),n.bezierCurveTo(.7*(a-y)+y,.7*(o-f)+f,.7*(a-c)+c,.7*(o-p)+p,c,p))},getRect:function(e){return e.__rect?e.__rect:(this._pathProxy.isEmpty()||this.buildPath(null,e),this._pathProxy.fastBoundingRect())},isCover:function(e,t){var i=this.getRect(this.style);return e>=i.x&&e<=i.x+i.width&&t>=i.y&&t<=i.y+i.height?o.isInsidePath(this._pathProxy.pathCommands,0,"fill",e,t):void 0}},a.inherits(t,i),t}),define("echarts/data/Graph",["require","zrender/tool/util"],function(e){var t=e("zrender/tool/util"),i=function(e){this._directed=e||!1,this.nodes=[],this.edges=[],this._nodesMap={},this._edgesMap={}};i.prototype.isDirected=function(){return this._directed},i.prototype.addNode=function(e,t){if(this._nodesMap[e])return this._nodesMap[e];var n=new i.Node(e,t);return this.nodes.push(n),this._nodesMap[e]=n,n},i.prototype.getNodeById=function(e){return this._nodesMap[e]},i.prototype.addEdge=function(e,t,n){if("string"==typeof e&&(e=this._nodesMap[e]),"string"==typeof t&&(t=this._nodesMap[t]),e&&t){var a=e.id+"-"+t.id;if(this._edgesMap[a])return this._edgesMap[a];var o=new i.Edge(e,t,n);return this._directed&&(e.outEdges.push(o),t.inEdges.push(o)),e.edges.push(o),e!==t&&t.edges.push(o),this.edges.push(o),this._edgesMap[a]=o,o}},i.prototype.removeEdge=function(e){var i=e.node1,n=e.node2,a=i.id+"-"+n.id;this._directed&&(i.outEdges.splice(t.indexOf(i.outEdges,e),1),n.inEdges.splice(t.indexOf(n.inEdges,e),1)),i.edges.splice(t.indexOf(i.edges,e),1),i!==n&&n.edges.splice(t.indexOf(n.edges,e),1),delete this._edgesMap[a],this.edges.splice(t.indexOf(this.edges,e),1)},i.prototype.getEdge=function(e,t){return"string"!=typeof e&&(e=e.id),"string"!=typeof t&&(t=t.id),this._directed?this._edgesMap[e+"-"+t]:this._edgesMap[e+"-"+t]||this._edgesMap[t+"-"+e]},i.prototype.removeNode=function(e){if("string"!=typeof e||(e=this._nodesMap[e])){delete this._nodesMap[e.id],this.nodes.splice(t.indexOf(this.nodes,e),1);for(var i=0;in;)e.call(t,this.nodes[n],n)?n++:(this.removeNode(this.nodes[n]),i--)},i.prototype.filterEdge=function(e,t){for(var i=this.edges.length,n=0;i>n;)e.call(t,this.edges[n],n)?n++:(this.removeEdge(this.edges[n]),i--)},i.prototype.eachNode=function(e,t){for(var i=this.nodes.length,n=0;i>n;n++)this.nodes[n]&&e.call(t,this.nodes[n],n)},i.prototype.eachEdge=function(e,t){for(var i=this.edges.length,n=0;i>n;n++)this.edges[n]&&e.call(t,this.edges[n],n)},i.prototype.clear=function(){this.nodes.length=0,this.edges.length=0,this._nodesMap={},this._edgesMap={}},i.prototype.breadthFirstTraverse=function(e,t,i,n){if("string"==typeof t&&(t=this._nodesMap[t]),t){var a="edges";"out"===i?a="outEdges":"in"===i&&(a="inEdges");for(var o=0;or;r++){var s=o.addNode(e[r].id,e[r]);s.data.value=0,n&&(s.data.outValue=s.data.inValue=0)}for(var r=0;a>r;r++)for(var l=0;a>l;l++){var h=t[r][l];n&&(o.nodes[r].data.outValue+=h,o.nodes[l].data.inValue+=h),o.nodes[r].data.value+=h,o.nodes[l].data.value+=h}for(var r=0;a>r;r++)for(var l=r;a>l;l++){var h=t[r][l];if(0!==h){var d=o.nodes[r],c=o.nodes[l],p=o.addEdge(d,c,{});if(p.data.weight=h,r!==l&&n&&t[l][r]){var m=o.addEdge(c,d,{});m.data.weight=t[l][r]}}}return o}},i}),define("echarts/layout/Chord",["require"],function(){var e=function(e){e=e||{},this.sort=e.sort||null,this.sortSub=e.sortSub||null,this.padding=.05,this.startAngle=e.startAngle||0,this.clockWise=null==e.clockWise?!1:e.clockWise,this.center=e.center||[0,0],this.directed=!0};e.prototype.run=function(e){e instanceof Array||(e=[e]);var n=e.length;if(n){for(var a=e[0],o=a.nodes.length,r=[],s=0,l=0;o>l;l++){var h=a.nodes[l],d={size:0,subGroups:[],node:h};r.push(d);for(var c=0,p=0;pl;l++){var d=r[l];d.node.layout.startAngle=_,d.node.layout.endAngle=_+b*d.size*U,d.node.layout.subGroups=[];for(var V=0;Vn;n++)if(i[n].type===this.type){e=this.component.xAxis.getAxis(i[n].xAxisIndex||0);for(var o=0,r=i[n].data.length;r>o;o++){t=i[n].data[o].evolution;for(var l=0,h=t.length;h>l;l++)t[l].timeScale=e.getCoord(s.getNewDate(t[l].time)-0),t[l].valueScale=Math.pow(t[l].value,.8)}}this._intervalX=Math.round(this.component.grid.getWidth()/40)},_drawEventRiver:function(){for(var e=this.series,t=0;ta)){for(var o=[],r=[],s=0;a>s;s++)o.push(n[s].timeScale),r.push(n[s].valueScale);var l=[];l.push([o[0],i]);var s=0;for(s=0;a-1>s;s++)l.push([(o[s]+o[s+1])/2,r[s]/-2+i]);for(l.push([(o[s]+(o[s]+t))/2,r[s]/-2+i]),l.push([o[s]+t,i]),l.push([(o[s]+(o[s]+t))/2,r[s]/2+i]),s=a-1;s>0;s--)l.push([(o[s]+o[s-1])/2,r[s-1]/2+i]);return l}},ondragend:function(e,t){this.isDragend&&e.target&&(t.dragOut=!0,t.dragIn=!0,t.needRefresh=!1,this.isDragend=!1)},refresh:function(e){e&&(this.option=e,this.series=e.series),this.backupShapeList(),this._buildShape()}},l.inherits(t,i),e("../chart").define("eventRiver",t),t}),define("echarts/layout/eventRiver",["require"],function(){function e(e,i,o){function r(e,t){var i=e.importance,n=t.importance;return i>n?-1:n>i?1:0}for(var s=4,l=0;l=e)return[0];for(var t=[];e--;)t.push(0);return t}(),u=c.slice(0),y=[],g=0,b=0,l=0;l.5?.5:1,r=t.y,s=(t.height-n)/i,l=0,h=e.length;h>l;l++){var m=e[l];m.y=r+s*m.y+m._offset*o,delete m.time,delete m.value,delete m.xpx,delete m.ypx,delete m._offset;for(var V=m.evolution,U=0,d=V.length;d>U;U++)V[U].valueScale*=s}}function i(e,t,i,n){if(e===i)throw new Error("x0 is equal with x1!!!");if(t===n)return function(){return t};var a=(t-n)/(e-i),o=(n*e-t*i)/(e-i);return function(e){return a*e+o}}function n(e,t,n){var a=~~t,o=e.time.length;e.xpx=[],e.ypx=[];for(var r,s=0,l=0,h=0,m=0,V=0;o>s;s++){l=~~e.time[s],m=e.value[s]/2,s===o-1?(h=l+a,V=0):(h=~~e.time[s+1],V=e.value[s+1]/2),r=i(l,m,h,V);for(var U=l;h>U;U++)e.xpx.push(U-n),e.ypx.push(r(U))}e.xpx.push(h-n),e.ypx.push(V)}function a(e,t,i){for(var n,a=0,o=t.xpx.length,r=0;o>r;r++)n=i(t,r),a=Math.max(a,n+e[t.xpx[r]]);for(r=0;o>r;r++)n=i(t,r),e[t.xpx[r]]=a+n;return a}return e}); -------------------------------------------------------------------------------- /app/static/res/lib/echarts/chart/funnel.js: -------------------------------------------------------------------------------- 1 | define("echarts/chart/funnel",["require","./base","zrender/shape/Text","zrender/shape/Line","zrender/shape/Polygon","../config","../util/ecData","../util/number","zrender/tool/util","zrender/tool/color","zrender/tool/area","../chart"],function(e){function t(e,t,n,a,o){i.call(this,e,t,n,a,o),this.refresh(a)}var i=e("./base"),n=e("zrender/shape/Text"),a=e("zrender/shape/Line"),o=e("zrender/shape/Polygon"),r=e("../config");r.funnel={zlevel:0,z:2,clickable:!0,legendHoverLink:!0,x:80,y:60,x2:80,y2:60,min:0,max:100,minSize:"0%",maxSize:"100%",sort:"descending",gap:0,funnelAlign:"center",itemStyle:{normal:{borderColor:"#fff",borderWidth:1,label:{show:!0,position:"outer"},labelLine:{show:!0,length:10,lineStyle:{width:1,type:"solid"}}},emphasis:{borderColor:"rgba(0,0,0,0)",borderWidth:1,label:{show:!0},labelLine:{show:!0}}}};var s=e("../util/ecData"),l=e("../util/number"),h=e("zrender/tool/util"),m=e("zrender/tool/color"),V=e("zrender/tool/area");return t.prototype={type:r.CHART_TYPE_FUNNEL,_buildShape:function(){var e=this.series,t=this.component.legend;this._paramsMap={},this._selected={},this.selectedMap={};for(var i,n=0,a=e.length;a>n;n++)if(e[n].type===r.CHART_TYPE_FUNNEL){if(e[n]=this.reformOption(e[n]),this.legendHoverLink=e[n].legendHoverLink||this.legendHoverLink,i=e[n].name||"",this.selectedMap[i]=t?t.isSelected(i):!0,!this.selectedMap[i])continue;this._buildSingleFunnel(n),this.buildMark(n)}this.addShapeList()},_buildSingleFunnel:function(e){var t=this.component.legend,i=this.series[e],n=this._mapData(e),a=this._getLocation(e);this._paramsMap[e]={location:a,data:n};for(var o,r=0,s=[],h=0,m=n.length;m>h;h++)o=n[h].name,this.selectedMap[o]=t?t.isSelected(o):!0,this.selectedMap[o]&&!isNaN(n[h].value)&&(s.push(n[h]),r++);if(0!==r){for(var V,U,d,p,c=this._buildFunnelCase(e),u=i.funnelAlign,y=i.gap,g=r>1?(a.height-(r-1)*y)/r:a.height,b=a.y,f="descending"===i.sort?this._getItemWidth(e,s[0].value):l.parsePercent(i.minSize,a.width),k="descending"===i.sort?1:0,_=a.centerX,x=[],h=0,m=s.length;m>h;h++)if(o=s[h].name,this.selectedMap[o]&&!isNaN(s[h].value)){switch(V=m-2>=h?this._getItemWidth(e,s[h+k].value):"descending"===i.sort?l.parsePercent(i.minSize,a.width):l.parsePercent(i.maxSize,a.width),u){case"left":U=a.x;break;case"right":U=a.x+a.width-f;break;default:U=_-f/2}d=this._buildItem(e,s[h]._index,t?t.getColor(o):this.zr.getColor(s[h]._index),U,b,f,V,g,u),b+=g+y,p=d.style.pointList,x.unshift([p[0][0]-10,p[0][1]]),x.push([p[1][0]+10,p[1][1]]),0===h&&(0===f?(p=x.pop(),"center"==u&&(x[0][0]+=10),"right"==u&&(x[0][0]=p[0]),x[0][1]-="center"==u?10:15,1==m&&(p=d.style.pointList)):(x[x.length-1][1]-=5,x[0][1]-=5)),f=V}c&&(x.unshift([p[3][0]-10,p[3][1]]),x.push([p[2][0]+10,p[2][1]]),0===f?(p=x.pop(),"center"==u&&(x[0][0]+=10),"right"==u&&(x[0][0]=p[0]),x[0][1]+="center"==u?10:15):(x[x.length-1][1]+=5,x[0][1]+=5),c.style.pointList=x)}},_buildFunnelCase:function(e){var t=this.series[e];if(this.deepQuery([t,this.option],"calculable")){var i=this._paramsMap[e].location,n=10,a={hoverable:!1,style:{pointListd:[[i.x-n,i.y-n],[i.x+i.width+n,i.y-n],[i.x+i.width+n,i.y+i.height+n],[i.x-n,i.y+i.height+n]],brushType:"stroke",lineWidth:1,strokeColor:t.calculableHolderColor||this.ecTheme.calculableHolderColor||r.calculableHolderColor}};return s.pack(a,t,e,void 0,-1),this.setCalculable(a),a=new o(a),this.shapeList.push(a),a}},_getLocation:function(e){var t=this.series[e],i=this.zr.getWidth(),n=this.zr.getHeight(),a=this.parsePercent(t.x,i),o=this.parsePercent(t.y,n),r=null==t.width?i-a-this.parsePercent(t.x2,i):this.parsePercent(t.width,i);return{x:a,y:o,width:r,height:null==t.height?n-o-this.parsePercent(t.y2,n):this.parsePercent(t.height,n),centerX:a+r/2}},_mapData:function(e){function t(e,t){return"-"===e.value?1:"-"===t.value?-1:t.value-e.value}function i(e,i){return-t(e,i)}for(var n=this.series[e],a=h.clone(n.data),o=0,r=a.length;r>o;o++)a[o]._index=o;return"none"!=n.sort&&a.sort("descending"===n.sort?t:i),a},_buildItem:function(e,t,i,n,a,o,r,l,h){var m=this.series,V=m[e],U=V.data[t],d=this.getPolygon(e,t,i,n,a,o,r,l,h);s.pack(d,m[e],e,m[e].data[t],t,m[e].data[t].name),this.shapeList.push(d);var p=this.getLabel(e,t,i,n,a,o,r,l,h);s.pack(p,m[e],e,m[e].data[t],t,m[e].data[t].name),this.shapeList.push(p),this._needLabel(V,U,!1)||(p.invisible=!0);var c=this.getLabelLine(e,t,i,n,a,o,r,l,h);this.shapeList.push(c),this._needLabelLine(V,U,!1)||(c.invisible=!0);var u=[],y=[];return this._needLabelLine(V,U,!0)&&(u.push(c.id),y.push(c.id)),this._needLabel(V,U,!0)&&(u.push(p.id),y.push(d.id)),d.hoverConnect=u,p.hoverConnect=y,d},_getItemWidth:function(e,t){var i=this.series[e],n=this._paramsMap[e].location,a=i.min,o=i.max,r=l.parsePercent(i.minSize,n.width),s=l.parsePercent(i.maxSize,n.width);return(t-a)*(s-r)/(o-a)+r},getPolygon:function(e,t,i,n,a,r,s,l,h){var V,U=this.series[e],d=U.data[t],p=[d,U],c=this.deepMerge(p,"itemStyle.normal")||{},u=this.deepMerge(p,"itemStyle.emphasis")||{},y=this.getItemStyleColor(c.color,e,t,d)||i,g=this.getItemStyleColor(u.color,e,t,d)||("string"==typeof y?m.lift(y,-.2):y);switch(h){case"left":V=n;break;case"right":V=n+(r-s);break;default:V=n+(r-s)/2}var b={zlevel:U.zlevel,z:U.z,clickable:this.deepQuery(p,"clickable"),style:{pointList:[[n,a],[n+r,a],[V+s,a+l],[V,a+l]],brushType:"both",color:y,lineWidth:c.borderWidth,strokeColor:c.borderColor},highlightStyle:{color:g,lineWidth:u.borderWidth,strokeColor:u.borderColor}};return this.deepQuery([d,U,this.option],"calculable")&&(this.setCalculable(b),b.draggable=!0),new o(b)},getLabel:function(e,t,i,a,o,r,s,l,U){var d,p=this.series[e],c=p.data[t],u=this._paramsMap[e].location,y=h.merge(h.clone(c.itemStyle)||{},p.itemStyle),g="normal",b=y[g].label,f=b.textStyle||{},k=y[g].labelLine.length,_=this.getLabelText(e,t,g),x=this.getFont(f),L=i;b.position=b.position||y.normal.label.position,"inner"===b.position||"inside"===b.position||"center"===b.position?(d=U,L=Math.max(r,s)/2>V.getTextWidth(_,x)?"#fff":m.reverse(i)):d="left"===b.position?"right":"left";var W={zlevel:p.zlevel,z:p.z+1,style:{x:this._getLabelPoint(b.position,a,u,r,s,k,U),y:o+l/2,color:f.color||L,text:_,textAlign:f.align||d,textBaseline:f.baseline||"middle",textFont:x}};return g="emphasis",b=y[g].label||b,f=b.textStyle||f,k=y[g].labelLine.length||k,b.position=b.position||y.normal.label.position,_=this.getLabelText(e,t,g),x=this.getFont(f),L=i,"inner"===b.position||"inside"===b.position||"center"===b.position?(d=U,L=Math.max(r,s)/2>V.getTextWidth(_,x)?"#fff":m.reverse(i)):d="left"===b.position?"right":"left",W.highlightStyle={x:this._getLabelPoint(b.position,a,u,r,s,k,U),color:f.color||L,text:_,textAlign:f.align||d,textFont:x,brushType:"fill"},new n(W)},getLabelText:function(e,t,i){var n=this.series,a=n[e],o=a.data[t],r=this.deepQuery([o,a],"itemStyle."+i+".label.formatter");return r?"function"==typeof r?r.call(this.myChart,{seriesIndex:e,seriesName:a.name||"",series:a,dataIndex:t,data:o,name:o.name,value:o.value}):"string"==typeof r?r=r.replace("{a}","{a0}").replace("{b}","{b0}").replace("{c}","{c0}").replace("{a0}",a.name).replace("{b0}",o.name).replace("{c0}",o.value):void 0:o.name},getLabelLine:function(e,t,i,n,o,r,s,l,m){var V=this.series[e],U=V.data[t],d=this._paramsMap[e].location,p=h.merge(h.clone(U.itemStyle)||{},V.itemStyle),c="normal",u=p[c].labelLine,y=p[c].labelLine.length,g=u.lineStyle||{},b=p[c].label;b.position=b.position||p.normal.label.position;var f={zlevel:V.zlevel,z:V.z+1,hoverable:!1,style:{xStart:this._getLabelLineStartPoint(n,d,r,s,m),yStart:o+l/2,xEnd:this._getLabelPoint(b.position,n,d,r,s,y,m),yEnd:o+l/2,strokeColor:g.color||i,lineType:g.type,lineWidth:g.width}};return c="emphasis",u=p[c].labelLine||u,y=p[c].labelLine.length||y,g=u.lineStyle||g,b=p[c].label||b,b.position=b.position,f.highlightStyle={xEnd:this._getLabelPoint(b.position,n,d,r,s,y,m),strokeColor:g.color||i,lineType:g.type,lineWidth:g.width},new a(f)},_getLabelPoint:function(e,t,i,n,a,o,r){switch(e="inner"===e||"inside"===e?"center":e){case"center":return"center"==r?t+n/2:"left"==r?t+10:t+n-10;case"left":return"auto"===o?i.x-10:"center"==r?i.centerX-Math.max(n,a)/2-o:"right"==r?t-(a>n?a-n:0)-o:i.x-o;default:return"auto"===o?i.x+i.width+10:"center"==r?i.centerX+Math.max(n,a)/2+o:"right"==r?i.x+i.width+o:t+Math.max(n,a)+o}},_getLabelLineStartPoint:function(e,t,i,n,a){return"center"==a?t.centerX:n>i?e+Math.min(i,n)/2:e+Math.max(i,n)/2},_needLabel:function(e,t,i){return this.deepQuery([t,e],"itemStyle."+(i?"emphasis":"normal")+".label.show")},_needLabelLine:function(e,t,i){return this.deepQuery([t,e],"itemStyle."+(i?"emphasis":"normal")+".labelLine.show")},refresh:function(e){e&&(this.option=e,this.series=e.series),this.backupShapeList(),this._buildShape()}},h.inherits(t,i),e("../chart").define("funnel",t),t}); -------------------------------------------------------------------------------- /app/static/res/lib/echarts/chart/gauge.js: -------------------------------------------------------------------------------- 1 | define("echarts/chart/gauge",["require","./base","../util/shape/GaugePointer","zrender/shape/Text","zrender/shape/Line","zrender/shape/Rectangle","zrender/shape/Circle","zrender/shape/Sector","../config","../util/ecData","../util/accMath","zrender/tool/util","../chart"],function(e){function t(e,t,n,a,o){i.call(this,e,t,n,a,o),this.refresh(a)}var i=e("./base"),n=e("../util/shape/GaugePointer"),a=e("zrender/shape/Text"),o=e("zrender/shape/Line"),r=e("zrender/shape/Rectangle"),s=e("zrender/shape/Circle"),l=e("zrender/shape/Sector"),h=e("../config");h.gauge={zlevel:0,z:2,center:["50%","50%"],clickable:!0,legendHoverLink:!0,radius:"75%",startAngle:225,endAngle:-45,min:0,max:100,splitNumber:10,axisLine:{show:!0,lineStyle:{color:[[.2,"#228b22"],[.8,"#48b"],[1,"#ff4500"]],width:30}},axisTick:{show:!0,splitNumber:5,length:8,lineStyle:{color:"#eee",width:1,type:"solid"}},axisLabel:{show:!0,textStyle:{color:"auto"}},splitLine:{show:!0,length:30,lineStyle:{color:"#eee",width:2,type:"solid"}},pointer:{show:!0,length:"80%",width:8,color:"auto"},title:{show:!0,offsetCenter:[0,"-40%"],textStyle:{color:"#333",fontSize:15}},detail:{show:!0,backgroundColor:"rgba(0,0,0,0)",borderWidth:0,borderColor:"#ccc",width:100,height:40,offsetCenter:[0,"40%"],textStyle:{color:"auto",fontSize:30}}};var m=e("../util/ecData"),V=e("../util/accMath"),U=e("zrender/tool/util");return t.prototype={type:h.CHART_TYPE_GAUGE,_buildShape:function(){var e=this.series;this._paramsMap={},this.selectedMap={};for(var t=0,i=e.length;i>t;t++)e[t].type===h.CHART_TYPE_GAUGE&&(this.selectedMap[e[t].name]=!0,e[t]=this.reformOption(e[t]),this.legendHoverLink=e[t].legendHoverLink||this.legendHoverLink,this._buildSingleGauge(t),this.buildMark(t));this.addShapeList()},_buildSingleGauge:function(e){var t=this.series[e];this._paramsMap[e]={center:this.parseCenter(this.zr,t.center),radius:this.parseRadius(this.zr,t.radius),startAngle:t.startAngle.toFixed(2)-0,endAngle:t.endAngle.toFixed(2)-0},this._paramsMap[e].totalAngle=this._paramsMap[e].startAngle-this._paramsMap[e].endAngle,this._colorMap(e),this._buildAxisLine(e),this._buildSplitLine(e),this._buildAxisTick(e),this._buildAxisLabel(e),this._buildPointer(e),this._buildTitle(e),this._buildDetail(e)},_buildAxisLine:function(e){var t=this.series[e];if(t.axisLine.show)for(var i,n,a=t.min,o=t.max-a,r=this._paramsMap[e],s=r.center,l=r.startAngle,h=r.totalAngle,V=r.colorArray,U=t.axisLine.lineStyle,d=this.parsePercent(U.width,r.radius[1]),p=r.radius[1],c=p-d,u=l,y=0,g=V.length;g>y;y++)n=l-h*(V[y][0]-a)/o,i=this._getSector(s,c,p,n,u,V[y][1],U,t.zlevel,t.z),u=n,i._animationAdd="r",m.set(i,"seriesIndex",e),m.set(i,"dataIndex",y),this.shapeList.push(i)},_buildSplitLine:function(e){var t=this.series[e];if(t.splitLine.show)for(var i,n,a,r=this._paramsMap[e],s=t.splitNumber,l=t.min,h=t.max-l,m=t.splitLine,V=this.parsePercent(m.length,r.radius[1]),U=m.lineStyle,d=U.color,p=r.center,c=r.startAngle*Math.PI/180,u=r.totalAngle*Math.PI/180,y=r.radius[1],g=y-V,b=0;s>=b;b++)i=c-u/s*b,n=Math.sin(i),a=Math.cos(i),this.shapeList.push(new o({zlevel:t.zlevel,z:t.z+1,hoverable:!1,style:{xStart:p[0]+a*y,yStart:p[1]-n*y,xEnd:p[0]+a*g,yEnd:p[1]-n*g,strokeColor:"auto"===d?this._getColor(e,l+h/s*b):d,lineType:U.type,lineWidth:U.width,shadowColor:U.shadowColor,shadowBlur:U.shadowBlur,shadowOffsetX:U.shadowOffsetX,shadowOffsetY:U.shadowOffsetY}}))},_buildAxisTick:function(e){var t=this.series[e];if(t.axisTick.show)for(var i,n,a,r=this._paramsMap[e],s=t.splitNumber,l=t.min,h=t.max-l,m=t.axisTick,V=m.splitNumber,U=this.parsePercent(m.length,r.radius[1]),d=m.lineStyle,p=d.color,c=r.center,u=r.startAngle*Math.PI/180,y=r.totalAngle*Math.PI/180,g=r.radius[1],b=g-U,f=0,k=s*V;k>=f;f++)f%V!==0&&(i=u-y/k*f,n=Math.sin(i),a=Math.cos(i),this.shapeList.push(new o({zlevel:t.zlevel,z:t.z+1,hoverable:!1,style:{xStart:c[0]+a*g,yStart:c[1]-n*g,xEnd:c[0]+a*b,yEnd:c[1]-n*b,strokeColor:"auto"===p?this._getColor(e,l+h/k*f):p,lineType:d.type,lineWidth:d.width,shadowColor:d.shadowColor,shadowBlur:d.shadowBlur,shadowOffsetX:d.shadowOffsetX,shadowOffsetY:d.shadowOffsetY}})))},_buildAxisLabel:function(e){var t=this.series[e];if(t.axisLabel.show)for(var i,n,o,r,s=t.splitNumber,l=t.min,h=t.max-l,m=t.axisLabel.textStyle,U=this.getFont(m),d=m.color,p=this._paramsMap[e],c=p.center,u=p.startAngle,y=p.totalAngle,g=p.radius[1]-this.parsePercent(t.splitLine.length,p.radius[1])-5,b=0;s>=b;b++)r=V.accAdd(l,V.accMul(V.accDiv(h,s),b)),i=u-y/s*b,n=Math.sin(i*Math.PI/180),o=Math.cos(i*Math.PI/180),i=(i+360)%360,this.shapeList.push(new a({zlevel:t.zlevel,z:t.z+1,hoverable:!1,style:{x:c[0]+o*g,y:c[1]-n*g,color:"auto"===d?this._getColor(e,r):d,text:this._getLabelText(t.axisLabel.formatter,r),textAlign:i>=110&&250>=i?"left":70>=i||i>=290?"right":"center",textBaseline:i>=10&&170>=i?"top":i>=190&&350>=i?"bottom":"middle",textFont:U,shadowColor:m.shadowColor,shadowBlur:m.shadowBlur,shadowOffsetX:m.shadowOffsetX,shadowOffsetY:m.shadowOffsetY}}))},_buildPointer:function(e){var t=this.series[e];if(t.pointer.show){var i=t.max-t.min,a=t.pointer,o=this._paramsMap[e],r=this.parsePercent(a.length,o.radius[1]),l=this.parsePercent(a.width,o.radius[1]),h=o.center,V=this._getValue(e);V=V2?2:l/2,color:"#fff"}});m.pack(p,this.series[e],e,this.series[e].data[0],0,this.series[e].data[0].name,V),this.shapeList.push(p),this.shapeList.push(new s({zlevel:t.zlevel,z:t.z+2,hoverable:!1,style:{x:h[0],y:h[1],r:a.width/2.5,color:"#fff"}}))}},_buildTitle:function(e){var t=this.series[e];if(t.title.show){var i=t.data[0],n=null!=i.name?i.name:"";if(""!==n){var o=t.title,r=o.offsetCenter,s=o.textStyle,l=s.color,h=this._paramsMap[e],m=h.center[0]+this.parsePercent(r[0],h.radius[1]),V=h.center[1]+this.parsePercent(r[1],h.radius[1]);this.shapeList.push(new a({zlevel:t.zlevel,z:t.z+(Math.abs(m-h.center[0])+Math.abs(V-h.center[1])<2*s.fontSize?2:1),hoverable:!1,style:{x:m,y:V,color:"auto"===l?this._getColor(e):l,text:n,textAlign:"center",textFont:this.getFont(s),shadowColor:s.shadowColor,shadowBlur:s.shadowBlur,shadowOffsetX:s.shadowOffsetX,shadowOffsetY:s.shadowOffsetY}}))}}},_buildDetail:function(e){var t=this.series[e];if(t.detail.show){var i=t.detail,n=i.offsetCenter,a=i.backgroundColor,o=i.textStyle,s=o.color,l=this._paramsMap[e],h=this._getValue(e),m=l.center[0]-i.width/2+this.parsePercent(n[0],l.radius[1]),V=l.center[1]+this.parsePercent(n[1],l.radius[1]);this.shapeList.push(new r({zlevel:t.zlevel,z:t.z+(Math.abs(m+i.width/2-l.center[0])+Math.abs(V+i.height/2-l.center[1])r;r++)o.push([a[r][0]*n+i,a[r][1]]);this._paramsMap[e].colorArray=o},_getColor:function(e,t){null==t&&(t=this._getValue(e));for(var i=this._paramsMap[e].colorArray,n=0,a=i.length;a>n;n++)if(i[n][0]>=t)return i[n][1];return i[i.length-1][1]},_getSector:function(e,t,i,n,a,o,r,s,h){return new l({zlevel:s,z:h,hoverable:!1,style:{x:e[0],y:e[1],r0:t,r:i,startAngle:n,endAngle:a,brushType:"fill",color:o,shadowColor:r.shadowColor,shadowBlur:r.shadowBlur,shadowOffsetX:r.shadowOffsetX,shadowOffsetY:r.shadowOffsetY}})},_getLabelText:function(e,t){if(e){if("function"==typeof e)return e.call(this.myChart,t);if("string"==typeof e)return e.replace("{value}",t)}return t},refresh:function(e){e&&(this.option=e,this.series=e.series),this.backupShapeList(),this._buildShape()}},U.inherits(t,i),e("../chart").define("gauge",t),t}),define("echarts/util/shape/GaugePointer",["require","zrender/shape/Base","zrender/tool/util","./normalIsCover"],function(e){function t(e){i.call(this,e)}var i=e("zrender/shape/Base"),n=e("zrender/tool/util");return t.prototype={type:"gauge-pointer",buildPath:function(e,t){var i=t.r,n=t.width,a=t.angle,o=t.x-Math.cos(a)*n*(n>=i/3?1:2),r=t.y+Math.sin(a)*n*(n>=i/3?1:2);a=t.angle-Math.PI/2,e.moveTo(o,r),e.lineTo(t.x+Math.cos(a)*n,t.y-Math.sin(a)*n),e.lineTo(t.x+Math.cos(t.angle)*i,t.y-Math.sin(t.angle)*i),e.lineTo(t.x-Math.cos(a)*n,t.y+Math.sin(a)*n),e.lineTo(o,r)},getRect:function(e){if(e.__rect)return e.__rect;var t=2*e.width,i=e.x,n=e.y,a=i+Math.cos(e.angle)*e.r,o=n-Math.sin(e.angle)*e.r;return e.__rect={x:Math.min(i,a)-t,y:Math.min(n,o)-t,width:Math.abs(i-a)+t,height:Math.abs(n-o)+t},e.__rect},isCover:e("./normalIsCover")},n.inherits(t,i),t}); -------------------------------------------------------------------------------- /app/static/res/lib/echarts/chart/heatmap.js: -------------------------------------------------------------------------------- 1 | define("echarts/chart/heatmap",["require","./base","../layer/heatmap","../config","../util/ecData","zrender/tool/util","zrender/tool/color","zrender/shape/Image","../chart"],function(e){function t(e,t,n,a,o){i.call(this,e,t,n,a,o),this.refresh(a)}var i=e("./base"),n=e("../layer/heatmap"),a=e("../config"),o=(e("../util/ecData"),e("zrender/tool/util")),r=(e("zrender/tool/color"),e("zrender/shape/Image"));return a.heatmap={zlevel:0,z:2,clickable:!0},t.prototype={type:a.CHART_TYPE_HEATMAP,refresh:function(e){this.clear(),e&&(this.option=e,this.series=e.series),this._init()},_init:function(){var e=this.series;this.backupShapeList();for(var t=e.length,i=0;t>i;++i)if(e[i].type===a.CHART_TYPE_HEATMAP){e[i]=this.reformOption(e[i]);var o=new n(e[i]),s=o.getCanvas(e[i].data,this.zr.getWidth(),this.zr.getHeight()),l=new r({position:[0,0],scale:[1,1],hoverable:this.option.hoverable,style:{x:0,y:0,image:s,width:s.width,height:s.height}});this.shapeList.push(l)}this.addShapeList()}},o.inherits(t,i),e("../chart").define("heatmap",t),t}),define("echarts/layer/heatmap",["require"],function(){function e(e){if(this.option=e,e)for(var i in t)this.option[i]=void 0!==e[i]?e[i]:t[i];else this.option=t}var t={blurSize:30,gradientColors:["blue","cyan","lime","yellow","red"],minAlpha:.05,valueScale:1,opacity:1},i=20,n=256;return e.prototype={getCanvas:function(e,t,a){var o=this._getBrush(),r=this._getGradient(),s=i+this.option.blurSize,l=document.createElement("canvas");l.width=t,l.height=a;for(var h=l.getContext("2d"),m=e.length,V=0;m>V;++V){var d=e[V],U=d[0],p=d[1],c=d[2],u=Math.min(1,Math.max(c*this.option.valueScale||this.option.minAlpha,this.option.minAlpha));h.globalAlpha=u,h.drawImage(o,U-s,p-s)}for(var g=h.getImageData(0,0,l.width,l.height),y=g.data,m=y.length/4;m--;){var b=4*m+3,u=y[b]/256,f=Math.floor(u*(n-1));y[b-3]=r[4*f],y[b-2]=r[4*f+1],y[b-1]=r[4*f+2],y[b]*=this.option.opacity}return h.putImageData(g,0,0),l},_getBrush:function(){if(!this._brushCanvas){this._brushCanvas=document.createElement("canvas");var e=i+this.option.blurSize,t=2*e;this._brushCanvas.width=t,this._brushCanvas.height=t;var n=this._brushCanvas.getContext("2d");n.shadowOffsetX=t,n.shadowBlur=this.option.blurSize,n.shadowColor="black",n.beginPath(),n.arc(-e,e,i,0,2*Math.PI,!0),n.closePath(),n.fill()}return this._brushCanvas},_getGradient:function(){if(!this._gradientPixels){var e=n,t=document.createElement("canvas");t.width=1,t.height=e;for(var i=t.getContext("2d"),a=i.createLinearGradient(0,0,0,e),o=this.option.gradientColors.length,r=0;o>r;++r)"string"==typeof this.option.gradientColors[r]?a.addColorStop((r+1)/o,this.option.gradientColors[r]):a.addColorStop(this.option.gradientColors[r].offset,this.option.gradientColors[r].color);i.fillStyle=a,i.fillRect(0,0,1,e),this._gradientPixels=i.getImageData(0,0,1,e).data}return this._gradientPixels}},e}),define("echarts/layer/heatmap",["require"],function(){function e(e){if(this.option=e,e)for(var i in t)this.option[i]=void 0!==e[i]?e[i]:t[i];else this.option=t}var t={blurSize:30,gradientColors:["blue","cyan","lime","yellow","red"],minAlpha:.05,valueScale:1,opacity:1},i=20,n=256;return e.prototype={getCanvas:function(e,t,a){var o=this._getBrush(),r=this._getGradient(),s=i+this.option.blurSize,l=document.createElement("canvas");l.width=t,l.height=a;for(var h=l.getContext("2d"),m=e.length,V=0;m>V;++V){var d=e[V],U=d[0],p=d[1],c=d[2],u=Math.min(1,Math.max(c*this.option.valueScale||this.option.minAlpha,this.option.minAlpha));h.globalAlpha=u,h.drawImage(o,U-s,p-s)}for(var g=h.getImageData(0,0,l.width,l.height),y=g.data,m=y.length/4;m--;){var b=4*m+3,u=y[b]/256,f=Math.floor(u*(n-1));y[b-3]=r[4*f],y[b-2]=r[4*f+1],y[b-1]=r[4*f+2],y[b]*=this.option.opacity}return h.putImageData(g,0,0),l},_getBrush:function(){if(!this._brushCanvas){this._brushCanvas=document.createElement("canvas");var e=i+this.option.blurSize,t=2*e;this._brushCanvas.width=t,this._brushCanvas.height=t;var n=this._brushCanvas.getContext("2d");n.shadowOffsetX=t,n.shadowBlur=this.option.blurSize,n.shadowColor="black",n.beginPath(),n.arc(-e,e,i,0,2*Math.PI,!0),n.closePath(),n.fill()}return this._brushCanvas},_getGradient:function(){if(!this._gradientPixels){var e=n,t=document.createElement("canvas");t.width=1,t.height=e;for(var i=t.getContext("2d"),a=i.createLinearGradient(0,0,0,e),o=this.option.gradientColors.length,r=0;o>r;++r)"string"==typeof this.option.gradientColors[r]?a.addColorStop((r+1)/o,this.option.gradientColors[r]):a.addColorStop(this.option.gradientColors[r].offset,this.option.gradientColors[r].color);i.fillStyle=a,i.fillRect(0,0,1,e),this._gradientPixels=i.getImageData(0,0,1,e).data}return this._gradientPixels}},e}); -------------------------------------------------------------------------------- /app/static/res/lib/echarts/chart/k.js: -------------------------------------------------------------------------------- 1 | define("echarts/chart/k",["require","./base","../util/shape/Candle","../component/axis","../component/grid","../component/dataZoom","../config","../util/ecData","zrender/tool/util","../chart"],function(e){function t(e,t,n,a,o){i.call(this,e,t,n,a,o),this.refresh(a)}var i=e("./base"),n=e("../util/shape/Candle");e("../component/axis"),e("../component/grid"),e("../component/dataZoom");var a=e("../config");a.k={zlevel:0,z:2,clickable:!0,hoverable:!0,legendHoverLink:!1,xAxisIndex:0,yAxisIndex:0,itemStyle:{normal:{color:"#fff",color0:"#00aa11",lineStyle:{width:1,color:"#ff3200",color0:"#00aa11"},label:{show:!1}},emphasis:{label:{show:!1}}}};var o=e("../util/ecData"),r=e("zrender/tool/util");return t.prototype={type:a.CHART_TYPE_K,_buildShape:function(){var e=this.series;this.selectedMap={};for(var t,i={top:[],bottom:[]},n=0,o=e.length;o>n;n++)e[n].type===a.CHART_TYPE_K&&(e[n]=this.reformOption(e[n]),this.legendHoverLink=e[n].legendHoverLink||this.legendHoverLink,t=this.component.xAxis.getAxis(e[n].xAxisIndex),t.type===a.COMPONENT_TYPE_AXIS_CATEGORY&&i[t.getPosition()].push(n));for(var r in i)i[r].length>0&&this._buildSinglePosition(r,i[r]);this.addShapeList()},_buildSinglePosition:function(e,t){var i=this._mapData(t),n=i.locationMap,a=i.maxDataLength;if(0!==a&&0!==n.length){this._buildHorizontal(t,a,n);for(var o=0,r=t.length;r>o;o++)this.buildMark(t[o])}},_mapData:function(e){for(var t,i,n=this.series,a=this.component.legend,o=[],r=0,s=0,l=e.length;l>s;s++)t=n[e[s]],i=t.name,this.selectedMap[i]=a?a.isSelected(i):!0,this.selectedMap[i]&&o.push(e[s]),r=Math.max(r,t.data.length);return{locationMap:o,maxDataLength:r}},_buildHorizontal:function(e,t,i){for(var n,a,o,r,s,l,h,d,c,m,p=this.series,u={},g=0,V=i.length;V>g;g++){n=i[g],a=p[n],o=a.xAxisIndex||0,r=this.component.xAxis.getAxis(o),h=a.barWidth||Math.floor(r.getGap()/2),m=a.barMaxWidth,m&&h>m&&(h=m),s=a.yAxisIndex||0,l=this.component.yAxis.getAxis(s),u[n]=[];for(var U=0,y=t;y>U&&null!=r.getNameByIndex(U);U++)d=a.data[U],c=this.getDataFromOption(d,"-"),"-"!==c&&4==c.length&&u[n].push([r.getCoordByIndex(U),h,l.getCoord(c[0]),l.getCoord(c[1]),l.getCoord(c[2]),l.getCoord(c[3]),U,r.getNameByIndex(U)])}this._buildKLine(e,u)},_buildKLine:function(e,t){for(var i,n,o,r,s,l,h,d,c,m,p,u,g,V,U,y,f,_=this.series,b=0,x=e.length;x>b;b++)if(f=e[b],p=_[f],V=t[f],this._isLarge(V)&&(V=this._getLargePointList(V)),p.type===a.CHART_TYPE_K&&null!=V){u=p,i=this.query(u,"itemStyle.normal.lineStyle.width"),n=this.query(u,"itemStyle.normal.lineStyle.color"),o=this.query(u,"itemStyle.normal.lineStyle.color0"),r=this.query(u,"itemStyle.normal.color"),s=this.query(u,"itemStyle.normal.color0"),l=this.query(u,"itemStyle.emphasis.lineStyle.width"),h=this.query(u,"itemStyle.emphasis.lineStyle.color"),d=this.query(u,"itemStyle.emphasis.lineStyle.color0"),c=this.query(u,"itemStyle.emphasis.color"),m=this.query(u,"itemStyle.emphasis.color0");for(var k=0,v=V.length;v>k;k++)U=V[k],g=p.data[U[6]],u=g,y=U[3]a;a++)n[a]=e[Math.floor(i/t*a)];return n},_getCandle:function(e,t,i,a,r,s,l,h,d,c,m,p,u,g,V){var U=this.series,y=U[e],f=y.data[t],_=[f,y],b={zlevel:y.zlevel,z:y.z,clickable:this.deepQuery(_,"clickable"),hoverable:this.deepQuery(_,"hoverable"),style:{x:a,y:[s,l,h,d],width:r,color:c,strokeColor:p,lineWidth:m,brushType:"both"},highlightStyle:{color:u,strokeColor:V,lineWidth:g},_seriesIndex:e};return b=this.addLabel(b,y,f,i),o.pack(b,y,e,f,t,i),b=new n(b)},getMarkCoord:function(e,t){var i=this.series[e],n=this.component.xAxis.getAxis(i.xAxisIndex),a=this.component.yAxis.getAxis(i.yAxisIndex);return["string"!=typeof t.xAxis&&n.getCoordByIndex?n.getCoordByIndex(t.xAxis||0):n.getCoord(t.xAxis||0),"string"!=typeof t.yAxis&&a.getCoordByIndex?a.getCoordByIndex(t.yAxis||0):a.getCoord(t.yAxis||0)]},refresh:function(e){e&&(this.option=e,this.series=e.series),this.backupShapeList(),this._buildShape()},addDataAnimation:function(e,t){function i(){u--,0===u&&t&&t()}for(var n=this.series,a={},r=0,s=e.length;s>r;r++)a[e[r][0]]=e[r];for(var l,h,d,c,m,p,u=0,r=0,s=this.shapeList.length;s>r;r++)if(m=this.shapeList[r]._seriesIndex,a[m]&&!a[m][3]&&"candle"===this.shapeList[r].type){if(p=o.get(this.shapeList[r],"dataIndex"),c=n[m],a[m][2]&&p===c.data.length-1){this.zr.delShape(this.shapeList[r].id);continue}if(!a[m][2]&&0===p){this.zr.delShape(this.shapeList[r].id);continue}h=this.component.xAxis.getAxis(c.xAxisIndex||0).getGap(),l=a[m][2]?h:-h,d=0,u++,this.zr.animate(this.shapeList[r].id,"").when(this.query(this.option,"animationDurationUpdate"),{position:[l,d]}).done(i).start()}u||t&&t()}},r.inherits(t,i),e("../chart").define("k",t),t}); -------------------------------------------------------------------------------- /app/static/res/lib/echarts/chart/line.js: -------------------------------------------------------------------------------- 1 | define("echarts/chart/line",["require","./base","zrender/shape/Polyline","../util/shape/Icon","../util/shape/HalfSmoothPolygon","../component/axis","../component/grid","../component/dataZoom","../config","../util/ecData","zrender/tool/util","zrender/tool/color","../chart"],function(e){function t(e,t,i,a,o){n.call(this,e,t,i,a,o),this.refresh(a)}function i(e,t,i){var n=t.x,a=t.y,r=t.width,s=t.height,l=s/2;t.symbol.match("empty")&&(e.fillStyle="#fff"),t.brushType="both";var h=t.symbol.replace("empty","").toLowerCase();h.match("star")?(l=h.replace("star","")-0||5,a-=1,h="star"):("rectangle"===h||"arrow"===h)&&(n+=(r-s)/2,r=s);var d="";if(h.match("image")&&(d=h.replace(new RegExp("^image:\\/\\/"),""),h="image",n+=Math.round((r-s)/2)-1,r=s+=2),h=o.prototype.iconLibrary[h]){var c=t.x,m=t.y;e.moveTo(c,m+l),e.lineTo(c+5,m+l),e.moveTo(c+t.width-5,m+l),e.lineTo(c+t.width,m+l);var p=this;h(e,{x:n+4,y:a+4,width:r-8,height:s-8,n:l,image:d},function(){p.modSelf(),i()})}else e.moveTo(n,a+l),e.lineTo(n+r,a+l)}var n=e("./base"),a=e("zrender/shape/Polyline"),o=e("../util/shape/Icon"),r=e("../util/shape/HalfSmoothPolygon");e("../component/axis"),e("../component/grid"),e("../component/dataZoom");var s=e("../config");s.line={zlevel:0,z:2,clickable:!0,legendHoverLink:!0,xAxisIndex:0,yAxisIndex:0,dataFilter:"nearest",itemStyle:{normal:{label:{show:!1},lineStyle:{width:2,type:"solid",shadowColor:"rgba(0,0,0,0)",shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0}},emphasis:{label:{show:!1}}},symbolSize:2,showAllSymbol:!1};var l=e("../util/ecData"),h=e("zrender/tool/util"),d=e("zrender/tool/color");return t.prototype={type:s.CHART_TYPE_LINE,_buildShape:function(){this.finalPLMap={},this._buildPosition()},_buildHorizontal:function(e,t,i,n){for(var a,o,r,s,l,h,d,c,m,p=this.series,u=i[0][0],V=p[u],U=this.component.xAxis.getAxis(V.xAxisIndex||0),g={},f=0,y=t;y>f&&null!=U.getNameByIndex(f);f++){o=U.getCoordByIndex(f);for(var b=0,_=i.length;_>b;b++){a=this.component.yAxis.getAxis(p[i[b][0]].yAxisIndex||0),l=s=d=h=a.getCoord(0);for(var x=0,k=i[b].length;k>x;x++)u=i[b][x],V=p[u],c=V.data[f],m=this.getDataFromOption(c,"-"),g[u]=g[u]||[],n[u]=n[u]||{min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY,sum:0,counter:0,average:0},"-"!==m?(m>=0?(s-=x>0?a.getCoordSize(m):l-a.getCoord(m),r=s):0>m&&(h+=x>0?a.getCoordSize(m):a.getCoord(m)-d,r=h),g[u].push([o,r,f,U.getNameByIndex(f),o,l]),n[u].min>m&&(n[u].min=m,n[u].minY=r,n[u].minX=o),n[u].max0&&(this.finalPLMap[u]=this.finalPLMap[u]||[],this.finalPLMap[u].push(g[u]),g[u]=[])}s=this.component.grid.getY();for(var v,b=0,_=i.length;_>b;b++)for(var x=0,k=i[b].length;k>x;x++)u=i[b][x],V=p[u],c=V.data[f],m=this.getDataFromOption(c,"-"),"-"==m&&this.deepQuery([c,V,this.option],"calculable")&&(v=this.deepQuery([c,V],"symbolSize"),s+=2*v+5,r=s,this.shapeList.push(this._getCalculableItem(u,f,U.getNameByIndex(f),o,r,"horizontal")))}for(var L in g)g[L].length>0&&(this.finalPLMap[L]=this.finalPLMap[L]||[],this.finalPLMap[L].push(g[L]),g[L]=[]);this._calculMarkMapXY(n,i,"y"),this._buildBorkenLine(e,this.finalPLMap,U,"horizontal")},_buildVertical:function(e,t,i,n){for(var a,o,r,s,l,h,d,c,m,p=this.series,u=i[0][0],V=p[u],U=this.component.yAxis.getAxis(V.yAxisIndex||0),g={},f=0,y=t;y>f&&null!=U.getNameByIndex(f);f++){r=U.getCoordByIndex(f);for(var b=0,_=i.length;_>b;b++){a=this.component.xAxis.getAxis(p[i[b][0]].xAxisIndex||0),l=s=d=h=a.getCoord(0);for(var x=0,k=i[b].length;k>x;x++)u=i[b][x],V=p[u],c=V.data[f],m=this.getDataFromOption(c,"-"),g[u]=g[u]||[],n[u]=n[u]||{min:Number.POSITIVE_INFINITY,max:Number.NEGATIVE_INFINITY,sum:0,counter:0,average:0},"-"!==m?(m>=0?(s+=x>0?a.getCoordSize(m):a.getCoord(m)-l,o=s):0>m&&(h-=x>0?a.getCoordSize(m):d-a.getCoord(m),o=h),g[u].push([o,r,f,U.getNameByIndex(f),l,r]),n[u].min>m&&(n[u].min=m,n[u].minX=o,n[u].minY=r),n[u].max0&&(this.finalPLMap[u]=this.finalPLMap[u]||[],this.finalPLMap[u].push(g[u]),g[u]=[])}s=this.component.grid.getXend();for(var v,b=0,_=i.length;_>b;b++)for(var x=0,k=i[b].length;k>x;x++)u=i[b][x],V=p[u],c=V.data[f],m=this.getDataFromOption(c,"-"),"-"==m&&this.deepQuery([c,V,this.option],"calculable")&&(v=this.deepQuery([c,V],"symbolSize"),s-=2*v+5,o=s,this.shapeList.push(this._getCalculableItem(u,f,U.getNameByIndex(f),o,r,"vertical")))}for(var L in g)g[L].length>0&&(this.finalPLMap[L]=this.finalPLMap[L]||[],this.finalPLMap[L].push(g[L]),g[L]=[]);this._calculMarkMapXY(n,i,"x"),this._buildBorkenLine(e,this.finalPLMap,U,"vertical")},_buildOther:function(e,t,i,n){for(var a,o=this.series,r={},s=0,l=i.length;l>s;s++)for(var h=0,d=i[s].length;d>h;h++){var c=i[s][h],m=o[c];a=this.component.xAxis.getAxis(m.xAxisIndex||0);var p=this.component.yAxis.getAxis(m.yAxisIndex||0),u=p.getCoord(0);r[c]=r[c]||[],n[c]=n[c]||{min0:Number.POSITIVE_INFINITY,min1:Number.POSITIVE_INFINITY,max0:Number.NEGATIVE_INFINITY,max1:Number.NEGATIVE_INFINITY,sum0:0,sum1:0,counter0:0,counter1:0,average0:0,average1:0};for(var V=0,U=m.data.length;U>V;V++){var g=m.data[V],f=this.getDataFromOption(g,"-");if(f instanceof Array){var y=a.getCoord(f[0]),b=p.getCoord(f[1]);r[c].push([y,b,V,f[0],y,u]),n[c].min0>f[0]&&(n[c].min0=f[0],n[c].minY0=b,n[c].minX0=y),n[c].max0f[1]&&(n[c].min1=f[1],n[c].minY1=b,n[c].minX1=y),n[c].max10&&(this.finalPLMap[_]=this.finalPLMap[_]||[],this.finalPLMap[_].push(r[_]),r[_]=[]);this._calculMarkMapXY(n,i,"xy"),this._buildBorkenLine(e,this.finalPLMap,a,"other")},_buildBorkenLine:function(e,t,i,n){for(var o,s="other"==n?"horizontal":n,c=this.series,m=e.length-1;m>=0;m--){var p=e[m],u=c[p],V=t[p];if(u.type===this.type&&null!=V)for(var U=this._getBbox(p,s),g=this._sIndex2ColorMap[p],f=this.query(u,"itemStyle.normal.lineStyle.width"),y=this.query(u,"itemStyle.normal.lineStyle.type"),b=this.query(u,"itemStyle.normal.lineStyle.color"),_=this.getItemStyleColor(this.query(u,"itemStyle.normal.color"),p,-1),x=null!=this.query(u,"itemStyle.normal.areaStyle"),k=this.query(u,"itemStyle.normal.areaStyle.color"),v=0,L=V.length;L>v;v++){var w=V[v],W="other"!=n&&this._isLarge(s,w);if(W)w=this._getLargePointList(s,w,u.dataFilter);else for(var X=0,I=w.length;I>X;X++)o=u.data[w[X][2]],(this.deepQuery([o,u,this.option],"calculable")||this.deepQuery([o,u],"showAllSymbol")||"categoryAxis"===i.type&&i.isMainAxis(w[X][2])&&"none"!=this.deepQuery([o,u],"symbol"))&&this.shapeList.push(this._getSymbol(p,w[X][2],w[X][3],w[X][0],w[X][1],s));var S=new a({zlevel:u.zlevel,z:u.z,style:{miterLimit:f,pointList:w,strokeColor:b||_||g,lineWidth:f,lineType:y,smooth:this._getSmooth(u.smooth),smoothConstraint:U,shadowColor:this.query(u,"itemStyle.normal.lineStyle.shadowColor"),shadowBlur:this.query(u,"itemStyle.normal.lineStyle.shadowBlur"),shadowOffsetX:this.query(u,"itemStyle.normal.lineStyle.shadowOffsetX"),shadowOffsetY:this.query(u,"itemStyle.normal.lineStyle.shadowOffsetY")},hoverable:!1,_main:!0,_seriesIndex:p,_orient:s});if(l.pack(S,c[p],p,0,v,c[p].name),this.shapeList.push(S),x){var K=new r({zlevel:u.zlevel,z:u.z,style:{miterLimit:f,pointList:h.clone(w).concat([[w[w.length-1][4],w[w.length-1][5]],[w[0][4],w[0][5]]]),brushType:"fill",smooth:this._getSmooth(u.smooth),smoothConstraint:U,color:k?k:d.alpha(g,.5)},highlightStyle:{brushType:"fill"},hoverable:!1,_main:!0,_seriesIndex:p,_orient:s});l.pack(K,c[p],p,0,v,c[p].name),this.shapeList.push(K)}}}},_getBbox:function(e,t){var i=this.component.grid.getBbox(),n=this.xMarkMap[e];return null!=n.minX0?[[Math.min(n.minX0,n.maxX0,n.minX1,n.maxX1),Math.min(n.minY0,n.maxY0,n.minY1,n.maxY1)],[Math.max(n.minX0,n.maxX0,n.minX1,n.maxX1),Math.max(n.minY0,n.maxY0,n.minY1,n.maxY1)]]:("horizontal"===t?(i[0][1]=Math.min(n.minY,n.maxY),i[1][1]=Math.max(n.minY,n.maxY)):(i[0][0]=Math.min(n.minX,n.maxX),i[1][0]=Math.max(n.minX,n.maxX)),i)},_isLarge:function(e,t){return t.length<2?!1:"horizontal"===e?Math.abs(t[0][0]-t[1][0])<.5:Math.abs(t[0][1]-t[1][1])<.5},_getLargePointList:function(e,t,i){var n;n="horizontal"===e?this.component.grid.getWidth():this.component.grid.getHeight();var a=t.length,o=[];if("function"!=typeof i)switch(i){case"min":i=function(e){return Math.max.apply(null,e)};break;case"max":i=function(e){return Math.min.apply(null,e)};break;case"average":i=function(e){for(var t=0,i=0;is;s++){var l=Math.floor(a/n*s),h=Math.min(Math.floor(a/n*(s+1)),a);if(!(l>=h)){for(var d=l;h>d;d++)r[d-l]="horizontal"===e?t[d][1]:t[d][0];r.length=h-l;for(var c=i(r),m=-1,p=1/0,d=l;h>d;d++){var u="horizontal"===e?t[d][1]:t[d][0],V=Math.abs(u-c);p>V&&(m=d,p=V)}var U=t[m].slice();"horizontal"===e?U[1]=c:U[0]=c,o.push(U)}}return o},_getSmooth:function(e){return e?.3:0},_getCalculableItem:function(e,t,i,n,a,o){var r=this.series,l=r[e].calculableHolderColor||this.ecTheme.calculableHolderColor||s.calculableHolderColor,h=this._getSymbol(e,t,i,n,a,o);return h.style.color=l,h.style.strokeColor=l,h.rotation=[0,0],h.hoverable=!1,h.draggable=!1,h.style.text=void 0,h},_getSymbol:function(e,t,i,n,a,o){var r=this.series,s=r[e],l=s.data[t],h=this.getSymbolShape(s,e,l,t,i,n,a,this._sIndex2ShapeMap[e],this._sIndex2ColorMap[e],"#fff","vertical"===o?"horizontal":"vertical");return h.zlevel=s.zlevel,h.z=s.z+1,this.deepQuery([l,s,this.option],"calculable")&&(this.setCalculable(h),h.draggable=!0),h},getMarkCoord:function(e,t){var i=this.series[e],n=this.xMarkMap[e],a=this.component.xAxis.getAxis(i.xAxisIndex),o=this.component.yAxis.getAxis(i.yAxisIndex);if(t.type&&("max"===t.type||"min"===t.type||"average"===t.type)){var r=null!=t.valueIndex?t.valueIndex:null!=n.maxX0?"1":"";return[n[t.type+"X"+r],n[t.type+"Y"+r],n[t.type+"Line"+r],n[t.type+r]]}return["string"!=typeof t.xAxis&&a.getCoordByIndex?a.getCoordByIndex(t.xAxis||0):a.getCoord(t.xAxis||0),"string"!=typeof t.yAxis&&o.getCoordByIndex?o.getCoordByIndex(t.yAxis||0):o.getCoord(t.yAxis||0)]},refresh:function(e){e&&(this.option=e,this.series=e.series),this.backupShapeList(),this._buildShape()},ontooltipHover:function(e,t){for(var i,n,a=e.seriesIndex,o=e.dataIndex,r=a.length;r--;)if(i=this.finalPLMap[a[r]])for(var s=0,l=i.length;l>s;s++){n=i[s];for(var h=0,d=n.length;d>h;h++)o===n[h][2]&&t.push(this._getSymbol(a[r],n[h][2],n[h][3],n[h][0],n[h][1],"horizontal"))}},addDataAnimation:function(e,t){function i(){V--,0===V&&t&&t()}function n(e){e.style.controlPointList=null}for(var a=this.series,o={},r=0,s=e.length;s>r;r++)o[e[r][0]]=e[r];for(var l,h,d,c,m,p,u,V=0,r=this.shapeList.length-1;r>=0;r--)if(m=this.shapeList[r]._seriesIndex,o[m]&&!o[m][3]){if(this.shapeList[r]._main&&this.shapeList[r].style.pointList.length>1){if(p=this.shapeList[r].style.pointList,h=Math.abs(p[0][0]-p[1][0]),c=Math.abs(p[0][1]-p[1][1]),u="horizontal"===this.shapeList[r]._orient,o[m][2]){if("half-smooth-polygon"===this.shapeList[r].type){var U=p.length;this.shapeList[r].style.pointList[U-3]=p[U-2],this.shapeList[r].style.pointList[U-3][u?0:1]=p[U-4][u?0:1],this.shapeList[r].style.pointList[U-2]=p[U-1]}this.shapeList[r].style.pointList.pop(),u?(l=h,d=0):(l=0,d=-c)}else{if(this.shapeList[r].style.pointList.shift(),"half-smooth-polygon"===this.shapeList[r].type){var g=this.shapeList[r].style.pointList.pop();u?g[0]=p[0][0]:g[1]=p[0][1],this.shapeList[r].style.pointList.push(g)}u?(l=-h,d=0):(l=0,d=c)}this.shapeList[r].style.controlPointList=null,this.zr.modShape(this.shapeList[r])}else{if(o[m][2]&&this.shapeList[r]._dataIndex===a[m].data.length-1){this.zr.delShape(this.shapeList[r].id);continue}if(!o[m][2]&&0===this.shapeList[r]._dataIndex){this.zr.delShape(this.shapeList[r].id);continue}}this.shapeList[r].position=[0,0],V++,this.zr.animate(this.shapeList[r].id,"").when(this.query(this.option,"animationDurationUpdate"),{position:[l,d]}).during(n).done(i).start()}V||t&&t()}},o.prototype.iconLibrary.legendLineIcon=i,h.inherits(t,n),e("../chart").define("line",t),t}),define("echarts/util/shape/HalfSmoothPolygon",["require","zrender/shape/Base","zrender/shape/util/smoothBezier","zrender/tool/util","zrender/shape/Polygon"],function(e){function t(e){i.call(this,e)}var i=e("zrender/shape/Base"),n=e("zrender/shape/util/smoothBezier"),a=e("zrender/tool/util");return t.prototype={type:"half-smooth-polygon",buildPath:function(t,i){var a=i.pointList;if(!(a.length<2))if(i.smooth){var o=n(a.slice(0,-2),i.smooth,!1,i.smoothConstraint);t.moveTo(a[0][0],a[0][1]);for(var r,s,l,h=a.length,d=0;h-3>d;d++)r=o[2*d],s=o[2*d+1],l=a[d+1],t.bezierCurveTo(r[0],r[1],s[0],s[1],l[0],l[1]);t.lineTo(a[h-2][0],a[h-2][1]),t.lineTo(a[h-1][0],a[h-1][1]),t.lineTo(a[0][0],a[0][1])}else e("zrender/shape/Polygon").prototype.buildPath(t,i)}},a.inherits(t,i),t}); -------------------------------------------------------------------------------- /app/static/res/lib/echarts/chart/pie.js: -------------------------------------------------------------------------------- 1 | define("echarts/chart/pie",["require","./base","zrender/shape/Text","zrender/shape/Ring","zrender/shape/Circle","zrender/shape/Sector","zrender/shape/Polyline","../config","../util/ecData","zrender/tool/util","zrender/tool/math","zrender/tool/color","../chart"],function(e){function t(e,t,n,a,o){i.call(this,e,t,n,a,o);var r=this;r.shapeHandler.onmouseover=function(e){var t=e.target,i=h.get(t,"seriesIndex"),n=h.get(t,"dataIndex"),a=h.get(t,"special"),o=[t.style.x,t.style.y],s=t.style.startAngle,l=t.style.endAngle,d=((l+s)/2+360)%360,c=t.highlightStyle.color,m=r.getLabel(i,n,a,o,d,c,!0);m&&r.zr.addHoverShape(m);var p=r.getLabelLine(i,n,o,t.style.r0,t.style.r,d,c,!0);p&&r.zr.addHoverShape(p)},this.refresh(a)}var i=e("./base"),n=e("zrender/shape/Text"),a=e("zrender/shape/Ring"),o=e("zrender/shape/Circle"),r=e("zrender/shape/Sector"),s=e("zrender/shape/Polyline"),l=e("../config");l.pie={zlevel:0,z:2,clickable:!0,legendHoverLink:!0,center:["50%","50%"],radius:[0,"75%"],clockWise:!0,startAngle:90,minAngle:0,selectedOffset:10,itemStyle:{normal:{borderColor:"rgba(0,0,0,0)",borderWidth:1,label:{show:!0,position:"outer"},labelLine:{show:!0,length:20,lineStyle:{width:1,type:"solid"}}},emphasis:{borderColor:"rgba(0,0,0,0)",borderWidth:1,label:{show:!1},labelLine:{show:!1,length:20,lineStyle:{width:1,type:"solid"}}}}};var h=e("../util/ecData"),d=e("zrender/tool/util"),c=e("zrender/tool/math"),m=e("zrender/tool/color");return t.prototype={type:l.CHART_TYPE_PIE,_buildShape:function(){var e=this.series,t=this.component.legend;this.selectedMap={},this._selected={};var i,n,r;this._selectedMode=!1;for(var s,d=0,c=e.length;c>d;d++)if(e[d].type===l.CHART_TYPE_PIE){if(e[d]=this.reformOption(e[d]),this.legendHoverLink=e[d].legendHoverLink||this.legendHoverLink,s=e[d].name||"",this.selectedMap[s]=t?t.isSelected(s):!0,!this.selectedMap[s])continue;i=this.parseCenter(this.zr,e[d].center),n=this.parseRadius(this.zr,e[d].radius),this._selectedMode=this._selectedMode||e[d].selectedMode,this._selected[d]=[],this.deepQuery([e[d],this.option],"calculable")&&(r={zlevel:e[d].zlevel,z:e[d].z,hoverable:!1,style:{x:i[0],y:i[1],r0:n[0]<=10?0:n[0]-10,r:n[1]+10,brushType:"stroke",lineWidth:1,strokeColor:e[d].calculableHolderColor||this.ecTheme.calculableHolderColor||l.calculableHolderColor}},h.pack(r,e[d],d,void 0,-1),this.setCalculable(r),r=n[0]<=10?new o(r):new a(r),this.shapeList.push(r)),this._buildSinglePie(d),this.buildMark(d)}this.addShapeList()},_buildSinglePie:function(e){for(var t,i=this.series,n=i[e],a=n.data,o=this.component.legend,r=0,s=0,l=0,h=Number.NEGATIVE_INFINITY,d=[],c=0,m=a.length;m>c;c++)t=a[c].name,this.selectedMap[t]=o?o.isSelected(t):!0,this.selectedMap[t]&&!isNaN(a[c].value)&&(0!==+a[c].value?r++:s++,l+=+a[c].value,h=Math.max(h,+a[c].value));if(0!==l){for(var p,u,g,V,U,y,f=100,_=n.clockWise,b=(n.startAngle.toFixed(2)-0+360)%360,x=n.minAngle||.01,k=360-x*r-.01*s,v=n.roseType,c=0,m=a.length;m>c;c++)if(t=a[c].name,this.selectedMap[t]&&!isNaN(a[c].value)){if(u=o?o.getColor(t):this.zr.getColor(c),f=a[c].value/l,p="area"!=v?_?b-f*k-(0!==f?x:.01):f*k+b+(0!==f?x:.01):_?b-360/m:360/m+b,p=p.toFixed(2)-0,f=(100*f).toFixed(2),g=this.parseCenter(this.zr,n.center),V=this.parseRadius(this.zr,n.radius),U=+V[0],y=+V[1],"radius"===v?y=a[c].value/h*(y-U)*.8+.2*(y-U)+U:"area"===v&&(y=Math.sqrt(a[c].value/h)*(y-U)+U),_){var L;L=b,b=p,p=L}this._buildItem(d,e,c,f,a[c].selected,g,U,y,b,p,u),_||(b=p)}this._autoLabelLayout(d,g,y);for(var c=0,m=d.length;m>c;c++)this.shapeList.push(d[c]);d=null}},_buildItem:function(e,t,i,n,a,o,r,s,l,d,c){var m=this.series,p=((d+l)/2+360)%360,u=this.getSector(t,i,n,a,o,r,s,l,d,c);h.pack(u,m[t],t,m[t].data[i],i,m[t].data[i].name,n),e.push(u);var g=this.getLabel(t,i,n,o,p,c,!1),V=this.getLabelLine(t,i,o,r,s,p,c,!1);V&&(h.pack(V,m[t],t,m[t].data[i],i,m[t].data[i].name,n),e.push(V)),g&&(h.pack(g,m[t],t,m[t].data[i],i,m[t].data[i].name,n),g._labelLine=V,e.push(g))},getSector:function(e,t,i,n,a,o,s,l,h,d){var p=this.series,u=p[e],g=u.data[t],V=[g,u],U=this.deepMerge(V,"itemStyle.normal")||{},y=this.deepMerge(V,"itemStyle.emphasis")||{},f=this.getItemStyleColor(U.color,e,t,g)||d,_=this.getItemStyleColor(y.color,e,t,g)||("string"==typeof f?m.lift(f,-.2):f),b={zlevel:u.zlevel,z:u.z,clickable:this.deepQuery(V,"clickable"),style:{x:a[0],y:a[1],r0:o,r:s,startAngle:l,endAngle:h,brushType:"both",color:f,lineWidth:U.borderWidth,strokeColor:U.borderColor,lineJoin:"round"},highlightStyle:{color:_,lineWidth:y.borderWidth,strokeColor:y.borderColor,lineJoin:"round"},_seriesIndex:e,_dataIndex:t};if(n){var x=((b.style.startAngle+b.style.endAngle)/2).toFixed(2)-0;b.style._hasSelected=!0,b.style._x=b.style.x,b.style._y=b.style.y;var k=this.query(u,"selectedOffset");b.style.x+=c.cos(x,!0)*k,b.style.y-=c.sin(x,!0)*k,this._selected[e][t]=!0}else this._selected[e][t]=!1;return this._selectedMode&&(b.onclick=this.shapeHandler.onclick),this.deepQuery([g,u,this.option],"calculable")&&(this.setCalculable(b),b.draggable=!0),(this._needLabel(u,g,!0)||this._needLabelLine(u,g,!0))&&(b.onmouseover=this.shapeHandler.onmouseover),b=new r(b)},getLabel:function(e,t,i,a,o,r,s){var l=this.series,h=l[e],m=h.data[t];if(this._needLabel(h,m,s)){var p,u,g,V=s?"emphasis":"normal",U=d.merge(d.clone(m.itemStyle)||{},h.itemStyle),y=U[V].label,f=y.textStyle||{},_=a[0],b=a[1],x=this.parseRadius(this.zr,h.radius),k="middle";y.position=y.position||U.normal.label.position,"center"===y.position?(p=_,u=b,g="center"):"inner"===y.position||"inside"===y.position?(x=(x[0]+x[1])*(y.distance||.5),p=Math.round(_+x*c.cos(o,!0)),u=Math.round(b-x*c.sin(o,!0)),r="#fff",g="center"):(x=x[1]- -U[V].labelLine.length,p=Math.round(_+x*c.cos(o,!0)),u=Math.round(b-x*c.sin(o,!0)),g=o>=90&&270>=o?"right":"left"),"center"!=y.position&&"inner"!=y.position&&"inside"!=y.position&&(p+="left"===g?20:-20),m.__labelX=p-("left"===g?5:-5),m.__labelY=u;var v=new n({zlevel:h.zlevel,z:h.z+1,hoverable:!1,style:{x:p,y:u,color:f.color||r,text:this.getLabelText(e,t,i,V),textAlign:f.align||g,textBaseline:f.baseline||k,textFont:this.getFont(f)},highlightStyle:{brushType:"fill"}});return v._radius=x,v._labelPosition=y.position||"outer",v._rect=v.getRect(v.style),v._seriesIndex=e,v._dataIndex=t,v}},getLabelText:function(e,t,i,n){var a=this.series,o=a[e],r=o.data[t],s=this.deepQuery([r,o],"itemStyle."+n+".label.formatter");return s?"function"==typeof s?s.call(this.myChart,{seriesIndex:e,seriesName:o.name||"",series:o,dataIndex:t,data:r,name:r.name,value:r.value,percent:i}):"string"==typeof s?(s=s.replace("{a}","{a0}").replace("{b}","{b0}").replace("{c}","{c0}").replace("{d}","{d0}"),s=s.replace("{a0}",o.name).replace("{b0}",r.name).replace("{c0}",r.value).replace("{d0}",i)):void 0:r.name},getLabelLine:function(e,t,i,n,a,o,r,l){var h=this.series,m=h[e],p=m.data[t];if(this._needLabelLine(m,p,l)){var u=l?"emphasis":"normal",g=d.merge(d.clone(p.itemStyle)||{},m.itemStyle),V=g[u].labelLine,U=V.lineStyle||{},y=i[0],f=i[1],_=a,b=this.parseRadius(this.zr,m.radius)[1]- -V.length,x=c.cos(o,!0),k=c.sin(o,!0);return new s({zlevel:m.zlevel,z:m.z+1,hoverable:!1,style:{pointList:[[y+_*x,f-_*k],[y+b*x,f-b*k],[p.__labelX,p.__labelY]],strokeColor:U.color||r,lineType:U.type,lineWidth:U.width},_seriesIndex:e,_dataIndex:t})}},_needLabel:function(e,t,i){return this.deepQuery([t,e],"itemStyle."+(i?"emphasis":"normal")+".label.show")},_needLabelLine:function(e,t,i){return this.deepQuery([t,e],"itemStyle."+(i?"emphasis":"normal")+".labelLine.show")},_autoLabelLayout:function(e,t,i){for(var n=[],a=[],o=0,r=e.length;r>o;o++)("outer"===e[o]._labelPosition||"outside"===e[o]._labelPosition)&&(e[o]._rect._y=e[o]._rect.y,e[o]._rect.xa;a++)if(e[a]._rect.y+=n,e[a].style.y+=n,e[a]._labelLine&&(e[a]._labelLine.style.pointList[1][1]+=n,e[a]._labelLine.style.pointList[2][1]+=n),a>t&&i>a+1&&e[a+1]._rect.y>e[a]._rect.y+e[a]._rect.height)return void o(a,n/2);o(i-1,n/2)}function o(t,i){for(var n=t;n>=0&&(e[n]._rect.y-=i,e[n].style.y-=i,e[n]._labelLine&&(e[n]._labelLine.style.pointList[1][1]-=i,e[n]._labelLine.style.pointList[2][1]-=i),!(n>0&&e[n]._rect.y>e[n-1]._rect.y+e[n-1]._rect.height));n--);}function r(e,t,i,n,a){for(var o,r,s,l=i[0],h=i[1],d=a>0?t?Number.MAX_VALUE:0:t?Number.MAX_VALUE:0,c=0,m=e.length;m>c;c++)r=Math.abs(e[c]._rect.y-h),s=e[c]._radius-n,o=n+s>r?Math.sqrt((n+s+20)*(n+s+20)-Math.pow(e[c]._rect.y-h,2)):Math.abs(e[c]._rect.x+(a>0?0:e[c]._rect.width)-l),t&&o>=d&&(o=d-10),!t&&d>=o&&(o=d+10),e[c]._rect.x=e[c].style.x=l+o*a,e[c]._labelLine&&(e[c]._labelLine.style.pointList[2][0]=l+(o-5)*a,e[c]._labelLine.style.pointList[1][0]=l+(o-20)*a),d=o}e.sort(function(e,t){return e._rect.y-t._rect.y});for(var s,l=0,h=e.length,d=[],c=[],m=0;h>m;m++)s=e[m]._rect.y-l,0>s&&a(m,h,-s,n),l=e[m]._rect.y+e[m]._rect.height;this.zr.getHeight()-l<0&&o(h-1,l-this.zr.getHeight());for(var m=0;h>m;m++)e[m]._rect.y>=t[1]?c.push(e[m]):d.push(e[m]);r(c,!0,t,i,n),r(d,!1,t,i,n)},reformOption:function(e){var t=d.merge;return e=t(t(e||{},d.clone(this.ecTheme.pie||{})),d.clone(l.pie)),e.itemStyle.normal.label.textStyle=this.getTextStyle(e.itemStyle.normal.label.textStyle),e.itemStyle.emphasis.label.textStyle=this.getTextStyle(e.itemStyle.emphasis.label.textStyle),this.z=e.z,this.zlevel=e.zlevel,e},refresh:function(e){e&&(this.option=e,this.series=e.series),this.backupShapeList(),this._buildShape()},addDataAnimation:function(e,t){function i(){s--,0===s&&t&&t()}for(var n=this.series,a={},o=0,r=e.length;r>o;o++)a[e[o][0]]=e[o];var s=0,h={},d={},c={},m=this.shapeList;this.shapeList=[];for(var p,u,g,V={},o=0,r=e.length;r>o;o++)p=e[o][0],u=e[o][2],g=e[o][3],n[p]&&n[p].type===l.CHART_TYPE_PIE&&(u?(g||(h[p+"_"+n[p].data.length]="delete"),V[p]=1):g?V[p]=0:(h[p+"_-1"]="delete",V[p]=-1),this._buildSinglePie(p));for(var U,y,o=0,r=this.shapeList.length;r>o;o++)switch(p=this.shapeList[o]._seriesIndex,U=this.shapeList[o]._dataIndex,y=p+"_"+U,this.shapeList[o].type){case"sector":h[y]=this.shapeList[o];break;case"text":d[y]=this.shapeList[o];break;case"polyline":c[y]=this.shapeList[o]}this.shapeList=[];for(var f,o=0,r=m.length;r>o;o++)if(p=m[o]._seriesIndex,a[p]){if(U=m[o]._dataIndex+V[p],y=p+"_"+U,f=h[y],!f)continue;if("sector"===m[o].type)"delete"!=f?(s++,this.zr.animate(m[o].id,"style").when(400,{startAngle:f.style.startAngle,endAngle:f.style.endAngle}).done(i).start()):(s++,this.zr.animate(m[o].id,"style").when(400,V[p]<0?{startAngle:m[o].style.startAngle}:{endAngle:m[o].style.endAngle}).done(i).start());else if("text"===m[o].type||"polyline"===m[o].type)if("delete"===f)this.zr.delShape(m[o].id);else switch(m[o].type){case"text":s++,f=d[y],this.zr.animate(m[o].id,"style").when(400,{x:f.style.x,y:f.style.y}).done(i).start();break;case"polyline":s++,f=c[y],this.zr.animate(m[o].id,"style").when(400,{pointList:f.style.pointList}).done(i).start()}}this.shapeList=m,s||t&&t()},onclick:function(e){var t=this.series;if(this.isClick&&e.target){this.isClick=!1;for(var i,n=e.target,a=n.style,o=h.get(n,"seriesIndex"),r=h.get(n,"dataIndex"),s=0,d=this.shapeList.length;d>s;s++)if(this.shapeList[s].id===n.id){if(o=h.get(n,"seriesIndex"),r=h.get(n,"dataIndex"),a._hasSelected)n.style.x=n.style._x,n.style.y=n.style._y,n.style._hasSelected=!1,this._selected[o][r]=!1;else{var m=((a.startAngle+a.endAngle)/2).toFixed(2)-0;n.style._hasSelected=!0,this._selected[o][r]=!0,n.style._x=n.style.x,n.style._y=n.style.y,i=this.query(t[o],"selectedOffset"),n.style.x+=c.cos(m,!0)*i,n.style.y-=c.sin(m,!0)*i}this.zr.modShape(n.id)}else this.shapeList[s].style._hasSelected&&"single"===this._selectedMode&&(o=h.get(this.shapeList[s],"seriesIndex"),r=h.get(this.shapeList[s],"dataIndex"),this.shapeList[s].style.x=this.shapeList[s].style._x,this.shapeList[s].style.y=this.shapeList[s].style._y,this.shapeList[s].style._hasSelected=!1,this._selected[o][r]=!1,this.zr.modShape(this.shapeList[s].id));this.messageCenter.dispatch(l.EVENT.PIE_SELECTED,e.event,{selected:this._selected,target:h.get(n,"name")},this.myChart),this.zr.refreshNextFrame()}}},d.inherits(t,i),e("../chart").define("pie",t),t}); -------------------------------------------------------------------------------- /app/static/res/lib/echarts/chart/radar.js: -------------------------------------------------------------------------------- 1 | define("echarts/chart/radar",["require","./base","zrender/shape/Polygon","../component/polar","../config","../util/ecData","zrender/tool/util","zrender/tool/color","../util/accMath","../chart"],function(e){function t(e,t,n,a,o){i.call(this,e,t,n,a,o),this.refresh(a)}var i=e("./base"),n=e("zrender/shape/Polygon");e("../component/polar");var a=e("../config");a.radar={zlevel:0,z:2,clickable:!0,legendHoverLink:!0,polarIndex:0,itemStyle:{normal:{label:{show:!1},lineStyle:{width:2,type:"solid"}},emphasis:{label:{show:!1}}},symbolSize:2};var o=e("../util/ecData"),r=e("zrender/tool/util"),s=e("zrender/tool/color");return t.prototype={type:a.CHART_TYPE_RADAR,_buildShape:function(){this.selectedMap={},this._symbol=this.option.symbolList,this._queryTarget,this._dropBoxList=[],this._radarDataCounter=0;for(var e,t=this.series,i=this.component.legend,n=0,o=t.length;o>n;n++)t[n].type===a.CHART_TYPE_RADAR&&(this.serie=this.reformOption(t[n]),this.legendHoverLink=t[n].legendHoverLink||this.legendHoverLink,e=this.serie.name||"",this.selectedMap[e]=i?i.isSelected(e):!0,this.selectedMap[e]&&(this._queryTarget=[this.serie,this.option],this.deepQuery(this._queryTarget,"calculable")&&this._addDropBox(n),this._buildSingleRadar(n),this.buildMark(n)));this.addShapeList()},_buildSingleRadar:function(e){for(var t,i,n,a,o=this.component.legend,r=this.serie.data,s=this.deepQuery(this._queryTarget,"calculable"),l=0;lr;r++)n=this.getDataFromOption(t.value[r]),i="-"!=n?o.getVector(e,r,n):!1,i&&a.push(i);return a},_addSymbol:function(e,t,i,n,a){for(var r,s=this.series,l=this.component.polar,h=0,d=e.length;d>h;h++)r=this.getSymbolShape(this.deepMerge([s[n].data[i],s[n]]),n,s[n].data[i].value[h],h,l.getIndicatorText(a,h),e[h][0],e[h][1],this._symbol[this._radarDataCounter%this._symbol.length],t,"#fff","vertical"),r.zlevel=this.getZlevelBase(),r.z=this.getZBase()+1,o.set(r,"data",s[n].data[i]),o.set(r,"value",s[n].data[i].value),o.set(r,"dataIndex",i),o.set(r,"special",h),this.shapeList.push(r)},_addDataShape:function(e,t,i,a,r,l){var h=this.series,d=[i,this.serie],c=this.getItemStyleColor(this.deepQuery(d,"itemStyle.normal.color"),a,r,i),p=this.deepQuery(d,"itemStyle.normal.lineStyle.width"),m=this.deepQuery(d,"itemStyle.normal.lineStyle.type"),u=this.deepQuery(d,"itemStyle.normal.areaStyle.color"),g=this.deepQuery(d,"itemStyle.normal.areaStyle"),V={zlevel:this.getZlevelBase(),z:this.getZBase(),style:{pointList:e,brushType:g?"both":"stroke",color:u||c||("string"==typeof t?s.alpha(t,.5):t),strokeColor:c||t,lineWidth:p,lineType:m},highlightStyle:{brushType:this.deepQuery(d,"itemStyle.emphasis.areaStyle")||g?"both":"stroke",color:this.deepQuery(d,"itemStyle.emphasis.areaStyle.color")||u||c||("string"==typeof t?s.alpha(t,.5):t),strokeColor:this.getItemStyleColor(this.deepQuery(d,"itemStyle.emphasis.color"),a,r,i)||c||t,lineWidth:this.deepQuery(d,"itemStyle.emphasis.lineStyle.width")||p,lineType:this.deepQuery(d,"itemStyle.emphasis.lineStyle.type")||m}};o.pack(V,h[a],a,i,r,i.name,this.component.polar.getIndicator(h[a].polarIndex)),l&&(V.draggable=!0,this.setCalculable(V)),V=new n(V),this.shapeList.push(V)},_addDropBox:function(e){var t=this.series,i=this.deepQuery(this._queryTarget,"polarIndex");if(!this._dropBoxList[i]){var n=this.component.polar.getDropBox(i);n.zlevel=this.getZlevelBase(),n.z=this.getZBase(),this.setCalculable(n),o.pack(n,t,e,void 0,-1),this.shapeList.push(n),this._dropBoxList[i]=!0}},ondragend:function(e,t){var i=this.series;if(this.isDragend&&e.target){var n=e.target,a=o.get(n,"seriesIndex"),r=o.get(n,"dataIndex");this.component.legend&&this.component.legend.del(i[a].data[r].name),i[a].data.splice(r,1),t.dragOut=!0,t.needRefresh=!0,this.isDragend=!1}},ondrop:function(t,i){var n=this.series;if(this.isDrop&&t.target){var a,r,s=t.target,l=t.dragged,h=o.get(s,"seriesIndex"),d=o.get(s,"dataIndex"),c=this.component.legend;if(-1===d)a={value:o.get(l,"value"),name:o.get(l,"name")},n[h].data.push(a),c&&c.add(a.name,l.style.color||l.style.strokeColor);else{var p=e("../util/accMath");a=n[h].data[d],c&&c.del(a.name),a.name+=this.option.nameConnector+o.get(l,"name"),r=o.get(l,"value");for(var m=0;mh;h++)t=d.polar2cartesian(s,o*Math.PI/180+r*h),l.push({vector:[t[1],-t[0]]})},_getRadius:function(){var e=this.polar[this._index];return this.parsePercent(e.radius,Math.min(this.zr.getWidth(),this.zr.getHeight())/2)},_buildSpiderWeb:function(e){var t=this.polar[e],i=t.__ecIndicator,n=t.splitArea,a=t.splitLine,o=this.getCenter(e),r=t.splitNumber,s=a.lineStyle.color,l=a.lineStyle.width,h=a.show,d=this.deepQuery(this._queryTarget,"axisLine");this._addArea(i,r,o,n,s,l,h),d.show&&this._addLine(i,o,d)},_addAxisLabel:function(t){for(var i,a,o,r,a,s,l,d,c,p,m=e("../util/accMath"),u=this.polar[t],g=this.deepQuery(this._queryTarget,"indicator"),V=u.__ecIndicator,y=this.deepQuery(this._queryTarget,"splitNumber"),U=this.getCenter(t),f=0;f=x;x+=p+1)r=h.merge({},o),l=m.accAdd(s.min,m.accMul(s.step,x)),l="function"==typeof b?b(l):"string"==typeof b?b.replace("{a}","{a0}").replace("{a0}",l):this.numAddCommas(l),r.text=l,r.x=x*a[0]/y+Math.cos(d)*c+U[0],r.y=x*a[1]/y+Math.sin(d)*c+U[1],this.shapeList.push(new n({zlevel:this.getZlevelBase(),z:this.getZBase(),style:r,draggable:!1,hoverable:!1}))}},_buildText:function(e){for(var t,i,a,o,r,s,l,h=this.polar[e],d=h.__ecIndicator,c=this.deepQuery(this._queryTarget,"indicator"),p=this.getCenter(e),m=0,u=0,g=0;g0?"left":Math.round(t[0])<0?"right":"center",null==o.margin?t=this._mapVector(t,p,1.1):(s=o.margin,m=t[0]>0?s:-s,u=t[1]>0?s:-s,m=0===t[0]?0:m,u=0===t[1]?0:u,t=this._mapVector(t,p,1)),i.textAlign=a,i.x=t[0]+m,i.y=t[1]+u,r=o.rotate?[o.rotate/180*Math.PI,t[0],t[1]]:[0,0,0],this.shapeList.push(new n({zlevel:this.getZlevelBase(),z:this.getZBase(),style:i,draggable:!1,hoverable:!1,rotation:r})))},getIndicatorText:function(e,t){return this.polar[e]&&this.polar[e].__ecIndicator[t]&&this.polar[e].__ecIndicator[t].text},getDropBox:function(e){var t,i,e=e||0,n=this.polar[e],a=this.getCenter(e),o=n.__ecIndicator,r=o.length,s=[],l=n.type;if("polygon"==l){for(var h=0;r>h;h++)t=o[h].vector,s.push(this._mapVector(t,a,1.2));i=this._getShape(s,"fill","rgba(0,0,0,0)","",1)}else"circle"==l&&(i=this._getCircle("",1,1.2,a,"fill","rgba(0,0,0,0)"));return i},_addArea:function(e,t,i,n,a,o,r){for(var s,l,h,d,c=this.deepQuery(this._queryTarget,"type"),p=0;t>p;p++)l=(t-p)/t,r&&("polygon"==c?(d=this._getPointList(e,l,i),s=this._getShape(d,"stroke","",a,o)):"circle"==c&&(s=this._getCircle(a,o,l,i,"stroke")),this.shapeList.push(s)),n.show&&(h=(t-p-1)/t,this._addSplitArea(e,n,l,h,i,p))},_getCircle:function(e,t,i,n,a,o){var s=this._getRadius();return new r({zlevel:this.getZlevelBase(),z:this.getZBase(),style:{x:n[0],y:n[1],r:s*i,brushType:a,strokeColor:e,lineWidth:t,color:o},hoverable:!1,draggable:!1})},_getRing:function(e,t,i,n){var a=this._getRadius();return new s({zlevel:this.getZlevelBase(),z:this.getZBase(),style:{x:n[0],y:n[1],r:t*a,r0:i*a,color:e,brushType:"fill"},hoverable:!1,draggable:!1})},_getPointList:function(e,t,i){for(var n,a=[],o=e.length,r=0;o>r;r++)n=e[r].vector,a.push(this._mapVector(n,i,t));return a},_getShape:function(e,t,i,n,a){return new o({zlevel:this.getZlevelBase(),z:this.getZBase(),style:{pointList:e,brushType:t,color:i,strokeColor:n,lineWidth:a},hoverable:!1,draggable:!1})},_addSplitArea:function(e,t,i,n,a,o){var r,s,l,h,d,c=e.length,p=t.areaStyle.color,m=[],c=e.length,u=this.deepQuery(this._queryTarget,"type");if("string"==typeof p&&(p=[p]),s=p.length,r=p[o%s],"polygon"==u)for(var g=0;c>g;g++)m=[],l=e[g].vector,h=e[(g+1)%c].vector,m.push(this._mapVector(l,a,i)),m.push(this._mapVector(l,a,n)),m.push(this._mapVector(h,a,n)),m.push(this._mapVector(h,a,i)),d=this._getShape(m,"fill",r,"",1),this.shapeList.push(d);else"circle"==u&&(d=this._getRing(r,i,n,a),this.shapeList.push(d))},_mapVector:function(e,t,i){return[e[0]*i+t[0],e[1]*i+t[1]]},getCenter:function(e){var e=e||0;return this.parseCenter(this.zr,this.polar[e].center)},_addLine:function(e,t,i){for(var n,a,o=e.length,r=i.lineStyle,s=r.color,l=r.width,h=r.type,d=0;o>d;d++)a=e[d].vector,n=this._getLine(t[0],t[1],a[0]+t[0],a[1]+t[1],s,l,h),this.shapeList.push(n)},_getLine:function(e,t,i,n,o,r,s){return new a({zlevel:this.getZlevelBase(),z:this.getZBase(),style:{xStart:e,yStart:t,xEnd:i,yEnd:n,strokeColor:o,lineWidth:r,lineType:s},hoverable:!1})},_adjustIndicatorValue:function(t){for(var i,n,a,o=this.polar[t],r=this.deepQuery(this._queryTarget,"indicator"),s=r.length,l=o.__ecIndicator,h=this._getSeriesData(t),d=o.boundaryGap,c=o.splitNumber,p=o.scale,m=e("../util/smartSteps"),u=0;s>u;u++){if("number"==typeof r[u].max)i=r[u].max,n=r[u].min||0,a={max:i,min:n};else{var g=this._findValue(h,u,c,d);n=g.min,i=g.max}!p&&n>=0&&i>=0&&(n=0),!p&&0>=n&&0>=i&&(i=0);var V=m(n,i,c,a);l[u].value={min:V.min,max:V.max,step:V.step}}},_getSeriesData:function(e){for(var t,i,n,a=[],o=this.component.legend,r=0;ro||void 0===o)&&(o=e),(r>e||void 0===r)&&(r=e)}var o,r,s;if(e&&0!==e.length){if(1==e.length&&(r=0),1!=e.length)for(var l=0;l0?r=o/i:o/=i),{max:o,min:r}}},getVector:function(e,t,i){e=e||0,t=t||0;var n=this.polar[e].__ecIndicator;if(!(t>=n.length)){var a,o=this.polar[e].__ecIndicator[t],r=this.getCenter(e),s=o.vector,l=o.value.max,h=o.value.min;if("undefined"==typeof i)return r;switch(i){case"min":i=h;break;case"max":i=l;break;case"center":i=(l+h)/2}return a=l!=h?(i-h)/(l-h):.5,this._mapVector(s,r,a)}},isInside:function(e){var t=this.getNearestIndex(e);return t?t.polarIndex:-1},getNearestIndex:function(e){for(var t,i,n,a,o,r,s,l,h,c=0;ca[0])return{polarIndex:c,valueIndex:Math.floor((h+l/2)/l)%s}}},getIndicator:function(e){var e=e||0;return this.polar[e].indicator},refresh:function(e){e&&(this.option=e,this.polar=this.option.polar,this.series=this.option.series),this.clear(),this._buildShape()}},h.inherits(t,i),e("../component").define("polar",t),t}),define("echarts/util/coordinates",["require","zrender/tool/math"],function(e){function t(e,t){return[e*n.sin(t),e*n.cos(t)]}function i(e,t){return[Math.sqrt(e*e+t*t),Math.atan(t/e)]}var n=e("zrender/tool/math");return{polar2cartesian:t,cartesian2polar:i}}); -------------------------------------------------------------------------------- /app/static/res/lib/echarts/chart/tree.js: -------------------------------------------------------------------------------- 1 | define("echarts/chart/tree",["require","./base","../util/shape/Icon","zrender/shape/Image","zrender/shape/Line","zrender/shape/BezierCurve","../layout/Tree","../data/Tree","../config","../util/ecData","zrender/config","zrender/tool/event","zrender/tool/util","../chart"],function(e){function t(e,t,n,a,o){i.call(this,e,t,n,a,o),this.refresh(a)}var i=e("./base"),n=.618,a=e("../util/shape/Icon"),o=e("zrender/shape/Image"),r=e("zrender/shape/Line"),s=e("zrender/shape/BezierCurve"),l=e("../layout/Tree"),h=e("../data/Tree"),m=e("../config");m.tree={zlevel:1,z:2,calculable:!1,clickable:!0,rootLocation:{},orient:"vertical",symbol:"circle",symbolSize:20,nodePadding:30,layerPadding:100,itemStyle:{normal:{label:{show:!0},lineStyle:{width:1,color:"#777",type:"curve"}},emphasis:{}}};var V=e("../util/ecData"),U=(e("zrender/config"),e("zrender/tool/event"),e("zrender/tool/util"));return t.prototype={type:m.CHART_TYPE_TREE,_buildShape:function(e,t){var i=e.data[0];this.tree=h.fromOptionData(i.name,i.children),this.tree.root.data=i,this._setTreeShape(e),this.tree.traverse(function(i){this._buildItem(i,e,t),i.children.length>0&&this._buildLink(i,e)},this);var n=e.roam===!0||"move"===e.roam,a=e.roam===!0||"scale"===e.roam;this.zr.modLayer(this.getZlevelBase(),{panable:n,zoomable:a}),(this.query("markPoint.effect.show")||this.query("markLine.effect.show"))&&this.zr.modLayer(m.EFFECT_ZLEVEL,{panable:n,zoomable:a}),this.addShapeList()},_buildItem:function(e,t,i){var n=[e.data,t],r=this.deepQuery(n,"symbol"),s=this.deepMerge(n,"itemStyle.normal")||{},l=this.deepMerge(n,"itemStyle.emphasis")||{},h=s.color||this.zr.getColor(),m=l.color||this.zr.getColor(),U=-e.layout.angle||0;e.id===this.tree.root.id&&(U=0);var d="right";Math.abs(U)>=Math.PI/2&&Math.abs(U)<3*Math.PI/2&&(U+=Math.PI,d="left");var p=[U,e.layout.position[0],e.layout.position[1]],c=new a({zlevel:this.getZlevelBase(),z:this.getZBase()+1,rotation:p,clickable:this.deepQuery(n,"clickable"),style:{x:e.layout.position[0]-.5*e.layout.width,y:e.layout.position[1]-.5*e.layout.height,width:e.layout.width,height:e.layout.height,iconType:r,color:h,brushType:"both",lineWidth:s.borderWidth,strokeColor:s.borderColor},highlightStyle:{color:m,lineWidth:l.borderWidth,strokeColor:l.borderColor}});c.style.iconType.match("image")&&(c.style.image=c.style.iconType.replace(new RegExp("^image:\\/\\/"),""),c=new o({rotation:p,style:c.style,highlightStyle:c.highlightStyle,clickable:c.clickable,zlevel:this.getZlevelBase(),z:this.getZBase()})),this.deepQuery(n,"itemStyle.normal.label.show")&&(c.style.text=null==e.data.label?e.id:e.data.label,c.style.textPosition=this.deepQuery(n,"itemStyle.normal.label.position"),"radial"===t.orient&&"inside"!==c.style.textPosition&&(c.style.textPosition=d),c.style.textColor=this.deepQuery(n,"itemStyle.normal.label.textStyle.color"),c.style.textFont=this.getFont(this.deepQuery(n,"itemStyle.normal.label.textStyle")||{})),this.deepQuery(n,"itemStyle.emphasis.label.show")&&(c.highlightStyle.textPosition=this.deepQuery(n,"itemStyle.emphasis.label.position"),c.highlightStyle.textColor=this.deepQuery(n,"itemStyle.emphasis.label.textStyle.color"),c.highlightStyle.textFont=this.getFont(this.deepQuery(n,"itemStyle.emphasis.label.textStyle")||{})),V.pack(c,t,i,e.data,0,e.id),this.shapeList.push(c)},_buildLink:function(e,t){var i=t.itemStyle.normal.lineStyle;if("broken"===i.type)return void this._buildBrokenLine(e,i,t);for(var n=0;nr&&(t=r),r>n&&(n=r)}e.layout.position[0]=e.children.length>0?(t+n)/2:0;var s=this._layerOffsets[e.depth]||0;if(s>e.layout.position[0]){var l=s-e.layout.position[0];this._shiftSubtree(e,l);for(var a=e.depth+1;a=0&&(t.splice(i,1),e.parent=null)},t.prototype.traverse=function(e,t){e.call(t,this);for(var i=0;it&&(t=n.height)}this.height=t+1},t.prototype.getNodeById=function(e){if(this.id===e)return this;for(var t=0;tt.width||e.normal.label.y+U>t.height)&&(h=""):h="",e.emphasis.label.show?(s.x+u>t.width||s.y+y>t.height)&&(p=""):p="";var g={style:{textX:t.x+e.normal.label.x,textY:t.y+e.normal.label.y,text:h,textPosition:"specific",textColor:o.color,textFont:m},highlightStyle:{textX:t.x+e.emphasis.label.x,textY:t.y+e.emphasis.label.y,text:p,textColor:s.color,textPosition:"specific"}};return g},getLabelText:function(e,t,i){return i?"function"==typeof i?i.call(this.myChart,e,t):"string"==typeof i?(i=i.replace("{b}","{b0}").replace("{c}","{c0}"),i=i.replace("{b0}",e).replace("{c0}",t)):void 0:e},_buildChildrenTreemap:function(e,t,i,n){for(var a=i.width*i.height,o=0,r=[],l=0;l ":"")},V),clickable:!0,highlightStyle:p});m.set(u,"seriesIndex",t),m.set(u,"name",a[c]),i+=u.getRect(u.style).width,this.shapeList.push(u)}},__onclick:function(e){var t=e.target;if(t){var i=m.get(t,"seriesIndex"),n=m.get(t,"name"),a=this._treesMap[i],o=a.getNodeById(n);o&&o.children.length&&this._buildTreemap(o,i)}}},U.inherits(t,i),e("../chart").define("treemap",t),t}),define("echarts/layout/TreeMap",["require"],function(){function e(e){({x:e.x,y:e.y,width:e.width,height:e.height});this.x=e.x,this.y=e.y,this.width=e.width,this.height=e.height}return e.prototype.run=function(e){var t=[];return this._squarify(e,{x:this.x,y:this.y,width:this.width,height:this.height},t),t},e.prototype._squarify=function(e,t,i){var n="VERTICAL",a=t.width,o=t.height;t.widthl;l++)r[s].y+=r[l].height}var h={};if("VERTICAL"==n){for(var m=0;ml;l++){var h=i*e[l]/o;a.push({width:s,height:h})}return a},e.prototype._isFirstBetter=function(e,t){var i=e[0].height/e[0].width;i=i>1?1/i:i;var n=t[0].height/t[0].width;return n=n>1?1/n:n,Math.abs(i-1)<=Math.abs(n-1)?!0:!1},e}),define("echarts/data/Tree",["require","zrender/tool/util"],function(e){function t(e,t){this.id=e,this.depth=0,this.height=0,this.children=[],this.parent=null,this.data=t||null}function i(e){this.root=new t(e)}var n=e("zrender/tool/util");return t.prototype.add=function(e){var t=this.children;e.parent!==this&&(t.push(e),e.parent=this)},t.prototype.remove=function(e){var t=this.children,i=n.indexOf(t,e);i>=0&&(t.splice(i,1),e.parent=null)},t.prototype.traverse=function(e,t){e.call(t,this);for(var i=0;it&&(t=n.height)}this.height=t+1},t.prototype.getNodeById=function(e){if(this.id===e)return this;for(var t=0;ta[1].value?(t=this.zr.getHeight()/3,i=t*Math.sqrt(a[1].value)/Math.sqrt(a[0].value)):(i=this.zr.getHeight()/3,t=i*Math.sqrt(a[0].value)/Math.sqrt(a[1].value));var o=this.zr.getWidth()/2-t,r=(t+i)/2*Math.sqrt(a[2].value)/Math.sqrt((a[0].value+a[1].value)/2),s=t+i;0!==a[2].value&&(s=this._getCoincideLength(a[0].value,a[1].value,a[2].value,t,i,r,Math.abs(t-i),t+i));var l=o+s,h=this.zr.getHeight()/2;if(this._buildItem(e,0,a[0],o,h,t),this._buildItem(e,1,a[1],l,h,i),0!==a[2].value&&a[2].value!==a[0].value&&a[2].value!==a[1].value){var m=(t*t-i*i)/(2*s)+s/2,V=s/2-(t*t-i*i)/(2*s),U=Math.sqrt(t*t-m*m),d=0,p=0;a[0].value>a[1].value&&o+m>l&&(p=1),a[0].valuel&&(d=1),this._buildCoincideItem(e,2,a[2],o+m,h-U,h+U,t,i,d,p)}},_getCoincideLength:function(e,t,i,n,a,o,r,s){var l=(n*n-a*a)/(2*o)+o/2,h=o/2-(n*n-a*a)/(2*o),m=Math.acos(l/n),V=Math.acos(h/a),U=n*n*Math.PI,d=m*n*n-l*n*Math.sin(m)+V*a*a-h*a*Math.sin(V),p=d/U,c=i/e,u=Math.abs(p/c);return u>.999&&1.001>u?o:.999>=u?(s=o,o=(o+r)/2,this._getCoincideLength(e,t,i,n,a,o,r,s)):(r=o,o=(o+s)/2,this._getCoincideLength(e,t,i,n,a,o,r,s))},_buildItem:function(e,t,i,n,a,o){var r=this.series,l=r[e],h=this.getCircle(e,t,i,n,a,o);if(s.pack(h,l,e,i,t,i.name),this.shapeList.push(h),l.itemStyle.normal.label.show){var m=this.getLabel(e,t,i,n,a,o);s.pack(m,l,e,l.data[t],t,l.data[t].name),this.shapeList.push(m)}},_buildCoincideItem:function(e,t,i,n,a,r,l,h,m,V){var U=this.series,d=U[e],p=[i,d],c=this.deepMerge(p,"itemStyle.normal")||{},u=this.deepMerge(p,"itemStyle.emphasis")||{},y=c.color||this.zr.getColor(t),g=u.color||this.zr.getColor(t),b="M"+n+","+a+"A"+l+","+l+",0,"+m+",1,"+n+","+r+"A"+h+","+h+",0,"+V+",1,"+n+","+a,f={color:y,path:b},k={zlevel:d.zlevel,z:d.z,style:f,highlightStyle:{color:g,lineWidth:u.borderWidth,strokeColor:u.borderColor}};k=new o(k),k.buildPathArray&&(k.style.pathArray=k.buildPathArray(f.path)),s.pack(k,U[e],0,i,t,i.name),this.shapeList.push(k)},getCircle:function(e,t,i,n,o,r){var s=this.series[e],l=[i,s],h=this.deepMerge(l,"itemStyle.normal")||{},m=this.deepMerge(l,"itemStyle.emphasis")||{},V=h.color||this.zr.getColor(t),U=m.color||this.zr.getColor(t),d={zlevel:s.zlevel,z:s.z,clickable:!0,style:{x:n,y:o,r:r,brushType:"fill",opacity:1,color:V},highlightStyle:{color:U,lineWidth:m.borderWidth,strokeColor:m.borderColor}};return this.deepQuery([i,s,this.option],"calculable")&&(this.setCalculable(d),d.draggable=!0),new a(d)},getLabel:function(e,t,i,a,o,r){var s=this.series[e],l=s.itemStyle,h=[i,s],m=this.deepMerge(h,"itemStyle.normal")||{},V="normal",U=l[V].label,d=U.textStyle||{},p=this.getLabelText(t,i,V),c=this.getFont(d),u=m.color||this.zr.getColor(t),y=d.fontSize||12,g={zlevel:s.zlevel,z:s.z,style:{x:a,y:o-r-y,color:d.color||u,text:p,textFont:c,textAlign:"center"}};return new n(g)},getLabelText:function(e,t,i){var n=this.series,a=n[0],o=this.deepQuery([t,a],"itemStyle."+i+".label.formatter");return o?"function"==typeof o?o(a.name,t.name,t.value):"string"==typeof o?(o=o.replace("{a}","{a0}").replace("{b}","{b0}").replace("{c}","{c0}"),o=o.replace("{a0}",a.name).replace("{b0}",t.name).replace("{c0}",t.value)):void 0:t.name},refresh:function(e){e&&(this.option=e,this.series=e.series),this._buildShape()}},l.inherits(t,i),e("../chart").define("venn",t),t}),define("zrender/shape/Path",["require","./Base","./util/PathProxy","../tool/util"],function(e){var t=e("./Base"),i=e("./util/PathProxy"),n=i.PathSegment,a=function(e){return Math.sqrt(e[0]*e[0]+e[1]*e[1])},o=function(e,t){return(e[0]*t[0]+e[1]*t[1])/(a(e)*a(t))},r=function(e,t){return(e[0]*t[1]0&&""===d[0]&&d.shift();for(var p=0;p0&&!isNaN(d[0]);){var c,u,y,g,b,f,k,_,x=null,L=[],W=h,X=m;switch(U){case"l":h+=d.shift(),m+=d.shift(),x="L",L.push(h,m);break;case"L":h=d.shift(),m=d.shift(),L.push(h,m);break;case"m":h+=d.shift(),m+=d.shift(),x="M",L.push(h,m),U="l";break;case"M":h=d.shift(),m=d.shift(),x="M",L.push(h,m),U="L";break;case"h":h+=d.shift(),x="L",L.push(h,m);break;case"H":h=d.shift(),x="L",L.push(h,m);break;case"v":m+=d.shift(),x="L",L.push(h,m);break;case"V":m=d.shift(),x="L",L.push(h,m);break;case"C":L.push(d.shift(),d.shift(),d.shift(),d.shift()),h=d.shift(),m=d.shift(),L.push(h,m);break;case"c":L.push(h+d.shift(),m+d.shift(),h+d.shift(),m+d.shift()),h+=d.shift(),m+=d.shift(),x="C",L.push(h,m);break;case"S":c=h,u=m,y=l[l.length-1],"C"===y.command&&(c=h+(h-y.points[2]),u=m+(m-y.points[3])),L.push(c,u,d.shift(),d.shift()),h=d.shift(),m=d.shift(),x="C",L.push(h,m);break;case"s":c=h,u=m,y=l[l.length-1],"C"===y.command&&(c=h+(h-y.points[2]),u=m+(m-y.points[3])),L.push(c,u,h+d.shift(),m+d.shift()),h+=d.shift(),m+=d.shift(),x="C",L.push(h,m);break;case"Q":L.push(d.shift(),d.shift()),h=d.shift(),m=d.shift(),L.push(h,m);break;case"q":L.push(h+d.shift(),m+d.shift()),h+=d.shift(),m+=d.shift(),x="Q",L.push(h,m);break;case"T":c=h,u=m,y=l[l.length-1],"Q"===y.command&&(c=h+(h-y.points[0]),u=m+(m-y.points[1])),h=d.shift(),m=d.shift(),x="Q",L.push(c,u,h,m);break;case"t":c=h,u=m,y=l[l.length-1],"Q"===y.command&&(c=h+(h-y.points[0]),u=m+(m-y.points[1])),h+=d.shift(),m+=d.shift(),x="Q",L.push(c,u,h,m);break;case"A":g=d.shift(),b=d.shift(),f=d.shift(),k=d.shift(),_=d.shift(),W=h,X=m,h=d.shift(),m=d.shift(),x="A",L=this._convertPoint(W,X,h,m,k,_,g,b,f);break;case"a":g=d.shift(),b=d.shift(),f=d.shift(),k=d.shift(),_=d.shift(),W=h,X=m,h+=d.shift(),m+=d.shift(),x="A",L=this._convertPoint(W,X,h,m,k,_,g,b,f)}for(var v=0,K=L.length;K>v;v+=2)L[v]+=t,L[v+1]+=i;l.push(new n(x||U,L))}("z"===U||"Z"===U)&&l.push(new n("z",[]))}return l},_convertPoint:function(e,t,i,n,a,s,l,h,m){var V=m*(Math.PI/180),U=Math.cos(V)*(e-i)/2+Math.sin(V)*(t-n)/2,d=-1*Math.sin(V)*(e-i)/2+Math.cos(V)*(t-n)/2,p=U*U/(l*l)+d*d/(h*h);p>1&&(l*=Math.sqrt(p),h*=Math.sqrt(p));var c=Math.sqrt((l*l*h*h-l*l*d*d-h*h*U*U)/(l*l*d*d+h*h*U*U));a===s&&(c*=-1),isNaN(c)&&(c=0);var u=c*l*d/h,y=c*-h*U/l,g=(e+i)/2+Math.cos(V)*u-Math.sin(V)*y,b=(t+n)/2+Math.sin(V)*u+Math.cos(V)*y,f=r([1,0],[(U-u)/l,(d-y)/h]),k=[(U-u)/l,(d-y)/h],_=[(-1*U-u)/l,(-1*d-y)/h],x=r(k,_);return o(k,_)<=-1&&(x=Math.PI),o(k,_)>=1&&(x=0),0===s&&x>0&&(x-=2*Math.PI),1===s&&0>x&&(x+=2*Math.PI),[g,b,l,h,f,x,V,s]},buildPath:function(e,t){var i=t.path,n=t.x||0,a=t.y||0;t.pathArray=t.pathArray||this.buildPathArray(i,n,a);for(var o=t.pathArray,r=t.pointList=[],s=[],l=0,h=o.length;h>l;l++){"M"==o[l].command.toUpperCase()&&(s.length>0&&r.push(s),s=[]);for(var m=o[l].points,V=0,U=m.length;U>V;V+=2)s.push([m[V],m[V+1]])}s.length>0&&r.push(s);for(var l=0,h=o.length;h>l;l++){var d=o[l].command,m=o[l].points;switch(d){case"L":e.lineTo(m[0],m[1]);break;case"M":e.moveTo(m[0],m[1]);break;case"C":e.bezierCurveTo(m[0],m[1],m[2],m[3],m[4],m[5]);break;case"Q":e.quadraticCurveTo(m[0],m[1],m[2],m[3]);break;case"A":var p=m[0],c=m[1],u=m[2],y=m[3],g=m[4],b=m[5],f=m[6],k=m[7],_=u>y?u:y,x=u>y?1:u/y,L=u>y?y/u:1;e.translate(p,c),e.rotate(f),e.scale(x,L),e.arc(0,0,_,g,g+b,1-k),e.scale(1/x,1/L),e.rotate(-f),e.translate(-p,-c);break;case"z":e.closePath()}}},getRect:function(e){if(e.__rect)return e.__rect;var t;t="stroke"==e.brushType||"fill"==e.brushType?e.lineWidth||1:0;for(var i=Number.MAX_VALUE,n=Number.MIN_VALUE,a=Number.MAX_VALUE,o=Number.MIN_VALUE,r=e.x||0,s=e.y||0,l=e.pathArray||this.buildPathArray(e.path),h=0;hn&&(n=m[V])):(m[V]+so&&(o=m[V]));var U;return U=i===Number.MAX_VALUE||n===Number.MIN_VALUE||a===Number.MAX_VALUE||o===Number.MIN_VALUE?{x:0,y:0,width:0,height:0}:{x:Math.round(i-t/2),y:Math.round(a-t/2),width:n-i+t,height:o-a+t},e.__rect=U,U}},e("../tool/util").inherits(s,t),s}); -------------------------------------------------------------------------------- /app/static/res/lib/md5.js: -------------------------------------------------------------------------------- 1 | var hexcase=0;var b64pad="";function hex_md5(s){return rstr2hex(rstr_md5(str2rstr_utf8(s)))}function b64_md5(s){return rstr2b64(rstr_md5(str2rstr_utf8(s)))}function any_md5(s,e){return rstr2any(rstr_md5(str2rstr_utf8(s)),e)}function hex_hmac_md5(k,d){return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k),str2rstr_utf8(d)))}function b64_hmac_md5(k,d){return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k),str2rstr_utf8(d)))}function any_hmac_md5(k,d,e){return rstr2any(rstr_hmac_md5(str2rstr_utf8(k),str2rstr_utf8(d)),e)}function md5_vm_test(){return hex_md5("abc").toLowerCase()=="900150983cd24fb0d6963f7d28e17f72"}function rstr_md5(s){return binl2rstr(binl_md5(rstr2binl(s),s.length*8))}function rstr_hmac_md5(a,b){var c=rstr2binl(a);if(c.length>16)c=binl_md5(c,a.length*8);var d=Array(16),opad=Array(16);for(var i=0;i<16;i++){d[i]=c[i]^0x36363636;opad[i]=c[i]^0x5C5C5C5C}var e=binl_md5(d.concat(rstr2binl(b)),512+b.length*8);return binl2rstr(binl_md5(opad.concat(e),512+128))}function rstr2hex(a){try{hexcase}catch(e){hexcase=0}var b=hexcase?"0123456789ABCDEF":"0123456789abcdef";var c="";var x;for(var i=0;i>>4)&0x0F)+b.charAt(x&0x0F)}return c}function rstr2b64(a){try{b64pad}catch(e){b64pad=''}var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var c="";var d=a.length;for(var i=0;ia.length*8)c+=b64pad;else c+=b.charAt((f>>>6*(3-j))&0x3F)}}return c}function rstr2any(a,b){var c=b.length;var i,j,q,x,quotient;var d=Array(Math.ceil(a.length/2));for(i=0;i0||q>0)quotient[quotient.length]=q}f[j]=x;d=quotient}var g="";for(i=f.length-1;i>=0;i--)g+=b.charAt(f[i]);return g}function str2rstr_utf8(a){var b="";var i=-1;var x,y;while(++i>>6)&0x1F),0x80|(x&0x3F));else if(x<=0xFFFF)b+=String.fromCharCode(0xE0|((x>>>12)&0x0F),0x80|((x>>>6)&0x3F),0x80|(x&0x3F));else if(x<=0x1FFFFF)b+=String.fromCharCode(0xF0|((x>>>18)&0x07),0x80|((x>>>12)&0x3F),0x80|((x>>>6)&0x3F),0x80|(x&0x3F))}return b}function str2rstr_utf16le(a){var b="";for(var i=0;i>>8)&0xFF);return b}function str2rstr_utf16be(a){var b="";for(var i=0;i>>8)&0xFF,a.charCodeAt(i)&0xFF);return b}function rstr2binl(a){var b=Array(a.length>>2);for(var i=0;i>5]|=(a.charCodeAt(i/8)&0xFF)<<(i%32);return b}function binl2rstr(a){var b="";for(var i=0;i>5]>>>(i%32))&0xFF);return b}function binl_md5(x,e){x[e>>5]|=0x80<<((e)%32);x[(((e+64)>>>9)<<4)+14]=e;var a=1732584193;var b=-271733879;var c=-1732584194;var d=271733878;for(var i=0;i>16)+(y>>16)+(a>>16);return(b<<16)|(a&0xFFFF)}function bit_rol(a,b){return(a<>>(32-b))} -------------------------------------------------------------------------------- /app/static/res/lib/simpleStorage.js: -------------------------------------------------------------------------------- 1 | /* jshint browser: true */ 2 | /* global define: false */ 3 | 4 | // AMD shim 5 | (function(root, factory) { 6 | 7 | 'use strict'; 8 | 9 | if (typeof define === 'function' && define.amd) { 10 | define(factory); 11 | } else if (typeof exports !== 'undefined') { 12 | module.exports = factory(); 13 | } else { 14 | root.simpleStorage = factory(); 15 | } 16 | 17 | }(this, function() { 18 | 19 | 'use strict'; 20 | 21 | var 22 | VERSION = '0.1.3', 23 | 24 | /* This is the object, that holds the cached values */ 25 | _storage = false, 26 | 27 | /* How much space does the storage take */ 28 | _storage_size = 0, 29 | 30 | _storage_available = false, 31 | 32 | _ttl_timeout = null; 33 | 34 | // This method might throw as it touches localStorage and doing so 35 | // can be prohibited in some environments 36 | function _init() { 37 | 38 | // If localStorage does not exist, the following throws 39 | // This is intentional 40 | window.localStorage.setItem('__simpleStorageInitTest', 'tmpval'); 41 | window.localStorage.removeItem('__simpleStorageInitTest'); 42 | 43 | // Load data from storage 44 | _load_storage(); 45 | 46 | // remove dead keys 47 | _handleTTL(); 48 | 49 | // start listening for changes 50 | _setupUpdateObserver(); 51 | 52 | // handle cached navigation 53 | if ('addEventListener' in window) { 54 | window.addEventListener('pageshow', function(event) { 55 | if (event.persisted) { 56 | _reloadData(); 57 | } 58 | }, false); 59 | } 60 | 61 | _storage_available = true; 62 | } 63 | 64 | /** 65 | * Sets up a storage change observer 66 | */ 67 | function _setupUpdateObserver() { 68 | if ('addEventListener' in window) { 69 | window.addEventListener('storage', _reloadData, false); 70 | } else { 71 | document.attachEvent('onstorage', _reloadData); 72 | } 73 | } 74 | 75 | /** 76 | * Reload data from storage when needed 77 | */ 78 | function _reloadData() { 79 | try { 80 | _load_storage(); 81 | } catch (E) { 82 | _storage_available = false; 83 | return; 84 | } 85 | _handleTTL(); 86 | } 87 | 88 | function _load_storage() { 89 | var source = localStorage.getItem('simpleStorage'); 90 | 91 | try { 92 | _storage = JSON.parse(source) || {}; 93 | } catch (E) { 94 | _storage = {}; 95 | } 96 | 97 | _storage_size = _get_storage_size(); 98 | } 99 | 100 | function _save() { 101 | try { 102 | localStorage.setItem('simpleStorage', JSON.stringify(_storage)); 103 | _storage_size = _get_storage_size(); 104 | } catch (E) { 105 | return E; 106 | } 107 | return true; 108 | } 109 | 110 | function _get_storage_size() { 111 | var source = localStorage.getItem('simpleStorage'); 112 | return source ? String(source).length : 0; 113 | } 114 | 115 | function _handleTTL() { 116 | var curtime, i, len, expire, keys, nextExpire = Infinity, 117 | expiredKeysCount = 0; 118 | 119 | clearTimeout(_ttl_timeout); 120 | 121 | if (!_storage || !_storage.__simpleStorage_meta || !_storage.__simpleStorage_meta.TTL) { 122 | return; 123 | } 124 | 125 | curtime = +new Date(); 126 | keys = _storage.__simpleStorage_meta.TTL.keys || []; 127 | expire = _storage.__simpleStorage_meta.TTL.expire || {}; 128 | 129 | for (i = 0, len = keys.length; i < len; i++) { 130 | if (expire[keys[i]] <= curtime) { 131 | expiredKeysCount++; 132 | delete _storage[keys[i]]; 133 | delete expire[keys[i]]; 134 | } else { 135 | if (expire[keys[i]] < nextExpire) { 136 | nextExpire = expire[keys[i]]; 137 | } 138 | break; 139 | } 140 | } 141 | 142 | // set next check 143 | if (nextExpire != Infinity) { 144 | _ttl_timeout = setTimeout(_handleTTL, Math.min(nextExpire - curtime, 0x7FFFFFFF)); 145 | } 146 | 147 | // remove expired from TTL list and save changes 148 | if (expiredKeysCount) { 149 | keys.splice(0, expiredKeysCount); 150 | 151 | _cleanMetaObject(); 152 | _save(); 153 | } 154 | } 155 | 156 | function _setTTL(key, ttl) { 157 | var curtime = +new Date(), 158 | i, len, added = false; 159 | 160 | ttl = Number(ttl) || 0; 161 | 162 | // Set TTL value for the key 163 | if (ttl !== 0) { 164 | // If key exists, set TTL 165 | if (_storage.hasOwnProperty(key)) { 166 | 167 | if (!_storage.__simpleStorage_meta) { 168 | _storage.__simpleStorage_meta = {}; 169 | } 170 | 171 | if (!_storage.__simpleStorage_meta.TTL) { 172 | _storage.__simpleStorage_meta.TTL = { 173 | expire: {}, 174 | keys: [] 175 | }; 176 | } 177 | 178 | _storage.__simpleStorage_meta.TTL.expire[key] = curtime + ttl; 179 | 180 | // find the expiring key in the array and remove it and all before it (because of sort) 181 | if (_storage.__simpleStorage_meta.TTL.expire.hasOwnProperty(key)) { 182 | for (i = 0, len = _storage.__simpleStorage_meta.TTL.keys.length; i < len; i++) { 183 | if (_storage.__simpleStorage_meta.TTL.keys[i] == key) { 184 | _storage.__simpleStorage_meta.TTL.keys.splice(i); 185 | } 186 | } 187 | } 188 | 189 | // add key to keys array preserving sort (soonest first) 190 | for (i = 0, len = _storage.__simpleStorage_meta.TTL.keys.length; i < len; i++) { 191 | if (_storage.__simpleStorage_meta.TTL.expire[_storage.__simpleStorage_meta.TTL.keys[i]] > (curtime + ttl)) { 192 | _storage.__simpleStorage_meta.TTL.keys.splice(i, 0, key); 193 | added = true; 194 | break; 195 | } 196 | } 197 | 198 | // if not added in previous loop, add here 199 | if (!added) { 200 | _storage.__simpleStorage_meta.TTL.keys.push(key); 201 | } 202 | } else { 203 | return false; 204 | } 205 | } else { 206 | // Remove TTL if set 207 | if (_storage && _storage.__simpleStorage_meta && _storage.__simpleStorage_meta.TTL) { 208 | 209 | if (_storage.__simpleStorage_meta.TTL.expire.hasOwnProperty(key)) { 210 | delete _storage.__simpleStorage_meta.TTL.expire[key]; 211 | for (i = 0, len = _storage.__simpleStorage_meta.TTL.keys.length; i < len; i++) { 212 | if (_storage.__simpleStorage_meta.TTL.keys[i] == key) { 213 | _storage.__simpleStorage_meta.TTL.keys.splice(i, 1); 214 | break; 215 | } 216 | } 217 | } 218 | 219 | _cleanMetaObject(); 220 | } 221 | } 222 | 223 | // schedule next TTL check 224 | clearTimeout(_ttl_timeout); 225 | if (_storage && _storage.__simpleStorage_meta && _storage.__simpleStorage_meta.TTL && _storage.__simpleStorage_meta.TTL.keys.length) { 226 | _ttl_timeout = setTimeout(_handleTTL, Math.min(Math.max(_storage.__simpleStorage_meta.TTL.expire[_storage.__simpleStorage_meta.TTL.keys[0]] - curtime, 0), 0x7FFFFFFF)); 227 | } 228 | 229 | return true; 230 | } 231 | 232 | function _cleanMetaObject() { 233 | var updated = false, 234 | hasProperties = false, 235 | i; 236 | 237 | if (!_storage || !_storage.__simpleStorage_meta) { 238 | return updated; 239 | } 240 | 241 | // If nothing to TTL, remove the object 242 | if (_storage.__simpleStorage_meta.TTL && !_storage.__simpleStorage_meta.TTL.keys.length) { 243 | delete _storage.__simpleStorage_meta.TTL; 244 | updated = true; 245 | } 246 | 247 | // If meta object is empty, remove it 248 | for (i in _storage.__simpleStorage_meta) { 249 | if (_storage.__simpleStorage_meta.hasOwnProperty(i)) { 250 | hasProperties = true; 251 | break; 252 | } 253 | } 254 | 255 | if (!hasProperties) { 256 | delete _storage.__simpleStorage_meta; 257 | updated = true; 258 | } 259 | 260 | return updated; 261 | } 262 | 263 | ////////////////////////// PUBLIC INTERFACE ///////////////////////// 264 | 265 | try { 266 | _init(); 267 | } catch (E) {} 268 | 269 | return { 270 | 271 | version: VERSION, 272 | 273 | canUse: function() { 274 | return !!_storage_available; 275 | }, 276 | 277 | set: function(key, value, options) { 278 | if (key == '__simpleStorage_meta') { 279 | return false; 280 | } 281 | 282 | if (!_storage) { 283 | return false; 284 | } 285 | 286 | // undefined values are deleted automatically 287 | if (typeof value == 'undefined') { 288 | return this.deleteKey(key); 289 | } 290 | 291 | options = options || {}; 292 | 293 | // Check if the value is JSON compatible (and remove reference to existing objects/arrays) 294 | try { 295 | value = JSON.parse(JSON.stringify(value)); 296 | } catch (E) { 297 | return E; 298 | } 299 | 300 | _storage[key] = value; 301 | 302 | _setTTL(key, options.TTL || 0); 303 | 304 | return _save(); 305 | }, 306 | 307 | get: function(key) { 308 | if (!_storage) { 309 | return false; 310 | } 311 | 312 | if (_storage.hasOwnProperty(key) && key != '__simpleStorage_meta') { 313 | // TTL value for an existing key is either a positive number or an Infinity 314 | if (this.getTTL(key)) { 315 | return _storage[key]; 316 | } 317 | } 318 | }, 319 | 320 | deleteKey: function(key) { 321 | 322 | if (!_storage) { 323 | return false; 324 | } 325 | 326 | if (key in _storage) { 327 | delete _storage[key]; 328 | 329 | _setTTL(key, 0); 330 | 331 | return _save(); 332 | } 333 | 334 | return false; 335 | }, 336 | 337 | setTTL: function(key, ttl) { 338 | if (!_storage) { 339 | return false; 340 | } 341 | 342 | _setTTL(key, ttl); 343 | 344 | return _save(); 345 | }, 346 | 347 | getTTL: function(key) { 348 | var ttl; 349 | 350 | if (!_storage) { 351 | return false; 352 | } 353 | 354 | if (_storage.hasOwnProperty(key)) { 355 | if (_storage.__simpleStorage_meta && 356 | _storage.__simpleStorage_meta.TTL && 357 | _storage.__simpleStorage_meta.TTL.expire && 358 | _storage.__simpleStorage_meta.TTL.expire.hasOwnProperty(key)) { 359 | 360 | ttl = Math.max(_storage.__simpleStorage_meta.TTL.expire[key] - (+new Date()) || 0, 0); 361 | 362 | return ttl || false; 363 | } else { 364 | return Infinity; 365 | } 366 | } 367 | 368 | return false; 369 | }, 370 | 371 | flush: function() { 372 | if (!_storage) { 373 | return false; 374 | } 375 | 376 | _storage = {}; 377 | try { 378 | localStorage.removeItem('simpleStorage'); 379 | return true; 380 | } catch (E) { 381 | return E; 382 | } 383 | }, 384 | 385 | index: function() { 386 | if (!_storage) { 387 | return false; 388 | } 389 | 390 | var index = [], 391 | i; 392 | for (i in _storage) { 393 | if (_storage.hasOwnProperty(i) && i != '__simpleStorage_meta') { 394 | index.push(i); 395 | } 396 | } 397 | return index; 398 | }, 399 | 400 | storageSize: function() { 401 | return _storage_size; 402 | } 403 | }; 404 | 405 | })); -------------------------------------------------------------------------------- /app/static/tmp/RAEDME.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/static/tmp/RAEDME.md -------------------------------------------------------------------------------- /app/static/upload/RAEDME.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/static/upload/RAEDME.md -------------------------------------------------------------------------------- /app/templates/http_monitor_page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Http Monitor 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
    16 | 19 |
    20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
    31 |

    [] Redis Monitor Informations

    32 | 33 | 38 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    Server服务端
    状态码编码连接服务器
    60 |
    61 |

    其他服务器

    62 |
      63 |
    64 | 67 |
    68 | 69 | 70 | 71 | 72 | 73 | 74 | 77 | 78 | -------------------------------------------------------------------------------- /app/templates/index_page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Server列表 - Server Monitor 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 | 20 |
    21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
    32 |

    监控Server列表 - Server Monitor Informations

    33 | 34 | 39 | 42 |
    43 | Redis | 44 | Host:    45 | Port:    46 | Password:    47 | Email:    48 |   49 | 50 |
    51 |
    52 |
    53 | Http | 54 | Url:    55 | 56 | Email:    57 |   58 | 59 |
    60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
    类型Server Information添加时间操作
    70 | 73 |
    74 | 75 | 77 | 78 | 79 | 80 | 81 | 84 | 85 | -------------------------------------------------------------------------------- /app/templates/redis_monitor_page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Redis Monitor 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
    16 | 19 |
    20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
    31 |

    [] Redis Monitor Informations

    32 | 33 | 38 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 |
    Server服务端
    VesionOSProcess_IDUp_TimeConnectionBlocked
    Stats相关内容
    connect_receivedcmd_processedops_per_secrejected_connectexpired_keysevicted_keyshitsmisses
    DB数据库相关
    DBkeysexpiresavg_ttl
    103 |
    104 |
    105 |
    106 |
    107 |

    其他Server服务器

    108 |
      109 |
    110 | 113 |
    114 | 115 | 116 | 117 | 118 | 119 | 120 | 123 | 124 | -------------------------------------------------------------------------------- /app/templates/tip.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 提示页面 6 | 7 | 75 | 76 | 77 |
    78 |

    TIP

    79 |

    80 | {{tip}} 81 | {% if url %} 82 | {{text}} 83 | {% endif %} 84 |

    85 |
    86 | 87 | -------------------------------------------------------------------------------- /app/utils/CJsonEncoder.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年1月27日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | from datetime import date 8 | from datetime import datetime 9 | import json 10 | 11 | 12 | class CJsonEncoder(json.JSONEncoder): 13 | def default(self, obj): 14 | if isinstance(obj, datetime): 15 | return obj.strftime('%Y-%m-%d %H:%M:%S') 16 | elif isinstance(obj, date): 17 | return obj.strftime('%Y-%m-%d') 18 | else: 19 | return json.JSONEncoder.default(self, obj) -------------------------------------------------------------------------------- /app/utils/DateUtil.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年8月24日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | import datetime 8 | 9 | 10 | #当前时间,可用于mysql datetime 11 | def now_datetime(): 12 | return datetime.datetime.now().strftime("%y-%m-%d %H:%M:%S") 13 | 14 | 15 | if __name__ == '__main__': 16 | print now_datetime() -------------------------------------------------------------------------------- /app/utils/LogUtil.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年8月24日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | from app.utils import PathUtil, DateUtil 8 | 9 | def append_log(log_file, data): 10 | ''' 11 | append data to file pathing with filePath 12 | ''' 13 | if data: 14 | file_handler = open(PathUtil.log_dir() + log_file, 'a') 15 | file_handler.write(data + '\n') 16 | file_handler.close() 17 | 18 | return True 19 | 20 | #记录非法用户的日志,一般这些用户都是尝试模拟请求的方式往数据库写入信息 21 | def log_invalid(request, ext_text): 22 | log = '%s - - [%s] %s %s %s' % (request.remote_addr, DateUtil.now_datetime(), request.method, request.path, ext_text) 23 | append_log('record_invaild_log.log', log) -------------------------------------------------------------------------------- /app/utils/OtherUtil.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年8月21日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | import hashlib 8 | import json 9 | from CJsonEncoder import CJsonEncoder 10 | 11 | def md5_salt(s, salt = "ab_test"): 12 | ''' 13 | md5 + 盐:即便两个用户使用了同一个密码,由于系统为它们生成的salt值不同,他们的散列值也是不同的。 14 | ''' 15 | if s: 16 | return md5(s + salt) 17 | else: 18 | return '' 19 | 20 | def md5(s): 21 | ''' 22 | md5 23 | ''' 24 | m = hashlib.md5() 25 | m.update(s) 26 | return m.hexdigest() 27 | 28 | def object_2_dict(obj): 29 | ''' 30 | py obj to dict 31 | ''' 32 | if obj == None: 33 | return {} 34 | return json.dumps(obj, cls = CJsonEncoder) -------------------------------------------------------------------------------- /app/utils/PathUtil.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年2月5日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | import os 8 | import sys 9 | 10 | def upload_dir(): 11 | return _cur_file_dir() + '/app/static/upload/' 12 | 13 | def log_dir(): 14 | return _cur_file_dir() + '/log/' 15 | 16 | def default_tmp_dir(): 17 | return _cur_file_dir() + '/app/static/tmp/' 18 | 19 | def _cur_file_dir(): 20 | #获取脚本路径 21 | path = sys.path[0] 22 | #判断为脚本文件还是py2exe编译后的文件,如果是脚本文件,则返回的是脚本的目录,如果是py2exe编译后的文件,则返回的是编译后的文件路径 23 | if os.path.isdir(path): 24 | return path 25 | elif os.path.isfile(path): 26 | return os.path.dirname(path) 27 | 28 | if __name__ == '__main__': 29 | print _cur_file_dir() 30 | -------------------------------------------------------------------------------- /app/utils/RequestUtil.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年8月21日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | 8 | #获得参数,post或者get 9 | def get_parameter(request, key, default = None): 10 | ''' 11 | info:获得请求参数,包括get和post,其他类型的访问不管 12 | ''' 13 | #post参数 14 | if request.method == 'POST': 15 | param = request.form.get(key, default) 16 | #get 17 | elif request.method == 'GET': 18 | param = request.args.get(key, default) 19 | else: 20 | return default 21 | 22 | return param 23 | 24 | #用户IP 25 | def get_request_ip(request): 26 | return request.remote_addr 27 | 28 | #获得用户访问方式 29 | def get_request_method(request): 30 | return request.method 31 | 32 | def get_request_ua(request): 33 | return request.headers.get('User-Agent', '') 34 | 35 | def get_request_accept_lang(request): 36 | request.environ.get('HTTP_ACCEPT_LANGUAGE', '') 37 | -------------------------------------------------------------------------------- /app/utils/StringUtil.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年6月16日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | 8 | def is_empty(s): 9 | if s == None or s == '': 10 | return True 11 | return False -------------------------------------------------------------------------------- /app/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/utils/__init__.py -------------------------------------------------------------------------------- /app/utils/jinja2_ex/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/utils/jinja2_ex/__init__.py -------------------------------------------------------------------------------- /app/utils/jinja2_ex/template_filter.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年5月6日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | from app import app 8 | 9 | @app.context_processor 10 | def ext_jinja2_processor(): 11 | ''' 12 | ps:扩展jinja2的内置方法 13 | ''' 14 | def str_sub(s, start, end, suffix = None): 15 | ''' 16 | str_sub;字符串截断 17 | ''' 18 | if suffix: 19 | return s[start:end] + suffix 20 | return s[start:end] 21 | 22 | def str_len(s): 23 | ''' 24 | str_len:字符串长度 25 | ''' 26 | return len(s) 27 | 28 | def to_str(i): 29 | ''' 30 | to_str:将数字转字符串,一些比较的时候会使用到 31 | ''' 32 | return str(i) 33 | 34 | def to_round(f, d = 3): 35 | ''' 36 | to_round:浮点数小数位数 37 | ''' 38 | return round(f, d) 39 | 40 | return dict(str_sub = str_sub, str_len = str_len, to_str = to_str, to_round = to_round) 41 | -------------------------------------------------------------------------------- /app/views/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/views/__init__.py -------------------------------------------------------------------------------- /app/views/main_views.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年6月16日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | from app import app 8 | import flask 9 | from app.utils import RequestUtil, OtherUtil 10 | from flask.globals import request 11 | from app.monitors.RedisMonitor import RedisMonitor 12 | from app.monitors.HttpMonitor import HttpMonitor 13 | 14 | @app.route('/', methods=['GET']) 15 | def index_page(): 16 | return flask.render_template('index_page.html') 17 | 18 | @app.route('/redis/.html', methods=['GET']) 19 | def redis_monitor_page(server_md5): 20 | return flask.render_template('redis_monitor_page.html', server_md5 = server_md5) 21 | 22 | @app.route('/redis_ping.json', methods=['GET', 'POST']) 23 | def redis_ping(): 24 | try: 25 | host = RequestUtil.get_parameter(request, 'host', '') 26 | port = int(RequestUtil.get_parameter(request, 'port', '6379')) 27 | password = RequestUtil.get_parameter(request, 'password', '') 28 | # rst = RedisMonitor().ping(host = host, port = port, password = password) 29 | rst = {'success': 1, 'data': 'ping error'} 30 | except: 31 | rst = {'success': 1, 'data': 'ping error'} 32 | return OtherUtil.object_2_dict(rst) 33 | 34 | @app.route('/http/.html', methods=['GET']) 35 | def http_monitor_page(server_md5): 36 | return flask.render_template('http_monitor_page.html', server_md5 = server_md5) 37 | 38 | @app.route('/server_information.json', methods=['GET', 'POST']) 39 | def get_server_paramter(): 40 | try: 41 | type = RequestUtil.get_parameter(request, 'type', '') 42 | host = RequestUtil.get_parameter(request, 'host', '1') 43 | port = int(RequestUtil.get_parameter(request, 'port', '6379')) 44 | password = RequestUtil.get_parameter(request, 'password', '') 45 | if type == 'http': 46 | rst = HttpMonitor().get_info(url = host) 47 | elif type == 'redis': 48 | rst = RedisMonitor().get_info(host = host, port = port, password = password) 49 | else: 50 | rst = {'success': 1, 'data': 0} 51 | except: 52 | rst = {'success': 0, 'data': ''} 53 | return OtherUtil.object_2_dict(rst) 54 | 55 | 56 | 57 | #定义404页面 58 | @app.errorhandler(404) 59 | def page_not_found(error): 60 | return '404' 61 | 62 | @app.errorhandler(502) 63 | def server_502_error(error): 64 | return '502' 65 | 66 | @app.route('/not_allow', methods=['GET']) 67 | def deny(error): 68 | return 'You IP address is not in white list...' -------------------------------------------------------------------------------- /app/wraps/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/app/wraps/__init__.py -------------------------------------------------------------------------------- /app/wraps/allow_request_wrap.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年6月17日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | 8 | -------------------------------------------------------------------------------- /app/wraps/async_task_wrap.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年6月16日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | from functools import wraps 8 | from threading import Thread 9 | 10 | 11 | def async_task(f): 12 | ''' 13 | wrap with this, the function will be async 14 | use at task which need long time to finish 15 | ''' 16 | @wraps(f) 17 | def wrapper(*args, **kwargs): 18 | thr = Thread(target=f, args=args, kwargs=kwargs) 19 | thr.start() 20 | return wrapper -------------------------------------------------------------------------------- /app/wraps/login_wrap.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年1月28日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | from functools import wraps 8 | 9 | from flask import request, redirect, url_for 10 | from flask.globals import session 11 | 12 | 13 | 14 | def login_required(f): 15 | ''' 16 | need login wrap 17 | ''' 18 | @wraps(f) 19 | def decorated_function(*args, **kwargs): 20 | if 'u_id' not in session or session['u_id'] is None or session['u_id'] == '': 21 | return redirect(url_for('login', next = request.url)) 22 | return f(*args, **kwargs) 23 | return decorated_function -------------------------------------------------------------------------------- /app/wraps/mysql_escape_warp.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年3月30日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | 8 | from functools import wraps 9 | import types 10 | 11 | import MySQLdb 12 | 13 | #对字典经典转义 14 | def _str_escape(s, d): 15 | if s == None: 16 | return '' 17 | return MySQLdb.escape_string(s) 18 | 19 | def _no_escape(s, d): 20 | if s == None: 21 | return '' 22 | return s 23 | 24 | def mysql_escape(f): 25 | @wraps(f) 26 | def decorated_function(*args, **kwargs): 27 | newargs = [] 28 | #先转义参数,再执行方法 29 | for arg in args: 30 | #字符串,包括中文 31 | if type(arg) is types.StringType or type(arg) is types.UnicodeType: 32 | newargs.append(MySQLdb.escape_string(arg)) 33 | 34 | #字典 35 | elif isinstance(arg, dict): 36 | newargs.append(MySQLdb.escape_dict(arg, { 37 | types.StringType: _str_escape, 38 | types.UnicodeType: _str_escape, 39 | types.IntType: _no_escape, 40 | types.FloatType: _no_escape 41 | })) 42 | #其他类型不转义 43 | else: 44 | newargs.append(arg) 45 | 46 | newargs = tuple(newargs) 47 | 48 | func = f(*newargs, **kwargs) 49 | 50 | return func 51 | return decorated_function -------------------------------------------------------------------------------- /app/wraps/singleton_wrap.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年8月21日 4 | 单利模式装饰器 5 | @author: hzwangzhiwei 6 | ''' 7 | def singleton(cls, *args, **kw): 8 | instances = {} 9 | def _singleton(): 10 | if cls not in instances: 11 | instances[cls] = cls(*args, **kw) 12 | return instances[cls] 13 | return _singleton -------------------------------------------------------------------------------- /app/wraps/trace_wrap.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2015年8月21日 4 | 5 | @author: hzwangzhiwei 6 | ''' 7 | 8 | from functools import wraps 9 | import traceback 10 | 11 | #定义一个trace监控的装饰器 12 | def log_traceback(f): 13 | @wraps(f) 14 | def decorated_function(*args, **kwargs): 15 | #先执行方法,然后写日志 16 | try: 17 | func = f(*args, **kwargs) 18 | return func 19 | except: 20 | #如果出现trace异常,发送到服务器 21 | trace = traceback.format_exc() 22 | print trace 23 | #TODO 将trace写入到文件或者post到服务器中 24 | return func 25 | return decorated_function -------------------------------------------------------------------------------- /doc/shot/shot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/doc/shot/shot_1.png -------------------------------------------------------------------------------- /doc/shot/shot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/doc/shot/shot_2.png -------------------------------------------------------------------------------- /doc/shot/shot_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdgdsffdsfff/simple-server-monitor/91f8dc4edb3101faebdd81fdf91bf139be99ec57/doc/shot/shot_3.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask 2 | requests 3 | redis -------------------------------------------------------------------------------- /run_monitor.py: -------------------------------------------------------------------------------- 1 | #coding=utf-8 2 | ''' 3 | Created on 2014年7月19日 4 | 一个flask 的sample 5 | @contact: http://www.atool.org 6 | ''' 7 | 8 | 9 | from app import app 10 | if __name__ == '__main__': 11 | app.run('0.0.0.0', 7259, debug = True, threaded = True) 12 | 13 | --------------------------------------------------------------------------------