270 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			HTML
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			270 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			HTML
		
	
	
	
		
			Vendored
		
	
	
	
{{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}}
 |