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
Sometimes some docker containers exit after a per...
Experimental environment Apache and Tomcat are bo...
Problem description (environment: windows7, MySql...
The principle of uploading pictures on the front ...
As shown below: select name from mysql.proc where...
1. Background The company's projects have alw...
Table of contents Introduction to Anaconda 1. Dow...
1. CSS background tag 1. Set the background color...
<br />In general guestbooks, forums and othe...
download Download address: https://redis.io/downl...
Nginx does not support nested if statements, nor ...
Table of contents What is cgroup Composition of c...
Problem background: When using docker to deploy t...
Preface: Mybatis special character processing, pr...
describe When calling this interface, you need to...