canvas绘制表格

canvas绘制表格

最近在为公司产品做技术预研,经理让用canvas做一个表格,于是就有了这篇博客。

我们的数据是后端通过MQTT推送过来的

我在代码中也直接使用了

具体MQTT的实现代码,可见博客
在vue使用MQTT

在这里为了方便实用我直接封装成组件了,当MQTT数据来了就出发绘制方法

js 复制代码
<template>  
  <div>  
    <!-- 画布元素,用于绘图 -->  
    <canvas ref="canvasRef" height="180" width="600"></canvas>  
  </div>  
</template>  
  
<script setup>  
import {defineExpose, onMounted, ref} from 'vue';  
import UseMqtt from "../hooks/useMqtt.js"; // 引入MQTT通信的自定义hook  
  
// 画布引用  
const canvasRef = ref(null);  
// 画布上下文  
const ctx = ref(null);  
// 存储接收到的数据  
const data = ref([]);  
// 行高  
const rowHeight = 30;  
// 当前偏移量,用于控制画布滚动  
const currentOffset = ref(30);  
  
// 数据格式示例  
/*[{  
  "hx": 56,  
  "szy": 77,  
  "xl": 74,  
  "ssy": 122,  
  "xybhd": 0.36  
}]*/  
  
/**  
 * 绘制函数,用于在画布上绘制表格  
 */  
const drawTable = () => {  
  const canvas = canvasRef.value;  
  ctx.value = canvas.getContext('2d');  
  ctx.value.clearRect(0, 0, canvas.width, canvas.height); // 清除画布  
  ctx.value.fillStyle = 'black'; // 设置填充颜色  
  ctx.value.font = '16px Arial'; // 设置字体  
  // 绘制列标题  
  const headers = ["hx", "szy", "xl", "ssy", "xybhd"];  
  headers.forEach((header, index) => {  
    ctx.value.fillText(header, index * 120, rowHeight);  
  });  
  
  // 绘制数据行  
  data.value.forEach((item, rowIndex) => {  
    const y = (rowIndex + 1) * rowHeight + currentOffset.value;  
    if (y < canvas.height) {  
      Object.values(item).forEach((value, colIndex) => {  
        ctx.value.fillText(value, colIndex * 120, y);  
      });  
    }  
  });  
};  
  
onMounted(() => {  
  drawTable(); // 组件挂载后绘制表格  
});  
  
const options = {  
  subscription: {topic: "/testtopic/yq", qos: 0} // MQTT订阅配置  
}  
const {  
  createAndDo,  
  destroyConnection  
} = UseMqtt(options, getMessage); // 使用MQTT hook,并传入消息处理函数  
  
/**  
 * 接收消息  
 * @param v 接收到的消息  
 */  
function getMessage(v) {  
  try {  
    data.value.push(JSON.parse(v)) // 解析并存储消息  
    if (data.value.length >= 5) {  
      data.value.shift() // 如果数据超过5条,移除最旧的一条  
    }  
    drawTable(); // 重新绘制表格  
  } catch (e) {  
    console.error(e) // 错误处理  
  }  
}  
  
onMounted(() => {  
  createAndDo() // 组件挂载后建立MQTT连接并开始接收消息  
})  
  
defineExpose({  
  destroyConnection, // 暴露销毁MQTT连接的方法  
  createAndDo // 暴露建立并开始MQTT连接的方法  
})  
</script>

效果图

相关推荐
卸任15 小时前
Vibe coding工具使用心得
前端·ai编程
brien915 小时前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance16 小时前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M16 小时前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写16 小时前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李16 小时前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易16 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
清晨Coding16 小时前
删了 Cookie 还能自动登录?Google系网站登录态自动恢复的原理分析
javascript
风骏时光牛马16 小时前
前沿视界
前端
kyriewen16 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员