Files
EdgeAdmin/web/public/js/components/server/metric-charts.js
2021-07-21 08:07:46 +08:00

417 lines
9.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 指标图表
Vue.component("metric-chart", {
props: ["v-chart", "v-stats", "v-item"],
mounted: function () {
this.load()
},
data: function () {
let stats = this.vStats
if (stats == null) {
stats = []
}
if (stats.length > 0) {
let sum = stats.$sum(function (k, v) {
return v.value
})
if (sum < stats[0].total) {
if (this.vChart.type == "pie") {
stats.push({
keys: ["其他"],
value: stats[0].total - sum,
total: stats[0].total,
time: stats[0].time
})
}
}
}
if (this.vChart.maxItems > 0) {
stats = stats.slice(0, this.vChart.maxItems)
} else {
stats = stats.slice(0, 10)
}
stats.$rsort(function (v1, v2) {
return v1.value - v2.value
})
let widthPercent = 100
if (this.vChart.widthDiv > 0) {
widthPercent = 100 / this.vChart.widthDiv
}
return {
chart: this.vChart,
stats: stats,
item: this.vItem,
width: widthPercent + "%",
chartId: "metric-chart-" + this.vChart.id,
valueTypeName: (this.vItem != null && this.vItem.valueTypeName != null && this.vItem.valueTypeName.length > 0) ? this.vItem.valueTypeName : ""
}
},
methods: {
load: function () {
var el = document.getElementById(this.chartId)
if (el == null || el.offsetWidth == 0 || el.offsetHeight == 0) {
setTimeout(this.load, 100)
} else {
this.render(el)
}
},
render: function (el) {
let chart = echarts.init(el)
window.addEventListener("resize", function () {
chart.resize()
})
switch (this.chart.type) {
case "pie":
this.renderPie(chart)
break
case "bar":
this.renderBar(chart)
break
case "timeBar":
this.renderTimeBar(chart)
break
case "timeLine":
this.renderTimeLine(chart)
break
case "table":
this.renderTable(chart)
break
}
},
renderPie: function (chart) {
let values = this.stats.map(function (v) {
return {
name: v.keys[0],
value: v.value
}
})
let that = this
chart.setOption({
tooltip: {
show: true,
trigger: "item",
formatter: function (data) {
let stat = that.stats[data.dataIndex]
let percent = 0
if (stat.total > 0) {
percent = Math.round((stat.value * 100 / stat.total) * 100) / 100
}
let value = stat.value
switch (that.item.valueType) {
case "byte":
value = teaweb.formatBytes(value)
break
}
return stat.keys[0] + ": " + value + ",占比:" + percent + "%"
}
},
series: [
{
name: name,
type: "pie",
data: values,
areaStyle: {},
color: ["#9DD3E8", "#B2DB9E", "#F39494", "#FBD88A", "#879BD7"]
}
]
})
},
renderTimeBar: function (chart) {
this.stats.$sort(function (v1, v2) {
return (v1.time < v2.time) ? -1 : 1
})
let values = this.stats.map(function (v) {
return v.value
})
let axis = {unit: "", divider: 1}
switch (this.item.valueType) {
case "count":
axis = teaweb.countAxis(values, function (v) {
return v
})
break
case "byte":
axis = teaweb.bytesAxis(values, function (v) {
return v
})
break
}
let that = this
chart.setOption({
xAxis: {
data: this.stats.map(function (v) {
return that.formatTime(v.time)
})
},
yAxis: {
axisLabel: {
formatter: function (value) {
return value + axis.unit
}
}
},
tooltip: {
show: true,
trigger: "item",
formatter: function (data) {
let stat = that.stats[data.dataIndex]
let value = stat.value
switch (that.item.valueType) {
case "byte":
value = teaweb.formatBytes(value)
break
}
return that.formatTime(stat.time) + ": " + value
}
},
grid: {
left: 50,
top: 10,
right: 20,
bottom: 25
},
series: [
{
name: name,
type: "bar",
data: values.map(function (v) {
return v / axis.divider
}),
itemStyle: {
color: "#9DD3E8"
},
areaStyle: {},
barWidth: "20em"
}
]
})
},
renderTimeLine: function (chart) {
this.stats.$sort(function (v1, v2) {
return (v1.time < v2.time) ? -1 : 1
})
let values = this.stats.map(function (v) {
return v.value
})
let axis = {unit: "", divider: 1}
switch (this.item.valueType) {
case "count":
axis = teaweb.countAxis(values, function (v) {
return v
})
break
case "byte":
axis = teaweb.bytesAxis(values, function (v) {
return v
})
break
}
let that = this
chart.setOption({
xAxis: {
data: this.stats.map(function (v) {
return that.formatTime(v.time)
})
},
yAxis: {
axisLabel: {
formatter: function (value) {
return value + axis.unit
}
}
},
tooltip: {
show: true,
trigger: "item",
formatter: function (data) {
let stat = that.stats[data.dataIndex]
let value = stat.value
switch (that.item.valueType) {
case "byte":
value = teaweb.formatBytes(value)
break
}
return that.formatTime(stat.time) + ": " + value
}
},
grid: {
left: 50,
top: 10,
right: 20,
bottom: 25
},
series: [
{
name: name,
type: "line",
data: values.map(function (v) {
return v / axis.divider
}),
itemStyle: {
color: "#9DD3E8"
},
areaStyle: {}
}
]
})
},
renderBar: function (chart) {
let values = this.stats.map(function (v) {
return v.value
})
let axis = {unit: "", divider: 1}
switch (this.item.valueType) {
case "count":
axis = teaweb.countAxis(values, function (v) {
return v
})
break
case "byte":
axis = teaweb.bytesAxis(values, function (v) {
return v
})
break
}
let bottom = 24
let rotate = 0
let result = teaweb.xRotation(chart, this.stats.map(function (v) {
return v.keys[0]
}))
if (result != null) {
bottom = result[0]
rotate = result[1]
}
let that = this
chart.setOption({
xAxis: {
data: this.stats.map(function (v) {
return v.keys[0]
}),
axisLabel: {
interval: 0,
rotate: rotate
}
},
tooltip: {
show: true,
trigger: "item",
formatter: function (data) {
let stat = that.stats[data.dataIndex]
let percent = 0
if (stat.total > 0) {
percent = Math.round((stat.value * 100 / stat.total) * 100) / 100
}
let value = stat.value
switch (that.item.valueType) {
case "byte":
value = teaweb.formatBytes(value)
break
}
return stat.keys[0] + ": " + value + ",占比:" + percent + "%"
}
},
yAxis: {
axisLabel: {
formatter: function (value) {
return value + axis.unit
}
}
},
grid: {
left: 40,
top: 10,
right: 20,
bottom: bottom
},
series: [
{
name: name,
type: "bar",
data: values.map(function (v) {
return v / axis.divider
}),
itemStyle: {
color: "#9DD3E8"
},
areaStyle: {},
barWidth: "20em"
}
]
})
// IP相关操作
if (this.item.keys != null && this.item.keys.$contains("${remoteAddr}")) {
let that = this
chart.on("click", function (args) {
let index = that.item.keys.$indexesOf("${remoteAddr}")[0]
let value = that.stats[args.dataIndex].keys[index]
teaweb.popup("/servers/ipbox?ip=" + value, {
width: "50em",
height: "30em"
})
})
}
},
renderTable: function (chart) {
let table = `<table class="ui table celled">
<thead>
<tr>
<th>对象</th>
<th>数值</th>
<th>占比</th>
</tr>
</thead>`
this.stats.forEach(function (v) {
let value = v.value
switch (that.item.valueType) {
case "byte":
value = teaweb.formatBytes(value)
break
}
table += "<tr><td>" + v.keys[0] + "</td><td>" + value + "</td>"
let percent = 0
if (v.total > 0) {
percent = Math.round((v.value * 100 / v.total) * 100) / 100
}
table += "<td><div class=\"ui progress blue\"><div class=\"bar\" style=\"min-width: 0; height: 4px; width: " + percent + "%\"></div></div>" + percent + "%</td>"
table += "</tr>"
})
table += `</table>`
document.getElementById(this.chartId).innerHTML = table
},
formatTime: function (time) {
if (time == null) {
return ""
}
switch (this.item.periodUnit) {
case "month":
return time.substring(0, 4) + "-" + time.substring(4, 6)
case "week":
return time.substring(0, 4) + "-" + time.substring(4, 6)
case "day":
return time.substring(0, 4) + "-" + time.substring(4, 6) + "-" + time.substring(6, 8)
case "hour":
return time.substring(0, 4) + "-" + time.substring(4, 6) + "-" + time.substring(6, 8) + " " + time.substring(8, 10)
case "minute":
return time.substring(0, 4) + "-" + time.substring(4, 6) + "-" + time.substring(6, 8) + " " + time.substring(8, 10) + ":" + time.substring(10, 12)
}
return time
}
},
template: `<div style="float: left" :style="{'width': width}">
<h4>{{chart.name}} <span>{{valueTypeName}}</span></h4>
<div class="ui divider"></div>
<div style="height: 20em; padding-bottom: 1em; " :id="chartId" :class="{'scroll-box': chart.type == 'table'}"></div>
</div>`
})
Vue.component("metric-board", {
template: `<div><slot></slot></div>`
})