| @@ -284,7 +284,7 @@ export default { | |||
| * @return {String} | |||
| */ | |||
| formateValueColor(row, cell, value, columnDef, dataContext) { | |||
| if (!cell || !value || isNaN(value) || value === Infinity || value === -Infinity) { | |||
| if (!cell || !value || this.judgeDataType(value)) { | |||
| return value; | |||
| } else if (value < 0) { | |||
| return `<span class="table-item-span" style="background:rgba(227, 125, 41, ${ | |||
| @@ -296,6 +296,15 @@ export default { | |||
| })">${value}</span>`; | |||
| } | |||
| }, | |||
| judgeDataType(value) { | |||
| return ( | |||
| isNaN(value) || | |||
| value === 'Infinity' || | |||
| value === '-Infinity' || | |||
| typeof value === 'boolean' || | |||
| value === 'null' | |||
| ); | |||
| }, | |||
| /** | |||
| * Setting the background color of data | |||
| * @param {Number} row | |||
| @@ -308,7 +317,7 @@ export default { | |||
| formateCompareColor(row, cell, value, columnDef, dataContext) { | |||
| if (value instanceof Array && value.length >= 3) { | |||
| const valueNum = value[2]; | |||
| if (!cell || !valueNum || isNaN(valueNum) || valueNum === Infinity || valueNum === -Infinity) { | |||
| if (!cell || !valueNum || this.judgeDataType(valueNum)) { | |||
| return `<span class="table-item-span" title="${value[0]}→${value[1]}">${valueNum}</span>`; | |||
| } else if (valueNum < 0) { | |||
| return `<span class="table-item-span" title="${value[0]}→${ | |||
| @@ -360,7 +369,7 @@ export default { | |||
| const innerOrder = innerIndex + this.tableStartIndex.colStartIndex; | |||
| const tempArr = []; | |||
| innerData.forEach((innerValue) => { | |||
| if (isNaN(innerValue) || innerValue === 'Infinity' || innerValue === '-Infinity') { | |||
| if (this.judgeDataType(innerValue)) { | |||
| tempArr.push(innerValue); | |||
| } else { | |||
| if (this.category === 'science') { | |||
| @@ -381,7 +390,7 @@ export default { | |||
| }; | |||
| outerData.forEach((innerData, innerIndex) => { | |||
| const innerOrder = innerIndex + this.tableStartIndex.colStartIndex; | |||
| if (isNaN(innerData) || innerData === 'Infinity' || innerData === '-Infinity') { | |||
| if (this.judgeDataType(innerData)) { | |||
| tempData[innerOrder] = innerData; | |||
| } else { | |||
| if (this.category === 'science') { | |||
| @@ -50,7 +50,8 @@ limitations under the License. | |||
| v-if="item.tip"> | |||
| <i class="el-icon-warning"></i>{{item.tip}} | |||
| </div> | |||
| <div class="tensor-advice"> | |||
| <div class="tensor-advice" | |||
| v-if="!item.tip"> | |||
| <span>{{ $t('debugger.tuningAdvice') }}</span> | |||
| <div class="advice-list-title"> | |||
| <div class="adviceTitle">{{ item.tuningAdviceTitle }}</div> | |||
| @@ -64,7 +65,7 @@ limitations under the License. | |||
| </div> | |||
| </div> | |||
| <div v-show="!leftDataShow" | |||
| class="leftNoData">{{ $t('public.noData') }}</div> | |||
| class="leftNoData">{{ $t('debugger.noWatchPoint') }}</div> | |||
| </div> | |||
| <div class="collapse-btn" | |||
| :class="{collapse:leftShow}" | |||
| @@ -94,15 +95,24 @@ limitations under the License. | |||
| </label> | |||
| <label v-if="key===1">{{$t('debugger.preStatisticsLabel')}}<span>{{ curRowObj.step-1 }}</span></label> | |||
| <label v-if="key===2">{{$t('debugger.diffStatisticsLabel')}}</label> | |||
| <span>{{ $t('debugger.max') }} {{ statistics.overall_max }}</span> | |||
| <span>{{ $t('debugger.min') }} {{ statistics.overall_min }}</span> | |||
| <span>{{ $t('debugger.mean') }} {{ statistics.overall_avg }}</span> | |||
| <span>{{ $t('debugger.nan') }} {{ statistics.overall_nan_count }}</span> | |||
| <span>{{ $t('debugger.negativeInf') }} {{ statistics.overall_neg_inf_count }}</span> | |||
| <span>{{ $t('debugger.inf') }} {{ statistics.overall_pos_inf_count }}</span> | |||
| <span>{{ $t('debugger.zero') }} {{ statistics.overall_zero_count }}</span> | |||
| <span>{{ $t('debugger.negativeNum') }} {{ statistics.overall_neg_zero_count }}</span> | |||
| <span>{{ $t('debugger.positiveNum') }} {{ statistics.overall_pos_zero_count }}</span> | |||
| <span>{{ $t('debugger.max') }} {{ statistics.overall_max===undefined?'--':statistics.overall_max }}</span> | |||
| <span>{{ $t('debugger.min') }} {{ statistics.overall_min===undefined?'--':statistics.overall_min }}</span> | |||
| <span>{{ $t('debugger.mean') }} {{ statistics.overall_avg===undefined?'--':statistics.overall_avg }}</span> | |||
| <span>{{ $t('debugger.nan') }} | |||
| {{ statistics.overall_nan_count===undefined?'--':statistics.overall_nan_count }} | |||
| </span> | |||
| <span>{{ $t('debugger.negativeInf') }} | |||
| {{ statistics.overall_neg_inf_count===undefined?'--':statistics.overall_neg_inf_count }} | |||
| </span> | |||
| <span>{{ $t('debugger.inf') }} | |||
| {{ statistics.overall_pos_inf_count===undefined?'--': statistics.overall_pos_inf_count}} | |||
| </span> | |||
| <span>{{ $t('debugger.zero') }} | |||
| {{ statistics.overall_zero_count===undefined?'--': statistics.overall_zero_count}}</span> | |||
| <span>{{ $t('debugger.negativeNum') }} | |||
| {{ statistics.overall_neg_zero_count===undefined?'--':statistics.overall_neg_zero_count }}</span> | |||
| <span>{{ $t('debugger.positiveNum') }} | |||
| {{ statistics.overall_pos_zero_count===undefined?'--':statistics.overall_pos_zero_count }}</span> | |||
| </div> | |||
| </div> | |||
| <div class="deb-con-slide"> | |||
| @@ -110,16 +120,17 @@ limitations under the License. | |||
| <el-button size="mini" | |||
| class="custom-btn" | |||
| :class="{green:gridType==='value'}" | |||
| :disabled="state==='running'" | |||
| @click="tabChange('value')">{{ $t('debugger.curStep') }}</el-button> | |||
| <el-button size="mini" | |||
| class="custom-btn" | |||
| :class="{green:gridType==='preStep'}" | |||
| :disabled="!curRowObj.has_prev_step" | |||
| :disabled="!curRowObj.has_prev_step || state==='running'" | |||
| @click="tabChange('preStep')">{{ $t('debugger.preStep') }}</el-button> | |||
| <el-button size="mini" | |||
| class="custom-btn" | |||
| :class="{green:gridType==='compare'}" | |||
| :disabled="!curRowObj.has_prev_step" | |||
| :disabled="!curRowObj.has_prev_step || state==='running'" | |||
| @click="tabChange('compare')">{{ $t('debugger.compareResult') }}</el-button> | |||
| </div> | |||
| <div class="deb-con-slide-left" | |||
| @@ -201,6 +212,7 @@ limitations under the License. | |||
| <div class="tensor"> | |||
| <div class="tensor-title">{{$t('debugger.tensorMsg')}}</div> | |||
| <div class="tensor-detail"> | |||
| <span>{{ $t('graph.name') + $t('symbols.colon') }} {{ statistics.name }}</span> | |||
| <span>{{ $t('debugger.max') }} {{ statistics.overall_max }}</span> | |||
| <span>{{ $t('debugger.min') }} {{ statistics.overall_min }}</span> | |||
| <span>{{ $t('debugger.mean') }} {{ statistics.overall_avg }}</span> | |||
| @@ -217,7 +229,8 @@ limitations under the License. | |||
| </div> | |||
| <div class="watch-point"> | |||
| <div class="watchPoint-title">{{ $t('debugger.watchList') }}</div> | |||
| <div class="point-list"> | |||
| <div class="point-list" | |||
| v-show="rightDataShow"> | |||
| <div v-for="(item,key) in watchPoints" | |||
| :key="key"> | |||
| <div class="watch-judgment"> | |||
| @@ -229,6 +242,8 @@ limitations under the License. | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div v-show="!rightDataShow" | |||
| class="leftNoData">{{ $t('debugger.noWatchPoint') }}</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -276,12 +291,18 @@ export default { | |||
| selectedNode: {}, | |||
| statistics: {}, | |||
| leftDataShow: true, | |||
| rightDataShow: true, | |||
| tuningAdvice: [], | |||
| tuningAdviceTitle: '', | |||
| watchPoints: [], | |||
| callbackFun: null, | |||
| }; | |||
| }, | |||
| computed: { | |||
| state() { | |||
| return this.$parent.metadata.state; | |||
| }, | |||
| }, | |||
| mounted() { | |||
| this.$nextTick(() => { | |||
| this.callbackFun = this.debounce(this.resizeCallback, 200); | |||
| @@ -330,6 +351,10 @@ export default { | |||
| this.selectedNode.name = this.curRowObj.name; | |||
| const dot = this.packageData(); | |||
| this.initGraph(dot); | |||
| } else { | |||
| if (this.selectedNode.name) { | |||
| this.setNodeData(); | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| @@ -578,19 +603,16 @@ export default { | |||
| const selectedNode = nodesList[index]; | |||
| if (selectedNode.id !== this.curRowObj.name) { | |||
| const data = this.tensorGraphData[selectedNode.id]; | |||
| if (data.statistics && JSON.stringify(data.statistics) !== '{}') { | |||
| this.curRowObj.name = data.name; | |||
| this.curRowObj.full_name = data.full_name; | |||
| this.curRowObj.graph_name = data.graph_name; | |||
| this.curRowObj.has_prev_step = data.has_prev_step; | |||
| this.curRowObj.shape = JSON.stringify(data.shape || []); | |||
| nodes.on('click', null); | |||
| nodes.on('dblclick', null); | |||
| this.resetTensor(); | |||
| } else { | |||
| this.$message.error(this.$t('debugger.jumpFailInformation')); | |||
| } | |||
| this.curRowObj.name = data.name; | |||
| this.curRowObj.full_name = data.full_name; | |||
| this.curRowObj.graph_name = data.graph_name; | |||
| this.curRowObj.has_prev_step = data.has_prev_step; | |||
| this.curRowObj.shape = JSON.stringify(data.shape || []); | |||
| nodes.on('click', null); | |||
| nodes.on('dblclick', null); | |||
| this.resetTensor(); | |||
| } | |||
| }); | |||
| @@ -701,13 +723,14 @@ export default { | |||
| }, | |||
| setNodeData() { | |||
| window.getSelection().removeAllRanges(); | |||
| const selectedNode = document.querySelector(`g[id="${this.selectedNode.name}"]`); | |||
| d3.selectAll('.node').classed('selected', false); | |||
| const selectedNode = document.querySelector(`#tensor-graph g[id="${this.selectedNode.name}"]`); | |||
| d3.selectAll('#tensor-graph .node').classed('selected', false); | |||
| selectedNode.classList.add('selected'); | |||
| d3.selectAll('.edge').classed('selected', false); | |||
| d3.selectAll('#tensor-graph .edge').classed('selected', false); | |||
| this.selectedNode = JSON.parse(JSON.stringify(this.tensorGraphData[this.selectedNode.name])); | |||
| const keys = [ | |||
| 'name', | |||
| 'overall_avg', | |||
| 'overall_count', | |||
| 'overall_max', | |||
| @@ -727,6 +750,8 @@ export default { | |||
| } else { | |||
| this.statistics = JSON.parse(JSON.stringify(this.selectedNode.statistics)); | |||
| } | |||
| this.statistics.name = JSON.parse(JSON.stringify(this.selectedNode.name)); | |||
| if (this.selectedNode.watch_points && this.selectedNode.watch_points.length) { | |||
| this.watchPoints = this.selectedNode.watch_points.map((val) => { | |||
| return { | |||
| @@ -736,16 +761,18 @@ export default { | |||
| selected: false, | |||
| }; | |||
| }); | |||
| this.rightDataShow = true; | |||
| } else { | |||
| this.watchPoints = []; | |||
| this.rightDataShow = false; | |||
| } | |||
| } else { | |||
| keys.forEach((key) => { | |||
| this.statistics[key] = '--'; | |||
| }); | |||
| this.watchPoints = []; | |||
| this.rightDataShow = false; | |||
| this.highLightEdges(); | |||
| } | |||
| this.$forceUpdate(); | |||
| }, | |||
| highLightEdges() { | |||
| const edges = []; | |||
| @@ -985,7 +1012,7 @@ export default { | |||
| this.showFilterInput = true; | |||
| } | |||
| if (res.data.tensor_value) { | |||
| const value = res.data.tensor_value.value; | |||
| let value = res.data.tensor_value.value; | |||
| const statistics = res.data.tensor_value.statistics || {}; | |||
| this.statisticsArr = [statistics]; | |||
| if (value === 'Too large to show.') { | |||
| @@ -1000,6 +1027,9 @@ export default { | |||
| }); | |||
| return; | |||
| } | |||
| if (value === null) { | |||
| value = 'null'; | |||
| } | |||
| this.tensorValue = value instanceof Array ? value : [value]; | |||
| this.$nextTick(() => { | |||
| this.$refs.tensorValue.updateGridData(this.tensorValue, JSON.parse(row.shape), statistics, shape); | |||
| @@ -1374,6 +1404,7 @@ export default { | |||
| display: inline-block; | |||
| padding: 5px 0px; | |||
| min-width: 50%; | |||
| word-break: break-all; | |||
| } | |||
| ul { | |||
| li { | |||
| @@ -542,7 +542,6 @@ | |||
| "tensorDiagram": "Tensor Relationship Diagram", | |||
| "selectDetail": "Select a tensor and double-click it to view details.", | |||
| "operator": "Operator", | |||
| "jumpFailInformation": "Redirection fails because the tensor information is empty.", | |||
| "optimizationOrientation": "Optimization Guide", | |||
| "tuningAdvice": "Optimization Suggestions", | |||
| "setValue": "Preset Value", | |||
| @@ -541,11 +541,11 @@ | |||
| "tensorDiagram": "张量关系图", | |||
| "selectDetail": "单击张量选中,双击张量查看详情", | |||
| "operator": "算子", | |||
| "jumpFailInformation": "跳转失败,张量信息为空", | |||
| "optimizationOrientation": "调优向导", | |||
| "tuningAdvice": "调优建议", | |||
| "setValue": "设置值", | |||
| "actualValue": "实际值", | |||
| "noWatchPoint": "没有命中的监测点", | |||
| "tensorTuningRule": { | |||
| "operator_real_data_validation": "真实数据单算子验证", | |||
| "loss_overflow": "检查loss值溢出(NAN,INF)", | |||
| @@ -392,7 +392,10 @@ export default { | |||
| this.isCurrentGraph = false; | |||
| } | |||
| this.metadata.pos = metadata.pos; | |||
| this.enableRecheck = metadata.enable_recheck; | |||
| if (metadata.enable_recheck !== undefined) { | |||
| this.enableRecheck = metadata.enable_recheck; | |||
| } | |||
| if (metadata.state) { | |||
| this.metadata.state = metadata.state; | |||
| } | |||
| @@ -421,13 +424,6 @@ export default { | |||
| if (metadata.step && metadata.step > this.metadata.step) { | |||
| this.metadata.step = metadata.step; | |||
| } | |||
| if (metadata.graph_name && metadata.tensor_name && this.tensorCompareFlag) { | |||
| const debTensor = this.$refs['deb-tensor']; | |||
| if (debTensor) { | |||
| debTensor.updateGraphData(metadata.graph_name, metadata.tensor_name); | |||
| } | |||
| } | |||
| }, | |||
| /** | |||
| * Long polling,update some info | |||
| @@ -472,6 +468,18 @@ export default { | |||
| this.radio1 = 'hit'; | |||
| this.getWatchpointHits(); | |||
| } | |||
| if ( | |||
| res.data.receive_tensor && | |||
| res.data.receive_tensor.graph_name && | |||
| res.data.receive_tensor.tensor_name && | |||
| this.tensorCompareFlag | |||
| ) { | |||
| const debTensor = this.$refs['deb-tensor']; | |||
| if (debTensor) { | |||
| debTensor.updateGraphData(res.data.receive_tensor.graph_name, res.data.receive_tensor.tensor_name); | |||
| } | |||
| } | |||
| this.pollData(); | |||
| } | |||
| }, | |||
| @@ -537,7 +545,7 @@ export default { | |||
| recheckWatchpoint() { | |||
| RequestService.recheckWatchPoints().then( | |||
| (res) => { | |||
| if (res && res.data && res.data.metadata) { | |||
| if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) { | |||
| this.enableRecheck = res.data.metadata.enable_recheck; | |||
| } | |||
| this.$message.success(this.$t('debugger.recheckSuccess')); | |||
| @@ -598,7 +606,7 @@ export default { | |||
| this.loadOriginalTree(); | |||
| this.queryWatchPoints(); | |||
| this.$message.success(this.$t('debugger.successDeleteWP')); | |||
| if (res && res.data && res.data.metadata) { | |||
| if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) { | |||
| this.enableRecheck = res.data.metadata.enable_recheck; | |||
| } | |||
| this.curWatchPointId = null; | |||
| @@ -660,7 +668,7 @@ export default { | |||
| this.createWatchPointArr = []; | |||
| this.createWPDialogVisible = false; | |||
| this.$message.success(this.$t('debugger.successCreateWP')); | |||
| if (res && res.data && res.data.metadata) { | |||
| if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) { | |||
| this.enableRecheck = res.data.metadata.enable_recheck; | |||
| } | |||
| @@ -806,7 +814,9 @@ export default { | |||
| RequestService.updateWatchpoint(params).then( | |||
| (res) => { | |||
| this.defaultCheckedArr = checkedKeys; | |||
| this.enableRecheck = res.data.metadata.enable_recheck; | |||
| if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) { | |||
| this.enableRecheck = res.data.metadata.enable_recheck; | |||
| } | |||
| this.$nextTick(() => { | |||
| if (node.indeterminate) { | |||
| node.checked = true; | |||
| @@ -869,7 +879,9 @@ export default { | |||
| RequestService.updateWatchpoint(params).then( | |||
| (res) => { | |||
| this.searchCheckedArr = checkedKeys; | |||
| this.enableRecheck = res.data.metadata.enable_recheck; | |||
| if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) { | |||
| this.enableRecheck = res.data.metadata.enable_recheck; | |||
| } | |||
| this.$nextTick(() => { | |||
| if (node.indeterminate) { | |||
| node.checked = true; | |||
| @@ -1096,7 +1108,9 @@ export default { | |||
| this.debuggerVersion = res.data.metadata.debugger_version; | |||
| } | |||
| this.metadata = res.data.metadata; | |||
| this.enableRecheck = res.data.metadata.enable_recheck; | |||
| if (res && res.data && res.data.metadata && res.data.metadata.enable_recheck !== undefined) { | |||
| this.enableRecheck = res.data.metadata.enable_recheck; | |||
| } | |||
| if (this.metadata.backend) { | |||
| this.version = this.metadata.backend; | |||
| } | |||
| @@ -1462,24 +1476,21 @@ export default { | |||
| const tensorName = `slot: ${i.slot}, `; | |||
| if (i.watch_points && i.watch_points.length) { | |||
| i.watch_points.forEach((j, key) => { | |||
| let item = `${tensorName} Watch Point Id: ${j.id}, `; | |||
| let item = `${tensorName}${this.$t('debugger.watchPoint')} ${j.id}, `; | |||
| let params = []; | |||
| if (j.watch_condition) { | |||
| item += ` ${this.transCondition(j.watch_condition.id)}`; | |||
| const param = (j.watch_condition.params || []) | |||
| .map((k) => | |||
| k.actual_value === undefined || k.actual_value === null | |||
| ? `${this.transCondition(k.name)}: ${this.$t('debugger.setValue')}:${k.value}` | |||
| : `${this.transCondition(k.name)}: ${this.$t('debugger.setValue')}:${k.value}, ${this.$t( | |||
| 'debugger.actualValue', | |||
| )}:${k.actual_value}`, | |||
| ) | |||
| .join(', '); | |||
| if (param) { | |||
| item += ` (${param})`; | |||
| } | |||
| params = (j.watch_condition.params || []).map((k) => | |||
| k.actual_value === undefined || k.actual_value === null | |||
| ? `${this.transCondition(k.name)}: ${this.$t('debugger.setValue')}:${k.value}` | |||
| : `${this.transCondition(k.name)}: ${this.$t('debugger.setValue')}:${k.value}, ${this.$t( | |||
| 'debugger.actualValue', | |||
| )}:${k.actual_value}`, | |||
| ); | |||
| } | |||
| obj.lists.push({ | |||
| name: item, | |||
| params, | |||
| id: `${key}${hit.node_name}`, | |||
| tip: j.error_code ? this.$t('debugger.checkTips', {msg: tipsMapping[j.error_code]}) : '', | |||
| }); | |||
| @@ -214,6 +214,12 @@ limitations under the License. | |||
| <ul> | |||
| <li v-for="(i, index) in props.row.lists" | |||
| :key="index">{{i.name}} | |||
| <div v-for="(j, ind) in i.params" | |||
| :key="ind" | |||
| class="param"> | |||
| <div class="tensor-icon"></div> | |||
| {{j}} | |||
| </div> | |||
| <div class="hit-tip" | |||
| v-if="i.tip"> | |||
| <i class="el-icon-warning"></i>{{i.tip}} | |||
| @@ -394,19 +400,22 @@ limitations under the License. | |||
| <div class="value-wrap"> | |||
| <el-button size="mini" | |||
| type="text" | |||
| :disabled="metadata.state==='running'" | |||
| v-if="scope.row.value === 'click to view'" | |||
| @click="showTensor(scope.row,'value')"> | |||
| {{ $t('debugger.view') }} | |||
| </el-button> | |||
| <span v-else | |||
| class="value-tip" | |||
| :class="{point:!isNaN(scope.row.value)}" | |||
| :title="isNaN(scope.row.value)?'':scope.row.value" | |||
| @click="isNaN(scope.row.value)?'javascript:;':showTensor(scope.row,'value')"> | |||
| {{ scope.row.value }}</span> | |||
| <el-button v-else | |||
| class="value-tip" | |||
| size="mini" | |||
| type="text" | |||
| :disabled="metadata.state==='running'" | |||
| :title="isNaN(scope.row.value)?'':scope.row.value" | |||
| @click="showTensor(scope.row,'value')"> | |||
| {{ scope.row.value }}</el-button> | |||
| <el-button size="mini" | |||
| type="text" | |||
| :disabled="!scope.row.has_prev_step" | |||
| :disabled="metadata.state==='running' || !scope.row.has_pre_step" | |||
| @click="showTensor(scope.row,'compare')"> | |||
| {{ $t('debugger.compareToPre') }} | |||
| </el-button> | |||
| @@ -471,7 +480,8 @@ limitations under the License. | |||
| <el-option v-for="i in conditionCollections" | |||
| :key="i.id" | |||
| :label="transCondition(i.id)" | |||
| :value="i.id"> | |||
| :value="i.id" | |||
| :class="{'deb-indent': i.id != 'tensor_condition_collection'}"> | |||
| </el-option> | |||
| </el-select> | |||
| <el-select v-model="item.condition.selectedId" | |||
| @@ -1830,6 +1840,16 @@ export default { | |||
| &:hover { | |||
| background-color: #ebeef5; | |||
| } | |||
| .param { | |||
| .tensor-icon { | |||
| display: inline-block; | |||
| width: 6px; | |||
| height: 6px; | |||
| border-radius: 3px; | |||
| background-color: #00a5a7; | |||
| margin-top: 8px; | |||
| } | |||
| } | |||
| .hit-tip { | |||
| margin-top: 10px; | |||
| font-size: 12px; | |||
| @@ -2081,9 +2101,6 @@ export default { | |||
| vertical-align: middle; | |||
| text-align: center; | |||
| } | |||
| .value-tip.point { | |||
| cursor: pointer; | |||
| } | |||
| .el-table--border { | |||
| border-right: none; | |||
| border-left: none; | |||