uni-app 微信小程序开始,引入的uchart,问题,canvas层级过高,出现穿透问题
微信小程序图表层级过高问题
因canvas在微信小程序是原生组件,如果使用自定义tabbar或者自定义导航栏,图表则会超出预期,此时需要给组件的canvas2d传值true来使用type='2d'的功能,开启此模式后,一定要在组件上自定义canvasId,不能为数字,不能动态绑定,要为随机字符串!不能“真机调试”,不能“真机调试”,不能“真机调试”开发者工具显示不正常,图表层级会变高,而正常预览或者发布上线则是正常状态,开发者不必担心,一切以真机预览为准(因微信开发者工具显示不正确,canvas2d这种模式下给调试带来了困难,开发时,可以先用:canvas2d="false"来调试,预览无误后再改成true)。
开启canvas2d后图表不显示问题
开启canvas2d后,需要手动指定canvasId,并且父元素不能含有v-if,否则会导致获取不到dom节点问题,请将v-if改成v-show,更多开启canvas2d不显示问题,请参考示例项目pages/layout/layout.vue文件,对照示例项目修改您的项目。
其实代码都有写明,
在下。
解决:
需要微信小程序有canvas2d模式,canvas添加type="2d"
<canvas canvas-id="canvasArcbar1" id="canvasArcbar1" class="charts3" type="2d"></canvas>
canvas重新渲染问题
首页home.vue
需要数据添加成功之后返回页面,canvas根据新的内容重新渲染。
问题:原先是开始绘画接口放置在了mounted生命周期中,但是部分手机出现了不重新渲染的问题
解决:页面请求完成之后数据再进行渲染。
//home.vue
<canvas canvas-id="canvasArcbarHome" id="canvasArcbarHome" class="charts3" type="2d"></canvas>
data(){
return{
canvasId: 'canvasArcbarHome'
}
},
onShow(){
bloodSugarInfoApi().then(res => {
if (res.code == 100 && res.data && res.data.bloodSugarNum) {
this.bloodData = res.data
this.measurementTime = res.data.dateTime
this.bloodSugarNum = res.data.bloodSugarNum
this.params = {}
this.params.code = res.data.dataTypeCode
//获取当前的params以及根据测量时间判断测量时段
this.$nextTick(() => {
this.initArcbar()
// this.handelDrawArcbar(res.data.bloodSugarNum)
this.diningCodeDegree()
this.noOnShow = false
})
} else {
this.bloodSugarNum = null
this.measurementTime = null
this.params = {}
}
})
}
记录页面record.vue
<canvas canvas-id="canvasArcbarRecord" id="canvasArcbarRecord" class="charts3" type="2d"></canvas>
data(){
return{
canvasId: 'canvasArcbarRecord'
}
},
onLoad(options) {
//获取当前的params以及根据测量时间判断测量时段
this.diningTimeDegree()
}
mounted() {
//进度条初始设置
this.initArcbar()
},
公共的mixin-progree.js
// mixin/mixin-progree.js
import {eatTimeArr, diningTimeArr} from '@/utils/data.js'
import uCharts from '@/uni_modules/qiun-data-charts/js_sdk/u-charts/u-charts'
var uChartsInstance = {}
export const mixinProgree = {
data() {
return {
cWidth3: '', //圆弧进度图
cHeight3: '', //圆弧进度图
arcbarWidth: '', //圆弧进度图,进度条宽度,此设置可使各端宽度一致
pixelRatio: 1, //设备像素比
curRange: {}, //测量时段拿到的当前range,用于获取
curEatTime: eatTimeArr[0], //就餐时间段 用于显示低血糖等
}
},
computed: {
testTime() {
const time = this.curEatTime.time
return time
},
},
created() {},
mounted() {
console.log('进度条初始设置')
//进度条初始设置
this.initArcbar()
},
methods: {
initArcbar() {
console.log('开始绘画')
//#ifdef MP-ALIPAY || MP-WEIXIN
this.pixelRatio = uni.getSystemInfoSync().pixelRatio
//#endif
this.cWidth3 = uni.upx2px(400) //这里要与样式的宽高对应
this.cHeight3 = uni.upx2px(400) //这里要与样式的宽高对应
this.arcbarWidth = uni.upx2px(24)
this.handelDrawArcbar(this.bloodSugarNum || '')
},
//input并出发canvas绘画
handelDrawArcbar(value) {
this.bloodSugarNum = Number(value)
this.$u.debounce(this.drawArcbar)
},
//设置绘画参数
drawArcbar() {
console.log('设置绘画参数')
this.setCurRange()
const bloodNumPercentage = this.bloodSugarNum / 30
const sendArcbar = {
series: [
{
data: [bloodNumPercentage > 1 ? 1 : bloodNumPercentage],
},
],
}
let sendColor = ['#F3F6F6', '#F3F6F6'] //初始化样式
if (this.curRange && bloodNumPercentage > 0) {
sendColor = this.curRange.sendColor
}
console.log(this.curRange, ' this.curRange')
this.showArcbar(this.canvasId, sendArcbar, sendColor)
},
//显示绘画
showArcbar(canvasId, chartData, cirCor) {
console.log('显示绘画', canvasId)
const query = uni.createSelectorQuery().in(this)
query
.select('#' + canvasId)
.fields({
node: true,
size: true,
})
.exec(res => {
if (res[0]) {
const canvas = res[0].node
//v2.0版本必须要获取context并传入opts(option)中
const ctx = canvas.getContext('2d')
canvas.width = res[0].width * this.pixelRatio
canvas.height = res[0].height * this.pixelRatio
uChartsInstance[canvasId] = new uCharts({
type: 'arcbar',
fontSize: 11,
legend: {show: false},
background: '#FFFFFF',
pixelRatio: this.pixelRatio, //像素
series: chartData.series,
animation: false,
width: this.cWidth3 * this.pixelRatio,
height: this.cHeight3 * this.pixelRatio,
dataLabel: true,
canvas2d: true, //开启canvas2d
context: ctx || uni.createCanvasContext(canvasId, this), //v2.0版本必须要传contex
extra: {
arcbar: {
type: 'default', //整圆类型进度条图
width: this.arcbarWidth, //圆弧的宽度
linearType: 'custom', //开启色值渐变色值
customColor: cirCor, //渐变色值
backgroundColor: '#F3F6F6', //环形图的剩余百分比颜色
},
},
})
} else {
console.error('[uCharts]:未获取到context')
}
})
},
//获取当前的params以及根据测量时间判断测量时段
diningTimeDegree() {
const centerTime = this.$date.formatDate(this.measurementTime, 'hh:mm')
const dining = diningTimeArr.find(v => centerTime >= v.start && centerTime < v.end)
this.params = dining
this.setCurEatTime()
},
//根据code获取当前的params
diningCodeDegree() {
const dining = diningTimeArr.find(v => v.code == this.params.code)
this.params = dining
this.setCurEatTime()
},
//获取当前的血糖值 根据code查询 red:严重 orange:偏高 green:正常 blue1:偏低 blue2:低血糖
setCurRange() {
const bloodSugarNum = this.bloodSugarNum || 0
const code = this.params.code || 0
const obj = diningTimeArr.find(v => v.code == code)
if (obj) {
const curRange = obj.range.find(v => bloodSugarNum >= v.min && bloodSugarNum < v.max)
this.curRange = curRange
}
},
//获取当前选中的就餐时间段 根据code查询
setCurEatTime() {
const eatTime = eatTimeArr.find(v => v.code == this.params.code)
this.curEatTime = eatTime
},
},
}
// canvas 进度条
.charts3 {
width: 400rpx;
height: 400rpx;
margin: 0 auto;
}