提交 36b9cc7b 编写于 作者: Q qin_jun_yan

Model traceability parameter optimization target code function submission

上级 a161455f
<!--
Copyright 2020 Huawei Technologies Co., Ltd.All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<template>
<div class="scatter"
ref="scatter">
</div>
</template>
<script>
import echarts from 'echarts';
export default {
props: {
data: Array,
tooltipsData: Array,
yTitle: String,
xTitle: String,
showTooltip: Boolean,
},
watch: {
data: {
handler(newValue, oldValue) {
this.chartOption = this.formateCharOption();
this.createChart();
},
},
},
data() {
return {
chartObj: null,
chartOption: {},
charResizeTimer: null,
};
},
destroyed() {
// remove the size of a window and change the listener
window.removeEventListener('resize', this.resizeCallback);
// Remove Chart Calculation Delay
if (this.charResizeTimer) {
clearTimeout(this.charResizeTimer);
this.charResizeTimer = null;
}
},
mounted() {
window.addEventListener('resize', this.resizeCallback, false);
},
methods: {
/**
* formate Chart option
*/
formateCharOption() {
const tempOption = {
// Set the top, bottom, left, and right blanks of the echart diagram
grid: {
left: 20,
right: 20,
x2: 20,
y2: 20,
containLabel: true,
},
tooltip: {
trigger: 'item',
show: this.showTooltip,
axisPointer: {
type: 'cross',
},
formatter: (params) => {
const dataIndex = params.dataIndex;
const item = this.tooltipsData[dataIndex];
let res = '';
const obj = Object.keys(item);
for (let i = 0; i < obj.length; i++) {
if (obj[i] && item[obj[i]] !== null) {
if (typeof item[obj[i]] === 'number') {
if (item[obj[i]] < 0.0001 && item[obj[i]] > 0) {
item[obj[i]] = item[obj[i]].toExponential(4);
} else {
item[obj[i]] =
Math.round(item[obj[i]] * Math.pow(10, 4)) /
Math.pow(10, 4);
}
}
res +=
'<p>' + obj[i] + ':' + '&nbsp;&nbsp;' + item[obj[i]] + '</p>';
}
}
return res;
},
},
xAxis: {
name: this.xTitle,
nameLocation: 'end',
nameTextStyle: {
align: 'right',
padding: [60, 0, 0, 0],
},
axisLine: {
show: true,
},
axisTick: {
show: false,
},
axisLabel: {},
},
yAxis: {
name: this.yTitle,
nameGap: 20,
nameTextStyle: {
align: 'middle',
},
axisLine: {
show: true,
},
axisTick: {
show: false,
},
axisLabel: {
formatter: (value) => {
const symbol = Math.abs(value);
if (symbol.toString().length > 6) {
return value.toExponential(4);
} else if (value >= 1000 || value <= -1000) {
return parseFloat((value / 1000).toFixed(2)) + 'k';
} else if (value > 0) {
return value;
} else {
return parseFloat(value.toFixed(3));
}
},
},
splitLine: {
lineStyle: {
color: '#E6EBF5',
width: 1,
},
},
},
series: [
{
symbol: 'circle',
data: this.data,
name: this.yTitle,
type: 'scatter',
// Set scatter color
color: '#cc5b58',
},
],
};
return tempOption;
},
/**
* formate Chart option
*/
createChart() {
if (!this.chartObj) {
this.chartObj = echarts.init(this.$refs.scatter);
this.chartObj.setOption(this.chartOption, true);
} else {
this.chartObj.setOption(this.chartOption, false);
}
},
/**
*window resize
*/
resizeCallback() {
this.charResizeTimer = setTimeout(() => {
if (this.chartObj) {
this.chartObj.resize();
}
}, 500);
},
},
components: {},
};
</script>
<style lang="scss">
.scatter {
height: 100%;
}
</style>
...@@ -42,6 +42,13 @@ export default { ...@@ -42,6 +42,13 @@ export default {
}); });
}, },
queryTargetsData() {
return axios({
method: 'get',
url: `v1/mindinsight/optimizer/targets`,
});
},
// query summary list // query summary list
querySummaryList(params, isIgnoreError) { querySummaryList(params, isIgnoreError) {
return axios({ return axios({
......
...@@ -14,318 +14,325 @@ See the License for the specific language governing permissions and ...@@ -14,318 +14,325 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<template> <template>
<div id="cl-data-traceback"> <div class="cl-data-traceback">
<div v-if="loading" <div class="traceback-tab">
class="no-data-page"> <div class="traceback-tab-item"
<div class="no-data-img"> @click="jumpToModelTraceback()">{{$t("summaryManage.modelTraceback")}}</div>
<img :src="require('@/assets/images/nodata.png')" <div class="traceback-tab-item item-active">{{$t("summaryManage.dataTraceback")}}</div>
alt="" />
<p class="no-data-text">{{$t("public.dataLoading")}}</p>
</div>
</div> </div>
<div class="cl-data-right" <div id="data-traceback-con">
v-if="!loading"> <div v-if="loading"
<!-- select area --> class="no-data-page">
<div class="data-checkbox-area" <div class="no-data-img">
v-show="!errorData&&!(!totalSeries.length&&pagination.total)"> <img :src="require('@/assets/images/nodata.png')"
<div class="select-container" alt="" />
v-show="totalSeries && totalSeries.length && <p class="no-data-text">{{$t("public.dataLoading")}}</p>
</div>
</div>
<div class="cl-data-right"
v-if="!loading">
<!-- select area -->
<div class="data-checkbox-area"
v-show="!errorData && !(!totalSeries.length && pagination.total)">
<div class="select-container"
v-show="totalSeries && totalSeries.length &&
(!summaryDirList || (summaryDirList && summaryDirList.length))"> (!summaryDirList || (summaryDirList && summaryDirList.length))">
<div class="display-column"> <div class="display-column">
{{$t('modelTraceback.displayColumn')}} {{$t('modelTraceback.displayColumn')}}
</div> </div>
<div class="inline-block-set"> <div class="inline-block-set">
<!-- multiple collapse-tags --> <!-- multiple collapse-tags -->
<el-select v-model="selectArrayValue" <el-select v-model="selectArrayValue"
multiple multiple
collapse-tags collapse-tags
@change="selectValueChange" @change="selectValueChange"
:placeholder="$t('public.select')" :placeholder="$t('public.select')"
@focus="selectinputFocus"> @focus="selectinputFocus">
<div class="select-input-button"> <div class="select-input-button">
<div class="select-inner-input"> <div class="select-inner-input">
<el-input v-model="keyWord" <el-input v-model="keyWord"
v-on:input="myfilter" v-on:input="myfilter"
:placeholder="$t('public.search')"> :placeholder="$t('public.search')">
</el-input> </el-input>
</div> </div>
<button type="text" <button type="text"
@click="allSelect" @click="allSelect"
class="select-all-button" class="select-all-button"
:class="[selectCheckAll ? 'checked-color' : 'button-text', :class="[selectCheckAll ? 'checked-color' : 'button-text',
basearr.length > checkOptions.length ? 'btn-disabled' : '']" basearr.length > checkOptions.length ? 'btn-disabled' : '']"
:disabled="basearr.length > checkOptions.length"> :disabled="basearr.length > checkOptions.length">
{{ $t('public.selectAll')}} {{ $t('public.selectAll')}}
</button> </button>
<button type="text" <button type="text"
@click="deselectAll" @click="deselectAll"
class="deselect-all-button" class="deselect-all-button"
:class="[!selectCheckAll ? 'checked-color' : 'button-text', :class="[!selectCheckAll ? 'checked-color' : 'button-text',
basearr.length > checkOptions.length ? 'btn-disabled' : '']" basearr.length > checkOptions.length ? 'btn-disabled' : '']"
:disabled="basearr.length > checkOptions.length"> :disabled="basearr.length > checkOptions.length">
{{ $t('public.deselectAll')}} {{ $t('public.deselectAll')}}
</button> </button>
</div> </div>
<el-option v-for="item in checkOptions" <el-option v-for="item in checkOptions"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value" :value="item.value"
:disabled="item.disabled" :disabled="item.disabled"
:title="item.disabled ? $t('modelTraceback.mustExist') : ''"> :title="item.disabled ? $t('modelTraceback.mustExist') : ''">
</el-option> </el-option>
</el-select> </el-select>
</div>
</div>
<!-- show all data button -->
<div class="btns">
<el-button class="reset-btn custom-btn"
@click="echartShowAllData"
type="primary"
size="mini"
plain
v-show="(summaryDirList && !summaryDirList.length)||(totalSeries && totalSeries.length)">
{{ $t('modelTraceback.showAllData') }}
</el-button>
</div> </div>
</div> </div>
<!-- show all data button --> <!-- echart drawing area -->
<div class="btns"> <div id="data-echart"
<el-button class="reset-btn custom-btn" v-show="showEchartPic && !echartNoData"></div>
@click="echartShowAllData" <div class="echart-nodata-container"
type="primary" v-show="!showEchartPic && showTable && !(summaryDirList && !summaryDirList.length)">
</div>
<div class="btns-container"
v-show="!echartNoData && showTable">
<el-button type="primary"
size="mini"
class="custom-btn"
@click="hiddenRecords"
plain>
{{ $t('modelTraceback.hide')}}
</el-button>
<el-button type="primary"
size="mini" size="mini"
plain class="custom-btn"
v-show="(summaryDirList && !summaryDirList.length)||(totalSeries && totalSeries.length)"> @click="unhideRecords"
{{ $t('modelTraceback.showAllData') }} plain>
{{$t('modelTraceback.unhide')}}
</el-button> </el-button>
</div> </div>
</div> <!-- table area -->
<!-- echart drawing area --> <div class="table-container"
<div id="data-echart" v-show="!echartNoData && showTable">
v-show="showEchartPic && !echartNoData"></div> <div class="disabled-checked"
<div class="echart-nodata-container" v-show="!table.data.length"></div>
v-show="!showEchartPic && showTable && !(summaryDirList && !summaryDirList.length)"> <el-table ref="table"
</div> :data="table.data"
<div class="btns-container" tooltip-effect="light"
v-show="!echartNoData && showTable"> height="calc(100% - 40px)"
<el-button type="primary" row-key="summary_dir"
size="mini" @selection-change="handleSelectionChange"
class="custom-btn" @sort-change="tableSortChange">
@click="hiddenRecords" <el-table-column type="selection"
plain> width="55"
{{ $t('modelTraceback.hide')}} :reserve-selection="true"
</el-button> v-show="!echartNoData && showTable">
<el-button type="primary" </el-table-column>
size="mini" <el-table-column v-for="key in table.column"
class="custom-btn" :key="key"
@click="unhideRecords" :prop="key"
plain> :label="table.columnOptions[key].label"
{{$t('modelTraceback.unhide')}} :sortable="sortArray.includes(table.columnOptions[key].label) ? 'custom' : false"
</el-button> :fixed="table.columnOptions[key].label === text ? true : false"
</div> min-width="200"
<!-- table area --> show-overflow-tooltip>
<div class="table-container" <template slot="header"
v-show="!echartNoData && showTable"> slot-scope="scope">
<div class="disabled-checked" <div class="custom-label"
v-show="!table.data.length"></div> :title="scope.column.label">
<el-table ref="table" {{scope.column.label}}
:data="table.data" </div>
tooltip-effect="light" </template>
height="calc(100% - 40px)" <template slot-scope="scope">
row-key="summary_dir" <span class="icon-container"
@selection-change="handleSelectionChange" v-show="table.columnOptions[key].label === text">
@sort-change="tableSortChange"> <el-tooltip effect="light"
<el-table-column type="selection" :content="$t('dataTraceback.dataTraceTips')"
width="55" placement="top"
:reserve-selection="true" v-show="scope.row.children">
v-show="!echartNoData && showTable"> <i class="el-icon-warning"></i>
</el-table-column> </el-tooltip>
<el-table-column v-for="key in table.column" </span>
:key="key" <span @click="jumpToTrainDashboard(scope.row[key])"
:prop="key" v-if="table.columnOptions[key].label === text"
:label="table.columnOptions[key].label" class="href-color">
:sortable="sortArray.includes(table.columnOptions[key].label) ? 'custom' : false" {{ scope.row[key] }}
:fixed="table.columnOptions[key].label === text ? true : false" </span>
min-width="200" <span v-else
show-overflow-tooltip> @click="showDialogData(scope.row[key], scope)"
<template slot="header" class="click-span">
slot-scope="scope"> {{formatNumber(key, scope.row[key]) }}
<div class="custom-label" </span>
:title="scope.column.label"> </template>
{{scope.column.label}} </el-table-column>
</div> <!-- remark column -->
</template> <el-table-column fixed="right"
<template slot-scope="scope"> width="260">
<span class="icon-container" <template slot="header">
v-show="table.columnOptions[key].label === text"> <div>
<el-tooltip effect="light" <div class="label-text">{{$t('public.remark')}}</div>
:content="$t('dataTraceback.dataTraceTips')" <div class="remark-tip">{{$t('modelTraceback.remarkTips')}}</div>
placement="top" </div>
v-show="scope.row.children"> </template>
<i class="el-icon-warning"></i> <template slot-scope="scope">
</el-tooltip> <!-- The system determines whether to display the pen icon and
</span>
<span @click="jumpToTrainDashboard(scope.row[key])"
v-if="table.columnOptions[key].label === text"
class="href-color">
{{ scope.row[key] }}
</span>
<span v-else
@click="showDialogData(scope.row[key], scope)"
class="click-span">
{{formatNumber(key, scope.row[key]) }}
</span>
</template>
</el-table-column>
<!-- remark column -->
<el-table-column fixed="right"
width="260">
<template slot="header">
<div>
<div class="label-text">{{$t('public.remark')}}</div>
<div class="remark-tip">{{$t('modelTraceback.remarkTips')}}</div>
</div>
</template>
<template slot-scope="scope">
<!-- The system determines whether to display the pen icon and
text box based on the values of editShow --> text box based on the values of editShow -->
<div class="edit-text-container" <div class="edit-text-container"
v-show="scope.row.editShow">{{ scope.row.remark }}</div> v-show="scope.row.editShow">{{ scope.row.remark }}</div>
<div class="inline-block-set"> <div class="inline-block-set">
<i class="el-icon-edit" <i class="el-icon-edit"
@click="editRemarks(scope.row)" @click="editRemarks(scope.row)"
v-show="scope.row.editShow"></i> v-show="scope.row.editShow"></i>
<el-input type="text" <el-input type="text"
v-model="scope.row.remark" v-model="scope.row.remark"
v-show="!scope.row.editShow" v-show="!scope.row.editShow"
:placeholder="$t('public.enter')" :placeholder="$t('public.enter')"
class="remark-input-style"></el-input> class="remark-input-style"></el-input>
<i class="el-icon-check" <i class="el-icon-check"
@click="saveRemarksValue(scope.row)" @click="saveRemarksValue(scope.row)"
v-show="!scope.row.editShow"></i> v-show="!scope.row.editShow"></i>
<i class="el-icon-close" <i class="el-icon-close"
@click="cancelRemarksValue(scope.row)" @click="cancelRemarksValue(scope.row)"
v-show="!scope.row.editShow"></i> v-show="!scope.row.editShow"></i>
<div class="validation-error" <div class="validation-error"
v-show="scope.row.isError"> v-show="scope.row.isError">
{{ $t('modelTraceback.remarkValidation')}} {{ $t('modelTraceback.remarkValidation')}}
</div>
</div> </div>
</div> </template>
</template> </el-table-column>
</el-table-column> <!-- tag column -->
<!-- tag column --> <el-table-column label="tag"
<el-table-column label="tag" fixed="right"
fixed="right" prop="tag"
prop="tag" sortable="custom">
sortable="custom"> <template slot-scope="scope">
<template slot-scope="scope"> <div @click="showAllIcon(scope.row, scope, $event)"
<div @click="showAllIcon(scope.row, scope, $event)" class="tag-icon-container">
class="tag-icon-container"> <img v-if="scope.row.tag"
<img v-if="scope.row.tag" :class="'img' + scope.$index"
:class="'img' + scope.$index" :src="require('@/assets/images/icon' + scope.row.tag + '.svg')">
:src="require('@/assets/images/icon' + scope.row.tag + '.svg')"> <img v-else
<img v-else :class="'img' + scope.$index"
:class="'img' + scope.$index" :src="require('@/assets/images/icon-down.svg')">
:src="require('@/assets/images/icon-down.svg')"> </div>
</div> </template>
</template> </el-table-column>
</el-table-column> </el-table>
</el-table> <div class="pagination-container">
<div class="pagination-container"> <el-pagination @current-change="handleCurrentChange"
<el-pagination @current-change="handleCurrentChange" :current-page="pagination.currentPage"
:current-page="pagination.currentPage" :page-size="pagination.pageSize"
:page-size="pagination.pageSize" :layout="pagination.layout"
:layout="pagination.layout" :total="pagination.total">
:total="pagination.total"> </el-pagination>
</el-pagination> <div class="hide-count"
<div class="hide-count" v-show="recordsNumber-showNumber">
v-show="recordsNumber-showNumber"> {{ $t('modelTraceback.totalHide').replace(`{n}`, (recordsNumber-showNumber))}}
{{ $t('modelTraceback.totalHide').replace(`{n}`, (recordsNumber-showNumber))}} </div>
<div class="clear"></div>
</div> </div>
<div class="clear"></div>
</div> </div>
</div> <div v-show="nodata"
<div v-show="nodata" class="no-data-page">
class="no-data-page"> <div class="no-data-img"
<div class="no-data-img" :class="{'set-height-class':(summaryDirList && !summaryDirList.length)}">
:class="{'set-height-class':(summaryDirList && !summaryDirList.length)}"> <img :src="require('@/assets/images/nodata.png')"
<img :src="require('@/assets/images/nodata.png')" alt="" />
alt="" /> <p class="no-data-text"
<p class="no-data-text" v-show="!summaryDirList || (summaryDirList && summaryDirList.length) && !lineagedata.serData">
v-show="!summaryDirList || (summaryDirList && summaryDirList.length) && !lineagedata.serData"> {{ $t('public.noData') }}
{{ $t('public.noData') }}
</p>
<div v-show="echartNoData && (lineagedata.serData && !!lineagedata.serData.length)">
<p class="no-data-text">{{ $t('dataTraceback.noDataFound') }}</p>
</div>
<div v-show="summaryDirList && !summaryDirList.length">
<p class="no-data-text">{{ $t('dataTraceback.noDataFound') }}</p>
<p class="no-data-text">
{{ $t('dataTraceback.click') }}
<b> {{ $t('modelTraceback.showAllDataBtn') }}</b>
{{ $t('dataTraceback.viewAllData') }}
</p> </p>
<div v-show="echartNoData && (lineagedata.serData && !!lineagedata.serData.length)">
<p class="no-data-text">{{ $t('dataTraceback.noDataFound') }}</p>
</div>
<div v-show="summaryDirList && !summaryDirList.length">
<p class="no-data-text">{{ $t('dataTraceback.noDataFound') }}</p>
<p class="no-data-text">
{{ $t('dataTraceback.click') }}
<b> {{ $t('modelTraceback.showAllDataBtn') }}</b>
{{ $t('dataTraceback.viewAllData') }}
</p>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> <div v-if="detailsDialogVisible">
<div v-if="detailsDialogVisible"> <el-dialog :title="rowName"
<el-dialog :title="rowName" :visible.sync="detailsDialogVisible"
:visible.sync="detailsDialogVisible" width="50%"
width="50%" :close-on-click-modal="false"
:close-on-click-modal="false" class="details-data-list">
class="details-data-list"> <div class="details-data-title">{{ detailsDataTitle }}</div>
<div class="details-data-title">{{ detailsDataTitle }}</div> <el-table :data="detailsDataList"
<el-table :data="detailsDataList" row-key="id"
row-key="id" lazy
lazy tooltip-effect="light"
tooltip-effect="light" :load="loadDataListChildren"
:load="loadDataListChildren" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"> <el-table-column width="50" />
<el-table-column width="50" /> <el-table-column prop="key"
<el-table-column prop="key" width="180"
width="180" label="Key">
label="Key"> </el-table-column>
</el-table-column> <el-table-column prop="value"
<el-table-column prop="value" show-overflow-tooltip
show-overflow-tooltip label="Value">
label="Value"> <template slot-scope="scope">
<template slot-scope="scope"> {{ scope.row.value }}
{{ scope.row.value }} </template>
</template> </el-table-column>
</el-table-column> </el-table>
</el-table> </el-dialog>
</el-dialog> </div>
</div> <!-- tag dialog -->
<!-- tag dialog --> <div v-show="tagDialogShow"
<div v-show="tagDialogShow" id="tag-dialog"
id="tag-dialog" class="icon-dialog">
class="icon-dialog"> <div>
<div> <div class="icon-image-container">
<div class="icon-image-container"> <div class="icon-image"
<div class="icon-image" v-for="item in imageList"
v-for="item in imageList" :key="item.number"
:key="item.number" :class="[tagScope.row && item.number === tagScope.row.tag ? 'icon-border' : '']"
:class="[tagScope.row && item.number === tagScope.row.tag ? 'icon-border' : '']" @click="iconValueChange(tagScope.row, item.number, $event)">
@click="iconValueChange(tagScope.row, item.number, $event)"> <img :src="item.iconAdd">
<img :src="item.iconAdd"> </div>
</div>
</div>
<div class="btn-container-margin">
<div class="tag-button-container">
<el-button type="primary"
size="mini"
class="custom-btn"
@click="iconChangeSave(tagScope)"
plain>
{{ $t('public.sure')}}
</el-button>
</div>
<div class="tag-button-container">
<el-button type="primary"
size="mini"
class="custom-btn"
@click="clearIcon(tagScope,$event)"
plain>
{{ $t('public.clear')}}
</el-button>
</div> </div>
<div class="tag-button-container"> <div class="btn-container-margin">
<el-button type="primary" <div class="tag-button-container">
size="mini" <el-button type="primary"
class="custom-btn" size="mini"
@click="cancelChangeIcon(tagScope.row)" class="custom-btn"
plain> @click="iconChangeSave(tagScope)"
{{ $t('public.cancel')}} plain>
</el-button> {{ $t('public.sure')}}
</el-button>
</div>
<div class="tag-button-container">
<el-button type="primary"
size="mini"
class="custom-btn"
@click="clearIcon(tagScope,$event)"
plain>
{{ $t('public.clear')}}
</el-button>
</div>
<div class="tag-button-container">
<el-button type="primary"
size="mini"
class="custom-btn"
@click="cancelChangeIcon(tagScope.row)"
plain>
{{ $t('public.cancel')}}
</el-button>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -528,13 +535,8 @@ export default { ...@@ -528,13 +535,8 @@ export default {
}, },
computed: {}, computed: {},
mounted() { mounted() {
this.imageList = []; // Set the image display of the tag
for (let i = 1; i <= 10; i++) { this.setTagImage();
const obj = {};
obj.number = i;
obj.iconAdd = require('@/assets/images/icon' + obj.number + '.svg');
this.imageList.push(obj);
}
document.title = `${this.$t('summaryManage.dataTraceback')}-MindInsight`; document.title = `${this.$t('summaryManage.dataTraceback')}-MindInsight`;
document.addEventListener('click', this.blurFloat, true); document.addEventListener('click', this.blurFloat, true);
this.$nextTick(() => { this.$nextTick(() => {
...@@ -542,212 +544,659 @@ export default { ...@@ -542,212 +544,659 @@ export default {
}); });
}, },
methods: { methods: {
blurFloat(event) { setTagImage() {
const domArr = document.querySelectorAll('.icon-dialog'); this.imageList = [];
const path = event.path || (event.composedPath && event.composedPath()); for (let i = 1; i <= 10; i++) {
const isActiveDom = path.some((item) => { const obj = {};
return item.className === 'icon-dialog'; obj.number = i;
}); obj.iconAdd = require('@/assets/images/icon' + obj.number + '.svg');
if (!isActiveDom) { this.imageList.push(obj);
this.removeIconBorder();
domArr.forEach((item) => {
item.style.display = 'none';
});
this.tagDialogShow = false;
}
},
/**
* Display of the icon dialog box
* @param {Object} row
* @param {Object} scope
* @param {Object} event
*/
showAllIcon(row, scope, event) {
this.tagScope = scope;
this.iconValue = row.tag >= 0 ? row.tag : 0;
if (this.tagDialogShow) {
this.tagDialogShow = false;
this.removeIconBorder();
return;
}
this.addIconBorder(row);
this.tagDialogShow = true;
const ev = window.event || event;
document.getElementById('tag-dialog').style.top = ev.clientY - 130 + 'px';
},
/**
* Add icon border style
* @param {Object} row
*/
addIconBorder(row) {
const iconImage = document.querySelectorAll('.icon-image');
iconImage.forEach((item, index) => {
if (index + 1 === row.tag) {
item.classList.add('icon-border');
}
});
},
/**
* Remove icon border style
*/
removeIconBorder() {
const classArr = document.querySelectorAll('.icon-border');
if (classArr.length) {
classArr.forEach((item) => {
item.classList.remove('icon-border');
});
}
},
/**
* icon value change
* @param {Object} row
* @param {Number} num
* @param {Object} event
*/
iconValueChange(row, num, event) {
const path = event.path || (event.composedPath && event.composedPath());
const classWrap = path.find((item) => {
return item.className === 'icon-dialog';
});
const classArr = classWrap.querySelectorAll('.icon-border');
classArr.forEach((item) => {
item.classList.remove('icon-border');
});
const htmDom = path.find((item) => {
return item.nodeName === 'DIV';
});
htmDom.classList.add('icon-border');
this.iconValue = num;
},
/**
* Save the modification of the icon
* @param {Object} scope
*/
iconChangeSave(scope) {
this.tagDialogShow = false;
if (scope.row.tag === this.iconValue || this.iconValue === 0) {
return;
} }
this.tagScope.row.tag = this.iconValue;
const imgDom = document.querySelectorAll('.img' + scope.$index);
imgDom.forEach((item) => {
item.src = require('@/assets/images/icon' + this.iconValue + '.svg');
});
this.$forceUpdate();
const params = {
train_id: scope.row.summary_dir,
body: {
tag: this.tagScope.row.tag,
},
};
this.putChangeToLineagesData(params);
},
/**
* clear icon
* @param {Object} scope
* @param {Object} event
*/
clearIcon(scope, event) {
const path = event.path || (event.composedPath && event.composedPath());
const classWrap = path.find((item) => {
return item.className === 'icon-dialog';
});
const classArr = classWrap.querySelectorAll('.icon-border');
classArr.forEach((item) => {
item.classList.remove('icon-border');
});
this.tagDialogShow = false;
this.iconValue = 0;
this.tagScope.row.tag = 0;
const imgDom = document.querySelectorAll('.img' + scope.$index);
imgDom.forEach((item) => {
item.src = require('@/assets/images/icon-down.svg');
});
const params = {
train_id: scope.row.summary_dir,
body: {
tag: 0,
},
};
this.putChangeToLineagesData(params);
this.tagDialogShow = false;
},
/**
* Cancel Save
* @param {Object} row
*/
cancelChangeIcon(row) {
this.removeIconBorder();
this.addIconBorder(row);
this.tagDialogShow = false;
}, },
/** Data source page initialization**/
/** /**
* Select all * init
*/ */
allSelect() { init() {
if (this.selectCheckAll) { this.customizedColumnOptions =
return; this.$store.state.customizedColumnOptions || [];
this.table.columnOptions = Object.assign(
this.table.columnOptions,
this.customizedColumnOptions,
);
// Obtain the value of summary_dir from the store,
this.summaryDirList = this.$store.state.summaryDirList;
this.selectedBarList = this.$store.state.selectedBarList;
if (this.selectedBarList && this.selectedBarList.length) {
this.tableFilter = {};
} else {
this.tableFilter.lineage_type = {in: ['dataset']};
} }
this.selectArrayValue = []; const params = {};
this.checkOptions.forEach((item) => { if (this.summaryDirList) {
this.selectArrayValue.push(item.value); this.tableFilter.summary_dir = {in: this.summaryDirList};
});
this.selectCheckAll = !this.selectCheckAll;
this.$nextTick(() => {
this.initChart();
});
const list = [];
this.checkOptions.forEach((item) => {
this.selectArrayValue.forEach((i) => {
if (i === item.value) {
list.push(i);
}
});
});
if (this.selectedBarList) {
const resultArray = this.hideDataMarkTableData();
this.table.column = this.dirPathList.concat(resultArray, list);
} else { } else {
this.table.column = this.dirPathList.concat(list); this.tableFilter.summary_dir = undefined;
} }
params.body = Object.assign({}, this.tableFilter);
this.queryLineagesData(params);
}, },
/** /**
* deselect all * Method of invoking the interface
* @param {Object} params
*/ */
deselectAll() { queryLineagesData(params) {
this.selectArrayValue = []; RequestService.queryLineagesData(params)
this.checkOptions.forEach((item) => { .then(
if (item.disabled) { (res) => {
this.selectArrayValue.push(item.value); this.initOver = true;
} this.loading = false;
}); this.echartNoData = false;
this.selectCheckAll = false; if (!res || !res.data) {
this.$nextTick(() => { this.nodata = true;
this.initChart(); return;
}); }
const list = []; this.nodata = false;
this.checkOptions.forEach((item) => { this.errorData = false;
this.selectArrayValue.forEach((i) => { this.customizedTypeObject = res.data.customized;
if (i === item.value) { let keys = Object.keys(this.customizedTypeObject);
list.push(i); if (keys.length) {
} keys = keys.map((i) => {
}); if (i.startsWith(this.replaceStr.userDefined)) {
}); return i.replace(this.replaceStr.userDefined, '[U]');
if (this.selectedBarList) { } else if (i.startsWith(this.replaceStr.metric)) {
const resultArray = this.hideDataMarkTableData(); return i.replace(this.replaceStr.metric, '[M]');
this.table.column = this.dirPathList.concat(resultArray, list); }
});
this.sortArray = this.sortArray.concat(keys);
}
// Model source tracing filtering parameters
this.selectedBarList = this.$store.state.selectedBarList;
if (this.selectedBarList && this.selectedBarList.length) {
const tempList = JSON.parse(JSON.stringify(res.data.object));
const list = [];
const metricKeys = {};
tempList.forEach((item) => {
if (item.model_lineage) {
const modelData = JSON.parse(
JSON.stringify(item.model_lineage),
);
modelData.model_size = parseFloat(
((modelData.model_size || 0) / 1024 / 1024).toFixed(2),
);
const keys = Object.keys(modelData.metric || {});
if (keys.length) {
keys.forEach((key) => {
if (
modelData.metric[key] ||
modelData.metric[key] === 0
) {
const temp = this.replaceStr.metric + key;
metricKeys[temp] = key;
modelData[temp] = modelData.metric[key];
}
});
delete modelData.metric;
}
const udkeys = Object.keys(modelData.user_defined || {});
if (udkeys.length) {
udkeys.forEach((key) => {
if (
modelData.user_defined[key] ||
modelData.user_defined[key] === 0
) {
const temp = this.replaceStr.userDefined + key;
modelData[temp] = modelData.user_defined[key];
}
});
delete modelData.user_defined;
}
list.push(modelData);
}
});
this.modelObjectArray = [];
for (let i = 0; i < list.length; i++) {
const modelObject = {};
for (let j = 0; j < this.selectedBarList.length; j++) {
const tempObject = list[i];
const key = this.selectedBarList[j];
modelObject[key] = tempObject[key];
}
this.modelObjectArray.push(modelObject);
}
}
this.fixedSeries = [];
this.noFixedSeries = [];
this.checkedSeries = [];
this.lineagedata = this.formateOriginData(res.data);
this.totalSeries = this.lineagedata.fullNodeList;
if (!this.totalSeries.length) {
this.echartNoData = true;
this.nodata = true;
} else {
this.nodata = false;
}
this.totalSeries.forEach((nodeItem) => {
if (this.createType[nodeItem.name]) {
nodeItem.checked = true;
this.fixedSeries.push(nodeItem);
} else {
nodeItem.checked = false;
this.noFixedSeries.push(nodeItem);
}
});
this.noFixedSeries.forEach((item) => {
item.checked = true;
});
this.getCheckedSerList();
if (this.fixedSeries.length) {
this.setObjectValue(this.fixedSeries, true);
}
if (this.noFixedSeries.length) {
this.setObjectValue(this.noFixedSeries, false);
}
const list1 = this.fixedSeries.concat(this.noFixedSeries);
list1.forEach((item, index) => {
this.checkOptions[index] = {};
this.basearr[index] = {};
this.checkOptions[index].label = item.name;
this.checkOptions[index].value = item.id;
if (this.createType[item.name]) {
this.checkOptions[index].disabled = true;
this.basearr[index].disabled = true;
}
this.basearr[index].label = item.name;
this.basearr[index].value = item.id;
});
this.checkOptions.forEach((item) => {
this.selectArrayValue.push(item.value);
});
this.hidenDirChecked = this.$store.state.hidenDirChecked || [];
this.echart.brushData = this.lineagedata.serData;
if (this.hidenDirChecked.length) {
const listdada = this.lineagedata.serData.slice();
this.hidenDirChecked.forEach((item) => {
listdada.forEach((i, index) => {
if (i.summary_dir === item) {
listdada.splice(index, 1);
}
});
});
if (listdada.length) {
this.showEchartPic = true;
} else {
this.showEchartPic = false;
}
this.echart.showData = listdada;
} else {
this.echart.showData = this.echart.brushData;
this.showEchartPic = true;
}
this.resizeChart();
this.setEchartValue();
this.$nextTick(() => {
this.initChart();
});
// Total number of pages in the table
this.pagination.total = res.data.count;
// Data encapsulation of the table
let data = [];
data = this.setTableData();
this.table.data = data;
this.showTable = true;
if (this.selectedBarList) {
const resultArray = this.hideDataMarkTableData();
this.table.column = this.dirPathList.concat(
resultArray,
this.checkedSeries.map((i) => i.id),
);
} else {
this.table.column = this.dirPathList.concat(
this.checkedSeries.map((i) => i.id),
);
}
},
(error) => {
this.loading = false;
this.initOver = true;
this.showEchartPic = false;
this.errorData = true;
this.nodata = true;
},
)
.catch(() => {
this.loading = false;
this.initOver = true;
this.showEchartPic = false;
this.errorData = true;
this.nodata = true;
});
},
/**
* Gets the selected items and updates the select all state.
*/
getCheckedSerList() {
this.checkedSeries = [];
this.totalSeries.forEach((nodeItem) => {
if (nodeItem.checked) {
this.checkedSeries.push(nodeItem);
}
});
},
/**
* Chart data encapsulation
* @param {Object} data
* @return {Object}
*/
formateOriginData(data) {
if (!data || !data.object) {
return {};
}
// Preliminarily filter the required data from the original data and form a unified format.
const objectDataArr = [];
data.object.forEach((object) => {
this.tempFormateData = {
nodeList: [],
children: false,
summary_dir: object.summary_dir,
remark: object.added_info.remark ? object.added_info.remark : '',
tag: object.added_info.tag,
};
if (JSON.stringify(object.dataset_graph) !== '{}') {
this.getSingleRunData(object.dataset_graph);
}
objectDataArr.push(JSON.parse(JSON.stringify(this.tempFormateData)));
});
// The data in the unified format is combined by category.
const fullNodeList = [];
const tempDic = {};
objectDataArr.forEach((objectData) => {
if (fullNodeList.length) {
let startIndex = 0;
let tempNodeListMap = fullNodeList.map((nodeObj) => nodeObj.name);
objectData.nodeList.forEach((nodeItem) => {
const tempIndex = tempNodeListMap.indexOf(
nodeItem.name,
startIndex,
);
if (tempIndex === -1) {
if (!tempDic[nodeItem.name]) {
tempDic[nodeItem.name] = 0;
}
tempDic[nodeItem.name]++;
let tempId = '';
const createKey = Object.keys(this.createType);
if (createKey.includes(nodeItem.name)) {
tempId = nodeItem.name;
} else {
tempId = `${nodeItem.name}${tempDic[nodeItem.name]}`;
}
fullNodeList.splice(startIndex, 0, {
name: nodeItem.name,
id: tempId,
});
nodeItem.id = tempId;
startIndex++;
tempNodeListMap = fullNodeList.map((nodeObj) => nodeObj.name);
} else {
nodeItem.id = fullNodeList[tempIndex].id;
startIndex = tempIndex + 1;
}
});
} else {
objectData.nodeList.forEach((nodeItem) => {
if (!tempDic[nodeItem.name]) {
tempDic[nodeItem.name] = 0;
}
tempDic[nodeItem.name]++;
const createKey = Object.keys(this.createType);
if (createKey.includes(nodeItem.name)) {
fullNodeList.push({
name: nodeItem.name,
id: nodeItem.name,
});
nodeItem.id = nodeItem.name;
} else {
fullNodeList.push({
name: nodeItem.name,
id: `${nodeItem.name}${tempDic[nodeItem.name]}`,
});
nodeItem.id = `${nodeItem.name}${tempDic[nodeItem.name]}`;
}
});
}
});
// Obtain the value of run on each coordinate.
const serData = [];
objectDataArr.forEach((objectData) => {
const curDataObj = {};
objectData.nodeList.forEach((nodeItem) => {
curDataObj[nodeItem.id] = nodeItem.value;
});
curDataObj.children = objectData.children;
curDataObj.summary_dir = objectData.summary_dir;
// set remark value
curDataObj.remark = objectData.remark;
// set tag value
curDataObj.tag = objectData.tag;
// set remark icon is show
curDataObj.editShow = true;
curDataObj.isError = false;
serData.push(curDataObj);
});
const formateData = {
fullNodeList: fullNodeList,
serData: serData,
};
return formateData;
},
setEchartValue() {
if (this.modelObjectArray.length) {
const list = this.echart.showData;
for (let i = 0; i < list.length; i++) {
const temp = this.modelObjectArray[i];
this.echart.showData[i] = Object.assign(
this.echart.showData[i],
temp,
);
}
}
},
/*
* Initialize the echart diagram.
*/
initChart() {
const parallelAxis = [];
const selectedBarList = this.$store.state.selectedBarList;
const data = [];
const arrayTemp = [];
if (selectedBarList && selectedBarList.length) {
selectedBarList.forEach((item) => {
const value = this.customizedTypeObject[item];
const obj = {
name: this.table.columnOptions[item].label,
id: item,
checked: true,
};
if (value && value.type === this.valueType.float) {
obj.type = this.valueType.float;
} else if (value && value.type === this.valueType.int) {
obj.type = this.valueType.int;
}
arrayTemp.push(obj);
});
}
const list = [];
this.basearr.forEach((item) => {
this.selectArrayValue.forEach((i) => {
if (i === item.value) {
const obj = {};
obj.id = item.value;
obj.name = item.label;
list.push(obj);
}
});
});
const totalBarArray = arrayTemp.concat(list);
this.echart.showData.forEach((val, i) => {
let item = {};
item = {
lineStyle: {
normal: {
color: CommonProperty.commonColorArr[i % 10],
},
},
value: [],
};
totalBarArray.forEach((obj) => {
item.value.push(val[obj.id]);
});
data.push(item);
});
totalBarArray.forEach((content, i) => {
const obj = {dim: i, name: content.name, id: content.id};
if (
content.name === this.repeatTitle ||
content.name === this.shuffleTitle ||
content.id === this.deviceNum ||
(content.type && content.type === this.valueType.int)
) {
obj.scale = true;
obj.minInterval = 1;
this.setColorOfSelectedBar(selectedBarList, obj);
} else if (
this.numberTypeIdList.includes(content.id) ||
(content.type && content.type === this.valueType.float)
) {
obj.scale = true;
this.setColorOfSelectedBar(selectedBarList, obj);
} else {
// String type
obj.type = this.categoryType;
obj.axisLabel = {
show: false,
};
this.setColorOfSelectedBar(selectedBarList, obj);
if (content.id === this.valueType.dataset_mark) {
obj.axisLabel = {
show: false,
};
}
const values = {};
this.echart.showData.forEach((i) => {
if (i[content.id] || i[content.id] === 0) {
values[i[content.id]] = '';
}
});
obj.data = Object.keys(values);
}
parallelAxis.push(obj);
});
const option = {
backgroundColor: 'white',
parallelAxis: parallelAxis,
tooltip: {
trigger: 'axis',
},
parallel: {
top: 30,
left: 90,
right: 100,
bottom: 12,
parallelAxisDefault: {
areaSelectStyle: {
width: 40,
},
tooltip: {
show: true,
},
realtime: false,
},
},
series: {
type: 'parallel',
lineStyle: {
width: 1,
opacity: 1,
},
data: data,
},
};
if (this.parallelEchart) {
this.parallelEchart.off('axisareaselected', null);
window.removeEventListener('resize', this.resizeChart, false);
} else {
this.parallelEchart = Echarts.init(
document.querySelector('#data-echart'),
);
}
this.parallelEchart.setOption(option, true);
window.addEventListener('resize', this.resizeChart, false);
this.chartEventsListen(parallelAxis);
},
chartEventsListen(parallelAxis) {
this.parallelEchart.on('axisareaselected', (params) => {
this.recordsNumber = 0;
this.showNumber = 0;
const key = params.parallelAxisId;
const range = params.intervals[0] || [];
const [axisData] = parallelAxis.filter((i) => {
return i.id === key;
});
if (axisData && range.length === 2) {
if (axisData.type === this.categoryType) {
const selectedAxisKeys = axisData.data.slice(
range[0],
range[1] + 1,
);
this.echart.brushData = this.echart.showData.filter((i) => {
return selectedAxisKeys.includes(i[key]);
});
} else {
this.echart.brushData = this.echart.showData.filter((i) => {
return i[key] >= range[0] && i[key] <= range[1];
});
}
const tempList = this.echart.brushData;
const summaryList = [];
tempList.forEach((item) => {
summaryList.push(item.summary_dir);
});
// The summaryList value could not be saved in the destroy state.
this.dataCheckedSummary = [];
this.$store.commit('setSummaryDirList', summaryList);
this.tableFilter.summary_dir = {in: summaryList};
if (!tempList.length) {
this.summaryDirList = [];
this.lineagedata.serData = undefined;
this.showTable = false;
this.nodata = true;
this.echartNoData = true;
} else {
this.echart.showData = this.echart.brushData;
this.$nextTick(() => {
this.initChart();
});
this.pagination.currentPage = 1;
this.pagination.total = this.echart.brushData.length;
this.table.data = this.echart.brushData.slice(
(this.pagination.currentPage - 1) * this.pagination.pageSize,
this.pagination.currentPage * this.pagination.pageSize,
);
const tableLength = this.table.data.length;
this.recordsNumber = tableLength;
this.showNumber = tableLength;
this.showTable = true;
}
}
});
},
/**
* The window size changes. Resizing Chart
*/
resizeChart() {
if (
document.getElementById('data-echart') &&
document.getElementById('data-echart').style.display !== 'none' &&
this.parallelEchart
) {
this.parallelEchart.resize();
}
},
/**
* Setting Table Data
* @return {Array}
*/
setTableData() {
let data = [];
// Table data encapsulation
const pathData = JSON.parse(JSON.stringify(this.echart.brushData));
// Obtain table data based on the page number and number of records.
data = pathData.slice(
(this.pagination.currentPage - 1) * this.pagination.pageSize,
this.pagination.currentPage * this.pagination.pageSize,
);
this.recordsNumber = data.length;
if (this.hidenDirChecked.length) {
this.hidenDirChecked.forEach((dir) => {
data.forEach((item, index) => {
if (item.summary_dir === dir) {
data.splice(index, 1);
}
});
});
}
this.showNumber = data.length;
return data;
},
/**
* The table column data is deleted from the data processing result.
* @return {Array}
*/
hideDataMarkTableData() {
const result = [];
this.selectedBarList.forEach((item) => {
if (item !== this.valueType.dataset_mark) {
result.push(item);
}
});
return result;
},
/**
* Set the color of the model tracing axis.
* @param {Array} selectedBarList
* @param {Object} obj
*/
setColorOfSelectedBar(selectedBarList, obj) {
if (selectedBarList && obj.dim < selectedBarList.length) {
obj.nameTextStyle = {
color: '#00a5a7',
};
obj.axisLabel = {
show: true,
textStyle: {
color: '#00a5a7',
},
formatter: function(val) {
if (typeof val !== 'string') {
return val;
}
const strs = val.split('');
let str = '';
const maxStringLength = 100;
const showStringLength = 12;
if (val.length > maxStringLength) {
return val.substring(0, showStringLength) + '...';
} else {
for (let i = 0, s = ''; (s = strs[i++]); ) {
str += s;
if (!(i % showStringLength)) {
str += '\n';
}
}
return str;
}
},
};
obj.axisLine = {
show: true,
lineStyle: {
color: '#00a5a7',
},
};
} else { } else {
this.table.column = this.dirPathList.concat(list); // Text color
obj.nameTextStyle = {
color: 'black',
};
} }
}, },
...@@ -792,7 +1241,6 @@ export default { ...@@ -792,7 +1241,6 @@ export default {
row.remark = this.beforeEditValue; row.remark = this.beforeEditValue;
row.isError = false; row.isError = false;
}, },
/** /**
* After the remark or tag is modified,invoke the interface and save the modification * After the remark or tag is modified,invoke the interface and save the modification
* @param {Object} params * @param {Object} params
...@@ -810,6 +1258,216 @@ export default { ...@@ -810,6 +1258,216 @@ export default {
.catch(() => {}); .catch(() => {});
}, },
// Set tag style
blurFloat(event) {
const domArr = document.querySelectorAll('.icon-dialog');
const path = event.path || (event.composedPath && event.composedPath());
const isActiveDom = path.some((item) => {
return item.className === 'icon-dialog';
});
if (!isActiveDom) {
this.removeIconBorder();
domArr.forEach((item) => {
item.style.display = 'none';
});
this.tagDialogShow = false;
}
},
/**
* Display of the icon dialog box
* @param {Object} row
* @param {Object} scope
* @param {Object} event
*/
showAllIcon(row, scope, event) {
this.tagScope = scope;
this.iconValue = row.tag >= 0 ? row.tag : 0;
if (this.tagDialogShow) {
this.tagDialogShow = false;
this.removeIconBorder();
return;
}
this.addIconBorder(row);
this.tagDialogShow = true;
const ev = window.event || event;
document.getElementById('tag-dialog').style.top = ev.clientY - 130 + 'px';
},
/**
* Add icon border style
* @param {Object} row
*/
addIconBorder(row) {
const iconImage = document.querySelectorAll('.icon-image');
iconImage.forEach((item, index) => {
if (index + 1 === row.tag) {
item.classList.add('icon-border');
}
});
},
/**
* Remove icon border style
*/
removeIconBorder() {
const classArr = document.querySelectorAll('.icon-border');
if (classArr.length) {
classArr.forEach((item) => {
item.classList.remove('icon-border');
});
}
},
/**
* icon value change
* @param {Object} row
* @param {Number} num
* @param {Object} event
*/
iconValueChange(row, num, event) {
const path = event.path || (event.composedPath && event.composedPath());
const classWrap = path.find((item) => {
return item.className === 'icon-dialog';
});
const classArr = classWrap.querySelectorAll('.icon-border');
classArr.forEach((item) => {
item.classList.remove('icon-border');
});
const htmDom = path.find((item) => {
return item.nodeName === 'DIV';
});
htmDom.classList.add('icon-border');
this.iconValue = num;
},
/**
* Save the modification of the icon
* @param {Object} scope
*/
iconChangeSave(scope) {
this.tagDialogShow = false;
if (scope.row.tag === this.iconValue || this.iconValue === 0) {
return;
}
this.tagScope.row.tag = this.iconValue;
const imgDom = document.querySelectorAll('.img' + scope.$index);
imgDom.forEach((item) => {
item.src = require('@/assets/images/icon' + this.iconValue + '.svg');
});
this.$forceUpdate();
const params = {
train_id: scope.row.summary_dir,
body: {
tag: this.tagScope.row.tag,
},
};
this.putChangeToLineagesData(params);
},
/**
* clear icon
* @param {Object} scope
* @param {Object} event
*/
clearIcon(scope, event) {
const path = event.path || (event.composedPath && event.composedPath());
const classWrap = path.find((item) => {
return item.className === 'icon-dialog';
});
const classArr = classWrap.querySelectorAll('.icon-border');
classArr.forEach((item) => {
item.classList.remove('icon-border');
});
this.tagDialogShow = false;
this.iconValue = 0;
this.tagScope.row.tag = 0;
const imgDom = document.querySelectorAll('.img' + scope.$index);
imgDom.forEach((item) => {
item.src = require('@/assets/images/icon-down.svg');
});
const params = {
train_id: scope.row.summary_dir,
body: {
tag: 0,
},
};
this.putChangeToLineagesData(params);
this.tagDialogShow = false;
},
/**
* Cancel Save
* @param {Object} row
*/
cancelChangeIcon(row) {
this.removeIconBorder();
this.addIconBorder(row);
this.tagDialogShow = false;
},
/**
* Select all
*/
allSelect() {
if (this.selectCheckAll) {
return;
}
this.selectArrayValue = [];
this.checkOptions.forEach((item) => {
this.selectArrayValue.push(item.value);
});
this.selectCheckAll = !this.selectCheckAll;
this.$nextTick(() => {
this.initChart();
});
const list = [];
this.checkOptions.forEach((item) => {
this.selectArrayValue.forEach((i) => {
if (i === item.value) {
list.push(i);
}
});
});
if (this.selectedBarList) {
const resultArray = this.hideDataMarkTableData();
this.table.column = this.dirPathList.concat(resultArray, list);
} else {
this.table.column = this.dirPathList.concat(list);
}
},
/**
* deselect all
*/
deselectAll() {
this.selectArrayValue = [];
this.checkOptions.forEach((item) => {
if (item.disabled) {
this.selectArrayValue.push(item.value);
}
});
this.selectCheckAll = false;
this.$nextTick(() => {
this.initChart();
});
const list = [];
this.checkOptions.forEach((item) => {
this.selectArrayValue.forEach((i) => {
if (i === item.value) {
list.push(i);
}
});
});
if (this.selectedBarList) {
const resultArray = this.hideDataMarkTableData();
this.table.column = this.dirPathList.concat(resultArray, list);
} else {
this.table.column = this.dirPathList.concat(list);
}
},
/** /**
* Hidden records * Hidden records
*/ */
...@@ -938,307 +1596,37 @@ export default { ...@@ -938,307 +1596,37 @@ export default {
}, },
/** /**
* Selected data in the table * Selected data in the table
*/
selectValueChange() {
const templist = [];
this.basearr.forEach((item) => {
templist.push(item.label);
});
if (templist.length > this.selectArrayValue.length) {
this.selectCheckAll = false;
} else {
this.selectCheckAll = true;
}
this.$nextTick(() => {
this.initChart();
});
const list = [];
this.basearr.forEach((item) => {
this.selectArrayValue.forEach((i) => {
if (i === item.value) {
list.push(i);
}
});
});
if (this.selectedBarList) {
const resultArray = this.hideDataMarkTableData();
this.table.column = this.dirPathList.concat(resultArray, list);
} else {
this.table.column = this.dirPathList.concat(list);
}
},
/**
* init
*/
init() {
this.customizedColumnOptions =
this.$store.state.customizedColumnOptions || [];
this.table.columnOptions = Object.assign(
this.table.columnOptions,
this.customizedColumnOptions,
);
// Obtain the value of summary_dir from the store,
this.summaryDirList = this.$store.state.summaryDirList;
this.selectedBarList = this.$store.state.selectedBarList;
if (this.selectedBarList && this.selectedBarList.length) {
this.tableFilter = {};
} else {
this.tableFilter.lineage_type = {in: ['dataset']};
}
const params = {};
if (this.summaryDirList) {
this.tableFilter.summary_dir = {in: this.summaryDirList};
} else {
this.tableFilter.summary_dir = undefined;
}
params.body = Object.assign({}, this.tableFilter);
this.queryLineagesData(params);
},
/*
* Initialize the echart diagram.
*/
initChart() {
const parallelAxis = [];
const selectedBarList = this.$store.state.selectedBarList;
const data = [];
const arrayTemp = [];
if (selectedBarList && selectedBarList.length) {
selectedBarList.forEach((item) => {
const value = this.customizedTypeObject[item];
const obj = {
name: this.table.columnOptions[item].label,
id: item,
checked: true,
};
if (value && value.type === this.valueType.float) {
obj.type = this.valueType.float;
} else if (value && value.type === this.valueType.int) {
obj.type = this.valueType.int;
}
arrayTemp.push(obj);
});
}
const list = [];
this.basearr.forEach((item) => {
this.selectArrayValue.forEach((i) => {
if (i === item.value) {
const obj = {};
obj.id = item.value;
obj.name = item.label;
list.push(obj);
}
});
});
const totalBarArray = arrayTemp.concat(list);
this.echart.showData.forEach((val, i) => {
let item = {};
item = {
lineStyle: {
normal: {
color: CommonProperty.commonColorArr[i % 10],
},
},
value: [],
};
totalBarArray.forEach((obj) => {
item.value.push(val[obj.id]);
});
data.push(item);
});
totalBarArray.forEach((content, i) => {
const obj = {dim: i, name: content.name, id: content.id};
if (
content.name === this.repeatTitle ||
content.name === this.shuffleTitle ||
content.id === this.deviceNum ||
(content.type && content.type === this.valueType.int)
) {
obj.scale = true;
obj.minInterval = 1;
this.setColorOfSelectedBar(selectedBarList, obj);
} else if (
this.numberTypeIdList.includes(content.id) ||
(content.type && content.type === this.valueType.float)
) {
obj.scale = true;
this.setColorOfSelectedBar(selectedBarList, obj);
} else {
// String type
obj.type = this.categoryType;
obj.axisLabel = {
show: false,
};
this.setColorOfSelectedBar(selectedBarList, obj);
if (content.id === this.valueType.dataset_mark) {
obj.axisLabel = {
show: false,
};
}
const values = {};
this.echart.showData.forEach((i) => {
if (i[content.id] || i[content.id] === 0) {
values[i[content.id]] = '';
}
});
obj.data = Object.keys(values);
}
parallelAxis.push(obj);
});
const option = {
backgroundColor: 'white',
parallelAxis: parallelAxis,
tooltip: {
trigger: 'axis',
},
parallel: {
top: 30,
left: 90,
right: 100,
bottom: 12,
parallelAxisDefault: {
areaSelectStyle: {
width: 40,
},
tooltip: {
show: true,
},
realtime: false,
},
},
series: {
type: 'parallel',
lineStyle: {
width: 1,
opacity: 1,
},
data: data,
},
};
if (this.parallelEchart) {
this.parallelEchart.off('axisareaselected', null);
window.removeEventListener('resize', this.resizeChart, false);
} else {
this.parallelEchart = Echarts.init(
document.querySelector('#data-echart'),
);
}
this.parallelEchart.setOption(option, true);
window.addEventListener('resize', this.resizeChart, false);
this.chartEventsListen(parallelAxis);
},
chartEventsListen(parallelAxis) {
this.parallelEchart.on('axisareaselected', (params) => {
this.recordsNumber = 0;
this.showNumber = 0;
const key = params.parallelAxisId;
const range = params.intervals[0] || [];
const [axisData] = parallelAxis.filter((i) => {
return i.id === key;
});
if (axisData && range.length === 2) {
if (axisData.type === this.categoryType) {
const selectedAxisKeys = axisData.data.slice(
range[0],
range[1] + 1,
);
this.echart.brushData = this.echart.showData.filter((i) => {
return selectedAxisKeys.includes(i[key]);
});
} else {
this.echart.brushData = this.echart.showData.filter((i) => {
return i[key] >= range[0] && i[key] <= range[1];
});
}
const tempList = this.echart.brushData;
const summaryList = [];
tempList.forEach((item) => {
summaryList.push(item.summary_dir);
});
// The summaryList value could not be saved in the destroy state.
this.dataCheckedSummary = [];
this.$store.commit('setSummaryDirList', summaryList);
this.tableFilter.summary_dir = {in: summaryList};
if (!tempList.length) {
this.summaryDirList = [];
this.lineagedata.serData = undefined;
this.showTable = false;
this.nodata = true;
this.echartNoData = true;
} else {
this.echart.showData = this.echart.brushData;
this.$nextTick(() => {
this.initChart();
});
this.pagination.currentPage = 1;
this.pagination.total = this.echart.brushData.length;
this.table.data = this.echart.brushData.slice(
(this.pagination.currentPage - 1) * this.pagination.pageSize,
this.pagination.currentPage * this.pagination.pageSize,
);
const tableLength = this.table.data.length;
this.recordsNumber = tableLength;
this.showNumber = tableLength;
this.showTable = true;
}
}
});
},
/**
* Set the color of the model tracing axis.
* @param {Array} selectedBarList
* @param {Object} obj
*/ */
setColorOfSelectedBar(selectedBarList, obj) { selectValueChange() {
if (selectedBarList && obj.dim < selectedBarList.length) { const templist = [];
obj.nameTextStyle = { this.basearr.forEach((item) => {
color: '#00a5a7', templist.push(item.label);
}; });
obj.axisLabel = { if (templist.length > this.selectArrayValue.length) {
show: true, this.selectCheckAll = false;
textStyle: {
color: '#00a5a7',
},
formatter: function(val) {
if (typeof val !== 'string') {
return val;
}
const strs = val.split('');
let str = '';
const maxStringLength = 100;
const showStringLength = 12;
if (val.length > maxStringLength) {
return val.substring(0, showStringLength) + '...';
} else {
for (let i = 0, s = ''; (s = strs[i++]); ) {
str += s;
if (!(i % showStringLength)) {
str += '\n';
}
}
return str;
}
},
};
obj.axisLine = {
show: true,
lineStyle: {
color: '#00a5a7',
},
};
} else { } else {
// Text color this.selectCheckAll = true;
obj.nameTextStyle = {
color: 'black',
};
} }
}, this.$nextTick(() => {
this.initChart();
});
const list = [];
this.basearr.forEach((item) => {
this.selectArrayValue.forEach((i) => {
if (i === item.value) {
list.push(i);
}
});
});
if (this.selectedBarList) {
const resultArray = this.hideDataMarkTableData();
this.table.column = this.dirPathList.concat(resultArray, list);
} else {
this.table.column = this.dirPathList.concat(list);
}
},
/** /**
* jump to train dashboard * jump to train dashboard
* @param {String} val * @param {String} val
...@@ -1251,7 +1639,14 @@ export default { ...@@ -1251,7 +1639,14 @@ export default {
}); });
window.open(routeUrl.href, '_blank'); window.open(routeUrl.href, '_blank');
}, },
/**
* Jump to DataTraceback
*/
jumpToModelTraceback() {
this.$router.push({
path: '/model-traceback',
});
},
/** /**
* Formatting Data * Formatting Data
* @param {String} key * @param {String} key
...@@ -1404,264 +1799,46 @@ export default { ...@@ -1404,264 +1799,46 @@ export default {
modelData[temp] = modelData.user_defined[key]; modelData[temp] = modelData.user_defined[key];
} }
}); });
delete modelData.user_defined; delete modelData.user_defined;
}
list.push(modelData);
}
});
this.modelObjectArray = [];
for (let i = 0; i < list.length; i++) {
const modelObject = {};
for (let j = 0; j < this.selectedBarList.length; j++) {
const tempObject = list[i];
const key = this.selectedBarList[j];
modelObject[key] = tempObject[key];
}
this.modelObjectArray.push(modelObject);
}
if (this.modelObjectArray.length) {
const list = JSON.parse(JSON.stringify(serData));
for (let i = 0; i < list.length; i++) {
const temp = this.modelObjectArray[i];
list[i] = Object.assign(list[i], temp);
}
this.table.data = list;
} else {
this.table.data = JSON.parse(JSON.stringify(serData));
}
} else {
this.table.data = JSON.parse(JSON.stringify(serData));
}
},
(error) => {
this.errorData = true;
this.nodata = true;
},
)
.catch(() => {
this.errorData = true;
this.nodata = true;
});
},
/**
* Method of invoking the interface
* @param {Object} params
*/
queryLineagesData(params) {
RequestService.queryLineagesData(params)
.then(
(res) => {
this.initOver = true;
this.loading = false;
this.echartNoData = false;
if (!res || !res.data) {
this.nodata = true;
return;
}
this.nodata = false;
this.errorData = false;
this.customizedTypeObject = res.data.customized;
let keys = Object.keys(this.customizedTypeObject);
if (keys.length) {
keys = keys.map((i) => {
if (i.startsWith(this.replaceStr.userDefined)) {
return i.replace(this.replaceStr.userDefined, '[U]');
} else if (i.startsWith(this.replaceStr.metric)) {
return i.replace(this.replaceStr.metric, '[M]');
}
});
this.sortArray = this.sortArray.concat(keys);
}
// Model source tracing filtering parameters
this.selectedBarList = this.$store.state.selectedBarList;
if (this.selectedBarList && this.selectedBarList.length) {
const tempList = JSON.parse(JSON.stringify(res.data.object));
const list = [];
const metricKeys = {};
tempList.forEach((item) => {
if (item.model_lineage) {
const modelData = JSON.parse(
JSON.stringify(item.model_lineage),
);
modelData.model_size = parseFloat(
((modelData.model_size || 0) / 1024 / 1024).toFixed(2),
);
const keys = Object.keys(modelData.metric || {});
if (keys.length) {
keys.forEach((key) => {
if (
modelData.metric[key] ||
modelData.metric[key] === 0
) {
const temp = this.replaceStr.metric + key;
metricKeys[temp] = key;
modelData[temp] = modelData.metric[key];
}
});
delete modelData.metric;
}
const udkeys = Object.keys(modelData.user_defined || {});
if (udkeys.length) {
udkeys.forEach((key) => {
if (
modelData.user_defined[key] ||
modelData.user_defined[key] === 0
) {
const temp = this.replaceStr.userDefined + key;
modelData[temp] = modelData.user_defined[key];
}
});
delete modelData.user_defined;
}
list.push(modelData);
}
});
this.modelObjectArray = [];
for (let i = 0; i < list.length; i++) {
const modelObject = {};
for (let j = 0; j < this.selectedBarList.length; j++) {
const tempObject = list[i];
const key = this.selectedBarList[j];
modelObject[key] = tempObject[key];
}
this.modelObjectArray.push(modelObject);
}
}
this.fixedSeries = [];
this.noFixedSeries = [];
this.checkedSeries = [];
this.lineagedata = this.formateOriginData(res.data);
this.totalSeries = this.lineagedata.fullNodeList;
if (!this.totalSeries.length) {
this.echartNoData = true;
this.nodata = true;
} else {
this.nodata = false;
}
this.totalSeries.forEach((nodeItem) => {
if (this.createType[nodeItem.name]) {
nodeItem.checked = true;
this.fixedSeries.push(nodeItem);
} else {
nodeItem.checked = false;
this.noFixedSeries.push(nodeItem);
}
});
this.noFixedSeries.forEach((item) => {
item.checked = true;
});
this.getCheckedSerList();
if (this.fixedSeries.length) {
this.setObjectValue(this.fixedSeries, true);
}
if (this.noFixedSeries.length) {
this.setObjectValue(this.noFixedSeries, false);
}
const list1 = this.fixedSeries.concat(this.noFixedSeries);
list1.forEach((item, index) => {
this.checkOptions[index] = {};
this.basearr[index] = {};
this.checkOptions[index].label = item.name;
this.checkOptions[index].value = item.id;
if (this.createType[item.name]) {
this.checkOptions[index].disabled = true;
this.basearr[index].disabled = true;
}
this.basearr[index].label = item.name;
this.basearr[index].value = item.id;
});
this.checkOptions.forEach((item) => {
this.selectArrayValue.push(item.value);
});
this.hidenDirChecked = this.$store.state.hidenDirChecked || [];
this.echart.brushData = this.lineagedata.serData;
if (this.hidenDirChecked.length) {
const listdada = this.lineagedata.serData.slice();
this.hidenDirChecked.forEach((item) => {
listdada.forEach((i, index) => {
if (i.summary_dir === item) {
listdada.splice(index, 1);
} }
}); list.push(modelData);
}
}); });
if (listdada.length) { this.modelObjectArray = [];
this.showEchartPic = true; for (let i = 0; i < list.length; i++) {
const modelObject = {};
for (let j = 0; j < this.selectedBarList.length; j++) {
const tempObject = list[i];
const key = this.selectedBarList[j];
modelObject[key] = tempObject[key];
}
this.modelObjectArray.push(modelObject);
}
if (this.modelObjectArray.length) {
const list = JSON.parse(JSON.stringify(serData));
for (let i = 0; i < list.length; i++) {
const temp = this.modelObjectArray[i];
list[i] = Object.assign(list[i], temp);
}
this.table.data = list;
} else { } else {
this.showEchartPic = false; this.table.data = JSON.parse(JSON.stringify(serData));
} }
this.echart.showData = listdada;
} else {
this.echart.showData = this.echart.brushData;
this.showEchartPic = true;
}
this.resizeChart();
this.setEchartValue();
this.$nextTick(() => {
this.initChart();
});
// Total number of pages in the table
this.pagination.total = res.data.count;
// Data encapsulation of the table
let data = [];
data = this.setTableData();
this.table.data = data;
this.showTable = true;
if (this.selectedBarList) {
const resultArray = this.hideDataMarkTableData();
this.table.column = this.dirPathList.concat(
resultArray,
this.checkedSeries.map((i) => i.id),
);
} else { } else {
this.table.column = this.dirPathList.concat( this.table.data = JSON.parse(JSON.stringify(serData));
this.checkedSeries.map((i) => i.id),
);
} }
}, },
(error) => { (error) => {
this.loading = false;
this.initOver = true;
this.showEchartPic = false;
this.errorData = true; this.errorData = true;
this.nodata = true; this.nodata = true;
}, },
) )
.catch(() => { .catch(() => {
this.loading = false;
this.initOver = true;
this.showEchartPic = false;
this.errorData = true; this.errorData = true;
this.nodata = true; this.nodata = true;
}); });
}, },
/**
* Gets the selected items and updates the select all state.
*/
getCheckedSerList() {
this.checkedSeries = [];
this.totalSeries.forEach((nodeItem) => {
if (nodeItem.checked) {
this.checkedSeries.push(nodeItem);
}
});
},
/**
* The window size changes. Resizing Chart
*/
resizeChart() {
if (
document.getElementById('data-echart') &&
document.getElementById('data-echart').style.display !== 'none' &&
this.parallelEchart
) {
this.parallelEchart.resize();
}
},
/** /**
* reset echart data.Show all data * reset echart data.Show all data
*/ */
...@@ -1692,20 +1869,6 @@ export default { ...@@ -1692,20 +1869,6 @@ export default {
}, this.delayTime); }, this.delayTime);
}, },
/**
* The table column data is deleted from the data processing result.
* @return {Array}
*/
hideDataMarkTableData() {
const result = [];
this.selectedBarList.forEach((item) => {
if (item !== this.valueType.dataset_mark) {
result.push(item);
}
});
return result;
},
/** /**
* Selected rows of tables * Selected rows of tables
* @param {Object} val * @param {Object} val
...@@ -1726,19 +1889,6 @@ export default { ...@@ -1726,19 +1889,6 @@ export default {
}); });
}, },
setEchartValue() {
if (this.modelObjectArray.length) {
const list = this.echart.showData;
for (let i = 0; i < list.length; i++) {
const temp = this.modelObjectArray[i];
this.echart.showData[i] = Object.assign(
this.echart.showData[i],
temp,
);
}
}
},
/** /**
* Sort by path parameter * Sort by path parameter
* @param {Object} data * @param {Object} data
...@@ -1801,142 +1951,6 @@ export default { ...@@ -1801,142 +1951,6 @@ export default {
this.queryTableLineagesData(params); this.queryTableLineagesData(params);
}, },
/**
* Setting Table Data
* @return {Array}
*/
setTableData() {
let data = [];
// Table data encapsulation
const pathData = JSON.parse(JSON.stringify(this.echart.brushData));
// Obtain table data based on the page number and number of records.
data = pathData.slice(
(this.pagination.currentPage - 1) * this.pagination.pageSize,
this.pagination.currentPage * this.pagination.pageSize,
);
this.recordsNumber = data.length;
if (this.hidenDirChecked.length) {
this.hidenDirChecked.forEach((dir) => {
data.forEach((item, index) => {
if (item.summary_dir === dir) {
data.splice(index, 1);
}
});
});
}
this.showNumber = data.length;
return data;
},
/**
* Chart data encapsulation
* @param {Object} data
* @return {Object}
*/
formateOriginData(data) {
if (!data || !data.object) {
return {};
}
// Preliminarily filter the required data from the original data and form a unified format.
const objectDataArr = [];
data.object.forEach((object) => {
this.tempFormateData = {
nodeList: [],
children: false,
summary_dir: object.summary_dir,
remark: object.added_info.remark ? object.added_info.remark : '',
tag: object.added_info.tag,
};
if (JSON.stringify(object.dataset_graph) !== '{}') {
this.getSingleRunData(object.dataset_graph);
}
objectDataArr.push(JSON.parse(JSON.stringify(this.tempFormateData)));
});
// The data in the unified format is combined by category.
const fullNodeList = [];
const tempDic = {};
objectDataArr.forEach((objectData) => {
if (fullNodeList.length) {
let startIndex = 0;
let tempNodeListMap = fullNodeList.map((nodeObj) => nodeObj.name);
objectData.nodeList.forEach((nodeItem) => {
const tempIndex = tempNodeListMap.indexOf(
nodeItem.name,
startIndex,
);
if (tempIndex === -1) {
if (!tempDic[nodeItem.name]) {
tempDic[nodeItem.name] = 0;
}
tempDic[nodeItem.name]++;
let tempId = '';
const createKey = Object.keys(this.createType);
if (createKey.includes(nodeItem.name)) {
tempId = nodeItem.name;
} else {
tempId = `${nodeItem.name}${tempDic[nodeItem.name]}`;
}
fullNodeList.splice(startIndex, 0, {
name: nodeItem.name,
id: tempId,
});
nodeItem.id = tempId;
startIndex++;
tempNodeListMap = fullNodeList.map((nodeObj) => nodeObj.name);
} else {
nodeItem.id = fullNodeList[tempIndex].id;
startIndex = tempIndex + 1;
}
});
} else {
objectData.nodeList.forEach((nodeItem) => {
if (!tempDic[nodeItem.name]) {
tempDic[nodeItem.name] = 0;
}
tempDic[nodeItem.name]++;
const createKey = Object.keys(this.createType);
if (createKey.includes(nodeItem.name)) {
fullNodeList.push({
name: nodeItem.name,
id: nodeItem.name,
});
nodeItem.id = nodeItem.name;
} else {
fullNodeList.push({
name: nodeItem.name,
id: `${nodeItem.name}${tempDic[nodeItem.name]}`,
});
nodeItem.id = `${nodeItem.name}${tempDic[nodeItem.name]}`;
}
});
}
});
// Obtain the value of run on each coordinate.
const serData = [];
objectDataArr.forEach((objectData) => {
const curDataObj = {};
objectData.nodeList.forEach((nodeItem) => {
curDataObj[nodeItem.id] = nodeItem.value;
});
curDataObj.children = objectData.children;
curDataObj.summary_dir = objectData.summary_dir;
// set remark value
curDataObj.remark = objectData.remark;
// set tag value
curDataObj.tag = objectData.tag;
// set remark icon is show
curDataObj.editShow = true;
curDataObj.isError = false;
serData.push(curDataObj);
});
const formateData = {
fullNodeList: fullNodeList,
serData: serData,
};
return formateData;
},
/** /**
* Get single run data * Get single run data
* @param {Object} nodeObj * @param {Object} nodeObj
...@@ -2067,6 +2081,37 @@ export default { ...@@ -2067,6 +2081,37 @@ export default {
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
.cl-data-traceback {
height: 100%;
background-color: #fff;
}
.traceback-tab {
height: 51px;
line-height: 56px;
padding: 0 24px;
border-bottom: 1px solid rgba($color: #000000, $alpha: 0.1);
}
.traceback-tab-item {
padding: 0 10px;
height: 48px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
line-height: 48px;
display: inline-block;
list-style: none;
font-size: 18px;
color: #303133;
position: relative;
}
.item-active {
color: #00a5a7;
font-weight: bold;
border-bottom: 3px solid rgba($color: #00a5a7, $alpha: 1);
}
.traceback-tab-item:hover {
color: #00a5a7;
cursor: pointer;
}
.label-text { .label-text {
line-height: 20px !important; line-height: 20px !important;
padding-top: 20px; padding-top: 20px;
...@@ -2128,9 +2173,9 @@ export default { ...@@ -2128,9 +2173,9 @@ export default {
.btn-disabled { .btn-disabled {
cursor: not-allowed !important; cursor: not-allowed !important;
} }
#cl-data-traceback { #data-traceback-con {
display: flex; display: flex;
height: 100%; height: calc(100% - 51px);
overflow-y: auto; overflow-y: auto;
position: relative; position: relative;
background: #fff; background: #fff;
...@@ -2266,7 +2311,7 @@ export default { ...@@ -2266,7 +2311,7 @@ export default {
overflow: hidden; overflow: hidden;
.data-checkbox-area { .data-checkbox-area {
margin: 24px 32px 12px; margin: 6px 32px;
height: 46px; height: 46px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
...@@ -2287,12 +2332,12 @@ export default { ...@@ -2287,12 +2332,12 @@ export default {
padding: 0 12px; padding: 0 12px;
} }
.echart-nodata-container { .echart-nodata-container {
height: 32%; height: 35%;
width: 100%; width: 100%;
} }
.table-container { .table-container {
background-color: white; background-color: white;
height: calc(68% - 130px); height: calc(65% - 88px);
padding: 6px 32px; padding: 6px 32px;
position: relative; position: relative;
.disabled-checked { .disabled-checked {
......
...@@ -14,346 +14,490 @@ See the License for the specific language governing permissions and ...@@ -14,346 +14,490 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<template> <template>
<div id="cl-model-traceback"> <div class="cl-model-traceback">
<div v-if="loading" <div class="traceback-tab">
class="no-data-page"> <div class="traceback-tab-item item-active">{{$t("summaryManage.modelTraceback")}}</div>
<div class="no-data-img"> <div class="traceback-tab-item"
<img :src="require('@/assets/images/nodata.png')" @click="jumpToDataTraceback()">{{$t("summaryManage.dataTraceback")}}</div>
alt="" />
<p class="no-data-text">{{$t("public.dataLoading")}}</p>
</div>
</div> </div>
<div class="cl-model-right" <div id="model-traceback-con">
v-if="!loading"> <div v-if="loading"
<div class="top-area" class="no-data-page">
v-show="!errorData"> <div class="no-data-img">
<div class="select-box" <img :src="require('@/assets/images/nodata.png')"
v-if="!noData && alt="" />
(!summaryDirList || (summaryDirList && summaryDirList.length))"> <p class="no-data-text">{{$t("public.dataLoading")}}</p>
<div v-show="showTable && !noData" </div>
class="select-container"> </div>
<!-- multiple collapse-tags -->
<div class="display-column"> {{$t('modelTraceback.displayColumn')}}</div> <div class="cl-model-left"
<div class="inline-block-set"> :class="{collapse:collapse}"
<el-select v-model="selectArrayValue" v-show="!loading && !errorData">
multiple <div class="left-chart-container"
collapse-tags v-show="!collapse && !errorData">
@change="selectValueChange" <div class="left-title">
:placeholder="$t('public.select')" <div class="title-style">{{$t('modelTraceback.optimizationObject')}}
@focus="selectinputFocus"> </div>
<div class="select-input-button"> <div class="pie-select-style">
<div class="select-inner-input"> <el-select v-model="targetValue"
<el-input v-model="keyWord" class="left-select"
@input="myfilter" @change="targetSelectChange()">
:placeholder="$t('public.search')"></el-input> <el-option v-for="item in targetOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</div>
<!-- pie chart -->
<div class="pie-module-container">
<div class="title-container">
<div class="pie-title">{{$t('modelTraceback.targetDistribution')}}</div>
</div>
<div id="pie-chart">
</div>
</div>
<!-- bar -->
<div class="bar-module-container">
<div class="bar-title-container">
<div class="bar-title"> {{$t('modelTraceback.parameterImportance')}}</div>
<div class="inline-block-set bar-select">
<!-- Parameter importance drop-down box -->
<el-select v-model="selectedBarArray"
multiple
collapse-tags
@change="selectedBarNameListChange"
:placeholder="$t('public.select')"
@focus="selectinputFocus('left')">
<div class="select-input-button">
<div class="select-inner-input">
<el-input v-model="barKeyWord"
@input="myfilter('left')"
:placeholder="$t('public.search')"></el-input>
</div>
<button type="text"
@click="barAllSelect"
class="select-all-button"
:class="[selectedAllBar ? 'checked-color' : 'button-text',
baseSelectOptions.length > barNameList.length ? 'btn-disabled' : '']"
:disabled="baseSelectOptions.length > barNameList.length">
{{$t('public.selectAll')}}
</button>
<button type="text"
@click="barDeselectAll"
class="deselect-all-button"
:class="[!selectedAllBar ? 'checked-color' : 'button-text',
baseSelectOptions.length > barNameList.length ? 'btn-disabled' : '']"
:disabled="baseSelectOptions.length > barNameList.length">
{{$t('public.deselectAll')}}
</button>
</div> </div>
<button type="text" <el-option-group v-for="group in barNameList"
@click="allSelect" :key="group.label"
class="select-all-button" :label="group.label">
:class="[selectCheckAll ? 'checked-color' : 'button-text', <el-option v-for="item in group.options"
basearr.length > checkOptions.length ? 'btn-disabled' : '']" :key="item.value"
:disabled="basearr.length > checkOptions.length"> :label="item.label"
{{$t('public.selectAll')}} :value="item.value"
</button> :disabled="item.disabled"
<button type="text" :title="item.disabled ? $t('modelTraceback.mustExist') : ''">
@click="deselectAll" </el-option>
class="deselect-all-button" </el-option-group>
:class="[!selectCheckAll ? 'checked-color' : 'button-text', </el-select>
basearr.length > checkOptions.length ? 'btn-disabled' : '']" </div>
:disabled="basearr.length > checkOptions.length"> </div>
{{$t('public.deselectAll')}} <div id="bar-chart"></div>
</button> </div>
<!-- scatter -->
<div class="scatter-container">
<div class="scatter-title-container">
<div>
{{$t('modelTraceback.optimizationTitle')}}
<el-tooltip class="item"
effect="light"
placement="top-start">
<div slot="content"
class="tooltip-container">
{{$t('modelTraceback.targetTips')}}
</div>
<i class="el-icon-info"></i>
</el-tooltip>
</div>
<div class="right-view">
<div class="view-big"
@click="viewLargeImage"
:title="$t('modelTraceback.viewBigImage')">
</div> </div>
<el-option-group v-for="group in checkOptions" </div>
:key="group.label"
:label="group.label">
<el-option v-for="item in group.options"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
:title="item.disabled ? $t('modelTraceback.mustExist') : ''">
</el-option>
</el-option-group>
</el-select>
</div> </div>
<div class="label-legend" <div class="left-scatters-container">
v-if="haveCustomizedParams"> <Scatter :data="scatterChartData"
<div>[U]: {{$t('modelTraceback.userDefined')}}</div> :yTitle="yTitle"
<div>[M]: {{$t('modelTraceback.metric')}}</div> :xTitle="xTitle"
:tooltipsData="tooltipsData"
:showTooltip="false">
</Scatter>
</div> </div>
</div> </div>
</div> </div>
<div class="btns"> <div class="collapse-btn"
<el-button class="custom-btn" :class="{collapse:collapse}"
@click="resetChart" @click="collapseLeft()">
type="primary" </div>
size="mini" </div>
plain <!-- Model traceability right column -->
v-if="(!noData && basearr.length) || <div class="cl-model-right"
v-if="!loading"
:class="{collapse:collapse}">
<div class="top-area"
v-show="!errorData">
<div class="select-box"
v-if="!noData &&
(!summaryDirList || (summaryDirList && summaryDirList.length))">
<div v-show="showTable && !noData"
class="select-container">
<!-- multiple collapse-tags -->
<div class="display-column"> {{$t('modelTraceback.displayColumn')}}</div>
<div class="inline-block-set">
<el-select v-model="selectArrayValue"
multiple
collapse-tags
@change="selectValueChange"
:placeholder="$t('public.select')"
@focus="selectinputFocus">
<div class="select-input-button">
<div class="select-inner-input">
<el-input v-model="keyWord"
@input="myfilter"
:placeholder="$t('public.search')"></el-input>
</div>
<button type="text"
@click="allSelect"
class="select-all-button"
:class="[selectCheckAll ? 'checked-color' : 'button-text',
basearr.length > checkOptions.length ? 'btn-disabled' : '']"
:disabled="basearr.length > checkOptions.length">
{{$t('public.selectAll')}}
</button>
<button type="text"
@click="deselectAll"
class="deselect-all-button"
:class="[!selectCheckAll ? 'checked-color' : 'button-text',
basearr.length > checkOptions.length ? 'btn-disabled' : '']"
:disabled="basearr.length > checkOptions.length">
{{$t('public.deselectAll')}}
</button>
</div>
<el-option-group v-for="group in checkOptions"
:key="group.label"
:label="group.label">
<el-option v-for="item in group.options"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
:title="item.disabled ? $t('modelTraceback.mustExist') : ''">
</el-option>
</el-option-group>
</el-select>
</div>
<div class="label-legend"
v-if="haveCustomizedParams">
<div>[U]: {{$t('modelTraceback.userDefined')}}</div>
<div>[M]: {{$t('modelTraceback.metric')}}</div>
</div>
</div>
</div>
<div class="btns">
<el-button class="custom-btn"
@click="showAllDatafun"
type="primary"
size="mini"
plain
v-if="(!noData && basearr.length) ||
(noData && summaryDirList && !summaryDirList.length)"> (noData && summaryDirList && !summaryDirList.length)">
{{ $t('modelTraceback.showAllData') }}</el-button> {{ $t('modelTraceback.showAllData') }}</el-button>
</div>
</div>
<div id="echart"
v-show="!noData && showEchartPic && !loading"></div>
<div class="echart-no-data"
v-show="!noData && !showEchartPic && !loading">
</div> </div>
<div class="btns-container"
v-show="showTable && !noData">
<el-button type="primary"
size="mini"
class="custom-btn"
@click="hiddenRecords"
plain>{{$t('modelTraceback.hide')}}</el-button>
<el-button type="primary"
size="mini"
class="custom-btn"
@click="unhideRecords"
plain>{{$t('modelTraceback.unhide')}}</el-button>
</div>
<div class="table-container"
v-show="showTable && !noData">
<div class="disabled-checked"
v-show="!table.data.length"></div>
<el-table ref="table"
:data="table.data"
tooltip-effect="light"
height="calc(100% - 30px)"
@selection-change="selectionChange"
@sort-change="sortChange"
row-key="summary_dir">
<el-table-column type="selection"
width="55"
:reserve-selection="true"
v-show="showTable && !noData">
</el-table-column>
</div> <!--metric table column-->
<div id="echart" <el-table-column :label="$t('modelTraceback.metricLabel')"
v-show="!noData && showEchartPic && !loading"></div> align="center"
<div class="echart-no-data" v-if="metricList.length">
v-show="!noData && !showEchartPic && !loading"> <el-table-column v-for="key in metricList"
</div> :key="key"
<div class="btns-container" :prop="key"
v-show="showTable && !noData"> :label="table.columnOptions[key].label.substring(3)"
<el-button type="primary" show-overflow-tooltip
size="mini" min-width="120"
class="custom-btn" sortable="custom">
@click="hiddenRecords" <template slot="header"
plain>{{$t('modelTraceback.hide')}}</el-button> slot-scope="scope">
<el-button type="primary" <div class="custom-label"
size="mini" :title="scope.column.label">
class="custom-btn" {{scope.column.label}}
@click="unhideRecords" </div>
plain>{{$t('modelTraceback.unhide')}}</el-button> </template>
</div> <template slot-scope="scope">
<div class="table-container" <span>{{formatNumber(key,scope.row[key])}}</span>
v-show="showTable && !noData"> </template>
<div class="disabled-checked" </el-table-column>
v-show="!table.data.length"></div> </el-table-column>
<el-table ref="table"
:data="table.data" <!--user Defined table column-->
tooltip-effect="light" <el-table-column :label="$t('modelTraceback.userDefinedLabel')"
height="calc(100% - 40px)" align="center"
@selection-change="selectionChange" v-if="userDefinedList.length">
@sort-change="sortChange" <el-table-column v-for="key in userDefinedList"
row-key="summary_dir"> :key="key"
<el-table-column type="selection" :prop="key"
width="55" :label="table.columnOptions[key].label.substring(3)"
:reserve-selection="true" show-overflow-tooltip
v-show="showTable && !noData"> min-width="120"
</el-table-column> sortable="custom">
<template slot="header"
slot-scope="scope">
<div class="custom-label"
:title="scope.column.label">
{{scope.column.label}}
</div>
</template>
<template slot-scope="scope">
<span>{{formatNumber(key,scope.row[key])}}</span>
</template>
</el-table-column>
</el-table-column>
<!--metric table column--> <!--hyper List table column-->
<el-table-column :label="$t('modelTraceback.metricLabel')" <el-table-column :label="$t('modelTraceback.hyperLabel')"
align="center" align="center"
v-if="metricList.length"> v-if="hyperList.length">
<el-table-column v-for="key in metricList" <el-table-column v-for="key in hyperList"
:key="key"
:prop="key"
:label="table.columnOptions[key].label"
show-overflow-tooltip
min-width="154"
sortable="custom">
<template slot="header"
slot-scope="scope">
<div class="custom-label"
:title="scope.column.label">
{{scope.column.label}}
</div>
</template>
<template slot-scope="scope">
<span>{{formatNumber(key, scope.row[key])}}</span>
</template>
</el-table-column>
</el-table-column>
<!--other column-->
<el-table-column v-for="key in table.otherColumn"
:key="key" :key="key"
:prop="key" :prop="key"
:label="table.columnOptions[key].label.substring(3)" :label="table.columnOptions[key].label"
:fixed="table.columnOptions[key].label === text ? true : false"
show-overflow-tooltip show-overflow-tooltip
min-width="120" min-width="150"
sortable="custom"> sortable="custom">
<template slot="header" <template slot="header"
slot-scope="scope"> slot-scope="scope">
<div class="custom-label" <div class="custom-label"
:title="scope.column.label"> :title="scope.column.label">
{{scope.column.label}} {{ scope.column.label }}
</div> </div>
</template> </template>
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{formatNumber(key,scope.row[key])}}</span> <a v-if="key === 'summary_dir'"
@click="jumpToTrainDashboard(scope.row[key])">{{ scope.row[key] }}</a>
<span v-else>{{ formatNumber(key, scope.row[key]) }}</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table-column> <!-- remark column -->
<el-table-column fixed="right"
<!--user Defined table column--> width="260">
<el-table-column :label="$t('modelTraceback.userDefinedLabel')" <template slot="header">
align="center" <div>
v-if="userDefinedList.length"> <div class="label-text">{{$t('public.remark')}}</div>
<el-table-column v-for="key in userDefinedList" <div class="remark-tip">{{$t('modelTraceback.remarkTips')}}</div>
:key="key"
:prop="key"
:label="table.columnOptions[key].label.substring(3)"
show-overflow-tooltip
min-width="120"
sortable="custom">
<template slot="header"
slot-scope="scope">
<div class="custom-label"
:title="scope.column.label">
{{scope.column.label}}
</div> </div>
</template> </template>
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{formatNumber(key,scope.row[key])}}</span> <div class="edit-text-container"
v-show="scope.row.editShow">{{scope.row.remark}}</div>
<div class="inline-block-set">
<i class="el-icon-edit"
@click="editRemarks(scope.row)"
v-show="scope.row.editShow"></i>
<el-input type="text"
v-model="scope.row.remark"
v-show="!scope.row.editShow"
:placeholder="$t('public.enter')"
class="remark-input-style"></el-input>
<i class="el-icon-check"
@click="saveRemarksValue(scope.row)"
v-show="!scope.row.editShow"></i>
<i class="el-icon-close"
@click="cancelRemarksValue(scope.row)"
v-show="!scope.row.editShow"></i>
<div class="validation-error"
v-show="scope.row.isError">
{{$t('modelTraceback.remarkValidation')}}
</div>
</div>
</template> </template>
</el-table-column> </el-table-column>
</el-table-column> <!-- tag -->
<el-table-column label="tag"
<!--hyper List table column--> fixed="right"
<el-table-column :label="$t('modelTraceback.hyperLabel')" prop="tag"
align="center"
v-if="hyperList.length">
<el-table-column v-for="key in hyperList"
:key="key"
:prop="key"
:label="table.columnOptions[key].label"
show-overflow-tooltip
min-width="154"
sortable="custom"> sortable="custom">
<template slot="header"
slot-scope="scope">
<div class="custom-label"
:title="scope.column.label">
{{scope.column.label}}
</div>
</template>
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{formatNumber(key, scope.row[key])}}</span> <div @click="showAllIcon(scope.row, scope, $event)"
class="tag-icon-container">
<img v-if="scope.row.tag"
:class="'img' + scope.$index"
:src="require('@/assets/images/icon' + scope.row.tag + '.svg')">
<img v-else
:class="'img' + scope.$index"
:src="require('@/assets/images/icon-down.svg')">
</div>
</template> </template>
</el-table-column> </el-table-column>
</el-table-column> </el-table>
<!--other column--> <div class="pagination-container">
<el-table-column v-for="key in table.otherColumn" <el-pagination @current-change="pagination.pageChange"
:key="key" :current-page="pagination.currentPage"
:prop="key" :page-size="pagination.pageSize"
:label="table.columnOptions[key].label" :layout="pagination.layout"
:fixed="table.columnOptions[key].label === text ? true : false" :total="pagination.total">
show-overflow-tooltip </el-pagination>
min-width="150" <div class="hide-count"
sortable="custom"> v-show="recordsNumber-showNumber">
<template slot="header" {{$t('modelTraceback.totalHide').replace(`{n}`, (recordsNumber-showNumber))}}
slot-scope="scope"> </div>
<div class="custom-label" <div class="clear"></div>
:title="scope.column.label">
{{ scope.column.label }}
</div>
</template>
<template slot-scope="scope">
<a v-if="key === 'summary_dir'"
@click="jumpToTrainDashboard(scope.row[key])">{{ scope.row[key] }}</a>
<span v-else>{{ formatNumber(key, scope.row[key]) }}</span>
</template>
</el-table-column>
<!-- remark column -->
<el-table-column fixed="right"
width="260">
<template slot="header">
<div>
<div class="label-text">{{$t('public.remark')}}</div>
<div class="remark-tip">{{$t('modelTraceback.remarkTips')}}</div>
</div>
</template>
<template slot-scope="scope">
<div class="edit-text-container"
v-show="scope.row.editShow">{{scope.row.remark}}</div>
<div class="inline-block-set">
<i class="el-icon-edit"
@click="editRemarks(scope.row)"
v-show="scope.row.editShow"></i>
<el-input type="text"
v-model="scope.row.remark"
v-show="!scope.row.editShow"
:placeholder="$t('public.enter')"
class="remark-input-style"></el-input>
<i class="el-icon-check"
@click="saveRemarksValue(scope.row)"
v-show="!scope.row.editShow"></i>
<i class="el-icon-close"
@click="cancelRemarksValue(scope.row)"
v-show="!scope.row.editShow"></i>
<div class="validation-error"
v-show="scope.row.isError">
{{$t('modelTraceback.remarkValidation')}}
</div>
</div>
</template>
</el-table-column>
<!-- tag -->
<el-table-column label="tag"
fixed="right"
prop="tag"
sortable="custom">
<template slot-scope="scope">
<div @click="showAllIcon(scope.row, scope, $event)"
class="tag-icon-container">
<img v-if="scope.row.tag"
:class="'img' + scope.$index"
:src="require('@/assets/images/icon' + scope.row.tag + '.svg')">
<img v-else
:class="'img' + scope.$index"
:src="require('@/assets/images/icon-down.svg')">
</div>
</template>
</el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination @current-change="pagination.pageChange"
:current-page="pagination.currentPage"
:page-size="pagination.pageSize"
:layout="pagination.layout"
:total="pagination.total">
</el-pagination>
<div class="hide-count"
v-show="recordsNumber-showNumber">
{{$t('modelTraceback.totalHide').replace(`{n}`, (recordsNumber-showNumber))}}
</div> </div>
<div class="clear"></div>
</div> </div>
</div> <div v-if="noData"
<div v-if="noData" class="no-data-page">
class="no-data-page"> <div class="no-data-img"
<div class="no-data-img" :class="{'set-height-class':(summaryDirList && !summaryDirList.length)}">
:class="{'set-height-class':(summaryDirList && !summaryDirList.length)}"> <img :src="require('@/assets/images/nodata.png')"
<img :src="require('@/assets/images/nodata.png')" alt />
alt /> <p class="no-data-text"
<p class="no-data-text" v-show="!summaryDirList || (summaryDirList && summaryDirList.length)">
v-show="!summaryDirList || (summaryDirList && summaryDirList.length)"> {{ $t('public.noData') }}</p>
{{ $t('public.noData') }}</p> <div v-show="summaryDirList && !summaryDirList.length">
<div v-show="summaryDirList && !summaryDirList.length"> <p class="no-data-text">{{ $t('modelTraceback.noDataFound') }}</p>
<p class="no-data-text">{{ $t('modelTraceback.noDataFound') }}</p> <p class="no-data-text">
<p class="no-data-text"> {{ $t('modelTraceback.click') }}
{{ $t('modelTraceback.click') }} <b> {{ $t('modelTraceback.showAllDataBtn') }}</b>
<b> {{ $t('modelTraceback.showAllDataBtn') }}</b> {{ $t('modelTraceback.viewAllData') }}
{{ $t('modelTraceback.viewAllData') }} </p>
</p> </div>
</div> </div>
</div> </div>
</div> </div>
</div> <!-- tag dialog -->
<!-- tag dialog --> <div v-show="tagDialogShow"
<div v-show="tagDialogShow" id="tag-dialog"
id="tag-dialog" class="icon-dialog">
class="icon-dialog"> <div>
<div> <div class="icon-image-container">
<div class="icon-image-container"> <div class="icon-image"
<div class="icon-image" v-for="item in imageList"
v-for="item in imageList" :key="item.number"
:key="item.number" :class="[tagScope.row && item.number === tagScope.row.tag ? 'icon-border':'']"
:class="[tagScope.row && item.number === tagScope.row.tag ? 'icon-border':'']" @click="iconValueChange(tagScope.row, item.number, $event)">
@click="iconValueChange(tagScope.row, item.number, $event)"> <img :src="item.iconAdd">
<img :src="item.iconAdd"> </div>
</div>
</div>
<div class="btn-container-margin">
<div class="tag-button-container">
<el-button type="primary"
size="mini"
class="custom-btn"
@click="iconChangeSave(tagScope)"
plain>
{{$t('public.sure')}}
</el-button>
</div>
<div class="tag-button-container">
<el-button type="primary"
size="mini"
class="custom-btn"
@click="clearIcon(tagScope, $event)"
plain>
{{$t('public.clear')}}
</el-button>
</div> </div>
<div class="tag-button-container"> <div class="btn-container-margin">
<el-button type="primary" <div class="tag-button-container">
size="mini" <el-button type="primary"
class="custom-btn" size="mini"
@click="cancelChangeIcon(tagScope.row)" class="custom-btn"
plain> @click="iconChangeSave(tagScope)"
{{$t('public.cancel')}} plain>
</el-button> {{$t('public.sure')}}
</el-button>
</div>
<div class="tag-button-container">
<el-button type="primary"
size="mini"
class="custom-btn"
@click="clearIcon(tagScope, $event)"
plain>
{{$t('public.clear')}}
</el-button>
</div>
<div class="tag-button-container">
<el-button type="primary"
size="mini"
class="custom-btn"
@click="cancelChangeIcon(tagScope.row)"
plain>
{{$t('public.cancel')}}
</el-button>
</div>
</div> </div>
</div> </div>
</div> </div>
<!-- echart dialog -->
<div v-show="echartDialogVisible">
<el-dialog :title="$t('modelTraceback.optimizationTitle')"
:visible.sync="echartDialogVisible"
width="50%"
:close-on-click-modal="false"
class="echart-data-list">
<div class="dialog-scatter">
<Scatter ref="dialogScatter"
:data="largeScatterChartData"
:yTitle="yTitle"
:xTitle="xTitle"
:tooltipsData="tooltipsData"
:showTooltip="true">
</Scatter>
</div>
</el-dialog>
</div>
</div> </div>
</div> </div>
</template> </template>
...@@ -361,12 +505,53 @@ limitations under the License. ...@@ -361,12 +505,53 @@ limitations under the License.
import RequestService from '../../services/request-service'; import RequestService from '../../services/request-service';
import CommonProperty from '@/common/common-property.js'; import CommonProperty from '@/common/common-property.js';
import Echarts from 'echarts'; import Echarts from 'echarts';
import Scatter from '@/components/scatter';
export default { export default {
props: {}, props: {},
watch: {}, watch: {},
data() { data() {
return { return {
// left data
// Expand and collapse the left column
collapse: false,
showLeftChart: null,
targetValue: '',
targetOptions: [],
targetLabel: '',
targetData: [],
scatterData: [],
pieLegendData: [],
pieSeriesData: [],
barYAxisData: [],
barSeriesData: [],
scatterChartData: [],
largeScatterChartData: [],
// Scatter chart tips data
tooltipsData: [],
// The content of the bar graph drop-down box
barNameList: [],
// All values of the drop-down box initially saved
baseSelectOptions: [],
// Whether to select all the drop-down boxes of the histogram
selectedAllBar: false,
// Selected select bar name
selectBarNameList: [],
// input key word
barKeyWord: '',
// List of selected bars
selectedBarArray: [],
// List of all bars
allBararr: [],
yTitle: '',
xTitle: '',
// bar datazoom scroll bar settings
barStart: 100,
barEnd: 0,
tooltipsBarData: [],
echartDialogVisible: false,
// right data
sortChangeTimer: null, sortChangeTimer: null,
unhideRecordsTimer: null, unhideRecordsTimer: null,
tagDialogShow: false, tagDialogShow: false,
...@@ -380,6 +565,7 @@ export default { ...@@ -380,6 +565,7 @@ export default {
recordsNumber: 0, recordsNumber: 0,
showNumber: 0, showNumber: 0,
delayTime: 500, delayTime: 500,
otherDelayTime: 300,
showEchartPic: true, showEchartPic: true,
hideRecord: false, hideRecord: false,
hidenDirChecked: [], hidenDirChecked: [],
...@@ -454,13 +640,7 @@ export default { ...@@ -454,13 +640,7 @@ export default {
computed: {}, computed: {},
mounted() { mounted() {
this.setInitListValue(); this.setInitListValue();
this.imageList = []; this.setTableTagImage();
for (let i = 1; i <= 10; i++) {
const obj = {};
obj.number = i;
obj.iconAdd = require('@/assets/images/icon' + obj.number + '.svg');
this.imageList.push(obj);
}
document.title = `${this.$t('summaryManage.modelTraceback')}-MindInsight`; document.title = `${this.$t('summaryManage.modelTraceback')}-MindInsight`;
document.addEventListener('click', this.blurFloat, true); document.addEventListener('click', this.blurFloat, true);
this.$store.commit('setSelectedBarList', []); this.$store.commit('setSelectedBarList', []);
...@@ -474,357 +654,449 @@ export default { ...@@ -474,357 +654,449 @@ export default {
}); });
}, },
methods: { methods: {
blurFloat(event) { // Set the image display of the tag
const domArr = document.querySelectorAll('.icon-dialog'); setTableTagImage() {
const path = event.path || (event.composedPath && event.composedPath()); this.imageList = [];
const isActiveDom = path.some((item) => { for (let i = 1; i <= 10; i++) {
return item.className === 'icon-dialog'; const obj = {};
}); obj.number = i;
if (!isActiveDom) { obj.iconAdd = require('@/assets/images/icon' + obj.number + '.svg');
this.removeIconBorder(); this.imageList.push(obj);
domArr.forEach((item) => {
item.style.display = 'none';
});
this.tagDialogShow = false;
} }
}, },
/** *** left code***/
/** /**
* Display of the icon dialog box * open or close left column
* @param {Object} row
* @param {Object} scope
* @param {Object} event
*/ */
showAllIcon(row, scope, event) { collapseLeft() {
this.iconValue = row.tag >= 0 ? row.tag : 0; this.collapse = !this.collapse;
this.tagScope = scope; if (this.showLeftChart) {
if (this.tagDialogShow) { clearTimeout(this.showLeftChart);
this.tagDialogShow = false; this.showLeftChart = null;
this.removeIconBorder();
return;
} }
this.addIconBorder(row); this.showLeftChart = setTimeout(() => {
this.tagDialogShow = true; this.resizeChart();
const dialogHeight = 130; }, 50);
const ev = window.event || event;
document.getElementById('tag-dialog').style.top =
ev.clientY - dialogHeight + 'px';
}, },
/** /**
* Add icon border style * Call the left side to optimize the target interface to obtain data
* @param {Object} row
*/ */
addIconBorder(row) { initLeftColumnData() {
const iconImage = document.querySelectorAll('.icon-image'); this.getTargetsData();
iconImage.forEach((item, index) => { },
if (index + 1 === row.tag) { getTargetsData() {
item.classList.add('icon-border'); this.targetOptions = [];
RequestService.queryTargetsData().then((resp) => {
if (
resp &&
resp.data &&
resp.data.targets &&
resp.data.targets.length
) {
this.targetData = JSON.parse(JSON.stringify(resp.data.targets));
this.scatterData = JSON.parse(JSON.stringify(resp.data));
let targetName = '';
for (let i = 0; i < this.targetData.length; i++) {
const obj = {};
targetName = this.targetData[i].name;
obj.value = targetName;
obj.label = targetName;
this.targetOptions.push(obj);
}
this.targetValue = this.targetData[0].name;
this.targetLabel = this.targetData[0].name;
this.setTargetsData(0);
this.$nextTick(() => {
setTimeout(() => {
this.setChartOfPie();
this.setChartOfBar();
this.setChartOfScatters();
}, this.otherDelayTime);
});
} }
}); });
}, },
/** /**
* Remove icon border style * Single selection drop-down box on the left
*/ */
removeIconBorder() { targetSelectChange() {
const classArr = document.querySelectorAll('.icon-border'); const length = this.targetOptions.length;
if (classArr.length) { let index = 0;
classArr.forEach((item) => { for (let i = 0; i < length; i++) {
item.classList.remove('icon-border'); if (this.targetValue === this.targetOptions[i].value) {
}); this.targetLabel = this.targetOptions[i].label;
index = i;
}
} }
this.setTargetsData(index);
this.$nextTick(() => {
this.setChartOfPie();
this.setChartOfBar();
this.setChartOfScatters();
});
}, },
/** /**
* icon value change * The method of changing the value of the multi-select drop-down box of the histogram
* @param {Object} row
* @param {Number} num
* @param {Object} event
*/ */
iconValueChange(row, num, event) { selectedBarNameListChange() {
const path = event.path || (event.composedPath && event.composedPath()); // Setting the bar selection
const classWrap = path.find((item) => { const list = [];
return item.className === 'icon-dialog'; this.baseSelectOptions.forEach((item) => {
}); item.options.forEach((option) => {
const classArr = classWrap.querySelectorAll('.icon-border'); list.push(option.label);
classArr.forEach((item) => { });
item.classList.remove('icon-border');
});
const htmDom = path.find((item) => {
return item.nodeName === 'DIV';
}); });
htmDom.classList.add('icon-border'); if (list.length > this.selectedBarArray.length) {
this.iconValue = num; this.selectedAllBar = false;
} else {
this.selectedAllBar = true;
}
this.selectedSetBarData();
}, },
/** // Select all bar options
* Save the modification of the icon. barAllSelect() {
* @param {Object} scope if (this.selectedAllBar) {
*/
iconChangeSave(scope) {
this.tagDialogShow = false;
if (scope.row.tag === this.iconValue || this.iconValue === 0) {
return; return;
} }
this.tagScope.row.tag = this.iconValue; this.selectedBarArray = [];
const imgDom = document.querySelectorAll('.img' + scope.$index); this.barNameList.forEach((item) => {
imgDom.forEach((item) => { item.options.forEach((option) => {
item.src = require('@/assets/images/icon' + this.iconValue + '.svg'); this.selectedBarArray.push(option.label);
});
}); });
this.$forceUpdate(); this.selectedAllBar = !this.selectedAllBar;
const params = { this.selectedSetBarData();
train_id: scope.row.summary_dir,
body: {
tag: this.tagScope.row.tag,
},
};
this.putChangeToLineagesData(params);
}, },
/** // Bar unselect all
* clear icon barDeselectAll() {
* @param {Object} scope this.selectedBarArray = [];
* @param {Object} event this.barNameList.forEach((item) => {
*/ item.options.forEach((option) => {
clearIcon(scope, event) { if (option.disabled) {
const path = event.path || (event.composedPath && event.composedPath()); this.selectedBarArray.push(option.label);
const classWrap = path.find((item) => { }
return item.className === 'icon-dialog'; });
});
const classArr = classWrap.querySelectorAll('.icon-border');
classArr.forEach((item) => {
item.classList.remove('icon-border');
}); });
this.tagDialogShow = false; this.selectedAllBar = false;
this.iconValue = 0; this.selectedSetBarData();
this.tagScope.row.tag = 0; },
const imgDom = document.querySelectorAll('.img' + scope.$index);
imgDom.forEach((item) => { viewLargeImage() {
item.src = require('@/assets/images/icon-down.svg'); this.echartDialogVisible = true;
this.$nextTick(() => {
this.largeScatterChartData = this.scatterChartData;
this.$refs.dialogScatter.resizeCallback();
}); });
const params = { },
train_id: scope.row.summary_dir,
body: { sortBy(field) {
tag: 0, return function(a, b) {
}, return a[field] - b[field];
}; };
this.putChangeToLineagesData(params);
}, },
/** setNumberType(value) {
* cancel save const num = 1000000;
* @param {Object} row if (value < num) {
*/ return Math.round(value * Math.pow(10, 4)) / Math.pow(10, 4);
cancelChangeIcon(row) { } else {
this.removeIconBorder(); return value.toExponential(4);
this.addIconBorder(row); }
this.tagDialogShow = false;
}, },
/** setTargetsData(index) {
* Select all const pieHBuckets = this.targetData[index].buckets;
*/ this.pieLegendData = [];
allSelect() { this.pieSeriesData = [];
if (this.selectCheckAll) { // data of pie
return; for (let i = 0; i < pieHBuckets.length; i++) {
const objData = {};
let preNumber = pieHBuckets[i][0];
preNumber = Math.round(preNumber * Math.pow(10, 4)) / Math.pow(10, 4);
let nextNumber = pieHBuckets[i][1];
nextNumber = Math.round(nextNumber * Math.pow(10, 4)) / Math.pow(10, 4);
let numSum = preNumber + nextNumber;
numSum = Math.round(numSum * Math.pow(10, 4)) / Math.pow(10, 4);
const numSumString = preNumber + '~' + numSum;
this.pieLegendData.push(numSumString);
objData.value = pieHBuckets[i][2];
objData.name = numSumString;
this.pieSeriesData.push(objData);
} }
this.selectArrayValue = []; this.setBarData(index);
this.checkOptions.forEach((item) => { },
item.options.forEach((option) => {
this.selectArrayValue.push(option.label); //
}); setBarData(index) {
}); const barHyper = this.targetData[index].hyper_parameters;
this.selectCheckAll = !this.selectCheckAll; barHyper.sort(this.sortBy('importance'));
let allList = []; this.selectedBarArray = [];
const listA = [this.$t('modelTraceback.summaryPath')]; const mustSelectOptions = [];
allList = this.selectArrayValue.concat(listA); const otherListOptions = [];
// Set selected of the column data in the table to false; const selectBar = [];
Object.keys(this.table.columnOptions).filter((i) => { barHyper.forEach((item) => {
this.table.columnOptions[i].selected = false; if (item.name.startsWith('[U]')) {
}); otherListOptions.push({
allList.forEach((item) => { value: item.name,
Object.keys(this.table.columnOptions).filter((i) => { label: item.name,
const labelValue = this.table.columnOptions[i].label; disabled: false,
if (labelValue === item) { });
this.table.columnOptions[i].selected = true; } else {
} mustSelectOptions.push({
}); value: item.name,
label: item.name,
disabled: true,
});
selectBar.push(item.name);
}
}); });
this.initColumm(); this.selectedBarArray = selectBar;
this.barNameList = [];
this.baseSelectOptions = [];
const nameObjMust = {
label: this.$t('modelTraceback.mustOptions'),
options: mustSelectOptions,
};
const nameObjOther = {
label: this.$t('modelTraceback.customOptions'),
options: otherListOptions,
};
// The displayed bar drop-down box content
this.barNameList.push(nameObjMust, nameObjOther);
// Save all the contents of the drop-down box
this.baseSelectOptions.push(nameObjMust, nameObjOther);
this.barYAxisData = [];
this.barSeriesData = [];
for (let i = 0; i < barHyper.length; i++) {
const name = barHyper[i].name;
let importanceValue = barHyper[i].importance;
const smallNum = 0.0001;
if (importanceValue < smallNum && importanceValue > 0) {
importanceValue = importanceValue.toExponential(4);
} else {
importanceValue =
Math.round(importanceValue * Math.pow(10, 4)) / Math.pow(10, 4);
}
if (!barHyper[i].name.startsWith('[U]')) {
this.barYAxisData.push(name);
this.barSeriesData.push(importanceValue);
}
}
this.selectedAllBar =
barHyper.length > this.barYAxisData.length ? false : true;
},
setChartOfPie() {
const myPieChart = Echarts.init(document.getElementById('pie-chart'));
const pieOption = {
grid: {
y2: 0,
y: 0,
containLabel: true,
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/> {b} : {c} ({d}%)',
},
legend: {
data: this.pieLegendData,
selectedMode: false,
icon: 'circle',
itemWidth: 10,
itemHeight: 10,
itemGap: 10,
},
color: ['#6c91fb', '#7cdc9f', '#fc8b5d', '#f1689b', '#ab74ff'],
series: [
{
name: this.targetLabel,
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
label: {formatter: '{c}({d}%)'},
data: this.pieSeriesData,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
},
},
],
};
this.$nextTick(() => { this.$nextTick(() => {
this.initChart(); myPieChart.setOption(pieOption);
this.$refs.table.doLayout();
}); });
}, },
/** setChartOfBar() {
* deselect all this.xTitle = this.barYAxisData[this.barYAxisData.length - 1];
*/ const myBarChart = Echarts.init(document.getElementById('bar-chart'));
deselectAll() { const barOption = {
this.selectArrayValue = []; tooltip: {
this.checkOptions.forEach((item) => { trigger: 'axis',
item.options.forEach((option) => { axisPointer: {
if (option.disabled) { type: 'shadow',
this.selectArrayValue.push(option.label); },
} formatter: (val) => {
}); this.tooltipsBarData = val;
const res =
'<p>' +
val[0].name +
'</p><p>' +
this.$t('modelTraceback.parameterImportance') +
':' +
'&nbsp;&nbsp;' +
val[0].value +
'</p>';
return res;
},
},
xAxis: [{type: 'value'}],
yAxis: [
{
type: 'category',
axisTick: {show: false},
data: this.barYAxisData,
axisLabel: {
textStyle: {
color: (params) => {
const textColor =
params === this.xTitle ? '#cc5b58' : 'black';
return textColor;
},
},
},
},
],
series: [
{
name: this.$t('modelTraceback.parameterImportance'),
type: 'bar',
barGap: 0,
barWidth: 10,
data: this.barSeriesData,
itemStyle: {
normal: {
color: (params) => {
// Determine the selected name to change the color setting of the column
if (params.name === this.xTitle) {
return '#cc5b58';
} else {
return '#6c92fa';
}
},
},
},
},
],
grid: {
x: 90,
y: 30,
x2: 40,
y2: 30,
},
dataZoom: [
{
show: this.barYAxisData.length > 15 ? true : false,
type: 'slider',
yAxisIndex: 0,
width: '30px',
start: 100, // The starting percentage of the data frame range
end: this.barYAxisData.length > 15 ? 40 : 0, // The end percentage of the data frame range
},
],
};
this.barEnd = this.barYAxisData.length > 15 ? 40 : 0;
this.$nextTick(() => {
myBarChart.setOption(barOption);
}); });
this.selectCheckAll = false; myBarChart.on('datazoom', (params) => {
let allList = []; this.barStart = params.start;
const listA = [this.$t('modelTraceback.summaryPath')]; this.barEnd = params.end;
allList = this.selectArrayValue.concat(listA);
// Set selected to false for these columns in the table.
Object.keys(this.table.columnOptions).filter((i) => {
this.table.columnOptions[i].selected = false;
}); });
allList.forEach((item) => { myBarChart.getZr().on('click', (params) => {
Object.keys(this.table.columnOptions).filter((i) => { this.xTitle = this.tooltipsBarData[0].name;
const labelValue = this.table.columnOptions[i].label; barOption.dataZoom = [
if (labelValue === item) { {
this.table.columnOptions[i].selected = true; show: this.barYAxisData.length > 15 ? true : false,
} type: 'slider',
yAxisIndex: 0,
width: '30px',
start: this.barStart,
end: this.barEnd,
},
];
barOption.yAxis = [
{
type: 'category',
axisTick: {show: false},
data: this.barYAxisData,
},
];
barOption.series = [
{
type: 'bar',
barWidth: 10,
data: this.barSeriesData,
itemStyle: {
normal: {
color: (params) => {
// Determine the selected name to change the color setting of the column
if (params.name === this.xTitle) {
return '#cc5b58';
} else {
return '#6c92fa';
}
},
},
},
},
];
this.$nextTick(() => {
myBarChart.setOption(barOption);
}); });
// Draw a scatter chart after click
this.setChartOfScatters();
}); });
this.initChart();
this.initColumm();
},
/**
* Edit remarks
* @param {Object} row
*/
editRemarks(row) {
row.editShow = false;
row.isError = false;
this.beforeEditValue = row.remark;
}, },
/** /**
* Save remarks * set data of scatters echart
* @param {Object} row
*/ */
saveRemarksValue(row) { setChartOfScatters() {
const tagValidation = new RegExp('^[a-zA-Z0-9\u4e00-\u9fa5_.-]{1,128}$'); this.yTitle = this.targetLabel;
const result = row.remark.length ? tagValidation.test(row.remark) : true; let xvalue = [];
if (result) { let yvalue = [];
row.isError = false; this.tooltipsData = [];
row.editShow = true; const hyper = this.scatterData.metadata.hyper_parameters;
const params = { for (let m = 0; m < hyper.length; m++) {
train_id: row.summary_dir, if (hyper[m].name === this.xTitle) {
body: { xvalue = hyper[m].data;
remark: row.remark, }
},
};
this.putChangeToLineagesData(params);
} else {
row.isError = true;
} }
}, for (let k = 0; k < this.scatterData.targets.length; k++) {
if (this.scatterData.targets[k].name === this.yTitle) {
/** yvalue = this.scatterData.targets[k].data;
* Cancel save editing
* @param {Object} row
*/
cancelRemarksValue(row) {
row.editShow = true;
row.remark = this.beforeEditValue;
row.isError = false;
},
/**
*After the remark or tag is modified, invoke the interface and save the modification.
* @param {Object} params
*/
putChangeToLineagesData(params) {
RequestService.putLineagesData(params)
.then(
(res) => {
if (res) {
this.$message.success(this.$t('modelTraceback.changeSuccess'));
}
},
(error) => {},
)
.catch(() => {});
},
selectinputFocus() {
this.keyWord = '';
this.checkOptions = this.basearr;
},
/**
* Input search filtering in the select module.
*/
myfilter() {
const queryString = this.keyWord;
const restaurants = this.basearr;
const results = queryString
? this.createFilter(queryString, restaurants)
: restaurants;
this.checkOptions = results;
},
/**
*Input search filtering in the select module.
* @param {String} queryString
* @param {Array} restaurants
* @return {Array}
*/
createFilter(queryString, restaurants) {
const list = [];
restaurants.forEach((item) => {
const object = {};
const options = [];
if (item.options) {
item.options.forEach((item) => {
if (
item.label.toLowerCase().indexOf(queryString.toLowerCase()) >= 0
) {
const tempObj = {};
tempObj.label = item.label;
tempObj.value = item.value;
tempObj.disabled = item.disabled;
options.push(tempObj);
}
});
} }
if (options.length > 0) { }
object.label = item.label; const arrayTemp = [];
object.options = options; for (let i = 0; i < xvalue.length; i++) {
list.push(object); if ((xvalue[i] || xvalue[i] === 0) && (yvalue[i] || yvalue[i] === 0)) {
arrayTemp.push([xvalue[i], yvalue[i]]);
const obj = {train_id: this.scatterData.metadata['train_id'][i]};
obj[this.xTitle] = xvalue[i];
obj[this.yTitle] = yvalue[i];
this.tooltipsData.push(obj);
} }
});
return list;
},
getStoreList() {
this.summaryDirList = this.$store.state.summaryDirList;
if (this.summaryDirList) {
this.tableFilter.summary_dir = {
in: this.summaryDirList,
};
} else {
this.tableFilter.summary_dir = undefined;
} }
}, this.scatterChartData = arrayTemp;
setInitListValue() {
this.keysOfStringValue = [
'summary_dir',
'network',
'optimizer',
'loss_function',
'train_dataset_path',
'test_dataset_path',
'dataset_mark',
]; // All keys whose values are character strings
this.keysOfIntValue = [
'train_dataset_count',
'test_dataset_count',
'epoch',
'batch_size',
'device_num',
]; // All keys whose values are int
this.keysOfMixed = [];
}, },
/** ***********right column*********** **/
/** /**
* Initialization * Initialization
*/ */
...@@ -924,67 +1196,10 @@ export default { ...@@ -924,67 +1196,10 @@ export default {
this.hidenDirChecked = this.$store.state.hidenDirChecked || []; this.hidenDirChecked = this.$store.state.hidenDirChecked || [];
this.queryLineagesData(true); this.queryLineagesData(true);
}, },
/** /**
* Column initialization * Querying All Model Version Information
*/ * @param {Boolean} allData Indicates whether to query all data
initColumm() {
this.metricList = [];
this.userDefinedList = [];
// hyper list
this.hyperList = [];
this.summaryList = [];
this.table.mandatoryColumn = Object.keys(this.table.columnOptions).filter(
(i) => {
return this.table.columnOptions[i].required;
},
);
this.table.optionalColumn = Object.keys(this.table.columnOptions).filter(
(i) => {
return !this.table.columnOptions[i].required;
},
);
const columnList = Object.keys(this.table.columnOptions).filter((i) => {
return (
!this.table.optionsNotInTable.includes(i) &&
this.table.columnOptions[i].selected
);
});
const metricArray = [];
const userDefinedArray = [];
const columnArray = [];
const hyperArray = [];
columnList.forEach((item) => {
if (item.indexOf('metric/') === 0) {
metricArray.push(item);
} else if (item.indexOf('user_defined/') === 0) {
userDefinedArray.push(item);
} else if (
item === this.labelValue.epoch ||
item === this.labelValue.batch_size ||
item === this.labelValue.learning_rate
) {
hyperArray.push(item);
} else {
columnArray.push(item);
}
});
this.showTable = true;
this.table.otherColumn = columnArray;
this.metricList = metricArray;
this.userDefinedList = userDefinedArray;
// hyper list
this.hyperList = hyperArray;
this.table.selectedColumn = this.table.optionalColumn;
this.table.selectAll = true;
this.showTable = true;
this.$nextTick(() => {
this.$refs.table.doLayout();
});
},
/**
* Querying All Model Version Information
* @param {Boolean} allData Indicates whether to query all data
*/ */
queryLineagesData(allData) { queryLineagesData(allData) {
const params = { const params = {
...@@ -1011,6 +1226,8 @@ export default { ...@@ -1011,6 +1226,8 @@ export default {
} else { } else {
params.body = Object.assign(params.body, this.tableFilter); params.body = Object.assign(params.body, this.tableFilter);
} }
// 1.调取左边栏数据接口请求
this.initLeftColumnData();
RequestService.queryLineagesData(params) RequestService.queryLineagesData(params)
.then( .then(
(res) => { (res) => {
...@@ -1273,7 +1490,6 @@ export default { ...@@ -1273,7 +1490,6 @@ export default {
this.noData = true; this.noData = true;
}); });
}, },
/** /**
* Selected data in the table * Selected data in the table
* @param {Array} data * @param {Array} data
...@@ -1325,285 +1541,130 @@ export default { ...@@ -1325,285 +1541,130 @@ export default {
}); });
return modelLineageList; return modelLineageList;
}, },
setInitListValue() {
this.keysOfStringValue = [
'summary_dir',
'network',
'optimizer',
'loss_function',
'train_dataset_path',
'test_dataset_path',
'dataset_mark',
]; // All keys whose values are character strings
this.keysOfIntValue = [
'train_dataset_count',
'test_dataset_count',
'epoch',
'batch_size',
'device_num',
]; // All keys whose values are int
this.keysOfMixed = [];
},
/** /**
* Selected data in the table * Column initialization
* @param {Array} list Selected data in the table
*/ */
selectionChange(list = []) { initColumm() {
if (this.hideRecord) { this.metricList = [];
return; this.userDefinedList = [];
} // hyper list
this.echart.showData = list.length ? list : this.echart.brushData; this.hyperList = [];
this.$nextTick(() => { this.summaryList = [];
this.initChart(); this.table.mandatoryColumn = Object.keys(this.table.columnOptions).filter(
(i) => {
return this.table.columnOptions[i].required;
},
);
this.table.optionalColumn = Object.keys(this.table.columnOptions).filter(
(i) => {
return !this.table.columnOptions[i].required;
},
);
const columnList = Object.keys(this.table.columnOptions).filter((i) => {
return (
!this.table.optionsNotInTable.includes(i) &&
this.table.columnOptions[i].selected
);
}); });
this.checkedSummary = list; const metricArray = [];
const summaryDirFilter = []; const userDefinedArray = [];
this.echart.showData.forEach((i) => { const columnArray = [];
summaryDirFilter.push(i.summary_dir); const hyperArray = [];
columnList.forEach((item) => {
if (item.indexOf('metric/') === 0) {
metricArray.push(item);
} else if (item.indexOf('user_defined/') === 0) {
userDefinedArray.push(item);
} else if (
item === this.labelValue.epoch ||
item === this.labelValue.batch_size ||
item === this.labelValue.learning_rate
) {
hyperArray.push(item);
} else {
columnArray.push(item);
}
});
this.showTable = true;
this.table.otherColumn = columnArray;
this.metricList = metricArray;
this.userDefinedList = userDefinedArray;
// hyper list
this.hyperList = hyperArray;
this.table.selectedColumn = this.table.optionalColumn;
this.table.selectAll = true;
this.showTable = true;
this.$nextTick(() => {
this.$refs.table.doLayout();
}); });
this.tableFilter.summary_dir = {
in: summaryDirFilter,
};
}, },
/** /**
* Selected data in the table * Initializing the Eechart
*/ */
selectValueChange() { initChart() {
const list = []; const chartAxis = Object.keys(this.table.columnOptions).filter((i) => {
this.basearr.forEach((item) => { return (
item.options.forEach((option) => { this.table.columnOptions[i].selected &&
list.push(option.label); !this.table.optionsNotInEchart.includes(i)
}); );
});
if (list.length > this.selectArrayValue.length) {
this.selectCheckAll = false;
} else {
this.selectCheckAll = true;
}
let allList = [];
const listA = [this.$t('modelTraceback.summaryPath')];
allList = this.selectArrayValue.concat(listA);
Object.keys(this.table.columnOptions).filter((i) => {
this.table.columnOptions[i].selected = false;
}); });
allList.forEach((item) => { const data = [];
Object.keys(this.table.columnOptions).filter((i) => { this.echart.showData.forEach((i, index) => {
const labelValue = this.table.columnOptions[i].label; let item = {};
if (labelValue === item) { item = {
this.table.columnOptions[i].selected = true; lineStyle: {
normal: {
color: CommonProperty.commonColorArr[index % 10],
},
},
value: [],
};
chartAxis.forEach((key) => {
if (
(i[key] || i[key] === 0) &&
this.keysOfMixed &&
this.keysOfMixed.length &&
this.keysOfMixed.includes(key)
) {
item.value.push(i[key].toString());
} else {
item.value.push(i[key]);
} }
}); });
data.push(item);
}); });
this.$nextTick(() => {
this.initChart();
});
this.initColumm();
},
/** const parallelAxis = [];
* Hidden records chartAxis.forEach((key, index) => {
*/ const obj = {dim: index, scale: true, id: key};
hiddenRecords() { obj.name = this.table.columnOptions[key].label;
this.hideRecord = true; if (this.keysOfStringValue.includes(key)) {
if (this.checkedSummary.length) { const values = {};
this.checkedSummary.forEach((i) => { this.echart.showData.forEach((i) => {
this.hidenDirChecked.push(i.summary_dir); if (i[key] || i[key] === 0) {
}); values[i[key].toString()] = i[key].toString();
}
this.checkedSummary = [];
this.summaryDirList = this.$store.state.summaryDirList;
this.tableFilter.summary_dir = {
in: this.summaryDirList,
};
this.$store.commit('setHidenDirChecked', this.hidenDirChecked);
if (this.hidenDirChecked.length) {
const tempEchartData = this.echart.brushData;
this.hidenDirChecked.forEach((dir) => {
tempEchartData.forEach((item, index) => {
if (item.summary_dir === dir) {
tempEchartData.splice(index, 1);
}
});
});
const tableTemp = this.table.data;
this.hidenDirChecked.forEach((dir) => {
tableTemp.forEach((item, index) => {
if (item.summary_dir === dir) {
tableTemp.splice(index, 1);
}
});
});
this.table.data = tableTemp;
this.showNumber = tableTemp.length;
this.echart.showData = tempEchartData;
// Restore the style of the table selection box.
this.$refs.table.clearSelection();
if (this.echart.showData.length > 0) {
this.$nextTick(() => {
this.initChart();
});
} else {
this.showEchartPic = false;
}
}
this.hideRecord = false;
},
/**
* Unhide
*/
unhideRecords() {
if (this.unhideRecordsTimer) {
clearTimeout(this.unhideRecordsTimer);
this.unhideRecordsTimer = null;
}
this.unhideRecordsTimer = setTimeout(() => {
this.showEchartPic = true;
this.$refs.table.clearSelection();
this.$store.commit('setHidenDirChecked', []);
if (this.hidenDirChecked.length) {
this.checkedSummary = [];
this.hidenDirChecked = [];
}
const params = {
body: {},
};
const tempParam = {
sorted_name: this.sortInfo.sorted_name,
sorted_type: this.sortInfo.sorted_type,
};
this.summaryDirList = this.$store.state.summaryDirList;
this.tableFilter.summary_dir = {
in: this.summaryDirList,
};
params.body = Object.assign(
params.body,
this.chartFilter,
tempParam,
this.tableFilter,
);
RequestService.queryLineagesData(params).then(
(res) => {
if (res && res.data && res.data.object) {
this.errorData = false;
const list = this.setDataOfModel(res.data.object);
this.echart.allData = list;
this.echart.brushData = list;
this.echart.showData = this.echart.brushData;
this.$nextTick(() => {
this.resizeChart();
this.initChart();
});
const showList = list.slice(
(this.pagination.currentPage - 1) * this.pagination.pageSize,
this.pagination.currentPage * this.pagination.pageSize,
);
this.table.data = showList;
this.recordsNumber = this.table.data.length;
this.showNumber = this.table.data.length;
this.pagination.total = res.data.count || 0;
} else {
this.errorData = true;
}
},
(error) => {
this.errorData = true;
},
);
}, this.delayTime);
},
/**
* Sort data in the table
* @param {Object} column current column
*/
sortChange(column) {
if (this.sortChangeTimer) {
clearTimeout(this.sortChangeTimer);
this.sortChangeTimer = null;
}
this.sortChangeTimer = setTimeout(() => {
this.sortInfo.sorted_name = column.prop;
this.sortInfo.sorted_type = column.order;
this.recordsNumber = 0;
this.showNumber = 0;
this.getStoreList();
const tempParam = {
limit: this.pagination.pageSize,
offset: 0,
sorted_name: this.sortInfo.sorted_name,
sorted_type: this.sortInfo.sorted_type,
};
const params = {};
params.body = Object.assign(
{},
tempParam,
this.tableFilter,
this.chartFilter || {},
);
RequestService.queryLineagesData(params)
.then(
(res) => {
if (res && res.data && res.data.object) {
this.errorData = false;
const list = this.setDataOfModel(res.data.object);
const tempList = list.slice(0, this.pagination.pageSize);
this.recordsNumber = tempList.length;
if (this.hidenDirChecked.length) {
this.hidenDirChecked.forEach((dir) => {
tempList.forEach((item, index) => {
if (item.summary_dir === dir) {
tempList.splice(index, 1);
}
});
});
}
this.showNumber = tempList.length;
this.table.data = tempList;
this.pagination.total = res.data.count || 0;
this.pagination.currentPage = 1;
} else {
this.errorData = true;
}
},
(error) => {
this.errorData = true;
},
)
.catch(() => {
this.errorData = true;
});
}, this.delayTime);
},
/**
* Initializing the Eechart
*/
initChart() {
const chartAxis = Object.keys(this.table.columnOptions).filter((i) => {
return (
this.table.columnOptions[i].selected &&
!this.table.optionsNotInEchart.includes(i)
);
});
const data = [];
this.echart.showData.forEach((i, index) => {
let item = {};
item = {
lineStyle: {
normal: {
color: CommonProperty.commonColorArr[index % 10],
},
},
value: [],
};
chartAxis.forEach((key) => {
if (
(i[key] || i[key] === 0) &&
this.keysOfMixed &&
this.keysOfMixed.length &&
this.keysOfMixed.includes(key)
) {
item.value.push(i[key].toString());
} else {
item.value.push(i[key]);
}
});
data.push(item);
});
const parallelAxis = [];
chartAxis.forEach((key, index) => {
const obj = {dim: index, scale: true, id: key};
obj.name = this.table.columnOptions[key].label;
if (this.keysOfStringValue.includes(key)) {
const values = {};
this.echart.showData.forEach((i) => {
if (i[key] || i[key] === 0) {
values[i[key].toString()] = i[key].toString();
} }
}); });
obj.type = this.valueType.category; obj.type = this.valueType.category;
...@@ -1713,6 +1774,10 @@ export default { ...@@ -1713,6 +1774,10 @@ export default {
window.addEventListener('resize', this.resizeChart, false); window.addEventListener('resize', this.resizeChart, false);
this.chartEventsListen(parallelAxis); this.chartEventsListen(parallelAxis);
}, },
/**
* Model traceability parallel coordinate system echart frame selection operation monitoring
* @param {Object} parallelAxis
*/
chartEventsListen(parallelAxis) { chartEventsListen(parallelAxis) {
this.echart.chart.on('axisareaselected', (params) => { this.echart.chart.on('axisareaselected', (params) => {
const key = params.parallelAxisId; const key = params.parallelAxisId;
...@@ -1786,6 +1851,8 @@ export default { ...@@ -1786,6 +1851,8 @@ export default {
this.tableFilter, this.tableFilter,
this.sortInfo, this.sortInfo,
); );
// 调取target接口,传入框选参数
this.initLeftColumnData();
RequestService.queryLineagesData(filterParams) RequestService.queryLineagesData(filterParams)
.then( .then(
(res) => { (res) => {
...@@ -1858,69 +1925,686 @@ export default { ...@@ -1858,69 +1925,686 @@ export default {
this.errorData = true; this.errorData = true;
}); });
} }
}); });
},
/**
* Get table data
* @param {Object} tableParams
*/
getTableList(tableParams) {
RequestService.queryLineagesData(tableParams)
.then(
(res) => {
if (res && res.data && res.data.object) {
this.errorData = false;
if (res.data.object.length) {
const list = this.setDataOfModel(res.data.object);
if (this.hidenDirChecked.length) {
this.hidenDirChecked.forEach((dir) => {
list.forEach((item, index) => {
if (item.summary_dir === dir) {
list.splice(index, 1);
}
});
});
}
const tempList = list.slice(0, this.pagination.pageSize);
this.recordsNumber = tempList.length;
this.showNumber = tempList.length;
this.table.data = tempList;
this.pagination.currentPage = 1;
this.pagination.total = this.echart.brushData.length;
this.$refs.table.clearSelection();
}
} else {
this.errorData = true;
}
},
(error) => {
this.errorData = true;
},
)
.catch(() => {
this.errorData = true;
});
},
/**
* Resetting the Eechart
*/
showAllDatafun() {
this.summaryDirList = undefined;
this.$store.commit('setSummaryDirList', undefined);
this.$store.commit('setSelectedBarList', []);
this.noData = false;
this.showTable = false;
this.selectCheckAll = true;
this.chartFilter = {};
this.tableFilter.summary_dir = undefined;
this.sortInfo = {};
this.pagination.currentPage = 1;
this.echart.allData = [];
if (this.echart.chart) {
this.echart.chart.clear();
}
this.init();
this.$refs.table.clearSelection();
},
// Set tag style
blurFloat(event) {
const domArr = document.querySelectorAll('.icon-dialog');
const path = event.path || (event.composedPath && event.composedPath());
const isActiveDom = path.some((item) => {
return item.className === 'icon-dialog';
});
if (!isActiveDom) {
this.removeIconBorder();
domArr.forEach((item) => {
item.style.display = 'none';
});
this.tagDialogShow = false;
}
},
/**
* Display of the icon dialog box
* @param {Object} row
* @param {Object} scope
* @param {Object} event
*/
showAllIcon(row, scope, event) {
this.iconValue = row.tag >= 0 ? row.tag : 0;
this.tagScope = scope;
if (this.tagDialogShow) {
this.tagDialogShow = false;
this.removeIconBorder();
return;
}
this.addIconBorder(row);
this.tagDialogShow = true;
const dialogHeight = 130;
const ev = window.event || event;
document.getElementById('tag-dialog').style.top =
ev.clientY - dialogHeight + 'px';
},
/**
* Add icon border style
* @param {Object} row
*/
addIconBorder(row) {
const iconImage = document.querySelectorAll('.icon-image');
iconImage.forEach((item, index) => {
if (index + 1 === row.tag) {
item.classList.add('icon-border');
}
});
},
/**
* Remove icon border style
*/
removeIconBorder() {
const classArr = document.querySelectorAll('.icon-border');
if (classArr.length) {
classArr.forEach((item) => {
item.classList.remove('icon-border');
});
}
},
/**
* icon value change
* @param {Object} row
* @param {Number} num
* @param {Object} event
*/
iconValueChange(row, num, event) {
const path = event.path || (event.composedPath && event.composedPath());
const classWrap = path.find((item) => {
return item.className === 'icon-dialog';
});
const classArr = classWrap.querySelectorAll('.icon-border');
classArr.forEach((item) => {
item.classList.remove('icon-border');
});
const htmDom = path.find((item) => {
return item.nodeName === 'DIV';
});
htmDom.classList.add('icon-border');
this.iconValue = num;
},
/**
* Save the modification of the icon.
* @param {Object} scope
*/
iconChangeSave(scope) {
this.tagDialogShow = false;
if (scope.row.tag === this.iconValue || this.iconValue === 0) {
return;
}
this.tagScope.row.tag = this.iconValue;
const imgDom = document.querySelectorAll('.img' + scope.$index);
imgDom.forEach((item) => {
item.src = require('@/assets/images/icon' + this.iconValue + '.svg');
});
this.$forceUpdate();
const params = {
train_id: scope.row.summary_dir,
body: {
tag: this.tagScope.row.tag,
},
};
this.putChangeToLineagesData(params);
},
/**
* clear icon
* @param {Object} scope
* @param {Object} event
*/
clearIcon(scope, event) {
const path = event.path || (event.composedPath && event.composedPath());
const classWrap = path.find((item) => {
return item.className === 'icon-dialog';
});
const classArr = classWrap.querySelectorAll('.icon-border');
classArr.forEach((item) => {
item.classList.remove('icon-border');
});
this.tagDialogShow = false;
this.iconValue = 0;
this.tagScope.row.tag = 0;
const imgDom = document.querySelectorAll('.img' + scope.$index);
imgDom.forEach((item) => {
item.src = require('@/assets/images/icon-down.svg');
});
const params = {
train_id: scope.row.summary_dir,
body: {
tag: 0,
},
};
this.putChangeToLineagesData(params);
},
/**
* cancel save
* @param {Object} row
*/
cancelChangeIcon(row) {
this.removeIconBorder();
this.addIconBorder(row);
this.tagDialogShow = false;
},
/**
* Select all
*/
allSelect() {
if (this.selectCheckAll) {
return;
}
this.selectArrayValue = [];
this.checkOptions.forEach((item) => {
item.options.forEach((option) => {
this.selectArrayValue.push(option.label);
});
});
this.selectCheckAll = !this.selectCheckAll;
let allList = [];
const listA = [this.$t('modelTraceback.summaryPath')];
allList = this.selectArrayValue.concat(listA);
// Set selected of the column data in the table to false;
Object.keys(this.table.columnOptions).filter((i) => {
this.table.columnOptions[i].selected = false;
});
allList.forEach((item) => {
Object.keys(this.table.columnOptions).filter((i) => {
const labelValue = this.table.columnOptions[i].label;
if (labelValue === item) {
this.table.columnOptions[i].selected = true;
}
});
});
this.initColumm();
this.$nextTick(() => {
this.initChart();
this.$refs.table.doLayout();
});
},
/**
* deselect all
*/
deselectAll() {
this.selectArrayValue = [];
this.checkOptions.forEach((item) => {
item.options.forEach((option) => {
if (option.disabled) {
this.selectArrayValue.push(option.label);
}
});
});
this.selectCheckAll = false;
let allList = [];
const listA = [this.$t('modelTraceback.summaryPath')];
allList = this.selectArrayValue.concat(listA);
// Set selected to false for these columns in the table.
Object.keys(this.table.columnOptions).filter((i) => {
this.table.columnOptions[i].selected = false;
});
allList.forEach((item) => {
Object.keys(this.table.columnOptions).filter((i) => {
const labelValue = this.table.columnOptions[i].label;
if (labelValue === item) {
this.table.columnOptions[i].selected = true;
}
});
});
this.initChart();
this.initColumm();
},
/**
* Edit remarks
* @param {Object} row
*/
editRemarks(row) {
row.editShow = false;
row.isError = false;
this.beforeEditValue = row.remark;
},
/**
* Save remarks
* @param {Object} row
*/
saveRemarksValue(row) {
const tagValidation = new RegExp('^[a-zA-Z0-9\u4e00-\u9fa5_.-]{1,128}$');
const result = row.remark.length ? tagValidation.test(row.remark) : true;
if (result) {
row.isError = false;
row.editShow = true;
const params = {
train_id: row.summary_dir,
body: {
remark: row.remark,
},
};
this.putChangeToLineagesData(params);
} else {
row.isError = true;
}
},
/**
* Cancel save editing
* @param {Object} row
*/
cancelRemarksValue(row) {
row.editShow = true;
row.remark = this.beforeEditValue;
row.isError = false;
},
/**
*After the remark or tag is modified, invoke the interface and save the modification.
* @param {Object} params
*/
putChangeToLineagesData(params) {
RequestService.putLineagesData(params)
.then(
(res) => {
if (res) {
this.$message.success(this.$t('modelTraceback.changeSuccess'));
}
},
(error) => {},
)
.catch(() => {});
},
/**
* The method for the drop-down box to get the focus operation.
* @param {String} val
*/
selectinputFocus(val) {
if (val === 'left') {
// Parameter importance drop-down box
this.barKeyWord = '';
this.barNameList = this.baseSelectOptions;
} else {
// Model traceability drop-down box on the right
this.keyWord = '';
this.checkOptions = this.basearr;
}
},
/**
* Input search filtering in the select module.
* @param {String} val
*/
myfilter(val) {
if (val === 'left') {
// Parameter importance drop-down box
const queryString = this.barKeyWord;
const restaurants = this.baseSelectOptions;
const results = queryString
? this.createFilter(queryString, restaurants)
: restaurants;
this.barNameList = results;
} else {
// Model traceability drop-down box on the right
const queryString = this.keyWord;
const restaurants = this.basearr;
const results = queryString
? this.createFilter(queryString, restaurants)
: restaurants;
this.checkOptions = results;
}
},
/**
*Input search filtering in the select module.
* @param {String} queryString
* @param {Array} restaurants
* @return {Array}
*/
createFilter(queryString, restaurants) {
const list = [];
restaurants.forEach((item) => {
const object = {};
const options = [];
if (item.options) {
item.options.forEach((item) => {
if (
item.label.toLowerCase().indexOf(queryString.toLowerCase()) >= 0
) {
const tempObj = {};
tempObj.label = item.label;
tempObj.value = item.value;
tempObj.disabled = item.disabled;
options.push(tempObj);
}
});
}
if (options.length > 0) {
object.label = item.label;
object.options = options;
list.push(object);
}
});
return list;
},
getStoreList() {
this.summaryDirList = this.$store.state.summaryDirList;
if (this.summaryDirList) {
this.tableFilter.summary_dir = {
in: this.summaryDirList,
};
} else {
this.tableFilter.summary_dir = undefined;
}
},
/**
* Selected data in the table
* @param {Array} list Selected data in the table
*/
selectionChange(list = []) {
if (this.hideRecord) {
return;
}
this.echart.showData = list.length ? list : this.echart.brushData;
this.$nextTick(() => {
this.initChart();
});
this.checkedSummary = list;
const summaryDirFilter = [];
this.echart.showData.forEach((i) => {
summaryDirFilter.push(i.summary_dir);
});
this.tableFilter.summary_dir = {
in: summaryDirFilter,
};
},
/**
* Selected data in the table
*/
selectValueChange() {
const list = [];
this.basearr.forEach((item) => {
item.options.forEach((option) => {
list.push(option.label);
});
});
if (list.length > this.selectArrayValue.length) {
this.selectCheckAll = false;
} else {
this.selectCheckAll = true;
}
let allList = [];
const listA = [this.$t('modelTraceback.summaryPath')];
allList = this.selectArrayValue.concat(listA);
Object.keys(this.table.columnOptions).filter((i) => {
this.table.columnOptions[i].selected = false;
});
allList.forEach((item) => {
Object.keys(this.table.columnOptions).filter((i) => {
const labelValue = this.table.columnOptions[i].label;
if (labelValue === item) {
this.table.columnOptions[i].selected = true;
}
});
});
this.$nextTick(() => {
this.initChart();
});
this.initColumm();
},
selectedSetBarData() {
// Set the y-axis coordinate
let barHyper = [];
for (let i = 0; i < this.targetData.length; i++) {
if (this.targetData[i].name === this.yTitle) {
barHyper = this.targetData[i].hyper_parameters;
}
}
barHyper.sort(this.sortBy('importance'));
this.barYAxisData = [];
this.barSeriesData = [];
for (let j = 0; j < barHyper.length; j++) {
const name = barHyper[j].name;
let importanceValue = barHyper[j].importance;
if (importanceValue < 0.0001 && importanceValue > 0) {
importanceValue = importanceValue.toExponential(4);
} else {
importanceValue =
Math.round(importanceValue * Math.pow(10, 4)) / Math.pow(10, 4);
}
if (this.selectedBarArray.includes(name)) {
this.barYAxisData.push(name);
this.barSeriesData.push(importanceValue);
}
}
this.selectedAllBar =
barHyper.length > this.barYAxisData.length ? false : true;
this.$nextTick(() => {
this.setChartOfBar();
this.setChartOfScatters();
});
},
/**
* Hidden records
*/
hiddenRecords() {
this.hideRecord = true;
if (this.checkedSummary.length) {
this.checkedSummary.forEach((i) => {
this.hidenDirChecked.push(i.summary_dir);
});
}
this.checkedSummary = [];
this.summaryDirList = this.$store.state.summaryDirList;
this.tableFilter.summary_dir = {
in: this.summaryDirList,
};
this.$store.commit('setHidenDirChecked', this.hidenDirChecked);
if (this.hidenDirChecked.length) {
const tempEchartData = this.echart.brushData;
this.hidenDirChecked.forEach((dir) => {
tempEchartData.forEach((item, index) => {
if (item.summary_dir === dir) {
tempEchartData.splice(index, 1);
}
});
});
const tableTemp = this.table.data;
this.hidenDirChecked.forEach((dir) => {
tableTemp.forEach((item, index) => {
if (item.summary_dir === dir) {
tableTemp.splice(index, 1);
}
});
});
this.table.data = tableTemp;
this.showNumber = tableTemp.length;
this.echart.showData = tempEchartData;
// Restore the style of the table selection box.
this.$refs.table.clearSelection();
if (this.echart.showData.length > 0) {
this.$nextTick(() => {
this.initChart();
});
} else {
this.showEchartPic = false;
}
}
this.hideRecord = false;
}, },
/** /**
* Get table data * Unhide
* @param {Object} tableParams
*/ */
getTableList(tableParams) { unhideRecords() {
RequestService.queryLineagesData(tableParams) if (this.unhideRecordsTimer) {
.then( clearTimeout(this.unhideRecordsTimer);
(res) => { this.unhideRecordsTimer = null;
if (res && res.data && res.data.object) { }
this.errorData = false; this.unhideRecordsTimer = setTimeout(() => {
if (res.data.object.length) { this.showEchartPic = true;
this.$refs.table.clearSelection();
this.$store.commit('setHidenDirChecked', []);
if (this.hidenDirChecked.length) {
this.checkedSummary = [];
this.hidenDirChecked = [];
}
const params = {
body: {},
};
const tempParam = {
sorted_name: this.sortInfo.sorted_name,
sorted_type: this.sortInfo.sorted_type,
};
this.summaryDirList = this.$store.state.summaryDirList;
this.tableFilter.summary_dir = {
in: this.summaryDirList,
};
params.body = Object.assign(
params.body,
this.chartFilter,
tempParam,
this.tableFilter,
);
RequestService.queryLineagesData(params).then(
(res) => {
if (res && res.data && res.data.object) {
this.errorData = false;
const list = this.setDataOfModel(res.data.object);
this.echart.allData = list;
this.echart.brushData = list;
this.echart.showData = this.echart.brushData;
this.$nextTick(() => {
this.resizeChart();
this.initChart();
});
const showList = list.slice(
(this.pagination.currentPage - 1) * this.pagination.pageSize,
this.pagination.currentPage * this.pagination.pageSize,
);
this.table.data = showList;
this.recordsNumber = this.table.data.length;
this.showNumber = this.table.data.length;
this.pagination.total = res.data.count || 0;
} else {
this.errorData = true;
}
},
(error) => {
this.errorData = true;
},
);
}, this.delayTime);
},
/**
* Sort data in the table
* @param {Object} column current column
*/
sortChange(column) {
if (this.sortChangeTimer) {
clearTimeout(this.sortChangeTimer);
this.sortChangeTimer = null;
}
this.sortChangeTimer = setTimeout(() => {
this.sortInfo.sorted_name = column.prop;
this.sortInfo.sorted_type = column.order;
this.recordsNumber = 0;
this.showNumber = 0;
this.getStoreList();
const tempParam = {
limit: this.pagination.pageSize,
offset: 0,
sorted_name: this.sortInfo.sorted_name,
sorted_type: this.sortInfo.sorted_type,
};
const params = {};
params.body = Object.assign(
{},
tempParam,
this.tableFilter,
this.chartFilter || {},
);
RequestService.queryLineagesData(params)
.then(
(res) => {
if (res && res.data && res.data.object) {
this.errorData = false;
const list = this.setDataOfModel(res.data.object); const list = this.setDataOfModel(res.data.object);
const tempList = list.slice(0, this.pagination.pageSize);
this.recordsNumber = tempList.length;
if (this.hidenDirChecked.length) { if (this.hidenDirChecked.length) {
this.hidenDirChecked.forEach((dir) => { this.hidenDirChecked.forEach((dir) => {
list.forEach((item, index) => { tempList.forEach((item, index) => {
if (item.summary_dir === dir) { if (item.summary_dir === dir) {
list.splice(index, 1); tempList.splice(index, 1);
} }
}); });
}); });
} }
const tempList = list.slice(0, this.pagination.pageSize);
this.recordsNumber = tempList.length;
this.showNumber = tempList.length; this.showNumber = tempList.length;
this.table.data = tempList; this.table.data = tempList;
this.pagination.total = res.data.count || 0;
this.pagination.currentPage = 1; this.pagination.currentPage = 1;
this.pagination.total = this.echart.brushData.length; } else {
this.$refs.table.clearSelection(); this.errorData = true;
} }
} else { },
(error) => {
this.errorData = true; this.errorData = true;
} },
}, )
(error) => { .catch(() => {
this.errorData = true; this.errorData = true;
}, });
) }, this.delayTime);
.catch(() => {
this.errorData = true;
});
},
/**
* Resetting the Eechart
*/
resetChart() {
this.summaryDirList = undefined;
this.$store.commit('setSummaryDirList', undefined);
this.$store.commit('setSelectedBarList', []);
this.noData = false;
this.showTable = false;
this.selectCheckAll = true;
this.chartFilter = {};
this.tableFilter.summary_dir = undefined;
this.sortInfo = {};
this.pagination.currentPage = 1;
this.echart.allData = [];
if (this.echart.chart) {
this.echart.chart.clear();
}
this.init();
this.$refs.table.clearSelection();
}, },
/** /**
...@@ -1935,6 +2619,14 @@ export default { ...@@ -1935,6 +2619,14 @@ export default {
}); });
window.open(routeUrl.href, '_blank'); window.open(routeUrl.href, '_blank');
}, },
/**
* Jump to DataTraceback
*/
jumpToDataTraceback() {
this.$router.push({
path: '/data-traceback',
});
},
/** /**
* Keep the number with n decimal places. * Keep the number with n decimal places.
* @param {Number} num * @param {Number} num
...@@ -2019,9 +2711,43 @@ export default { ...@@ -2019,9 +2711,43 @@ export default {
} }
document.removeEventListener('resize', this.blurFloat); document.removeEventListener('resize', this.blurFloat);
}, },
components: {
Scatter,
},
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
.cl-model-traceback {
height: 100%;
background-color: #fff;
}
.traceback-tab {
height: 51px;
line-height: 56px;
padding: 0 24px;
border-bottom: 1px solid rgba($color: #000000, $alpha: 0.1);
}
.traceback-tab-item {
padding: 0 10px;
height: 48px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
line-height: 48px;
display: inline-block;
list-style: none;
font-size: 18px;
color: #303133;
position: relative;
}
.item-active {
color: #00a5a7;
font-weight: bold;
border-bottom: 3px solid rgba($color: #00a5a7, $alpha: 1);
}
.traceback-tab-item:hover {
color: #00a5a7;
cursor: pointer;
}
.label-text { .label-text {
line-height: 20px !important; line-height: 20px !important;
padding-top: 20px; padding-top: 20px;
...@@ -2043,7 +2769,7 @@ export default { ...@@ -2043,7 +2769,7 @@ export default {
color: #fff; color: #fff;
} }
.select-inner-input { .select-inner-input {
width: calc(100% - 140px); width: calc(100% - 130px);
margin: 2px 4px; margin: 2px 4px;
display: inline-block; display: inline-block;
} }
...@@ -2087,9 +2813,9 @@ export default { ...@@ -2087,9 +2813,9 @@ export default {
background: none; background: none;
} }
#cl-model-traceback { #model-traceback-con {
display: flex; display: flex;
height: 100%; height: calc(100% - 51px);
overflow-y: auto; overflow-y: auto;
position: relative; position: relative;
background: #fff; background: #fff;
...@@ -2123,6 +2849,24 @@ export default { ...@@ -2123,6 +2849,24 @@ export default {
text-align: center; text-align: center;
} }
} }
.echart-data-list {
.dialog-scatter {
width: 100%;
height: 100%;
}
.el-dialog__title {
font-weight: bold;
}
.el-dialog__body {
height: 500px;
padding-top: 0px;
margin-bottom: 20px;
overflow: auto;
.details-data-title {
margin-bottom: 20px;
}
}
}
.el-table th.gutter { .el-table th.gutter {
display: table-cell !important; display: table-cell !important;
} }
...@@ -2180,7 +2924,7 @@ export default { ...@@ -2180,7 +2924,7 @@ export default {
text-align: center; text-align: center;
} }
.btns-container { .btns-container {
padding: 14px 32px 4px; padding: 6px 32px 4px;
} }
.table-container .el-icon-edit { .table-container .el-icon-edit {
margin-left: 5px; margin-left: 5px;
...@@ -2224,12 +2968,154 @@ export default { ...@@ -2224,12 +2968,154 @@ export default {
.button-text { .button-text {
color: #606266 !important; color: #606266 !important;
} }
// left module
.cl-model-left {
width: 400px;
background: #edf0f5;
overflow-y: auto;
margin: 6px 0px 10px 32px;
padding: 10px 20px;
.left-chart-container {
height: 100%;
min-height: 800px;
}
.left-title {
height: 30px;
display: flex;
.pie-select-style {
flex: 1;
}
.left-select {
width: 200px;
.el-select > .el-input {
width: 200px !important;
}
}
}
.title-style {
font-size: 18px;
flex: 1;
font-weight: bold;
margin-bottom: 4px;
margin-right: 80px;
.el-icon-refresh-right {
font-size: 20px;
vertical-align: middle;
cursor: pointer;
}
}
.pie-title {
margin-right: 110px;
height: 20px;
line-height: 20px;
font-weight: bold;
}
.title-container {
margin-bottom: 10px;
display: flex;
.tooltip-container {
line-height: 20px;
padding: 10px;
}
}
.pie-module-container {
padding: 10px 0 0px;
height: 280px;
#pie-chart {
width: 100%;
height: 240px;
}
}
.bar-module-container {
height: 270px;
border-bottom: 1px solid #b9bcc1;
border-top: 1px solid #b9bcc1;
padding: 10px 0;
.bar-select {
display: flex;
flex: 1.5;
.el-select {
width: 240px;
}
}
.bar-title-container {
display: flex;
}
.bar-title {
font-weight: bold;
flex: 1;
height: 32px;
line-height: 32px;
}
#bar-chart {
width: 100%;
height: 220px;
}
}
.scatter-container {
height: calc(100% - 30px - 270px - 270px);
padding-top: 10px;
.scatter-title-container {
display: flex;
font-weight: bold;
flex-direction: row;
width: 100%;
.right-view {
position: relative;
flex: 1;
}
.el-icon-info {
font-size: 16px;
margin-left: 5px;
color: #6c7280;
}
.view-big {
position: absolute;
right: 10px;
width: 12px;
height: 12px;
cursor: pointer;
background-image: url('../../assets/images/full-screen.png');
}
}
}
.left-scatters-container {
overflow: auto;
width: 100%;
height: calc(100% - 32px);
}
.collapse-btn {
position: absolute;
width: 31px;
height: 100px;
top: 50%;
left: 423px;
margin-top: -50px;
cursor: pointer;
line-height: 86px;
z-index: 1999;
text-align: center;
background-image: url('../../assets/images/collapse-left.svg');
}
.collapse-btn.collapse {
left: -10px;
background-image: url('../../assets/images/collapse-right.svg');
}
}
.cl-model-right.collapse {
width: 100% !important;
}
.cl-model-left.collapse {
width: 0;
padding: 0px;
}
.cl-model-right { .cl-model-right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%; width: 100%;
flex: 1; flex: 1;
width: calc(100% - 400px);
background-color: #fff; background-color: #fff;
-webkit-box-shadow: 0 1px 0 0 rgba(200, 200, 200, 0.5); -webkit-box-shadow: 0 1px 0 0 rgba(200, 200, 200, 0.5);
box-shadow: 0 1px 0 0 rgba(200, 200, 200, 0.5); box-shadow: 0 1px 0 0 rgba(200, 200, 200, 0.5);
...@@ -2240,7 +3126,7 @@ export default { ...@@ -2240,7 +3126,7 @@ export default {
max-width: 500px !important; max-width: 500px !important;
} }
.top-area { .top-area {
margin: 24px 32px 12px; margin: 6px 32px;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
.select-box { .select-box {
...@@ -2265,16 +3151,16 @@ export default { ...@@ -2265,16 +3151,16 @@ export default {
} }
} }
#echart { #echart {
height: 32%; height: 33%;
padding: 0 12px; padding: 0 12px;
} }
.echart-no-data { .echart-no-data {
height: 32%; height: 33%;
width: 100%; width: 100%;
} }
.table-container { .table-container {
background-color: white; background-color: white;
height: calc(68% - 130px); height: calc(67% - 88px);
padding: 6px 32px; padding: 6px 32px;
position: relative; position: relative;
.disabled-checked { .disabled-checked {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册