Commit d8e1c4af authored by Lijiao's avatar Lijiao Committed by chicm-ms
Browse files

Use scu to avoid unnecessary rendering (#1095)

parent 1d8f4eab
......@@ -192,19 +192,23 @@ class Overview extends React.Component<{}, OverviewState> {
method: 'GET'
})
.then(res => {
if (res.status === 200 && this._isMounted) {
if (res.status === 200) {
const errors = res.data.errors;
if (errors.length !== 0) {
if (this._isMounted) {
this.setState({
status: res.data.status,
errorStr: res.data.errors[0]
});
}
} else {
if (this._isMounted) {
this.setState({
status: res.data.status,
});
}
}
}
});
}
......@@ -254,7 +258,8 @@ class Overview extends React.Component<{}, OverviewState> {
case 'SUCCEEDED':
profile.succTrial += 1;
const desJobDetail: Parameters = {
parameters: {}
parameters: {},
intermediate: []
};
const duration = (tableData[item].endTime - tableData[item].startTime) / 1000;
const acc = getFinal(tableData[item].finalMetricData);
......
......@@ -27,6 +27,11 @@ interface TrialDetailState {
entriesInSelect: string;
searchSpace: string;
isMultiPhase: boolean;
isTableLoading: boolean;
whichGraph: string;
hyperCounts: number; // user click the hyper-parameter counts
durationCounts: number;
intermediateCounts: number;
}
class TrialsDetail extends React.Component<{}, TrialDetailState> {
......@@ -70,9 +75,14 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
experimentLogCollection: false,
entriesTable: 20,
entriesInSelect: '20',
isHasSearch: false,
searchSpace: '',
isMultiPhase: false
whichGraph: '1',
isHasSearch: false,
isMultiPhase: false,
isTableLoading: false,
hyperCounts: 0,
durationCounts: 0,
intermediateCounts: 0
};
}
......@@ -85,6 +95,9 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
])
.then(axios.spread((res, res1) => {
if (res.status === 200 && res1.status === 200) {
if (this._isMounted === true) {
this.setState(() => ({ isTableLoading: true }));
}
const trialJobs = res.data;
const metricSource = res1.data;
const trialTable: Array<TableObj> = [];
......@@ -175,6 +188,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
}
if (this._isMounted) {
this.setState(() => ({
isTableLoading: false,
tableListSource: trialTable
}));
}
......@@ -239,17 +253,12 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
}
handleEntriesSelect = (value: string) => {
switch (value) {
case '20':
this.setState(() => ({ entriesTable: 20 }));
break;
case '50':
this.setState(() => ({ entriesTable: 50 }));
break;
case '100':
this.setState(() => ({ entriesTable: 100 }));
break;
case 'all':
// user select isn't 'all'
if (value !== 'all') {
if (this._isMounted) {
this.setState(() => ({ entriesTable: parseInt(value, 10) }));
}
} else {
const { tableListSource } = this.state;
if (this._isMounted) {
this.setState(() => ({
......@@ -257,8 +266,13 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
entriesTable: tableListSource.length
}));
}
break;
default:
}
}
handleWhichTabs = (activeKey: string) => {
// const which = JSON.parse(activeKey);
if (this._isMounted) {
this.setState(() => ({ whichGraph: activeKey }));
}
}
......@@ -315,18 +329,21 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
const {
tableListSource, searchResultSource, isHasSearch, isMultiPhase,
entriesTable, experimentPlatform, searchSpace, experimentLogCollection
entriesTable, experimentPlatform, searchSpace, experimentLogCollection,
whichGraph, isTableLoading
} = this.state;
const source = isHasSearch ? searchResultSource : tableListSource;
return (
<div>
<div className="trial" id="tabsty">
<Tabs type="card">
<Tabs type="card" onChange={this.handleWhichTabs}>
{/* <TabPane tab={this.titleOfacc} key="1" destroyInactiveTabPane={true}> */}
<TabPane tab={this.titleOfacc} key="1">
<Row className="graph">
<DefaultPoint
height={432}
showSource={source}
whichGraph={whichGraph}
/>
</Row>
</TabPane>
......@@ -335,14 +352,16 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
<Para
dataSource={source}
expSearchSpace={searchSpace}
whichGraph={whichGraph}
/>
</Row>
</TabPane>
<TabPane tab={this.titleOfDuration} key="3">
<Duration source={source} />
<Duration source={source} whichGraph={whichGraph} />
{/* <Duration source={source} whichGraph={whichGraph} clickCounts={durationCounts} /> */}
</TabPane>
<TabPane tab={this.titleOfIntermediate} key="4">
<Intermediate source={source} />
<Intermediate source={source} whichGraph={whichGraph} />
</TabPane>
</Tabs>
</div>
......@@ -388,6 +407,7 @@ class TrialsDetail extends React.Component<{}, TrialDetailState> {
<TableList
entries={entriesTable}
tableSource={source}
isTableLoading={isTableLoading}
isMultiPhase={isMultiPhase}
platform={experimentPlatform}
updateList={this.getDetailSource}
......
import * as React from 'react';
import ReactEcharts from 'echarts-for-react';
import { filterByStatus } from '../../static/function';
import { TableObj, DetailAccurPoint, TooltipForAccuracy } from '../../static/interface';
require('echarts/lib/chart/scatter');
require('echarts/lib/component/tooltip');
......@@ -8,11 +9,13 @@ require('echarts/lib/component/title');
interface DefaultPointProps {
showSource: Array<TableObj>;
height: number;
whichGraph: string;
}
interface DefaultPointState {
defaultSource: object;
accNodata: string;
succeedTrials: number;
}
class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState> {
......@@ -22,15 +25,46 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
super(props);
this.state = {
defaultSource: {},
accNodata: 'No data'
accNodata: '',
succeedTrials: 10000000
};
}
defaultMetric = (showSource: Array<TableObj>) => {
defaultMetric = (succeedSource: Array<TableObj>) => {
const accSource: Array<DetailAccurPoint> = [];
const showSource: Array<TableObj> = succeedSource.filter(filterByStatus);
const lengthOfSource = showSource.length;
const tooltipDefault = lengthOfSource === 0 ? 'No data' : '';
if (this._isMounted === true) {
this.setState(() => ({
succeedTrials: lengthOfSource,
accNodata: tooltipDefault
}));
}
if (lengthOfSource === 0) {
const nullGraph = {
grid: {
left: '8%'
},
xAxis: {
name: 'Trial',
type: 'category',
},
yAxis: {
name: 'Default metric',
type: 'value',
}
};
if (this._isMounted === true) {
this.setState(() => ({
defaultSource: nullGraph
}));
}
} else {
const resultList: Array<number | string>[] = [];
Object.keys(showSource).map(item => {
const temp = showSource[item];
if (temp.status === 'SUCCEEDED' && temp.acc !== undefined) {
if (temp.acc !== undefined) {
if (temp.acc.default !== undefined) {
const searchSpace = temp.description.parameters;
accSource.push({
......@@ -41,7 +75,6 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
}
}
});
const resultList: Array<number | string>[] = [];
Object.keys(accSource).map(item => {
const items = accSource[item];
let temp: Array<number | string>;
......@@ -89,25 +122,34 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
}]
};
if (this._isMounted === true) {
this.setState({ defaultSource: allAcuracy }, () => {
if (resultList.length === 0) {
this.setState({
accNodata: 'No data'
});
} else {
this.setState({
accNodata: ''
});
this.setState(() => ({
defaultSource: allAcuracy
}));
}
});
}
}
// update parent component state
componentWillReceiveProps(nextProps: DefaultPointProps) {
const showSource = nextProps.showSource;
const { whichGraph, showSource } = nextProps;
if (whichGraph === '1') {
this.defaultMetric(showSource);
}
}
shouldComponentUpdate(nextProps: DefaultPointProps, nextState: DefaultPointState) {
const { whichGraph } = nextProps;
const succTrial = this.state.succeedTrials;
const { succeedTrials } = nextState;
if (whichGraph === '1') {
if (succeedTrials !== succTrial) {
return true;
}
}
// only whichGraph !== '1', default metric can't update
return false;
}
componentDidMount() {
this._isMounted = true;
......@@ -131,6 +173,7 @@ class DefaultPoint extends React.Component<DefaultPointProps, DefaultPointState>
}}
theme="my_theme"
notMerge={true} // update now
// lazyUpdate={true}
/>
<div className="showMess">{accNodata}</div>
</div>
......
import * as React from 'react';
import ReactEcharts from 'echarts-for-react';
import { TableObj } from 'src/static/interface';
import { filterDuration } from 'src/static/function';
require('echarts/lib/chart/bar');
require('echarts/lib/component/tooltip');
require('echarts/lib/component/title');
......@@ -12,6 +13,7 @@ interface Runtrial {
interface DurationProps {
source: Array<TableObj>;
whichGraph: string;
}
interface DurationState {
......@@ -26,11 +28,62 @@ class Duration extends React.Component<DurationProps, DurationState> {
super(props);
this.state = {
durationSource: {}
durationSource: this.initDuration(this.props.source),
};
}
initDuration = (source: Array<TableObj>) => {
const trialId: Array<string> = [];
const trialTime: Array<number> = [];
const trialJobs = source.filter(filterDuration);
Object.keys(trialJobs).map(item => {
const temp = trialJobs[item];
trialId.push(temp.sequenceId);
trialTime.push(temp.duration);
});
return {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
bottom: '3%',
containLabel: true,
left: '1%',
right: '4%'
},
dataZoom: [{
type: 'slider',
name: 'trial',
filterMode: 'filter',
yAxisIndex: 0,
orient: 'vertical'
}, {
type: 'slider',
name: 'trial',
filterMode: 'filter',
xAxisIndex: 0
}],
xAxis: {
name: 'Time',
type: 'value',
},
yAxis: {
name: 'Trial',
type: 'category',
data: trialId
},
series: [{
type: 'bar',
data: trialTime
}]
};
}
getOption = (dataObj: Runtrial) => {
return {
tooltip: {
......@@ -74,17 +127,16 @@ class Duration extends React.Component<DurationProps, DurationState> {
};
}
drawDurationGraph = (trialJobs: Array<TableObj>) => {
drawDurationGraph = (source: Array<TableObj>) => {
// why this function run two times when props changed?
const trialId: Array<string> = [];
const trialTime: Array<number> = [];
const trialRun: Array<Runtrial> = [];
const trialJobs = source.filter(filterDuration);
Object.keys(trialJobs).map(item => {
const temp = trialJobs[item];
if (temp.status !== 'WAITING') {
trialId.push(temp.sequenceId);
trialTime.push(temp.duration);
}
});
trialRun.push({
trialId: trialId,
......@@ -97,17 +149,42 @@ class Duration extends React.Component<DurationProps, DurationState> {
}
}
componentWillReceiveProps(nextProps: DurationProps) {
const trialJobs = nextProps.source;
this.drawDurationGraph(trialJobs);
}
componentDidMount() {
this._isMounted = true;
// init: user don't search
const {source} = this.props;
const { source } = this.props;
this.drawDurationGraph(source);
}
componentWillReceiveProps(nextProps: DurationProps) {
const { whichGraph, source } = nextProps;
if (whichGraph === '3') {
this.drawDurationGraph(source);
}
}
shouldComponentUpdate(nextProps: DurationProps, nextState: DurationState) {
const { whichGraph, source } = nextProps;
if (whichGraph === '3') {
const beforeSource = this.props.source;
if (whichGraph !== this.props.whichGraph) {
return true;
}
if (source.length !== beforeSource.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;
}
}
return false;
}
componentWillUnmount() {
this._isMounted = false;
......@@ -121,6 +198,7 @@ class Duration extends React.Component<DurationProps, DurationState> {
option={durationSource}
style={{ width: '95%', height: 412, margin: '0 auto' }}
theme="my_theme"
notMerge={true} // update now
/>
</div>
);
......
......@@ -11,16 +11,21 @@ interface Intermedia {
data: Array<number | object>; // intermediate data
hyperPara: object; // each trial hyperpara value
}
interface IntermediateState {
detailSource: Array<TableObj>;
interSource: object;
filterSource: Array<TableObj>;
eachIntermediateNum: number; // trial's intermediate number count
isLoadconfirmBtn: boolean;
isFilter: boolean;
length: number;
clickCounts: number; // user filter intermediate click confirm btn's counts
}
interface IntermediateProps {
source: Array<TableObj>;
whichGraph: string;
}
class Intermediate extends React.Component<IntermediateProps, IntermediateState> {
......@@ -34,39 +39,25 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
constructor(props: IntermediateProps) {
super(props);
this.state = {
detailSource: [],
interSource: {},
filterSource: [],
eachIntermediateNum: 1,
isLoadconfirmBtn: false,
isFilter: false
isFilter: false,
length: 100000,
clickCounts: 0
};
}
initMediate = () => {
const option = {
grid: {
left: '5%',
top: 40,
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
},
yAxis: {
type: 'value',
name: 'Scape'
}
};
drawIntermediate = (source: Array<TableObj>) => {
if (source.length > 0) {
if (this._isMounted) {
this.setState(() => ({
interSource: option
length: source.length,
detailSource: source
}));
}
}
drawIntermediate = (source: Array<TableObj>) => {
if (source.length > 0) {
const trialIntermediate: Array<Intermedia> = [];
Object.keys(source).map(item => {
const temp = source[item];
......@@ -140,7 +131,24 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
}));
}
} else {
this.initMediate();
const nullData = {
grid: {
left: '5%',
top: 40,
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
},
yAxis: {
type: 'value',
name: 'Scape'
}
};
if (this._isMounted) {
this.setState(() => ({ interSource: nullData }));
}
}
}
......@@ -183,8 +191,9 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
this.setState({ filterSource: filterSource });
}
this.drawIntermediate(filterSource);
const counts = this.state.clickCounts + 1;
this.setState({ isLoadconfirmBtn: false, clickCounts: counts });
}
this.setState({ isLoadconfirmBtn: false });
});
}
}
......@@ -204,19 +213,65 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
this.drawIntermediate(source);
}
componentWillReceiveProps(nextProps: IntermediateProps) {
const { isFilter, filterSource } = this.state;
componentWillReceiveProps(nextProps: IntermediateProps, nextState: IntermediateState) {
const { isFilter, filterSource } = nextState;
const { whichGraph, source } = nextProps;
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(nextProps.source);
this.drawIntermediate(source);
} else {
this.drawIntermediate(filterSource);
}
} else {
this.drawIntermediate(nextProps.source);
this.drawIntermediate(source);
}
}
}
shouldComponentUpdate(nextProps: IntermediateProps, nextState: IntermediateState) {
const { whichGraph } = nextProps;
const beforeGraph = this.props.whichGraph;
if (whichGraph === '4') {
const { source } = nextProps;
const { isFilter, length, clickCounts } = nextState;
const beforeLength = this.state.length;
const beforeSource = this.state.detailSource;
const beforeClickCounts = this.state.clickCounts;
if (isFilter !== this.state.isFilter) {
return true;
}
if (clickCounts !== beforeClickCounts) {
return true;
}
if (isFilter === false) {
if (whichGraph !== beforeGraph) {
return true;
}
if (length !== beforeLength) {
return true;
}
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;
}
}
}
return false;
}
componentWillUnmount() {
......@@ -225,7 +280,6 @@ class Intermediate extends React.Component<IntermediateProps, IntermediateState>
render() {
const { interSource, isLoadconfirmBtn, isFilter } = this.state;
return (
<div>
{/* style in para.scss */}
......
import * as React from 'react';
import ReactEcharts from 'echarts-for-react';
import { filterByStatus } from '../../static/function';
import { Row, Col, Select, Button, message } from 'antd';
import { ParaObj, Dimobj, TableObj, SearchSpace } from '../../static/interface';
import { ParaObj, Dimobj, TableObj } from '../../static/interface';
const Option = Select.Option;
require('echarts/lib/chart/parallel');
require('echarts/lib/component/tooltip');
......@@ -11,6 +12,7 @@ require('../../static/style/para.scss');
require('../../static/style/button.scss');
interface ParaState {
// paraSource: Array<TableObj>;
option: object;
paraBack: ParaObj;
dimName: Array<string>;
......@@ -19,11 +21,15 @@ interface ParaState {
paraNodata: string;
max: number; // graph color bar limit
min: number;
sutrialCount: number; // succeed trial numbers for SUC
clickCounts: number;
isLoadConfirm: boolean;
}
interface ParaProps {
dataSource: Array<TableObj>;
expSearchSpace: string;
whichGraph: string;
}
message.config({
......@@ -45,6 +51,8 @@ class Para extends React.Component<ParaProps, ParaState> {
constructor(props: ParaProps) {
super(props);
this.state = {
// paraSource: [],
// option: this.hyperParaPic,
option: {},
dimName: [],
paraBack: {
......@@ -58,27 +66,80 @@ class Para extends React.Component<ParaProps, ParaState> {
percent: 0,
paraNodata: '',
min: 0,
max: 1
max: 1,
sutrialCount: 10000000,
clickCounts: 1,
isLoadConfirm: false
};
}
componentDidMount() {
this._isMounted = true;
this.reInit();
}
getParallelAxis =
(
dimName: Array<string>, searchRange: SearchSpace,
accPara: Array<number>,
eachTrialParams: Array<string>, paraYdata: number[][]
dimName: Array<string>, parallelAxis: Array<Dimobj>,
accPara: Array<number>, eachTrialParams: Array<string>
) => {
if (this._isMounted) {
this.setState(() => ({
dimName: dimName
}));
// get data for every lines. if dim is choice type, number -> toString()
const paraYdata: number[][] = [];
Object.keys(eachTrialParams).map(item => {
let temp: Array<number> = [];
for (let i = 0; i < dimName.length; i++) {
if ('type' in parallelAxis[i]) {
temp.push(
eachTrialParams[item][dimName[i]].toString()
);
} else {
temp.push(
eachTrialParams[item][dimName[i]]
);
}
}
paraYdata.push(temp);
});
// add acc
Object.keys(paraYdata).map(item => {
paraYdata[item].push(accPara[item]);
});
// according acc to sort ydata // sort to find top percent dataset
if (paraYdata.length !== 0) {
const len = paraYdata[0].length - 1;
paraYdata.sort((a, b) => b[len] - a[len]);
}
const paraData = {
parallelAxis: parallelAxis,
data: paraYdata
};
const { percent, swapAxisArr } = this.state;
// need to cut down the data
if (percent !== 0) {
const linesNum = paraData.data.length;
// Math.ceil rather than Math.floor to avoid lost lines
const len = Math.ceil(linesNum * percent);
paraData.data.length = len;
}
// need to swap the yAxis
if (swapAxisArr.length >= 2) {
this.swapGraph(paraData, swapAxisArr);
}
this.getOption(paraData);
if (this._isMounted === true) {
this.setState(() => ({ paraBack: paraData }));
}
}
hyperParaPic = (source: Array<TableObj>, searchSpace: string) => {
// filter succeed trials [{}, {}, {}]
const dataSource: Array<TableObj> = source.filter(filterByStatus);
const lenOfDataSource: number = dataSource.length;
const accPara: Array<number> = [];
// specific value array
const eachTrialParams: Array<string> = [];
// experiment interface search space obj
const searchRange = searchSpace !== undefined ? JSON.parse(searchSpace) : '';
const dimName = Object.keys(searchRange);
if (this._isMounted === true) {
this.setState(() => ({ dimName: dimName }));
}
const parallelAxis: Array<Dimobj> = [];
// search space range and specific value [only number]
for (let i = 0; i < dimName.length; i++) {
......@@ -149,72 +210,66 @@ class Para extends React.Component<ParaProps, ParaState> {
}
}
// get data for every lines. if dim is choice type, number -> toString()
Object.keys(eachTrialParams).map(item => {
let temp: Array<number> = [];
for (let i = 0; i < dimName.length; i++) {
if ('type' in parallelAxis[i]) {
temp.push(
eachTrialParams[item][dimName[i]].toString()
);
} else {
temp.push(
eachTrialParams[item][dimName[i]]
);
if (lenOfDataSource === 0) {
const optionOfNull = {
parallelAxis,
tooltip: {
trigger: 'item'
},
parallel: {
parallelAxisDefault: {
tooltip: {
show: true
},
axisLabel: {
formatter: function (value: string) {
const length = value.length;
if (length > 16) {
const temp = value.split('');
for (let i = 16; i < temp.length; i += 17) {
temp[i] += '\n';
}
return temp.join('');
} else {
return value;
}
paraYdata.push(temp);
});
// add acc
Object.keys(paraYdata).map(item => {
paraYdata[item].push(accPara[item]);
});
// according acc to sort ydata
if (paraYdata.length !== 0) {
const len = paraYdata[0].length - 1;
paraYdata.sort((a, b) => b[len] - a[len]);
}
const paraData = {
parallelAxis: parallelAxis,
data: paraYdata
};
const { percent, swapAxisArr } = this.state;
// need to cut down the data
if (percent !== 0) {
const linesNum = paraData.data.length;
// Math.ceil rather than Math.floor to avoid lost lines
const len = Math.ceil(linesNum * percent);
paraData.data.length = len;
},
}
// need to swap the yAxis
if (swapAxisArr.length >= 2) {
this.swapGraph(paraData, swapAxisArr);
},
visualMap: {
type: 'continuous',
min: 0,
max: 1,
color: ['#CA0000', '#FFC400', '#90EE90']
}
this.getOption(paraData);
};
if (this._isMounted === true) {
this.setState({
paraNodata: 'No data',
option: optionOfNull,
sutrialCount: 0
});
}
hyperParaPic = (dataSource: Array<TableObj>, searchSpace: string) => {
const accPara: Array<number> = [];
// specific value array
const eachTrialParams: Array<string> = [];
const paraYdata: number[][] = [];
// experiment interface search space obj
const searchRange = JSON.parse(searchSpace);
const dimName = Object.keys(searchRange);
// trial-jobs interface list
} else {
Object.keys(dataSource).map(item => {
const temp = dataSource[item];
if (temp.status === 'SUCCEEDED') {
accPara.push(temp.acc.default);
eachTrialParams.push(temp.description.parameters);
// may be a succeed trial hasn't final result
// all detail page may be break down if havn't if
if (temp.acc !== undefined) {
if (temp.acc.default !== undefined) {
accPara.push(temp.acc.default);
}
}
});
if (this._isMounted) {
this.setState({ max: Math.max(...accPara), min: Math.min(...accPara) }, () => {
this.getParallelAxis(dimName, searchRange, accPara, eachTrialParams, paraYdata);
this.getParallelAxis(dimName, parallelAxis, accPara, eachTrialParams);
});
}
}
}
// get percent value number
percentNum = (value: string) => {
......@@ -229,9 +284,10 @@ class Para extends React.Component<ParaProps, ParaState> {
// deal with response data into pic data
getOption = (dataObj: ParaObj) => {
// dataObj [[y1], [y2]... [default metric]]
const { max, min } = this.state;
let parallelAxis = dataObj.parallelAxis;
let paralleData = dataObj.data;
const parallelAxis = dataObj.parallelAxis;
const paralleData = dataObj.data;
let visualMapObj = {};
if (max === min) {
visualMapObj = {
......@@ -251,7 +307,7 @@ class Para extends React.Component<ParaProps, ParaState> {
color: ['#CA0000', '#FFC400', '#90EE90']
};
}
let optionown = {
const optionown = {
parallelAxis,
tooltip: {
trigger: 'item'
......@@ -288,21 +344,11 @@ class Para extends React.Component<ParaProps, ParaState> {
}
};
// please wait the data
if (this._isMounted) {
if (paralleData.length === 0) {
this.setState({
paraNodata: 'No data'
});
} else {
this.setState({
paraNodata: ''
});
}
}
// draw search space graph
if (this._isMounted) {
this.setState(() => ({
option: optionown
option: optionown,
paraNodata: '',
sutrialCount: paralleData.length
}));
}
}
......@@ -320,6 +366,68 @@ class Para extends React.Component<ParaProps, ParaState> {
this.hyperParaPic(dataSource, expSearchSpace);
}
swapReInit = () => {
const { clickCounts } = this.state;
const val = clickCounts + 1;
if (this._isMounted) {
this.setState({ isLoadConfirm: true, clickCounts: val, });
}
const { paraBack, swapAxisArr } = this.state;
const paralDim = paraBack.parallelAxis;
const paraData = paraBack.data;
let temp: number;
let dim1: number;
let dim2: number;
let bool1: boolean = false;
let bool2: boolean = false;
let bool3: boolean = false;
Object.keys(paralDim).map(item => {
const paral = paralDim[item];
switch (paral.name) {
case swapAxisArr[0]:
dim1 = paral.dim;
bool1 = true;
break;
case swapAxisArr[1]:
dim2 = paral.dim;
bool2 = true;
break;
default:
}
if (bool1 && bool2) {
bool3 = true;
}
});
// swap dim's number
Object.keys(paralDim).map(item => {
if (bool3) {
if (paralDim[item].name === swapAxisArr[0]) {
paralDim[item].dim = dim2;
}
if (paralDim[item].name === swapAxisArr[1]) {
paralDim[item].dim = dim1;
}
}
});
paralDim.sort(this.sortDimY);
// swap data array
Object.keys(paraData).map(paraItem => {
temp = paraData[paraItem][dim1];
paraData[paraItem][dim1] = paraData[paraItem][dim2];
paraData[paraItem][dim2] = temp;
});
this.getOption(paraBack);
// please wait the data
if (this._isMounted) {
this.setState(() => ({
isLoadConfirm: false
}));
}
}
sortDimY = (a: Dimobj, b: Dimobj) => {
return a.dim - b.dim;
}
......@@ -374,11 +482,39 @@ class Para extends React.Component<ParaProps, ParaState> {
});
}
componentDidMount() {
this._isMounted = true;
this.reInit();
}
componentWillReceiveProps(nextProps: ParaProps) {
const dataSource = nextProps.dataSource;
const expSearchSpace = nextProps.expSearchSpace;
const { dataSource, expSearchSpace, whichGraph } = nextProps;
if (whichGraph === '2') {
this.hyperParaPic(dataSource, expSearchSpace);
}
}
shouldComponentUpdate(nextProps: ParaProps, nextState: ParaState) {
const { whichGraph } = nextProps;
const beforeGraph = this.props.whichGraph;
if (whichGraph === '2') {
if (whichGraph !== beforeGraph) {
return true;
}
const { sutrialCount, clickCounts } = nextState;
const beforeCount = this.state.sutrialCount;
const beforeClickCount = this.state.clickCounts;
if (sutrialCount !== beforeCount) {
return true;
}
if (clickCounts !== beforeClickCount) {
return true;
}
}
return false;
}
componentWillUnmount() {
......@@ -386,7 +522,7 @@ class Para extends React.Component<ParaProps, ParaState> {
}
render() {
const { option, paraNodata, dimName } = this.state;
const { option, paraNodata, dimName, isLoadConfirm } = this.state;
return (
<Row className="parameter">
<Row>
......@@ -423,7 +559,8 @@ class Para extends React.Component<ParaProps, ParaState> {
<Button
type="primary"
className="changeBtu tableButton"
onClick={this.reInit}
onClick={this.swapReInit}
disabled={isLoadConfirm}
>
Confirm
</Button>
......@@ -434,7 +571,7 @@ class Para extends React.Component<ParaProps, ParaState> {
<ReactEcharts
option={option}
style={this.chartMulineStyle}
lazyUpdate={true}
// lazyUpdate={true}
notMerge={true} // update now
/>
<div className="noneData">{paraNodata}</div>
......
import * as React from 'react';
import axios from 'axios';
import ReactEcharts from 'echarts-for-react';
import {
Row, Table, Button, Popconfirm, Modal, Checkbox
} from 'antd';
import { Row, Table, Button, Popconfirm, Modal, Checkbox } from 'antd';
const CheckboxGroup = Checkbox.Group;
import { MANAGER_IP, trialJobStatus, COLUMN, COLUMN_INDEX } from '../../static/const';
import { convertDuration, intermediateGraphOption, killJob } from '../../static/function';
import { TableObj, TrialJob } from '../../static/interface';
import OpenRow from '../public-child/OpenRow';
// import DefaultMetric from '../public-child/DefaultMetrc';
import IntermediateVal from '../public-child/IntermediateVal';
import IntermediateVal from '../public-child/IntermediateVal'; // table default metric column
import '../../static/style/search.scss';
require('../../static/style/tableStatus.css');
require('../../static/style/logPath.scss');
......@@ -33,6 +30,7 @@ interface TableListProps {
platform: string;
logCollection: boolean;
isMultiPhase: boolean;
isTableLoading: boolean;
}
interface TableListState {
......@@ -197,7 +195,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
render() {
const { entries, tableSource, updateList } = this.props;
const { entries, tableSource, updateList, isTableLoading } = this.props;
const { intermediateOption, modalVisible, isShowColumn, columnSelected } = this.state;
let showTitle = COLUMN;
let bgColor = '';
......@@ -420,6 +418,7 @@ class TableList extends React.Component<TableListProps, TableListState> {
dataSource={tableSource}
className="commonTableStyle"
pagination={{ pageSize: entries }}
loading={isTableLoading}
/>
{/* Intermediate Result Modal */}
<Modal
......
import axios from 'axios';
import {
message
} from 'antd';
import { message } from 'antd';
import { MANAGER_IP } from './const';
import { FinalResult, FinalType } from './interface';
import { FinalResult, FinalType, TableObj } from './interface';
const convertTime = (num: number) => {
if (num % 3600 === 0) {
......@@ -131,7 +129,16 @@ const killJob = (key: number, id: string, status: string, updateList: Function)
});
};
const filterByStatus = (item: TableObj) => {
return item.status === 'SUCCEEDED';
};
// a waittiong trial may havn't start time
const filterDuration = (item: TableObj) => {
return item.status !== 'WAITING';
};
export {
convertTime, convertDuration, getFinalResult,
getFinal, intermediateGraphOption, killJob
convertTime, convertDuration, getFinalResult, getFinal,
intermediateGraphOption, killJob, filterByStatus, filterDuration
};
......@@ -26,7 +26,7 @@ interface ErrorParameter {
interface Parameters {
parameters: ErrorParameter;
logPath?: string;
intermediate?: Array<number>;
intermediate: Array<number>;
}
interface Experiment {
......
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