1、文档
具体使用方式参考官方文档
官方文档-指南 - uCharts 跨平台图表库
2、使用方式选择
uCharts 包含原生 canvas 和组件两种引用方式:
1、原生方式 uCharts 体积小巧(18 个类型的图表压缩后 130kb)性能强大、各端的表现一致, 跨平台兼容性好;
2、uCharts 组件是官方在原生 uCharts 的基础上进行的封装,把一些新手容易出问题的用法、各平台不一致特有的需要注意的地方做了优化。支持 uni-app 组件和原生小程序组件,小程序组件需要根据不同平台引入对应版本。
由于小程序目前使用 taro.js 框架, 以及考虑到后续会兼容支付宝小程序,我们这里采用原生 canvas 的引用方式。
3、Taro vue 组件封装
官方演示文档 Taro 版本为 React 版本,下面配置参考微信原生组件开启 2d 版本。为解决 ios canvas 兼容问题,需开启 canvas 2d,避免使用定位和 scroll-view。
<template>
<view :id="'box-' + id" @tap="tap">
<canvas
:id="id"
:canvas-id="id"
:style="'width:' + width + 'rpx;height:' + height + 'rpx;'"
type="2d"
:disable-scroll="false"
/>
</view>
</template>
<script>
import uCharts from "@qiun/ucharts/u-charts";
import Taro from "@tarojs/taro";
import { mapState } from "vuex";
const uChartsInstance = {};
export default {
name: "Chart",
props: {
width: {
type: Number,
default: 750,
},
height: {
type: Number,
default: 500,
},
id: {
type: String,
default: "",
},
showTip: {
type: Function,
default: function () {},
},
option: {
type: Object,
default() {
return {};
},
},
},
data() {
return {
path: "",
cWidth: 0,
cHeight: 0,
};
},
computed: {
...mapState({
systemInfo: (state) => state.base.systemInfo,
}),
},
watch: {
option: {
handler(newVal) {
if (newVal.series !== undefined && newVal.series.length > 0) {
this.updateCharts();
}
},
deep: true,
},
},
created() {
if (this.id) {
this.cWidth =
(this.width / 750) *
this.systemInfo.windowWidth *
this.systemInfo.pixelRatio;
this.cHeight =
(this.height / 750) *
this.systemInfo.windowWidth *
this.systemInfo.pixelRatio;
Taro.nextTick(() => {
setTimeout(() => {
this.drawCharts();
}, 500);
});
}
},
methods: {
drawCharts() {
// taro vue 版本不可加.in(this) 否者找不到
// const query = wx.createSelectorQuery().in(this);
const query = Taro.createSelectorQuery();
query
.select("#" + this.id)
.fields({ node: true, size: true })
.exec((res) => {
if (res[0]) {
const canvas = res[0].node;
const ctx = canvas.getContext("2d");
canvas.width = res[0].width * this.systemInfo.pixelRatio;
canvas.height = res[0].height * this.systemInfo.pixelRatio;
uChartsInstance[this.id] = new uCharts({
context: ctx,
width: this.cWidth,
height: this.cHeight,
pixelRatio: this.systemInfo.pixelRatio,
...this.option,
});
} else {
console.error("[uCharts]: 未获取到 context");
}
});
},
updateCharts() {
uChartsInstance[this.id].updateData({
...this.option,
});
},
// 获取点击item 索引
getIndex(e) {
const dataIndex = uChartsInstance[this.id].getCurrentDataIndex(e);
if (typeof dataIndex === "object") return dataIndex.index;
else return dataIndex;
},
tap(e) {
e.changedTouches = [];
// 计算点击 坐标
e.changedTouches.unshift({
x: e.detail.x - e.currentTarget.offsetLeft,
y: e.detail.y - e.currentTarget.offsetTop,
});
let tipOption = {};
const origin = this.getIndex(e);
// 自定义tip配置
if (this.showTip && typeof this.showTip === "function") {
if (origin !== -1)
tipOption = this.showTip(this.option.series, origin) || {};
}
uChartsInstance[this.id].touchLegend(e);
uChartsInstance[this.id].showToolTip(e, tipOption);
// 获取x轴 点击索引
// e.changedTouches[0].y = e.changedTouches[0].y - 25
// const xAxis = this.getIndex(e)
// console.log(origin, xAxis)
// if (origin === -1 && xAxis !== -1) {
// this.$emit('getXAxisIndex', xAxis)
// }
},
},
};
</script>
4、问题解决
1、使用绝对定位导致,点击图表 tooltip 提示异常
.header {
position: fixed;
width: 100%;
top: 0;
height: 176px;
}
.main {
// main中包含图表组件, 若此处使用margin计算点击事件坐标 会出现偏差,偏差值为magrin-top 高度, 使用padding不会出现此问题。
// margin:176px 0 96px
padding: 176px 0 96px;
}