1. 添加 时间轴
处理数据:
//存放原始table数据
const economicList = ref<any[]>([]);
//存放用来渲染table的数据
const groupedData = ref<any[]>([]);
//接口返回的数据格式:
economicList.value = [
{
"country": "沙特",
"name": "xxx",
"determine": 1,
"event_content": "xxxxxxxxx。",
"event_time": "2024-05-05T16:00:00.000Z",
"id": 1054072,
},
{
"country": "立陶宛",
"name": "xxx",
"determine": 0,
"event_content": "xxxxxxxx。",
"event_time": "2024-05-05T22:00:00.000Z",
"id": 1054672,
},
]
//处理数据
watch(
() => economicList.value,
(res) => {
let bol = res.length > 0 ? true : false;
const groups = {};
// 根据 pub_time 分组: 通过dayjs().format("HH:mm")将event_time转化为"HH:mm"再进行分组
res.forEach((item) => {
const date = dayjs(item.event_time).format("HH:mm");
if (!groups[date]) {
groups[date] = [];
}
groups[date].push(item);
});
groupedData.value = Object.entries(groups);
},
{ deep: true }
);
处理table表格:
<table class="table" cellspacing="0" cellpadding="0" border="0">
<tr class="table-title">
<td>日期时间</td>
<td>数据</td>
<td>重要性</td>
<td>前值</td>
<td>预测值</td>
<td>公布值</td>
<td>解读</td>
</tr>
<tbody v-if="groupedData?.length > 0" style="opacity: 0.8">
<template v-for="([date, items], groupIndex) in groupedData">
<!-- 数据行,每个数据行都包含日期 -->
<tr
v-for="(item, index) in items"
:key="'item-' + groupIndex + '-' + index"
class="table-line"
>
<!-- 将日期放在每个数据行的第一列 -->
<td v-if="index === 0" :rowspan="items.length">{{ date }}</td>
<td
v-else-if="index !== 0"
:rowspan="0"
style="display: none"
>
</td>
<td>
{{ item.country + item.name }}
</td>
<td>
...
</td>
<td>
...
</td>
<td>
...
</td>
<td>
...
</td>
<td>
...
</td>
</tr>
</template>
</tbody>
<tbody v-if="economicList?.length === 0 && !loading">
...
</tbody>
</table>
效果如下:
2. 添加 水印
如果你有多张表需要加水印 实现水印的方法要写在最外层或者某个工具库中,具体可根据需求实现。
// 添加水印的方法==> res为绑定dom的id,isShow为是否添加水印
const addWatermark = (res: string, isShow: boolean) => {
// 初始化canvas
const canvas = document.createElement("canvas");
const ctx: any = canvas.getContext("2d");
// 设置canvas大小,应与目标div大小匹配或按需调整
canvas.width = document.getElementById(res)?.clientWidth as number;
canvas.height = document.getElementById(res)?.clientHeight as number; // 示例高度,根据需要调整
// 设置水印文字和样式
const watermarkText = "测试水印";
const font = "18px Microsoft Yahei";
const color = "rgba(150, 150, 150, 0.8)"; // 半透明灰色
const angle = -Math.PI / 30; // 30度倾斜角
// 绘制水印到canvas
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.font = font;
ctx.fillStyle = color;
// ctx.globalAlpha = 0.07;
ctx.translate(50, 50);
ctx.rotate(angle);
for (let x = 0; x < canvas.width; x += 200) {
// 水印横向间隔
for (
let y = 0;
y < canvas.height;
canvas.height < 50 ? (y += canvas.height + 10) : (y += 100)
) {
// 水印纵向间隔
ctx.fillText(watermarkText, x, y);
}
}
// 将canvas内容转为data URL,并设置为div背景
const dataURL = canvas.toDataURL();
if (!isShow) {
document.getElementById(res).style.backgroundImage = ``;
} else {
document.getElementById(res).style.backgroundImage = `url(${dataURL})`;
}
};
我的需求:
1) table添加水印
2) table有数据时添加水印 没有数据时去掉水印
3)表头不能有水印
因此这里我设置了两个参数==> res为绑定dom的id,isShow为是否添加水印
这里我将tbody的style设置为 style="opacity: 0.8"即可实现 表头不能有水印 的需求,同理:如果把样式加到table上即可实现整个table的水印效果,具体效果可以根据需求来
//Vue模板
<arco-spin :loading="loading" tip="数据加载中..." class="w-100" dot>
<div id="watermarkedDiv">
<table class="table" cellspacing="0" cellpadding="0" border="0">
<tr class="table-title">
<td>日期时间</td>
<td>数据</td>
<td>xxx</td>
<td>xxx</td>
<td>xxx</td>
<td>xxx</td>
<td>xxx</td>
</tr>
<tbody v-if="groupedData?.length > 0" style="opacity: 0.8">
...
</tbody>
<tbody v-if="economicList?.length === 0 && !loading">
...
</tbody>
</table>
</div>
</arco-spin>
//js代码
watch(
() => economicList.value,
(res) => {
//判断是否有数据
let bol = res.length > 0 ? true : false;
nextTick(() => {
//调用添加水印的方法
addWatermark("watermarkedDiv", bol);
});
},
{ deep: true }
);
注意点:
1. 添加水印方法中一定要有以下代码,不然会导致多个图表水印文字大小不一致的bug
// 设置canvas大小,应与目标div大小匹配或按需调整
canvas.width = document.getElementById(res)?.clientWidth as number;
canvas.height = document.getElementById(res)?.clientHeight as number; // 示例高度,根据需要调整
2. 调用水印方法时要加上nextTick方法,使其在下次dom更新后调用,防止水印不生效
nextTick(() => {
//调用添加水印的方法
addWatermark("watermarkedDiv", bol);
});
效果图: