Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] main from hamster1963:main #25

Merged
merged 5 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 63 additions & 9 deletions app/(main)/ClientComponents/detail/NetworkChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,48 @@ export const NetworkChart = React.memo(function NetworkChart({
return activeChart === defaultChart ? formattedData : chartData[activeChart]
}

// 如果开启了削峰,对数据进行处理
const data = (
activeChart === defaultChart ? formattedData : chartData[activeChart]
) as ResultItem[]
const windowSize = 7 // 增加到7个点的移动平均
const weights = [0.1, 0.1, 0.15, 0.3, 0.15, 0.1, 0.1] // 加权平均的权重

const windowSize = 11 // 增加窗口大小以获取更好的统计效果
const alpha = 0.3 // EWMA平滑因子

// 辅助函数:计算中位数
const getMedian = (arr: number[]) => {
const sorted = [...arr].sort((a, b) => a - b)
const mid = Math.floor(sorted.length / 2)
return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2
}

// 辅助函数:异常值处理
const processValues = (values: number[]) => {
if (values.length === 0) return null

const median = getMedian(values)
const deviations = values.map((v) => Math.abs(v - median))
const medianDeviation = getMedian(deviations) * 1.4826 // MAD估计器

// 使用中位数绝对偏差(MAD)进行异常值检测
const validValues = values.filter(
(v) =>
Math.abs(v - median) <= 3 * medianDeviation && // 更严格的异常值判定
v <= median * 3, // 限制最大值不超过中位数的3倍
)

if (validValues.length === 0) return median // 如果没有有效值,返回中位数

// 计算EWMA
let ewma = validValues[0]
for (let i = 1; i < validValues.length; i++) {
ewma = alpha * validValues[i] + (1 - alpha) * ewma
}

return ewma
}

// 初始化EWMA历史值
const ewmaHistory: { [key: string]: number } = {}

return data.map((point, index) => {
if (index < windowSize - 1) return point
Expand All @@ -174,22 +210,40 @@ export const NetworkChart = React.memo(function NetworkChart({
const smoothed = { ...point } as ResultItem

if (activeChart === defaultChart) {
// 处理所有线路的数据
chartDataKey.forEach((key) => {
const values = window
.map((w) => w[key])
.filter((v) => v !== undefined && v !== null) as number[]
if (values.length === windowSize) {
smoothed[key] = values.reduce((acc, val, idx) => acc + val * weights[idx], 0)

if (values.length > 0) {
const processed = processValues(values)
if (processed !== null) {
// 应用EWMA平滑
if (ewmaHistory[key] === undefined) {
ewmaHistory[key] = processed
} else {
ewmaHistory[key] = alpha * processed + (1 - alpha) * ewmaHistory[key]
}
smoothed[key] = ewmaHistory[key]
}
}
})
} else {
// 处理单条线路的数据
const values = window
.map((w) => w.avg_delay)
.filter((v) => v !== undefined && v !== null) as number[]
if (values.length === windowSize) {
smoothed.avg_delay = values.reduce((acc, val, idx) => acc + val * weights[idx], 0)

if (values.length > 0) {
const processed = processValues(values)
if (processed !== null) {
// 应用EWMA平滑
if (ewmaHistory["current"] === undefined) {
ewmaHistory["current"] = processed
} else {
ewmaHistory["current"] = alpha * processed + (1 - alpha) * ewmaHistory["current"]
}
smoothed.avg_delay = ewmaHistory["current"]
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions app/(main)/ClientComponents/main/ServerOverviewClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,11 @@ export default function ServerOverviewClient() {
</div>
{data?.result ? (
<>
<section className="flex items-start flex-row pr-0 gap-1">
<p className="sm:text-[12px] text-[10px] text-blue-800 dark:text-blue-400 text-nowrap font-medium">
<section className="flex flex-col sm:flex-row items-start pr-0 gap-1">
<p className="text-[12px] text-blue-800 dark:text-blue-400 text-nowrap font-medium">
↑{formatBytes(data?.total_out_bandwidth)}
</p>
<p className="sm:text-[12px] text-[10px] text-purple-800 dark:text-purple-400 text-nowrap font-medium">
<p className="text-[12px] text-purple-800 dark:text-purple-400 text-nowrap font-medium">
↓{formatBytes(data?.total_in_bandwidth)}
</p>
</section>
Expand Down
Binary file modified bun.lockb
Binary file not shown.
28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nezha-dash",
"version": "1.8.2",
"version": "1.8.4",
"private": true,
"scripts": {
"dev": "next dev -p 3040",
Expand All @@ -15,22 +15,22 @@
"dependencies": {
"@ducanh2912/next-pwa": "^10.2.9",
"@heroicons/react": "^2.2.0",
"@radix-ui/react-dialog": "^1.1.3",
"@radix-ui/react-dropdown-menu": "^2.1.3",
"@radix-ui/react-dialog": "^1.1.4",
"@radix-ui/react-dropdown-menu": "^2.1.4",
"@radix-ui/react-label": "^2.1.1",
"@radix-ui/react-navigation-menu": "^1.2.2",
"@radix-ui/react-popover": "^1.1.3",
"@radix-ui/react-navigation-menu": "^1.2.3",
"@radix-ui/react-popover": "^1.1.4",
"@radix-ui/react-progress": "^1.1.1",
"@radix-ui/react-separator": "^1.1.1",
"@radix-ui/react-slot": "^1.1.1",
"@radix-ui/react-switch": "^1.1.2",
"@radix-ui/react-tooltip": "^1.1.5",
"@radix-ui/react-tooltip": "^1.1.6",
"@trivago/prettier-plugin-sort-imports": "^5.2.0",
"@turf/turf": "^7.1.0",
"@types/d3-geo": "^3.1.0",
"@types/luxon": "^3.4.2",
"@typescript-eslint/eslint-plugin": "^8.18.0",
"caniuse-lite": "^1.0.30001688",
"@typescript-eslint/eslint-plugin": "^8.18.1",
"caniuse-lite": "^1.0.30001689",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"country-flag-icons": "^1.5.13",
Expand All @@ -42,7 +42,7 @@
"lucide-react": "^0.454.0",
"luxon": "^3.5.0",
"maxmind": "^4.3.23",
"next": "^15.1.0",
"next": "^15.1.1",
"next-auth": "^5.0.0-beta.25",
"next-intl": "^3.26.1",
"next-runtime-env": "^3.2.2",
Expand All @@ -57,22 +57,22 @@
"swr": "^2.2.6-beta.5",
"tailwind-merge": "^2.5.5",
"tailwindcss-animate": "^1.0.7",
"typescript-eslint": "^8.18.0"
"typescript-eslint": "^8.18.1"
},
"devDependencies": {
"@next/bundle-analyzer": "^15.1.0",
"@tailwindcss/postcss": "^4.0.0-beta.7",
"@next/bundle-analyzer": "^15.1.1",
"@tailwindcss/postcss": "^4.0.0-beta.8",
"@types/node": "^22.10.2",
"@types/react": "^19.0.1",
"@types/react-dom": "^19.0.2",
"eslint": "^9.17.0",
"eslint-config-next": "^15.1.0",
"eslint-config-next": "^15.1.1",
"eslint-plugin-turbo": "^2.3.3",
"eslint-plugin-unused-imports": "^4.1.4",
"postcss": "^8.4.49",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.9",
"tailwindcss": "^4.0.0-beta.7",
"tailwindcss": "^4.0.0-beta.8",
"typescript": "^5.7.2",
"vercel": "^39.2.2"
},
Expand Down
Loading