{{define "theme-default/network"}} {{template "theme-default/header" .}} {{if ts .CustomCode}} {{.CustomCode|safe}} {{end}} {{template "theme-default/menu" .}} <div class="nb-container"> <div class="ui container"> <div class="service-status"> <table class="ui celled table"> <button class="ui nezha-primary-btn button" v-for="server in servers" style="margin-top: 3px" @click="redirectNetwork(server.ID)"> @#server.Name#@ <i :class="server.Host.CountryCode + ' flag'"></i> </button> </table> </div> </div> <div class="ui container"> <div ref="chartDom" style="margin-top: 15px;height: auto;overflow: hidden"></div> </div> </div> {{template "theme-default/footer" .}} <script> const monitorInfo = JSON.parse('{{.MonitorInfos}}'); const initData = JSON.parse('{{.Servers}}').servers; let MaxTCPPingValue = {{.Conf.MaxTCPPingValue}}; new Vue({ el: '#app', delimiters: ['@#', '#@'], data: { page: 'network', defaultTemplate: {{.Conf.Site.Theme}}, templates: {{.Themes}}, servers: initData, option: {} }, mixins: [mixinsVue], created() { this.option = { tooltip: { trigger: 'axis', position: function (pt) { return [pt[0], '10%']; }, formatter: function(params){ let result = params[0].axisValueLabel + "<br />"; params.forEach(function(item){ result += item.marker + item.seriesName + ": " + item.value[1].toFixed(2) + " ms<br />"; }) return result; }, confine: true, transitionDuration: 0 }, title: { left: 'center', text: "", textStyle: {} }, legend: { top: '5%', data: [], textStyle: { fontSize: 14 } }, grid: { left: this.isMobile ? '8%' : '3.8%', right: this.isMobile ? '8%' : '3.8%', }, backgroundColor: '', dataZoom: [ { type: 'slider', start: 0, end: 100 } ], xAxis: { type: 'time', boundaryGap: false }, yAxis: { type: 'value', boundaryGap: false }, series: [], } }, mounted() { this.renderChart(); this.parseMonitorInfo(monitorInfo); window.addEventListener('resize', this.resizeHandle); }, destroyed () { window.removeEventListener('resize', this.resizeHandle) }, methods: { getFontLogoClass(str) { if (["almalinux", "alpine", "aosc", "apple", "archlinux", "archlabs", "artix", "budgie", "centos", "coreos", "debian", "deepin", "devuan", "docker", "elementary", "fedora", "ferris", "flathub", "freebsd", "gentoo", "gnu-guix", "illumos", "kali-linux", "linuxmint", "mageia", "mandriva", "manjaro", "nixos", "openbsd", "opensuse", "pop-os", "raspberry-pi", "redhat", "rocky-linux", "sabayon", "slackware", "snappy", "solus", "tux", "ubuntu", "void", "zorin"].indexOf(str) > -1) { return str; } if (['openwrt', 'linux', "immortalwrt"].indexOf(str) > -1) { return 'tux'; } if (str == 'amazon') { return 'redhat'; } if (str == 'arch') { return 'archlinux'; } return ''; }, redirectNetwork(id) { this.getMonitorHistory(id) .then(function(monitorInfo) { var vm = app.__vue__; vm.parseMonitorInfo(monitorInfo); }) .catch(function(error){ window.location.href = "/404"; }) }, getMonitorHistory(id) { return $.ajax({ url: "/api/v1/monitor/"+id, method: "GET" }); }, parseMonitorInfo(monitorInfo) { let tSeries = []; let tLegendData = []; var lcolors = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc']; for (let i = 0; i < monitorInfo.result.length; i++) { var lcolor = lcolors[i % lcolors.length]; var rgbaColorMarker = 'rgba(' + parseInt(lcolor.slice(1, 3), 16) + ',' + parseInt(lcolor.slice(3, 5), 16) + ',' + parseInt(lcolor.slice(5, 7), 16) + ',0.5)'; var rgbaColorBar = 'rgba(' + parseInt(lcolor.slice(1, 3), 16) + ',' + parseInt(lcolor.slice(3, 5), 16) + ',' + parseInt(lcolor.slice(5, 7), 16) + ',0.35)'; let loss = 0; let data = []; let datal = []; for (let j = 0; j < monitorInfo.result[i].created_at.length; j++) { avgDelay = Math.round(monitorInfo.result[i].avg_delay[j]); if (avgDelay > 0 && avgDelay < MaxTCPPingValue) { data.push([monitorInfo.result[i].created_at[j], avgDelay]); } else { loss += 1; datal.push({ xAxis: monitorInfo.result[i].created_at[j], label: { show: false }, emphasis: { disabled: true }, lineStyle: { type: "solid", color: rgbaColorBar } }); } } lossRate = ((loss / monitorInfo.result[i].created_at.length) * 100).toFixed(1); if (lossRate > 99) { datal = []; } legendName = monitorInfo.result[i].monitor_name +" "+ lossRate + "%"; tLegendData.push(legendName); tSeries.push({ name: legendName, type: 'line', smooth: true, symbol: 'none', data: data, markLine: { symbol: "none", symbolSize :0, data: datal }, markPoint: { data: [ { type: 'max', symbol: 'pin', name: 'Max', itemStyle: { color: rgbaColorMarker }, symbolSize: 30, label: { fontSize: 8 } }, { type: 'min', symbol: 'pin', name: 'Min', itemStyle: { color: rgbaColorMarker }, symbolSize: 30, label: { fontSize: 8, offset: [0, 7.5] }, symbolRotate: 180 } ] } }); } this.option.title.text = monitorInfo.result[0].server_name; this.option.series = tSeries; this.option.legend.data = tLegendData; const maxLegendsPerRowMobile = localStorage.getItem("maxLegendsPerRowMobile") ? localStorage.getItem("maxLegendsPerRowMobile") : 2; const maxLegendsPerRowPc = localStorage.getItem("maxLegendsPerRowPc") ? localStorage.getItem("maxLegendsPerRowPc") : 6; const autoIncrement = Math.floor((tLegendData.length - 1) / (this.isMobile ? maxLegendsPerRowMobile : maxLegendsPerRowPc)) * (this.isMobile ? 28 : 34); const height = 520 + autoIncrement; const gridTop = 60 + autoIncrement; this.option.grid = { left: this.isMobile ? '8%' : '3.8%', right: this.isMobile ? '8%' : '3.8%', top: gridTop }; this.myChart.resize({ width: 'auto', height: height }); this.myChart.clear(); this.myChart.setOption(this.option); }, isWindowsPlatform(str) { return str.includes('Windows') }, renderChart() { const chartTheme = $('html').attr('nz-theme') == "dark" ? "dark" : ""; this.myChart = echarts.init(this.$refs.chartDom,chartTheme); this.myChart.setOption(this.option); }, resizeHandle () { this.myChart.resize(); }, }, beforeDestroy() { this.myChart.dispose(); this.myChart = null; }, }); </script> {{end}}