1.安装依赖
npm i @antv/f2 --save
# 微信小程序
npm i @antv/f2-my --save
2.拷贝组件
将node_modules里面的(@antv/f2-my),拷贝出来,到src/components下面。
然后,在 app.config.js 里面,全局引入小程序组件。
或者在单独的页面里引用
usingComponents: {
f2: '@/components/f2-my/es/index',
},
修改src/components/f2-my/es/index.js里面的onRender为render,同时改为非函数
props: {
render: '',
// width height 会作为元素兜底的宽高使用
width: null,
height: null,
type: '2d', // canvas 2d, 基础库 2.7 以上支持
},
/**
* 组件创建时触发
* 注意:
* 使用该生命周期,项目配置需启用:"component2": true
*/
onInit: function onInit() {
this.setCanvasId();
},
didMount: function didMount() {
var _this = this;
if (isAppX2CanvasEnv()) {
return;
}
var id = this.data.id;
var query = my.createSelectorQuery({
page: this.$page,
});
query
.select('#'.concat(id))
.boundingClientRect()
.exec(function (res) {
// 获取画布实际宽高, 用props的宽高做失败兜底
var _ref = res && res[0] ? res[0] : _this.props,
width = _ref.width,
height = _ref.height;
var pixelRatio = getPixelRatio(); // 高清解决方案
_this.setData(
{
width: width * pixelRatio,
height: height * pixelRatio,
},
function () {
var myCtx = my.createCanvasContext(id);
var context = F2Context(myCtx);
_this.canvasRender({
width: width,
height: height,
context: context,
pixelRatio: pixelRatio,
});
}
);
});
},
didUpdate: function didUpdate() {
var canvas = this.canvas,
props = this.props;
if (!canvas) return;
var children = props.render;
canvas.update({
children: children,
});
},
didUnmount: function didUnmount() {
var canvas = this.canvas;
if (!canvas) return;
canvas.destroy();
},
methods: {
setCanvasId: function setCanvasId() {
var pageId = (this.$page && this.$page.$id) || 0;
var id = 'f2-canvas-'.concat(pageId, '-').concat(this.$id);
this.setData({
id: id,
});
},
onCanvasReady: function onCanvasReady() {
var _this2 = this;
var id = this.data.id;
var query = my.createSelectorQuery();
query
.select('#'.concat(id)) // @ts-ignore
.node()
.exec(function (res) {
if (!res[0]) {
return;
}
var canvas = res[0].node;
var width = canvas.width,
height = canvas.height;
var pixelRatio = getPixelRatio();
canvas.width = width * pixelRatio;
canvas.height = height * pixelRatio;
var context = canvas.getContext('2d');
_this2.canvasRender({
width: width,
height: height,
pixelRatio: pixelRatio,
context: context,
});
});
},
canvasRender: function canvasRender(_ref2) {
var width = _ref2.width,
height = _ref2.height,
pixelRatio = _ref2.pixelRatio,
context = _ref2.context;
if (!width || !height) {
return;
}
var children = this.props.render;
var canvas = new Canvas({
pixelRatio: pixelRatio,
width: width,
height: height,
context: context,
children: children,
});
canvas.render();
this.canvas = canvas;
this.canvasEl = canvas.canvas.get('el');
},
click: function click(e) {
var canvasEl = this.canvasEl;
if (!canvasEl) {
return;
}
var event = wrapEvent(e);
var detail = e.detail,
target = e.target;
var x = detail.x,
y = detail.y;
var _target$offsetLeft = target.offsetLeft,
offsetLeft = _target$offsetLeft === void 0 ? 0 : _target$offsetLeft,
_target$offsetTop = target.offsetTop,
offsetTop = _target$offsetTop === void 0 ? 0 : _target$offsetTop; // 包装成 touch 对象
event.touches = [
{
x: x - offsetLeft,
y: y - offsetTop,
},
];
canvasEl.dispatchEvent('click', event);
},
touchStart: function touchStart(e) {
var canvasEl = this.canvasEl;
if (!canvasEl) {
return;
}
canvasEl.dispatchEvent('touchstart', wrapEvent(e));
},
touchMove: function touchMove(e) {
var canvasEl = this.canvasEl;
if (!canvasEl) {
return;
}
canvasEl.dispatchEvent('touchmove', wrapEvent(e));
},
touchEnd: function touchEnd(e) {
var canvasEl = this.canvasEl;
if (!canvasEl) {
return;
}
canvasEl.dispatchEvent('touchend', wrapEvent(e));
},
},
});
3.编写图表组件
新建文件 chart-box.jsx 写一个 雷达图,如下:
import { Chart, Point, Line, Area, Axis, Legend } from '@antv/f2';
const ChartBox = props => {
const { data } = props;
return (
<Chart
data={data}
coord='polar'
scale={{
score: {
min: 0,
max: 100,
nice: false,
tickCount: 5,
},
}}
>
<Axis field='item' />
<Axis field='score' />
<Line x='item' y='score' color='#43A5F3' />
<Area x='item' y='score' color='user' />
<Point x='item' y='score' color='#43A5F3' />
<Legend />
</Chart>
);
};
export default ChartBox;
4.引用
import { View, Text, Image } from '@tarojs/components';
import { useState, useEffect } from 'react';
import ChartBox from './chart-box';
import './index.less';
const data = [
{
item: '准确度',
user: '用户 A',
score: 70,
},
{
item: '语调',
user: '用户 A',
score: 60,
},
{
item: '流利度',
user: '用户 A',
score: 50,
},
{
item: '完整度',
user: '用户 A',
score: 40,
},
];
const RadarChart = () => {
return (
<View class='chart-container'>
<f2 render={<ChartBox data={data} />}></f2>
</View>
);
};
export default RadarChart;