网络管理-期末项目(附源码)

环境:网络管理 主机资源监控系统项目搭建 (保姆级教程 建议点赞 收藏)_搭建网络版信息管理系统-CSDN博客

效果图

 

下面3个文件的项目目录(python3.8.8的虚拟环境)

D:\py_siqintu\myproject5\Scripts\mytest.py

D:\py_siqintu\myproject5\Scripts\templates\main.html

D:\py_siqintu\myproject5\Scripts\static\css\style.css

main.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>System Information</title> 
    <script src="{{ url_for('static', filename='js/Bubble.js') }}"></script>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
    <script type="text/javascript" src="https://registry.npmmirror.com/jquery/3.7.1/files/dist/jquery.min.js"></script>
    <script type="text/javascript" src="https://registry.npmmirror.com/echarts/5.5.1/files/dist/echarts.min.js"></script>
</head>

<body>
  <div class="head clearfix">
    <h1 style="text-align: center;">主机资源监控系统</h1>
    </div>
    <div class="mainbox">
    
    <ul class="clearfix nav1">
      <li style="width: 22%">
      <div class="box" style="padding-right: 0;">
        <div class="tit">CPU负载Top5</div>		
        <div id="cpu-monitor" style="width: 340px;height:230px;"></div>
      </div>
      <div class="box">
      <div class="tit">内存占用Top5</div>
      <div id="memory-monitor" style="width: 340px;height:230px;" ></div>
      </div>
      </li>
      <li style="width: 56%">
      <div class="box">
        <div class="boxnav mapc" style="height: 550px; position: relative">
          <div class="mapnav1" style="display: flex;">
            <img style="height: 200px; width: 250px; margin-top: 20px;" src="{{ url_for('static', filename='images/pc.png') }}" alt="PC Image">
            <div style="margin-top: 20px;">
              <div style="font-family: Arial, sans-serif; font-size: 14px; border: 1px solid #ccc; border-radius: 5px; padding: 10px; background-color: #f9f9f9; width: 700px;">
                <div style="display: flex; justify-content: space-between; margin-bottom: 5px; border-bottom: 1px solid #ddd; padding-bottom: 5px;">
                    <p style="font-weight: bold; margin: 0;">系统名字:</p>
                    <p id="SystemNamessr2" style="margin: 0;"></p>
                </div>
                <div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
                    <p style="font-weight: bold; margin: 0;">系统描述:</p>
                    <p id="SystemDescription" style="margin: 0;"></p>
                </div>
                <div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
                    <p style="font-weight: bold; margin: 0;">内存大小:</p>
                    <p id="Memorysize" style="margin: 0;"></p>
                </div>
                <div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
                    <p style="font-weight: bold; margin: 0;">运行时间:</p>
                    <p id="Systemuptime" style="margin: 0;"></p>
                </div>
                <div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
                    <p style="font-weight: bold; margin: 0;">TCP活跃连接数:</p>
                    <p id="tcp_connections" style="margin: 0;"></p>
                </div>
                <div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
                    <p style="font-weight: bold; margin: 0;">当前进程总数:</p>
                    <p id="process_count" style="margin: 0;"></p>
                </div>
                <div style="display: flex; justify-content: space-between; margin-bottom: 5px;">
                    <p style="font-weight: bold; margin: 0;">本机IP:</p>
                    <p id="ip_address" style="margin: 0;"></p>
                </div>
            </div>
           <script>var myurCON = "http://" + window.location.host+"/config/";
            setInterval(()=>{
              fetch(myurCON).then(res=>{
                return res.json()
              }).then((json)=>{
                console.log(json);
                var SystemNamessr2 = document.getElementById('SystemNamessr2');
                SystemNamessr2.innerHTML = json.ssyname;

                var SystemDescription = document.getElementById('SystemDescription');
                SystemDescription.innerHTML =  json.sysDecr;
        
                var Memorysize = document.getElementById('Memorysize');
                let memoryInKiB = json.mem; 
                let memoryReadable =  (memoryInKiB / 1048576).toFixed(2) + " GB"
                Memorysize.innerHTML = memoryReadable;

                var Systemuptime = document.getElementById('Systemuptime');
                let uptimeInHundredths = json.sysUptime; 
                let uptimeInSeconds = uptimeInHundredths * 0.01; 
                let days = Math.floor(uptimeInSeconds / (24 * 3600));
                let hours = Math.floor((uptimeInSeconds % (24 * 3600)) / 3600);
                let minutes = Math.floor((uptimeInSeconds % 3600) / 60);
                let seconds = Math.floor(uptimeInSeconds % 60);
                let uptimeReadable = `${days}天 ${hours}小时 ${minutes}分钟 ${seconds}秒`;
                Systemuptime.innerHTML = uptimeReadable;
              })
            },1000)</script>
          </div>     
        </div>
        <div style="display: flex;">
          <div id="gaugeChart" class="chart" style="width: 350px;height:300px;"></div>	
          <script>
          var gaugeDom = document.getElementById('gaugeChart');
            var gaugeChart = echarts.init(gaugeDom, null, {
              renderer: 'canvas',
              useDirtyRect: false
            });
            var app={}
            var gaugeOption = {
              tooltip: {
                formatter: '{a} <br/>{b} : {c}%'
              },
              series: [
                {
                  name: 'Pressure',
                  type: 'gauge',
                  detail: {
                    formatter: '{value}'
                  },
                  data: [
                    {
                      value: 98,
                      name: 'CPU负载'
                    }
                  ]
                }
              ]
            };
        
            if (gaugeOption && typeof gaugeOption === 'object') {
              gaugeChart.setOption(gaugeOption);
            }
            var myurl3 = "http://" + window.location.host+"/cpu/";
            setInterval(()=>{
              fetch(myurl3).then(res=>{
                return res.json()
              }).then((json)=>{
                gaugeOption.series[0].data[0].value = json.cpu;
                gaugeChart.setOption(gaugeOption);
              })
            },1000)
            </script>
          <div id="disk_usage" style="width: 350px;height:300px;"></div>	
          <script>
            var domdisk_usage = document.getElementById('disk_usage');
var myChartdisk_usage = echarts.init(domdisk_usage, null, {
renderer: 'canvas',
useDirtyRect: false
});
var mydisk_usage = "http://" + window.location.host + "/get_disk/";
var optiondisk_usage = {
tooltip: {
    trigger: 'item',
    formatter: '{a} <br/>{b}: {c}% ({d}%)'
},
legend: {
    top: '5%',
    left: 'center'
},
series: [
    {
        name: 'Disk Usage',
        type: 'pie',
        radius: ['40%', '70%'],
        center: ['50%', '60%'],
        startAngle: 180,
        endAngle: 360,
        data: [
            { name: 'Free', value: 0 },
            { name: 'Used', value: 0 }
        ] 
    }
]
};
myChartdisk_usage.setOption(optiondisk_usage);

setInterval(() => {
fetch(mydisk_usage)
    .then(response => response.json())
    .then(data => {
        console.log(data); 
        const free = data.free;
        const used = data.used;
        const total = data.total;
        if (typeof free === 'number' && typeof used === 'number' && typeof total === 'number') {

            const freePercent = (free / total) * 100;
            const usedPercent = (used / total) * 100;

       
            myChartdisk_usage.setOption({
                series: [
                    {
                        data: [
                            { name: 'Free', value: freePercent },
                            { name: 'Used', value: usedPercent }
                        ]
                    }
                ]
            });
        } else {
            console.error('Invalid data format', data);
        }
    })
    .catch(error => {
        console.error('Error fetching disk usage:', error);
    });
}, 1000);



  </script>
          <div id="memory_usage" class="chart" style="height: 300px; width: 350px;"></div>
          </div>
          <script>

var memory_usageDom = document.getElementById('memory_usage');
    var memory_usageChart = echarts.init(memory_usageDom, null, {
      renderer: 'canvas',
      useDirtyRect: false
    });
    var app={}
    var memory_usageOption = {
      tooltip: {
        formatter: '{a} <br/>{b} : {c}%'
      },
      series: [
        {
          name: 'Pressure',
          type: 'gauge',
          detail: {
            formatter: '{value}'
          },
          data: [
            {
              value: 98,
              name: '内存占有率'
            }
          ]
        }
      ]
    };
    if (memory_usageOption && typeof memory_usageOption === 'object') {
      memory_usageChart.setOption(memory_usageOption);
    }
    var myurl99 = "http://" + window.location.host+"/Memoryusage/";
  setInterval(()=>{
    fetch(myurl99).then(res=>{    
          return res.json()
       }).then((json)=>{
        memory_usageOption.series[0].data[0].value = json.memory_usage;
        memory_usageChart.setOption(memory_usageOption);
         })},1000);
          </script>

      </li>
      <li style="width: 22%">
      
      <div class="box">
        <div class="tit">网络接口状态统计</div>
        <div  id="echart3">
        <div id="interface_status" style="height: 230px; width: 350px;"></div>
        <script>


var interfaceDataUrl = "http://" + window.location.host + "/interface_status/";
let interfaceChart = echarts.init(document.getElementById('interface_status'));
let interfaceChartOption = {
    
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'shadow'
        }
    },
    xAxis: {
        type: 'category',
        data: [], 
        axisLabel: {
            interval: 0,
            rotate: 45
        }
    },
    yAxis: {
        type: 'value',
        name: '',
        minInterval: 1
    },
    series: [
        {
            name: '',
            type: 'bar',
            data: [], 
            itemStyle: {
                color: function (params) {
                    let colorMap = {
                        '运行中': '#4caf50',   
                        '已关闭': '#f44336', 
                        '未启用': '#9e9e9e'  
                    };
                    return colorMap[params.name] || '#000'; 
                }
            }
        }
    ]
};
interfaceChart.setOption(interfaceChartOption);
setInterval(() => {
    fetch(interfaceDataUrl)
        .then(response => response.json())
        .then(data => {
            let statusNames = {
                up: '运行中',
                down: '已关闭',
                notPresent: '未启用'
            };
            let statusCount = {
                '运行中': 0,
                '已关闭': 0,
                '未启用': 0
            };
            data.interfaces.forEach(interface => {
                let status = statusNames[interface.status];
                if (statusCount[status] !== undefined) {
                    statusCount[status]++;
                }
            });
            interfaceChartOption.xAxis.data = Object.keys(statusCount);
            interfaceChartOption.series[0].data = Object.values(statusCount); 

            interfaceChart.setOption(interfaceChartOption);
        })
        .catch(error => {
            console.error("Error fetching interface data:", error);
        });
}, 1000); 

        </script>
        </div>
        </div>
        <div class="box">
        <div class="tit">丢包率和误包率</div>
 
        <div id="error_loss_chart" style="width: 350px;height:200px; margin-top: 20px;"></div>	
        </div>
      
      </li>
      </ul>
      
      <div class="box" style="padding: 20px 0; height: 335px;">
      <ul class="clearfix nav2 ">
      <li style="width:25%;"><div class="tit01">实时流量(MB)</div>
        
        
        <div id="net_s" style="width: 350px;height:240px; margin-top: 20px;"></div>
        <script>

var net_s_Dom = document.getElementById('net_s');
    var myChart_net_s = echarts.init(net_s_Dom, null, {
      renderer: 'canvas',
      useDirtyRect: false
    });
var x_a = new Array();
for(var i =0;i<=200;i++)
{
  x_a.push(i)
}
var app={}
var option_net_s = {
  animation: false,
  title: {
    text: ''
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type:'',
      label: {
        backgroundColor: '#6a7985'
      }
    }
  },
  legend: {
    data: ['入流量', '出流量']
  },
  toolbox: {
    feature: {
      saveAsImage: {}
    }
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },  
  xAxis: [
    {
      type: 'category',
      boundaryGap: false,
      data: x_a
    }
  ],
  yAxis: [
    {
      type: 'value'
    }
  ],

series: [
    {
      name: '入流量',
      type: 'line',
      
      emphasis: {
        focus: 'series'
      },
      data: []
    },
    {
      name: '出流量',
      type: 'line',
      
      emphasis: {
        focus: 'series'
      },
      data: [],
      valueAnimation: false
    }
  ]
};
myChart_net_s.setOption(option_net_s);

var mydata_net_in= new Array();
  var mydata_net_out = new Array();
  var net_last_in = 0;
  var net_last_out = 0;
  var myurl4 = "http://" + window.location.host+"/net_m/";
  setInterval(()=>{
    fetch(myurl4).then(res=>{    
          return res.json()
       }).then((json)=>{
          i = (json.in_s - net_last_in);
          o = (json.out_s - net_last_out);
          console.log(i,o);
          
          if(i < 0) 
             i = i + 2**32;
          if(o < 0) 
            o = o + 2**32
          i = i / (1048576)
          o = o / (1048576)
          mydata_net_in.push(i);
          mydata_net_out.push(o);
          net_last_in = json.in_s
          net_last_out = json.out_s
          if (mydata_net_in.length > 200)
          {
             mydata_net_in.shift(json.in_s);
             mydata_net_out.shift(json.out_s);
          }
          option_net_s.series[0].data=mydata_net_in;
          option_net_s.series[1].data=mydata_net_out;
          myChart_net_s.setOption(option_net_s);
         })},1000);

        </script>
        </li>
      <li style="width:25%"><div class="tit01">历史网络流量(5min)</div>
        <div id="net_traffic_chart" style="width: 350px;height:350px;"></div>
       <script>
        var netTrafficContainer = document.getElementById('net_traffic_chart');
var netTrafficChart = echarts.init(netTrafficContainer, null, {
  renderer: 'canvas',
  useDirtyRect: false
});
var netTrafficOption = {
  tooltip: { trigger: 'axis' },
  legend: { data: ['入流量', '出流量'] },
  xAxis: { type: 'category', boundaryGap: true, data: [] },
  yAxis: { type: 'value', name: 'Traffic (MB)' },
  series: [
    { name: 'Incoming Traffic', type: 'line', data: [] },
    { name: 'Outgoing Traffic', type: 'line', data: [] }
  ],
  animationDuration: 0,
  animationDurationUpdate: 3000,
  animationEasing: 'linear',
  animationEasingUpdate: 'linear'
};

netTrafficChart.setOption(netTrafficOption);
var trafficDataUrl = "http://" + window.location.host + "/net_h/";
setInterval(() => {
  fetch(trafficDataUrl)
    .then(response => response.json())
    .then(data => {
      var newTimeStamps = data.timestamps || [];
      var newIncomingTraffic = data.net_in || [];
      var newOutgoingTraffic = data.net_out || [];
      netTrafficOption.xAxis.data = newTimeStamps.slice(-30);
      netTrafficOption.series[0].data = newIncomingTraffic.slice(-30);
      netTrafficOption.series[1].data = newOutgoingTraffic.slice(-30);
      netTrafficChart.setOption(netTrafficOption);
    })
    .catch(error => console.error('Error fetching traffic data:', error));
}, 3000);
window.addEventListener('resize', netTrafficChart.resize);
       </script>
        <div class="ftechart" id="echart4"></div>
        </li>
      <li style="width:25%">
        <div class="tit01">网络波动</div>
        						<div id="network_volatility" style="width: 300px; height: 300px;"></div>

                    <script>

var networkVolatilityDom = document.getElementById('network_volatility');
var networkVolatilityChart = echarts.init(networkVolatilityDom, null, {
    renderer: 'canvas',
    useDirtyRect: false
});

var networkVolatilityOption = {
    tooltip: {
        trigger: 'axis'
    },
    xAxis: {
        type: 'category',
        data: [] 
    },
    yAxis: {
        type: 'value',
        axisLabel: {
            formatter: '{value} bytes'
        }
    },
    series: [
        {
            name: '波动字节',
            type: 'line',
            smooth: true,
            data: []  
        }
    ]
};

if (networkVolatilityOption && typeof networkVolatilityOption === 'object') {
    networkVolatilityChart.setOption(networkVolatilityOption);
}
var myurlNetworkVolatility = "http://" + window.location.host + "/volatility/";

setInterval(() => {
    fetch(myurlNetworkVolatility)  
        .then(res => res.json())
        .then((json) => {
            const currentTimestamp = new Date().toISOString(); 
            if (json.volatility !== undefined) {
                networkVolatilityOption.xAxis.data.push(currentTimestamp);  
                networkVolatilityOption.series[0].data.push(json.volatility);  
            }
            if (networkVolatilityOption.xAxis.data.length > 10) {
                networkVolatilityOption.xAxis.data.shift();
                networkVolatilityOption.series[0].data.shift();
            }

            networkVolatilityChart.setOption(networkVolatilityOption);
        })
        .catch((error) => console.error("获取网络波动字节数据失败", error));
}, 1000);

                    </script>
        </li>
      <li style="width:25%"><div class="tit01">TCP&UDP</div>
        <div id="tcp_udp_chart" style="width: 350px;height:240px; margin-top: 20px;"></div>

        <script>

var tcp_udp_Dom = document.getElementById('tcp_udp_chart');
var tcp_udp_chart = echarts.init(tcp_udp_Dom, null, {
    renderer: 'canvas',
    useDirtyRect: false
});
var tcp_udp_option = {
    title: {
        text: ''
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data: ['TCP In', 'TCP Out', 'UDP In', 'UDP Out']
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
    },
    xAxis: {
        type: 'category',
        boundaryGap: false,
        data: []  
    },
    yAxis: [
        {
            type: 'value',
            name: 'TCP Packets',
            min: 0,
            max: 800000, 
            position: 'left',
            axisLine: {
                lineStyle: {
                    color: '#5470C6' 
                }
            }
        },
        {
            type: 'value',
            name: 'UDP Packets',
            min: 0,
            max: 800000, 
            position: 'right',
            axisLine: {
                lineStyle: {
                    color: '#91CC75' 
                }
            }
        }
    ],
    series: [
        {
            name: 'TCP In',
            type: 'line',
            yAxisIndex: 0, 
            data: []  
        },
        {
            name: 'TCP Out',
            type: 'line',
            yAxisIndex: 0, 
            data: []  
        },
        {
            name: 'UDP In',
            type: 'line',
            yAxisIndex: 1, 
            data: []  
        },
        {
            name: 'UDP Out',
            type: 'line',
            yAxisIndex: 1,
            data: [] 
        }
    ]
};

tcp_udp_chart.setOption(tcp_udp_option);
var myurl2 = "http://" + window.location.host + "/tcp_udp_status/";

setInterval(() => {
    fetch(myurl2)
        .then(res => res.json())
        .then(json => {
            var now = new Date().toLocaleTimeString(); 
            tcp_udp_option.xAxis.data.push(now);
            if (tcp_udp_option.xAxis.data.length > 50) {
                tcp_udp_option.xAxis.data.shift();
            }
            tcp_udp_option.series[0].data.push(json.tcp_in); 
            tcp_udp_option.series[1].data.push(json.tcp_out);
            tcp_udp_option.series[2].data.push(json.udp_in);         
            tcp_udp_option.series[3].data.push(json.udp_out);         
            if (tcp_udp_option.series[0].data.length > 50) {
                tcp_udp_option.series[0].data.shift();
                tcp_udp_option.series[1].data.shift();
                tcp_udp_option.series[2].data.shift();
                tcp_udp_option.series[3].data.shift();
            }
            tcp_udp_chart.setOption(tcp_udp_option);
        })
        .catch(error => console.error('Error fetching TCP/UDP data:', error));
}, 1000);
        </script>
        <div class="" id="">
        <div style="float: left; width: 50%; height: 200px" id="fb03"></div>
        <div style="float: left; width: 50%; height: 200px"  id="fb04"></div>
          
        </div>
        
        </li>
      </ul>
      </div>
     
    </div>




       
   

    <script>


    var myur50 = "http://" + window.location.host+"/ip_addresses/";
    setInterval(()=>{
      fetch(myur50).then(res=>{
        return res.json()
      }).then((json)=>{
        console.log(json)
        var SystemDescription = document.getElementById('ip_address');
        SystemDescription.innerHTML =  json.ip_addresses.ip_addresses;
      })
    },1000)
   
    




    


    var errorLossChartDom = document.getElementById('error_loss_chart');
var errorLossChart = echarts.init(errorLossChartDom, null, {
    renderer: 'canvas',
    useDirtyRect: false
});
var errorLossChartOptions = {
    title: {
        text: ''
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data: [
            'In Packet Loss Rate', 
            'Out Packet Loss Rate', 
            'In Error Rate', 
            'Out Error Rate'
        ]
    },
    grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
    },
    xAxis: {
        type: 'category',
        boundaryGap: false,
        data: []  
    },
    yAxis: {
        type: 'value',
        name: 'Rate (%)',
        min: 0,
        max: 100,
        position: 'left',
        axisLine: {
            lineStyle: {
                color: '#5470C6' 
            }
        }
    },
    series: [
        {
            name: 'In Packet Loss Rate',
            type: 'line',
            data: [], 
            lineStyle: {
                color: '#EE6666'
            }
        },
        {
            name: 'Out Packet Loss Rate',
            type: 'line',
            data: [], 
            lineStyle: {
                color: '#5470C6'
            }
        },
        {
            name: 'In Error Rate',
            type: 'line',
            data: [],  
            lineStyle: {
                color: '#91CC75'
            }
        },
        {
            name: 'Out Error Rate',
            type: 'line',
            data: [],  
            lineStyle: {
                color: '#FAC858'
            }
        }
    ]
};

errorLossChart.setOption(errorLossChartOptions);
var errorLossDataUrl = "http://" + window.location.host + "/packet_loss_rate/";
setInterval(() => {
    fetch(errorLossDataUrl)
        .then(res => res.json())
        .then(json => {
            var now = new Date().toLocaleTimeString(); 
            errorLossChartOptions.xAxis.data.push(now);
            if (errorLossChartOptions.xAxis.data.length > 50) {
                errorLossChartOptions.xAxis.data.shift();
            }
            errorLossChartOptions.series[0].data.push(json.in_packet_loss_rate);
            errorLossChartOptions.series[1].data.push(json.out_packet_loss_rate);
            errorLossChartOptions.series[2].data.push(json.in_error_rate);
            errorLossChartOptions.series[3].data.push(json.out_error_rate);
            if (errorLossChartOptions.series[0].data.length > 50) {
                errorLossChartOptions.series[0].data.shift();
                errorLossChartOptions.series[1].data.shift();
                errorLossChartOptions.series[2].data.shift();
                errorLossChartOptions.series[3].data.shift();
            }
            errorLossChart.setOption(errorLossChartOptions);
        })
        .catch(error => console.error('Error fetching Packet Loss & Error Rate data:', error));
}, 1000);

var cpuMonitorContainer = document.getElementById('cpu-monitor');
    var cpuChart = echarts.init(cpuMonitorContainer, null, {
      renderer: 'canvas',
      useDirtyRect: false
    });


    var cpuChartOption = {
      grid: {
    left: '20%', 
    right: '10%',
    top: '10%',
    bottom: '10%'
  },
      xAxis: {
        type: 'value',
        max: 'dataMax',
        name: 'CPU %',
        nameLocation: 'middle',
        nameGap: 30
      },
      yAxis: {
        type: 'category',
        data: [], 
        inverse: true,
        name: '',
        nameLocation: 'middle',
        nameGap: 50,
        nameTextStyle: {
    fontSize: 16, 
    fontWeight: 'bold',
    color: '#333' 
  }
      },
      series: [
        {
          name: 'CPU Usage',
          type: 'bar',
          data: [], 
          label: {
            show: true,
            position: 'right',
            formatter: '{c}%', 
            valueAnimation: true
          }
        }
      ],
      tooltip: {
        trigger: 'item',
        formatter: '{b}: {c}%' 
      },
      legend: {
        show: true,
        data: ['CPU Usage']
      },
      animationDuration: 0,
      animationDurationUpdate: 3000,
      animationEasing: 'linear',
      animationEasingUpdate: 'linear'
    };


    const processNames = []; 
    const processCpuUsage = []; 

    
    cpuChart.setOption(cpuChartOption);

    
    window.addEventListener('resize', cpuChart.resize);
    errorLossChart.setOption(errorLossChartOptions);
    var cpuDataUrl = "http://" + window.location.host + "/top_processes/";
setInterval(() => {
    fetch(cpuDataUrl)
        .then(res => res.json())
        .then(data => {
            var processNames = [];
            var processCpuUsage = [];
            
          
            data.top_cpu_processes.forEach(process => {
                processNames.push(process.name || `PID ${process.pid}`);
                processCpuUsage.push(process.cpu_percent);
            });

            
            cpuChartOption.yAxis.data = processNames;
            cpuChartOption.series[0].data = processCpuUsage;
            
         
            cpuChart.setOption(cpuChartOption);
        })
        .catch(error => console.error('Error fetching CPU data:', error));
}, 1000);
var memoryMonitorContainer = document.getElementById('memory-monitor');
var memoryChart = echarts.init(memoryMonitorContainer, null, {
  renderer: 'canvas',
  useDirtyRect: false
});


var memoryChartOption = {
  grid: {
    left: '20%', 
    right: '10%',
    top: '10%',
    bottom: '10%'
  },
  xAxis: {
    type: 'value',
    max: 'dataMax',
    name: 'Memory %',
    nameLocation: 'middle',
    nameGap: 30
  },
  yAxis: {
    type: 'category',
    data: [], 
    inverse: true,
    name: '',
    nameLocation: 'middle',
    nameGap: 50,
    nameTextStyle: {
    fontSize: 16, 
    fontWeight: 'bold', 
    color: '#333' 
  }
  },
  series: [
    {
      name: 'Memory Usage',
      type: 'bar',
      data: [], 
      label: {
        show: true,
        position: 'right',
        formatter: '{c}%', 
        valueAnimation: true
      }
    }
  ],
  tooltip: {
    trigger: 'item',
    formatter: '{b}: {c}%' 
  },
  legend: {
    show: true,
    data: ['Memory Usage']
  },
  animationDuration: 0,
  animationDurationUpdate: 3000,
  animationEasing: 'linear',
  animationEasingUpdate: 'linear'
};


const processNames2 = []; 
const processMemoryUsage = []; 


memoryChart.setOption(memoryChartOption);


window.addEventListener('resize', memoryChart.resize);


var memoryDataUrl = "http://" + window.location.host + "/top_processes/";

setInterval(() => {
  fetch(memoryDataUrl)
    .then(res => res.json())
    .then(data => {
      var processNames2 = [];
      var processMemoryUsage = [];
      
     
      data.top_memory_processes.forEach(process => {
        processNames2.push(process.name || `PID ${process.pid}`);
        processMemoryUsage.push((process.memory_percent).toFixed(2)); 
      });

      
      memoryChartOption.yAxis.data = processNames2;
      memoryChartOption.series[0].data = processMemoryUsage;
      
     
      memoryChart.setOption(memoryChartOption);
    })
    .catch(error => console.error('Error fetching memory data:', error));
}, 1000);


var myur15 = "http://" + window.location.host+"/tcp_connections/";
    setInterval(()=>{
      fetch(myur15).then(res=>{
        return res.json()
      }).then((json)=>{
        var tcp_connections2 = document.getElementById('tcp_connections');
        tcp_connections2.innerHTML =  json.tcp_active_connections;
      })
    },1000)
    var myur16 = "http://" + window.location.host+"/process_count/";
    setInterval(()=>{
      fetch(myur16).then(res=>{
        return res.json()
      }).then((json)=>{
        var process_count = document.getElementById('process_count');
        process_count.innerHTML =  json.process_count;
      })
    },1000)






    </script>
</body>
</html>

mytest.py

import random
from pysnmp.hlapi import *
from flask import Flask,render_template
app = Flask(__name__)

myhost='localhost'
myport=161
mycommunity ='public'
myifindex ='.10'

myOIDs={
      'os_version': '1.3.6.1.2.1.1.1.0',
    'hostname': '1.3.6.1.2.1.1.5.0',
    'cpu_count': '1.3.6.1.4.1.2021.11.50.0',
    'disk_total': '1.3.6.1.4.1.2021.9.1.6.1',
    'disk_used': '1.3.6.1.4.1.2021.9.1.8.1',
    'disk_free': '1.3.6.1.4.1.2021.9.1.7.1',
    'process_count': '1.3.6.1.2.1.25.1.6.0',
    'tcp_active_connections': '1.3.6.1.2.1.6.9.0',
    'interface_status': '1.3.6.1.2.1.2.2.1.8',
  'sysDecr' : ".1.3.6.1.2.1.1.1.0",
  'sysUptime' : ".1.3.6.1.2.1.1.3.0",
    'sysName':".1.3.6.1.2.1.1.5.0",
    'wlan_if_in':'1.3.6.1.2.1.2.2.1.10',
    'wlan_if_out':'1.3.6.1.2.1.2.2.1.16',
  'if_in'     : ".1.3.6.1.2.1.2.2.1.10",
  'if_out'    : ".1.3.6.1.2.1.2.2.1.16",
  'if_inpkt'  : ".1.3.6.1.2.1.2.2.1.11",
  'if_outpkt' : ".1.3.6.1.2.1.2.2.1.17",
  'if_inbpkt' : ".1.3.6.1.2.1.2.2.1.12",
  'if_outbpkt': ".1.3.6.1.2.1.2.2.1.18",
  'if_speed'  : ".1.3.6.1.2.1.2.2.1.5",
  'mem_total' : ".1.3.6.1.2.1.25.2.2.0",
  'cpu_loads' : ". 1.3.6.1.2.1.25.3.3.1.2",
    'hrStorageSize':'1.3.6.1.2.1.25.2.3.1.5.4',
'hrStorageUsed':"1.3.6.1.2.1.25.2.3.1.6.4" ,
'if_in_discards': "1.3.6.1.2.1.2.2.1.13",
'if_out_discards': "1.3.6.1.2.1.2.2.1.19"  ,
'if_in_errors': "1.3.6.1.2.1.2.2.1.14",
'if_out_errors': "1.3.6.1.2.1.2.2.1.20",
'ipAddrTable_oid' :'1.3.6.1.2.1.4.20.1.1',
  }

def getTableRows(oids):
    iterator = nextCmd(
        SnmpEngine(),
        CommunityData(mycommunity, mpModel=0),
        UdpTransportTarget((myhost, myport)),
        ContextData(),
        *oids,
    lexicographicMode = False)
    ret = []
    for errorIndication, errorStatus, errorIndex, varBinds in iterator:
        count = ()
        if errorIndication:
            print(errorIndication)
            break
        elif errorStatus:
            print('%s at %s' % (errorStatus.prettyPrint(),
                                errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
            break
        else:
            for varBind in varBinds:
                count = count + (varBind[1]._value,)
            ret.append(count)
    return ret
def getObjs(oids):
  iterator = getCmd(
      SnmpEngine(),
      CommunityData(mycommunity, mpModel=0),
      UdpTransportTarget((myhost, myport)),
      ContextData(),
      *oids)
  ret = []
  errorIndication, errorStatus, errorIndex, varBinds = next(iterator)
  if errorIndication:
        print(errorIndication)
        return 0
  elif errorStatus:
        print('%s at %s' % (errorStatus.prettyPrint(),
                            errorIndex and varBinds[int(errorIndex)-1][0] or '?'))
        return 0
  else:
        for varBind in varBinds:
            ret.append(varBind[1]._value)
  return ret
def get_memory_usage():
    total_memory = getObjs([ObjectType(ObjectIdentity(myOIDs['hrStorageSize']))])
    used_memory = getObjs([ObjectType(ObjectIdentity(myOIDs['hrStorageUsed']))])
    if total_memory and used_memory and total_memory[0] > 0:
        memory_usage = (used_memory[0] / total_memory[0]) * 100
        return round(memory_usage, 2)
    else:
        return None
@app.route('/')
def index():
    return render_template('main.html')

@app.route('/cpu/')
def cpu_used():
    cpuoid=ObjectType(ObjectIdentity(myOIDs['cpu_loads']))
    ret = getTableRows((cpuoid,))
    cpuload=0
    for i in ret:
        cpuload += i[0]
    print(cpuload)
    return {'cpu':cpuload}
@app.route('/net_m/')
def net_used():
    getoids=(ObjectType(ObjectIdentity(myOIDs['if_in']+'.41')),
             ObjectType(ObjectIdentity(myOIDs['if_out']+'.41')))
    in_out = getObjs(getoids)
    return {'in_s':in_out[0],'out_s':in_out[1]}
@app.route('/config/')
def m_config():
    getoids=(ObjectType(ObjectIdentity(myOIDs['sysDecr'])),
             ObjectType(ObjectIdentity(myOIDs['sysUptime'])),
             ObjectType(ObjectIdentity(myOIDs['mem_total'])),
             ObjectType(ObjectIdentity(myOIDs['sysName'])),
    )

    configs = getObjs(getoids)
    return {'sysDecr':configs[0].decode(),
            'sysUptime':configs[1],
            'mem':configs[2],
            'ssyname': configs[3].decode(),
           }
@app.route('/Memoryusage/')
def Memoryusage():
    memory_usage = get_memory_usage()
    return {
            'memory_usage': memory_usage
           }
@app.route('/tcp_udp_status/')
def tcp_udp_status():
    tcp_in_oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.6.10.0'))
    tcp_out_oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.6.11.0'))
    udp_in_oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.7.1.0'))
    udp_out_oid = ObjectType(ObjectIdentity('1.3.6.1.2.1.7.4.0'))
    tcp_udp_data = getObjs([tcp_in_oid,tcp_out_oid, udp_in_oid, udp_out_oid])
    if tcp_udp_data:
        return {
            'tcp_in': tcp_udp_data[0],
            'tcp_out': tcp_udp_data[1],
            'udp_in': tcp_udp_data[2],
            'udp_out': tcp_udp_data[3]
        }
    else:
        return {'error': 'Failed to retrieve TCP/UDP statistics'}, 500
def get_packet_loss_rate():
    getoids = (
        ObjectType(ObjectIdentity(myOIDs['if_in_discards'] + '.41')),
        ObjectType(ObjectIdentity(myOIDs['if_out_discards'] + '.41')),
        ObjectType(ObjectIdentity(myOIDs['if_inpkt'] + '.41')),
        ObjectType(ObjectIdentity(myOIDs['if_outpkt'] + '.41'))
    )
    results = getObjs(getoids)
    in_discards = results[0]
    out_discards = results[1]
    in_pkts = results[2]
    out_pkts = results[3]
    in_packet_loss_rate = (in_discards / in_pkts) * 100 if in_pkts > 0 else 0
    out_packet_loss_rate = (out_discards / out_pkts) * 100 if out_pkts > 0 else 0
    return round(in_packet_loss_rate, 2), round(out_packet_loss_rate, 2)

def get_error_rate():
    getoids = (
        ObjectType(ObjectIdentity(myOIDs['if_in_errors'] + '.41')),
        ObjectType(ObjectIdentity(myOIDs['if_out_errors'] + '.41')),
        ObjectType(ObjectIdentity(myOIDs['if_inpkt'] + '.41')),
        ObjectType(ObjectIdentity(myOIDs['if_outpkt'] + '.41'))
    )
    results = getObjs(getoids)
    in_errors = results[0]
    out_errors = results[1]
    in_pkts = results[2]
    out_pkts = results[3]
    in_error_rate = (in_errors / in_pkts) * 100 if in_pkts > 0 else 0
    out_error_rate = (out_errors / out_pkts) * 100 if out_pkts > 0 else 0
    return round(in_error_rate, 2), round(out_error_rate, 2)

@app.route('/packet_loss_rate/')
def packet_loss_rate():
    in_loss_rate, out_loss_rate = get_packet_loss_rate()
    in_error_rate, out_error_rate = get_error_rate()
    if None not in (in_loss_rate, out_loss_rate, in_error_rate, out_error_rate):
        return {
            'in_packet_loss_rate': in_loss_rate,
            'out_packet_loss_rate': out_loss_rate,
            'in_error_rate': in_error_rate,
            'out_error_rate': out_error_rate
        }
    else:
        return {'error': 'Failed to retrieve packet loss or error rate'}, 500

import ipaddress
import struct

def parse_ip_from_binary(binary_data):
    try:
        ip_address = ipaddress.ip_address(binary_data)
        return str(ip_address)
    except ValueError:
        print(f"Invalid binary data: {binary_data}")
        return None

def get_ip_addresses():
    ip_addresses = []
    ip_entries = getTableRows([ObjectType(ObjectIdentity(myOIDs['ipAddrTable_oid']))])
    if ip_entries:
        for entry in ip_entries:
            ip_address = entry[0]
            if isinstance(ip_address, bytes):
                ip_address = parse_ip_from_binary(ip_address)
                if ip_address:
                    ip_addresses.append(ip_address)
            else:
                print(f"Unexpected format: {ip_address}")

        if ip_addresses:
            return {"ip_addresses": ip_addresses}
        else:
            return {"error": "No valid IP addresses found"}
    else:
        return {"error": "Failed to retrieve IP addresses"}


import psutil  

@app.route('/top_processes/')
def top_processes():
    processes = []
    for proc in psutil.process_iter(['pid', 'name', 'cpu_percent', 'memory_percent']):
        try:
            proc_info = proc.info
            processes.append(proc_info)
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass
    top_cpu_processes = sorted(processes, key=lambda x: x['cpu_percent'], reverse=True)[1:6]
    top_memory_processes = sorted(processes, key=lambda x: x['memory_percent'], reverse=True)[:5]

    return {
        'top_cpu_processes': top_cpu_processes,
        'top_memory_processes': top_memory_processes
    }
@app.route('/interface_status/')
def interface_status():
    interfaces = getTableRows([ObjectType(ObjectIdentity(myOIDs['interface_status']))])
    status_map = {1: 'up', 2: 'down', 3: 'testing', 4: 'unknown', 5: 'dormant', 6: 'notPresent', 7: 'lowerLayerDown'}
    interface_status = [{'interface_index': idx+1, 'status': status_map.get(status, 'unknown')} for idx, (status,) in enumerate(interfaces)]
    return {'interfaces': interface_status}

@app.route('/tcp_connections/')
def tcp_connections():
    tcp_active_connections = getObjs([ObjectType(ObjectIdentity(myOIDs['tcp_active_connections']))])
    if tcp_active_connections:
        return {'tcp_active_connections': tcp_active_connections[0]}
    else:
        return {'error': 'Failed to retrieve TCP connections'}, 500
@app.route('/process_count/')
def process_count():
    process_count = getObjs([ObjectType(ObjectIdentity(myOIDs['process_count']))])
    if process_count:
        return {'process_count': process_count[0]}
    else:
        return {'error': 'Failed to retrieve process count'}, 500
#     ip
@app.route('/ip_addresses/')
def ip_addresses():
    ip_list = get_ip_addresses()
    if ip_list:
        return {'ip_addresses': ip_list}
    else:
        return {'error': 'Failed to retrieve IP addresses'}, 500


from collections import deque
import threading
import time
from datetime import datetime, timedelta

net_history_data = deque(maxlen=30)
def update_net_history():
    while True:
        getoids = (
            ObjectType(ObjectIdentity(myOIDs['if_in'] + '.41')),
            ObjectType(ObjectIdentity(myOIDs['if_out'] + '.41'))
        )
        in_out = getObjs(getoids)
        if in_out:
            timestamp = datetime.now()
            net_history_data.append({
                "timestamp": timestamp,
                "net_in": in_out[0],
                "net_out": in_out[1]
            })
        else:
            print("Failed to retrieve network data")
        time.sleep(10)
threading.Thread(target=update_net_history, daemon=True).start()
@app.route('/net_h/')
def net_history():
    net_in = [round(entry["net_in"] / (1024 * 1024), 2) for entry in net_history_data]
    net_out = [round(entry["net_out"] / (1024 * 1024), 2) for entry in net_history_data]
    timestamps = [entry["timestamp"].strftime('%Y-%m-%d %H:%M:%S') for entry in net_history_data]
    return {"net_in": net_in, "net_out": net_out, "timestamps": timestamps}
@app.route('/get_disk/')
def get_disk_usage():
    getoids = (
        ObjectType(ObjectIdentity('1.3.6.1.2.1.25.2.3.1.5.2')),
        ObjectType(ObjectIdentity('1.3.6.1.2.1.25.2.3.1.5.1')),
        ObjectType(ObjectIdentity('1.3.6.1.2.1.25.2.3.1.6.1')),
        ObjectType(ObjectIdentity('1.3.6.1.2.1.25.2.3.1.6.2'))
    )
    results = getObjs(getoids)
    total_part1 = results[0]
    total_part2 = results[1]
    used_part1 = results[2]
    used_part2 = results[3]
    if None not in [total_part1, total_part2, used_part1, used_part2]:
        total = (total_part1 + total_part2) * 4096
        used = (used_part1 + used_part2) * 4096
        free = total - used
        return {
            'total': round(total / (1024 ** 3), 2),
            'used': round(used / (1024 ** 3), 2),
            'free': round(free / (1024 ** 3), 2)
        }
    else:
        return None

def get_network_traffic():
    in_bytes = getObjs([ObjectType(ObjectIdentity(myOIDs['if_in']+'.41'))])
    return in_bytes[0] if in_bytes else 0
last_in_bytes = 0
@app.route('/volatility/')
def network_traffic_volatility():
    global last_in_bytes
    in_bytes= get_network_traffic()
    volatility = in_bytes - last_in_bytes
    last_in_bytes = in_bytes
    return {'volatility': volatility}
if __name__ == '__main__':
    app.run()

style.css

@charset "utf-8";
/* CSS Document */
*{
	-webkit-box-sizing: border-box;
	-moz-box-sizing: border-box;
	box-sizing: border-box}
*,body{padding:0px;	margin:0px;font-family: "微软雅黑";}
body{color:#2c3e50;font-size: 16px; background: #fff;}
html,body{height: 100%;}
li{ list-style-type:none;}
i{ margin:0px; padding:0px; text-indent:0px;}
img{ border:none; max-width: 100%;}
a{ text-decoration:none; color:#34495e;}
a.active,a:focus{ outline:none!important; text-decoration:none;}
ol,ul,p,h1,h2,h3,h4,h5,h6{ padding:0; margin:0}
a:hover{ color:#3498db; text-decoration: none!important}
.clearfix:after, .clearfix:before {display: table;content: " "}
.clearfix:after {clear: both}
.pulll_left{float:left;}
.pulll_right{float:right;}
i{font-style: normal;}
.text-w{color: #f1c40f}
.text-d{color: #e67e22}
.text-s{color: #2ecc71}
.text-b{color: #3498db}

.head{position: relative; height: 90px; margin: 0 15px; padding-right: 60px;}
.head h1{  font-size: 30px; letter-spacing: -2px; text-align: center; line-height: 90px; padding-right: 55px; color: #3498db;}
.head .menu ul{ font-size: 0;}

.head .menu li{ display: inline-block; position: relative;margin: 25px 15px;;}
.head .menu li a{ display: block; font-size: 18px; color: #34495e; line-height: 40px; padding: 0 15px; }
.head .time{position: absolute; right: 0; line-height: 90px;}

.menu li:before,
.menu li:after{ position:absolute; width:10px; height:5px;opacity: .4; content: "";  border-top: 2px solid #3498db; top: -1px;border-radius: 2px;}
.menu li:before,.menu li a:before{border-left: 2px solid #3498db;left: -1px;}
.menu li:after,.menu li a:after{border-right: 2px solid #3498db; right: -1px;}
.menu li a{ position:relative;}
.menu li a:before,
.menu li a:after{ position:absolute; width:10px; height:5px; opacity: .4;  content: "";border-bottom: 2px solid #3498db; bottom:-1px;border-radius: 2px;}

.head .menu li a:hover{ color: #3498db;}
.menu li a:hover:before,
.menu li a:hover:after,
.menu li:hover:before,
.menu li:hover:after{border-color: #3498db; opacity: 1;}

.mainbox{padding: 0px 10px;}
.nav1{margin-left: -6px; margin-right:-6px;}
.nav1>li{padding:0 6px; float: left;}

.box{ border:1px solid rgba(52,152,219,.5); box-shadow:inset 0 0 10px rgba(52,152,219,.4); margin-bottom: 12px; position: relative;}
.tit{ padding: 10px 10px 10px 25px;border-bottom:1px solid rgba(52,152,219,.7);font-size: 16px; font-weight: 500; position: relative;}
.tit:before,.tit01:before{position: absolute; content: ""; width: 6px; height: 6px; background: rgba(52,152,219,.9);box-shadow: 0 0 5px rgba(52,152,219,.9); border-radius: 10px; left: 10px; top: 18px;}

.tit:after,.box:before{ width: 100%; height: 1px; content: ""; position: absolute; left: 0; bottom:-1px; background:linear-gradient(to right,#3498db,#2980b9,#3498db); box-shadow: 0 0 5px rgba(52,152,219,1); opacity: .6}
.box:before{top: -1px;}

.boxnav{padding: 10px;}
.nav2>li:first-child{border:none;}
.nav2>li{float: left;border-left:1px solid rgba(52,152,219,.2); height:240px; padding: 0 10px 10px 10px;}
.tit01{font-size: 16px; font-weight: 500; position: relative; padding-left: 15px;}
.tit01:before{ left: 3px; top: 8px;}

.ftechart{height: 200px;}

.table1 th{ border-bottom: 1px solid #3498db; font-size: 14px; text-align: center; padding: 6px 0; color: rgba(44,62,80,.9)}
.table1 td{ border-bottom: 1px dotted #3498db;font-size: 12px; padding:6px 0;text-align: center; color: rgba(44,62,80,.7)}
.table1 tr:last-child td{border: none;}
.mapc{background: url(../images/bg3.png) no-repeat center center; background-size: 100% 100%}
.map{position: relative; height: 100%; padding-left: 10%;}

.mapnav{position: absolute;z-index: 10;}
.mapnav div{ background: url(../images/bg1.png) no-repeat; background-size:100% auto;  width: 110px;text-align: center; padding: 20px 0; line-height: 120%;}
.mapnav div span{font-size: 14px; opacity: .6}
.mapnav div p{font-size: 20px; font-weight: bold; padding-top: 5px;}
.mapnav li{float: left; margin-right: 6px;}

.leidanav{margin-top: -5px;}
.leidanav li{float: left; width: 20%; text-align: center; border-left: 1px solid rgba(52,152,219,.1)}
.leidanav2 li{ width: 33.3333%}
.leidanav3 li{ width: 25%}
.leidanav li:first-child{border-left: none;}
.leidanav span{font-size: 12px; opacity: .6}

.leidanav p{font-size: 18px; color: #3498db }
.mapnav2{ position: absolute; left: 10px; bottom:0px; width: 40%; z-index: 10;}
.ybp{width: 100%}
.ybp li{float: left; width: 50%; height: 120px; }
.duibi li{float: left; width: 25%; height: 200px; padding: 0; border: none;}

.btn{ position: absolute;  border-radius:2px; padding:4px 20px; opacity: .8;}
.btn1{border: 1px solid rgba(52,152,219,.5); background: #27ae60; left:35%; top: 30%;}
.btn2{ border: 1px solid rgba(52,152,219,.5); background: #2980b9;right:32%; top: 60%;}
.btn:hover{color: #fff; opacity:1;}
.btn1:before,.btn2:before{position: absolute; content: ''; width: 50px; height: 1px; background: #2c3e50;}
.btn1:before{ transform: rotate(30deg); right: -65%; top: 100%}
.btn2:before{ transform: rotate(30deg); left: -65%; top: -10%}
.tit02{font-size: 14px; padding: 10px 0;}
.water-container {
  position: relative;
  text-align: center;
}

.circle {
  position: relative;
  width: 150px;
  height: 150px;
  border-radius: 50%;
  overflow: hidden;
  background: #f0f0f0;
  box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.1);
}

.water {
  position: absolute;
  bottom: 0;
  width: 100%;
  height: 100%;
  background: #4da6ff;
  animation: wave 2s infinite linear;
  transform: translateY(70%);
}

.text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 20px;
  font-weight: bold;
  color: #333;
}

.label {
  margin-top: 10px;
  font-size: 16px;
  color: #888;
}

/* 波浪动画 */
@keyframes wave {
  from {
      transform: translateY(70%);
  }
  to {
      transform: translateY(65%);
  }
}

.tagcloud { 
  width:100%; 
  height:90%!important; 
  overflow: hidden;
  position: relative;
}
.tagcloud a {
  display: block;
  border-radius: 50%;
  color: #2c3e50;
  font-weight: bold;
  font-size: 14px;
  text-decoration: none;
  text-align: center;
  display: flex; 
  align-items: center; 
  justify-content: center;
}

.b01{ width: 50px; height: 50px; }
.b02{ width: 80px; height: 80px; }
.b03{ width: 60px; height: 60px; }
.b04{ width: 70px; height: 70px; }

.co01{ border: 2px solid rgba(52,152,219,1); box-shadow: inset 0 0 20px rgba(52,152,219,1);}
.co02{ border: 2px solid rgba(241,196,15,1); box-shadow: inset 0 0 20px rgba(241,196,15,1);}
.co03{ border: 2px solid rgba(41,128,185,1); box-shadow: inset 0 0 20px rgba(41,128,185,1);}
.co04{ border: 2px solid rgba(46,204,113,1); box-shadow: inset 0 0 20px rgba(46,204,113,1);}
.co05{ border: 2px solid rgba(230,126,34,1); box-shadow: inset 0 0 20px rgba(230,126,34,1);}

.huati{ padding-top: 20px;}
.huati li{ font-size: 12px; line-height: 230%;}

.wancheng{display: flex; align-items: center; justify-content: center;}
.wancheng span{font-size: 14px; color: #2c3e50;}
.wancheng h3{font-size: 20px; color:#3498db;}
.wancheng h3 i{font-size: 12px; color:#2c3e50;}
.yuan{padding:5px;border-radius: 100%; margin-left: 10px; border: 2px solid rgba(52,152,219,.8);}
.yuan span{width: 60px; height: 60px; border-radius: 100%; background: rgba(52,152,219,.8); display: flex; align-items: center; justify-content: center; font-size: 20px;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/943048.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

通过GRE协议组建VPN网络

GRE&#xff08;Generic Routing Encapsulation&#xff0c;通用路由封装协议&#xff09;协议是一种简单而有效的封装协议&#xff0c;它在网络中的广泛应用&#xff0c;比如在构建VPN网络。   GRE是一种封装协议&#xff0c;它允许网络层协议&#xff08;如IP&#xff09;的…

kafka的备份策略:从备份到恢复

文章目录 一、全量备份二、增量备份三、全量恢复四、增量恢复 前言&#xff1a;Kafka的备份的单元是partition&#xff0c;也就是每个partition都都会有leader partiton和follow partiton。其中leader partition是用来进行和producer进行写交互&#xff0c;follow从leader副本进…

CHM助手 >> 如何安装CHM助手

1 如何安装CHM助手 下载CHM助手.ezip&#xff0c;下载地址打开EverEdit&#xff0c;选择主菜单“扩展 -> 扩展管理 -> 从本地文件安装扩展”&#xff0c;在弹出的文件浏览窗口中选择插件安装包&#xff0c;如下图所示&#xff1a; &#x1f56e;说明&#xff1a;   …

vulnhub靶场【shuriken】之node

前言 靶机&#xff1a;shuriken-node&#xff0c;ip地址192.168.1.127 攻击&#xff1a;kali&#xff0c;ip地址192.168.1.16 主机发现 使用arp-scan -l或者netdiscover -r 192.168.1.1/24扫描 信息收集 使用nmap扫描端口 网站信息探测 访问8080端口网站&#xff0c;可以…

数据仓库工具箱—读书笔记02(Kimball维度建模技术概述04、使用一致性维度集成)

Kimball维度建模技术概述 记录一下读《数据仓库工具箱》时的思考&#xff0c;摘录一些书中关于维度建模比较重要的思想与大家分享&#x1f923;&#x1f923;&#x1f923; 第二章前言部分作者提到&#xff1a;技术的介绍应该通过涵盖各种行业的熟悉的用例展开&#xff08;赞同…

[实战]推流服务SRS安装

业务场景 在Web浏览器端展示摄像头的视频数据。 协议 物联代理推流协议&#xff1a;rtmp 浏览器器拉流协议&#xff1a;http-flv 推流方案 1、Nginx加nginx-http-flv-modules模块 2、采用SRS服务器 推流服务SRS网站&#xff1a;https://ossrs.io/lts/zh-cn/ 推流服务…

PH热榜 | 2024-12-25

1. Assistive24 标语&#xff1a;为残障人士提供的免费辅助技术 介绍&#xff1a;Assistive24 是一款免费的 Chrome 浏览器扩展程序&#xff0c;可以帮助患有注意力缺陷多动障碍 (ADHD)、阅读障碍 (dyslexia) 和低视力等障碍的用户更方便地浏览网页。它提供语音导航、自定义…

Java中三大构建工具的发展历程(Ant、Maven和Gradle)

&#x1f438; 背景 我们要写一个Java程序&#xff0c;一般的步骤是编译&#xff0c;测试&#xff0c;打包。 这个构建的过程&#xff0c;如果文件比较少&#xff0c;我们可以手动使用java, javac,jar命令去做这些事情。但当工程越来越大&#xff0c;文件越来越多&#xff0c…

自学记录HarmonyOS Next DRM API 13:构建安全的数字内容保护系统

在完成了HarmonyOS Camera API的开发之后&#xff0c;我开始关注更复杂的系统级功能。在浏览HarmonyOS Next文档时&#xff0c;我发现了一个非常有趣的领域&#xff1a;数字版权管理&#xff08;DRM&#xff09;。最新的DRM API 13提供了强大的工具&#xff0c;用于保护数字内容…

Unity中如何修改Sprite的渲染网格

首先打开SpriteEditor 选择Custom OutLine,点击Genrate 则在图片边缘会出现边缘线&#xff0c;调整白色小方块可以调整边缘 调整后&#xff0c;Sprite就会按照调整后的网格渲染了。 如何在UI中使用&#xff1f; 只要在UI的Image组件中选择Use Sprite Mesh 即可 结果&#xff1…

跟着 8.6k Star 的开源数据库,搞 RAG!

过去 9 年里&#xff0c;HelloGitHub 月刊累计收录了 3000 多个开源项目。然而&#xff0c;随着项目数量的增加&#xff0c;不少用户反馈&#xff1a;“搜索功能不好用&#xff0c;找不到想要的项目&#xff01;” 这让我意识到&#xff0c;仅仅收录项目是不够的&#xff0c;还…

Sashulin升级啦,开箱即用!

经过多年的不断投入&#xff0c;升级为了Sashulin基础软件系列&#xff0c;本系列包含&#xff1a; 1、Sashulin IDE 2025全域通用开发工具 通用型Java开发工具&#xff0c;并可以进行业务流可视化开发。 2、发布Sashulin Webserver 2025 将Html等网页文件发布成网站&#xf…

linux下搭建lamp环境(dvwa)

lamp简介 LAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写&#xff1a; Linux&#xff0c;操作系统 Apache&#xff0c;网页服务器 MariaDB或MySQL&#xff0c;数据库管理系统或数据库服务器 PHP、Perl或Python&#xff0c;脚本语言 # ubuntu安装…

RAGFlow 基于深度文档理解构建的开源 RAG引擎 - 使用Ollama添加大模型

RAGFlow 基于深度文档理解构建的开源 RAG引擎 - 使用Ollama添加大模型 flyfish 当安装完ragflow之后&#xff0c;开始添加大模型 $ git clone https://github.com/infiniflow/ragflow.git $ cd ragflow $ docker compose -f docker/docker-compose.yml up -d浏览器打开http:…

NiChart 多模态神经影像(structural MRI,functional MRI,and diffusion MRI)处理和分析工具包安装

NiChart多模态神经影像部署 NiChart 本地安装Git clone 问题personal access token PAT 问题 NiChart 云端注册AWS验证问题 NiChart 是UPenn大学&#xff0c;Christos Davatzikos教授开发的一个多模态MRI影像&#xff0c;structural (sMRI), diffusion (dMRI)&#xff0c; and …

路由策略

控制层流量 --- 路由协议传递路由信息时产生的流量 数据层流量 --- 设备访问目标地址时产生的流量 所谓的路由策略----在控制层面转发流量的过程中&#xff0c;截取流量&#xff0c;之后修改流量再转发或不转发的技术&#xff0c;最终达到影响路由器路由表的生成&#xff0c…

深度学习实战之超分辨率算法(tensorflow)——ESPCN

espcn原理算法请参考上一篇论文&#xff0c;这里主要给实现。 数据集如下&#xff1a;尺寸相等即可 针对数据集&#xff0c;生成样本代码preeate_data.py import imageio from scipy import misc, ndimage import numpy as np import imghdr import shutil import os import…

Dockerfile的用法

Dockerfile的用法 示例 `Dockerfile`使用 `Dockerfile` 创建 Docker 镜像`Dockerfile` 指令详解其他常用指令总结Dockerfile 是一个文本文件,包含了用于创建 Docker 镜像的一系列指令。这些指令描述了镜像的基础、所安装的软件、文件的复制、环境变量的设置以及其他配置。下面…

【GO基础学习】gin框架路由详解

文章目录 gin框架路由详解&#xff08;1&#xff09;go mod tidy&#xff08;2&#xff09;r : gin.Default()&#xff08;3&#xff09;r.GET()路由注册 &#xff08;4&#xff09;r.Run()路由匹配 总结 gin框架路由详解 先创建一个项目&#xff0c;编写一个简单的demo&#…

直流无刷电机驱动原理1--简介和例程演示

基础知识 BLDC&#xff08;Brushless DC Motor&#xff0c;无刷直流电机&#xff09; 和 PMSM&#xff08;Permanent Magnet Synchronous Motor&#xff0c;永磁同步电机&#xff09; 都是基于永磁体技术的无刷电机&#xff0c;但它们在结构、控制方式和应用场景上存在一些区别…