最近项目,有一个频谱图和瀑布图的需求,做一下记录,也是网上搜的资料,下面是效果图。因为是静态数据,简单记录,项目后续还需要进一步完善(下面的是瀑布图,另一篇随笔里记录)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> #mainCanvas { border: 1px solid red; } </style> </head> <body> <canvas id="mainCanvas" width="1300" height="400"></canvas> <div id="num"></div> <script src="https://cdn.bootcss.com/Mock.js/0.1.11/mock-min.js"></script> <script> function windowTocanvas(canvas, x, y) { var bbox = canvas.getBoundingClientRect(); return { x: x - bbox.left * (canvas.width / bbox.width), y: y - bbox.top * (canvas.height / bbox.height) }; } const numDom = document.getElementById(‘num‘) // const plan = numDom.createSVGMatrix() // console.log(‘y‘, plan) // const plan = numDom.getBoundingClientRect(); // console.log(‘y‘, plan) const main = document.getElementById(‘mainCanvas‘); let ctx = main.getContext(‘2d‘); function draw(data, x, y, color) { ctx.clearRect(0, 0, 2000, 400); // 坐标轴 ctx.beginPath(); ctx.moveTo(30, 30); ctx.lineTo(30, 350); ctx.strokeStyle = ‘#ccc‘ ctx.closePath(); ctx.stroke(); // ctx.restore() ctx.save(); ctx.beginPath() ctx.moveTo(30, 350); ctx.lineTo(1200, 350); ctx.strokeStyle = ‘#ccc‘ ctx.closePath(); ctx.stroke(); ctx.restore() // 单位 ctx.save(); ctx.beginPath() ctx.font = 12; ctx.fillStyle = ‘#ccc‘; ctx.fillText(‘单位‘, 25, 25); ctx.restore() // 刻度 // Y // 计算数据所在y轴 const dataList = data// 计算每个数据处于x轴的坐标,把坐标轴平均到每一度 0/1220 * data + 30 let datax = []; const numx = 320 / y dataList.forEach((item, index) => { datax.push(350 - numx * item) }) let dataxy = [] const ydate = x; const step = 1200 / ydate.length // x轴 for (let i = 30, j = 0; i <= 1200; i += step, j++) { // console.log(i) dataxy.push([i, datax[j]]) // 计算数据所在x轴,push到一个新数组,合并xy轴坐标 ctx.save(); ctx.beginPath() ctx.strokeStyle = "#333" ctx.closePath(); ctx.stroke(); ctx.restore(); } // y轴模拟x轴最大值为3000 // 渲染数据DATA const maxNum = 1220; const stepX = 320 / 5 for (var i = 350, j = 0; i >= 30; i -= stepX, j += 244) { ctx.save(); ctx.beginPath() ctx.moveTo(30, i); ctx.lineTo(35, i); ctx.fillText(j, 5, i + 5); ctx.strokeStyle = "#333" ctx.closePath(); ctx.stroke(); ctx.restore(); } // 渲染数据 for (var i = 0; i < dataxy.length; i++) { if (i === 0) { ctx.save(); ctx.beginPath() ctx.moveTo(dataxy[i][0], dataxy[i][1]); ctx.lineTo(dataxy[i][0], dataxy[i][1]); ctx.strokeStyle = "red" // ctx.closePath(); ctx.stroke(); ctx.restore(); } else { ctx.save(); ctx.beginPath() ctx.moveTo(dataxy[i - 1][0], dataxy[i - 1][1]); ctx.lineTo(dataxy[i][0], dataxy[i][1]); ctx.strokeStyle = color ? color : "#FF6347" ctx.stroke(); ctx.restore(); } } } function floor() { let list = [] let x = [] for (var i = 0; i < 2000; i++) { list.push(Mock.mock({ "number|1-1200": 100 }).number) x.push(Mock.mock(‘@now("H:m:s")‘)) } return { list, x } } let listData = floor() let dataList = listData.list; let yAxis = 1200; let xAxis = listData.x; draw(dataList, xAxis, yAxis); // let colorList = [‘#FF6347‘, ‘#FFFF33‘, ‘#FF6347‘, ‘#FF00FF‘, ‘#DDA0DD‘, ‘#C0FF3E‘, ‘#87CEFF‘, ‘#FF4500‘, ‘#FF82AB‘, ‘#FF1493‘] setInterval(function () { let start = new Date() listData = floor() dataList = listData.list; xAxis = listData.x; // linecolor = colorList[Math.ceil(Math.random()*10)] draw(dataList, xAxis, yAxis) let end = new Date() numDom.innerHTML = ‘时间‘ + (end - start) }, 50) </script> </body> </html>