商业版首页增加地图/调低各个图表的高度,以便同时可以显示更多的图表

This commit is contained in:
GoEdgeLab
2021-12-05 18:59:20 +08:00
parent 7db6e536fc
commit 90f48a1a3c
27 changed files with 447 additions and 30 deletions

View File

@@ -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 + "<br/>流量:" + stat.formattedBytes + "<br/>请求数:" + teaweb.formatNumber(stat.countRequests) + "<br/>流量占比:" + 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: `<div>
<table style="width: 100%; border: 0; padding: 0; margin: 0">
<tr>
<td>
<div class="traffic-map-box" id="traffic-map-box" ></div>
</td>
<td style="width: 14em">
<div style="overflow-y: auto; height: 16em">
<table class="ui table selectable">
<thead>
<tr>
<th colspan="2">国家/地区排行</th>
</tr>
</thead>
<tbody v-if="stats.length == 0">
<tr>
<td colspan="2">暂无数据</td>
</tr>
</tbody>
<tbody>
<tr v-for="(stat, index) in stats.slice(0, 10)">
<td @click.prevent="select(stat.name)" style="cursor: pointer" colspan="2">
<div class="ui progress bar blue" style="margin-bottom: 0.3em">
<div class="bar" style="min-width: 0; height: 4px;" :style="{width: stat.percent + '%'}"></div>
</div>
<div>{{stat.name}}</div>
<div><span class="grey">{{stat.percent}}% </span><span class="small grey">{{stat.formattedBytes}}</span></div>
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</table>
</div>`
})

View File

@@ -411,7 +411,7 @@ Vue.component("metric-chart", {
template: `<div style="float: left" :style="{'width': width}"> template: `<div style="float: left" :style="{'width': width}">
<h4>{{chart.name}} <span>{{valueTypeName}}</span></h4> <h4>{{chart.name}} <span>{{valueTypeName}}</span></h4>
<div class="ui divider"></div> <div class="ui divider"></div>
<div style="height: 20em; padding-bottom: 1em; " :id="chartId" :class="{'scroll-box': chart.type == 'table'}"></div> <div style="height: 14em; padding-bottom: 1em; " :id="chartId" :class="{'scroll-box': chart.type == 'table'}"></div>
</div>` </div>`
}) })

View File

@@ -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": "津巴布韦"
}

View File

@@ -26,7 +26,7 @@
display: inline; display: inline;
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
h4 span { h4 span {
font-size: 0.8em; font-size: 0.8em;

View File

@@ -38,7 +38,7 @@
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
h4 { h4 {

View File

@@ -26,7 +26,7 @@
display: inline; display: inline;
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
h4 span { h4 span {
font-size: 0.8em; font-size: 0.8em;

View File

@@ -38,7 +38,7 @@
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
h4 { h4 {

View File

@@ -28,6 +28,6 @@
display: inline; display: inline;
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
/*# sourceMappingURL=dns.css.map */ /*# sourceMappingURL=dns.css.map */

View File

@@ -42,5 +42,5 @@
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }

View File

@@ -28,7 +28,13 @@
display: inline; display: inline;
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
}
.traffic-map-box {
height: 16em;
}
.traffic-map-box div::-webkit-scrollbar {
width: 4px;
} }
h4 span { h4 span {
font-size: 0.8em; font-size: 0.8em;

View File

@@ -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"} {"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"}

View File

@@ -1,5 +1,11 @@
{$layout} {$layout}
{$template "/echarts"}
{$var "header"}
<!-- world map -->
<script type="text/javascript" src="/js/echarts/echarts.min.js"></script>
<script type="text/javascript" src="/js/world.js"></script>
<script type="text/javascript" src="/js/world-countries-map.js"></script>
{$end}
{$template "menu"} {$template "menu"}
@@ -111,6 +117,12 @@
<div class="ui divider"></div> <div class="ui divider"></div>
<!-- 流量地图 -->
<div class="traffic-map-box" v-if="!isLoading">
<traffic-map-box :v-stats="topCountryStats"></traffic-map-box>
</div>
<div class="ui divider"></div>
<!-- 流量 --> <!-- 流量 -->
<div class="ui menu tabular" v-show="!isLoading"> <div class="ui menu tabular" v-show="!isLoading">
<a href="" class="item" :class="{active: trafficTab == 'hourly'}" @click.prevent="selectTrafficTab('hourly')">24小时流量趋势</a> <a href="" class="item" :class="{active: trafficTab == 'hourly'}" @click.prevent="selectTrafficTab('hourly')">24小时流量趋势</a>

View File

@@ -3,6 +3,7 @@ Tea.context(function () {
this.trafficTab = "hourly" this.trafficTab = "hourly"
this.metricCharts = [] this.metricCharts = []
this.plusExpireDay = "" this.plusExpireDay = ""
this.topCountryStats = []
this.$delay(function () { this.$delay(function () {
this.$post("$") this.$post("$")

View File

@@ -44,7 +44,15 @@
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
}
.traffic-map-box {
height: 16em;
div::-webkit-scrollbar {
width: 4px;
}
} }
h4 { h4 {

View File

@@ -28,7 +28,7 @@
display: inline; display: inline;
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
h4 span { h4 span {
font-size: 0.8em; font-size: 0.8em;

View File

@@ -42,7 +42,7 @@
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
h4 { h4 {

View File

@@ -28,7 +28,7 @@
display: inline; display: inline;
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
.color-span { .color-span {
font-size: 0.8em; font-size: 0.8em;

View File

@@ -42,7 +42,7 @@
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
.color-span { .color-span {

View File

@@ -28,7 +28,7 @@
display: inline; display: inline;
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
h4 span { h4 span {
font-size: 0.8em; font-size: 0.8em;

View File

@@ -44,7 +44,7 @@
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
h4 { h4 {

View File

@@ -28,6 +28,6 @@
display: inline; display: inline;
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
/*# sourceMappingURL=index.css.map */ /*# sourceMappingURL=index.css.map */

View File

@@ -42,5 +42,5 @@
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }

View File

@@ -23,7 +23,7 @@
display: inline; display: inline;
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
h4 span { h4 span {
font-size: 0.8em; font-size: 0.8em;

View File

@@ -34,7 +34,7 @@
} }
.chart-box { .chart-box {
height: 20em; height: 14em;
} }
h4 { h4 {

View File

@@ -1,5 +1,5 @@
.chart-box { .chart-box {
height: 21em; height: 14em;
} }
h4 span.small { h4 span.small {
font-size: 0.8em; font-size: 0.8em;

View File

@@ -4,27 +4,27 @@ Tea.context(function () {
this.reloadRequestsChart("minutely-requests-chart", "请求数统计", this.minutelyStats, function (args) { this.reloadRequestsChart("minutely-requests-chart", "请求数统计", this.minutelyStats, function (args) {
if (args.seriesIndex == 0) { if (args.seriesIndex == 0) {
return that.minutelyStats[args.dataIndex].day + " " + that.minutelyStats[args.dataIndex].minute + " 请求数: " + teaweb.formatNumber(that.minutelyStats[args.dataIndex].countRequests) return that.minutelyStats[args.dataIndex].day + " " + that.minutelyStats[args.dataIndex].minute + "<br/>请求数: " + teaweb.formatNumber(that.minutelyStats[args.dataIndex].countRequests)
} }
if (args.seriesIndex == 1) { if (args.seriesIndex == 1) {
let ratio = 0 let ratio = 0
if (that.minutelyStats[args.dataIndex].countRequests > 0) { if (that.minutelyStats[args.dataIndex].countRequests > 0) {
ratio = Math.round(that.minutelyStats[args.dataIndex].countCachedRequests * 10000 / that.minutelyStats[args.dataIndex].countRequests) / 100 ratio = Math.round(that.minutelyStats[args.dataIndex].countCachedRequests * 10000 / that.minutelyStats[args.dataIndex].countRequests) / 100
} }
return that.minutelyStats[args.dataIndex].day + " " + that.minutelyStats[args.dataIndex].minute + " 缓存请求数: " + teaweb.formatNumber(that.minutelyStats[args.dataIndex].countCachedRequests) + ", 命中率:" + ratio + "%" return that.minutelyStats[args.dataIndex].day + " " + that.minutelyStats[args.dataIndex].minute + "<br/>缓存请求数: " + teaweb.formatNumber(that.minutelyStats[args.dataIndex].countCachedRequests) + "<br/>命中率:" + ratio + "%"
} }
return "" return ""
}) })
this.reloadTrafficChart("minutely-traffic-chart", "流量统计", this.minutelyStats, function (args) { this.reloadTrafficChart("minutely-traffic-chart", "流量统计", this.minutelyStats, function (args) {
if (args.seriesIndex == 0) { if (args.seriesIndex == 0) {
return that.minutelyStats[args.dataIndex].day + " " + that.minutelyStats[args.dataIndex].minute + " 流量: " + teaweb.formatBytes(that.minutelyStats[args.dataIndex].bytes) return that.minutelyStats[args.dataIndex].day + " " + that.minutelyStats[args.dataIndex].minute + "<br/>流量: " + teaweb.formatBytes(that.minutelyStats[args.dataIndex].bytes)
} }
if (args.seriesIndex == 1) { if (args.seriesIndex == 1) {
let ratio = 0 let ratio = 0
if (that.minutelyStats[args.dataIndex].bytes > 0) { if (that.minutelyStats[args.dataIndex].bytes > 0) {
ratio = Math.round(that.minutelyStats[args.dataIndex].cachedBytes * 10000 / that.minutelyStats[args.dataIndex].bytes) / 100 ratio = Math.round(that.minutelyStats[args.dataIndex].cachedBytes * 10000 / that.minutelyStats[args.dataIndex].bytes) / 100
} }
return that.minutelyStats[args.dataIndex].day + " " + that.minutelyStats[args.dataIndex].minute + " 缓存流量: " + teaweb.formatBytes(that.minutelyStats[args.dataIndex].cachedBytes) + ", 命中率:" + ratio + "%" return that.minutelyStats[args.dataIndex].day + " " + that.minutelyStats[args.dataIndex].minute + "<br/>缓存流量: " + teaweb.formatBytes(that.minutelyStats[args.dataIndex].cachedBytes) + "<br/>命中率:" + ratio + "%"
} }
return "" return ""
}) })
@@ -36,6 +36,15 @@ Tea.context(function () {
return return
} }
// 每N分钟取一次
let newStats = []
for (let i = 0; i < stats.length; i++) {
if (i % 5 == 0) {
newStats.push(stats[i])
}
}
stats = newStats
let axis = teaweb.countAxis(stats, function (v) { let axis = teaweb.countAxis(stats, function (v) {
return Math.max(v.countRequests, v.countCachedRequests) return Math.max(v.countRequests, v.countCachedRequests)
}) })
@@ -72,9 +81,7 @@ Tea.context(function () {
data: stats.map(function (v) { data: stats.map(function (v) {
return v.countRequests / axis.divider return v.countRequests / axis.divider
}), }),
itemStyle: {
color: "#9DD3E8"
},
areaStyle: { areaStyle: {
color: "#9DD3E8" color: "#9DD3E8"
}, },
@@ -110,6 +117,15 @@ Tea.context(function () {
return return
} }
// 每N分钟取一次
let newStats = []
for (let i = 0; i < stats.length; i++) {
if (i % 5 == 0) {
newStats.push(stats[i])
}
}
stats = newStats
let axis = teaweb.bytesAxis(stats, function (v) { let axis = teaweb.bytesAxis(stats, function (v) {
return Math.max(v.bytes, v.cachedBytes) return Math.max(v.bytes, v.cachedBytes)
}) })

View File

@@ -1,5 +1,5 @@
.chart-box { .chart-box {
height: 21em; height: 14em;
} }
h4 span.small { h4 span.small {