Without further ado, here is a demo picture. The functions implemented are: legend on the left, waterfall chart on the right, and data information corresponding to the current coordinates popping up when the mouse is moved (there is room for optimization, please feel free to play with it). Plugins used in the illustration It is recommended to install the npm plugin colormap Waterfall chart bodyI won’t explain it here. They are all native tags and vue-bound events. You can encapsulate them into components according to the actual project situation. I have written them together here. <template> <div> <div class="content"> <div class="neirong"> <!--Legend--> <div class="legend"> <canvas ref="legend"></canvas> </div> <!--Waterfall Chart--> <div class="waterFall" ref="waterFallContent" @mousemove="waterFallMove($event)" @mouseleave="waterFallLeave" > <canvas ref="waterFall"></canvas> <!--Move the mouse into the pop-up box--> <div ref="tip" class="tip"></div> </div> </div> </div> </div> </template> Here is the Data used
<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 } }, The following is a specific method. It is written roughly. Please read it carefully. If you find it useful, please take it away. If there are any shortcomings, you can modify it freely. I won't explain the method call here, leaving the page will destroy the timer. mounted() { let dx = this dx.setColormap() dx.createLegendCanvas() dx.queryChartList() }, destroyed() { let dx = this clearInterval(dx.waterFallIntervals) }, Create a color library For details, please refer to the official website of the above plug-in for detailed introduction. setColormap() { let dx = this let colormap = require('colormap') dx.colormap = colormap({ colormap: 'jet', nshades: 150, format: 'rba', alpha: 1, }) }, Creating a LegendcreateLegendCanvas() { 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) }, Creating a waterfall chartcreateWaterFallCanvas() { let dx = this let waterFall = dx.$refs.waterFall dx.waterFall = waterFall.getContext('2d') waterFall.width = dx.waterFallWidth waterFall.height = dx.$refs.waterFallContent.offsetHeight }, Draw a single line imagerowToImageData(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) } }, Returns the Colormap color corresponding to the datacolorMapData(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) }, Move the mouse into the waterfall chartwaterFallMove(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 = 'Value:' + 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' } }, Move the mouse out of the waterfall chartwaterFallLeave() { let dx = this dx.$refs.tip.style.display = 'none' }, Waterfall chart fake data simulationqueryChartList() { 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) }, Style Code .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; } At this point, the Demo can basically run without any errors. The code is not very advanced. I am also a beginner and this is my first time writing an article. I hope the big guys can give me some better suggestions and I will study hard. I also hope that friends who encounter similar requirements and have no ideas can learn from my experience of stepping into the pit and grow faster. This is the end of this article about how vue+canvas achieves real-time data refresh from top to bottom waterfall chart effect (similar to QT). For more related vue+canvas real-time refresh waterfall chart content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future! You may also be interested in:
|
>>: Mysql 5.7.18 Using MySQL proxies_priv to implement similar user group management
Download the official website First go to the off...
Overview The prototype pattern refers to the type...
Preface: When we use Vue, we often use and write ...
Find the containerID of tomcat and enter the toma...
Problem description (what is keep-alive) keep-ali...
I have used the vi editor for several years, but ...
This article shares the specific code of Vue+Webs...
Table of contents 1. Parent-child component commu...
Table of contents introduce Prepare Download syst...
Add monitoring host Host 192.168.179.104 is added...
Table of contents Preface Global parameter persis...
Table of contents background 1) Enable the keepch...
MySQL itself was developed based on the file syst...
Today, when we were learning about the Niu Nan new...
When I was writing a project yesterday, I needed ...