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

news2024/12/27 2:17:59

环境:网络管理 主机资源监控系统项目搭建 (保姆级教程 建议点赞 收藏)_搭建网络版信息管理系统-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;}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

62.基于SpringBoot + Vue实现的前后端分离-驾校预约学习系统(项目+论文)

项目介绍 伴随着信息技术与互联网技术的不断发展&#xff0c;人们进到了一个新的信息化时代&#xff0c;传统管理技术性没法高效率、容易地管理信息内容。为了实现时代的发展必须&#xff0c;提升管理高效率&#xff0c;各种各样管理管理体系应时而生&#xff0c;各个领域陆续进…

MySQL用表组织数据

用表组织数据 文章目录 用表组织数据一.四种完整性约束二.数值类型2-1三.数值类型2-2四.字符串.日期类型五.设置1.设置主键2.设置标识列3.设置非空4.设置默认值 六.主外键建立后注意事项 一.四种完整性约束 1.域完整性 列 域完整性约束方法:限制数据类型,检查约束,外键约束,默…

iOS开发代码块-OC版

iOS开发代码块-OC版 资源分享资源使用详情Xcode自带代码块自定义代码块 资源分享 自提&#xff1a; 通过网盘分享的文件&#xff1a;CodeSnippets 2.zip 链接: https://pan.baidu.com/s/1Yh8q9PbyeNpuYpasG4IiVg?pwddn1i 提取码: dn1i Xcode中的代码片段默认放在下面的目录中…

基于微信小程序的校园访客登记系统

基于微信小程序的校园访客登记系统 功能列表 用户端功能 注册与登录 &#xff1a;支持用户通过手机号短信验证码注册和登录。个人资料管理 &#xff1a;允许用户编辑和更新个人信息及其密码。站内信消息通知&#xff1a;通知公告。来访预约&#xff1a;提交来访预约支持车牌…

mac启ssh服务用于快速文件传输

x.1 在mac上启SSH服务 方法一&#xff1a;图形交互界面启ssh&#xff08;推荐&#xff09; 通过sharing - advanced - remote login来启动ssh&#xff1b;&#xff08;中文版mac应该是 “系统设置 → 通用 → 共享”里打开“远程登录”来启动&#xff09; 查看自己的用户名和…

Magnet: 基于推送的大规模数据处理Shuffle服务

本文翻译自&#xff1a;《Magnet: Push-based Shuffle Service for Large-scale Data Processing》 摘要 在过去的十年中&#xff0c;Apache Spark 已成为大规模数据处理的流行计算引擎。与其他基于 MapReduce 计算范式的计算引擎一样&#xff0c;随机Shuffle操作&#xff08;即…

面试真题:Integer(128)引发的思考

引言 在 Java 编程语言中&#xff0c;数据类型的使用至关重要。作为一种静态类型语言&#xff0c;Java 提供了丰富的基本数据类型和对应的包装类。其中&#xff0c;Integer 类是 int 类型的包装类&#xff0c;承载着更复杂的功能&#xff0c;如缓存、装箱和拆箱等。掌握 Integ…

Windows脚本清理C盘缓存

方法一&#xff1a;使用power文件.ps1的文件 脚本功能 清理临时文件夹&#xff1a; 当前用户的临时文件夹&#xff08;%Temp%&#xff09;。系统临时文件夹&#xff08;C:\Windows\Temp&#xff09;。 清理 Windows 更新缓存&#xff1a; 删除 Windows 更新下载缓存&#xff0…

Type-c接口

6P Type C 接口座&#xff1a; 仅支持充电 16P 与 12P Type C 接口座&#xff1a; 支持数据传输 Type-c引脚&#xff1a; SUB1,SUB2为辅助通讯引脚&#xff0c;主要用在音视频信号传输中&#xff0c;很多DIY都用不到 CC1、CC2引脚用于连接检测&#xff0c;一般可以不用连接&am…

基于python语音启动电脑应用程序

osk模型进行输入语音转换 txt字典导航程序路径 pyttsx3引擎进行语音打印输出 关键词程序路径 import os import json import queue import sounddevice as sd from vosk import Model, KaldiRecognizer import subprocess import time import pyttsx3 import threading# 初始…

互联网视频云平台EasyDSS无人机推流直播技术如何助力野生动植物保护工作?

在当今社会&#xff0c;随着科技的飞速发展&#xff0c;无人机技术已经广泛应用于各个领域&#xff0c;为我们的生活带来了诸多便利。而在动植物保护工作中&#xff0c;无人机的应用更是为这一领域注入了新的活力。EasyDSS&#xff0c;作为一款集视频处理、分发、存储于一体的综…

垃圾分割数据集labelme格式659张1类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;659 标注数量(json文件个数)&#xff1a;659 标注类别数&#xff1a;1 标注类别名称:["garbage"] 每个类别标注的框数&#…

记我的Springboot2.6.4从集成swagger到springdoc的坎坷路~

项目背景 主要依赖及jdk信息&#xff1a; Springboot&#xff1a;2.6.4 Jdk: 1.8 最近新搭建了一套管理系统&#xff0c;前端部分没有公司的前端团队&#xff0c;自己在github上找了一个star较多使用相对也简单的框架。在这个管理系统搭建好上线之后&#xff0c;给组内的小伙…

NNDL 作业11 LSTM

习题6-4 推导LSTM网络中参数的梯度&#xff0c; 并分析其避免梯度消失的效果 先来推个实例&#xff1a; 看式子中间&#xff0c;上半部分并未有连乘项&#xff0c;而下半部分有到的连乘项&#xff0c;从这可以看出&#xff0c;LSTM能缓解梯度消失&#xff0c;梯度爆炸只是不易…

uniapp使用live-pusher实现模拟人脸识别效果

需求&#xff1a; 1、前端实现模拟用户人脸识别&#xff0c;识别成功后抓取视频流或认证的一张静态图给服务端。 2、服务端调用第三方活体认证接口&#xff0c;验证前端传递的人脸是否存在&#xff0c;把认证结果反馈给前端。 3、前端根据服务端返回的状态&#xff0c;显示在…

MySQL中Performance Schema库的详解(下)

昨天说了关于SQL语句相关的&#xff0c;今天来说说性能相关的&#xff0c;如果没有看过上篇请点传送门https://blog.csdn.net/2301_80479959/article/details/144693574?fromshareblogdetail&sharetypeblogdetail&sharerId144693574&sharereferPC&sharesource…

YOLO11全解析:从原理到实战,全流程体验下一代目标检测

前言 一、模型介绍 二、网络结构 1.主干网络&#xff08;Backbone&#xff09; 2.颈部网络&#xff08;Neck&#xff09; 3.头部网络&#xff08;Head&#xff09; 三、算法改进 1.增强的特征提取 2.优化的效率和速度 3.更高的准确性与更少的参数 4.环境适应性强 5.…

【Qt】了解和HelloWorld

目录 0.用户交互界面风格 Windows下GUI开发方案&#xff1f; 1.Qt简介 1.1 版本Qt5. 1.2搭建Qt开发环境 需要安装3个工具 安装过程 熟悉QtSDK重要工具 2.使用Qt Creator创建项目 2.1代码解释 2.2helloworld 1.图形化方式 2.代码方式 0.用户交互界面风格 1.TUI&…

原点安全再次入选信通院 2024 大数据“星河”案例

近日&#xff0c;中国信息通信研究院和中国通信标准化协会大数据技术标准推进委员会&#xff08;CCSA TC601&#xff09;共同组织开展的 2024 大数据“星河&#xff08;Galaxy&#xff09;”案例征集活动结果正式公布。由工银瑞信基金管理有限公司、北京原点数安科技有限公司联…

【MySQL初阶】--- 数据类型

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; MySQL &#x1f3e0; 数据类型分类 MySQL是一套整体的对外数据存取方案,既然要存取数据,而数据有不同的类型,因此MySQL也存在不同的数据类型,有不同的用…