Intermediate.tsx 12.9 KB
Newer Older
1
import * as React from 'react';
2
import { Row, Button, Switch } from 'antd';
Lijiao's avatar
Lijiao committed
3
import { TooltipForIntermediate, TableObj, Intermedia, EventMap } from '../../static/interface';
4
5
6
7
8
import ReactEcharts from 'echarts-for-react';
require('echarts/lib/component/tooltip');
require('echarts/lib/component/title');

interface IntermediateState {
9
    detailSource: Array<TableObj>;
10
11
12
13
14
    interSource: object;
    filterSource: Array<TableObj>;
    eachIntermediateNum: number; // trial's intermediate number count
    isLoadconfirmBtn: boolean;
    isFilter: boolean;
15
    length: number;
16
    clickCounts: number; // user filter intermediate click confirm btn's counts
Lijiao's avatar
Lijiao committed
17
18
    startMediaY: number;
    endMediaY: number;
19
20
21
22
}

interface IntermediateProps {
    source: Array<TableObj>;
23
    whichGraph: string;
24
25
26
27
28
29
30
31
32
33
34
35
}

class Intermediate extends React.Component<IntermediateProps, IntermediateState> {

    static intervalMediate = 1;
    public pointInput: HTMLInputElement | null;
    public minValInput: HTMLInputElement | null;
    public maxValInput: HTMLInputElement | null;

    constructor(props: IntermediateProps) {
        super(props);
        this.state = {
36
            detailSource: [],
37
38
39
40
            interSource: {},
            filterSource: [],
            eachIntermediateNum: 1,
            isLoadconfirmBtn: false,
41
42
            isFilter: false,
            length: 100000,
Lijiao's avatar
Lijiao committed
43
44
45
            clickCounts: 0,
            startMediaY: 0,
            endMediaY: 100
46
47
48
        };
    }

Lijiao's avatar
Lijiao committed
49
    drawIntermediate = (source: Array<TableObj>): void => {
50
        if (source.length > 0) {
51
52
53
54
            this.setState({
                length: source.length,
                detailSource: source
            });
Lijiao's avatar
Lijiao committed
55
            const { startMediaY, endMediaY } = this.state;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
            const trialIntermediate: Array<Intermedia> = [];
            Object.keys(source).map(item => {
                const temp = source[item];
                trialIntermediate.push({
                    name: temp.id,
                    data: temp.description.intermediate,
                    type: 'line',
                    hyperPara: temp.description.parameters
                });
            });
            // find max intermediate number
            trialIntermediate.sort((a, b) => { return (b.data.length - a.data.length); });
            const legend: Array<string> = [];
            // max length
            const length = trialIntermediate[0].data.length;
Lijiao's avatar
Lijiao committed
71
            const xAxis: number[] = [];
72
73
74
75
76
77
78
79
80
81
82
            Object.keys(trialIntermediate).map(item => {
                const temp = trialIntermediate[item];
                legend.push(temp.name);
            });
            for (let i = 1; i <= length; i++) {
                xAxis.push(i);
            }
            const option = {
                tooltip: {
                    trigger: 'item',
                    enterable: true,
Lijiao's avatar
Lijiao committed
83
                    position: function (point: number[], data: TooltipForIntermediate): number[] {
84
85
86
87
88
89
                        if (data.dataIndex < length / 2) {
                            return [point[0], 80];
                        } else {
                            return [point[0] - 300, 80];
                        }
                    },
Lijiao's avatar
Lijiao committed
90
                    formatter: function (data: TooltipForIntermediate): any {
91
92
93
94
95
96
97
                        const trialId = data.seriesName;
                        let obj = {};
                        const temp = trialIntermediate.find(key => key.name === trialId);
                        if (temp !== undefined) {
                            obj = temp.hyperPara;
                        }
                        return '<div class="tooldetailAccuracy">' +
Lijiao's avatar
Lijiao committed
98
                            '<div>Trial ID: ' + trialId + '</div>' +
99
100
101
102
103
104
105
106
107
108
109
110
111
112
                            '<div>Intermediate: ' + data.data + '</div>' +
                            '<div>Parameters: ' +
                            '<pre>' + JSON.stringify(obj, null, 4) + '</pre>' +
                            '</div>' +
                            '</div>';
                    }
                },
                grid: {
                    left: '5%',
                    top: 40,
                    containLabel: true
                },
                xAxis: {
                    type: 'category',
113
                    // name: '# Intermediate',
114
115
116
117
118
                    boundaryGap: false,
                    data: xAxis
                },
                yAxis: {
                    type: 'value',
119
                    name: 'Metric'
120
                },
Lijiao's avatar
Lijiao committed
121
122
123
124
125
126
127
128
129
130
                dataZoom: [
                    {
                        id: 'dataZoomY',
                        type: 'inside',
                        yAxisIndex: [0],
                        filterMode: 'empty',
                        start: startMediaY,
                        end: endMediaY
                    }
                ],
131
132
                series: trialIntermediate
            };
133
134
135
            this.setState({
                interSource: option
            });
136
        } else {
137
138
139
140
141
142
143
144
145
146
147
148
            const nullData = {
                grid: {
                    left: '5%',
                    top: 40,
                    containLabel: true
                },
                xAxis: {
                    type: 'category',
                    boundaryGap: false,
                },
                yAxis: {
                    type: 'value',
149
                    name: 'Metric'
150
151
                }
            };
152
            this.setState({ interSource: nullData });
153
154
155
156
        }
    }

    // confirm btn function [filter data]
Lijiao's avatar
Lijiao committed
157
    filterLines = (): void => {
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
        const filterSource: Array<TableObj> = [];
        this.setState({ isLoadconfirmBtn: true }, () => {
            const { source } = this.props;
            // get input value
            const pointVal = this.pointInput !== null ? this.pointInput.value : '';
            const minVal = this.minValInput !== null ? this.minValInput.value : '';
            const maxVal = this.maxValInput !== null ? this.maxValInput.value : '';
            // user not input message
            if (pointVal === '' || minVal === '') {
                alert('Please input filter message');
            } else {
                // user not input max value
                const position = JSON.parse(pointVal);
                const min = JSON.parse(minVal);
                if (maxVal === '') {
                    Object.keys(source).map(item => {
                        const temp = source[item];
                        const val = temp.description.intermediate[position - 1];
                        if (val >= min) {
                            filterSource.push(temp);
                        }
                    });
180
                } else {
181
182
183
184
185
186
187
188
                    const max = JSON.parse(maxVal);
                    Object.keys(source).map(item => {
                        const temp = source[item];
                        const val = temp.description.intermediate[position - 1];
                        if (val >= min && val <= max) {
                            filterSource.push(temp);
                        }
                    });
189
                }
190
191
192
193
194
195
                this.setState({ filterSource: filterSource });
                this.drawIntermediate(filterSource);
            }
            const counts = this.state.clickCounts + 1;
            this.setState({ isLoadconfirmBtn: false, clickCounts: counts });
        });
196
197
    }

Lijiao's avatar
Lijiao committed
198
    switchTurn = (checked: boolean): void => {
199
        this.setState({ isFilter: checked });
200
201
202
203
204
        if (checked === false) {
            this.drawIntermediate(this.props.source);
        }
    }

Lijiao's avatar
Lijiao committed
205
    componentDidMount(): void {
206
207
208
209
        const { source } = this.props;
        this.drawIntermediate(source);
    }

Lijiao's avatar
Lijiao committed
210
    componentWillReceiveProps(nextProps: IntermediateProps, nextState: IntermediateState): void {
211
212
        const { isFilter, filterSource } = nextState;
        const { whichGraph, source } = nextProps;
213

214
215
216
217
218
219
220
221
222
        if (whichGraph === '4') {
            if (isFilter === true) {
                const pointVal = this.pointInput !== null ? this.pointInput.value : '';
                const minVal = this.minValInput !== null ? this.minValInput.value : '';
                if (pointVal === '' && minVal === '') {
                    this.drawIntermediate(source);
                } else {
                    this.drawIntermediate(filterSource);
                }
223
            } else {
224
                this.drawIntermediate(source);
225
226
227
228
            }
        }
    }

Lijiao's avatar
Lijiao committed
229
    shouldComponentUpdate(nextProps: IntermediateProps, nextState: IntermediateState): boolean {
230
        const { whichGraph, source } = nextProps;
231
232
233
234
        const beforeGraph = this.props.whichGraph;
        if (whichGraph === '4') {
            const { isFilter, length, clickCounts } = nextState;
            const beforeLength = this.state.length;
235
            const beforeSource = this.props.source;
236
            const beforeClickCounts = this.state.clickCounts;
237

238
239
240
241
242
243
244
            if (isFilter !== this.state.isFilter) {
                return true;
            }

            if (clickCounts !== beforeClickCounts) {
                return true;
            }
245

246
247
248
249
250
251
252
            if (isFilter === false) {
                if (whichGraph !== beforeGraph) {
                    return true;
                }
                if (length !== beforeLength) {
                    return true;
                }
253
                if (beforeSource.length !== source.length) {
254
255
                    return true;
                }
256
257
258
259
260
261
262
263
264
265
266
                if (beforeSource[beforeSource.length - 1] !== undefined) {
                    if (source[source.length - 1].description.intermediate.length !==
                        beforeSource[beforeSource.length - 1].description.intermediate.length) {
                        return true;
                    }
                    if (source[source.length - 1].duration !== beforeSource[beforeSource.length - 1].duration) {
                        return true;
                    }
                    if (source[source.length - 1].status !== beforeSource[beforeSource.length - 1].status) {
                        return true;
                    }
267
268
269
270
271
272
273
                }
            }
        }

        return false;
    }

Lijiao's avatar
Lijiao committed
274
    render(): React.ReactNode {
275
        const { interSource, isLoadconfirmBtn, isFilter } = this.state;
Lijiao's avatar
Lijiao committed
276
        const IntermediateEvents = { 'dataZoom': this.intermediateDataZoom };
277
278
279
280
281
282
283
        return (
            <div>
                {/* style in para.scss */}
                <Row className="meline intermediate">
                    {
                        isFilter
                            ?
Lijiao's avatar
Lijiao committed
284
                            <span style={{ marginRight: 15 }}>
285
                                <span className="filter-x"># Intermediate result</span>
286
287
                                <input
                                    // placeholder="point"
Lijiao's avatar
Lijiao committed
288
                                    ref={(input): any => this.pointInput = input}
289
290
291
292
293
                                    className="strange"
                                />
                                <span>Metric range</span>
                                <input
                                    // placeholder="range"
Lijiao's avatar
Lijiao committed
294
                                    ref={(input): any => this.minValInput = input}
295
296
297
298
                                />
                                <span className="hyphen">-</span>
                                <input
                                    // placeholder="range"
Lijiao's avatar
Lijiao committed
299
                                    ref={(input): any => this.maxValInput = input}
300
301
302
303
304
305
306
307
308
309
                                />
                                <Button
                                    type="primary"
                                    className="changeBtu tableButton"
                                    onClick={this.filterLines}
                                    disabled={isLoadconfirmBtn}
                                >
                                    Confirm
                                </Button>
                            </span>
310
                            :
311
                            null
312
                    }
Lijiao's avatar
Lijiao committed
313
314
315
316
317
318
                    {/* filter message */}
                    <span>Filter</span>
                    <Switch
                        defaultChecked={false}
                        onChange={this.switchTurn}
                    />
319
                </Row>
320
                <Row className="intermediate-graph">
321
322
323
324
                    <ReactEcharts
                        option={interSource}
                        style={{ width: '100%', height: 418, margin: '0 auto' }}
                        notMerge={true} // update now
Lijiao's avatar
Lijiao committed
325
                        onEvents={IntermediateEvents}
326
                    />
327
                    <div className="yAxis"># Intermediate result</div>
328
329
330
331
                </Row>
            </div>
        );
    }
Lijiao's avatar
Lijiao committed
332

Lijiao's avatar
Lijiao committed
333
    private intermediateDataZoom = (e: EventMap): void => {
Lijiao's avatar
Lijiao committed
334
335
336
337
338
339
340
        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)
            }));
        }
    }
341
342
}

v-liguo's avatar
v-liguo committed
343
export default Intermediate;