一、表格效果
二、核心思想
不做前端的人,会觉得“一”中图展示的就是一张表格;做前端的,看完“四”中注释的业务逻辑(可能看不懂,但无所谓,业务逻辑嘛,重要的是处理思想),会更觉得像Excel,自然也就不能直接将“三”中数据赋给el-table。
处理的核心思想就是先处理出表头(列prop赋值为顺序排列的小写字母)、第一列,再根据每一列的表头和第一行的数据找出填充的值(有点像直接坐标系,表头为X轴,第一列为Y轴)。
三、数据格式
三、组件代码
<template>
<div>
<div v-for="(table, index) in tables" :key="'table'+index" class="tables">
<el-tag size="medium" effect="dark">{{ table.name }}</el-tag>
<el-table :data="table.dataSource" border>
<el-table-column v-for="column in table.columns" :key="'table'+index+column.prop" :prop="column.prop" :label="column.label" :min-width="column.minWidth" :align="column.align" :show-overflow-tooltip="column.tooltip"></el-table-column>
</el-table>
</div>
</div>
</template>
<script>
export default {
props: {
params: {
type: Object,
default () {
return {
tempCheck: [],
temperatureCompensation: [],
linear: [],
linearCheck: []
}
}
}
},
computed: {
tables () {
let tables = [
{
//表格名称
name: '温补结果',
//表格列,数据未处理之前写死在columns中的是固定列,其余列根据需求及数据处理而来
columns: [ //其余列是数据里不重复的pressPoint字段值+单位kPa
{
prop: 'a',
label: '温度℃', //列数据为不重复的temperaturePoint值
minWidth: 100,
align: 'center'
},
{
prop: 'b',
label: '温度AD', //只和温度temperaturePoint有关,列数据为不同temperaturePoint对应的temperatureAD值
minWidth: 100,
align: 'center'
}
],
//表格数据,展示temperaturePoint和pressPoint对应的pressAD,数据来源params.temperatureCompensation
dataSource: []
},
{
name: '线性化结果',
columns: [], //不重复的pressPoint字段值+单位kPa
dataSource: [{}] //只会有一行数据,展示pressPoint对应的pressAD, 数据来源params.linear
},
{
name: '温补校验结果',
columns: [ //其余列是数据里不重复的temperaturePoint+单位℃
{
prop: 'a',
label: '压力', //列数据为不重复的pressPoint
minWidth: 100,
align: 'center'
}
],
dataSource: [] //展示temperaturePoint和pressPoint对应的press,数据来源params.tempCheck
},
{
name: '线性化校验结果',
columns: [], //不重复的pressPoint字段值+单位kPa
dataSource: [{}] //只会有一行数据,展示pressPoint对应的press,数据来源params.linearCheck
}
],
//根据tables注释的业务逻辑开始处理数据
columns = this.getXYNoRepeatData('temperatureCompensation', 'pressPoint').map((li, index) => {
return {
prop: String.fromCharCode(99+index),
label: li+'kPa',
minWidth: 100,
align: 'center'
}
}), dataSource = this.getXYNoRepeatData('temperatureCompensation', 'temperaturePoint').map(li => {
return {
a: li,
b: this.getADColumn('temperatureCompensation', li, 'temperaturePoint', 'temperatureAD')
};
}), errorRateList = [], errorRate = '', errorRateRrop = '';
columns.forEach(column => {
dataSource.forEach(d => {
Object.assign(d, {
[column.prop]: this.getValueByXY('temperatureCompensation', column.label.replace('kPa', ''), d.a, 'pressPoint', 'temperaturePoint', 'pressAD')
});
});
});
tables[0].columns = tables[0].columns.concat(columns);
tables[0].dataSource = dataSource; //完成温补结果columns、dataSource计算
//计算线性化结果columns、dataSource
columns = this.getXYNoRepeatData('linear', 'pressPoint').map((li, index) => {
return {
prop: String.fromCharCode(97+index), //列prop处理为顺序排列的小写英文字母
label: li+'kPa',
minWidth: 100,
align: 'center'
}
});
tables[1].columns = columns;
columns.forEach(column => {
Object.assign(tables[1].dataSource[0], {
[column.prop]: this.getValueByX('linear', column.label.replace('kPa', ''), 'pressPoint', 'pressAD')
});
});
//计算温补校验结果columns、dataSource
columns = this.getXYNoRepeatData('tempCheck', 'temperaturePoint').map((li, index) => {
return {
prop: String.fromCharCode(98+index),
label: li+'℃',
minWidth: 100,
align: 'center'
}
});
dataSource = this.getXYNoRepeatData('tempCheck', 'pressPoint').map(li => {
return {
a: li+'kPa'
};
});
columns.forEach(column => {
dataSource.forEach(d => {
Object.assign(d, {
[column.prop]: this.getValueByXY('tempCheck', column.label.replace('℃', ''), d.a.replace('kPa', ''), 'temperaturePoint', 'pressPoint', 'press')
});
});
});
errorRateRrop = String.fromCharCode(98+columns.length);
columns.push({ //固定最后一列
prop: errorRateRrop,
label: '最大误差%', //列数据为每行temperaturePoint、pressPoint对应的errorRate的最大值
minWidth: 100,
align: 'center'
});
dataSource.forEach(d => {
errorRateList = [];
for(let i=0; i<columns.length-1; i++) {
errorRate = this.getValueByXY('tempCheck', columns[i].label.replace('℃', ''), d.a.replace('kPa', ''), 'temperaturePoint', 'pressPoint', 'errorRate');
errorRate===''?'':errorRateList.push(errorRate);
}
if(errorRateList.length>0) {
errorRateList.sort((a, b) => {
return b-a;
});
Object.assign(d, {
[errorRateRrop]: errorRateList[0]
});
} else {
Object.assign(d, {
[errorRateRrop]: ''
});
}
});
tables[2].columns = tables[2].columns.concat(columns);
tables[2].dataSource = dataSource;
//计算线性化校验结果columns、dataSource
columns = this.getXYNoRepeatData('linearCheck', 'pressPoint').map((li, index) => {
return {
prop: String.fromCharCode(97+index),
label: li+'kPa',
minWidth: 100,
align: 'center'
}
});
columns.forEach(column => {
Object.assign(tables[3].dataSource[0], {
[column.prop]: this.getValueByX('linearCheck', column.label.replace('kPa', ''), 'pressPoint', 'press')
});
});
errorRateRrop = String.fromCharCode(97+columns.length);
columns.push({
prop: errorRateRrop,
label: '最大误差%',
minWidth: 100,
align: 'center'
});
errorRateList = this.params.result.linearCheck.map(li => {
return li.errorRate;
}).sort((a, b) => {
return b-a;
});
Object.assign(tables[3].dataSource[0], {
[errorRateRrop]: errorRateList.length>0?errorRateList[0]:''
});
tables[3].columns = columns;
return tables;
}
},
methods: {
getXYNoRepeatData (vari, variable) {
let arr = this.params[vari].map(li => {
return li[variable];
}).sort((a, b) => {
return a-b;
}), set = new Set(arr);
return Array.from(set.values());
},
getADColumn (vari, val, valueField, labelField) {
let item = this.params[vari].find(li => li[valueField]===val);
return item?item[labelField].toFixed(1):'';
},
getValueByXY (vari, x, y, xField, yField, valueField) {
let item = this.params[vari].find(li => li[xField]==x&&li[yField]==y);
return item?item[valueField].toFixed(valueField.includes('AD')?1:3):'';
},
getValueByX (vari, x, xField, valueField) {
let item = this.params[vari].find(li => li[xField]==x);
return item?item[valueField].toFixed(valueField.includes('AD')?1:3):'';
}
}
}
</script>
<style scoped>
.tables >>>.el-tag {
margin: 20px 0 10px 0;
}
</style>