diff --git a/mindinsight/ui/src/views/explain/conterfactual-interpretation.vue b/mindinsight/ui/src/views/explain/conterfactual-interpretation.vue
index 436823fd..a5251284 100644
--- a/mindinsight/ui/src/views/explain/conterfactual-interpretation.vue
+++ b/mindinsight/ui/src/views/explain/conterfactual-interpretation.vue
@@ -294,14 +294,20 @@ export default {
imageIndex: 0,
curSampleData: {},
},
- dataWaitCount: 2, // Number of waiting times when no data is available
dataWaitTimer: null, // No data available timer
+ // Status of metaData request
+ status: {
+ pendding: 'PENDING',
+ loading: 'LOADING',
+ loaded: 'LOADED',
+ stop: 'STOP',
+ },
};
},
computed: {},
watch: {},
created() {
- this.getHOCData();
+ this.getMetaData();
},
mounted() {
if (!this.trainId) {
@@ -343,13 +349,29 @@ export default {
!res ||
!res.data ||
!res.data.classes ||
- !res.data.classes.length ||
!res.data.saliency
) {
+ this.initOver = true;
return;
}
- this.labelLlist = [this.emptyLabelSelect].concat(res.data.classes);
- this.minConfidence = res.data.saliency.min_confidence;
+ const status = res.data.status;
+ // IF status is not loaded, delay 500ms and request again
+ const delayTime = 500;
+ if (status !== this.status.loaded) {
+ if (this.dataWaitTimer) {
+ clearTimeout(this.dataWaitTimer);
+ this.dataWaitTimer = null;
+ }
+ this.dataWaitTimer = setTimeout(() => {
+ this.getMetaData();
+ }, delayTime);
+ } else {
+ this.labelLlist = [this.emptyLabelSelect].concat(res.data.classes);
+ this.minConfidence = res.data.saliency.min_confidence;
+ this.getHOCData();
+ }
+ }, () => {
+ this.initOver = true;
},
);
},
@@ -370,29 +392,16 @@ export default {
}
RequestService.queryHOCData(params).then(
(res) => {
+ this.initOver = true;
if (!res || !res.data) {
- this.initOver = true;
+ this.pageData.totalNum = 0;
+ this.resetIniitData();
return;
}
- if (!res.data.count && !this.initOver && this.dataWaitCount) {
- this.dataWaitCount--;
- if (this.dataWaitTimer) {
- clearTimeout(this.dataWaitTimer);
- this.dataWaitTimer = null;
- }
- this.dataWaitTimer = setTimeout(() => {
- this.getHOCData();
- }, 1500);
- } else {
- if (!this.initOver) {
- this.getMetaData();
- }
- this.initOver = true;
- this.pageData.totalNum = res.data.count;
- this.fullData = res.data.samples;
- this.curSelectedDataIndex = 0;
- this.formateCurrentHOCData();
- }
+ this.pageData.totalNum = res.data.count;
+ this.fullData = res.data.samples;
+ this.curSelectedDataIndex = 0;
+ this.formateCurrentHOCData();
},
() => {
this.pageData.totalNum = 0;
diff --git a/mindinsight/ui/src/views/explain/saliency-map.vue b/mindinsight/ui/src/views/explain/saliency-map.vue
index de5aa39e..a5ad4284 100644
--- a/mindinsight/ui/src/views/explain/saliency-map.vue
+++ b/mindinsight/ui/src/views/explain/saliency-map.vue
@@ -1,5 +1,5 @@
+ v-if="!hasData">
+ v-if="isLoading">
{{ $t('public.dataLoading') }}
+ :empty-text="$t('public.noData')">
+ v-show="hasData">
{
this.queryParameters.offset = val - 1;
- this.queryPageInfo(this.queryParameters).then();
+ this.queryPageInfo(this.queryParameters);
this.pageChangeTimer = null;
}, this.pageChangeDelay);
},
@@ -494,7 +496,7 @@ export default {
this.queryParameters.sorted_name = val;
this.pageInfo.currentPage = 1;
this.queryParameters.offset = this.pageInfo.currentPage - 1;
- this.queryPageInfo(this.queryParameters).then();
+ this.queryPageInfo(this.queryParameters);
},
/**
* The logic of click the explainer method canvas
@@ -512,66 +514,78 @@ export default {
/**
* Request basic information of train
* @param {Object} params Parameters of the request basic information of train interface
+ * @return {Promise}
*/
queryTrainInfo(params) {
- requestService
- .queryTrainInfo(params)
- .then(
- (res) => {
- if (res && res.data) {
- if (res.data.saliency) {
- this.minConfidence = res.data.saliency.min_confidence
- ? res.data.saliency.min_confidence
- : '--';
- this.hasMetric = res.data.saliency.metrics.length
- ? true
- : false;
- this.allExplainers = this.arrayToCheckBox(
- res.data.saliency.explainers,
- );
- }
- if (res.data.classes) {
- const truthLabels = [];
- for (let i = 0; i < res.data.classes.length; i++) {
- truthLabels.push(res.data.classes[i].label);
- }
- this.truthLabels = truthLabels;
- }
- if (res.data.uncertainty) {
- this.uncertaintyEnabled = res.data.uncertainty.enabled
- ? true
- : false;
- // The sort by uncertainty only valid when uncertaintyEnabled is true
- if (this.uncertaintyEnabled) {
- this.sortedNames.push({
- label: this.$t('explain.byUncertainty'),
- value: UNCERTAINTY,
+ return new Promise((resolve, reject) => {
+ requestService
+ .queryTrainInfo(params)
+ .then(
+ (res) => {
+ if (res && res.data) {
+ const status = res.data.status.toUpperCase();
+ if (status !== STATUS.LOADED) {
+ resolve({
+ again: true,
+ continue: false,
+ });
+ } else {
+ // status === 'LOADED'
+ this.processTrainInfo(res.data);
+ resolve({
+ again: false,
+ continue: true,
});
}
+ } else {
+ resolve({
+ again: false,
+ continue: false,
+ });
}
- }
- this.ifNoData = false;
- this.ifLoading = false;
- },
- () => {
- this.ifNoData = false;
- this.ifLoading = false;
- this.ifError = true;
- },
- )
- .catch(() => {
- this.ifNoData = false;
- this.ifLoading = false;
- this.ifError = true;
+ },
+ )
+ .catch((error) => {
+ reject(error);
+ });
+ });
+ },
+ /**
+ * The logic of process train info
+ * @param {Object} data
+ */
+ processTrainInfo(data) {
+ const truthLabels = [];
+ for (let i = 0; i < data.classes.length; i++) {
+ truthLabels.push(data.classes[i].label);
+ }
+ this.truthLabels = truthLabels;
+ if (data.saliency) {
+ this.minConfidence = data.saliency.min_confidence;
+ this.hasMetric = data.saliency.metrics.length ? true : false;
+ this.allExplainers = this.arrayToCheckBox(
+ data.saliency.explainers,
+ );
+ }
+ if (data.uncertainty) {
+ this.uncertaintyEnabled = data.uncertainty.enabled ? true : false;
+ // The sort by uncertainty only valid when uncertaintyEnabled is true
+ if (this.uncertaintyEnabled) {
+ this.sortedNames.push({
+ label: this.$t('explain.byUncertainty'),
+ value: UNCERTAINTY,
});
+ }
+ }
},
/**
* The complete logic of table update when any condition changed
* @param {Object} params The main parameters
* @param {Object} supParams The supplymentary parameters
+ * @param {Boolean} first If first query
* @return {Promise}
*/
- updateTable(params, supParams) {
+ updateTable(params, supParams, first = false) {
const paramsTemp = JSON.parse(JSON.stringify(params));
for (const attr in paramsTemp) {
if ({}.hasOwnProperty.call(paramsTemp, attr)) {
@@ -588,70 +602,49 @@ export default {
}
}
Object.assign(paramsTemp, supParams);
- return this.queryPageInfo(paramsTemp);
+ return this.queryPageInfo(paramsTemp, first);
},
/**
* Request page table information
* @param {Object} params Parameters of the request page information interface
- * @return {Promise}
+ * @param {Boolean} first If first query
*/
- queryPageInfo(params) {
+ queryPageInfo(params, first = false) {
params.train_id = decodeURIComponent(params.train_id);
this.queryParameters = params;
- return new Promise((resolve) => {
- requestService
- .queryPageInfo(params)
- .then(
- (res) => {
- // Make sure the offset of response is equal to offset of request
- if (params.offset === this.queryParameters.offset) {
- if (res && res.data && res.data.samples) {
- this.tableData = this.processTableData(res.data.samples);
- this.pageInfo.total = res.data.count ? res.data.count : 0;
- if (!res.data.count) {
- // 3: Prediction type has three valid values
- // When length === 3 || length === 0, means search without type limit
- const typeLimit =
- params.prediction_types.length !== 3 &&
- params.prediction_types.length !== 0;
- if (params.labels || typeLimit) {
- // With label or type limit
- this.emptyText = this.$t('public.noData');
- } else {
- // Without limit
- if (this.requestTime === this.requestLimit) {
- this.emptyText = this.$t('public.noData');
- } else {
- this.emptyText = this.$t('explain.noData');
- }
- }
- resolve(false);
+ requestService
+ .queryPageInfo(params)
+ .then(
+ (res) => {
+ // Make sure the offset of response is equal to offset of request
+ if (params.offset === this.queryParameters.offset) {
+ if (res && res.data) {
+ if (!res.data.count) {
+ if (first) {
+ this.isLoading = false;
} else {
- resolve(true);
+ this.tableData = this.processTableData(res.data.samples);
+ this.pageInfo.total = 0;
}
} else {
- this.pageInfo.total = 0;
+ this.tableData = this.processTableData(res.data.samples);
+ this.pageInfo.total = res.data.count;
+ this.hasData = true;
}
}
- },
- () => {
- this.ifNoData = false;
- this.ifLoading = false;
- this.ifError = true;
- },
- )
- .catch(() => {
- this.ifNoData = false;
- this.ifLoading = false;
- this.ifError = true;
- });
- });
+ }
+ },
+ () => {
+ this.isLoading = false;
+ },
+ )
+ .catch(() => {
+ this.isLoading = false;
+ });
},
/**
* Process the original table data
* @param {Object} samples The original table data
- * @param {number | boolean} minConfidence The min confindence
- * If min confidence is lost, replace with type except number, such as 'false', 'null'
* @return {Object} The processed table data
*/
processTableData(samples) {
@@ -735,55 +728,50 @@ export default {
query: {id: this.trainID},
});
},
+ /**
+ * The logic of init page
+ */
initPage() {
- return new Promise((resolve) => {
- this.updateTable(this.baseQueryParameters, {
- limit: this.pageInfo.pageSize,
- offset: this.pageInfo.currentPage - 1,
- }).then((hasData) => {
- // If has data now
- if (hasData) {
- const params = {
- train_id: this.trainID,
- };
- this.queryTrainInfo(params);
- resolve(true);
- } else {
- resolve(false);
- }
- });
- });
+ const params = {
+ train_id: this.trainID,
+ };
+ this.queryTrainInfo(params)
+ .then(
+ (res) => {
+ if (res.again) {
+ // Request again
+ setTimeout(() => {
+ this.initPage();
+ }, this.requestDelay);
+ } else {
+ // No need to request again
+ if (res.continue) {
+ this.updateTable(this.baseQueryParameters, {
+ limit: this.pageInfo.pageSize,
+ offset: this.pageInfo.currentPage - 1,
+ }, true);
+ } else {
+ this.isLoading = false;
+ }
+ }
+ },
+ () => {
+ // Has error
+ this.isLoading = false;
+ })
+ .catch(() => {
+ this.isLoading = false;
+ });
},
},
created() {
if (!this.$route.query.id) {
this.$message.error(this.$t('trainingDashboard.invalidId'));
- this.ifError = true;
+ this.isLoading = false;
return;
}
this.trainID = this.$route.query.id;
- this.initPage().then((hasData) => {
- this.requestTime = 1;
- if (!hasData) {
- this.requestTimer = setInterval(() => {
- this.initPage().then((hasDataNow) => {
- this.requestTime++;
- if (hasDataNow) {
- clearInterval(this.requestTimer);
- } else {
- if (this.requestTime === this.requestLimit) {
- // Still has no data
- this.ifLoading = false;
- clearInterval(this.requestTimer);
- }
- }
- });
- }, this.requestDelay);
- }
- });
- },
- destroyed() {
- clearInterval(this.requestTimer);
+ this.initPage();
},
mounted() {
// Change the page title