提交 d3dd97cd 编写于 作者: M mindspore-ci-bot 提交者: Gitee

!39 UI Linkage of lineages: model and dataset

Merge pull request !39 from 潘慧/master_ph
...@@ -43,13 +43,18 @@ ...@@ -43,13 +43,18 @@
"lossFunc": "损失函数", "lossFunc": "损失函数",
"learningRate": "学习率", "learningRate": "学习率",
"modelSize": "模型大小", "modelSize": "模型大小",
"dataProcess": "数据处理" "dataProcess": "数据处理",
"noDataFound":"暂无满足筛选条件的数据",
"noDataTips":"请点击“显示全量数据”按钮查看全量数据"
}, },
"dataTraceback": { "dataTraceback": {
"details": "详情", "details": "详情",
"key": "KEY", "key": "KEY",
"value": "VALUE", "value": "VALUE",
"dataTraceTips": "该数据涉及合并操作" "dataTraceTips": "该数据涉及合并操作",
"noDataFound":"暂无满足筛选条件的数据",
"noDataTips":"请点击“显示全量数据”按钮查看全量数据"
}, },
"trainingDashboard": { "trainingDashboard": {
"trainingDashboardTitle": "训练看板", "trainingDashboardTitle": "训练看板",
......
...@@ -25,19 +25,11 @@ export default { ...@@ -25,19 +25,11 @@ export default {
}); });
}, },
// query dataset lineage // NEW API for model and data source tracing
getDatasetLineage() { queryLineagesData(params) {
return axios({ return axios({
method: 'post', method: 'post',
url: 'v1/mindinsight/datasets/dataset_lineage', url: '/v1/mindinsight/lineagemgr/lineages',
});
},
// query model versions
queryModelVersions(params) {
return axios({
method: 'post',
url: 'v1/mindinsight/models/model_lineage',
data: params.body, data: params.body,
}); });
}, },
......
...@@ -27,8 +27,9 @@ export default new Vuex.Store({ ...@@ -27,8 +27,9 @@ export default new Vuex.Store({
// Scheduled reload flag // Scheduled reload flag
isTimeReload: localStorage.isTimeReload === 'false' ? false : true, isTimeReload: localStorage.isTimeReload === 'false' ? false : true,
// reload time // reload time
timeReloadValue: localStorage.timeReloadValue ? localStorage.timeReloadValue : 3, timeReloadValue: localStorage.timeReloadValue
? localStorage.timeReloadValue
: 3,
}, },
mutations: { mutations: {
// set cancelTokenArr // set cancelTokenArr
...@@ -46,6 +47,15 @@ export default new Vuex.Store({ ...@@ -46,6 +47,15 @@ export default new Vuex.Store({
setIsReload: (state, val) => { setIsReload: (state, val) => {
state.isReload = val; state.isReload = val;
}, },
setSummaryDirList: (state, val) => {
state.summaryDirList = val;
},
setSelectedBarList: (state, val) => {
state.selectedBarList = val;
},
customizedColumnOptions: (state, val) => {
state.customizedColumnOptions = val;
},
// set isTimeReload // set isTimeReload
setIsTimeReload: (state, val) => { setIsTimeReload: (state, val) => {
state.isTimeReload = val; state.isTimeReload = val;
...@@ -53,7 +63,6 @@ export default new Vuex.Store({ ...@@ -53,7 +63,6 @@ export default new Vuex.Store({
setTimeReloadValue: (state, val) => { setTimeReloadValue: (state, val) => {
state.timeReloadValue = val; state.timeReloadValue = val;
}, },
}, },
actions: {}, actions: {},
}); });
...@@ -16,14 +16,18 @@ limitations under the License. ...@@ -16,14 +16,18 @@ limitations under the License.
<template> <template>
<div id="cl-model-traceback"> <div id="cl-model-traceback">
<div class="cl-model-right"> <div class="cl-model-right">
<div class="checkbox-area" <div class="checkbox-area">
v-if="!noData && echart.allData.length">
<el-button class="reset-btn custom-btn" <el-button class="reset-btn custom-btn"
@click="resetChart" @click="resetChart"
type="primary" type="primary"
size="mini" size="mini"
plain>{{ $t('modelTraceback.showAllData') }}</el-button> plain
<div class="checkbox"> v-if="(!noData && echart.allData.length) ||
(noData && summaryDirList && !summaryDirList.length)">
{{ $t('modelTraceback.showAllData') }}</el-button>
<div class="checkbox"
v-if="!noData && echart.allData.length &&
(!summaryDirList ||(summaryDirList && summaryDirList.length))">
<el-checkbox v-for="item in table.mandatoryColumn" <el-checkbox v-for="item in table.mandatoryColumn"
:key="item" :key="item"
:label="item" :label="item"
...@@ -61,7 +65,7 @@ limitations under the License. ...@@ -61,7 +65,7 @@ limitations under the License.
row-key="summary_dir"> row-key="summary_dir">
<el-table-column type="selection" <el-table-column type="selection"
width="55" width="55"
v-if="table.data.length" v-if="table.data && table.data.length"
:reserve-selection="true"></el-table-column> :reserve-selection="true"></el-table-column>
<el-table-column v-for="key in table.column" <el-table-column v-for="key in table.column"
:key="key" :key="key"
...@@ -95,7 +99,13 @@ limitations under the License. ...@@ -95,7 +99,13 @@ limitations under the License.
<div class="no-data-img"> <div class="no-data-img">
<img :src="require('@/assets/images/nodata.png')" <img :src="require('@/assets/images/nodata.png')"
alt /> alt />
<p class="no-data-text">{{ $t('public.noData') }}</p> <p class="no-data-text"
v-show="!summaryDirList || (summaryDirList && summaryDirList.length)">
{{ $t('public.noData') }}</p>
<div v-show="summaryDirList && !summaryDirList.length">
<p class="no-data-text">{{ $t('modelTraceback.noDataFound') }}</p>
<p class="no-data-text">{{ $t('modelTraceback.noDataTips') }}</p>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -111,7 +121,76 @@ export default { ...@@ -111,7 +121,76 @@ export default {
watch: {}, watch: {},
data() { data() {
return { return {
table: { table: {},
summaryDirList: undefined,
checkedSummary: [],
keysOfStringValue: [
'summary_dir',
'network',
'optimizer',
'loss_function',
'train_dataset_path',
'test_dataset_path',
'dataset_mark',
], // All keys whose values are character strings
keysOfIntValue: [
'train_dataset_count',
'test_dataset_count',
'epoch',
'batch_size',
], // All keys whose values are int
echart: {
chart: null,
allData: [],
brushData: [],
showData: [],
},
pagination: {
currentPage: 1,
pageSize: 8,
total: 0,
layout: 'total, prev, pager, next, jumper',
pageChange: {},
},
chartFilter: {}, // chart filter condition
tableFilter: {lineage_type: {in: ['model']}}, // table filter condition
sortInfo: {
sorted_name: 'summary_dir',
sorted_type: null,
},
showTable: false,
noData: false,
};
},
computed: {},
mounted() {
this.$store.commit('setSelectedBarList', []);
this.getStoreList();
this.pagination.pageChange = (page) => {
this.pagination.currentPage = page;
this.queryLineagesData(false);
};
this.$nextTick(() => {
this.init();
});
},
methods: {
getStoreList() {
this.summaryDirList = this.$store.state.summaryDirList;
if (this.summaryDirList) {
this.tableFilter.summary_dir = {
in: this.summaryDirList,
};
} else {
this.tableFilter.summary_dir = undefined;
}
},
/**
* Initialization
*/
init() {
this.table = {
columnOptions: { columnOptions: {
train_dataset_path: { train_dataset_path: {
label: this.$t('modelTraceback.trainSetPath'), label: this.$t('modelTraceback.trainSetPath'),
...@@ -180,61 +259,8 @@ export default { ...@@ -180,61 +259,8 @@ export default {
selectedColumn: [], selectedColumn: [],
selectAll: false, // Whether to select all columns selectAll: false, // Whether to select all columns
indeterminate: false, indeterminate: false,
},
keysOfStringValue: [
'summary_dir',
'network',
'optimizer',
'loss_function',
'train_dataset_path',
'test_dataset_path',
'dataset_mark',
], // All keys whose values are character strings
keysOfIntValue: [
'train_dataset_count',
'test_dataset_count',
'epoch',
'batch_size',
], // All keys whose values are int
echart: {
chart: null,
allData: [],
brushData: [],
showData: [],
},
pagination: {
currentPage: 1,
pageSize: 8,
total: 0,
layout: 'total, prev, pager, next, jumper',
pageChange: {},
},
chartFilter: {}, // chart filter condition
tableFilter: {}, // table filter condition
sortInfo: {
sorted_name: 'summary_dir',
sorted_type: null,
},
showTable: false,
noData: false,
};
},
computed: {},
mounted() {
this.pagination.pageChange = (page) => {
this.pagination.currentPage = page;
this.queryModelVersions(false);
}; };
this.$nextTick(() => { this.queryLineagesData(true);
this.init();
});
},
methods: {
/**
* Initialization
*/
init() {
this.queryModelVersions(true);
}, },
/** /**
* Column initialization * Column initialization
...@@ -261,27 +287,36 @@ export default { ...@@ -261,27 +287,36 @@ export default {
* Querying All Model Version Information * Querying All Model Version Information
* @param {Boolean} allData Indicates whether to query all data * @param {Boolean} allData Indicates whether to query all data
*/ */
queryModelVersions(allData) { queryLineagesData(allData) {
const params = {}; const params = {
if (!allData) { body: {},
};
const tempParam = { const tempParam = {
limit: this.pagination.pageSize,
offset: this.pagination.currentPage - 1,
sorted_name: this.sortInfo.sorted_name, sorted_name: this.sortInfo.sorted_name,
sorted_type: this.sortInfo.sorted_type, sorted_type: this.sortInfo.sorted_type,
}; };
if (Object.keys(this.chartFilter).length > 0) { if (!allData) {
params.body = Object.assign({}, tempParam, this.chartFilter); this.summaryDirList = this.$store.state.summaryDirList;
} else { this.tableFilter.summary_dir = {
params.body = tempParam; in: this.summaryDirList,
} };
tempParam.limit = this.pagination.pageSize;
tempParam.offset = this.pagination.currentPage - 1;
params.body = Object.assign(params.body, this.chartFilter);
} }
RequestService.queryModelVersions(params) params.body = Object.assign(params.body, tempParam, this.tableFilter);
RequestService.queryLineagesData(params)
.then( .then(
(res) => { (res) => {
if (res && res.data && res.data.object) { if (res && res.data && res.data.object) {
const list = JSON.parse(JSON.stringify(res.data.object)); const tempList = JSON.parse(JSON.stringify(res.data.object));
list.forEach((i) => { const list = [];
tempList.forEach((item) => {
if (item.model_lineage) {
item.model_lineage.summary_dir = item.summary_dir;
const i = JSON.parse(JSON.stringify(item.model_lineage));
i.model_size = parseFloat( i.model_size = parseFloat(
((i.model_size || 0) / 1024 / 1024).toFixed(2), ((i.model_size || 0) / 1024 / 1024).toFixed(2),
); );
...@@ -305,24 +340,24 @@ export default { ...@@ -305,24 +340,24 @@ export default {
}); });
delete i.user_defined; delete i.user_defined;
} }
list.push(i);
}
}); });
if (allData) { if (allData) {
let customized = {};
if (res.data.customized) { if (res.data.customized) {
const customized = JSON.parse( customized = JSON.parse(JSON.stringify(res.data.customized));
JSON.stringify(res.data.customized),
);
const customizedKeys = Object.keys(customized); const customizedKeys = Object.keys(customized);
if (customizedKeys.length > 0) { if (customizedKeys.length > 0) {
const metricColumnOptions = {}; customizedKeys.forEach((i) => {
const userDefinedColumnOptions = {}; if (customized[i].type === 'int') {
customizedKeys.forEach((key) => { this.keysOfIntValue.push(i);
const str = key.substring(0, key.indexOf('/')); } else if (customized[i].type === 'str') {
if ('metric' === str) { this.keysOfStringValue.push(i);
metricColumnOptions[key] = customized[key];
} else if ('user_defined' === str) {
userDefinedColumnOptions[key] = customized[key];
} }
}); });
}
}
this.table.columnOptions = Object.assign( this.table.columnOptions = Object.assign(
{ {
summary_dir: { summary_dir: {
...@@ -334,23 +369,13 @@ export default { ...@@ -334,23 +369,13 @@ export default {
required: true, required: true,
}, },
}, },
metricColumnOptions, customized,
userDefinedColumnOptions,
this.table.columnOptions, this.table.columnOptions,
); );
customizedKeys.forEach((i) => { this.$store.commit('customizedColumnOptions', customized);
if (customized[i].type === 'int') {
this.keysOfIntValue.push(i);
} else if (customized[i].type === 'str') {
this.keysOfStringValue.push(i);
}
});
}
}
this.noData = !!!res.data.object.length; this.noData = !res.data.object.length;
this.echart.allData = list; this.echart.showData = this.echart.brushData = this.echart.allData = list;
this.echart.showData = this.echart.brushData = this.echart.allData;
Object.keys(this.table.columnOptions).forEach((i) => { Object.keys(this.table.columnOptions).forEach((i) => {
const flag = list.some((val) => { const flag = list.some((val) => {
return val[i] || val[i] === 0; return val[i] || val[i] === 0;
...@@ -422,6 +447,7 @@ export default { ...@@ -422,6 +447,7 @@ export default {
selectionChange(list = []) { selectionChange(list = []) {
this.echart.showData = list.length ? list : this.echart.brushData; this.echart.showData = list.length ? list : this.echart.brushData;
this.initChart(); this.initChart();
this.checkedSummary = list;
const summaryDirFilter = []; const summaryDirFilter = [];
this.echart.showData.forEach((i) => { this.echart.showData.forEach((i) => {
summaryDirFilter.push(i.summary_dir); summaryDirFilter.push(i.summary_dir);
...@@ -437,6 +463,7 @@ export default { ...@@ -437,6 +463,7 @@ export default {
sortChange(column) { sortChange(column) {
this.sortInfo.sorted_name = column.prop; this.sortInfo.sorted_name = column.prop;
this.sortInfo.sorted_type = column.order; this.sortInfo.sorted_type = column.order;
this.getStoreList();
const tempParam = { const tempParam = {
limit: this.pagination.pageSize, limit: this.pagination.pageSize,
offset: 0, offset: 0,
...@@ -444,17 +471,23 @@ export default { ...@@ -444,17 +471,23 @@ export default {
sorted_type: this.sortInfo.sorted_type, sorted_type: this.sortInfo.sorted_type,
}; };
const params = {}; const params = {};
if (Object.keys(this.chartFilter).length > 0) { params.body = Object.assign(
params.body = Object.assign({}, tempParam, this.chartFilter); {},
} else { tempParam,
params.body = tempParam; this.tableFilter,
} this.chartFilter || {},
RequestService.queryModelVersions(params) );
RequestService.queryLineagesData(params)
.then( .then(
(res) => { (res) => {
if (res && res.data && res.data.object) { if (res && res.data && res.data.object) {
const list = JSON.parse(JSON.stringify(res.data.object)); const tempList = JSON.parse(JSON.stringify(res.data.object));
list.forEach((i) => { const list = [];
tempList.forEach((item) => {
if (item.model_lineage) {
item.model_lineage.summary_dir = item.summary_dir;
const i = JSON.parse(JSON.stringify(item.model_lineage));
i.model_size = parseFloat( i.model_size = parseFloat(
((i.model_size || 0) / 1024 / 1024).toFixed(2), ((i.model_size || 0) / 1024 / 1024).toFixed(2),
); );
...@@ -478,6 +511,8 @@ export default { ...@@ -478,6 +511,8 @@ export default {
}); });
delete i.user_defined; delete i.user_defined;
} }
list.push(i);
}
}); });
this.table.data = list; this.table.data = list;
this.pagination.total = res.data.count || 0; this.pagination.total = res.data.count || 0;
...@@ -607,6 +642,18 @@ export default { ...@@ -607,6 +642,18 @@ export default {
// select use api // select use api
this.echart.chart.on('axisareaselected', (params) => { this.echart.chart.on('axisareaselected', (params) => {
const key = params.parallelAxisId; const key = params.parallelAxisId;
const list = this.$store.state.selectedBarList || [];
const selectedAxisId = params.parallelAxisId;
if (list.length) {
list.forEach((item, index) => {
if (item == selectedAxisId) {
list.splice(index, 1);
}
});
}
list.push(selectedAxisId);
this.$store.commit('setSelectedBarList', list);
let range = params.intervals[0] || []; let range = params.intervals[0] || [];
const [axisData] = parallelAxis.filter((i) => { const [axisData] = parallelAxis.filter((i) => {
return i.id === key; return i.id === key;
...@@ -645,12 +692,17 @@ export default { ...@@ -645,12 +692,17 @@ export default {
this.tableFilter, this.tableFilter,
this.sortInfo, this.sortInfo,
); );
RequestService.queryModelVersions(filterParams) RequestService.queryLineagesData(filterParams)
.then( .then(
(res) => { (res) => {
if (res && res.data && res.data.object) { if (res && res.data && res.data.object) {
const list = JSON.parse(JSON.stringify(res.data.object)); const tempList = JSON.parse(JSON.stringify(res.data.object));
list.forEach((i) => { const list = [];
const summaryDirList = [];
tempList.forEach((item) => {
if (item.model_lineage) {
item.model_lineage.summary_dir = item.summary_dir;
const i = JSON.parse(JSON.stringify(item.model_lineage));
i.model_size = parseFloat( i.model_size = parseFloat(
((i.model_size || 0) / 1024 / 1024).toFixed(2), ((i.model_size || 0) / 1024 / 1024).toFixed(2),
); );
...@@ -664,17 +716,25 @@ export default { ...@@ -664,17 +716,25 @@ export default {
}); });
delete i.metric; delete i.metric;
} }
summaryDirList.push(i.summary_dir);
const udkeys = Object.keys(i.user_defined || {}); const udkeys = Object.keys(i.user_defined || {});
if (udkeys.length) { if (udkeys.length) {
udkeys.forEach((key) => { udkeys.forEach((key) => {
if (i.user_defined[key] || i.user_defined[key] === 0) { if (
i.user_defined[key] ||
i.user_defined[key] === 0
) {
const temp = 'user_defined/' + key; const temp = 'user_defined/' + key;
i[temp] = i.user_defined[key]; i[temp] = i.user_defined[key];
} }
}); });
delete i.user_defined; delete i.user_defined;
} }
list.push(i);
}
}); });
this.$store.commit('setSummaryDirList', summaryDirList);
this.echart.showData = this.echart.brushData = list; this.echart.showData = this.echart.brushData = list;
this.initChart(); this.initChart();
...@@ -686,6 +746,11 @@ export default { ...@@ -686,6 +746,11 @@ export default {
this.pagination.currentPage = 1; this.pagination.currentPage = 1;
this.pagination.total = this.echart.brushData.length; this.pagination.total = this.echart.brushData.length;
this.$refs.table.clearSelection(); this.$refs.table.clearSelection();
} else {
this.summaryDirList = [];
this.$store.commit('setSummaryDirList', []);
this.noData = true;
this.checkedSummary = summaryDirList;
} }
}, },
(error) => {}, (error) => {},
...@@ -698,13 +763,20 @@ export default { ...@@ -698,13 +763,20 @@ export default {
* Resetting the Eechart * Resetting the Eechart
*/ */
resetChart() { resetChart() {
this.summaryDirList = undefined;
this.$store.commit('setSummaryDirList', undefined);
this.$store.commit('setSelectedBarList', []);
this.noData = false;
this.showTable = false;
this.chartFilter = {}; this.chartFilter = {};
this.tableFilter = {}; this.tableFilter.summary_dir = undefined;
this.pagination.currentPage = 1; this.pagination.currentPage = 1;
this.echart.showData = this.echart.brushData = this.echart.allData; this.echart.allData = [];
this.queryModelVersions(false); if (this.echart.chart) {
this.echart.chart.clear();
}
this.init();
this.$refs.table.clearSelection(); this.$refs.table.clearSelection();
this.initChart();
}, },
/** /**
* Select all columns in the table. * Select all columns in the table.
...@@ -785,6 +857,13 @@ export default { ...@@ -785,6 +857,13 @@ export default {
}, },
}, },
destroyed() { destroyed() {
if (this.checkedSummary.length) {
const tempList = [];
this.checkedSummary.forEach((item) => {
tempList.push(item.summary_dir);
});
this.$store.commit('setSummaryDirList', tempList);
}
if (this.echart.chart) { if (this.echart.chart) {
window.removeEventListener('resize', this.resizeChart, false); window.removeEventListener('resize', this.resizeChart, false);
this.echart.chart.clear(); this.echart.chart.clear();
...@@ -820,6 +899,8 @@ export default { ...@@ -820,6 +899,8 @@ export default {
.checkbox-area { .checkbox-area {
margin: 24px 32px 16px; margin: 24px 32px 16px;
position: relative; position: relative;
min-height: 42px;
max-height: 66px;
.checkbox { .checkbox {
width: calc(100% - 264px); width: calc(100% - 264px);
max-height: 66px; max-height: 66px;
...@@ -848,7 +929,7 @@ export default { ...@@ -848,7 +929,7 @@ export default {
} }
} }
#echart { #echart {
height: 40%; height: 39%;
} }
.table-container { .table-container {
background-color: white; background-color: white;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册