Unverified Commit e2d8cc1b authored by Lijiaoa's avatar Lijiaoa Committed by GitHub
Browse files

[webui] format code by eslint and prettier (#2744)



* update

* format as prettier

* fix error

* add stylelint for scss css file

* add arrow-parens rule

* update

* fix lint

* fix conflict
Co-authored-by: default avatarLijiao <15910218274@163.com>
Co-authored-by: default avatarLijiao <Lijiaoa@outlook.com>
Co-authored-by: default avatarLijiao <1425861283@qq.com>
parent 4668fc08
......@@ -23,16 +23,13 @@ interface DurationState {
}
class Duration extends React.Component<DurationProps, DurationState> {
constructor(props: DurationProps) {
super(props);
this.state = {
startDuration: 0, // for record data zoom
endDuration: 100,
durationSource: this.initDuration(this.props.source),
durationSource: this.initDuration(this.props.source)
};
}
initDuration = (source: Array<TableObj>): any => {
......@@ -50,12 +47,15 @@ class Duration extends React.Component<DurationProps, DurationState> {
axisPointer: {
type: 'shadow'
},
formatter: (data: any): React.ReactNode => (
formatter: (data: any): React.ReactNode =>
'<div>' +
'<div>Trial No.: ' + data[0].dataIndex + '</div>' +
'<div>Duration: ' + convertDuration(data[0].data) + '</div>' +
'<div>Trial No.: ' +
data[0].dataIndex +
'</div>' +
'<div>Duration: ' +
convertDuration(data[0].data) +
'</div>' +
'</div>'
),
},
grid: {
bottom: '3%',
......@@ -71,11 +71,11 @@ class Duration extends React.Component<DurationProps, DurationState> {
filterMode: 'empty',
start: 0,
end: 100
},
}
],
xAxis: {
name: 'Time/s',
type: 'value',
type: 'value'
},
yAxis: {
name: 'Trial No.',
......@@ -85,12 +85,14 @@ class Duration extends React.Component<DurationProps, DurationState> {
padding: [0, 0, 0, 30]
}
},
series: [{
type: 'bar',
data: trialTime
}]
series: [
{
type: 'bar',
data: trialTime
}
]
};
}
};
getOption = (dataObj: Runtrial): any => {
const { startDuration, endDuration } = this.state;
......@@ -100,12 +102,15 @@ class Duration extends React.Component<DurationProps, DurationState> {
axisPointer: {
type: 'shadow'
},
formatter: (data: any): React.ReactNode => (
formatter: (data: any): React.ReactNode =>
'<div>' +
'<div>Trial No.: ' + data[0].dataIndex + '</div>' +
'<div>Duration: ' + convertDuration(data[0].data) + '</div>' +
'<div>Trial No.: ' +
data[0].dataIndex +
'</div>' +
'<div>Duration: ' +
convertDuration(data[0].data) +
'</div>' +
'</div>'
),
},
grid: {
bottom: '3%',
......@@ -121,11 +126,11 @@ class Duration extends React.Component<DurationProps, DurationState> {
filterMode: 'empty',
start: startDuration,
end: endDuration
},
}
],
xAxis: {
name: 'Time',
type: 'value',
type: 'value'
},
yAxis: {
name: 'Trial',
......@@ -135,12 +140,14 @@ class Duration extends React.Component<DurationProps, DurationState> {
padding: [0, 0, 0, 30]
}
},
series: [{
type: 'bar',
data: dataObj.trialTime
}]
series: [
{
type: 'bar',
data: dataObj.trialTime
}
]
};
}
};
drawDurationGraph = (source: Array<TableObj>): void => {
// why this function run two times when props changed?
......@@ -160,7 +167,7 @@ class Duration extends React.Component<DurationProps, DurationState> {
this.setState({
durationSource: this.getOption(trialRun[0])
});
}
};
componentDidMount(): void {
const { source } = this.props;
......@@ -178,13 +185,13 @@ class Duration extends React.Component<DurationProps, DurationState> {
render(): React.ReactNode {
const { durationSource } = this.state;
const onEvents = { 'dataZoom': this.durationDataZoom };
const onEvents = { dataZoom: this.durationDataZoom };
return (
<div>
<ReactEcharts
option={durationSource}
style={{ width: '94%', height: 412, margin: '0 auto', marginTop: 15 }}
theme="my_theme"
theme='my_theme'
notMerge={true} // update now
onEvents={onEvents}
/>
......@@ -195,11 +202,11 @@ class Duration extends React.Component<DurationProps, DurationState> {
private durationDataZoom = (e: EventMap): void => {
if (e.batch !== undefined) {
this.setState(() => ({
startDuration: (e.batch[0].start !== null ? e.batch[0].start : 0),
endDuration: (e.batch[0].end !== null ? e.batch[0].end : 100)
startDuration: e.batch[0].start !== null ? e.batch[0].start : 0,
endDuration: e.batch[0].end !== null ? e.batch[0].end : 100
}));
}
}
};
}
export default Duration;
......@@ -28,7 +28,6 @@ interface IntermediateProps {
}
class Intermediate extends React.Component<IntermediateProps, IntermediateState> {
static intervalMediate = 1;
public pointInput!: HTMLInputElement | null;
public minValInput!: HTMLInputElement | null;
......@@ -68,7 +67,9 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
});
});
// find max intermediate number
trialIntermediate.sort((a, b) => { return (b.data.length - a.data.length); });
trialIntermediate.sort((a, b) => {
return b.data.length - a.data.length;
});
const legend: string[] = [];
// max length
const length = trialIntermediate[0].data.length;
......@@ -84,27 +85,35 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
tooltip: {
trigger: 'item',
enterable: true,
position: function (point: number[], data: TooltipForIntermediate): number[] {
position: function(point: number[], data: TooltipForIntermediate): number[] {
if (data.dataIndex < length / 2) {
return [point[0], 80];
} else {
return [point[0] - 300, 80];
}
},
formatter: function (data: TooltipForIntermediate): React.ReactNode {
formatter: function(data: TooltipForIntermediate): React.ReactNode {
const trialId = data.seriesName;
let obj = {};
const temp = trialIntermediate.find(key => key.name === trialId);
if (temp !== undefined) {
obj = temp.hyperPara;
}
return '<div class="tooldetailAccuracy">' +
'<div>Trial ID: ' + trialId + '</div>' +
'<div>Intermediate: ' + data.data + '</div>' +
return (
'<div class="tooldetailAccuracy">' +
'<div>Trial ID: ' +
trialId +
'</div>' +
'<div>Intermediate: ' +
data.data +
'</div>' +
'<div>Parameters: ' +
'<pre>' + JSON.stringify(obj, null, 4) + '</pre>' +
'<pre>' +
JSON.stringify(obj, null, 4) +
'</pre>' +
'</div>' +
'</div>';
'</div>'
);
}
},
grid: {
......@@ -121,7 +130,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
yAxis: {
type: 'value',
name: 'Metric',
scale: true,
scale: true
},
dataZoom: [
{
......@@ -147,7 +156,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
},
xAxis: {
type: 'category',
boundaryGap: false,
boundaryGap: false
},
yAxis: {
type: 'value',
......@@ -156,7 +165,7 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
};
this.setState({ interSource: nullData });
}
}
};
// confirm btn function [filter data]
filterLines = (): void => {
......@@ -198,14 +207,14 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
const counts = this.state.clickCounts + 1;
this.setState({ isLoadconfirmBtn: false, clickCounts: counts });
});
}
};
switchTurn = (ev: React.MouseEvent<HTMLElement>, checked?: boolean): void => {
this.setState({ isFilter: checked });
if (checked === false) {
this.drawIntermediate(this.props.source);
}
}
};
componentDidMount(): void {
const { source } = this.props;
......@@ -235,56 +244,47 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
render(): React.ReactNode {
const { interSource, isLoadconfirmBtn, isFilter } = this.state;
const IntermediateEvents = { 'dataZoom': this.intermediateDataZoom };
const IntermediateEvents = { dataZoom: this.intermediateDataZoom };
return (
<div>
{/* style in para.scss */}
<Stack horizontal horizontalAlign="end" tokens={stackTokens} className="meline intermediate">
{
isFilter
?
<div>
<span className="filter-x"># Intermediate result</span>
<input
// placeholder="point"
ref={(input): any => this.pointInput = input}
className="strange"
/>
<span>Metric range</span>
<input
// placeholder="range"
ref={(input): any => this.minValInput = input}
/>
<span className="hyphen">-</span>
<input
// placeholder="range"
ref={(input): any => this.maxValInput = input}
/>
<PrimaryButton
text="Confirm"
onClick={this.filterLines}
disabled={isLoadconfirmBtn}
/>
</div>
:
null
}
<Stack horizontal horizontalAlign='end' tokens={stackTokens} className='meline intermediate'>
{isFilter ? (
<div>
<span className='filter-x'># Intermediate result</span>
<input
// placeholder="point"
ref={(input): any => (this.pointInput = input)}
className='strange'
/>
<span>Metric range</span>
<input
// placeholder="range"
ref={(input): any => (this.minValInput = input)}
/>
<span className='hyphen'>-</span>
<input
// placeholder="range"
ref={(input): any => (this.maxValInput = input)}
/>
<PrimaryButton text='Confirm' onClick={this.filterLines} disabled={isLoadconfirmBtn} />
</div>
) : null}
{/* filter message */}
<Stack horizontal className="filter-toggle">
<Stack horizontal className='filter-toggle'>
<span>Filter</span>
<Toggle onChange={this.switchTurn} />
</Stack>
</Stack>
<div className="intermediate-graph">
<div className='intermediate-graph'>
<ReactEcharts
option={interSource}
style={{ width: '100%', height: 400, margin: '0 auto' }}
notMerge={true} // update now
onEvents={IntermediateEvents}
/>
<div className="xAxis"># Intermediate result</div>
<div className='xAxis'># Intermediate result</div>
</div>
</div>
);
......@@ -293,11 +293,11 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
private intermediateDataZoom = (e: EventMap): void => {
if (e.batch !== undefined) {
this.setState(() => ({
startMediaY: (e.batch[0].start !== null ? e.batch[0].start : 0),
endMediaY: (e.batch[0].end !== null ? e.batch[0].end : 100)
startMediaY: e.batch[0].start !== null ? e.batch[0].start : 0,
endMediaY: e.batch[0].end !== null ? e.batch[0].end : 100
}));
}
}
};
}
export default Intermediate;
......@@ -24,7 +24,6 @@ interface ParaProps {
}
class Para extends React.Component<ParaProps, ParaState> {
private paraRef = React.createRef<HTMLDivElement>();
private pcs: any;
......@@ -57,7 +56,7 @@ class Para extends React.Component<ParaProps, ParaState> {
this.renderParallelCoordinates();
});
}
}
};
// select all final keys
updateEntries = (event: React.FormEvent<HTMLDivElement>, item: any): void => {
......@@ -66,7 +65,7 @@ class Para extends React.Component<ParaProps, ParaState> {
this.renderParallelCoordinates();
});
}
}
};
componentDidMount(): void {
this.renderParallelCoordinates();
......@@ -86,8 +85,8 @@ class Para extends React.Component<ParaProps, ParaState> {
const { selectedPercent, noChart } = this.state;
return (
<div className="parameter">
<Stack horizontal className="para-filter" horizontalAlign="end">
<div className='parameter'>
<Stack horizontal className='para-filter' horizontalAlign='end'>
<Dropdown
selectedKey={selectedPercent}
onChange={this.percentNum}
......@@ -95,15 +94,15 @@ class Para extends React.Component<ParaProps, ParaState> {
{ key: '0.01', text: 'Top 1%' },
{ key: '0.05', text: 'Top 5%' },
{ key: '0.2', text: 'Top 20%' },
{ key: '1', text: 'Top 100%' },
{ key: '1', text: 'Top 100%' }
]}
styles={{ dropdown: { width: 120 } }}
className="para-filter-percent"
className='para-filter-percent'
/>
{this.finalKeysDropdown()}
</Stack>
<div className="parcoords" style={this.chartMulineStyle} ref={this.paraRef}/>
{noChart && <div className="nodata">No data</div>}
<div className='parcoords' style={this.chartMulineStyle} ref={this.paraRef} />
{noChart && <div className='nodata'>No data</div>}
</div>
);
}
......@@ -116,18 +115,19 @@ class Para extends React.Component<ParaProps, ParaState> {
const finalKeysDropdown: any = [];
TRIALS.finalKeys().forEach(item => {
finalKeysDropdown.push({
key: item, text: item
key: item,
text: item
});
});
return (
<div>
<span className="para-filter-text para-filter-middle">Metrics</span>
<span className='para-filter-text para-filter-middle'>Metrics</span>
<Dropdown
selectedKey={primaryMetricKey}
options={finalKeysDropdown}
onChange={this.updateEntries}
styles={{ root: { width: 150, display: 'inline-block' } }}
className="para-filter-percent"
className='para-filter-percent'
/>
</div>
);
......@@ -150,13 +150,17 @@ class Para extends React.Component<ParaProps, ParaState> {
let convertedTrials = this.getTrialsAsObjectList(inferredSearchSpace, inferredMetricSpace);
const dimensions: [any, any][] = [];
let colorDim: string | undefined = undefined, colorScale: any = undefined;
let colorDim: string | undefined = undefined,
colorScale: any = undefined;
// treat every axis as numeric to fit for brush
for (const [k, v] of inferredSearchSpace.axes) {
dimensions.push([k, {
type: 'number',
yscale: this.convertToD3Scale(v)
}]);
dimensions.push([
k,
{
type: 'number',
yscale: this.convertToD3Scale(v)
}
]);
}
for (const [k, v] of inferredMetricSpace.axes) {
const scale = this.convertToD3Scale(v);
......@@ -164,7 +168,7 @@ class Para extends React.Component<ParaProps, ParaState> {
// set color for primary metrics
// `colorScale` is used to produce a color range, while `scale` is to produce a pixel range
colorScale = this.convertToD3Scale(v, false);
convertedTrials.sort((a, b) => EXPERIMENT.optimizeMode === 'minimize' ? a[k] - b[k] : b[k] - a[k]);
convertedTrials.sort((a, b) => (EXPERIMENT.optimizeMode === 'minimize' ? a[k] - b[k] : b[k] - a[k]));
// filter top trials
if (percent != 1) {
const keptTrialNum = Math.max(Math.ceil(convertedTrials.length * percent), 1);
......@@ -179,20 +183,24 @@ class Para extends React.Component<ParaProps, ParaState> {
// reverse the converted trials to show the top ones upfront
convertedTrials.reverse();
const assignColors = (scale: any): void => {
scale.range([0, 1]); // fake a range to perform invert
scale.range([0, 1]); // fake a range to perform invert
const [scaleMin, scaleMax] = scale.domain();
const pivot = scale.invert(0.5);
scale.domain([scaleMin, pivot, scaleMax])
scale
.domain([scaleMin, pivot, scaleMax])
.range(['#90EE90', '#FFC400', '#CA0000'])
.interpolate(d3.interpolateHsl);
};
assignColors(colorScale);
colorDim = k;
}
dimensions.push([k, {
type: 'number',
yscale: scale
}]);
dimensions.push([
k,
{
type: 'number',
yscale: scale
}
]);
}
if (convertedTrials.length === 0 || dimensions.length <= 1) {
......@@ -203,13 +211,15 @@ class Para extends React.Component<ParaProps, ParaState> {
if (firstRun) {
this.pcs = ParCoords()(this.paraRef.current);
}
this.pcs.data(convertedTrials)
this.pcs
.data(convertedTrials)
.dimensions(dimensions.reduce((obj, entry) => ({ ...obj, [entry[0]]: entry[1] }), {}));
if (firstRun) {
this.pcs.margin(this.innerChartMargins)
this.pcs
.margin(this.innerChartMargins)
.alphaOnBrushed(0.2)
.smoothness(0.1)
.brushMode("1D-axes")
.brushMode('1D-axes')
.reorderable()
.interactive();
}
......@@ -228,7 +238,7 @@ class Para extends React.Component<ParaProps, ParaState> {
return succeededTrials.map(s => {
const entries = Array.from(s.parameters(inferredSearchSpace).entries());
entries.push(...(Array.from(s.metrics(inferredMetricSpace).entries())));
entries.push(...Array.from(s.metrics(inferredMetricSpace).entries()));
const ret = {};
for (const [k, v] of entries) {
ret[k.fullName] = v;
......@@ -247,20 +257,26 @@ class Para extends React.Component<ParaProps, ParaState> {
private convertToD3Scale(axis: SingleAxis, initRange: boolean = true): any {
const padLinear = ([x0, x1], k = 0.1): [number, number] => {
const dx = (x1 - x0) * k / 2;
const dx = ((x1 - x0) * k) / 2;
return [x0 - dx, x1 + dx];
};
const padLog = ([x0, x1], k = 0.1): [number, number] => {
const [y0, y1] = padLinear([Math.log(x0), Math.log(x1)], k);
return [Math.exp(y0), Math.exp(y1)];
}
};
let scaleInst: any = undefined;
if (axis.scale === 'ordinal') {
if (axis.nested) {
// TODO: handle nested entries
scaleInst = d3.scalePoint().domain(Array.from(axis.domain.keys())).padding(0.2);
scaleInst = d3
.scalePoint()
.domain(Array.from(axis.domain.keys()))
.padding(0.2);
} else {
scaleInst = d3.scalePoint().domain(axis.domain).padding(0.2);
scaleInst = d3
.scalePoint()
.domain(axis.domain)
.padding(0.2);
}
} else if (axis.scale === 'log') {
scaleInst = d3.scaleLog().domain(padLog(axis.domain));
......
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
line-height: 1;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
font-family:
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
'Roboto',
'Oxygen',
'Ubuntu',
'Cantarell',
'Fira Sans',
'Droid Sans',
'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
line-height: 1;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
font-family:
source-code-pro,
Menlo,
Monaco,
Consolas,
'Courier New',
monospace;
}
/* http://meyerweb.com/eric/tools/css/reset/
......@@ -21,46 +35,135 @@ code {
License: none (public domain)
*/
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
main, menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font: inherit;
font-size: 100%;
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
main,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font: inherit;
font-size: 100%;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, main, menu, nav, section {
display: block;
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section {
display: block;
}
/* HTML5 hidden-attribute fix for newer browsers */
*[hidden] {
display: none;
}
ol, ul {
list-style: none;
ol,
ul {
list-style: none;
}
blockquote, q {
quotes: none;
blockquote,
q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
blockquote::before,
blockquote::after,
q::before,
q::after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
border-collapse: collapse;
border-spacing: 0;
}
......@@ -8,21 +8,19 @@ import './index.css';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
(
<Router>
<App>
<Switch>
<Suspense fallback={null}>
<Route path="/oview" component={Overview} />
<Route path="/detail" component={TrialsDetail} />
<Route path="/" render={(): React.ReactNode => <Redirect to={{ pathname: '/oview' }} />} />
</Suspense>
</Switch>
</App>
</Router>
<App>
<Switch>
<Suspense fallback={null}>
<Route path='/oview' component={Overview} />
<Route path='/detail' component={TrialsDetail} />
<Route path='/' render={(): React.ReactNode => <Redirect to={{ pathname: '/oview' }} />} />
</Suspense>
</Switch>
</App>
</Router>,
),
document.getElementById('root')
document.getElementById('root')
);
// If you want your app to work offline and load faster, you can change
......
declare namespace NodeJS {
interface ProcessEnv {
readonly NODE_ENV: 'development' | 'production' | 'test';
readonly PUBLIC_URL: string;
}
interface ProcessEnv {
readonly NODE_ENV: 'development' | 'production' | 'test';
readonly PUBLIC_URL: string;
}
}
declare module '*.bmp' {
const src: string;
export default src;
const src: string;
export default src;
}
declare module '*.gif' {
const src: string;
export default src;
const src: string;
export default src;
}
declare module '*.jpg' {
const src: string;
export default src;
const src: string;
export default src;
}
declare module '*.jpeg' {
const src: string;
export default src;
const src: string;
export default src;
}
declare module '*.png' {
const src: string;
export default src;
const src: string;
export default src;
}
declare module '*.webp' {
......@@ -36,25 +36,25 @@ declare module '*.webp' {
}
declare module '*.svg' {
import * as React from 'react';
import * as React from 'react';
export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
export const ReactComponent: React.FunctionComponent<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
const src: string;
export default src;
}
declare module '*.module.css' {
const classes: { [key: string]: string };
export default classes;
const classes: { [key: string]: string };
export default classes;
}
declare module '*.module.scss' {
const classes: { [key: string]: string };
export default classes;
const classes: { [key: string]: string };
export default classes;
}
declare module '*.module.sass' {
const classes: { [key: string]: string };
export default classes;
const classes: { [key: string]: string };
export default classes;
}
......@@ -15,15 +15,11 @@ const trialJobStatus = [
'SYS_CANCELED',
'EARLY_STOPPED'
];
const CONTROLTYPE = [
'SEARCH_SPACE',
'TRIAL_CONCURRENCY',
'MAX_EXEC_DURATION'
];
const CONTROLTYPE = ['SEARCH_SPACE', 'TRIAL_CONCURRENCY', 'MAX_EXEC_DURATION'];
const MONACO = {
readOnly: true,
automaticLayout: true,
scrollBeyondLastLine: false,
scrollBeyondLastLine: false
};
const DRAWEROPTION = {
minimap: { enabled: false },
......@@ -34,8 +30,17 @@ const OPERATION = 'Operation';
// defatult selected column
const COLUMN = ['Trial No.', 'ID', 'Duration', 'Status', 'Default', OPERATION];
// all choice column !dictory final
const COLUMNPro = ['Trial No.', 'ID', 'Start time', 'End time', 'Duration', 'Status',
'Intermediate result', 'Default', OPERATION];
const COLUMNPro = [
'Trial No.',
'ID',
'Start time',
'End time',
'Duration',
'Status',
'Intermediate result',
'Default',
OPERATION
];
const CONCURRENCYTOOLTIP = 'Trial concurrency is the number of trials running concurrently.';
const SUPPORTED_SEARCH_SPACE_TYPE = [
'choice',
......@@ -53,8 +58,18 @@ const SUPPORTED_SEARCH_SPACE_TYPE = [
];
export {
MANAGER_IP, DOWNLOAD_IP, trialJobStatus, COLUMNPro, WEBUIDOC,
CONTROLTYPE, MONACO, COLUMN, DRAWEROPTION, OPERATION,
METRIC_GROUP_UPDATE_THRESHOLD, METRIC_GROUP_UPDATE_SIZE, CONCURRENCYTOOLTIP,
MANAGER_IP,
DOWNLOAD_IP,
trialJobStatus,
COLUMNPro,
WEBUIDOC,
CONTROLTYPE,
MONACO,
COLUMN,
DRAWEROPTION,
OPERATION,
METRIC_GROUP_UPDATE_THRESHOLD,
METRIC_GROUP_UPDATE_SIZE,
CONCURRENCYTOOLTIP,
SUPPORTED_SEARCH_SPACE_TYPE
};
......@@ -24,7 +24,7 @@ const convertTime = (num: number): string => {
return num / 3600 + 'h';
} else {
const hour = Math.floor(num / 3600);
const min = Math.floor(num / 60 % 60);
const min = Math.floor((num / 60) % 60);
return hour > 0 ? `${hour}h ${min}min` : `${min}min`;
}
};
......@@ -35,7 +35,7 @@ const convertDuration = (num: number): string => {
return '0s';
}
const hour = Math.floor(num / 3600);
const minute = Math.floor(num / 60 % 60);
const minute = Math.floor((num / 60) % 60);
const second = Math.floor(num % 60);
const result: string[] = [];
if (hour > 0) {
......@@ -60,7 +60,7 @@ function parseMetrics(metricData: string): any {
const isArrayType = (list: any): boolean | undefined => {
return Array.isArray(list);
}
};
// get final result value
// draw Accuracy point graph
......@@ -69,11 +69,11 @@ const getFinalResult = (final?: MetricDataRecord[]): number => {
let showDefault = 0;
if (final) {
acc = parseMetrics(final[final.length - 1].data);
if (typeof (acc) === 'object' && !isArrayType(acc)) {
if (typeof acc === 'object' && !isArrayType(acc)) {
if (acc.default) {
showDefault = acc.default;
}
} else if (typeof (acc) === 'number') {
} else if (typeof acc === 'number') {
showDefault = acc;
} else {
showDefault = NaN;
......@@ -94,7 +94,7 @@ const getFinal = (final?: MetricDataRecord[]): FinalType | undefined => {
if (final) {
showDefault = parseMetrics(final[final.length - 1].data);
if (typeof showDefault === 'number') {
if(!isNaNorInfinity(showDefault)){
if (!isNaNorInfinity(showDefault)) {
return { default: showDefault };
}
} else if (isArrayType(showDefault)) {
......@@ -121,7 +121,7 @@ const intermediateGraphOption = (intermediateArr: number[], id: string): any =>
left: 'center',
textStyle: {
fontSize: 16,
color: '#333',
color: '#333'
}
},
tooltip: {
......@@ -137,11 +137,13 @@ const intermediateGraphOption = (intermediateArr: number[], id: string): any =>
data: intermediateArr,
scale: true
},
series: [{
symbolSize: 6,
type: 'scatter',
data: intermediateArr
}]
series: [
{
symbolSize: 6,
type: 'scatter',
data: intermediateArr
}
]
};
};
......@@ -159,7 +161,7 @@ const killJob = (key: number, id: string, status: string, updateList?: Function)
alert('Cancel the job successfully');
// render the table
if (updateList) {
updateList(); // FIXME
updateList(); // FIXME
}
} else {
alert('fail to cancel the job');
......@@ -180,7 +182,7 @@ const filterByStatus = (item: TableObj): boolean => {
return item.status === 'SUCCEEDED';
};
// a waittiong trial may havn't start time
// a waittiong trial may havn't start time
const filterDuration = (item: TableObj): boolean => {
return item.status !== 'WAITING';
};
......@@ -197,7 +199,7 @@ const downFile = (content: string, fileName: string): void => {
}
if (navigator.userAgent.indexOf('Firefox') > -1) {
const downTag = document.createElement('a');
downTag.addEventListener('click', function () {
downTag.addEventListener('click', function() {
downTag.download = fileName;
downTag.href = URL.createObjectURL(file);
});
......@@ -227,7 +229,10 @@ function metricAccuracy(metric: MetricDataRecord): number {
function formatAccuracy(accuracy: number): string {
// TODO: how to format NaN?
return accuracy.toFixed(6).replace(/0+$/, '').replace(/\.$/, '');
return accuracy
.toFixed(6)
.replace(/0+$/, '')
.replace(/\.$/, '');
}
function formatComplexTypeValue(value: any): string | number {
......@@ -239,8 +244,21 @@ function formatComplexTypeValue(value: any): string | number {
}
export {
convertTime, convertDuration, getFinalResult, getFinal, downFile,
intermediateGraphOption, killJob, filterByStatus, filterDuration,
formatAccuracy, formatTimestamp, metricAccuracy, parseMetrics,
isArrayType, requestAxios, isNaNorInfinity, formatComplexTypeValue
convertTime,
convertDuration,
getFinalResult,
getFinal,
downFile,
intermediateGraphOption,
killJob,
filterByStatus,
filterDuration,
formatAccuracy,
formatTimestamp,
metricAccuracy,
parseMetrics,
isArrayType,
requestAxios,
isNaNorInfinity,
formatComplexTypeValue
};
......@@ -33,7 +33,7 @@ interface TableObj {
color?: string;
startTime?: number;
endTime?: number;
parameters(axes: MultipleAxes): Map<SingleAxis, any>;
parameters(axes: MultipleAxes): Map<SingleAxis, any>;
metrics(axes: MultipleAxes): Map<SingleAxis, any>;
}
......@@ -208,8 +208,25 @@ interface EventMap {
}
export {
TableObj, TableRecord, SearchSpace, FinalType, ErrorParameter, Parameters,
AccurPoint, DetailAccurPoint, TooltipForIntermediate, TooltipForAccuracy,
Dimobj, ParaObj, Intermedia, MetricDataRecord, TrialJobInfo, ExperimentParams,
ExperimentProfile, NNIManagerStatus, EventMap, SingleAxis, MultipleAxes
TableObj,
TableRecord,
SearchSpace,
FinalType,
ErrorParameter,
Parameters,
AccurPoint,
DetailAccurPoint,
TooltipForIntermediate,
TooltipForAccuracy,
Dimobj,
ParaObj,
Intermedia,
MetricDataRecord,
TrialJobInfo,
ExperimentParams,
ExperimentProfile,
NNIManagerStatus,
EventMap,
SingleAxis,
MultipleAxes
};
......@@ -87,17 +87,33 @@ class Experiment {
// set initProfile to prevent page broken
const initProfile = {
data: {
"id": "", "revision": 0, "execDuration": 0,
"logDir": "", "nextSequenceId": 0,
"params": {
"authorName": "", "experimentName": "", "trialConcurrency": 0, "maxExecDuration": 0, "maxTrialNum": 0, "searchSpace": "null",
"trainingServicePlatform": "", "tuner": {
"builtinTunerName": "TPE",
"classArgs": { "optimize_mode": "" }, "checkpointDir": ""
id: '',
revision: 0,
execDuration: 0,
logDir: '',
nextSequenceId: 0,
params: {
authorName: '',
experimentName: '',
trialConcurrency: 0,
maxExecDuration: 0,
maxTrialNum: 0,
searchSpace: 'null',
trainingServicePlatform: '',
tuner: {
builtinTunerName: 'TPE',
// eslint-disable-next-line @typescript-eslint/camelcase
classArgs: { optimize_mode: '' },
checkpointDir: ''
},
"versionCheck": true, "clusterMetaData": [{ "key": "", "value": "" },
{ "key": "", "value": "" }]
}, "startTime": 0, "endTime": 0
versionCheck: true,
clusterMetaData: [
{ key: '', value: '' },
{ key: '', value: '' }
]
},
startTime: 0,
endTime: 0
}
};
this.profileField = initProfile.data as any;
......@@ -112,7 +128,7 @@ class Experiment {
get optimizeMode(): string {
const tuner = this.profile.params.tuner;
return (tuner && tuner.classArgs && tuner.classArgs.optimize_mode) ? tuner.classArgs.optimize_mode : 'unknown';
return tuner && tuner.classArgs && tuner.classArgs.optimize_mode ? tuner.classArgs.optimize_mode : 'unknown';
}
get trainingServicePlatform(): string {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment