数据可视化
Canvas, D3, threeJs, antV, Echarts
什么是数据可视化
把数据经过一定的转换之后变成图形显示的操作
数据的分类
- 定性数据
- 文本描述
- 有序变量和无序变量
- 定量数据
- 连续性变量
- 离散变量
数据是如何变成图形
Excel
[{ name:"最低气温", data:[1,-20,2,5,13,8,0] }, { name:'最高气温', data:[10,4,12,15,26,17,10] }]
代码
- 执行映射将数据与不同标度对应
- 选择合适的图形形状将映射体现出来
什么是数据可视化
数据可视化,是关于数据视觉表现形式的科学技术研究
tips: 数据可视化是数据的一种表现形式(前端);数据可视化跟视觉(看起来顺眼)
数据可视化的发展历史
数据可视化起源于20世纪60年代诞生的计算机图形学
现在计算机图形学广泛引用于各个领域,深刻影响和改变着我们的生活
数据可视化的简单例子
使用Excel 实现简单的数据可视化
通过Excel可以简单了解到A,B,C,三个门店1~17号 每天的收入,结合其他工具可以很方便的调整运营策略
使用Xmind
学习完一个知识点后可以使用Xmmind梳理一些知识点关系,方便以后复习使用
这是我之前学习正则表达式时做的思维导图
总结一下
相比于复杂一串数字,人脑更偏向一组表现这串数字的图形或动画,通过做如统计学的一些知识可以将数字变成好看的图片但是我们在分析图片是要注意不要被 图片制作者误导
数据可视化的投入产出比高么
我认为前端的发展会出现两条路:
- 基建:通过工程化的手段搞定低端需求,把一些低级的前端开发用自动化手段生成或降低开发难度然后交给外包处理
- 多样化:前端的呈现越来越丰富,前端的呈现的效果令人称赞
数据可视化技术
Skia
Chrome 和 Android 的底层 2D 绘图引擎,具体可参考百度百科,Skia 采用 C++ 编程,由于它位于浏览器的更底层,所以我们平常接触较少
http://www.kevinbeason.com/smallpt/
OPenGL
OpenGL(Open Graphics Library)是2D、3D图形渲染库,它可以绘制从简单的2D图形到复杂的3D景象。OpenGL 常用于 CAD、VR、数据可视化和游戏等众多领域。
canvas
使用canvas 绘制点、矩形、直线和原形
canvas绘图流程
- 编写canvas标签
- 获取canvas DOM 对象
- 获取Canvas对象
- 设置绘图属性
- 调用绘图API
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>canvas 绘制点,直线, 圆</title> </head> <body> <canvas id="canvas" width="800" height="800"> </canvas> </body> <script> // 获取DOM对象 const canvas = document.getElementById('canvas') // 获取canvas对象 const ctx = canvas.getContext('2d'); // 填充为橙色 ctx.fillStyle = 'orange'; // 绘制矩形 ctx.fillRect(0, 0, 50, 50); // 绘制一个点 // 开始绘制路径 ctx.beginPath(); // 线条宽度 ctx.lineWidth = 1; // 线条填充色 ctx.strokeStyle = 'orange'; // 起点坐标 ctx.moveTo(100, 100); // 中间点坐标 ctx.lineTo(250, 75); // 终点坐标 ctx.lineTo(300, 100); ctx.stroke(); // 绘制实心圆 ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = 'orange'; // 圆形边框色 ctx.fillStyle = 'orange'; // 圆形填充色 ctx.arc(200, 200, 50, 0, 2 * Math.PI); // 绘制圆形 ctx.stroke(); // 绘制圆形的边框 ctx.fill(); // 绘制圆形的填充色 // 绘制一个点 ctx.beginPath(); ctx.lineWidth = 1; ctx.strokeStyle = 'orage'; ctx.moveTo(300, 300); ctx.lineTo(301, 301); ctx.stroke(); </script> </html>
参考文档:https://www.w3school.com.cn/tags/html_ref_canvas.asp
图片压缩
<!DOCTYPE html> <html> <head> </head> <body> <input type="file" id="upload"> <script> const ACCEPT = ['image/jpg', 'image/png', 'image/jpeg']; // 限定图片文件类型 const MAXSIZE = 1024 * 1024 * 3; // 限定图片最大容量 const MAXSIZE_STR = '3MB'; function convertImageToBase64(file, cb) { let reader = new FileReader(); reader.addEventListener('load', function(e) { const base64Image = e.target.result; // 获取文件内容,等同于 reader.result cb(base64Image); reader = null; }); reader.readAsDataURL(file); // 读取 file 对象中的内容 } function compress(base64Image, cb) { let maxW = 1024; let maxH = 1024; const image = new Image(); image.addEventListener('load', function() { let ratio; // 压缩比 let needCompress = false; // 是否需要压缩 if (maxW < image.naturalWidth) { needCompress = true; ratio = image.naturalWidth / maxW; maxH = image.naturalHeight / ratio; } if (maxH < image.naturalHeight) { needCompress = true; ratio = image.naturalHeight / maxH; maxW = image.naturalWidth / ratio; } if (!needCompress) { maxW = image.naturalWidth; maxH = image.naturalHeight; } const canvas = document.createElement('canvas'); canvas.setAttribute('id', '__compress__'); canvas.width = maxW; canvas.height = maxH; canvas.style.visibility = 'hidden'; document.body.append(canvas); const ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, maxW, maxH); ctx.drawImage(image, 0, 0, maxW, maxH); // 渲染图片 const compressImage = canvas.toDataURL('image/jpeg', 0.9); // 压缩图片 cb(compressImage); const _image = new Image(); _image.src = compressImage; document.body.appendChild(_image); canvas.remove(); // 移除 canvas }); image.src = base64Image; // 将图片设置到 image 的 src 属性中 document.body.appendChild(image); } function uploadImage(compressImage) { console.log('upload image to server...', compressImage); } const upload = document.getElementById('upload'); upload.addEventListener('change', function(e) { const file = e.target.files[0]; console.log(file); if (!file) { return; } const { type: fileType, size: fileSize } = file; // 图片类型检查 if (!ACCEPT.includes(fileType)) { alert('不支持上传该格式文件!'); upload.value = ''; return; } // 图片大小检查 if (fileSize > MAXSIZE) { alert('文件超出' + MAXSIZE_STR + '!'); upload.value = ''; return; } // 压缩文件 convertImageToBase64(file, (base64Image) => compress(base64Image, uploadImage)); }); </script> </body> </html>
实战
数据报表和数据大屏
为了看起来像个真实的项目,我把这两个页面整合到 vue-element-admin中
安装并运行vue-element-admin
git clone https://github.com/PanJiaChen/vue-admin-template.git #拉取代码 cd vue-element-admin #切换到具体目录下 npm run dev #启动开发调试模式 查看package.json文件的scripts可知晓启动命令
登录模块
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通