效果图:
后端接口返回:
使用el-table时可以实现自定义表头、合计行列、自定义内容,但是表格渐变不符合需求,el-table渐变如下
el-table行不通,那就自己绘制表格(需求中R值(最左侧列), F值(表头)数据都是可维护的,个数不确定,并且合计行与合计列都是前端来计算)
页面及样式:
<div style="margin-bottom: 15px; font-weight: 800; font-size: 17px">
RF分析
</div>
<div style="width: 100%; margin-bottom: 15px">
<div v-if="tableFlag1" class="table1" />
<div v-else style="width: 100%; height: 100px; text-align: center; line-height: 100px; border: 1px solid #ebedf0; font-size: 14px; color: #909399;">暂无数据</div>
</div>
.table1 {
width: 100%;
display: grid;
grid-template-columns: repeat(var(--col), 1fr);
grid-template-rows: repeat(var(--row), 50px);
grid-template-areas: var(--temp);
border-right: 1px solid #ebedf0;
border-bottom: 1px solid #ebedf0;
}
/deep/.col {
text-align: center;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #ebedf0;
border-right: none;
border-bottom: none;
}
js:
getTable1() {
getRFData(this.formData).then(res => {
if (res.result.indexData.length === 0) {
this.tableFlag1 = false
return
}
// 处理后端返回的结果
const dataList = []
const indexDate = []
let arrIndex = 0
for (let i = 0; i < res.result.index.F.length; i++) {
indexDate.push([])
}
for (let i = 0; i < res.result.indexData.length; i++) {
if (arrIndex === res.result.index.F.length) {
arrIndex = 0
}
indexDate[arrIndex].push(
{
data: res.result.indexData[i]
}
)
arrIndex += 1
}
res.result.index.F.forEach((item, index) => {
dataList.push([])
res.result.index.R.forEach((it, ind) => {
dataList[index].push(
{
x: item.indexStage,
y: it.indexStage,
v: indexDate[index][ind].data
}
)
})
})
dataList.unshift([])
res.result.index.R.forEach(item => {
dataList[0].push({
x: '',
y: '',
v: ''
})
})
dataList.forEach(item => {
item.unshift({ x: '', y: '', v: '' }, { x: '', y: '', v: '' })
})
dataList.push([])
dataList.forEach((item, index) => {
item.forEach((it, ind) => {
if (index === 0) {
if (ind < 2) {
dataList[dataList.length - 1].push({ x: '', y: '', v: '' })
} else {
// 添加合计行
dataList[dataList.length - 1].push({
x: '合计',
y: dataList[1][ind].y,
v: {
yhs: 0,
zb: 0
}
})
}
} else {
if (index >= 1 && ind >= 2 && index < dataList.length - 1) {
dataList[dataList.length - 1][ind].v.yhs += dataList[index][ind].v.yhs / 1
dataList[dataList.length - 1][ind].v.zb += dataList[index][ind].v.zb / 1
}
}
})
})
dataList.forEach((item, index) => {
const v = {
yhs: 0,
zb: 0
}
item.forEach((it, ind) => {
v.yhs += (it.v?.yhs || 0)
v.zb += (it.v?.zb / 1 || 0)
})
// 添加合计列
item.push({
x: dataList[index][dataList[index].length - 1].x,
y: '合计',
v: v
})
})
const dom = {
table1: document.querySelector('.table1')
}
const newArr = this.transPose(dataList)
// 合计占比保留两位小数
newArr.forEach(item => {
item.forEach(it => {
if (it.x === '合计' || it.y === '合计') {
console.log(it)
it.v.zb = it.v.zb.toFixed(2)
}
})
})
dom.table1.style.cssText = `
--col: ${dataList.length};
--row: ${dataList[0].length};
--temp: ${this.createTableStr(newArr)};`
const table = newArr.map((item, index) => {
const colDom = item.map((itm, idx) => {
let evry = ''
if (index === 0 && idx > 0) { // 表头2
evry += `
<div class="col" style="grid-area: a2">
${index === 0 && idx === 1 ? ('F-购买频率(次)') : ''}
</div>
`
} else if ((index === 0 || index === 1) && idx === 0) { // 表头1
evry += `
<div class="col" style="grid-area: a1">
${index === 0 && idx === 0 ? 'R' + `<br/>` + '购买时间间隔(天)' : ''}
</div>
`
} else if (index === 1 && idx > 0) { //
evry += `
<div class="col">
${newArr[index + 1][idx].x}
</div>
`
} else if (idx === 0 && index > 0) {
evry += `
<div class="col">
${item[1].y}
</div>
`
} else {
evry += `
<div class="col" style="background-color: ${this.backgroundColor(index, idx, res.result.index.R.length, res.result.index.F.length)}">
${itm.v.yhs} <br/> ${itm.v.zb}%
</div>
`
}
return evry
}).join('')
return colDom
})
dom.table1.innerHTML = table.join('')
})
}
transPose(array) {
const result = []
for (let i = 0; i < array[0].length; i++) {
const row = []
for (let j = 0; j < array.length; j++) {
row.push(array[j][i])
}
result.push(row)
}
return result
}
createTableStr(data) {
let str = ''
data.map((item, index) => {
str += `"`
item.map((itm, idx) => {
str += `${idx === 0 ? '' : '\t'}${
((index === 0 || index === 1) && idx === 0) ? 'a1'
: (index === 0 && idx > 0) ? 'a2'
: (index === 1 && idx > 0) ? (('a') + (2 + idx)) : 'a0'
}`
})
str += `"\n`
})
return str
}
backgroundColor(n1, n2, r1, r2) {
let color = '#fff'
const sum = n1 + n2
const r = Math.floor(r1 + r2 / 2)
if (!n1 || !n2) {
return color
}
if (sum <= 3) {
color = '#0062ff95'
} else if (sum > r) {
return color
} else {
color = '#0062ff' + Math.floor((100 - ((n1 - 1) + (n2 - 2)) * (100 / ((r1 + r2) / 2))))
}
return color
}