diff --git a/web/public/js/components/maps/traffic-map-box.js b/web/public/js/components/maps/traffic-map-box.js new file mode 100644 index 00000000..296b2806 --- /dev/null +++ b/web/public/js/components/maps/traffic-map-box.js @@ -0,0 +1,183 @@ +Vue.component("traffic-map-box", { + props: ["v-stats", "v-is-attack"], + mounted: function () { + this.render() + }, + data: function () { + let maxPercent = 0 + this.vStats.forEach(function (v) { + let percent = parseFloat(v.percent) + if (percent > maxPercent) { + maxPercent = percent + } + }) + + if (maxPercent < 100) { + maxPercent *= 1.2 // 不要让某一项100% + } + + return { + stats: this.vStats, + chart: null, + minOpacity: 0.2, + maxPercent: maxPercent + } + }, + methods: { + render: function () { + this.chart = teaweb.initChart(document.getElementById("traffic-map-box")); + let that = this + this.chart.setOption({ + backgroundColor: "white", + grid: {top: 0, bottom: 0, left: 0, right: 0}, + roam: true, + tooltip: { + trigger: "item" + }, + series: [{ + type: "map", + map: "world", + zoom: 1.2, + selectedMode: false, + itemStyle: { + areaColor: "#E9F0F9", + borderColor: "#999" + }, + emphasis: { + itemStyle: { + areaColor: "#8B9BD3", + opacity: 1.0 + } + }, + //select: {itemStyle:{ areaColor: "#8B9BD3", opacity: 0.8 }}, + label: { + show: true, + formatter: function (args) { + return "" + } + }, + tooltip: { + formatter: function (args) { + let name = args.name + let stat = null + that.stats.forEach(function (v) { + if (v.name == name) { + stat = v + } + }) + + if (stat != null) { + return name + "
流量:" + stat.formattedBytes + "
请求数:" + teaweb.formatNumber(stat.countRequests) + "
流量占比:" + stat.percent + "%" + } + return name + } + }, + data: this.stats.map(function (v) { + let opacity = parseFloat(v.percent) / that.maxPercent + if (opacity < that.minOpacity) { + opacity = that.minOpacity + } + let fullOpacity = opacity * 3 + if (fullOpacity > 1) { + fullOpacity = 1 + } + let isAttack = this.vIsAttack + let bgColor = "#276AC6" + if (isAttack) { + bgColor = "#B03A5B" + } + return { + name: v.name, + value: v.bytes, + percent: parseFloat(v.percent), + itemStyle: { + areaColor: bgColor, + opacity: opacity + }, + emphasis: { + itemStyle: { + areaColor: bgColor, + opacity: fullOpacity + } + } + } + }), + nameMap: window.WorldCountriesMap + }] + }) + this.chart.resize() + }, + select: function (countryName) { + if (this.chart == null) { + return + } + let option = this.chart.getOption() + let that = this + option.series[0].data.forEach(function (v) { + let opacity = v.percent / that.maxPercent + if (opacity < that.minOpacity) { + opacity = that.minOpacity + } + + if (v.name == countryName) { + if (v.isSelected) { + v.itemStyle.opacity = opacity + v.isSelected = false + return + } + v.isSelected = true + opacity *= 3 + if (opacity > 1) { + opacity = 1 + } + + // 至少是0.5,让用户能够看清 + if (opacity < 0.5) { + opacity = 0.5 + } + v.itemStyle.opacity = opacity + } else { + v.itemStyle.opacity = opacity + v.isSelected = false + } + }) + this.chart.setOption(option) + } + }, + template: `
+ + + + + +
+
+
+
+ + + + + + + + + + + + + + + + +
国家/地区排行
暂无数据
+
+
+
+
{{stat.name}}
+
{{stat.percent}}% ({{stat.formattedBytes}})
+
+
+
+
` +}) \ No newline at end of file diff --git a/web/public/js/components/server/metric-charts.js b/web/public/js/components/server/metric-charts.js index 6e7354c2..62826bbd 100644 --- a/web/public/js/components/server/metric-charts.js +++ b/web/public/js/components/server/metric-charts.js @@ -411,7 +411,7 @@ Vue.component("metric-chart", { template: `

{{chart.name}} ({{valueTypeName}})

-
+
` }) diff --git a/web/public/js/world-countries-map.js b/web/public/js/world-countries-map.js new file mode 100644 index 00000000..ad44582f --- /dev/null +++ b/web/public/js/world-countries-map.js @@ -0,0 +1,191 @@ +window.WorldCountriesMap = { + "Afghanistan": "阿富汗", + "Albania": "阿尔巴尼亚", + "Algeria": "阿尔及利亚", + "Angola": "安哥拉", + "Argentina": "阿根廷", + "Armenia": "亚美尼亚", + "Australia": "澳大利亚", + "Austria": "奥地利", + "Azerbaijan": "阿塞拜疆", + "Bahamas": "巴哈马", + "Bahrain": "巴林", + "Bangladesh": "孟加拉国", + "Belarus": "白俄罗斯", + "Belgium": "比利时", + "Belize": "伯利兹", + "Benin": "贝宁", + "Bhutan": "不丹", + "Bolivia": "玻利维亚", + "Bosnia and Herz.": "波斯尼亚和墨塞哥维那", + "Botswana": "博茨瓦纳", + "Brazil": "巴西", + "British Virgin Islands": "英属维尔京群岛", + "Brunei": "文莱", + "Bulgaria": "保加利亚", + "Burkina Faso": "布基纳法索", + "Burundi": "布隆迪", + "Cambodia": "柬埔寨", + "Cameroon": "喀麦隆", + "Canada": "加拿大", + "Cape Verde": "佛得角", + "Cayman Islands": "开曼群岛", + "Central African Rep.": "中非共和国", + "Chad": "乍得", + "Chile": "智利", + "China": "中国", + "Colombia": "哥伦比亚", + "Comoros": "科摩罗", + "Congo": "刚果共和国", + "Costa Rica": "哥斯达黎加", + "Croatia": "克罗地亚", + "Cuba": "古巴", + "Cyprus": "塞浦路斯", + "Czech Rep.": "捷克", + "Côte d'Ivoire": "科特迪瓦", + "Dem. Rep. Congo": "刚果民主共和国", + "Dem. Rep. Korea": "朝鲜", + "Denmark": "丹麦", + "Djibouti": "吉布提", + "Dominican Rep.": "多米尼加共和国", + "Ecuador": "厄瓜多尔", + "Egypt": "埃及", + "El Salvador": "萨尔瓦多", + "Equatorial Guinea": "赤道几内亚", + "Eritrea": "厄立特里亚", + "Estonia": "爱沙尼亚", + "Ethiopia": "埃塞俄比亚", + "Falkland Is.": "福克兰群岛", + "Fiji": "斐济", + "Finland": "芬兰", + "Fr. S. Antarctic Lands": "所罗门群岛", + "France": "法国", + "Gabon": "加蓬", + "Gambia": "冈比亚", + "Georgia": "格鲁吉亚", + "Germany": "德国", + "Ghana": "加纳", + "Greece": "希腊", + "Greenland": "格陵兰", + "Guatemala": "危地马拉", + "Guinea": "几内亚", + "Guinea-Bissau": "几内亚比绍", + "Guyana": "圭亚那", + "Haiti": "海地", + "Honduras": "洪都拉斯", + "Hungary": "匈牙利", + "Iceland": "冰岛", + "India": "印度", + "Indonesia": "印度尼西亚", + "Iran": "伊朗", + "Iraq": "伊拉克", + "Ireland": "爱尔兰", + "Isle of Man": "英属马恩岛", + "Israel": "以色列", + "Italy": "意大利", + "Jamaica": "牙买加", + "Japan": "日本", + "Jordan": "约旦", + "Kazakhstan": "哈萨克斯坦", + "Kenya": "肯尼亚", + "Korea": "韩国", + "Kuwait": "科威特", + "Kyrgyzstan": "吉尔吉斯斯坦", + "Lao PDR": "老挝", + "Latvia": "拉脱维亚", + "Lebanon": "黎巴嫩", + "Lesotho": "莱索托", + "Liberia": "利比里亚", + "Libya": "利比亚", + "Lithuania": "立陶宛", + "Luxembourg": "卢森堡", + "Macedonia": "马其顿", + "Madagascar": "马达加斯加", + "Malawi": "马拉维", + "Malaysia": "马来西亚", + "Maldives": "马尔代夫", + "Mali": "马里", + "Malta": "马耳他", + "Mauritania": "毛里塔尼亚", + "Mauritius": "毛里求斯", + "Mexico": "墨西哥", + "Moldova": "摩尔多瓦", + "Monaco": "摩纳哥", + "Mongolia": "蒙古", + "Montenegro": "黑山共和国", + "Morocco": "摩洛哥", + "Mozambique": "莫桑比克", + "Myanmar": "缅甸", + "Namibia": "纳米比亚", + "Nepal": "尼泊尔", + "Netherlands": "荷兰", + "New Caledonia": "新喀里多尼亚", + "New Zealand": "新西兰", + "Nicaragua": "尼加拉瓜", + "Niger": "尼日尔", + "Nigeria": "尼日利亚", + "Norway": "挪威", + "Oman": "阿曼", + "Pakistan": "巴基斯坦", + "Panama": "巴拿马", + "Papua New Guinea": "巴布亚新几内亚", + "Paraguay": "巴拉圭", + "Peru": "秘鲁", + "Philippines": "菲律宾", + "Poland": "波兰", + "Portugal": "葡萄牙", + "Puerto Rico": "波多黎各", + "Qatar": "卡塔尔", + "Reunion": "留尼旺", + "Romania": "罗马尼亚", + "Russia": "俄罗斯", + "Rwanda": "卢旺达", + "S. Geo. and S. Sandw. Is.": "南乔治亚岛和南桑威奇群岛", + "S. Sudan": "南苏丹", + "San Marino": "圣马力诺", + "Saudi Arabia": "沙特阿拉伯", + "Senegal": "塞内加尔", + "Serbia": "塞尔维亚", + "Sierra Leone": "塞拉利昂", + "Singapore": "新加坡", + "Slovakia": "斯洛伐克", + "Slovenia": "斯洛文尼亚", + "Solomon Is.": "所罗门群岛", + "Somalia": "索马里", + "South Africa": "南非", + "Spain": "西班牙", + "Sri Lanka": "斯里兰卡", + "Sudan": "苏丹", + "Suriname": "苏里南", + "Swaziland": "斯威士兰", + "Sweden": "瑞典", + "Switzerland": "瑞士", + "Syria": "叙利亚", + "Tajikistan": "塔吉克斯坦", + "Tanzania": "坦桑尼亚", + "Thailand": "泰国", + "Togo": "多哥", + "Tonga": "汤加", + "Trinidad and Tobago": "特立尼达和多巴哥", + "Tunisia": "突尼斯", + "Turkey": "土耳其", + "Turkmenistan": "土库曼斯坦", + "U.S. Virgin Islands": "美属维尔京群岛", + "Uganda": "乌干达", + "Ukraine": "乌克兰", + "United Arab Emirates": "阿拉伯联合酋长国", + "United Kingdom": "英国", + "United States": "美国", + "Uruguay": "乌拉圭", + "Uzbekistan": "乌兹别克斯坦", + "Vanuatu": "瓦努阿图共和国", + "Vatican City": "梵蒂冈", + "Venezuela": "委内瑞拉", + "Vietnam": "越南", + "W. Sahara": "西撒哈拉", + "Yemen": "也门", + "Yugoslavia": "南斯拉夫", + "Zaire": "扎伊尔", + "Zambia": "赞比亚", + "Zimbabwe": "津巴布韦" +} \ No newline at end of file diff --git a/web/views/@default/clusters/cluster/boards/index.css b/web/views/@default/clusters/cluster/boards/index.css index 32455584..1d37831e 100644 --- a/web/views/@default/clusters/cluster/boards/index.css +++ b/web/views/@default/clusters/cluster/boards/index.css @@ -26,7 +26,7 @@ display: inline; } .chart-box { - height: 20em; + height: 14em; } h4 span { font-size: 0.8em; diff --git a/web/views/@default/clusters/cluster/boards/index.less b/web/views/@default/clusters/cluster/boards/index.less index 8c27d9ce..0e788f91 100644 --- a/web/views/@default/clusters/cluster/boards/index.less +++ b/web/views/@default/clusters/cluster/boards/index.less @@ -38,7 +38,7 @@ } .chart-box { - height: 20em; + height: 14em; } h4 { diff --git a/web/views/@default/clusters/cluster/node/boards/index.css b/web/views/@default/clusters/cluster/node/boards/index.css index 32455584..1d37831e 100644 --- a/web/views/@default/clusters/cluster/node/boards/index.css +++ b/web/views/@default/clusters/cluster/node/boards/index.css @@ -26,7 +26,7 @@ display: inline; } .chart-box { - height: 20em; + height: 14em; } h4 span { font-size: 0.8em; diff --git a/web/views/@default/clusters/cluster/node/boards/index.less b/web/views/@default/clusters/cluster/node/boards/index.less index 8c27d9ce..0e788f91 100644 --- a/web/views/@default/clusters/cluster/node/boards/index.less +++ b/web/views/@default/clusters/cluster/node/boards/index.less @@ -38,7 +38,7 @@ } .chart-box { - height: 20em; + height: 14em; } h4 { diff --git a/web/views/@default/dashboard/boards/dns.css b/web/views/@default/dashboard/boards/dns.css index 27ad787d..99af3c69 100644 --- a/web/views/@default/dashboard/boards/dns.css +++ b/web/views/@default/dashboard/boards/dns.css @@ -28,6 +28,6 @@ display: inline; } .chart-box { - height: 20em; + height: 14em; } /*# sourceMappingURL=dns.css.map */ \ No newline at end of file diff --git a/web/views/@default/dashboard/boards/dns.less b/web/views/@default/dashboard/boards/dns.less index fcb67336..0e503413 100644 --- a/web/views/@default/dashboard/boards/dns.less +++ b/web/views/@default/dashboard/boards/dns.less @@ -42,5 +42,5 @@ } .chart-box { - height: 20em; + height: 14em; } \ No newline at end of file diff --git a/web/views/@default/dashboard/boards/index.css b/web/views/@default/dashboard/boards/index.css index 5b8adc8c..76a0d662 100644 --- a/web/views/@default/dashboard/boards/index.css +++ b/web/views/@default/dashboard/boards/index.css @@ -28,7 +28,13 @@ display: inline; } .chart-box { - height: 20em; + height: 14em; +} +.traffic-map-box { + height: 16em; +} +.traffic-map-box div::-webkit-scrollbar { + width: 4px; } h4 span { font-size: 0.8em; diff --git a/web/views/@default/dashboard/boards/index.css.map b/web/views/@default/dashboard/boards/index.css.map index 7d33dd48..ce6de77e 100644 --- a/web/views/@default/dashboard/boards/index.css.map +++ b/web/views/@default/dashboard/boards/index.css.map @@ -1 +1 @@ -{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA,GAAG,QACF,EACC,MAAK;EACJ,kBAAA;EACA,UAAA;EACA,QAAA;;AAKH;EACC,0BAAA;EACA,2BAAA;;AAFD,KAIC;EACC,kBAAA;EACA,4BAAA;;AANF,KAIC,QAIC,IAAG;EACF,iBAAA;;AATH,KAIC,QAIC,IAAG,MAGF;EACC,cAAA;EACA,mBAAA;;AAbJ,KAkBC,QAAO;EACN,eAAA;;AAnBF,KAsBC,GACC;EACC,aAAA;;AAxBH,KA4BC,QAAO,MACN;EACC,eAAA;;AAKH;EACC,YAAA;;AAGD,EACC;EACC,gBAAA;EACA,WAAA","file":"index.css"} \ No newline at end of file +{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA,GAAG,QACF,EACC,MAAK;EACJ,kBAAA;EACA,UAAA;EACA,QAAA;;AAKH;EACC,0BAAA;EACA,2BAAA;;AAFD,KAIC;EACC,kBAAA;EACA,4BAAA;;AANF,KAIC,QAIC,IAAG;EACF,iBAAA;;AATH,KAIC,QAIC,IAAG,MAGF;EACC,cAAA;EACA,mBAAA;;AAbJ,KAkBC,QAAO;EACN,eAAA;;AAnBF,KAsBC,GACC;EACC,aAAA;;AAxBH,KA4BC,QAAO,MACN;EACC,eAAA;;AAKH;EACC,YAAA;;AAGD;EACC,YAAA;;AADD,gBAGC,IAAG;EACF,UAAA;;AAIF,EACC;EACC,gBAAA;EACA,WAAA","file":"index.css"} \ No newline at end of file diff --git a/web/views/@default/dashboard/boards/index.html b/web/views/@default/dashboard/boards/index.html index cff3f284..99866c2c 100644 --- a/web/views/@default/dashboard/boards/index.html +++ b/web/views/@default/dashboard/boards/index.html @@ -1,5 +1,11 @@ {$layout} -{$template "/echarts"} + +{$var "header"} + + + + +{$end} {$template "menu"} @@ -111,6 +117,12 @@
+ +
+ +
+
+