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
Table of contents Passing parameters between pare...
Table of contents 1. Example scenario 1.1. Set th...
Table of contents Solution 1 Solution 2 When crea...
Table of contents Common compression formats: gz ...
The following analysis is about product design pr...
Table of contents Install tinymce, tinymce ts, ti...
FastDFS & Nginx Integration: The tracker is c...
first step Delete it once with the built-in packa...
Table of contents 1. What is JSON 1.1 Array liter...
What is wxs? wxs (WeiXin Script) is a scripting l...
Recently, I started upgrading my blog. In the proc...
This article shares the specific code of JavaScri...
This article example shares the specific code of ...
Problem phenomenon I recently used sysbench to te...
Table of contents 1. Short circuit judgment 2. Op...