vue+canvas实现数据实时从上到下刷新瀑布图效果(类似QT的)

这篇文章主要介绍了vue+canvas实现数据实时从上到下刷新瀑布图效果(类似QT的),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

话不多说了,先上一张Demo图,实现的功能有:左侧图例、右侧瀑布图、鼠标移入弹出当前坐标对应的数据信息(有优化的空间,大家自由发挥)。

图例使用到的插件

这里推荐使用安装npm插件colormap

瀑布图主体内容

这里不多做解释了,都是一些原生标签还有vue绑定的事件,可以根据实际项目情况自己封装成组件,我这里是写在一起的。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

<template>

    <div>

        <div class="content">

            <div class="neirong">

                <!--图例-->

                <div class="legend">

                    <canvas ref="legend"></canvas>

                </div>

                <!--瀑布图-->

                <div class="waterFall" ref="waterFallContent"

                     @mousemove="waterFallMove($event)"

                     @mouseleave="waterFallLeave"

                >

                    <canvas ref="waterFall"></canvas>

                    <!--鼠标移入弹出框-->

                    <div ref="tip" class="tip"></div>

                </div>

            </div>

        </div>

    </div>

</template>

这里是用到的Data数据

  • colormap:颜色库
  • legend:图例
  • waterFall:瀑布图
  • waterFallList:瀑布图源数据
  • waterFallIndex:瀑布图定时器用到的计数标识
  • waterFallCopyList:瀑布图二维数组(用来显示数据做的临时储存)
  • waterFallIntervals:瀑布图定时器
  • waterFallWidth:瀑布图的宽度(后端返回的数据length)
  • waterFallHeight:瀑布图定高度(也可以理解成渲染次数 例如30次渲染完成)
  • maxNum:图例最大值
  • minNum:图例最小值

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

<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

            }

        },

下面是具体的方法,写的比较粗略,大家凑活看吧,觉得有用的大家拿走,不足之处自由发挥修改

方法调用这就不解释了,离开页面销毁定时器。

1

2

3

4

5

6

7

8

9

10

mounted() {

            let dx = this

            dx.setColormap()

            dx.createLegendCanvas()

            dx.queryChartList()

        },

        destroyed() {

            let dx = this

            clearInterval(dx.waterFallIntervals)

        },

创建颜色库

这个地方具体看上面插件的官网有详细的介绍

1

2

3

4

5

6

7

8

9

10

setColormap() {

      let dx = this

      let colormap = require('colormap')

      dx.colormap = colormap({

          colormap: 'jet',

          nshades: 150,

          format: 'rba',

          alpha: 1,

   })

},

创建图例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

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)

            },

创建瀑布图

1

2

3

4

5

6

7

createWaterFallCanvas() {

               let dx = this

               let waterFall = dx.$refs.waterFall

               dx.waterFall = waterFall.getContext('2d')

               waterFall.width = dx.waterFallWidth

               waterFall.height = dx.$refs.waterFallContent.offsetHeight

           },

绘制单行图像

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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)

               }

           },

返回数据对应的Colormap颜色

1

2

3

4

5

6

7

8

9

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)

            },

鼠标移入瀑布图

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

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 = '数值:' + 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'

    }

},

鼠标移出瀑布图

1

2

3

4

waterFallLeave() {

                let dx = this

                dx.$refs.tip.style.display = 'none'

            },

瀑布图假数据模拟

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

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)

            },

样式代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

.neirong {

        width1800px;

        height100%;

        margin80px auto;

        display: flex;

        justify-contentcenter;

    }

    .legend {

        width25px;

        height500px;

    }

    canvas {

        width100%;

        height100%;

    }

    .waterFall {

        width1500px;

        height500px;

        positionrelative;

    }

    .tip {

        pointer-events: none;

        displaynone;

        background-color#0404049e;

        border-radius: 10px;

        color#fff;

        padding10px;

        box-sizing: border-box;

    }

到这里这个Demo基本就是可以运行的,不会有任何报错,代码写的不是很高级,我本人也是个初级的小菜鸟,也是第一次写文章,希望大佬可以给出一些更好的建议我也会好好学习的,也希望那些遇到类似这个需求没什么思路的小伙伴可以借鉴我的踩坑之旅,可以更快的成长起来。

到此这篇关于vue+canvas实现数据实时从上到下刷新瀑布图效果(类似QT的)的文章就介绍到这了,更多相关vue+canvas实时刷新瀑布图 内容请搜索米米素材网以前的文章或继续浏览下面的相关文章希望大家以后多多支持米米素材网!

原文链接:https://www.mimisucai.com/teach/javascript/34435.html_米米素材网

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值