Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
VisualDL
提交
e698eda6
V
VisualDL
项目概览
PaddlePaddle
/
VisualDL
大约 1 年 前同步成功
通知
88
Star
4655
Fork
642
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
5
Wiki
分析
仓库
DevOps
项目成员
Pages
V
VisualDL
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
5
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
e698eda6
编写于
6月 27, 2020
作者:
P
Peter Pan
提交者:
GitHub
6月 27, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: pr-curve (#681)
上级
dc3bebb8
变更
40
展开全部
隐藏空白更改
内联
并排
Showing
40 changed file
with
7339 addition
and
241 deletion
+7339
-241
frontend/packages/cli/package.json
frontend/packages/cli/package.json
+1
-1
frontend/packages/core/components/Field.tsx
frontend/packages/core/components/Field.tsx
+1
-1
frontend/packages/core/components/HistogramPage/HistogramChart.tsx
...packages/core/components/HistogramPage/HistogramChart.tsx
+0
-1
frontend/packages/core/components/LineChart.tsx
frontend/packages/core/components/LineChart.tsx
+11
-0
frontend/packages/core/components/PRCurvePage/PRCurveChart.tsx
...end/packages/core/components/PRCurvePage/PRCurveChart.tsx
+204
-0
frontend/packages/core/components/PRCurvePage/StepSlider.tsx
frontend/packages/core/components/PRCurvePage/StepSlider.tsx
+92
-0
frontend/packages/core/components/RunAside.tsx
frontend/packages/core/components/RunAside.tsx
+1
-0
frontend/packages/core/components/ScalarsPage/ScalarChart.tsx
...tend/packages/core/components/ScalarsPage/ScalarChart.tsx
+22
-28
frontend/packages/core/components/TimeModeSelect.tsx
frontend/packages/core/components/TimeModeSelect.tsx
+41
-0
frontend/packages/core/components/TooltipTable.tsx
frontend/packages/core/components/TooltipTable.tsx
+99
-0
frontend/packages/core/hooks/useNavItems.ts
frontend/packages/core/hooks/useNavItems.ts
+26
-8
frontend/packages/core/package.json
frontend/packages/core/package.json
+5
-5
frontend/packages/core/pages/pr-curve.tsx
frontend/packages/core/pages/pr-curve.tsx
+161
-0
frontend/packages/core/pages/scalars.tsx
frontend/packages/core/pages/scalars.tsx
+4
-11
frontend/packages/core/public/locales/en/common.json
frontend/packages/core/public/locales/en/common.json
+6
-0
frontend/packages/core/public/locales/en/pr-curve.json
frontend/packages/core/public/locales/en/pr-curve.json
+10
-0
frontend/packages/core/public/locales/en/scalars.json
frontend/packages/core/public/locales/en/scalars.json
+1
-6
frontend/packages/core/public/locales/zh/common.json
frontend/packages/core/public/locales/zh/common.json
+6
-0
frontend/packages/core/public/locales/zh/pr-curve.json
frontend/packages/core/public/locales/zh/pr-curve.json
+10
-0
frontend/packages/core/public/locales/zh/scalars.json
frontend/packages/core/public/locales/zh/scalars.json
+1
-6
frontend/packages/core/resource/pr-curve/chart.ts
frontend/packages/core/resource/pr-curve/chart.ts
+17
-0
frontend/packages/core/resource/pr-curve/data.ts
frontend/packages/core/resource/pr-curve/data.ts
+16
-0
frontend/packages/core/resource/pr-curve/index.ts
frontend/packages/core/resource/pr-curve/index.ts
+3
-0
frontend/packages/core/resource/pr-curve/types.ts
frontend/packages/core/resource/pr-curve/types.ts
+38
-0
frontend/packages/core/resource/scalars/chart.ts
frontend/packages/core/resource/scalars/chart.ts
+33
-84
frontend/packages/core/resource/scalars/data.ts
frontend/packages/core/resource/scalars/data.ts
+1
-1
frontend/packages/core/resource/scalars/index.ts
frontend/packages/core/resource/scalars/index.ts
+11
-11
frontend/packages/core/resource/scalars/types.ts
frontend/packages/core/resource/scalars/types.ts
+9
-6
frontend/packages/core/types/index.ts
frontend/packages/core/types/index.ts
+8
-2
frontend/packages/i18n/package.json
frontend/packages/i18n/package.json
+2
-2
frontend/packages/mock/data/components.ts
frontend/packages/mock/data/components.ts
+1
-1
frontend/packages/mock/data/pr-curve/list.ts
frontend/packages/mock/data/pr-curve/list.ts
+6383
-0
frontend/packages/mock/data/pr-curve/steps.ts
frontend/packages/mock/data/pr-curve/steps.ts
+30
-0
frontend/packages/mock/data/pr-curve/tags.ts
frontend/packages/mock/data/pr-curve/tags.ts
+10
-0
frontend/packages/mock/package.json
frontend/packages/mock/package.json
+1
-1
frontend/packages/netron/package.json
frontend/packages/netron/package.json
+2
-2
frontend/packages/netron/src/view.js
frontend/packages/netron/src/view.js
+18
-22
frontend/packages/server/package.json
frontend/packages/server/package.json
+2
-2
frontend/packages/serverless/package.json
frontend/packages/serverless/package.json
+1
-1
frontend/yarn.lock
frontend/yarn.lock
+51
-39
未找到文件。
frontend/packages/cli/package.json
浏览文件 @
e698eda6
...
...
@@ -41,7 +41,7 @@
"yargs"
:
"15.3.1"
},
"devDependencies"
:
{
"@types/node"
:
"14.0.1
3
"
,
"@types/node"
:
"14.0.1
4
"
,
"@types/yargs"
:
"15.0.5"
,
"cross-env"
:
"7.0.2"
,
"ts-node"
:
"8.10.2"
,
...
...
frontend/packages/core/components/Field.tsx
浏览文件 @
e698eda6
...
...
@@ -14,7 +14,7 @@ const Label = styled.div`
`
;
type
FieldProps
=
{
label
?:
string
;
label
?:
string
|
JSX
.
Element
;
};
const
Field
:
FunctionComponent
<
FieldProps
&
WithStyled
>
=
({
label
,
children
,
className
})
=>
(
...
...
frontend/packages/core/components/HistogramPage/HistogramChart.tsx
浏览文件 @
e698eda6
...
...
@@ -55,7 +55,6 @@ type HistogramChartProps = {
tag
:
string
;
mode
:
Modes
;
running
?:
boolean
;
onToggleMaximized
?:
(
maximized
:
boolean
)
=>
void
;
};
const
HistogramChart
:
FunctionComponent
<
HistogramChartProps
>
=
({
cid
,
run
,
tag
,
mode
,
running
})
=>
{
...
...
frontend/packages/core/components/LineChart.tsx
浏览文件 @
e698eda6
...
...
@@ -18,6 +18,17 @@ type LineChartProps = {
zoom
?:
boolean
;
};
export
enum
XAxisType
{
value
=
'
value
'
,
log
=
'
log
'
,
time
=
'
time
'
}
export
enum
YAxisType
{
value
=
'
value
'
,
log
=
'
log
'
}
export
type
LineChartRef
=
{
restore
():
void
;
saveAsImage
():
void
;
...
...
frontend/packages/core/components/PRCurvePage/PRCurveChart.tsx
0 → 100644
浏览文件 @
e698eda6
import
LineChart
,
{
LineChartRef
}
from
'
~/components/LineChart
'
;
import
{
PRCurveData
,
Run
,
options
as
chartOptions
,
nearestPoint
}
from
'
~/resource/pr-curve
'
;
import
React
,
{
FunctionComponent
,
useCallback
,
useMemo
,
useRef
,
useState
}
from
'
react
'
;
import
{
rem
,
size
}
from
'
~/utils/style
'
;
import
ChartToolbox
from
'
~/components/ChartToolbox
'
;
import
{
EChartOption
}
from
'
echarts
'
;
import
TooltipTable
from
'
~/components/TooltipTable
'
;
import
{
cycleFetcher
}
from
'
~/utils/fetch
'
;
import
ee
from
'
~/utils/event
'
;
import
{
format
}
from
'
d3-format
'
;
import
queryString
from
'
query-string
'
;
import
{
renderToStaticMarkup
}
from
'
react-dom/server
'
;
import
styled
from
'
styled-components
'
;
import
{
useRunningRequest
}
from
'
~/hooks/useRequest
'
;
import
{
useTranslation
}
from
'
~/utils/i18n
'
;
import
zip
from
'
lodash/zip
'
;
const
axisFormatter
=
format
(
'
.4f
'
);
const
valueFormatter
=
format
(
'
.2f
'
);
const
Wrapper
=
styled
.
div
`
${
size
(
'
100%
'
,
'
100%
'
)}
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: space-between;
`
;
const
StyledLineChart
=
styled
(
LineChart
)
`
flex-grow: 1;
`
;
const
Toolbox
=
styled
(
ChartToolbox
)
`
margin-left:
${
rem
(
20
)}
;
margin-right:
${
rem
(
20
)}
;
margin-bottom:
${
rem
(
18
)}
;
`
;
const
Error
=
styled
.
div
`
${
size
(
'
100%
'
,
'
100%
'
)}
display: flex;
justify-content: center;
align-items: center;
`
;
type
PRCurveChartProps
=
{
cid
:
symbol
;
runs
:
Run
[];
tag
:
string
;
running
?:
boolean
;
};
const
PRCurveChart
:
FunctionComponent
<
PRCurveChartProps
>
=
({
cid
,
runs
,
tag
,
running
})
=>
{
const
{
t
}
=
useTranslation
([
'
pr-curve
'
,
'
common
'
]);
const
echart
=
useRef
<
LineChartRef
>
(
null
);
const
{
data
:
dataset
,
error
,
loading
}
=
useRunningRequest
<
PRCurveData
[]
>
(
runs
.
map
(
run
=>
`/pr-curve/list?
${
queryString
.
stringify
({
run
:
run
.
label
,
tag
})}
`
),
!!
running
,
(...
urls
)
=>
cycleFetcher
(
urls
)
);
const
[
maximized
,
setMaximized
]
=
useState
<
boolean
>
(
false
);
const
toggleMaximized
=
useCallback
(()
=>
{
ee
.
emit
(
'
toggle-chart-size
'
,
cid
,
!
maximized
);
setMaximized
(
m
=>
!
m
);
},
[
cid
,
maximized
]);
const
selectedData
=
useMemo
<
[
number
,
number
,
number
[][]][]
>
(
()
=>
runs
.
map
((
run
,
i
)
=>
{
const
[
wallTime
,
step
,
...
item
]
=
dataset
?.[
i
]?.
find
(
row
=>
row
[
1
]
===
run
.
steps
[
run
.
index
])
??
[
0
,
0
,
[],
[],
[],
[],
[],
[],
[]
];
return
[
wallTime
,
step
,
zip
(...
item
)
as
number
[][]];
}),
[
dataset
,
runs
]
);
const
data
=
useMemo
(
()
=>
selectedData
.
map
((
item
,
i
)
=>
{
const
run
=
runs
[
i
];
return
{
name
:
run
.
label
,
z
:
i
,
itemStyle
:
{
color
:
run
.
colors
[
0
]
},
lineStyle
:
{
color
:
run
.
colors
[
0
]
},
data
:
item
[
2
],
encode
:
{
x
:
[
1
],
y
:
[
0
]
}
};
}),
[
selectedData
,
runs
]
);
const
formatter
=
useCallback
(
(
params
:
EChartOption
.
Tooltip
.
Format
|
EChartOption
.
Tooltip
.
Format
[])
=>
{
const
series
=
Array
.
isArray
(
params
)
?
params
[
0
].
data
:
params
.
data
;
const
points
=
nearestPoint
(
selectedData
.
map
(
s
=>
s
[
2
]),
series
[
1
]
);
const
columns
=
[
{
label
:
t
(
'
pr-curve:threshold
'
)
},
{
label
:
t
(
'
pr-curve:precision
'
)
},
{
label
:
t
(
'
pr-curve:recall
'
)
},
{
label
:
t
(
'
pr-curve:true-positives
'
)
},
{
label
:
t
(
'
pr-curve:false-positives
'
)
},
{
label
:
t
(
'
pr-curve:true-negatives
'
)
},
{
label
:
t
(
'
pr-curve:false-negatives
'
)
}
];
const
data
=
points
.
map
(([
precision
,
recall
,
tp
,
fp
,
tn
,
fn
,
threshold
])
=>
[
valueFormatter
(
threshold
),
axisFormatter
(
precision
),
axisFormatter
(
recall
),
tp
,
fp
,
tn
,
fn
]);
return
renderToStaticMarkup
(
<
TooltipTable
run
=
{
t
(
'
common:runs
'
)
}
runs
=
{
runs
}
columns
=
{
columns
}
data
=
{
data
}
/>
);
},
[
selectedData
,
runs
,
t
]
);
const
options
=
useMemo
(
()
=>
({
...
chartOptions
,
tooltip
:
{
...
chartOptions
.
tooltip
,
formatter
}
}),
[
formatter
]
);
// display error only on first fetch
if
(
!
data
&&
error
)
{
return
<
Error
>
{
t
(
'
common:error
'
)
}
</
Error
>;
}
return
(
<
Wrapper
>
<
StyledLineChart
ref
=
{
echart
}
title
=
{
tag
}
options
=
{
options
}
data
=
{
data
}
loading
=
{
loading
}
zoom
/>
<
Toolbox
items
=
{
[
{
icon
:
'
maximize
'
,
activeIcon
:
'
minimize
'
,
tooltip
:
t
(
'
scalars:maximize
'
),
activeTooltip
:
t
(
'
scalars:minimize
'
),
toggle
:
true
,
onClick
:
toggleMaximized
},
{
icon
:
'
restore-size
'
,
tooltip
:
t
(
'
scalars:restore
'
),
onClick
:
()
=>
echart
.
current
?.
restore
()
},
{
icon
:
'
download
'
,
tooltip
:
t
(
'
scalars:download-image
'
),
onClick
:
()
=>
echart
.
current
?.
saveAsImage
()
}
]
}
/>
</
Wrapper
>
);
};
export
default
PRCurveChart
;
frontend/packages/core/components/PRCurvePage/StepSlider.tsx
0 → 100644
浏览文件 @
e698eda6
import
React
,
{
FunctionComponent
,
useEffect
,
useState
}
from
'
react
'
;
import
{
Run
,
TimeType
}
from
'
~/resource/pr-curve
'
;
import
{
ellipsis
,
size
,
textLighterColor
}
from
'
~/utils/style
'
;
import
Field
from
'
~/components/Field
'
;
import
RangeSlider
from
'
~/components/RangeSlider
'
;
import
{
format
}
from
'
d3-format
'
;
import
{
formatTime
}
from
'
~/utils
'
;
import
styled
from
'
styled-components
'
;
import
{
useTranslation
}
from
'
~/utils/i18n
'
;
const
relativeFormatter
=
format
(
'
.2f
'
);
const
TimeDisplay
=
styled
.
div
`
color:
${
textLighterColor
}
;
font-size: 0.857142857em;
padding-left: 1.666666667em;
margin-bottom: 0.416666667em;
`
;
const
Label
=
styled
.
span
<
{
color
:
string
}
>
`
display: inline-block;
padding-left: 1.428571429em;
position: relative;
${
ellipsis
()}
&::before {
content: '';
display: block;
${
size
(
'
0.857142857em
'
,
'
0.857142857em
'
)}
background-color:
${
props
=>
props
.
color
}
;
border-radius: 50%;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}
`
;
const
FullWidthRangeSlider
=
styled
(
RangeSlider
)
`
width: 100%;
`
;
const
typeMap
=
{
[
TimeType
.
WallTime
]:
'
wallTimes
'
,
[
TimeType
.
Relative
]:
'
relatives
'
,
[
TimeType
.
Step
]:
'
steps
'
}
as
const
;
const
formatter
=
{
[
TimeType
.
WallTime
]:
(
wallTime
:
number
,
{
i18n
}:
ReturnType
<
typeof
useTranslation
>
)
=>
formatTime
(
wallTime
,
i18n
.
language
),
[
TimeType
.
Relative
]:
(
relative
:
number
)
=>
`
${
relativeFormatter
(
relative
)}
ms`
,
[
TimeType
.
Step
]:
(
step
:
number
,
{
t
}:
ReturnType
<
typeof
useTranslation
>
)
=>
`
${
t
(
'
common:time-mode.step
'
)}
${
step
}
`
}
as
const
;
type
StepSliderProps
=
{
run
:
Run
;
type
:
TimeType
;
onChange
?:
(
step
:
number
)
=>
unknown
;
};
const
StepSlider
:
FunctionComponent
<
StepSliderProps
>
=
({
onChange
,
run
,
type
})
=>
{
const
translation
=
useTranslation
(
'
common
'
);
const
[
index
,
setIndex
]
=
useState
(
run
.
index
);
useEffect
(()
=>
setIndex
(
run
.
index
),
[
run
.
index
]);
return
(
<
Field
label
=
{
<
Label
color
=
{
run
.
colors
[
0
]
}
title
=
{
run
.
label
}
>
{
run
.
label
}
</
Label
>
}
>
<
TimeDisplay
>
{
run
[
typeMap
[
type
]][
index
]
==
null
?
'
...
'
:
formatter
[
type
](
run
[
typeMap
[
type
]][
index
],
translation
)
}
</
TimeDisplay
>
<
FullWidthRangeSlider
min
=
{
0
}
max
=
{
run
.
steps
.
length
?
run
.
steps
.
length
-
1
:
0
}
step
=
{
1
}
value
=
{
index
}
onChange
=
{
setIndex
}
onChangeComplete
=
{
()
=>
onChange
?.(
index
)
}
/>
</
Field
>
);
};
export
default
StepSlider
;
frontend/packages/core/components/RunAside.tsx
浏览文件 @
e698eda6
...
...
@@ -18,6 +18,7 @@ const StyledAside = styled(Aside)`
overflow-y: auto;
display: flex;
flex-direction: column;
margin-bottom: 0;
.run-select {
flex: auto;
...
...
frontend/packages/core/components/ScalarsPage/ScalarChart.tsx
浏览文件 @
e698eda6
import
LineChart
,
{
LineChartRef
}
from
'
~/components/LineChart
'
;
import
{
Dataset
,
Range
,
ScalarDataset
,
SortingMethod
,
...
...
@@ -14,21 +14,26 @@ import {
transform
,
xAxisMap
}
from
'
~/resource/scalars
'
;
import
LineChart
,
{
LineChartRef
,
XAxisType
,
YAxisType
}
from
'
~/components/LineChart
'
;
import
React
,
{
FunctionComponent
,
useCallback
,
useMemo
,
useRef
,
useState
}
from
'
react
'
;
import
{
rem
,
size
}
from
'
~/utils/style
'
;
import
ChartToolbox
from
'
~/components/ChartToolbox
'
;
import
{
EChartOption
}
from
'
echarts
'
;
import
{
Run
}
from
'
~/types
'
;
import
TooltipTable
from
'
~/components/TooltipTable
'
;
import
{
cycleFetcher
}
from
'
~/utils/fetch
'
;
import
ee
from
'
~/utils/event
'
;
import
{
format
}
from
'
d3-format
'
;
import
queryString
from
'
query-string
'
;
import
{
renderToStaticMarkup
}
from
'
react-dom/server
'
;
import
styled
from
'
styled-components
'
;
import
useHeavyWork
from
'
~/hooks/useHeavyWork
'
;
import
{
useRunningRequest
}
from
'
~/hooks/useRequest
'
;
import
{
useTranslation
}
from
'
~/utils/i18n
'
;
const
labelFormatter
=
format
(
'
.8
'
);
const
smoothWasm
=
()
=>
import
(
'
@visualdl/wasm
'
).
then
(({
scalar_transform
}):
typeof
transform
=>
params
=>
scalar_transform
(
params
.
datasets
,
params
.
smoothing
)
...
...
@@ -47,14 +52,6 @@ const Wrapper = styled.div`
flex-direction: column;
align-items: stretch;
justify-content: space-between;
.echarts td.run .run-indicator {
${
size
(
12
,
12
)}
display: inline-block;
border-radius: 6px;
vertical-align: middle;
margin-right: 5px;
}
`
;
const
StyledLineChart
=
styled
(
LineChart
)
`
...
...
@@ -74,17 +71,6 @@ const Error = styled.div`
align-items: center;
`
;
enum
XAxisType
{
value
=
'
value
'
,
log
=
'
log
'
,
time
=
'
time
'
}
enum
YAxisType
{
value
=
'
value
'
,
log
=
'
log
'
}
type
ScalarChartProps
=
{
cid
:
symbol
;
runs
:
Run
[];
...
...
@@ -94,7 +80,6 @@ type ScalarChartProps = {
sortingMethod
:
SortingMethod
;
outlier
?:
boolean
;
running
?:
boolean
;
onToggleMaximized
?:
(
maximized
:
boolean
)
=>
void
;
};
const
ScalarChart
:
FunctionComponent
<
ScalarChartProps
>
=
({
...
...
@@ -123,7 +108,7 @@ const ScalarChart: FunctionComponent<ScalarChartProps> = ({
setMaximized
(
m
=>
!
m
);
},
[
cid
,
maximized
]);
const
xAxisType
=
useMemo
(()
=>
(
xAxis
===
'
wall
'
?
XAxisType
.
time
:
XAxisType
.
value
),
[
xAxis
]);
const
xAxisType
=
useMemo
(()
=>
(
xAxis
===
XAxis
.
WallTime
?
XAxisType
.
time
:
XAxisType
.
value
),
[
xAxis
]);
const
[
yAxisType
,
setYAxisType
]
=
useState
<
YAxisType
>
(
YAxisType
.
value
);
const
toggleYAxisType
=
useCallback
(()
=>
{
...
...
@@ -179,13 +164,20 @@ const ScalarChart: FunctionComponent<ScalarChartProps> = ({
const
formatter
=
useCallback
(
(
params
:
EChartOption
.
Tooltip
.
Format
|
EChartOption
.
Tooltip
.
Format
[])
=>
{
const
data
=
Array
.
isArray
(
params
)
?
params
[
0
].
data
:
params
.
data
;
const
step
=
data
[
1
];
const
points
=
nearestPoint
(
smoothedDatasets
??
[],
runs
,
step
);
const
series
:
Dataset
[
number
]
=
Array
.
isArray
(
params
)
?
params
[
0
].
data
:
params
.
data
;
const
points
=
nearestPoint
(
smoothedDatasets
??
[],
runs
,
series
[
1
]);
const
sort
=
sortingMethodMap
[
sortingMethod
];
return
tooltip
(
sort
?
sort
(
points
,
data
)
:
points
,
maxStepLength
,
i18n
);
const
sorted
=
sort
(
points
,
series
);
const
{
columns
,
data
}
=
tooltip
(
sorted
.
map
(
i
=>
i
.
item
),
maxStepLength
,
i18n
);
return
renderToStaticMarkup
(
<
TooltipTable
run
=
{
t
(
'
common:runs
'
)
}
runs
=
{
sorted
.
map
(
i
=>
i
.
run
)
}
columns
=
{
columns
}
data
=
{
data
}
/>
);
},
[
smoothedDatasets
,
runs
,
sortingMethod
,
maxStepLength
,
i18n
]
[
smoothedDatasets
,
runs
,
sortingMethod
,
maxStepLength
,
t
,
i18n
]
);
const
options
=
useMemo
(
...
...
@@ -201,7 +193,9 @@ const ScalarChart: FunctionComponent<ScalarChartProps> = ({
axisPointer
:
{
label
:
{
formatter
:
xAxisType
===
XAxisType
.
time
?
undefined
:
({
value
}:
{
value
:
number
})
=>
format
(
'
.8
'
)(
value
)
xAxisType
===
XAxisType
.
time
?
undefined
:
({
value
}:
{
value
:
number
})
=>
labelFormatter
(
value
)
}
}
},
...
...
frontend/packages/core/components/TimeModeSelect.tsx
0 → 100644
浏览文件 @
e698eda6
import
React
,
{
FunctionComponent
,
useCallback
,
useEffect
,
useState
}
from
'
react
'
;
import
RadioButton
from
'
~/components/RadioButton
'
;
import
RadioGroup
from
'
~/components/RadioGroup
'
;
import
{
TimeMode
}
from
'
~/types
'
;
import
{
useTranslation
}
from
'
~/utils/i18n
'
;
const
timeModes
=
[
TimeMode
.
Step
,
TimeMode
.
Relative
,
TimeMode
.
WallTime
]
as
const
;
type
TimeModeSelectProps
=
{
value
:
TimeMode
;
onChange
?:
(
value
:
TimeMode
)
=>
unknown
;
};
const
TimeModeSelect
:
FunctionComponent
<
TimeModeSelectProps
>
=
({
value
,
onChange
})
=>
{
const
{
t
}
=
useTranslation
(
'
common
'
);
const
[
timeMode
,
setTimeMode
]
=
useState
(
value
);
useEffect
(()
=>
setTimeMode
(
value
),
[
value
]);
const
change
=
useCallback
(
(
v
:
TimeMode
)
=>
{
setTimeMode
(
v
);
onChange
?.(
v
);
},
[
onChange
]
);
return
(
<
RadioGroup
value
=
{
timeMode
}
onChange
=
{
change
}
>
{
timeModes
.
map
(
value
=>
(
<
RadioButton
key
=
{
value
}
value
=
{
value
}
>
{
t
(
`common:time-mode.
${
value
}
`
)
}
</
RadioButton
>
))
}
</
RadioGroup
>
);
};
export
default
TimeModeSelect
;
frontend/packages/core/components/TooltipTable.tsx
0 → 100644
浏览文件 @
e698eda6
import
React
,
{
FunctionComponent
}
from
'
react
'
;
import
{
rem
,
size
}
from
'
~/utils/style
'
;
import
{
Run
}
from
'
~/types
'
;
import
styled
from
'
styled-components
'
;
const
Wrapper
=
styled
.
div
`
table {
border-spacing: none;
text-align: left;
table-layout: fixed;
font-size:
${
rem
(
12
)}
;
th,
td {
margin: 0;
> span {
display: inline-block;
}
}
th {
font-size: 1.166666667em;
font-weight: bold;
padding: 0 0.285714286em;
&.run > span {
min-width: 4.285714286em;
max-width: 12.857142857em;
}
}
td {
padding: 0 0.333333333em;
&.run-indicator > span {
${
size
(
12
,
12
)}
border-radius: 6px;
vertical-align: middle;
background-color: currentColor;
}
}
}
`
;
type
TooltipTableProps
=
{
run
:
string
;
runs
:
Run
[];
columns
:
{
label
:
string
;
width
?:
string
;
}[];
data
?:
(
string
|
number
)[][];
};
const
TooltipTable
:
FunctionComponent
<
TooltipTableProps
>
=
({
run
,
runs
,
columns
,
data
})
=>
{
// CANNOT use translation here
// because we use `ReactDOMServer.renderToStaticMarkup` to render this component into echarts tooltip
// `ReactDOMServer.renderToStaticMarkup` WILL NOT call hydrate so translation will never be initialized
// const {t} = useTranslation('common');
return
(
<
Wrapper
>
<
table
>
<
thead
>
<
tr
>
<
th
className
=
"run-indicator"
></
th
>
<
th
className
=
"run"
>
{
run
}
</
th
>
{
columns
.
map
((
column
,
i
)
=>
(
<
th
key
=
{
i
}
>
<
span
style
=
{
{
width
:
column
.
width
??
'
auto
'
}
}
>
{
column
.
label
}
</
span
>
</
th
>
))
}
</
tr
>
</
thead
>
<
tbody
>
{
data
?.
map
((
row
,
j
)
=>
(
<
tr
key
=
{
j
}
>
<
td
className
=
"run-indicator"
>
<
span
style
=
{
{
color
:
runs
[
j
]?.
colors
[
0
]}
}
></
span
>
</
td
>
<
td
className
=
"run"
>
<
span
>
{
runs
[
j
]?.
label
}
</
span
>
</
td
>
{
row
.
map
((
cell
,
k
)
=>
(
<
td
key
=
{
k
}
>
<
span
>
{
cell
}
</
span
>
</
td
>
))
}
</
tr
>
))
}
</
tbody
>
</
table
>
</
Wrapper
>
);
};
export
default
TooltipTable
;
frontend/packages/core/hooks/useNavItems.ts
浏览文件 @
e698eda6
...
...
@@ -5,17 +5,35 @@ import {fetcher} from '~/utils/fetch';
import
intersection
from
'
lodash/intersection
'
;
import
useRequest
from
'
~/hooks/useRequest
'
;
const
allNavItems
=
[
'
scalars
'
,
'
histogram
'
,
'
samples
'
,
'
graphs
'
,
'
high-dimensional
'
];
enum
Pages
{
Scalars
=
'
scalars
'
,
Histogram
=
'
histogram
'
,
Samples
=
'
samples
'
,
Graphs
=
'
graphs
'
,
HighDimensional
=
'
high-dimensional
'
,
PRCurve
=
'
pr-curve
'
}
const
pages
=
[
Pages
.
Scalars
,
Pages
.
Histogram
,
Pages
.
Samples
,
Pages
.
Graphs
,
Pages
.
HighDimensional
,
Pages
.
PRCurve
]
as
const
;
export
const
navMap
=
{
scalar
:
'
scalars
'
,
histogram
:
'
histogram
'
,
image
:
'
samples
'
,
graph
:
'
graphs
'
,
embeddings
:
'
high-dimensional
'
scalar
:
Pages
.
Scalars
,
histogram
:
Pages
.
Histogram
,
image
:
Pages
.
Samples
,
graph
:
Pages
.
Graphs
,
embeddings
:
Pages
.
HighDimensional
,
'
pr-curve
'
:
Pages
.
PRCurve
}
as
const
;
const
useNavItems
=
()
=>
{
const
[
components
,
setComponents
]
=
useState
<
string
[]
>
([]);
const
[
components
,
setComponents
]
=
useState
<
Pages
[]
>
([]);
const
{
data
,
mutate
}
=
useRequest
<
(
keyof
typeof
navMap
)[]
>
(
'
/components
'
,
fetcher
,
{
refreshInterval
:
components
.
length
?
61
*
1000
:
15
*
1000
,
...
...
@@ -36,7 +54,7 @@ const useNavItems = () => {
},
[
mutate
]);
useEffect
(()
=>
{
setComponents
(
intersection
(
allNavItem
s
,
data
?.
map
(
component
=>
navMap
[
component
])
??
[]));
setComponents
(
intersection
(
page
s
,
data
?.
map
(
component
=>
navMap
[
component
])
??
[]));
},
[
data
]);
return
components
;
...
...
frontend/packages/core/package.json
浏览文件 @
e698eda6
...
...
@@ -32,7 +32,7 @@
"test"
:
"echo
\"
Error: no test specified
\"
&& exit 0"
},
"dependencies"
:
{
"@tippyjs/react"
:
"4.0.
4
"
,
"@tippyjs/react"
:
"4.0.
5
"
,
"@visualdl/i18n"
:
"2.0.0-beta.43"
,
"@visualdl/netron"
:
"2.0.0-beta.43"
,
"@visualdl/wasm"
:
"2.0.0-beta.43"
,
...
...
@@ -65,13 +65,13 @@
"devDependencies"
:
{
"@babel/core"
:
"7.10.3"
,
"@types/d3-format"
:
"1.3.1"
,
"@types/echarts"
:
"4.6.
2
"
,
"@types/echarts"
:
"4.6.
3
"
,
"@types/file-saver"
:
"2.0.1"
,
"@types/lodash"
:
"4.14.15
6
"
,
"@types/lodash"
:
"4.14.15
7
"
,
"@types/mime-types"
:
"2.1.0"
,
"@types/node"
:
"14.0.1
3
"
,
"@types/node"
:
"14.0.1
4
"
,
"@types/nprogress"
:
"0.2.0"
,
"@types/react"
:
"16.9.
38
"
,
"@types/react"
:
"16.9.
41
"
,
"@types/react-dom"
:
"16.9.8"
,
"@types/styled-components"
:
"5.1.0"
,
"@visualdl/mock"
:
"2.0.0-beta.43"
,
...
...
frontend/packages/core/pages/pr-curve.tsx
0 → 100644
浏览文件 @
e698eda6
import
ChartPage
,
{
WithChart
}
from
'
~/components/ChartPage
'
;
import
{
NextI18NextPage
,
useTranslation
}
from
'
~/utils/i18n
'
;
import
React
,
{
useCallback
,
useEffect
,
useMemo
,
useState
}
from
'
react
'
;
import
{
Run
,
StepInfo
,
Tag
,
TimeType
}
from
'
~/resource/pr-curve
'
;
import
{
borderColor
,
rem
}
from
'
~/utils/style
'
;
import
{
AsideSection
}
from
'
~/components/Aside
'
;
import
Content
from
'
~/components/Content
'
;
import
Error
from
'
~/components/Error
'
;
import
Field
from
'
~/components/Field
'
;
import
PRCurveChart
from
'
~/components/PRCurvePage/PRCurveChart
'
;
import
Preloader
from
'
~/components/Preloader
'
;
import
RunAside
from
'
~/components/RunAside
'
;
import
StepSlider
from
'
~/components/PRCurvePage/StepSlider
'
;
import
TimeModeSelect
from
'
~/components/TimeModeSelect
'
;
import
Title
from
'
~/components/Title
'
;
import
{
cycleFetcher
}
from
'
~/utils/fetch
'
;
import
queryString
from
'
query-string
'
;
import
styled
from
'
styled-components
'
;
import
{
useRunningRequest
}
from
'
~/hooks/useRequest
'
;
import
useTagFilter
from
'
~/hooks/useTagFilter
'
;
const
StepSliderWrapper
=
styled
.
div
`
max-height: 30vh;
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
>
${
AsideSection
}
:last-child {
padding-bottom:
${
rem
(
20
)}
;
margin-bottom: 0;
}
+ .run-section {
border-top: 1px solid
${
borderColor
}
;
margin-top: 0;
padding-top:
${
rem
(
20
)}
;
}
`
;
const
PRCurve
:
NextI18NextPage
=
()
=>
{
const
{
t
}
=
useTranslation
([
'
pr-curve
'
,
'
common
'
]);
const
[
running
,
setRunning
]
=
useState
(
true
);
const
{
runs
,
tags
,
selectedRuns
,
onChangeRuns
,
loadingRuns
,
loadingTags
}
=
useTagFilter
(
'
pr-curve
'
,
running
);
const
[
indexes
,
setIndexes
]
=
useState
<
Record
<
string
,
number
>>
({});
const
onChangeIndexes
=
useCallback
(
(
run
:
string
,
index
:
number
)
=>
setIndexes
(
indexes
=>
({
...
indexes
,
[
run
]:
index
})),
[]
);
useEffect
(
()
=>
setIndexes
(
indexes
=>
selectedRuns
.
reduce
<
typeof
indexes
>
((
m
,
c
)
=>
{
if
(
indexes
[
c
.
label
]
!=
null
)
{
m
[
c
.
label
]
=
indexes
[
c
.
label
];
}
return
m
;
},
{})
),
[
selectedRuns
]
);
const
{
data
:
stepInfo
}
=
useRunningRequest
<
StepInfo
[]
>
(
selectedRuns
.
map
(
run
=>
`/pr-curve/steps?
${
queryString
.
stringify
({
run
:
run
.
label
})}
`
),
!!
running
,
(...
urls
)
=>
cycleFetcher
(
urls
)
);
const
runWithInfo
=
useMemo
<
Run
[]
>
(
()
=>
selectedRuns
.
map
((
run
,
i
)
=>
({
...
run
,
index
:
indexes
[
run
.
label
]
??
(
stepInfo
?.[
i
].
length
??
1
)
-
1
,
steps
:
stepInfo
?.[
i
].
map
(
j
=>
j
[
1
])
??
[],
wallTimes
:
stepInfo
?.[
i
].
map
(
j
=>
Math
.
floor
(
j
[
0
]
*
1000
))
??
[],
relatives
:
stepInfo
?.[
i
].
map
(
j
=>
(
j
[
0
]
-
stepInfo
[
i
][
0
][
0
])
*
1000
)
??
[]
})),
[
selectedRuns
,
stepInfo
,
indexes
]
);
const
[
timeType
,
setTimeType
]
=
useState
<
TimeType
>
(
TimeType
.
Step
);
const
prCurveTags
=
useMemo
<
Tag
[]
>
(
()
=>
tags
.
map
(
tag
=>
({
...
tag
,
runs
:
tag
.
runs
.
map
(
run
=>
({
...
run
,
index
:
0
,
steps
:
[]
as
Run
[
'
steps
'
],
wallTimes
:
[]
as
Run
[
'
wallTimes
'
],
relatives
:
[]
as
Run
[
'
relatives
'
],
...
runWithInfo
.
find
(
r
=>
r
.
label
===
run
.
label
)
}))
})),
[
tags
,
runWithInfo
]
);
const
aside
=
useMemo
(
()
=>
runs
.
length
?
(
<
RunAside
runs
=
{
runs
}
selectedRuns
=
{
selectedRuns
}
onChangeRuns
=
{
onChangeRuns
}
running
=
{
running
}
onToggleRunning
=
{
setRunning
}
>
<
AsideSection
>
<
Field
label
=
{
t
(
'
pr-curve:time-display-type
'
)
}
>
<
TimeModeSelect
value
=
{
timeType
}
onChange
=
{
setTimeType
}
/>
</
Field
>
</
AsideSection
>
<
StepSliderWrapper
>
{
runWithInfo
.
map
(
run
=>
(
<
AsideSection
key
=
{
run
.
label
}
>
<
StepSlider
run
=
{
run
}
type
=
{
timeType
}
onChange
=
{
index
=>
onChangeIndexes
(
run
.
label
,
index
)
}
/>
</
AsideSection
>
))
}
</
StepSliderWrapper
>
</
RunAside
>
)
:
null
,
[
t
,
onChangeRuns
,
running
,
runs
,
selectedRuns
,
timeType
,
runWithInfo
,
onChangeIndexes
]
);
const
withChart
=
useCallback
<
WithChart
<
Tag
>>
(
({
label
,
runs
,
...
args
})
=>
<
PRCurveChart
runs
=
{
runs
}
tag
=
{
label
}
{
...
args
}
running
=
{
running
}
/>,
[
running
]
);
return
(
<>
<
Preloader
url
=
"/runs"
/>
<
Preloader
url
=
"/scalars/tags"
/>
<
Title
>
{
t
(
'
common:pr-curve
'
)
}
</
Title
>
<
Content
aside
=
{
aside
}
loading
=
{
loadingRuns
}
>
{
!
loadingRuns
&&
!
runs
.
length
?
(
<
Error
/>
)
:
(
<
ChartPage
items
=
{
prCurveTags
}
withChart
=
{
withChart
}
loading
=
{
loadingRuns
||
loadingTags
}
/>
)
}
</
Content
>
</>
);
};
PRCurve
.
getInitialProps
=
()
=>
({
namespacesRequired
:
[
'
pr-curve
'
,
'
common
'
]
});
export
default
PRCurve
;
frontend/packages/core/pages/scalars.tsx
浏览文件 @
e698eda6
import
ChartPage
,
{
WithChart
}
from
'
~/components/ChartPage
'
;
import
{
NextI18NextPage
,
useTranslation
}
from
'
~/utils/i18n
'
;
import
React
,
{
useCallback
,
useMemo
,
useState
}
from
'
react
'
;
import
{
SortingMethod
,
XAxis
,
sortingMethod
as
toolTipSortingValues
,
xAxis
as
xAxisValues
}
from
'
~/resource/scalars
'
;
import
{
SortingMethod
,
XAxis
,
sortingMethod
as
toolTipSortingValues
}
from
'
~/resource/scalars
'
;
import
{
AsideSection
}
from
'
~/components/Aside
'
;
import
Checkbox
from
'
~/components/Checkbox
'
;
...
...
@@ -9,13 +9,12 @@ import Content from '~/components/Content';
import
Error
from
'
~/components/Error
'
;
import
Field
from
'
~/components/Field
'
;
import
Preloader
from
'
~/components/Preloader
'
;
import
RadioButton
from
'
~/components/RadioButton
'
;
import
RadioGroup
from
'
~/components/RadioGroup
'
;
import
RunAside
from
'
~/components/RunAside
'
;
import
ScalarChart
from
'
~/components/ScalarsPage/ScalarChart
'
;
import
Select
from
'
~/components/Select
'
;
import
Slider
from
'
~/components/Slider
'
;
import
{
Tag
}
from
'
~/types
'
;
import
TimeModeSelect
from
'
~/components/TimeModeSelect
'
;
import
Title
from
'
~/components/Title
'
;
import
{
rem
}
from
'
~/utils/style
'
;
import
styled
from
'
styled-components
'
;
...
...
@@ -42,7 +41,7 @@ const Scalars: NextI18NextPage = () => {
const
[
smoothing
,
setSmoothing
]
=
useState
(
0.6
);
const
[
xAxis
,
setXAxis
]
=
useState
<
XAxis
>
(
xAxisValues
[
0
]
);
const
[
xAxis
,
setXAxis
]
=
useState
<
XAxis
>
(
XAxis
.
Step
);
const
[
tooltipSorting
,
setTooltipSorting
]
=
useState
<
SortingMethod
>
(
toolTipSortingValues
[
0
]);
...
...
@@ -81,13 +80,7 @@ const Scalars: NextI18NextPage = () => {
</
AsideSection
>
<
AsideSection
>
<
Field
label
=
{
t
(
'
scalars:x-axis
'
)
}
>
<
RadioGroup
value
=
{
xAxis
}
onChange
=
{
setXAxis
}
>
{
xAxisValues
.
map
(
value
=>
(
<
RadioButton
key
=
{
value
}
value
=
{
value
}
>
{
t
(
`scalars:x-axis-value.
${
value
}
`
)
}
</
RadioButton
>
))
}
</
RadioGroup
>
<
TimeModeSelect
value
=
{
xAxis
}
onChange
=
{
setXAxis
}
/>
</
Field
>
</
AsideSection
>
</
RunAside
>
...
...
frontend/packages/core/public/locales/en/common.json
浏览文件 @
e698eda6
...
...
@@ -9,6 +9,7 @@
"histogram"
:
"Histogram"
,
"loading"
:
"Please wait while loading data"
,
"next-page"
:
"Next Page"
,
"pr-curve"
:
"PR-Curve"
,
"previous-page"
:
"Prev Page"
,
"run"
:
"Run"
,
"running"
:
"Running"
,
...
...
@@ -27,6 +28,11 @@
"stop"
:
"Stop"
,
"stop-realtime-refresh"
:
"Stop realtime refresh"
,
"stopped"
:
"Stopped"
,
"time-mode"
:
{
"relative"
:
"Relative"
,
"step"
:
"Step"
,
"wall"
:
"Wall Time"
},
"total-page"
:
"{{count}} page, jump to"
,
"total-page_plural"
:
"{{count}} pages, jump to"
,
"unselected-empty"
:
"Nothing selected. <1/>Please select display data from right side."
...
...
frontend/packages/core/public/locales/en/pr-curve.json
0 → 100644
浏览文件 @
e698eda6
{
"false-negatives"
:
"FN"
,
"false-positives"
:
"FP"
,
"precision"
:
"Precision"
,
"recall"
:
"Recall"
,
"threshold"
:
"Threshold"
,
"time-display-type"
:
"Time Display Type"
,
"true-negatives"
:
"TN"
,
"true-positives"
:
"TP"
}
frontend/packages/core/public/locales/en/scalars.json
浏览文件 @
e698eda6
...
...
@@ -15,10 +15,5 @@
"nearest"
:
"Nearest"
},
"value"
:
"Value"
,
"x-axis"
:
"X-Axis"
,
"x-axis-value"
:
{
"relative"
:
"Relative"
,
"step"
:
"Step"
,
"wall"
:
"Wall Time"
}
"x-axis"
:
"X-Axis"
}
frontend/packages/core/public/locales/zh/common.json
浏览文件 @
e698eda6
...
...
@@ -9,6 +9,7 @@
"histogram"
:
"直方图"
,
"loading"
:
"数据载入中,请稍等"
,
"next-page"
:
"下一页"
,
"pr-curve"
:
"PR曲线"
,
"previous-page"
:
"上一页"
,
"run"
:
"运行"
,
"running"
:
"运行中"
,
...
...
@@ -27,6 +28,11 @@
"stop"
:
"停止"
,
"stop-realtime-refresh"
:
"停止实时数据刷新"
,
"stopped"
:
"已停止"
,
"time-mode"
:
{
"relative"
:
"Relative"
,
"step"
:
"Step"
,
"wall"
:
"Wall Time"
},
"total-page"
:
"共 {{count}} 页,跳转至"
,
"total-page_plural"
:
"共 {{count}} 页,跳转至"
,
"unselected-empty"
:
"未选中任何数据<1/>请在右侧操作栏选择要展示的数据"
...
...
frontend/packages/core/public/locales/zh/pr-curve.json
0 → 100644
浏览文件 @
e698eda6
{
"false-negatives"
:
"FN"
,
"false-positives"
:
"FP"
,
"precision"
:
"Precision"
,
"recall"
:
"Recall"
,
"threshold"
:
"Threshold"
,
"time-display-type"
:
"时间显示类型"
,
"true-negatives"
:
"TN"
,
"true-positives"
:
"TP"
}
frontend/packages/core/public/locales/zh/scalars.json
浏览文件 @
e698eda6
...
...
@@ -15,10 +15,5 @@
"nearest"
:
"最近"
},
"value"
:
"Value"
,
"x-axis"
:
"X轴"
,
"x-axis-value"
:
{
"relative"
:
"Relative"
,
"step"
:
"Step"
,
"wall"
:
"Wall Time"
}
"x-axis"
:
"X轴"
}
frontend/packages/core/resource/pr-curve/chart.ts
0 → 100644
浏览文件 @
e698eda6
export
const
options
=
{
legend
:
{
data
:
[]
},
tooltip
:
{
position
:
[
'
10%
'
,
'
100%
'
]
},
xAxis
:
{
min
:
0
,
max
:
1
},
yAxis
:
{
min
:
0
,
max
:
1
,
splitNumber
:
5
}
};
frontend/packages/core/resource/pr-curve/data.ts
0 → 100644
浏览文件 @
e698eda6
export
const
nearestPoint
=
(
data
:
number
[][][],
recall
:
number
):
number
[][]
=>
{
return
data
.
map
(
series
=>
{
let
delta
=
Number
.
POSITIVE_INFINITY
;
let
index
=
0
;
for
(
let
i
=
0
;
i
<
series
.
length
;
i
++
)
{
if
(
series
[
i
][
1
]
-
recall
<
Number
.
EPSILON
)
{
return
series
[
i
];
}
if
(
Math
.
abs
(
series
[
i
][
1
]
-
recall
)
<
delta
)
{
delta
=
Math
.
abs
(
series
[
i
][
1
]
-
recall
);
index
=
i
;
}
}
return
series
[
index
];
});
};
frontend/packages/core/resource/pr-curve/index.ts
0 → 100644
浏览文件 @
e698eda6
export
*
from
'
./types
'
;
export
*
from
'
./chart
'
;
export
*
from
'
./data
'
;
frontend/packages/core/resource/pr-curve/types.ts
0 → 100644
浏览文件 @
e698eda6
import
{
Run
as
BaseRun
,
Tag
as
BaseTag
,
TimeMode
}
from
'
~/types
'
;
export
{
TimeMode
as
TimeType
};
type
Step
=
number
;
type
WallTime
=
number
;
type
Relative
=
number
;
type
Precision
=
number
;
type
Recall
=
number
;
type
TruePositives
=
number
;
type
FalsePositives
=
number
;
type
TrueNegatives
=
number
;
type
FalseNegatives
=
number
;
type
Thresholds
=
number
;
export
type
PRCurveDataItem
=
[
WallTime
,
Step
,
Precision
[],
Recall
[],
TruePositives
[],
FalsePositives
[],
TrueNegatives
[],
FalseNegatives
[],
Thresholds
[]
];
export
type
PRCurveData
=
PRCurveDataItem
[];
export
interface
Run
extends
BaseRun
{
index
:
number
;
steps
:
Step
[];
wallTimes
:
WallTime
[];
relatives
:
Relative
[];
}
export
type
Tag
=
BaseTag
<
Run
>
;
export
type
StepInfo
=
[
WallTime
,
Step
][];
frontend/packages/core/resource/scalars/chart.ts
浏览文件 @
e698eda6
import
{
Dataset
,
TooltipData
,
XAxis
}
from
'
./types
'
;
import
{
Dataset
,
XAxis
}
from
'
./types
'
;
import
{
I18n
}
from
'
@visualdl/i18n
'
;
import
{
Run
}
from
'
~/types
'
;
...
...
@@ -64,87 +64,36 @@ export const chartData = ({data, runs, xAxis}: {data: Dataset[]; runs: Run[]; xA
})
.
flat
();
// TODO: make it better, don't concat html
export
const
tooltip
=
(
data
:
TooltipData
[],
stepLength
:
number
,
i18n
:
I18n
)
=>
{
const
indexPropMap
=
{
time
:
0
,
step
:
1
,
value
:
2
,
smoothed
:
3
,
relative
:
4
}
as
const
;
const
widthPropMap
:
Record
<
string
,
number
|
readonly
[
number
,
number
]
>
=
{
run
:
[
60
,
180
],
time
:
150
,
step
:
Math
.
max
(
stepLength
*
8
,
40
),
value
:
60
,
smoothed
:
70
,
relative
:
60
}
as
const
;
const
translatePropMap
=
{
run
:
'
common:runs
'
,
time
:
'
scalars:x-axis-value.wall
'
,
step
:
'
scalars:x-axis-value.step
'
,
value
:
'
scalars:value
'
,
smoothed
:
'
scalars:smoothed
'
,
relative
:
'
scalars:x-axis-value.relative
'
}
as
const
;
const
transformedData
=
data
.
map
(
item
=>
{
const
data
=
item
.
item
;
return
{
run
:
item
.
run
,
smoothed
:
valueFormatter
(
data
[
indexPropMap
.
smoothed
]
??
Number
.
NaN
),
value
:
valueFormatter
(
data
[
indexPropMap
.
value
]
??
Number
.
NaN
),
step
:
data
[
indexPropMap
.
step
],
time
:
formatTime
(
data
[
indexPropMap
.
time
],
i18n
.
language
),
// Relative display value should take easy-read into consideration.
// Better to tranform data to 'day:hour', 'hour:minutes', 'minute: seconds' and second only.
relative
:
Math
.
floor
(
data
[
indexPropMap
.
relative
]
*
60
*
60
)
+
'
s
'
}
as
const
;
});
const
renderContent
=
(
content
:
string
,
width
:
number
|
readonly
[
number
,
number
])
=>
`<div style="overflow: hidden;
${
Array
.
isArray
(
width
)
?
`min-width:
${(
width
as
[
number
,
number
])[
0
]}
;max-width:
${(
width
as
[
number
,
number
])[
1
]}
;`
:
`width:
${
width
as
number
}
px;`
}
">
${
content
}
</div>`
;
let
headerHtml
=
'
<tr style="font-size:14px;">
'
;
headerHtml
+=
(
Object
.
keys
(
transformedData
[
0
])
as
(
keyof
typeof
transformedData
[
0
])[])
.
map
(
key
=>
{
return
`<th style="padding: 0 4px; font-weight: bold;" class="
${
key
}
">
${
renderContent
(
i18n
.
t
(
translatePropMap
[
key
]),
widthPropMap
[
key
]
)}
</th>`
;
})
.
join
(
''
);
headerHtml
+=
'
</tr>
'
;
const
content
=
transformedData
.
map
(
item
=>
{
let
str
=
'
<tr style="font-size:12px;">
'
;
str
+=
Object
.
keys
(
item
)
.
map
(
key
=>
{
let
content
=
''
;
if
(
key
===
'
run
'
)
{
content
+=
`<span class="run-indicator" style="background-color:
${
item
[
key
].
colors
?.[
0
]
??
'
transpanent
'
}
"></span>`
;
content
+=
`<span title="
${
item
[
key
].
label
}
">
${
item
[
key
].
label
}
</span>`
;
}
else
{
content
+=
item
[
key
as
keyof
typeof
item
];
}
return
`<td style="padding: 0 4px;" class="
${
key
}
">
${
renderContent
(
content
,
widthPropMap
[
key
as
keyof
typeof
item
]
)}
</td>`
;
})
.
join
(
''
);
str
+=
'
</tr>
'
;
return
str
;
})
.
join
(
''
);
return
`<table style="text-align: left;table-layout: fixed;"><thead>
${
headerHtml
}
</thead><tbody>
${
content
}
</tbody><table>`
;
export
const
tooltip
=
(
data
:
Dataset
,
stepLength
:
number
,
i18n
:
I18n
)
=>
{
return
{
columns
:
[
{
label
:
i18n
.
t
(
'
scalars:smoothed
'
),
width
:
'
5em
'
},
{
label
:
i18n
.
t
(
'
scalars:value
'
),
width
:
'
4.285714286em
'
},
{
label
:
i18n
.
t
(
'
common:time-mode.step
'
),
width
:
`
${
Math
.
max
(
stepLength
*
0.571428571
,
2.857142857
)}
em`
},
{
label
:
i18n
.
t
(
'
common:time-mode.wall
'
),
width
:
'
10.714285714em
'
},
{
label
:
i18n
.
t
(
'
common:time-mode.relative
'
),
width
:
'
4.285714286em
'
}
],
data
:
data
.
map
(([
time
,
step
,
value
,
smoothed
,
relative
])
=>
[
valueFormatter
(
smoothed
??
Number
.
NaN
),
valueFormatter
(
value
??
Number
.
NaN
),
step
,
formatTime
(
time
,
i18n
.
language
),
Math
.
floor
(
relative
*
60
*
60
)
+
'
s
'
])
};
};
frontend/packages/core/resource/scalars/data.ts
浏览文件 @
e698eda6
...
...
@@ -103,6 +103,6 @@ export const nearestPoint = (data: Dataset[], runs: Run[], step: number) =>
}
return
{
run
:
runs
[
index
],
item
:
nearestItem
||
[]
item
:
nearestItem
||
[
0
,
0
,
0
,
0
,
0
]
};
});
frontend/packages/core/resource/scalars/index.ts
浏览文件 @
e698eda6
import
{
TooltipData
}
from
'
./types
'
;
import
{
SortingMethod
as
SM
,
TooltipData
,
XAxis
}
from
'
./types
'
;
import
sortBy
from
'
lodash/sortBy
'
;
export
const
xAxis
=
[
'
step
'
,
'
relative
'
,
'
wall
'
]
as
const
;
export
const
xAxisMap
=
{
step
:
1
,
relative
:
4
,
wall
:
0
[
XAxis
.
Step
]
:
1
,
[
XAxis
.
Relative
]
:
4
,
[
XAxis
.
WallTime
]
:
0
}
as
const
;
export
const
sortingMethod
=
[
'
default
'
,
'
descending
'
,
'
ascending
'
,
'
nearest
'
]
as
const
;
export
const
sortingMethodMap
=
{
default
:
null
,
descending
:
(
points
:
TooltipData
[])
=>
sortBy
(
points
,
point
=>
point
.
item
[
3
]).
reverse
(),
ascending
:
(
points
:
TooltipData
[])
=>
sortBy
(
points
,
point
=>
point
.
item
[
3
]),
export
const
sortingMethod
=
[
SM
.
Default
,
SM
.
Descending
,
SM
.
Ascending
,
SM
.
Nearest
]
as
const
;
export
const
sortingMethodMap
:
Record
<
SM
,
(
points
:
TooltipData
[],
data
:
number
[])
=>
TooltipData
[]
>
=
{
[
SM
.
Default
]:
(
points
:
TooltipData
[])
=>
points
,
[
SM
.
Descending
]
:
(
points
:
TooltipData
[])
=>
sortBy
(
points
,
point
=>
point
.
item
[
3
]).
reverse
(),
[
SM
.
Ascending
]
:
(
points
:
TooltipData
[])
=>
sortBy
(
points
,
point
=>
point
.
item
[
3
]),
// Compare other ponts width the trigger point, caculate the nearest sort.
nearest
:
(
points
:
TooltipData
[],
data
:
number
[])
=>
sortBy
(
points
,
point
=>
point
.
item
[
3
]
-
data
[
2
])
[
SM
.
Nearest
]
:
(
points
:
TooltipData
[],
data
:
number
[])
=>
sortBy
(
points
,
point
=>
point
.
item
[
3
]
-
data
[
2
])
}
as
const
;
export
*
from
'
./types
'
;
...
...
frontend/packages/core/resource/scalars/types.ts
浏览文件 @
e698eda6
import
{
sortingMethodMap
,
xAxisMap
}
from
'
./index
'
;
import
{
Run
}
from
'
~/types
'
;
import
{
Run
,
TimeMode
}
from
'
~/types
'
;
type
Value
=
number
;
type
WallTime
=
number
;
...
...
@@ -11,8 +9,13 @@ type Relative = number;
export
type
Dataset
=
[
WallTime
,
Step
,
Value
,
Smoothed
,
Relative
][];
export
type
ScalarDataset
=
[
WallTime
,
Step
,
Value
][];
export
type
XAxis
=
keyof
typeof
xAxisMap
;
export
type
SortingMethod
=
keyof
typeof
sortingMethodMap
;
export
{
TimeMode
as
XAxis
};
export
enum
SortingMethod
{
Default
=
'
default
'
,
Descending
=
'
descending
'
,
Ascending
=
'
ascending
'
,
Nearest
=
'
nearest
'
}
export
type
Range
=
{
min
:
number
;
...
...
@@ -21,5 +24,5 @@ export type Range = {
export
type
TooltipData
=
{
run
:
Run
;
item
:
number
[
];
item
:
Dataset
[
number
];
};
frontend/packages/core/types/index.
d.
ts
→
frontend/packages/core/types/index.ts
浏览文件 @
e698eda6
...
...
@@ -3,8 +3,8 @@ export interface Run {
colors
:
[
string
,
string
];
}
export
interface
Tag
{
runs
:
R
un
[];
export
interface
Tag
<
R
=
Run
>
{
runs
:
R
[];
label
:
string
;
}
...
...
@@ -12,3 +12,9 @@ export interface TagWithSingleRun {
label
:
string
;
run
:
Run
;
}
export
enum
TimeMode
{
Step
=
'
step
'
,
Relative
=
'
relative
'
,
WallTime
=
'
wall
'
}
frontend/packages/i18n/package.json
浏览文件 @
e698eda6
...
...
@@ -50,8 +50,8 @@
"devDependencies"
:
{
"@types/express"
:
"4.17.6"
,
"@types/hoist-non-react-statics"
:
"3.3.1"
,
"@types/node"
:
"14.0.1
3
"
,
"@types/react"
:
"16.9.
38
"
,
"@types/node"
:
"14.0.1
4
"
,
"@types/react"
:
"16.9.
41
"
,
"@types/react-dom"
:
"16.9.8"
,
"typescript"
:
"3.9.5"
},
...
...
frontend/packages/mock/data/components.ts
浏览文件 @
e698eda6
export
default
[
'
embeddings
'
,
'
scalar
'
,
'
image
'
,
'
graph
'
,
'
histogram
'
];
export
default
[
'
embeddings
'
,
'
scalar
'
,
'
image
'
,
'
graph
'
,
'
histogram
'
,
'
pr-curve
'
];
frontend/packages/mock/data/pr-curve/list.ts
0 → 100644
浏览文件 @
e698eda6
此差异已折叠。
点击以展开。
frontend/packages/mock/data/pr-curve/steps.ts
0 → 100644
浏览文件 @
e698eda6
import
{
Request
}
from
'
express
'
;
export
default
(
request
:
Request
)
=>
{
if
(
request
.
query
.
run
===
'
train
'
)
{
return
[
[
1593069993.786464
,
0
],
[
1593069993.787353
,
1
],
[
1593069993.7881448
,
2
],
[
1593069993.788836
,
3
],
[
1593069993.7894
,
4
],
[
1593069993.790076
,
5
],
[
1593069993.790763
,
6
],
[
1593069993.791473
,
7
],
[
1593069993.792149
,
8
],
[
1593069993.792763
,
9
]
];
}
return
[
[
1593069993.5386739
,
0
],
[
1593069993.539396
,
1
],
[
1593069993.540066
,
2
],
[
1593069993.540662
,
3
],
[
1593069993.541333
,
4
],
[
1593069993.542078
,
5
],
[
1593069993.5431821
,
6
],
[
1593069993.543998
,
7
],
[
1593069993.5449128
,
8
],
[
1593069993.54562
,
9
]
];
};
frontend/packages/mock/data/pr-curve/tags.ts
0 → 100644
浏览文件 @
e698eda6
export
default
{
test
:
[
'
layer2/biases/summaries/mean
'
,
'
test/1234
'
,
'
another
'
],
train
:
[
'
layer2/biases/summaries/mean
'
,
'
layer2/biases/summaries/accuracy
'
,
'
layer2/biases/summaries/cost
'
,
'
test/431
'
,
'
others
'
]
};
frontend/packages/mock/package.json
浏览文件 @
e698eda6
...
...
@@ -38,7 +38,7 @@
"devDependencies"
:
{
"@types/express"
:
"4.17.6"
,
"@types/faker"
:
"4.1.12"
,
"@types/node"
:
"14.0.1
3
"
,
"@types/node"
:
"14.0.1
4
"
,
"typescript"
:
"3.9.5"
},
"peerDependencies"
:
{
...
...
frontend/packages/netron/package.json
浏览文件 @
e698eda6
...
...
@@ -35,12 +35,12 @@
"dagre"
:
"0.8.5"
,
"long"
:
"4.0.0"
,
"marked"
:
"1.1.0"
,
"netron"
:
"
lutzroeder/netron#9f9be2e1d0cdeb538fcddbc359f1b4138223a953
"
,
"netron"
:
"
PeterPanZH/netron
"
,
"pako"
:
"1.0.11"
,
"protobufjs"
:
"lutzroeder/protobuf.js#b9a9d027589356226f4704f9d77f2639f52172f3"
},
"devDependencies"
:
{
"autoprefixer"
:
"9.8.
2
"
,
"autoprefixer"
:
"9.8.
4
"
,
"copy-webpack-plugin"
:
"6.0.2"
,
"css-loader"
:
"3.6.0"
,
"html-webpack-plugin"
:
"4.3.0"
,
...
...
frontend/packages/netron/src/view.js
浏览文件 @
e698eda6
...
...
@@ -1026,19 +1026,21 @@ view.ModelFactoryService = class {
this
.
register
(
'
./tflite
'
,
[
'
.tflite
'
,
'
.lite
'
,
'
.tfl
'
,
'
.bin
'
,
'
.pb
'
,
'
.tmfile
'
,
'
.h5
'
,
'
.model
'
,
'
.json
'
]);
this
.
register
(
'
./tf
'
,
[
'
.pb
'
,
'
.meta
'
,
'
.pbtxt
'
,
'
.prototxt
'
,
'
.json
'
,
'
.index
'
,
'
.ckpt
'
]);
this
.
register
(
'
./mediapipe
'
,
[
'
.pbtxt
'
]);
this
.
register
(
'
./sklearn
'
,
[
'
.pkl
'
,
'
.joblib
'
,
'
.model
'
,
'
.meta
'
,
'
.pb
'
]);
this
.
register
(
'
./uff
'
,
[
'
.uff
'
,
'
.pb
'
,
'
.trt
'
,
'
.pbtxt
'
,
'
.uff.txt
'
]);
this
.
register
(
'
./sklearn
'
,
[
'
.pkl
'
,
'
.pickle
'
,
'
.joblib
'
,
'
.model
'
,
'
.meta
'
,
'
.pb
'
,
'
.pt
'
,
'
.h5
'
]);
this
.
register
(
'
./cntk
'
,
[
'
.model
'
,
'
.cntk
'
,
'
.cmf
'
,
'
.dnn
'
]);
this
.
register
(
'
./paddle
'
,
[
'
.paddle
'
,
'
__model__
'
]);
this
.
register
(
'
./paddle
'
,
[
'
.paddle
'
,
'
.pdmodel
'
,
'
__model__
'
]);
this
.
register
(
'
./armnn
'
,
[
'
.armnn
'
]);
this
.
register
(
'
./bigdl
'
,
[
'
.model
'
,
'
.bigdl
'
]);
this
.
register
(
'
./darknet
'
,
[
'
.cfg
'
,
'
.model
'
]);
this
.
register
(
'
./mnn
'
,
[
'
.mnn
'
]);
this
.
register
(
'
./ncnn
'
,
[
'
.param
'
,
'
.bin
'
,
'
.cfg.ncnn
'
,
'
.weights.ncnn
'
]);
this
.
register
(
'
./tnn
'
,
[
'
.tnnproto
'
,
'
.tnnmodel
'
]);
this
.
register
(
'
./tengine
'
,
[
'
.tmfile
'
]);
this
.
register
(
'
./barracuda
'
,
[
'
.nn
'
]);
this
.
register
(
'
./openvino
'
,
[
'
.xml
'
,
'
.bin
'
]);
this
.
register
(
'
./flux
'
,
[
'
.bson
'
]);
this
.
register
(
'
./
chainer
'
,
[
'
.npz
'
,
'
.h5
'
,
'
.hd5
'
,
'
.hdf5
'
]);
this
.
register
(
'
./
npz
'
,
[
'
.npz
'
,
'
.h5
'
,
'
.hd5
'
,
'
.hdf5
'
]);
this
.
register
(
'
./dl4j
'
,
[
'
.zip
'
]);
this
.
register
(
'
./mlnet
'
,
[
'
.zip
'
]);
}
...
...
@@ -1300,27 +1302,21 @@ view.ModelFactoryService = class {
return
Promise
.
reject
(
new
ModelError
(
'
File has no content.
'
,
true
));
}
const
list
=
[
{
name
:
'
ELF executable
'
,
value
:
'
\
x7FELF
'
},
{
name
:
'
Git LFS header
'
,
value
:
'
version https://git-lfs.github.com/spec/v1
\n
'
},
{
name
:
'
Git LFS header
'
,
value
:
'
oid sha256:
'
},
{
name
:
'
HTML markup
'
,
value
:
'
<html>
'
},
{
name
:
'
HTML markup
'
,
value
:
'
<!DOCTYPE html>
'
},
{
name
:
'
HTML markup
'
,
value
:
'
<!DOCTYPE HTML>
'
},
{
name
:
'
HTML markup
'
,
value
:
'
\n\n\n\n\n
<!DOCTYPE html>
'
},
{
name
:
'
HTML markup
'
,
value
:
'
\n\n\n\n\n\n
<!DOCTYPE html>
'
},
{
name
:
'
Unity metadata
'
,
value
:
'
fileFormatVersion:
'
},
{
name
:
'
Vulkan SwiftShader ICD manifest
'
,
value
:
'
{"file_format_version": "1.0.0", "ICD":
'
},
{
name
:
'
StringIntLabelMapProto data
'
,
value
:
'
item {
\r\n
id:
'
},
{
name
:
'
StringIntLabelMapProto data
'
,
value
:
'
item {
\r\n
name:
'
},
{
name
:
'
StringIntLabelMapProto data
'
,
value
:
'
item {
\n
id:
'
},
{
name
:
'
StringIntLabelMapProto data
'
,
value
:
'
item {
\n
name:
'
},
{
name
:
'
Python source code
'
,
value
:
'
import sys, types, os;
'
}
{
name
:
'
ELF executable
'
,
value
:
/^
\x
7FELF/
},
{
name
:
'
Git LFS header
'
,
value
:
/^version https:
\/\/
git-lfs.github.com
\/
spec
\/
v1
\n
/
},
{
name
:
'
Git LFS header
'
,
value
:
/^oid sha256:/
},
{
name
:
'
HTML markup
'
,
value
:
/^
\s
*<html>/
},
{
name
:
'
HTML markup
'
,
value
:
/^
\s
*<!DOCTYPE html>/
},
{
name
:
'
HTML markup
'
,
value
:
/^
\s
*<!DOCTYPE HTML>/
},
{
name
:
'
Unity metadata
'
,
value
:
/^fileFormatVersion:/
},
{
name
:
'
Vulkan SwiftShader ICD manifest
'
,
value
:
/^{
\s
*"file_format_version":
\s
*"1.0.0"
\s
*,
\s
*"ICD":/
},
{
name
:
'
StringIntLabelMapProto data
'
,
value
:
/^item
\s
*{
\r?\n\s
*id:/
},
{
name
:
'
StringIntLabelMapProto data
'
,
value
:
/^item
\s
*{
\r?\n\s
*name:/
},
{
name
:
'
Python source code
'
,
value
:
/^
\s
*import sys, types, os;/
}
];
const
text
=
new
TextDecoder
().
decode
(
buffer
.
subarray
(
0
,
Math
.
min
(
1024
,
buffer
.
length
)));
for
(
const
item
of
list
)
{
if
(
buffer
.
length
>=
item
.
value
.
length
&&
buffer
.
subarray
(
0
,
item
.
value
.
length
).
every
((
v
,
i
)
=>
v
===
item
.
value
.
charCodeAt
(
i
))
)
{
if
(
text
.
match
(
item
.
value
))
{
return
Promise
.
reject
(
new
ModelError
(
'
Invalid file content. File contains
'
+
item
.
name
+
'
.
'
,
true
));
}
}
...
...
frontend/packages/server/package.json
浏览文件 @
e698eda6
...
...
@@ -46,9 +46,9 @@
},
"devDependencies"
:
{
"@types/express"
:
"4.17.6"
,
"@types/node"
:
"14.0.1
3
"
,
"@types/node"
:
"14.0.1
4
"
,
"@types/shelljs"
:
"0.8.8"
,
"@types/webpack"
:
"4.41.1
7
"
,
"@types/webpack"
:
"4.41.1
8
"
,
"@types/webpack-dev-middleware"
:
"3.7.1"
,
"@visualdl/mock"
:
"2.0.0-beta.43"
,
"cross-env"
:
"7.0.2"
,
...
...
frontend/packages/serverless/package.json
浏览文件 @
e698eda6
...
...
@@ -31,7 +31,7 @@
"test"
:
"echo
\"
Error: no test specified
\"
&& exit 0"
},
"devDependencies"
:
{
"@types/node"
:
"14.0.1
3
"
,
"@types/node"
:
"14.0.1
4
"
,
"@types/rimraf"
:
"3.0.0"
,
"@visualdl/core"
:
"2.0.0-beta.43"
,
"cross-env"
:
"7.0.2"
,
...
...
frontend/yarn.lock
浏览文件 @
e698eda6
...
...
@@ -2393,10 +2393,10 @@
dependencies:
defer-to-connect "^1.0.1"
"@tippyjs/react@4.0.
4
":
version "4.0.
4
"
resolved "https://registry.yarnpkg.com/@tippyjs/react/-/react-4.0.
4.tgz#7ba87ff8ad27eb4d5fae6daa4217f7d4de72088d
"
integrity sha512-
XifxYQU9Wx52gWRkF5WNDAurKh+s0O6B+j3nLLSCnhz8HigQlHuvsr+5ISiqFpeoA5/NAgFxLi6FPLNq8DfD8g
==
"@tippyjs/react@4.0.
5
":
version "4.0.
5
"
resolved "https://registry.yarnpkg.com/@tippyjs/react/-/react-4.0.
5.tgz#804399370d929b29bb6387b7dad9452635ee4221
"
integrity sha512-
Q7hv4Kkz5XlL71KP/SY8mdrfOkNkOmyQbMl2gh5fNPSzsqlPvAFbMyOP8iI0MS/sHASYGfth4+D9SzyTkrheTw
==
dependencies:
tippy.js "^6.2.0"
...
...
@@ -2430,10 +2430,10 @@
resolved "https://registry.yarnpkg.com/@types/d3-format/-/d3-format-1.3.1.tgz#35bf88264bd6bcda39251165bb827f67879c4384"
integrity sha512-KAWvReOKMDreaAwOjdfQMm0HjcUMlQG47GwqdVKgmm20vTd2pucj0a70c3gUSHrnsmo6H2AMrkBsZU2UhJLq8A==
"@types/echarts@4.6.
2
":
version "4.6.
2
"
resolved "https://registry.yarnpkg.com/@types/echarts/-/echarts-4.6.
2.tgz#f66b8736e2a554f432d58ec0361bf9c9d908ccfc
"
integrity sha512-
ovishXXoibnoPTgevsmZuuoVaHGzFlvBEsGzcdldlRwxiUsL+ChOfRat5JRWv5W2zUHxkposYQw+m0aDJM+S3Q
==
"@types/echarts@4.6.
3
":
version "4.6.
3
"
resolved "https://registry.yarnpkg.com/@types/echarts/-/echarts-4.6.
3.tgz#227b33b106203ceb2ca4fa51760f406618caa89a
"
integrity sha512-
XsDsLtPDxSGPqcHvVEbH+z5r9lPiduNOf4aL3NjGprQ/4SliDiTS7DErimHpVdiEOoVFzwjn2usvgLOb1JqOJA
==
dependencies:
"@types/zrender" "*"
...
...
@@ -2510,10 +2510,10 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"
integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==
"@types/lodash@4.14.15
6
":
version "4.14.15
6
"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.15
6.tgz#cbe30909c89a1feeb7c60803e785344ea0ec82d1
"
integrity sha512-
l2AgHXcKUwx2DsvP19wtRPqZ4NkONjmorOdq4sMcxIjqdIuuV/ULo2ftuv4NUpevwfW7Ju/UKLqo0ZXuEt/8l
Q==
"@types/lodash@4.14.15
7
":
version "4.14.15
7
"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.15
7.tgz#fdac1c52448861dfde1a2e1515dbc46e54926dc8
"
integrity sha512-
Ft5BNFmv2pHDgxV5JDsndOWTRJ+56zte0ZpYLowp03tW+K+t8u8YMOzAnpuqPgzX6WO1XpDIUm7u04M8vdDiV
Q==
"@types/long@^4.0.0":
version "4.0.1"
...
...
@@ -2552,10 +2552,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.5.tgz#3d03acd3b3414cf67faf999aed11682ed121f22b"
integrity sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==
"@types/node@14.0.1
3
":
version "14.0.1
3
"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.1
3.tgz#ee1128e881b874c371374c1f72201893616417c9
"
integrity sha512-
rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA
==
"@types/node@14.0.1
4
":
version "14.0.1
4
"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.1
4.tgz#24a0b5959f16ac141aeb0c5b3cd7a15b7c64cbce
"
integrity sha512-
syUgf67ZQpaJj01/tRTknkMNoBBLWJOBODF0Zm4NrXmiSuxjymFrxnTu1QVYRubhVkRcZLYZG8STTwJRdVm/WQ
==
"@types/node@^10.1.0":
version "10.17.24"
...
...
@@ -2619,10 +2619,10 @@
"@types/prop-types" "*"
csstype "^2.2.0"
"@types/react@16.9.
38
":
version "16.9.
38
"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.
38.tgz#868405dace93a4095d3e054f4c4a1de7a1ac0680
"
integrity sha512-
pHAeZbjjNRa/hxyNuLrvbxhhnKyKNiLC6I5fRF2Zr/t/S6zS41MiyzH4+c+1I9vVfvuRt1VS2Lodjr4ZWnxrdA
==
"@types/react@16.9.
41
":
version "16.9.
41
"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.
41.tgz#925137ee4d2ff406a0ecf29e8e9237390844002e
"
integrity sha512-
6cFei7F7L4wwuM+IND/Q2cV1koQUvJ8iSV+Gwn0c3kvABZ691g7sp3hfEQHOUBJtccl1gPi+EyNjMIl9nGA0ug
==
dependencies:
"@types/prop-types" "*"
csstype "^2.2.0"
...
...
@@ -2716,7 +2716,19 @@
"@types/webpack-sources" "*"
source-map "^0.6.0"
"@types/webpack@4.41.17", "@types/webpack@^4.41.8":
"@types/webpack@4.41.18":
version "4.41.18"
resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.18.tgz#2945202617866ecdffa582087f1b6de04a7eed55"
integrity sha512-mQm2R8vV2BZE/qIDVYqmBVLfX73a8muwjs74SpjEyJWJxeXBbsI9L65Pcia9XfYLYWzD1c1V8m+L0p30y2N7MA==
dependencies:
"@types/anymatch" "*"
"@types/node" "*"
"@types/tapable" "*"
"@types/uglify-js" "*"
"@types/webpack-sources" "*"
source-map "^0.6.0"
"@types/webpack@^4.41.8":
version "4.41.17"
resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.17.tgz#0a69005e644d657c85b7d6ec1c826a71bebd1c93"
integrity sha512-6FfeCidTSHozwKI67gIVQQ5Mp0g4X96c2IXxX75hYEQJwST/i6NyZexP//zzMOBb+wG9jJ7oO8fk9yObP2HWAw==
...
...
@@ -3402,14 +3414,14 @@ autobind-decorator@^1.3.4:
resolved "https://registry.yarnpkg.com/autobind-decorator/-/autobind-decorator-1.4.3.tgz#4c96ffa77b10622ede24f110f5dbbf56691417d1"
integrity sha1-TJb/p3sQYi7eJPEQ9du/VmkUF9E=
autoprefixer@9.8.
2
:
version "9.8.
2
"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.
2.tgz#7347396ee576b18687041bfbacd76d78e27baa56
"
integrity sha512-
9UwMMU8Rg7Fj0c55mbOpXrr/2WrRqoOwOlLNTyyYt+nhiyQdIBWipp5XWzt+Lge8r3DK5y+EHMc1OBf8VpZA6Q
==
autoprefixer@9.8.
4
:
version "9.8.
4
"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.
4.tgz#736f1012673a70fa3464671d78d41abd54512863
"
integrity sha512-
84aYfXlpUe45lvmS+HoAWKCkirI/sw4JK0/bTeeqgHYco3dcsOn0NqdejISjptsYwNji/21dnkDri9PsYKk89A
==
dependencies:
browserslist "^4.12.0"
caniuse-lite "^1.0.3000108
4
"
kleur "^4.0.1
"
caniuse-lite "^1.0.3000108
7
"
colorette "^1.2.0
"
normalize-range "^0.1.2"
num2fraction "^1.2.2"
postcss "^7.0.32"
...
...
@@ -4012,10 +4024,10 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001043:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001064.tgz#a0f49689119ba08943b09968e118faf3f645add0"
integrity sha512-hdBcQMFvJIrOhkpAZiRXz04Cmetwc9NekeuNl0qZfHOugxOhJKxsjF1RmISMPFjIF4PPx1reliIzbfN42EiQ5A==
caniuse-lite@^1.0.3000108
4
:
version "1.0.3000108
7
"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.3000108
7.tgz#4a0bdc5998a114fcf8b7954e7ba6c2c29831c54a
"
integrity sha512-
KAQRGtt+eGCQBSp2iZTQibdCf9oe6cNTi5lmpsW38NnxP4WMYzfU6HCRmh4kJyh6LrTM9/uyElK4xcO93kafp
g==
caniuse-lite@^1.0.3000108
7
:
version "1.0.3000108
8
"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.3000108
8.tgz#23a6b9e192106107458528858f2c0e0dba0d9073
"
integrity sha512-
6eYUrlShRYveyqKG58HcyOfPgh3zb2xqs7NvT2VVtP3hEUeeWvc3lqhpeMTxYWBBeeaT9A4bKsrtjATm66BTH
g==
caseless@~0.12.0:
version "0.12.0"
...
...
@@ -4330,6 +4342,11 @@ color@^3.0.0:
color-convert "^1.9.1"
color-string "^1.5.2"
colorette@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.0.tgz#45306add826d196e8c87236ac05d797f25982e63"
integrity sha512-soRSroY+OF/8OdA3PTQXwaDJeMc7TfknKKrxeSCencL2a4+Tx5zhxmmv7hdpCjhKBjehzp8+bwe/T68K0hpIjw==
columnify@^1.5.4:
version "1.5.4"
resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb"
...
...
@@ -8098,11 +8115,6 @@ kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
kleur@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.0.1.tgz#3d4948534b666e2578f93b6fafb62108e64f05ef"
integrity sha512-Qs6SqCLm63rd0kNVh+wO4XsWLU6kgfwwaPYsLiClWf0Tewkzsa6MvB21bespb8cz+ANS+2t3So1ge3gintzhlw==
latest-version@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face"
...
...
@@ -9051,9 +9063,9 @@ netmask@^1.0.6:
resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35"
integrity sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=
netron@
lutzroeder/netron#9f9be2e1d0cdeb538fcddbc359f1b4138223a953
:
version "4.
1.9
"
resolved "https://codeload.github.com/
lutzroeder/netron/tar.gz/9f9be2e1d0cdeb538fcddbc359f1b4138223a953
"
netron@
PeterPanZH/netron
:
version "4.
3.5
"
resolved "https://codeload.github.com/
PeterPanZH/netron/tar.gz/2c04a5d19b18ec09ddb9087f99177e7d27f156bd
"
dependencies:
d3 "5.16.0"
dagre "0.8.5"
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录