接口返回如下:
通过接口返回 unitDt作为表格头部,typeDt与右侧选中的进行匹配作为Y轴展示,以下是实现代码:
<template>
<div>
<div class="tableDiv">
<table id="table" class="table">
<thead id="table-thead">
<tr id="table-thead-tr">
<th class="incline-th">
<span class="incline-th-l">材料类型</span>
<span class="incline-th-r">地区</span>
</th>
</tr>
</thead>
<tbody id="table-tbody"></tbody>
</table>
</div>
</div>
</template>
<script>
export default {
data() {
return {
selectMaterCode: ["预警信号", "预警"],
};
},
mounted() {
setTimeout(() => {
this.getData();
}, 500);
},
methods: {
getData() {
// 接口请求
let res = {
unitDt: [
{
UNIT: "乐山市气象局",
NUM: 201,
},
],
typeDt: [
{
NUM: 1826,
TYPE: "预警信号",
},
{
NUM: 282,
TYPE: "预警",
},
],
allDt: [
{
UNIT: "乐山市气象局",
NUM: 168,
TYPE: "预警信号",
},
{
UNIT: "乐山市气象局",
NUM: 33,
TYPE: "预警",
},
],
};
var theadTr = document.getElementById('table-thead-tr');
var tbody = document.getElementById('table-tbody');
let city = []
let result = {}
theadTr.innerHTML = `<th class="incline-th">
<span class="incline-th-l">材料类型</span>
<span class="incline-th-r">地区</span>
</th>`;
res.unitDt.forEach(val => {
city.push({
cityName: val.UNIT
})
})
this.selectMaterCode.forEach((current,i) => {
current = current.substring(0, current.length);
result[current] = [];
if (i == this.selectMaterCode.length - 1) result['总计'] = [];
city.forEach((item,index) => {
let model = {}
let totalModel = {}
result[current][index] = {}
model = res.allDt.find(p => {
if(p.UNIT){
return p.UNIT === item.cityName && current === p['TYPE']
}
});
if(model) {
result[current][index].countValue = model.NUM;
}else{
result[current][index].countValue = 0;
}
totalModel = res.unitDt.find(p => {
if(p.UNIT){
return p.UNIT === item.cityName
}
});
result[current][index].materialName = current;
result[current][index].cityName = item.cityName;
if (i == this.selectMaterCode.length - 1) {
result['总计'][index] = {};
result['总计'][index].materialName = '总计';
result['总计'][index].cityName = item.cityName;
if (totalModel) result['总计'][index].countValue = totalModel.NUM;
else result['总计'][index].countValue = 0;
}
})
})
city.forEach((item) => {
var th = document.createElement('th');
th.innerHTML = item.cityName;
theadTr.appendChild(th);
});
theadTr.innerHTML += `<th>累计</th>`;
var tbodyHtml = '';
var a = []
for (var key in result) {
var arr = []
tbodyHtml += '<tr>';
tbodyHtml += '<td>' + result[key][0].materialName + '</td>';
var total = 0;
result[key].forEach((item,idx) => {
arr.push({
[`NUM${idx}`]: item.countValue,
TYPE: key
})
const flattenedArray = arr.reduce((acc, obj) => {
// 将对象的属性合并到累加器(acc)中
Object.assign(acc, obj);
return acc;
}, {});
if(res.unitDt.length - 1 === idx) {
a.push(flattenedArray)
}
tbodyHtml += `<td>${item.countValue}</td>`;
total += item.countValue;
});
tbodyHtml += `<td>${total}</td>`;
tbodyHtml += '</tr>';
}
tbody.innerHTML = tbodyHtml;
},
},
};
</script>
<style>
.tableDiv {
border: 1px solid #d6d9e9;
overflow: auto;
border-radius: 6px;
height: 90%;
}
.table {
width: 100%;
border-collapse: collapse;
text-align: center;
width: 4000px;
}
.incline-th {
width: 199px;
position: relative;
}
.incline-th:before {
content: "";
position: absolute;
width: 1px;
height: 204px;
top: 0;
left: 0;
background-color: #cee0f2;
display: block;
transform: rotate(-76deg);
transform-origin: top;
}
.incline-th .incline-th-l {
position: absolute;
left: 20px;
bottom: 8px;
line-height: 1;
}
.incline-th .incline-th-r {
position: absolute;
top: 8px;
right: 20px;
line-height: 1;
}
.table thead {
background: #eaf1ff;
height: 49px;
line-height: 49px;
font-weight: bold;
font-size: 16px;
color: #465069;
}
.table thead tr th {
border-right: 1px solid #d6d9e9;
text-align: center;
font-size: 16px;
font-family: Microsoft YaHei;
font-weight: bold;
color: #465069;
}
.table thead tr th:last-child {
border-right: none;
}
.table tbody {
height: 54px;
line-height: 54px;
font-size: 16px;
color: #465069;
}
.table tbody tr:nth-child(odd) {
background: #fff;
}
.table tbody tr:nth-child(even) {
background: #f5f6fc;
}
.table tbody tr td {
border-top: 1px solid #d6d9e9;
border-right: 1px solid #d6d9e9;
}
.table tbody tr td:last-child {
border-right: none;
}
</style>
效果: