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
OpenDAS
nni
Commits
f1105409
Unverified
Commit
f1105409
authored
Oct 15, 2020
by
liuzhe-lz
Committed by
GitHub
Oct 15, 2020
Browse files
Merge pull request #2959 from microsoft/v1.9
Merge v1.9 back to master
parents
0a6c234a
88a225f8
Changes
80
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1254 additions
and
727 deletions
+1254
-727
src/webui/src/components/overview/count/ExpDuration.tsx
src/webui/src/components/overview/count/ExpDuration.tsx
+54
-0
src/webui/src/components/overview/count/ExpDurationContext.tsx
...ebui/src/components/overview/count/ExpDurationContext.tsx
+7
-0
src/webui/src/components/overview/count/TrialCount.tsx
src/webui/src/components/overview/count/TrialCount.tsx
+107
-0
src/webui/src/components/overview/count/context.tsx
src/webui/src/components/overview/count/context.tsx
+17
-0
src/webui/src/components/overview/experiment/BasicInfo.tsx
src/webui/src/components/overview/experiment/BasicInfo.tsx
+98
-0
src/webui/src/components/overview/experiment/Command.tsx
src/webui/src/components/overview/experiment/Command.tsx
+63
-0
src/webui/src/components/overview/experiment/basicInfoStyles.ts
...bui/src/components/overview/experiment/basicInfoStyles.ts
+52
-0
src/webui/src/components/overview/overviewConst.ts
src/webui/src/components/overview/overviewConst.ts
+21
-0
src/webui/src/components/overview/table/Details.tsx
src/webui/src/components/overview/table/Details.tsx
+1
-1
src/webui/src/components/overview/table/SuccessTable.tsx
src/webui/src/components/overview/table/SuccessTable.tsx
+34
-18
src/webui/src/components/public-child/ExpandableDetails.tsx
src/webui/src/components/public-child/ExpandableDetails.tsx
+22
-0
src/webui/src/components/public-child/OpenRow.tsx
src/webui/src/components/public-child/OpenRow.tsx
+1
-1
src/webui/src/components/public-child/PaginationTable.tsx
src/webui/src/components/public-child/PaginationTable.tsx
+120
-0
src/webui/src/components/public-child/config/TrialConfigButton.tsx
.../src/components/public-child/config/TrialConfigButton.tsx
+27
-0
src/webui/src/components/public-child/config/TrialConfigPanel.tsx
...i/src/components/public-child/config/TrialConfigPanel.tsx
+104
-0
src/webui/src/components/stateless-component/NNItabs.tsx
src/webui/src/components/stateless-component/NNItabs.tsx
+1
-1
src/webui/src/components/trial-detail/Para.tsx
src/webui/src/components/trial-detail/Para.tsx
+51
-6
src/webui/src/components/trial-detail/TableList.tsx
src/webui/src/components/trial-detail/TableList.tsx
+465
-698
src/webui/src/index.tsx
src/webui/src/index.tsx
+8
-1
src/webui/src/static/const.ts
src/webui/src/static/const.ts
+1
-1
No files found.
src/webui/src/components/overview/count/ExpDuration.tsx
0 → 100644
View file @
f1105409
import
React
from
'
react
'
;
import
{
Stack
,
TooltipHost
,
ProgressIndicator
}
from
'
@fluentui/react
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
{
CONTROLTYPE
}
from
'
../../../static/const
'
;
import
{
convertDuration
}
from
'
../../../static/function
'
;
import
{
EditExperimentParam
}
from
'
./EditExperimentParam
'
;
import
{
ExpDurationContext
}
from
'
./ExpDurationContext
'
;
import
{
EditExpeParamContext
}
from
'
./context
'
;
import
'
../../../static/style/overview/count.scss
'
;
const
itemStyle1
:
React
.
CSSProperties
=
{
width
:
'
62%
'
,
height
:
80
};
const
itemStyle2
:
React
.
CSSProperties
=
{
width
:
'
63%
'
,
height
:
80
,
textAlign
:
'
right
'
};
export
const
ExpDuration
=
():
any
=>
(
<
ExpDurationContext
.
Consumer
>
{
(
value
):
React
.
ReactNode
=>
{
const
{
maxExecDuration
,
execDuration
,
updateOverviewPage
}
=
value
;
const
tooltip
=
maxExecDuration
-
execDuration
;
const
maxExecDurationStr
=
convertDuration
(
maxExecDuration
);
const
percent
=
execDuration
/
maxExecDuration
;
return
(
<
Stack
horizontal
className
=
'ExpDuration'
>
<
div
style
=
{
itemStyle1
}
>
<
TooltipHost
content
=
{
`
${
convertDuration
(
tooltip
)}
remaining`
}
>
<
ProgressIndicator
percentComplete
=
{
percent
}
barHeight
=
{
15
}
/>
</
TooltipHost
>
</
div
>
<
div
style
=
{
itemStyle2
}
>
<
Stack
horizontal
></
Stack
>
<
EditExpeParamContext
.
Provider
value
=
{
{
editType
:
CONTROLTYPE
[
0
],
field
:
'
maxExecDuration
'
,
title
:
'
Max duration
'
,
maxExecDuration
:
maxExecDurationStr
,
maxTrialNum
:
EXPERIMENT
.
profile
.
params
.
maxTrialNum
,
trialConcurrency
:
EXPERIMENT
.
profile
.
params
.
trialConcurrency
,
updateOverviewPage
}
}
>
<
EditExperimentParam
/>
</
EditExpeParamContext
.
Provider
>
</
div
>
</
Stack
>
);
}
}
</
ExpDurationContext
.
Consumer
>
);
src/webui/src/components/overview/count/ExpDurationContext.tsx
0 → 100644
View file @
f1105409
import
React
from
'
react
'
;
export
const
ExpDurationContext
=
React
.
createContext
({
maxExecDuration
:
0
,
execDuration
:
0
,
// eslint-disable-next-line @typescript-eslint/no-empty-function
updateOverviewPage
:
():
void
=>
{}
});
src/webui/src/components/overview/count/TrialCount.tsx
0 → 100644
View file @
f1105409
import
*
as
React
from
'
react
'
;
import
{
Stack
,
TooltipHost
,
ProgressIndicator
}
from
'
@fluentui/react
'
;
import
{
EXPERIMENT
,
TRIALS
}
from
'
../../../static/datamodel
'
;
import
{
CONTROLTYPE
}
from
'
../../../static/const
'
;
import
{
EditExperimentParam
}
from
'
./EditExperimentParam
'
;
import
{
EditExpeParamContext
}
from
'
./context
'
;
import
{
ExpDurationContext
}
from
'
./ExpDurationContext
'
;
const
itemStyles
:
React
.
CSSProperties
=
{
width
:
'
62%
'
};
const
itemStyle2
:
React
.
CSSProperties
=
{
width
:
'
63%
'
,
textAlign
:
'
right
'
};
const
itemStyle1
:
React
.
CSSProperties
=
{
width
:
'
30%
'
,
height
:
50
};
const
itemRunning
:
React
.
CSSProperties
=
{
width
:
'
42%
'
,
height
:
56
};
export
const
TrialCount
=
():
any
=>
{
const
count
=
TRIALS
.
countStatus
();
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const
stoppedCount
=
count
.
get
(
'
USER_CANCELED
'
)
!
+
count
.
get
(
'
SYS_CANCELED
'
)
!
+
count
.
get
(
'
EARLY_STOPPED
'
)
!
;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const
bar2
=
count
.
get
(
'
RUNNING
'
)
!
+
count
.
get
(
'
SUCCEEDED
'
)
!
+
count
.
get
(
'
FAILED
'
)
!
+
stoppedCount
;
// support type [0, 1], not 98%
const
bar2Percent
=
bar2
/
EXPERIMENT
.
profile
.
params
.
maxTrialNum
;
return
(
<
ExpDurationContext
.
Consumer
>
{
(
value
):
React
.
ReactNode
=>
{
const
{
updateOverviewPage
}
=
value
;
return
(
<
React
.
Fragment
>
<
Stack
horizontal
horizontalAlign
=
'space-between'
className
=
'ExpDuration'
>
<
div
style
=
{
itemStyles
}
>
<
TooltipHost
content
=
{
bar2
.
toString
()
}
>
<
ProgressIndicator
percentComplete
=
{
bar2Percent
}
barHeight
=
{
15
}
/>
</
TooltipHost
>
<
Stack
horizontal
className
=
'mess'
>
<
div
style
=
{
itemRunning
}
className
=
'basic'
>
<
p
>
Running
</
p
>
<
div
>
{
count
.
get
(
'
RUNNING
'
)
}
</
div
>
</
div
>
<
div
style
=
{
itemStyle1
}
className
=
'basic'
>
<
p
>
Failed
</
p
>
<
div
>
{
count
.
get
(
'
FAILED
'
)
}
</
div
>
</
div
>
<
div
style
=
{
itemStyle1
}
className
=
'basic'
>
<
p
>
Stopped
</
p
>
<
div
>
{
stoppedCount
}
</
div
>
</
div
>
</
Stack
>
<
Stack
horizontal
horizontalAlign
=
'space-between'
className
=
'mess'
>
<
div
style
=
{
itemStyle1
}
className
=
'basic'
>
<
p
>
Succeeded
</
p
>
<
div
>
{
count
.
get
(
'
SUCCEEDED
'
)
}
</
div
>
</
div
>
<
div
style
=
{
itemStyle1
}
className
=
'basic'
>
<
p
>
Waiting
</
p
>
<
div
>
{
count
.
get
(
'
WAITING
'
)
}
</
div
>
</
div
>
</
Stack
>
</
div
>
<
div
style
=
{
itemStyle2
}
>
<
EditExpeParamContext
.
Provider
value
=
{
{
title
:
'
Max trial numbers
'
,
field
:
'
maxTrialNum
'
,
editType
:
CONTROLTYPE
[
1
],
maxExecDuration
:
''
,
maxTrialNum
:
EXPERIMENT
.
profile
.
params
.
maxTrialNum
,
trialConcurrency
:
EXPERIMENT
.
profile
.
params
.
trialConcurrency
,
updateOverviewPage
}
}
>
<
EditExperimentParam
/>
</
EditExpeParamContext
.
Provider
>
<
EditExpeParamContext
.
Provider
value
=
{
{
title
:
'
Concurrency
'
,
field
:
'
trialConcurrency
'
,
editType
:
CONTROLTYPE
[
2
],
// maxExecDuration: EXPERIMENT.profile.params.maxExecDuration,
maxExecDuration
:
''
,
maxTrialNum
:
EXPERIMENT
.
profile
.
params
.
maxTrialNum
,
trialConcurrency
:
EXPERIMENT
.
profile
.
params
.
trialConcurrency
,
updateOverviewPage
}
}
>
<
EditExperimentParam
/>
</
EditExpeParamContext
.
Provider
>
</
div
>
</
Stack
>
</
React
.
Fragment
>
);
}
}
</
ExpDurationContext
.
Consumer
>
);
};
src/webui/src/components/overview/count/context.tsx
0 → 100644
View file @
f1105409
import
React
from
'
react
'
;
/***
* const CONTROLTYPE = ['MAX_EXEC_DURATION', 'MAX_TRIAL_NUM', 'TRIAL_CONCURRENCY', 'SEARCH_SPACE'];
* [0], 'MAX_EXEC_DURATION', params.maxExecDuration
* [1], 'MAX_TRIAL_NUM', params.maxTrialNum
* [2], 'TRIAL_CONCURRENCY', params.trialConcurrency
*/
export
const
EditExpeParamContext
=
React
.
createContext
({
editType
:
''
,
field
:
''
,
title
:
''
,
maxExecDuration
:
''
,
maxTrialNum
:
0
,
trialConcurrency
:
0
,
// eslint-disable-next-line @typescript-eslint/no-empty-function
updateOverviewPage
:
():
void
=>
{}
});
src/webui/src/components/overview/experiment/BasicInfo.tsx
0 → 100644
View file @
f1105409
import
React
,
{
useState
,
useCallback
}
from
'
react
'
;
import
{
Stack
,
Callout
,
Link
,
IconButton
}
from
'
@fluentui/react
'
;
import
LogDrawer
from
'
../../modals/LogPanel
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
{
formatTimestamp
}
from
'
../../../static/function
'
;
import
{
useId
}
from
'
@uifabric/react-hooks
'
;
import
{
BestMetricContext
}
from
'
../../Overview
'
;
import
{
styles
}
from
'
./basicInfoStyles
'
;
import
'
../../../static/style/progress/progress.scss
'
;
import
'
../../../static/style/progress/probar.scss
'
;
export
const
ReBasicInfo
=
():
any
=>
{
const
labelId
:
string
=
useId
(
'
callout-label
'
);
const
descriptionId
:
string
=
useId
(
'
callout-description
'
);
const
ref
=
React
.
createRef
<
HTMLDivElement
>
();
const
[
isCalloutVisible
,
setCalloutVisible
]
=
useState
(
false
);
const
[
isShowLogDrawer
,
setShowLogDrawer
]
=
useState
(
false
);
const
onDismiss
=
useCallback
(()
=>
setCalloutVisible
(
false
),
[]);
const
showCallout
=
useCallback
(()
=>
setCalloutVisible
(
true
),
[]);
const
closeLogDrawer
=
useCallback
(()
=>
setShowLogDrawer
(
false
),
[]);
const
ShowLogDrawer
=
useCallback
(()
=>
setShowLogDrawer
(
true
),
[]);
return
(
<
div
>
<
div
className
=
'basic'
>
<
p
>
ID:
{
EXPERIMENT
.
profile
.
id
}
</
p
>
<
div
>
{
EXPERIMENT
.
profile
.
params
.
experimentName
}
</
div
>
</
div
>
<
div
className
=
'basic'
>
<
Stack
className
=
'basic'
>
<
p
>
Status
</
p
>
<
Stack
horizontal
className
=
'status'
>
<
span
className
=
{
`
${
EXPERIMENT
.
status
}
status-text`
}
>
{
EXPERIMENT
.
status
}
</
span
>
{
EXPERIMENT
.
status
===
'
ERROR
'
?
(
<
div
>
<
div
className
=
{
styles
.
buttonArea
}
ref
=
{
ref
}
>
<
IconButton
iconProps
=
{
{
iconName
:
'
info
'
}
}
onClick
=
{
isCalloutVisible
?
onDismiss
:
showCallout
}
/>
</
div
>
{
isCalloutVisible
&&
(
<
Callout
className
=
{
styles
.
callout
}
ariaLabelledBy
=
{
labelId
}
ariaDescribedBy
=
{
descriptionId
}
role
=
'alertdialog'
gapSpace
=
{
0
}
target
=
{
ref
}
onDismiss
=
{
onDismiss
}
setInitialFocus
=
{
true
}
>
<
div
className
=
{
styles
.
header
}
>
<
p
className
=
{
styles
.
title
}
id
=
{
labelId
}
>
Error
</
p
>
</
div
>
<
div
className
=
{
styles
.
inner
}
>
<
p
className
=
{
styles
.
subtext
}
id
=
{
descriptionId
}
>
{
EXPERIMENT
.
error
}
</
p
>
<
div
className
=
{
styles
.
actions
}
>
<
Link
className
=
{
styles
.
link
}
onClick
=
{
ShowLogDrawer
}
>
Learn about
</
Link
>
</
div
>
</
div
>
</
Callout
>
)
}
</
div
>
)
:
null
}
</
Stack
>
</
Stack
>
</
div
>
<
div
className
=
'basic'
>
<
BestMetricContext
.
Consumer
>
{
(
value
):
React
.
ReactNode
=>
(
<
Stack
>
<
p
>
Best metric
</
p
>
<
div
>
{
isNaN
(
value
.
bestAccuracy
)
?
'
N/A
'
:
value
.
bestAccuracy
.
toFixed
(
6
)
}
</
div
>
</
Stack
>
)
}
</
BestMetricContext
.
Consumer
>
</
div
>
<
div
className
=
'basic'
>
<
p
>
Start time
</
p
>
<
div
className
=
'nowrap'
>
{
formatTimestamp
(
EXPERIMENT
.
profile
.
startTime
)
}
</
div
>
</
div
>
<
div
className
=
'basic'
>
<
p
>
End time
</
p
>
<
div
className
=
'nowrap'
>
{
formatTimestamp
(
EXPERIMENT
.
profile
.
endTime
)
}
</
div
>
</
div
>
{
/* learn about click -> default active key is dispatcher. */
}
{
isShowLogDrawer
?
<
LogDrawer
closeDrawer
=
{
closeLogDrawer
}
activeTab
=
'dispatcher'
/>
:
null
}
</
div
>
);
};
src/webui/src/components/overview/experiment/Command.tsx
0 → 100644
View file @
f1105409
import
React
from
'
react
'
;
import
{
TooltipHost
,
Stack
}
from
'
@fluentui/react
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
'
../../../static/style/overview/command.scss
'
;
export
const
Command
=
():
any
=>
{
const
clusterMetaData
=
EXPERIMENT
.
profile
.
params
.
clusterMetaData
;
const
tuner
=
EXPERIMENT
.
profile
.
params
.
tuner
;
const
advisor
=
EXPERIMENT
.
profile
.
params
.
advisor
;
const
assessor
=
EXPERIMENT
.
profile
.
params
.
assessor
;
let
title
=
''
;
let
builtinName
=
''
;
let
trialCommand
=
'
unknown
'
;
if
(
tuner
!==
undefined
)
{
title
=
title
.
concat
(
'
Tuner
'
);
if
(
tuner
.
builtinTunerName
!==
undefined
)
{
builtinName
=
builtinName
.
concat
(
tuner
.
builtinTunerName
);
}
}
if
(
advisor
!==
undefined
)
{
title
=
title
.
concat
(
'
/ Assessor
'
);
if
(
advisor
.
builtinAdvisorName
!==
undefined
)
{
builtinName
=
builtinName
.
concat
(
advisor
.
builtinAdvisorName
);
}
}
if
(
assessor
!==
undefined
)
{
title
=
title
.
concat
(
'
/ Addvisor
'
);
if
(
assessor
.
builtinAssessorName
!==
undefined
)
{
builtinName
=
builtinName
.
concat
(
assessor
.
builtinAssessorName
);
}
}
if
(
clusterMetaData
!==
undefined
)
{
for
(
const
item
of
clusterMetaData
)
{
if
(
item
.
key
===
'
command
'
)
{
trialCommand
=
item
.
value
;
}
}
}
return
(
<
div
className
=
'command basic'
>
<
div
className
=
'command1'
>
<
p
>
Training platform
</
p
>
<
div
className
=
'nowrap'
>
{
EXPERIMENT
.
profile
.
params
.
trainingServicePlatform
}
</
div
>
<
p
className
=
'lineMargin'
>
{
title
}
</
p
>
<
div
className
=
'nowrap'
>
{
builtinName
}
</
div
>
</
div
>
<
Stack
className
=
'command2'
>
<
p
>
Log directory
</
p
>
<
div
className
=
'nowrap'
>
<
TooltipHost
content
=
{
EXPERIMENT
.
profile
.
logDir
||
'
unknown
'
}
className
=
'nowrap'
>
{
EXPERIMENT
.
profile
.
logDir
||
'
unknown
'
}
</
TooltipHost
>
</
div
>
<
p
className
=
'lineMargin'
>
Trial command
</
p
>
<
div
className
=
'nowrap'
>
<
TooltipHost
content
=
{
trialCommand
||
'
unknown
'
}
className
=
'nowrap'
>
{
trialCommand
||
'
unknown
'
}
</
TooltipHost
>
</
div
>
</
Stack
>
</
div
>
);
};
src/webui/src/components/overview/experiment/basicInfoStyles.ts
0 → 100644
View file @
f1105409
import
{
FontWeights
,
mergeStyleSets
,
getTheme
}
from
'
@fluentui/react
'
;
const
theme
=
getTheme
();
export
const
styles
=
mergeStyleSets
({
buttonArea
:
{
verticalAlign
:
'
top
'
,
display
:
'
inline-block
'
,
textAlign
:
'
center
'
,
// margin: '0 100px',
minWidth
:
30
,
height
:
30
},
callout
:
{
maxWidth
:
300
},
header
:
{
padding
:
'
18px 24px 12px
'
},
title
:
[
theme
.
fonts
.
xLarge
,
{
margin
:
0
,
color
:
theme
.
palette
.
neutralPrimary
,
fontWeight
:
FontWeights
.
semilight
}
],
inner
:
{
height
:
'
100%
'
,
padding
:
'
0 24px 20px
'
},
actions
:
{
position
:
'
relative
'
,
marginTop
:
20
,
width
:
'
100%
'
,
whiteSpace
:
'
nowrap
'
},
subtext
:
[
theme
.
fonts
.
small
,
{
margin
:
0
,
color
:
theme
.
palette
.
neutralPrimary
,
fontWeight
:
FontWeights
.
semilight
}
],
link
:
[
theme
.
fonts
.
medium
,
{
color
:
theme
.
palette
.
neutralPrimary
}
]
});
src/webui/src/components/overview/overviewConst.ts
0 → 100644
View file @
f1105409
const
itemStyle1
:
React
.
CSSProperties
=
{
width
:
'
75%
'
};
const
itemStyleSucceed
:
React
.
CSSProperties
=
{
width
:
'
28%
'
};
const
itemStyle2
:
React
.
CSSProperties
=
{
height
:
38
};
// top trials entries
const
entriesOption
=
[
{
key
:
'
10
'
,
text
:
'
10
'
},
{
key
:
'
20
'
,
text
:
'
20
'
},
{
key
:
'
30
'
,
text
:
'
30
'
},
{
key
:
'
50
'
,
text
:
'
40
'
},
{
key
:
'
100
'
,
text
:
'
100
'
}
];
export
{
itemStyle1
,
itemStyleSucceed
,
itemStyle2
,
entriesOption
};
src/webui/src/components/overview/Details.tsx
→
src/webui/src/components/overview/
table/
Details.tsx
View file @
f1105409
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
DetailsRow
,
IDetailsRowBaseProps
}
from
'
@fluentui/react
'
;
import
{
DetailsRow
,
IDetailsRowBaseProps
}
from
'
@fluentui/react
'
;
import
OpenRow
from
'
../public-child/OpenRow
'
;
import
OpenRow
from
'
../
../
public-child/OpenRow
'
;
interface
DetailsProps
{
interface
DetailsProps
{
detailsProps
:
IDetailsRowBaseProps
;
detailsProps
:
IDetailsRowBaseProps
;
...
...
src/webui/src/components/overview/SuccessTable.tsx
→
src/webui/src/components/overview/
table/
SuccessTable.tsx
View file @
f1105409
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
import
{
DetailsList
,
IDetailsListProps
,
IColumn
}
from
'
@fluentui/react
'
;
import
{
DetailsList
,
IDetailsListProps
,
IColumn
}
from
'
@fluentui/react
'
;
import
DefaultMetric
from
'
../public-child/DefaultMetric
'
;
import
DefaultMetric
from
'
../
../
public-child/DefaultMetric
'
;
import
Details
from
'
./Details
'
;
import
Details
from
'
./Details
'
;
import
{
convertDuration
}
from
'
../../static/function
'
;
import
{
convertDuration
}
from
'
../../../static/function
'
;
import
{
TRIALS
}
from
'
../../static/datamodel
'
;
import
{
TRIALS
}
from
'
../../../static/datamodel
'
;
import
{
DETAILTABS
}
from
'
../stateless-component/NNItabs
'
;
import
{
DETAILTABS
}
from
'
../../stateless-component/NNItabs
'
;
import
'
../../static/style/succTable.scss
'
;
import
'
../../../static/style/succTable.scss
'
;
import
'
../../static/style/openRow.scss
'
;
import
'
../../../static/style/tableStatus.css
'
;
import
'
../../../static/style/openRow.scss
'
;
interface
SuccessTableProps
{
interface
SuccessTableProps
{
trialIds
:
string
[];
trialIds
:
string
[];
...
@@ -15,12 +16,17 @@ interface SuccessTableProps {
...
@@ -15,12 +16,17 @@ interface SuccessTableProps {
interface
SuccessTableState
{
interface
SuccessTableState
{
columns
:
IColumn
[];
columns
:
IColumn
[];
source
:
Array
<
any
>
;
source
:
Array
<
any
>
;
innerWidth
:
number
;
}
}
class
SuccessTable
extends
React
.
Component
<
SuccessTableProps
,
SuccessTableState
>
{
class
SuccessTable
extends
React
.
Component
<
SuccessTableProps
,
SuccessTableState
>
{
constructor
(
props
:
SuccessTableProps
)
{
constructor
(
props
:
SuccessTableProps
)
{
super
(
props
);
super
(
props
);
this
.
state
=
{
columns
:
this
.
columns
,
source
:
TRIALS
.
table
(
this
.
props
.
trialIds
)
};
this
.
state
=
{
columns
:
this
.
columns
,
source
:
TRIALS
.
table
(
this
.
props
.
trialIds
),
innerWidth
:
window
.
innerWidth
};
}
}
private
onRenderRow
:
IDetailsListProps
[
'
onRenderRow
'
]
=
props
=>
{
private
onRenderRow
:
IDetailsListProps
[
'
onRenderRow
'
]
=
props
=>
{
...
@@ -70,8 +76,8 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
...
@@ -70,8 +76,8 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
name
:
'
Trial No.
'
,
name
:
'
Trial No.
'
,
key
:
'
sequenceId
'
,
key
:
'
sequenceId
'
,
fieldName
:
'
sequenceId
'
,
// required!
fieldName
:
'
sequenceId
'
,
// required!
minWidth
:
60
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
120
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
isResizable
:
true
,
isResizable
:
true
,
data
:
'
number
'
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
onColumnClick
:
this
.
onColumnClick
...
@@ -80,8 +86,8 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
...
@@ -80,8 +86,8 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
name
:
'
ID
'
,
name
:
'
ID
'
,
key
:
'
id
'
,
key
:
'
id
'
,
fieldName
:
'
id
'
,
fieldName
:
'
id
'
,
minWidth
:
80
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
100
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
isResizable
:
true
,
isResizable
:
true
,
className
:
'
tableHead leftTitle
'
,
className
:
'
tableHead leftTitle
'
,
data
:
'
string
'
,
data
:
'
string
'
,
...
@@ -90,8 +96,8 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
...
@@ -90,8 +96,8 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
{
{
name
:
'
Duration
'
,
name
:
'
Duration
'
,
key
:
'
duration
'
,
key
:
'
duration
'
,
minWidth
:
100
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
210
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
isResizable
:
true
,
isResizable
:
true
,
fieldName
:
'
duration
'
,
fieldName
:
'
duration
'
,
data
:
'
number
'
,
data
:
'
number
'
,
...
@@ -105,8 +111,8 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
...
@@ -105,8 +111,8 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
{
{
name
:
'
Status
'
,
name
:
'
Status
'
,
key
:
'
status
'
,
key
:
'
status
'
,
minWidth
:
140
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
maxWidth
:
210
,
maxWidth
:
(
window
.
innerWidth
*
0.333
-
150
)
/
5
,
isResizable
:
true
,
isResizable
:
true
,
fieldName
:
'
status
'
,
fieldName
:
'
status
'
,
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
{
onRender
:
(
item
:
any
):
React
.
ReactNode
=>
{
...
@@ -117,8 +123,8 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
...
@@ -117,8 +123,8 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
name
:
'
Default metric
'
,
name
:
'
Default metric
'
,
key
:
'
accuracy
'
,
key
:
'
accuracy
'
,
fieldName
:
'
accuracy
'
,
fieldName
:
'
accuracy
'
,
minWidth
:
120
,
minWidth
:
(
window
.
innerWidth
*
0.333
-
200
)
/
5
,
maxWidth
:
360
,
//
maxWidth:
(window.innerWidth * 0.333 - 150) / 5
,
isResizable
:
true
,
isResizable
:
true
,
data
:
'
number
'
,
data
:
'
number
'
,
onColumnClick
:
this
.
onColumnClick
,
onColumnClick
:
this
.
onColumnClick
,
...
@@ -128,6 +134,17 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
...
@@ -128,6 +134,17 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
}
}
];
];
setInnerWidth
=
():
void
=>
{
this
.
setState
(()
=>
({
innerWidth
:
window
.
innerWidth
}));
};
componentDidMount
():
void
{
window
.
addEventListener
(
'
resize
'
,
this
.
setInnerWidth
);
}
componentWillUnmount
():
void
{
window
.
removeEventListener
(
'
resize
'
,
this
.
setInnerWidth
);
}
componentDidUpdate
(
prevProps
:
SuccessTableProps
):
void
{
componentDidUpdate
(
prevProps
:
SuccessTableProps
):
void
{
if
(
this
.
props
.
trialIds
!==
prevProps
.
trialIds
)
{
if
(
this
.
props
.
trialIds
!==
prevProps
.
trialIds
)
{
const
{
trialIds
}
=
this
.
props
;
const
{
trialIds
}
=
this
.
props
;
...
@@ -138,7 +155,6 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
...
@@ -138,7 +155,6 @@ class SuccessTable extends React.Component<SuccessTableProps, SuccessTableState>
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
{
columns
,
source
}
=
this
.
state
;
const
{
columns
,
source
}
=
this
.
state
;
const
isNoneData
=
source
.
length
===
0
?
true
:
false
;
const
isNoneData
=
source
.
length
===
0
?
true
:
false
;
return
(
return
(
<
div
id
=
'succTable'
>
<
div
id
=
'succTable'
>
<
DetailsList
<
DetailsList
...
...
src/webui/src/components/public-child/ExpandableDetails.tsx
0 → 100644
View file @
f1105409
import
*
as
React
from
'
react
'
;
import
{
DetailsRow
,
IDetailsRowBaseProps
}
from
'
@fluentui/react
'
;
import
OpenRow
from
'
../public-child/OpenRow
'
;
interface
ExpandableDetailsProps
{
detailsProps
:
IDetailsRowBaseProps
;
isExpand
:
boolean
;
}
class
ExpandableDetails
extends
React
.
Component
<
ExpandableDetailsProps
,
{}
>
{
render
():
React
.
ReactNode
{
const
{
detailsProps
,
isExpand
}
=
this
.
props
;
return
(
<
div
>
<
DetailsRow
{
...
detailsProps
}
/>
{
isExpand
&&
<
OpenRow
trialId
=
{
detailsProps
.
item
.
id
}
/>
}
</
div
>
);
}
}
export
default
ExpandableDetails
;
src/webui/src/components/public-child/OpenRow.tsx
View file @
f1105409
...
@@ -8,7 +8,7 @@ import JSONTree from 'react-json-tree';
...
@@ -8,7 +8,7 @@ import JSONTree from 'react-json-tree';
import
PaiTrialLog
from
'
../public-child/PaiTrialLog
'
;
import
PaiTrialLog
from
'
../public-child/PaiTrialLog
'
;
import
TrialLog
from
'
../public-child/TrialLog
'
;
import
TrialLog
from
'
../public-child/TrialLog
'
;
import
MessageInfo
from
'
../modals/MessageInfo
'
;
import
MessageInfo
from
'
../modals/MessageInfo
'
;
import
'
../../static/style/overview.scss
'
;
import
'
../../static/style/overview
/overview
.scss
'
;
import
'
../../static/style/copyParameter.scss
'
;
import
'
../../static/style/copyParameter.scss
'
;
import
'
../../static/style/openRow.scss
'
;
import
'
../../static/style/openRow.scss
'
;
...
...
src/webui/src/components/public-child/PaginationTable.tsx
0 → 100644
View file @
f1105409
import
*
as
React
from
'
react
'
;
import
{
DetailsList
,
Dropdown
,
Icon
,
IDetailsListProps
,
IDropdownOption
,
IStackTokens
,
Stack
}
from
'
@fluentui/react
'
;
import
ReactPaginate
from
'
react-paginate
'
;
interface
PaginationTableState
{
itemsPerPage
:
number
;
currentPage
:
number
;
itemsOnPage
:
any
[];
// this needs to be stored in state to prevent re-rendering
}
const
horizontalGapStackTokens
:
IStackTokens
=
{
childrenGap
:
20
,
padding
:
10
};
function
_currentTableOffset
(
perPage
:
number
,
currentPage
:
number
,
source
:
any
[]):
number
{
return
perPage
===
-
1
?
0
:
Math
.
min
(
currentPage
,
Math
.
floor
((
source
.
length
-
1
)
/
perPage
))
*
perPage
;
}
function
_obtainPaginationSlice
(
perPage
:
number
,
currentPage
:
number
,
source
:
any
[]):
any
[]
{
if
(
perPage
===
-
1
)
{
return
source
;
}
else
{
const
offset
=
_currentTableOffset
(
perPage
,
currentPage
,
source
);
return
source
.
slice
(
offset
,
offset
+
perPage
);
}
}
class
PaginationTable
extends
React
.
PureComponent
<
IDetailsListProps
,
PaginationTableState
>
{
constructor
(
props
:
IDetailsListProps
)
{
super
(
props
);
this
.
state
=
{
itemsPerPage
:
20
,
currentPage
:
0
,
itemsOnPage
:
[]
};
}
private
_onItemsPerPageSelect
(
event
:
React
.
FormEvent
<
HTMLDivElement
>
,
item
:
IDropdownOption
|
undefined
):
void
{
if
(
item
!==
undefined
)
{
const
{
items
}
=
this
.
props
;
// use current offset to calculate the next `current_page`
const
currentOffset
=
_currentTableOffset
(
this
.
state
.
itemsPerPage
,
this
.
state
.
currentPage
,
items
);
const
itemsPerPage
=
item
.
key
as
number
;
const
currentPage
=
Math
.
floor
(
currentOffset
/
itemsPerPage
);
this
.
setState
({
itemsPerPage
:
itemsPerPage
,
currentPage
:
currentPage
,
itemsOnPage
:
_obtainPaginationSlice
(
itemsPerPage
,
currentPage
,
this
.
props
.
items
)
});
}
}
private
_onPageSelect
(
event
:
any
):
void
{
const
currentPage
=
event
.
selected
;
this
.
setState
({
currentPage
:
currentPage
,
itemsOnPage
:
_obtainPaginationSlice
(
this
.
state
.
itemsPerPage
,
currentPage
,
this
.
props
.
items
)
});
}
componentDidUpdate
(
prevProps
:
IDetailsListProps
):
void
{
if
(
prevProps
.
items
!==
this
.
props
.
items
)
{
this
.
setState
({
itemsOnPage
:
_obtainPaginationSlice
(
this
.
state
.
itemsPerPage
,
this
.
state
.
currentPage
,
this
.
props
.
items
)
});
}
}
render
():
React
.
ReactNode
{
const
{
itemsPerPage
,
itemsOnPage
}
=
this
.
state
;
const
detailListProps
=
{
...
this
.
props
,
items
:
itemsOnPage
};
const
itemsCount
=
this
.
props
.
items
.
length
;
const
pageCount
=
itemsPerPage
===
-
1
?
1
:
Math
.
ceil
(
itemsCount
/
itemsPerPage
);
const
perPageOptions
=
[
{
key
:
10
,
text
:
'
10 items per page
'
},
{
key
:
20
,
text
:
'
20 items per page
'
},
{
key
:
50
,
text
:
'
50 items per page
'
},
{
key
:
-
1
,
text
:
'
All items
'
}
];
return
(
<
div
>
<
DetailsList
{
...
detailListProps
}
/>
<
Stack
horizontal
horizontalAlign
=
'end'
verticalAlign
=
'baseline'
styles
=
{
{
root
:
{
padding
:
10
}
}
}
tokens
=
{
horizontalGapStackTokens
}
>
<
Dropdown
selectedKey
=
{
itemsPerPage
}
options
=
{
perPageOptions
}
onChange
=
{
this
.
_onItemsPerPageSelect
.
bind
(
this
)
}
styles
=
{
{
dropdown
:
{
width
:
150
}
}
}
/>
<
ReactPaginate
previousLabel
=
{
<
Icon
aria
-
hidden
=
{
true
}
iconName
=
'ChevronLeft'
/>
}
nextLabel
=
{
<
Icon
aria
-
hidden
=
{
true
}
iconName
=
'ChevronRight'
/>
}
breakLabel
=
{
'
...
'
}
breakClassName
=
{
'
break
'
}
pageCount
=
{
pageCount
}
marginPagesDisplayed
=
{
2
}
pageRangeDisplayed
=
{
2
}
onPageChange
=
{
this
.
_onPageSelect
.
bind
(
this
)
}
containerClassName
=
{
itemsCount
===
0
?
'
pagination hidden
'
:
'
pagination
'
}
subContainerClassName
=
{
'
pages pagination
'
}
disableInitialCallback
=
{
false
}
activeClassName
=
{
'
active
'
}
/>
</
Stack
>
</
div
>
);
}
}
export
default
PaginationTable
;
src/webui/src/components/public-child/config/TrialConfigButton.tsx
0 → 100644
View file @
f1105409
import
React
,
{
useState
,
useCallback
}
from
'
react
'
;
import
{
DefaultButton
,
Stack
}
from
'
@fluentui/react
'
;
import
TrialConfigPanel
from
'
./TrialConfigPanel
'
;
import
'
../../../static/style/overview/config.scss
'
;
export
const
TrialConfigButton
=
():
any
=>
{
const
[
isShowConfigPanel
,
setShowConfigPanle
]
=
useState
(
false
);
const
[
activeTab
,
setActiveTab
]
=
useState
(
'
1
'
);
const
hideConfigPanel
=
useCallback
(()
=>
setShowConfigPanle
(
false
),
[]);
const
showTrialConfigpPanel
=
useCallback
(()
=>
{
setShowConfigPanle
(
true
);
setActiveTab
(
'
config
'
);
},
[]);
const
showSearchSpacePanel
=
useCallback
(()
=>
{
setShowConfigPanle
(
true
);
setActiveTab
(
'
search space
'
);
},
[]);
return
(
<
React
.
Fragment
>
<
Stack
className
=
'config'
>
<
DefaultButton
text
=
'Config'
onClick
=
{
showTrialConfigpPanel
}
/>
<
DefaultButton
text
=
'Search space'
onClick
=
{
showSearchSpacePanel
}
/>
</
Stack
>
{
isShowConfigPanel
&&
<
TrialConfigPanel
hideConfigPanel
=
{
hideConfigPanel
}
activeTab
=
{
activeTab
}
/>
}
</
React
.
Fragment
>
);
};
src/webui/src/components/public-child/config/TrialConfigPanel.tsx
0 → 100644
View file @
f1105409
import
*
as
React
from
'
react
'
;
import
{
Stack
,
Panel
,
Pivot
,
PivotItem
,
PrimaryButton
}
from
'
@fluentui/react
'
;
import
{
EXPERIMENT
}
from
'
../../../static/datamodel
'
;
import
MonacoEditor
from
'
react-monaco-editor
'
;
import
{
MONACO
}
from
'
../../../static/const
'
;
import
{
convertDuration
}
from
'
../../../static/function
'
;
import
{
prettyStringify
}
from
'
../../../static/json_util
'
;
import
lodash
from
'
lodash
'
;
import
'
../../../static/style/logDrawer.scss
'
;
interface
LogDrawerProps
{
hideConfigPanel
:
()
=>
void
;
activeTab
?:
string
;
}
interface
LogDrawerState
{
panelInnerHeight
:
number
;
}
class
TrialConfigPanel
extends
React
.
Component
<
LogDrawerProps
,
LogDrawerState
>
{
constructor
(
props
:
LogDrawerProps
)
{
super
(
props
);
this
.
state
=
{
panelInnerHeight
:
window
.
innerHeight
};
}
setLogDrawerHeight
():
void
{
this
.
setState
(()
=>
({
panelInnerHeight
:
window
.
innerHeight
}));
}
async
componentDidMount
():
Promise
<
void
>
{
window
.
addEventListener
(
'
resize
'
,
this
.
setLogDrawerHeight
);
}
componentWillUnmount
():
void
{
window
.
removeEventListener
(
'
resize
'
,
this
.
setLogDrawerHeight
);
}
render
():
React
.
ReactNode
{
const
{
hideConfigPanel
,
activeTab
}
=
this
.
props
;
const
{
panelInnerHeight
}
=
this
.
state
;
// [marginTop 16px] + [Search space 46px] +
// button[height: 32px, marginTop: 45px, marginBottom: 25px] + [padding-bottom: 20px]
const
monacoEditorHeight
=
panelInnerHeight
-
184
;
const
blacklist
=
[
'
id
'
,
'
logDir
'
,
'
startTime
'
,
'
endTime
'
,
'
experimentName
'
,
'
searchSpace
'
,
'
trainingServicePlatform
'
];
const
filter
=
(
key
:
string
,
val
:
any
):
any
=>
{
return
blacklist
.
includes
(
key
)
?
undefined
:
val
;
};
const
profile
=
lodash
.
cloneDeep
(
EXPERIMENT
.
profile
);
profile
.
execDuration
=
convertDuration
(
profile
.
execDuration
);
profile
.
params
.
maxExecDuration
=
convertDuration
(
profile
.
params
.
maxExecDuration
);
const
showProfile
=
JSON
.
stringify
(
profile
,
filter
,
2
);
return
(
<
Stack
>
<
Panel
isOpen
=
{
true
}
hasCloseButton
=
{
false
}
isFooterAtBottom
=
{
true
}
isLightDismiss
=
{
true
}
onLightDismissClick
=
{
hideConfigPanel
}
>
<
div
className
=
'log-tab-body'
>
<
Pivot
initialSelectedKey
=
{
activeTab
}
style
=
{
{
minHeight
:
190
,
paddingTop
:
'
16px
'
}
}
>
<
PivotItem
headerText
=
'Search space'
itemKey
=
'search space'
>
<
MonacoEditor
height
=
{
monacoEditorHeight
}
language
=
'json'
theme
=
'vs-light'
value
=
{
prettyStringify
(
EXPERIMENT
.
searchSpace
,
300
,
2
)
}
options
=
{
MONACO
}
/>
</
PivotItem
>
<
PivotItem
headerText
=
'Config'
itemKey
=
'config'
>
<
div
className
=
'profile'
>
<
MonacoEditor
width
=
'100%'
height
=
{
monacoEditorHeight
}
language
=
'json'
theme
=
'vs-light'
value
=
{
showProfile
}
options
=
{
MONACO
}
/>
</
div
>
</
PivotItem
>
</
Pivot
>
</
div
>
<
PrimaryButton
text
=
'Close'
className
=
'configClose'
onClick
=
{
hideConfigPanel
}
/>
</
Panel
>
</
Stack
>
);
}
}
export
default
TrialConfigPanel
;
src/webui/src/components/stateless-component/NNItabs.tsx
View file @
f1105409
...
@@ -15,7 +15,7 @@ const DETAILTABS = (
...
@@ -15,7 +15,7 @@ const DETAILTABS = (
const
NNILOGO
=
(
const
NNILOGO
=
(
<
NavLink
to
=
{
'
/oview
'
}
>
<
NavLink
to
=
{
'
/oview
'
}
>
<
img
src
=
{
require
(
'
../../static/img/logo
2
.png
'
)
}
alt
=
'NNI logo'
style
=
{
{
height
:
40
}
}
/>
<
img
src
=
{
require
(
'
../../static/img/logo.png
'
)
}
alt
=
'NNI logo'
style
=
{
{
height
:
40
}
}
/>
</
NavLink
>
</
NavLink
>
);
);
...
...
src/webui/src/components/trial-detail/Para.tsx
View file @
f1105409
import
*
as
d3
from
'
d3
'
;
import
*
as
d3
from
'
d3
'
;
import
{
Dropdown
,
IDropdownOption
,
Stack
}
from
'
@fluentui/react
'
;
import
{
Dropdown
,
IDropdownOption
,
Stack
,
DefaultButton
}
from
'
@fluentui/react
'
;
import
ParCoords
from
'
parcoord-es
'
;
import
ParCoords
from
'
parcoord-es
'
;
import
'
parcoord-es/dist/parcoords.css
'
;
import
'
parcoord-es/dist/parcoords.css
'
;
import
*
as
React
from
'
react
'
;
import
*
as
React
from
'
react
'
;
...
@@ -9,12 +9,16 @@ import { filterByStatus } from '../../static/function';
...
@@ -9,12 +9,16 @@ import { filterByStatus } from '../../static/function';
import
{
TableObj
,
SingleAxis
,
MultipleAxes
}
from
'
../../static/interface
'
;
import
{
TableObj
,
SingleAxis
,
MultipleAxes
}
from
'
../../static/interface
'
;
import
'
../../static/style/button.scss
'
;
import
'
../../static/style/button.scss
'
;
import
'
../../static/style/para.scss
'
;
import
'
../../static/style/para.scss
'
;
import
ChangeColumnComponent
from
'
../modals/ChangeColumnComponent
'
;
interface
ParaState
{
interface
ParaState
{
dimName
:
string
[];
dimName
:
string
[];
selectedPercent
:
string
;
selectedPercent
:
string
;
primaryMetricKey
:
string
;
primaryMetricKey
:
string
;
noChart
:
boolean
;
noChart
:
boolean
;
customizeColumnsDialogVisible
:
boolean
;
availableDimensions
:
string
[];
chosenDimensions
:
string
[];
}
}
interface
ParaProps
{
interface
ParaProps
{
...
@@ -45,7 +49,10 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -45,7 +49,10 @@ class Para extends React.Component<ParaProps, ParaState> {
dimName
:
[],
dimName
:
[],
primaryMetricKey
:
'
default
'
,
primaryMetricKey
:
'
default
'
,
selectedPercent
:
'
1
'
,
selectedPercent
:
'
1
'
,
noChart
:
true
noChart
:
true
,
customizeColumnsDialogVisible
:
false
,
availableDimensions
:
[],
chosenDimensions
:
[]
};
};
}
}
...
@@ -82,11 +89,24 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -82,11 +89,24 @@ class Para extends React.Component<ParaProps, ParaState> {
}
}
render
():
React
.
ReactNode
{
render
():
React
.
ReactNode
{
const
{
selectedPercent
,
noChart
}
=
this
.
state
;
const
{
selectedPercent
,
noChart
,
customizeColumnsDialogVisible
,
availableDimensions
,
chosenDimensions
}
=
this
.
state
;
return
(
return
(
<
div
className
=
'parameter'
>
<
div
className
=
'parameter'
>
<
Stack
horizontal
className
=
'para-filter'
horizontalAlign
=
'end'
>
<
Stack
horizontal
className
=
'para-filter'
horizontalAlign
=
'end'
>
<
DefaultButton
text
=
'Add/Remove axes'
onClick
=
{
():
void
=>
{
this
.
setState
({
customizeColumnsDialogVisible
:
true
});
}
}
styles
=
{
{
root
:
{
marginRight
:
10
}
}
}
/>
<
Dropdown
<
Dropdown
selectedKey
=
{
selectedPercent
}
selectedKey
=
{
selectedPercent
}
onChange
=
{
this
.
percentNum
}
onChange
=
{
this
.
percentNum
}
...
@@ -101,6 +121,21 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -101,6 +121,21 @@ class Para extends React.Component<ParaProps, ParaState> {
/>
/>
{
this
.
finalKeysDropdown
()
}
{
this
.
finalKeysDropdown
()
}
</
Stack
>
</
Stack
>
{
customizeColumnsDialogVisible
&&
availableDimensions
.
length
>
0
&&
(
<
ChangeColumnComponent
selectedColumns
=
{
chosenDimensions
}
allColumns
=
{
availableDimensions
.
map
(
dim
=>
({
key
:
dim
,
name
:
dim
}))
}
onSelectedChange
=
{
(
selected
:
string
[]):
void
=>
{
this
.
setState
({
chosenDimensions
:
selected
},
()
=>
{
this
.
renderParallelCoordinates
();
});
}
}
onHideDialog
=
{
():
void
=>
{
this
.
setState
({
customizeColumnsDialogVisible
:
false
});
}
}
minSelected
=
{
2
}
/>
)
}
<
div
className
=
'parcoords'
style
=
{
this
.
chartMulineStyle
}
ref
=
{
this
.
paraRef
}
/>
<
div
className
=
'parcoords'
style
=
{
this
.
chartMulineStyle
}
ref
=
{
this
.
paraRef
}
/>
{
noChart
&&
<
div
className
=
'nodata'
>
No data
</
div
>
}
{
noChart
&&
<
div
className
=
'nodata'
>
No data
</
div
>
}
</
div
>
</
div
>
...
@@ -143,13 +178,13 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -143,13 +178,13 @@ class Para extends React.Component<ParaProps, ParaState> {
private
renderParallelCoordinates
():
void
{
private
renderParallelCoordinates
():
void
{
const
{
searchSpace
}
=
this
.
props
;
const
{
searchSpace
}
=
this
.
props
;
const
percent
=
parseFloat
(
this
.
state
.
selectedPercent
);
const
percent
=
parseFloat
(
this
.
state
.
selectedPercent
);
const
{
primaryMetricKey
}
=
this
.
state
;
const
{
primaryMetricKey
,
chosenDimensions
}
=
this
.
state
;
const
inferredSearchSpace
=
TRIALS
.
inferredSearchSpace
(
searchSpace
);
const
inferredSearchSpace
=
TRIALS
.
inferredSearchSpace
(
searchSpace
);
const
inferredMetricSpace
=
TRIALS
.
inferredMetricSpace
();
const
inferredMetricSpace
=
TRIALS
.
inferredMetricSpace
();
let
convertedTrials
=
this
.
getTrialsAsObjectList
(
inferredSearchSpace
,
inferredMetricSpace
);
let
convertedTrials
=
this
.
getTrialsAsObjectList
(
inferredSearchSpace
,
inferredMetricSpace
);
const
dimensions
:
[
any
,
any
][]
=
[];
const
dimensions
:
[
string
,
any
][]
=
[];
let
colorDim
:
string
|
undefined
=
undefined
,
let
colorDim
:
string
|
undefined
=
undefined
,
colorScale
:
any
=
undefined
;
colorScale
:
any
=
undefined
;
// treat every axis as numeric to fit for brush
// treat every axis as numeric to fit for brush
...
@@ -213,7 +248,11 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -213,7 +248,11 @@ class Para extends React.Component<ParaProps, ParaState> {
}
}
this
.
pcs
this
.
pcs
.
data
(
convertedTrials
)
.
data
(
convertedTrials
)
.
dimensions
(
dimensions
.
reduce
((
obj
,
entry
)
=>
({
...
obj
,
[
entry
[
0
]]:
entry
[
1
]
}),
{}));
.
dimensions
(
dimensions
.
filter
(([
d
,
_
])
=>
chosenDimensions
.
length
===
0
||
chosenDimensions
.
includes
(
d
))
.
reduce
((
obj
,
entry
)
=>
({
...
obj
,
[
entry
[
0
]]:
entry
[
1
]
}),
{})
);
if
(
firstRun
)
{
if
(
firstRun
)
{
this
.
pcs
this
.
pcs
.
margin
(
this
.
innerChartMargins
)
.
margin
(
this
.
innerChartMargins
)
...
@@ -230,6 +269,12 @@ class Para extends React.Component<ParaProps, ParaState> {
...
@@ -230,6 +269,12 @@ class Para extends React.Component<ParaProps, ParaState> {
if
(
firstRun
)
{
if
(
firstRun
)
{
this
.
setState
({
noChart
:
false
});
this
.
setState
({
noChart
:
false
});
}
}
// set new available dims
this
.
setState
({
availableDimensions
:
dimensions
.
map
(
e
=>
e
[
0
]),
chosenDimensions
:
chosenDimensions
.
length
===
0
?
dimensions
.
map
(
e
=>
e
[
0
])
:
chosenDimensions
});
}
}
private
getTrialsAsObjectList
(
inferredSearchSpace
:
MultipleAxes
,
inferredMetricSpace
:
MultipleAxes
):
{}[]
{
private
getTrialsAsObjectList
(
inferredSearchSpace
:
MultipleAxes
,
inferredMetricSpace
:
MultipleAxes
):
{}[]
{
...
...
src/webui/src/components/trial-detail/TableList.tsx
View file @
f1105409
This diff is collapsed.
Click to expand it.
src/webui/src/index.tsx
View file @
f1105409
...
@@ -5,13 +5,20 @@ import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-d
...
@@ -5,13 +5,20 @@ import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-d
const
Overview
=
lazy
(()
=>
import
(
'
./components/Overview
'
));
const
Overview
=
lazy
(()
=>
import
(
'
./components/Overview
'
));
const
TrialsDetail
=
lazy
(()
=>
import
(
'
./components/TrialsDetail
'
));
const
TrialsDetail
=
lazy
(()
=>
import
(
'
./components/TrialsDetail
'
));
import
'
./index.css
'
;
import
'
./index.css
'
;
import
'
./static/style/loading.scss
'
;
import
*
as
serviceWorker
from
'
./serviceWorker
'
;
import
*
as
serviceWorker
from
'
./serviceWorker
'
;
ReactDOM
.
render
(
ReactDOM
.
render
(
<
Router
>
<
Router
>
<
App
>
<
App
>
<
Switch
>
<
Switch
>
<
Suspense
fallback
=
{
null
}
>
<
Suspense
fallback
=
{
<
div
className
=
'loading'
>
<
img
src
=
{
require
(
'
./static/img/loading.gif
'
)
}
/>
</
div
>
}
>
<
Route
path
=
'/oview'
component
=
{
Overview
}
/>
<
Route
path
=
'/oview'
component
=
{
Overview
}
/>
<
Route
path
=
'/detail'
component
=
{
TrialsDetail
}
/>
<
Route
path
=
'/detail'
component
=
{
TrialsDetail
}
/>
<
Route
path
=
'/'
render
=
{
():
React
.
ReactNode
=>
<
Redirect
to
=
{
{
pathname
:
'
/oview
'
}
}
/>
}
/>
<
Route
path
=
'/'
render
=
{
():
React
.
ReactNode
=>
<
Redirect
to
=
{
{
pathname
:
'
/oview
'
}
}
/>
}
/>
...
...
src/webui/src/static/const.ts
View file @
f1105409
...
@@ -15,7 +15,7 @@ const trialJobStatus = [
...
@@ -15,7 +15,7 @@ const trialJobStatus = [
'
SYS_CANCELED
'
,
'
SYS_CANCELED
'
,
'
EARLY_STOPPED
'
'
EARLY_STOPPED
'
];
];
const
CONTROLTYPE
=
[
'
SEARCH_SPACE
'
,
'
TRIAL_CONCURRENCY
'
,
'
MAX_EXEC_DURATION
'
];
const
CONTROLTYPE
=
[
'
MAX_EXEC_DURATION
'
,
'
MAX_TRIAL_NUM
'
,
'
TRIAL_CONCURRENCY
'
,
'
SEARCH_SPACE
'
];
const
MONACO
=
{
const
MONACO
=
{
readOnly
:
true
,
readOnly
:
true
,
automaticLayout
:
true
,
automaticLayout
:
true
,
...
...
Prev
1
2
3
4
Next
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