最近正在做一个uniapp项目,其中需要画一个两根折线的折线图,但是要求刷新速度快,差不多2ms要刷新一次数据,折线图也需要及时更新。一开始我使用echarts去做,根本刷新不过来,摁暂停按钮时,也卡的一批,后面我又尝试uchart,chart.js,anychart,但是他们都渲染不过来,抽样也想过,但业务不允许。最后没办法,只能自己用canvas自己写一个。
rendjs
rendjs是一种运行在试图层的js,具体是什么我也不清楚,可以去官网看看。我主要是看重他可以在视图层操作dom,可以提高视图性能。
renderjs | uni-app官网 (dcloud.net.cn)https://uniapp.dcloud.net.cn/tutorial/renderjs.html
初始化
//初始化 initLine(){ //主要是为了拿到HTMLCanvasElement 和 CanvasRenderingContext2D用来操作我们的画布 //之所以这样写,是因为如果直接getElementById,无法拿到它的上下文,也就是说getContext将失效 const content = document.getElementById('LineChart') canvasEle = document.createElement('canvas') content.appendChild(canvasEle) context = canvasEle.getContext('2d'); console.log(canvasEle); console.log(context); //设置线宽 context.lineWidth = 10; //将两条初始化的折线画出来 this.drawLine(pointArr1); this.drawLine(pointArr2); },
复制
绘画函数
drawLine(pointArr){ //将画笔的起点移到初始点 context.moveTo(0,canvasEle.height - pointArr[0]); for (var i = 1; i < pointArr.length; i++) { //从上一个点连线至目标点 context.lineTo(50*i,canvasEle.height - pointArr[i]); } //开始画图 context.stroke(); }
复制
接口函数
Lineupdate(num){ // console.log("3") //防止server初始化时,context不存在 if(typeof(context) == "undefined"){ return ; } //数组更新数值 pointArr1.shift(); pointArr1.push(num[0]); pointArr2.shift(); pointArr2.push(num[1]); //更新画布 canvasEle.height = 200; canvasEle.width = 200; // console.log("4") //画出这更新后的线 this.drawLine(pointArr1); this.drawLine(pointArr2); }
复制
完整代码
<template> <view> <canvas id="LineChart" width="400px" height="400px" :prop="num" :change:prop="LineChart.Lineupdate(num)"></canvas> </view> </template> <script> export default { data(){ return { num: [50,80] } },onLoad() { this.test(); }, methods: { test(){ setInterval(()=>{ this.$data.num[0] = Math.random()*100; this.$data.num[1] = Math.random()*100; },2) } } } </script> <script module = "LineChart" lang="renderjs"> let context; let canvasEle; let pointArr1 = [80,90,100,90,120]; let pointArr2 = [60,70,120,100,150]; export default { data(){ return{ } }, mounted(){ this.initLine(); }, methods:{ //初始化 initLine(){ //主要是为了拿到HTMLCanvasElement 和 CanvasRenderingContext2D用来操作我们的画布 //之所以这样写,是因为如果直接getElementById,无法拿到它的上下文,也就是说getContext将失效 const content = document.getElementById('LineChart') canvasEle = document.createElement('canvas') content.appendChild(canvasEle) context = canvasEle.getContext('2d'); console.log(canvasEle); console.log(context); //设置线宽 context.lineWidth = 10; //将两条初始化的折线画出来 this.drawLine(pointArr1); this.drawLine(pointArr2); }, Lineupdate(num){ if(typeof(context) == "undefined"){ return ; } pointArr1.shift(); pointArr1.push(num[0]); pointArr2.shift(); pointArr2.push(num[1]); canvasEle.height = 200; canvasEle.width = 200; this.drawLine(pointArr1); this.drawLine(pointArr2); }, drawLine(pointArr){ //将画笔的起点移到初始点 context.moveTo(0,canvasEle.height - pointArr[0]); for (var i = 1; i < pointArr.length; i++) { //从上一个点连线至目标点 context.lineTo(50*i,canvasEle.height - pointArr[i]); } //开始画图 context.stroke(); } } } </script> <style> </style>
复制
效果真的很好!!