diff --git a/web/public/js/components.js b/web/public/js/components.js
index 27efaa07..64134d4d 100755
--- a/web/public/js/components.js
+++ b/web/public/js/components.js
@@ -1,3 +1,213 @@
+Vue.component("traffic-map-box", {
+ props: ["v-stats", "v-is-attack"],
+ mounted: function () {
+ this.render()
+ },
+ data: function () {
+ let maxPercent = 0
+ let isAttack = this.vIsAttack
+ this.vStats.forEach(function (v) {
+ let percent = parseFloat(v.percent)
+ if (percent > maxPercent) {
+ maxPercent = percent
+ }
+
+ v.formattedCountRequests = teaweb.formatCount(v.countRequests) + "次"
+ v.formattedCountAttackRequests = teaweb.formatCount(v.countAttackRequests) + "次"
+ })
+
+ if (maxPercent < 100) {
+ maxPercent *= 1.2 // 不要让某一项100%
+ }
+
+ return {
+ isAttack: isAttack,
+ stats: this.vStats,
+ chart: null,
+ minOpacity: 0.2,
+ maxPercent: maxPercent,
+ selectedCountryName: ""
+ }
+ },
+ 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: "#DDD"
+ },
+ emphasis: {
+ itemStyle: {
+ areaColor: "#8B9BD3",
+ opacity: 1.0
+ }
+ },
+ //select: {itemStyle:{ areaColor: "#8B9BD3", opacity: 0.8 }},
+ 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 + "
流量占比:" + stat.percent + "%
请求数:" + stat.formattedCountRequests + "
攻击数:" + stat.formattedCountAttackRequests
+ }
+ 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 = that.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
+ }
+ },
+ label: {
+ show: false,
+ formatter: function (args) {
+ if (args.name == that.selectedCountryName) {
+ return args.name
+ }
+ return ""
+ },
+ fontSize: "10px",
+ color: "#fff",
+ backgroundColor: "#8B9BD3",
+ padding: [2, 2, 2, 2]
+ }
+ }
+ }),
+ 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
+ v.label.show = false
+ that.selectedCountryName = ""
+ return
+ }
+ v.isSelected = true
+ that.selectedCountryName = countryName
+ opacity *= 3
+ if (opacity > 1) {
+ opacity = 1
+ }
+
+ // 至少是0.5,让用户能够看清
+ if (opacity < 0.5) {
+ opacity = 0.5
+ }
+ v.itemStyle.opacity = opacity
+ v.label.show = true
+ } else {
+ v.itemStyle.opacity = opacity
+ v.isSelected = false
+ v.label.show = false
+ }
+ })
+ this.chart.setOption(option)
+ }
+ },
+ template: `
| + + | +
+
+
+
|
+ ||||||
为了给您提供更好的服务,我们正在升级网站,请稍后重新访问。
- +Request ID: \${requestId}, Powered by GoEdge.