最近正在做一个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>
效果真的很好!!