Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
liming6
dcu-process-montor
Commits
6e2dd6f5
Commit
6e2dd6f5
authored
Dec 04, 2025
by
liming6
Browse files
fix 修复timechart显示问题
parent
2636b033
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
112 additions
and
68 deletions
+112
-68
cmd/hytop/tui/timechart.go
cmd/hytop/tui/timechart.go
+83
-55
cmd/hytop/tui/tui_test.go
cmd/hytop/tui/tui_test.go
+4
-10
utils/utils_test.go
utils/utils_test.go
+25
-3
No files found.
cmd/hytop/tui/timechart.go
View file @
6e2dd6f5
...
...
@@ -13,6 +13,7 @@ import (
"github.com/NimbleMarkets/ntcharts/canvas/runes"
tea
"github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
linkedlist
"github.com/emirpasic/gods/v2/lists/doublylinkedlist"
zone
"github.com/lrstanley/bubblezone"
)
...
...
@@ -101,7 +102,7 @@ func NewTimeCharMsg(point []tchart.TimePoint, reset bool) MyTimeChartMsg {
type
MyTimeChart
struct
{
chart
*
tchart
.
Model
// 原始图表
zM
*
zone
.
Manager
// 区域管理
points
[
]
tchart
.
TimePoint
// 数据点
points
*
linkedlist
.
List
[
tchart
.
TimePoint
]
// 数据点
,这里只存储put的数据,不存储自动添加的数据
width
,
height
int
// 图表的高度和宽度
max
,
min
float64
// y轴的最值
lockPoints
sync
.
RWMutex
// 保护dataSet的并发读写
...
...
@@ -119,11 +120,12 @@ func NewTimeChart(width, height int, vmin, vmax float64, color []lipgloss.Color)
result
.
zM
=
zoneManager
result
.
lockPoints
=
sync
.
RWMutex
{}
result
.
lockPoints
.
Lock
()
result
.
points
=
make
([]
tchart
.
TimePoint
,
(
result
.
width
*
2
)
+
1
)
// 准备数据,数据间隔为1秒
result
.
points
=
linkedlist
.
New
[
tchart
.
TimePoint
]()
now
:=
time
.
Now
()
for
i
:=
result
.
width
*
2
;
i
>=
0
;
i
--
{
result
.
points
[
i
]
=
tchart
.
TimePoint
{
Time
:
now
.
Add
(
time
.
Duration
(
-
i
)
*
time
.
Second
),
Value
:
vmin
}
t
:=
result
.
width
*
2
+
1
tmpPoints
:=
make
([]
tchart
.
TimePoint
,
0
,
t
)
for
i
:=
range
t
{
tmpPoints
=
append
(
tmpPoints
,
tchart
.
TimePoint
{
Time
:
now
.
Add
(
time
.
Duration
(
-
i
)
*
time
.
Second
)})
}
result
.
lockPoints
.
Unlock
()
s
:=
tchart
.
New
(
width
,
height
+
1
,
...
...
@@ -131,37 +133,73 @@ func NewTimeChart(width, height int, vmin, vmax float64, color []lipgloss.Color)
tchart
.
WithZoneManager
(
zoneManager
),
tchart
.
WithYRange
(
vmin
,
vmax
),
tchart
.
WithXYSteps
(
0
,
0
),
tchart
.
WithTimeSeries
(
result
.
p
oints
),
tchart
.
WithTimeSeries
(
tmpP
oints
),
)
result
.
chart
=
&
s
result
.
color
=
color
return
&
result
}
func
(
m
*
MyTimeChart
)
SortPoints
()
{
m
.
points
.
Sort
(
func
(
x
,
y
tchart
.
TimePoint
)
int
{
if
x
.
Time
.
After
(
y
.
Time
)
{
return
1
}
if
x
.
Time
.
Before
(
y
.
Time
)
{
return
-
1
}
return
0
})
}
func
(
m
*
MyTimeChart
)
RemoveUselessPoint
()
{
m
.
SortPoints
()
th
:=
time
.
Now
()
.
Add
(
time
.
Duration
(
m
.
width
*-
2
)
*
time
.
Second
)
for
{
t
,
b
:=
m
.
points
.
Get
(
0
)
if
!
b
{
break
}
if
t
.
Time
.
Before
(
th
)
{
m
.
points
.
Remove
(
0
)
}
else
{
break
}
}
}
// PutPoint 添加若干数据点
func
(
m
*
MyTimeChart
)
PutPoint
(
points
[]
tchart
.
TimePoint
)
{
m
.
lockPoints
.
Lock
()
ops
:=
append
(
m
.
points
,
points
...
)
// 排序
sort
.
Slice
(
ops
,
func
(
i
,
j
int
)
bool
{
return
ops
[
i
]
.
Time
.
Before
(
ops
[
j
]
.
Time
)
})
threshold
:=
time
.
Now
()
.
Add
(
time
.
Second
*
time
.
Duration
(
-
2
*
m
.
width
))
targetIndex
:=
0
for
i
,
p
:=
range
ops
{
if
!
p
.
Time
.
Before
(
threshold
)
{
targetIndex
=
i
if
len
(
points
)
>
0
{
m
.
points
.
Add
(
points
...
)
}
m
.
RemoveUselessPoint
()
threshold
:=
time
.
Now
()
.
Add
(
time
.
Second
*
time
.
Duration
(
-
2
*
m
.
width
-
1
))
points
=
m
.
points
.
Values
()
tmpPoint
:=
make
([]
tchart
.
TimePoint
,
0
,
m
.
width
*
2
)
// 判断是否需要补充空点
if
!
points
[
0
]
.
Time
.
Before
(
threshold
)
{
t
:=
points
[
0
]
.
Time
.
Add
(
-
time
.
Second
)
for
{
if
!
t
.
Before
(
threshold
)
{
tmpPoint
=
append
(
tmpPoint
,
tchart
.
TimePoint
{
Time
:
t
,
Value
:
m
.
min
})
t
=
t
.
Add
(
-
time
.
Second
)
}
else
{
break
}
}
nps
:=
append
(
make
([]
tchart
.
TimePoint
,
0
,
targetIndex
+
1
),
ops
[
targetIndex
:
]
...
)
m
.
points
=
nps
}
tmpPoint
=
append
(
tmpPoint
,
points
...
)
sort
.
Slice
(
tmpPoint
,
func
(
i
,
j
int
)
bool
{
return
tmpPoint
[
i
]
.
Time
.
Before
(
tmpPoint
[
j
]
.
Time
)
})
s
:=
tchart
.
New
(
m
.
width
,
m
.
height
+
1
,
tchart
.
WithLineStyle
(
runes
.
ThinLineStyle
),
tchart
.
WithZoneManager
(
m
.
zM
),
tchart
.
WithYRange
(
m
.
min
,
m
.
max
),
tchart
.
WithXYSteps
(
0
,
0
),
tchart
.
WithTimeSeries
(
m
.
p
oint
s
),
tchart
.
WithTimeSeries
(
tmpP
oint
),
)
m
.
lockPoints
.
Unlock
()
// 插入数据
...
...
@@ -175,47 +213,37 @@ func (m *MyTimeChart) PutPoint(points []tchart.TimePoint) {
func
(
m
*
MyTimeChart
)
ResetPutPoint
(
points
[]
tchart
.
TimePoint
)
{
// 清除原有的点
m
.
lockPoints
.
Lock
()
m
.
points
=
m
.
points
[
:
0
]
m
.
points
.
Clear
()
if
len
(
points
)
>
0
{
m
.
points
.
Add
(
points
...
)
}
m
.
RemoveUselessPoint
()
threshold
:=
time
.
Now
()
.
Add
(
time
.
Second
*
time
.
Duration
(
-
2
*
m
.
width
-
1
))
points
=
m
.
points
.
Values
()
tmpPoint
:=
make
([]
tchart
.
TimePoint
,
0
,
m
.
width
*
2
)
// 排序输入数据
sort
.
Slice
(
points
,
func
(
i
,
j
int
)
bool
{
return
points
[
i
]
.
Time
.
Before
(
points
[
j
]
.
Time
)
})
// 补充数据 或 剔除数据
now
:=
time
.
Now
()
threshold
:=
now
.
Add
(
time
.
Duration
(
m
.
width
*-
2
)
*
time
.
Second
)
first
:=
points
[
0
]
.
Time
if
first
.
Before
(
threshold
)
{
// 需要剔除数据
index
:=
0
for
k
,
v
:=
range
points
{
if
v
.
Time
.
Before
(
threshold
)
{
continue
}
else
{
index
=
k
break
}
}
m
.
points
=
append
(
make
([]
tchart
.
TimePoint
,
0
,
len
(
points
[
index
:
])),
points
[
index
:
]
...
)
}
else
if
first
.
After
(
threshold
)
{
// 需要补充数据
max
:=
m
.
width
*
2
for
i
:=
1
;
i
<
max
;
i
++
{
ta
:=
now
.
Add
(
time
.
Second
*
time
.
Duration
(
-
i
))
if
!
ta
.
Before
(
threshold
)
{
m
.
points
=
append
(
m
.
points
,
tchart
.
TimePoint
{
Time
:
ta
,
Value
:
m
.
min
})
// 判断是否需要补充空点
if
!
points
[
0
]
.
Time
.
Before
(
threshold
)
{
t
:=
points
[
0
]
.
Time
.
Add
(
-
time
.
Second
)
for
{
if
!
t
.
Before
(
threshold
)
{
tmpPoint
=
append
(
tmpPoint
,
tchart
.
TimePoint
{
Time
:
t
,
Value
:
m
.
min
})
t
=
t
.
Add
(
-
time
.
Second
)
}
else
{
break
}
}
m
.
points
=
append
(
m
.
points
,
points
...
)
}
tmpPoint
=
append
(
tmpPoint
,
points
...
)
sort
.
Slice
(
tmpPoint
,
func
(
i
,
j
int
)
bool
{
return
tmpPoint
[
i
]
.
Time
.
Before
(
tmpPoint
[
j
]
.
Time
)
})
s
:=
tchart
.
New
(
m
.
width
,
m
.
height
+
1
,
tchart
.
WithLineStyle
(
runes
.
ThinLineStyle
),
tchart
.
WithZoneManager
(
m
.
zM
),
tchart
.
WithYRange
(
m
.
min
,
m
.
max
),
tchart
.
WithXYSteps
(
0
,
0
),
tchart
.
WithTimeSeries
(
m
.
p
oint
s
),
tchart
.
WithTimeSeries
(
tmpP
oint
),
)
m
.
lockPoints
.
Unlock
()
// 插入数据
...
...
cmd/hytop/tui/tui_test.go
View file @
6e2dd6f5
...
...
@@ -11,13 +11,6 @@ import (
"github.com/charmbracelet/lipgloss"
)
const
S
=
`├───────────────────────────────┼──────────────────────┼──────────────────────┼
│ 2 BW200, manual │ 0000:5e:00.0 Off │ Off On │ DCU: ░░░░░░░░░░░░░░░░░░░░░░░░░ 0% │`
func
TestLine
(
t
*
testing
.
T
)
{
t
.
Logf
(
"%d"
,
lipgloss
.
Width
(
S
))
}
func
TestHeader
(
t
*
testing
.
T
)
{
m
:=
ModelHeader
{}
cmd
:=
m
.
Init
()
...
...
@@ -80,14 +73,15 @@ func TestSysloadInit(t *testing.T) {
func
TestTimeChart
(
t
*
testing
.
T
)
{
chart1
:=
NewTimeChart
(
100
,
20
,
0
,
100
,
nil
)
chart2
:=
NewTimeChart
(
100
,
20
,
0
,
100
,
nil
)
//
chart2 := NewTimeChart(100, 20, 0, 100, nil)
now
:=
time
.
Now
()
points
:=
make
([]
tchart
.
TimePoint
,
0
,
200
)
for
i
:=
range
200
{
points
=
append
(
points
,
tchart
.
TimePoint
{
Time
:
now
.
Add
(
time
.
Duration
(
-
i
)
*
time
.
Second
),
Value
:
rand
.
Float64
()
*
100
})
}
chart1
.
PutPoint
(
points
)
t
.
Logf
(
"
\n
%s"
,
chart1
.
View
())
chart
2
.
PutPoint
(
points
)
t
.
Logf
(
"
\n
%s"
,
chart
2
.
View
())
chart
1
.
Reset
PutPoint
(
points
)
t
.
Logf
(
"
\n
%s"
,
chart
1
.
View
())
}
utils/utils_test.go
View file @
6e2dd6f5
...
...
@@ -10,6 +10,7 @@ import (
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/lipgloss/tree"
"github.com/emirpasic/gods/v2/lists/doublylinkedlist"
"github.com/emirpasic/gods/v2/maps/treemap"
"github.com/shirou/gopsutil/v4/process"
)
...
...
@@ -197,7 +198,28 @@ func TestChild(t *testing.T) {
}
func
TestCHar
(
t
*
testing
.
T
)
{
c1
:=
"⣿⣿⣿⣿⣿⣿⣿⣿"
c2
:=
"├"
t
.
Log
(
lipgloss
.
JoinHorizontal
(
lipgloss
.
Top
,
c2
,
c1
))
list
:=
doublylinkedlist
.
New
[
time
.
Time
]()
now
:=
time
.
Now
()
for
i
:=
range
10
{
if
i
%
2
==
0
{
list
.
Add
(
now
.
Add
(
time
.
Duration
(
i
)
*
time
.
Second
))
}
else
{
list
.
Add
(
now
.
Add
(
time
.
Duration
(
-
i
)
*
time
.
Second
))
}
}
list
.
Sort
(
func
(
x
,
y
time
.
Time
)
int
{
if
x
.
After
(
y
)
{
return
1
}
if
x
.
Before
(
y
)
{
return
-
1
}
return
0
})
for
_
=
range
list
.
Size
()
{
time
,
b
:=
list
.
Get
(
0
)
list
.
Remove
(
0
)
t
.
Logf
(
"%v: %v"
,
time
,
b
)
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment