钉钉小程序 antv/my-f2 半环形渐变图表
@antv/my-f2 图表组件,基于antv/f2 做了单独的自定义组件封装,适用于支付宝小程序、钉钉小程序。
F2 为小程序提供了灵活的图表 API 调用,my-f2 为小程序封装了自定义图表组件。
钉钉小程序原生语言 +f2 + my-f2
效果图:
代码开敲!
一、安装
f2官网:https://f2.antv.antgroup.com/
my-f2地址:https://github.com/antvis/my-f2?tab=readme-ov-file
npm install @antv/f2
npm install @antv/my-f2
二、引入组件
// index.json
{
"usingComponents": {
"f2": "@antv/my-f2"
}
}
三、容器与样式
<!-- index.axml -->
<view class="f2-chart">
<f2 onInit="onInitChart"></f2>
</view>
/* index.acss */
.f2-chart {
width: 260rpx;
height: 260rpx;
margin: auto;
margin-top: 100rpx;
}
四、实例化图表
// index.js
import F2 from '@antv/f2'
const {
Shape,
G,
Util,
Global
} = F2;
const Vector2 = G.Vector2;
const dataSource = [{ "x": 1, "y": 40 }]
Page({
onInitChart(F2, config) {
const pixelRatio = dd.getSystemInfoSync().pixelRatio
config.pixelRatio = pixelRatio
// 圆角
Shape.registerShape('interval', 'polar-tick', {
draw: function draw(cfg, group) {
const points = this.parsePoints(cfg.points);
const style = Util.mix({
stroke: cfg.color
}, Global.shape.interval, cfg.style);
let newPoints = points.slice(0);
if (this._coord.transposed) {
newPoints = [points[0], points[3], points[2], points[1]];
}
const center = cfg.center;
const x = center.x,
y = center.y;
const v = [1, 0];
const v0 = [newPoints[0].x - x, newPoints[0].y - y];
const v1 = [newPoints[1].x - x, newPoints[1].y - y];
const v2 = [newPoints[2].x - x, newPoints[2].y - y];
let startAngle = Vector2.angleTo(v, v1);
let endAngle = Vector2.angleTo(v, v2);
const r0 = Vector2.length(v0);
const r = Vector2.length(v1);
if (startAngle >= 1.5 * Math.PI) {
startAngle = startAngle - 2 * Math.PI;
}
if (endAngle >= 1.5 * Math.PI) {
endAngle = endAngle - 2 * Math.PI;
}
const lineWidth = r - r0;
const newRadius = r - lineWidth / 2;
return group.addShape('Arc', {
className: 'interval',
attrs: Util.mix({
x,
y,
startAngle,
endAngle,
r: newRadius,
lineWidth,
lineCap: 'round'
}, style)
});
}
});
let chartObj = this.initCircleChart(config)
chartObj.axis(false) // 不显示y轴坐标
chartObj.tooltip(false);
chartObj.render()
return chartObj
},
initCircleChart(config) {
config.padding = [16, 0, 0, 0]
let chart = new F2.Chart(config)
let [dataObj] = dataSource
const data = [{
const: 'a',
actual: dataObj.y,
expect: 100
}];
chart.source(data, {
actual: {
max: 100,
min: 0,
nice: false
}
});
// 设定极坐标系
chart.coord('polar', {
transposed: true,
innerRadius: 0.8,
startAngle: -Math.PI * 1.25,
endAngle: Math.PI / 4
});
chart.guide().text({
position: ['50%', '44%'],
content: `${dataObj.y}%`,
style: {
fill: '#333333',
fontSize: 25,
}
})
chart.guide().text({
position: ['50%', '65%'],
content: '完成率',
style: {
fill: '#8a9199',
fontSize: 13
}
})
// 绘制两个条形,分别作为背景和实际的百分比进度。
chart.interval()
.position('const*expect')
.shape('polar-tick')
.size(10)
.color('#E0EBF9')
.animate(false);
chart.interval()
.position('const*actual')
.shape('polar-tick')
.size(10)
.color('l(90) 0:#C07FEA 1:#287AEF')
.animate({
appear: {
duration: 500,
easing: 'linear',
animation: function animation(shape, animateCfg) {
const startAngle = shape.attr('startAngle');
let endAngle = shape.attr('endAngle');
if (startAngle > endAngle) {
endAngle += Math.PI * 2;
}
shape.attr('endAngle', startAngle);
shape.animate().to(Util.mix({
attrs: {
endAngle
}
}, animateCfg))
}
}
});
if (data[0]['actual'] !== 0) {
chart.point().position('const*actual').size(2)
.style({
fill: '#fff',
lineWidth: 0
});
}
return chart
},
})