vue+canvas实现数据实时从上到下刷新瀑布图效果(类似QT的)
导读:收集整理的这篇文章主要介绍了vue+canvas实现数据实时从上到下刷新瀑布图效果(类似QT的 ,觉得挺不错的,现在分享给大家,也给大家做个参考。 话不多说了,先上一张Demo图,实现的...
收集整理的这篇文章主要介绍了vue+canvas实现数据实时从上到下刷新瀑布图效果(类似QT的),觉得挺不错的,现在分享给大家,也给大家做个参考。 话不多说了,先上一张Demo图,实现的功能有:左侧图例、右侧瀑布图、鼠标移入弹出当前坐标对应的数据信息(有优化的空间,大家自由发挥)。
图例使用到的插件
这里推荐使用安装npm插件colormap
瀑布图主体内容
这里不多做解释了,都是一些原生标签还有vue绑定的事件,可以根据实际项目情况自己封装成组件,我这里是写在一起的。
template> div> div class="content"> div class="neirong"> !--图例--> div class="legend"> canvas ref="legend"> /canvas> /div> !--瀑布图--> div class="waterFall" ref="waterFallContent" @mouSEMove="waterFallMove($event)" @mouseleave="waterFallLeave" > canvas ref="waterFall"> /canvas> !--鼠标移入弹出框--> div ref="tip" class="tip"> /div> /div> /div> /div> /div> /template>
这里是用到的Data数据
- colormap:颜色库
- legend:图例
- waterFall:瀑布图
- waterFallList:瀑布图源数据
- waterFallIndex:瀑布图定时器用到的计数标识
- waterFallCopyList:瀑布图二维数组(用来显示数据做的临时储存)
- waterFallIntervals:瀑布图定时器
- waterFallWidth:瀑布图的宽度(后端返回的数据length)
- waterFallHeight:瀑布图定高度(也可以理解成渲染次数 例如30次渲染完成)
- maxNum:图例最大值
- minNum:图例最小值
script> export default { name: "index", data() { return { colormap: [], legend: null, waterFall: null, waterFallList: [], waterFallIndex: 0, waterFallCopyList: [], waterFallIntervals: null, waterFallWidth: 0, waterFallHeight: 0, maxNum: 10, minNum: 0 } } ,
下面是具体的方法,写的比较粗略,大家凑活看吧,觉得有用的大家拿走,不足之处自由发挥修改
方法调用这就不解释了,离开页面销毁定时器。
mounted() { let dx = this dx.setColormap() dx.createLegendCanvas() dx.queryChartList() } , destroyed() { let dx = this clearInterval(dx.waterFallIntervals) } ,
创建颜色库
这个地方具体看上面插件的官网有详细的介绍
setColormap() { let dx = this let colormap = require('colormap') dx.colormap = colormap({ colormap: 'jet', nshades: 150, format: 'rba', alpha: 1, } )} ,
创建图例
createLegendCanvas() { let dx = this let legendRefs = dx.$refs.legend dx.legend = legendRefs.getContext('2d') let legendCanvas = document.createElement('canvas') legendCanvas.width = 1 let legendCanvasTemporary = legendCanvas.getContext('2d') const imageData = legendCanvasTemporary.createImageData(1, dx.colormap.length) for (let i = 0; i dx.colormap.length; i++) { const color = dx.colormap[i] imageData.data[imageData.data.length - i * 4 + 0] = color[0] imageData.data[imageData.data.length - i * 4 + 1] = color[1] imageData.data[imageData.data.length - i * 4 + 2] = color[2] imageData.data[imageData.data.length - i * 4 + 3] = 255 } legendCanvasTemporary.putImageData(imageData, 0, 0) dx.legend.drawImage(legendCanvasTemporary.canvas, 0, 0, 1, dx.colormap.length, 50, 0, 200, dx.legend.canvas.height) } ,
创建瀑布图
createWaterFallCanvas() { let dx = this let waterFall = dx.$refs.waterFall dx.waterFall = waterFall.getContext('2d') waterFall.width = dx.waterFallWidth waterFall.height = dx.$refs.waterFallContent.offsetHeight } ,
绘制单行图像
rowToImageData(data) { let dx = this if (dx.$refs.waterFallContent !== undefined) { let canvasHeight = Math.floor(dx.$refs.waterFallContent.offsetHeight / dx.waterFallHeight) let imgOld = dx.waterFall.getImageData(0, 0, dx.waterFallWidth, canvasHeight * dx.waterFallIndex + 1) const imageData = dx.waterFall.createImageData(data.length, 1) for (let i = 0; i imageData.data.length; i += 4) { const cindex = dx.colorMapData(data[i / 4], 0, 130) const color = dx.colormap[cindex] imageData.data[i + 0] = color[0] imageData.data[i + 1] = color[1] imageData.data[i + 2] = color[2] imageData.data[i + 3] = 255 } for (let i = 0; i canvasHeight; i++) { dx.waterFall.putImageData(imageData, 0, i) } dx.waterFall.putImageData(imgOld, 0, canvasHeight) } } ,
返回数据对应的Colormap颜色
colorMapData(data, outMin, outMax) { let dx = this if (data = dx.minNum) { return outMin } else if (data > = dx.maxNum) { return outMax } return Math.round(((data - dx.minNum) / (dx.maxNum - dx.minNum)) * outMax) } ,
鼠标移入瀑布图
waterFallMove(event) { let dx = this let dataWidth = (dx.$refs.waterFallContent.offsetWidth / dx.waterFallWidth).toFixed(2) let dataHeight = (dx.$refs.waterFallContent.offsetHeight / dx.waterFallHeight).toFixed(2) let x = Math.floor(event.offsetX / dataWidth) let y = Math.floor(event.offsetY / dataHeight) try { dx.$refs.tip.innerHTML = '数值:' + JSON.parse(JSON.stringify(dx.waterFallCopyList[y][x])) let xx = event.offsetX + 5 let yy = event.offsetY - 20 if (event.offsetX > 1300) { xx = event.offsetX - 160 yy = event.offsetY - 20 } dx.$refs.tip.style.posITion = 'absolute' dx.$refs.tip.style.left = xx + 'px' dx.$refs.tip.style.top = yy + 'px' dx.$refs.tip.style.display = 'block' } catch (e) { dx.$refs.tip.style.display = 'none' } } ,
鼠标移出瀑布图
waterFallLeave() { let dx = this dx.$refs.tip.style.display = 'none' } ,
瀑布图假数据模拟
queryChartList() { let dx = this dx.waterFallWidth = 1500 dx.waterFallHeight = 30 let data = [] for (let i = 0; i 1500; i++) { data.push(Math.floor(Math.random() * (20 - 1)) + 1) } if (dx.waterFall === null) { dx.createWaterFallCanvas(data.length) } dx.rowToImageData(data) dx.waterFallCopyList.unshift(data) dx.waterFallIndex++ if (dx.waterFallIndex > dx.waterFallHeight) { dx.waterFallCopyList.pop() } dx.waterFallIntervals = setTimeout(() => { dx.queryChartList() } , 1000) } ,
样式代码
.neirong { width: 1800px; height: 100%; margin: 80px auto; display: flex; justify-content: center; } .legend { width: 25px; height: 500px; } canvas { width: 100%; height: 100%; } .waterFall { width: 1500px; height: 500px; position: relative; } .tip { pointer-events: none; display: none; background-color: #0404049e; border-radius: 10px; color: #fff; padding: 10px; box-sizing: border-box; }
到这里这个Demo基本就是可以运行的,不会有任何报错,代码写的不是很高级,我本人也是个初级的小菜鸟,也是第一次写文章,希望大佬可以给出一些更好的建议我也会好好学习的,也希望那些遇到类似这个需求没什么思路的小伙伴可以借鉴我的踩坑之旅,可以更快的成长起来。
到此这篇关于vue+canvas实现数据实时从上到下刷新瀑布图效果(类似QT的)的文章就介绍到这了,更多相关vue+canvas实时刷新瀑布图 内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
您可能感兴趣的文章:- Vue2.0/3.0双向数据绑定的实现原理详解
- 关于vuex强刷数据丢失问题解析
- Vue 如何追踪数据变化
- vue 数据(data)赋值问题的解决方案
- Vue 重置data的数据为初始状态操作
- Vue组件传值过程中丢失数据的分析与解决方案
- SpringBoot+Vue实现数据添加功能
- 手写Vue2.0 数据劫持的示例
- vue 数据双向绑定的实现方法
- Vue中避免滥用this去读取data中数据
- 用vue设计一个数据采集器
声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!
若转载请注明出处: vue+canvas实现数据实时从上到下刷新瀑布图效果(类似QT的)
本文地址: https://pptw.com/jishu/595141.html