Overview.tsx 10.5 KB
Newer Older
Lijiao's avatar
Lijiao committed
1
import * as React from 'react';
2
import { Stack, Icon, Dropdown, DefaultButton } from '@fluentui/react';
Lijiaoa's avatar
Lijiaoa committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { EXPERIMENT, TRIALS } from '@static/datamodel';
import { Trial } from '@static/model/trial';
import { AppContext } from '@/App';
import { Title } from './Title';
import SuccessTable from './table/SuccessTable';
import DefaultPoint from '../trialdetail/chart/DefaultMetricPoint';
import { BasicInfo } from './params/BasicInfo';
import { ExpDuration } from './count/ExpDuration';
import { ExpDurationContext } from './count/ExpDurationContext';
import { TrialCount } from './count/TrialCount';
import { Command1 } from './command/Command1';
import { Command2 } from './command/Command2';
import { TitleContext } from './TitleContext';
import { itemStyleSucceed, entriesOption } from './overviewConst';
import '@style/experiment/overview/overview.scss';
import '@style/experiment/overview/topTrial.scss';
import '@style/logPath.scss';

/**
 * single experiment
 * overview page
 */
Lijiao's avatar
Lijiao committed
25

26
27
interface OverviewState {
    trialConcurrency: number;
28
29
}

30
31
export const BestMetricContext = React.createContext({
    bestAccuracy: 0
32
33
34
35
});

class Overview extends React.Component<{}, OverviewState> {
    static contextType = AppContext;
36
    context!: React.ContextType<typeof AppContext>;
37
38

    constructor(props) {
Lijiao's avatar
Lijiao committed
39
40
        super(props);
        this.state = {
Lijiao's avatar
Lijiao committed
41
            trialConcurrency: EXPERIMENT.trialConcurrency
Lijiao's avatar
Lijiao committed
42
43
44
        };
    }

Lijiao's avatar
Lijiao committed
45
    clickMaxTop = (event: React.SyntheticEvent<EventTarget>): void => {
46
47
        event.stopPropagation();
        // #999 panel active bgcolor; #b3b3b3 as usual
48
        const { changeMetricGraphMode } = this.context;
Lijiao's avatar
Lijiao committed
49
        changeMetricGraphMode('max');
50
    };
Lijiaoa's avatar
Lijiaoa committed
51

Lijiao's avatar
Lijiao committed
52
    clickMinTop = (event: React.SyntheticEvent<EventTarget>): void => {
53
        event.stopPropagation();
54
        const { changeMetricGraphMode } = this.context;
Lijiao's avatar
Lijiao committed
55
        changeMetricGraphMode('min');
56
    };
57

Lijiaoa's avatar
Lijiaoa committed
58
59
    updateEntries = (event: React.FormEvent<HTMLDivElement>, item: any): void => {
        if (item !== undefined) {
60
            this.context.changeEntries(item.key);
Lijiaoa's avatar
Lijiaoa committed
61
        }
62
    };
Lijiaoa's avatar
Lijiaoa committed
63

Lijiao's avatar
Lijiao committed
64
    render(): React.ReactNode {
65
        const bestTrials = this.findBestTrials();
Lijiao's avatar
Lijiao committed
66
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
67
        const bestAccuracy = bestTrials.length > 0 ? bestTrials[0].accuracy! : NaN;
68
        const execDuration = EXPERIMENT.profile.execDuration;
69

Lijiao's avatar
Lijiao committed
70
        return (
71
72
            <AppContext.Consumer>
                {(value): React.ReactNode => {
73
74
75
76
                    const {
                        metricGraphMode,
                        bestTrialEntries,
                        maxDurationUnit,
77
                        expandRowIDs,
78
                        updateOverviewPage,
79
80
                        changeMaxDurationUnit,
                        changeExpandRowIDs
81
                    } = value;
82
83
                    const maxActive = metricGraphMode === 'max' ? 'active' : '';
                    const minActive = metricGraphMode === 'min' ? 'active' : '';
84
                    return (
85
                        <div className='overview'>
86
                            <div className='overviewWrapper'>
87
88
89
90
                                {/* exp params */}
                                <div className='overviewBasicInfo'>
                                    <TitleContext.Provider value={{ text: 'Experiment', icon: 'AutoRacing' }}>
                                        <Title />
91
                                    </TitleContext.Provider>
92
                                    <BestMetricContext.Provider value={{ bestAccuracy: bestAccuracy }}>
93
                                        <BasicInfo />
94
95
96
                                    </BestMetricContext.Provider>
                                </div>
                                {/* duration & trial numbers */}
Lijiaoa's avatar
Lijiaoa committed
97
98
99
100
101
102
                                <div className='duration'>
                                    <TitleContext.Provider value={{ text: 'Duration', icon: 'Timer' }}>
                                        <Title />
                                    </TitleContext.Provider>
                                    <ExpDurationContext.Provider
                                        value={{
103
                                            maxExecDuration: EXPERIMENT.maxExperimentDurationSeconds,
Lijiaoa's avatar
Lijiaoa committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
                                            execDuration,
                                            updateOverviewPage,
                                            maxDurationUnit,
                                            changeMaxDurationUnit
                                        }}
                                    >
                                        <ExpDuration />
                                    </ExpDurationContext.Provider>
                                </div>
                                <div className='trialCount'>
                                    <TitleContext.Provider value={{ text: 'Trial numbers', icon: 'NumberSymbol' }}>
                                        <Title />
                                    </TitleContext.Provider>
                                    <ExpDurationContext.Provider
                                        value={{
119
                                            maxExecDuration: EXPERIMENT.maxExperimentDurationSeconds,
Lijiaoa's avatar
Lijiaoa committed
120
121
122
123
124
125
126
127
                                            execDuration,
                                            updateOverviewPage,
                                            maxDurationUnit,
                                            changeMaxDurationUnit
                                        }}
                                    >
                                        <TrialCount />
                                    </ExpDurationContext.Provider>
128
129
                                </div>
                                {/* table */}
Lijiaoa's avatar
Lijiaoa committed
130
                                <div className='overviewBestMetric'>
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
                                    <Stack horizontal>
                                        <div style={itemStyleSucceed}>
                                            <TitleContext.Provider value={{ text: 'Top trials', icon: 'BulletedList' }}>
                                                <Title />
                                            </TitleContext.Provider>
                                        </div>
                                        <div className='topTrialTitle'>
                                            <Stack horizontal horizontalAlign='end'>
                                                <DefaultButton
                                                    onClick={this.clickMaxTop}
                                                    className={maxActive}
                                                    styles={{ root: { minWidth: 70, padding: 0 } }}
                                                >
                                                    <Icon iconName='Market' />
                                                    <span className='max'>Max</span>
                                                </DefaultButton>
                                                <div className='mincenter'>
                                                    <DefaultButton
                                                        onClick={this.clickMinTop}
                                                        className={minActive}
                                                        styles={{ root: { minWidth: 70, padding: 0 } }}
                                                    >
                                                        <Icon iconName='MarketDown' />
                                                        <span className='max'>Min</span>
                                                    </DefaultButton>
                                                </div>
                                                <div>
                                                    <Stack horizontal>
                                                        <div className='chooseEntry'>Display top</div>
                                                        <div>
                                                            <Dropdown
                                                                selectedKey={bestTrialEntries}
                                                                options={entriesOption}
                                                                onChange={this.updateEntries}
                                                                styles={{ root: { width: 70 } }}
                                                            />
                                                        </div>
                                                    </Stack>
                                                </div>
                                            </Stack>
                                        </div>
                                    </Stack>
Lijiaoa's avatar
Lijiaoa committed
173
                                    <div className='overviewChart'>
174
175
176
177
                                        <DefaultPoint
                                            trialIds={bestTrials.map(trial => trial.info.trialJobId)}
                                            chartHeight={300}
                                            hasBestCurve={false}
178
                                            changeExpandRowIDs={changeExpandRowIDs}
179
                                        />
180
181
182
                                        <SuccessTable
                                            trialIds={bestTrials.map(trial => trial.info.trialJobId)}
                                            updateOverviewPage={updateOverviewPage}
183
184
                                            expandRowIDs={expandRowIDs}
                                            changeExpandRowIDs={changeExpandRowIDs}
185
                                        />
Lijiaoa's avatar
Lijiaoa committed
186
                                    </div>
187
                                </div>
188
                                <Stack className='overviewCommand' horizontal>
189
                                    <Command2 />
190
191
                                    <Command1 />
                                </Stack>
192
                            </div>
193
                        </div>
194
195
                    );
                }}
196
            </AppContext.Consumer>
Lijiao's avatar
Lijiao committed
197
198
        );
    }
199
200

    private findBestTrials(): Trial[] {
Lijiao's avatar
Lijiao committed
201
        const bestTrials = TRIALS.sort();
202
203
        const { bestTrialEntries, metricGraphMode } = this.context;
        if (metricGraphMode === 'max') {
Lijiaoa's avatar
Lijiaoa committed
204
            bestTrials.reverse().splice(JSON.parse(bestTrialEntries));
205
        } else {
Lijiaoa's avatar
Lijiaoa committed
206
            bestTrials.splice(JSON.parse(bestTrialEntries));
207
208
209
        }
        return bestTrials;
    }
Lijiao's avatar
Lijiao committed
210
}
211

Lijiao's avatar
Lijiao committed
212
export default Overview;