其实Taro官方文档里有给出使用Echarts的例子,即“使用小程序原生第三方组件和插件”方法。
在我的项目内有生成雷达图的需求,我项目升级前使用的是Taro@1.3.10。
当时的处理方式是单独写了一个生成雷达图的组件,然后在页面内注册使用,具体代码(如果你是Taro 3请忽略并往下看):
// RadarChar.js
import Taro, { Component } from "@tarojs/taro";
import * as echarts from "./ec-canvas/echarts";
import util from '../utils';
function setChartData(chart, data) { // 为图表设置数据
let option = {
title: {
textStyle: {
color: "#eee",
size: 12,
rich: {}
}
},
grid: {
x: 20,
y: 20,
x2: 20,
y2: 20,
top: 20,
bottom: 20,
left: 20,
right: 20,
containLabel: true
},
radar: {
indicator: data,
name: {
textStyle: {
color: "#333333",
fontSize: 10,
backgroundColor: "rgba(255,216,1,0.4)",
padding: [0, 5],
borderRadius: 50,
lineHeight: 20,
rich: {}
}
},
// splitNumber: 8,
splitLine: {
lineStyle: {
color: [
"rgba(255, 216, 1, 1)",
"rgba(255, 216, 1, 1)",
"rgba(255, 216, 1, 1)",
"rgba(255, 216, 1, 1)",
"rgba(255, 216, 1, 1)",
"rgba(255, 216, 1, 1)"
].reverse()
}
},
splitArea: {
show: false,
areaStyle: {
color: [
"rgba(255, 216, 1, 0.1)",
"rgba(255, 216, 1, 0.2)",
"rgba(255, 216, 1, 0.3)",
"rgba(255, 216, 1, 0.4)",
"rgba(255, 216, 1, 0.6)",
"rgba(255, 216, 1, 0.8)"
].reverse() // 图表背景网格的颜色
}
},
axisLine: {
lineStyle: {
color: "#FFD801"
}
}
},
series: []
};
if (data && data.dimensions && data.measures) {
option.radar.indicator = data.dimensions.data;
option.series = data.measures.map(item => {
return {
...item,
type: "radar"
};
});
}
chart.setOption(option);
}
export default class RadarChar extends Component {
config = {
usingComponents: {
"ec-canvas": "./ec-canvas/ec-canvas" // 图表组件注册
}
};
constructor(props) {
super(props);
}
state = {
ec: {
lazyLoad: true
}
};
refresh(data) { // 初始化图表,需要在父组件内调用
this.Chart.init((canvas, width, height) => {
const chart = echarts.init(canvas, null, {
width: width,
height: height
});
setChartData(chart, data);
return chart;
});
}
refChart = node => (this.Chart = node);
render() {
return (
ref={this.refChart}
canvas-id="mychart-area"
ec={this.state.ec}
/>
);
}
}
// 父组件
// render内
refRadarChar = node => (this.radarChar = node);
createRadarChar(label, data) { // 获取图表数据后调用
const _this = this;
const chartData = {
dimensions: {
data: label
},
measures: [
{
data: [
{
name: "作品分析",
type: "radar",
lineStyle: {
normal: {
width: 1,
opacity: 1
}
},
value: data,
symbol: "circle" /*曲线圆点*/,
symbolSize: 10,
itemStyle: {
normal: {
color: "#FFD801"
}
},
areaStyle: {
normal: {
color: "#FFD801",
opacity: 0.7
}
}
}
],
label: {
normal: {
rich: {}
}
}
}
]
};
this.radarChar.refresh(chartData);
}
效果
但是升级为Taro3之后,无法获取到this.Chart的原生实例对象,在v1.3.10内获取到的this.Chart:
this.Chart in Taro@1.3
this.Chart in Taro@3
所以在Taro@3内无法执行chart的init方法,同时页面也未渲染ec-canvas节点。
是因为在Taro@3内使用原生第三方组件或插件需要在page级页面内注册组件,在子组件内注册无效。
因为获取不到正确的this.Chart,所以最后通过它的onInit事件实现,具体代码如下:
import Taro from "@tarojs/taro";
import React, { Component } from "react";
import { View } from "@tarojs/components";
import * as echarts from "../ec-canvas/echarts.js";
let chart = null;
function setChartData(chart, data) {
let option = {
title: {
textStyle: {
color: "#eee",
size: 12,
rich: {}
}
},
grid: {
x: 20,
y: 20,
x2: 20,
y2: 20,
top: 20,
bottom: 20,
left: 20,
right: 20,
containLabel: true
},
radar: {
indicator: data,
name: {
textStyle: {
color: "#333333",
fontSize: 10,
backgroundColor: "rgba(255,216,1,0.4)",
padding: [0, 5],
borderRadius: 50,
lineHeight: 20,
rich: {}
}
},
// splitNumber: 8,
splitLine: {
lineStyle: {
color: [
"rgba(255, 216, 1, 1)",
"rgba(255, 216, 1, 1)",
"rgba(255, 216, 1, 1)",
"rgba(255, 216, 1, 1)",
"rgba(255, 216, 1, 1)",
"rgba(255, 216, 1, 1)"
].reverse()
}
},
splitArea: {
show: false,
areaStyle: {
color: [
"rgba(255, 216, 1, 0.1)",
"rgba(255, 216, 1, 0.2)",
"rgba(255, 216, 1, 0.3)",
"rgba(255, 216, 1, 0.4)",
"rgba(255, 216, 1, 0.6)",
"rgba(255, 216, 1, 0.8)"
].reverse() // 图表背景网格的颜色
}
},
axisLine: {
lineStyle: {
color: "#FFD801"
}
}
},
series: []
};
if (data && data.dimensions && data.measures) {
option.radar.indicator = data.dimensions.data;
option.series = data.measures.map(item => {
return {
...item,
type: "radar"
};
});
}
chart.setOption(option);
}
function initChart(canvas, width, height) { // 初始化图表
console.log("init");
chart = echarts.init(canvas, null, {
width: width,
height: height
});
canvas.setChart(chart);
setChartData(chart, {});
return chart;
}
export default class RadarChar extends Component {
constructor(props) {
super(props);
this.refresh = this.refresh.bind(this);
}
state = {
ec: {
onInit: initChart
},
init_chart: false
};
componentDidUpdate(nextProps) {
const _this = this;
setTimeout(() => {
setChartData(chart, nextProps.chartData)
}, 2000); // 异步获取到图表数据并更新
}
render() {
return (
id="mychart-dom-area"
canvas-id="mychart-area"
ec={this.state.ec}
/>
);
}
}