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

  1. 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
  1. 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
  1. 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!