No more words, first a Demo diagram, the realization of the functions are: left legend, right waterfall diagram, mouse move popup the current coordinate corresponding data information (there is optimized space, we play freely).
The plug-in used by the legend
The NPM plug-in is recommendedcolormap
Waterfall diagram body content
- There is no more explanation here. These are native tags and vUE bound events that can be packaged into components based on the actual project situation. I have written them together here.
<template>
<div>
<div class="content">
<div class="neirong">
<! - the legend -- -- >
<div class="legend">
<canvas ref="legend"></canvas>
</div>
<! -- Waterfall -->
<div class="waterFall" ref="waterFallContent"
@mousemove="waterFallMove($event)"
@mouseleave="waterFallLeave"
>
<canvas ref="waterFall"></canvas>
<! -- Mouse over popup -->
<div ref="tip" class="tip"></div>
</div>
</div>
</div>
</div>
</template>
Copy the code
- So here’s the Data that’s used
WaterFallIndex: indicates the count identifier used by the waterFall timer. WaterFallCopyList: Indicates the waterFall waterFall waterFall. WaterFallWidth: the width of the waterfall (the length of the data returned from the back end) Set the height of the waterfall (also known as the number of renderings, such as 30 renderings). MaxNum: maximum number of legend minNum: minimum number of legend
<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}},Copy the code
- The following is the specific method, write more rough, we gather together live to see, feel useful we take away, inadequate place free play modification
Method call this is not explained, leave the page destroy timer.
mounted() {
let dx = this
dx.setColormap()
dx.createLegendCanvas()
dx.queryChartList()
},
destroyed() {
let dx = this
clearInterval(dx.waterFallIntervals)
},
Copy the code
Create a color library
This place has a detailed introduction on the official website of the plug-in
setColormap() {
let dx = this
let colormap = require('colormap')
dx.colormap = colormap({
colormap: 'jet'.nshades: 150.format: 'rba'.alpha: 1,}}),Copy the code
Create a legend
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)
},
Copy the code
Creating a waterfall diagram
createWaterFallCanvas() {
let dx = this
let waterFall = dx.$refs.waterFall
dx.waterFall = waterFall.getContext('2d')
waterFall.width = dx.waterFallWidth
waterFall.height = dx.$refs.waterFallContent.offsetHeight
},
Copy the code
Draws a single line image
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)
}
},
Copy the code
Returns the corresponding Colormap color of the data
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)
},
Copy the code
Mouse over the waterfall diagram
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 = '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'}},Copy the code
Mouse over the waterfall diagram
waterFallLeave() {
let dx = this
dx.$refs.tip.style.display = 'none'
},
Copy the code
Waterfall diagram fake data simulation
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)},Copy the code
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;
}
Copy the code
This Demo is basic can run here and there won’t be any error, the code is not very advanced, I am also a junior rookie, is writing an article for the first time, hope bosses can give some better advice I will study hard, also hope that similar this needs no idea friend can draw lessons from my trip to hit the pit, Can grow up faster. Finally, thank you for reading!