antv f2的api地址: f2.antv.antgroup.com/api/f2
在原生小程序里使用f2绘制图表可太恶心了,一大堆问题,有时候就像玄学一样,同样的写法同样的数据绘制的图表还会有差异,但代码是最客观的,不存在玄学,只是我太菜而已,所以记录一下最近开发的几种f2图表
曲线图
<f2 id="complexChartNew" class="chart-view__f2" onInit="{{onInitOCCLineChart}}"></f2>
//初始化配置
Page({
/**
* 页面的初始数据
*/
data: {
// 经营趋势曲线图
complexChart: {
//图表数据
data: [],
// 是否已渲染
rendered: false,
// 渲染图表 interval 标识
updateInterval: -1
},
// 经营趋势曲线图配置
onInitOCCLineChart(F2, config) {
const data = []; //图表数据
config.appendPadding = [20, 14, 25, 11]; //图表的内边距
const chart = new F2.Chart(config);
// 配置数据和坐标轴
chart.source([], {
date: { //日期 X轴
type: 'cat', //x轴数据格式(identity`、`linear`、`cat`、`timeCat`)
range: [0, 1], //数据范围
tickCount: 6 //x轴个数
},
value: { //数据 y轴
tickCount: 8,
},
});
// 配置 tooltip (示数据气泡提示)
chart.tooltip({
showItemMarker: true,
showTitle: true,
layout: 'vertical', //设置垂直显示
offsetY: 50, //设置居中展示
onShow(obj) { //自定义tooltip数据展示格式
const items = obj.items;
let flag = items[0].name === '出租率' ? '%' : ''
items[0].name = items[0].name || '';
items[0].value = items[0].value + flag;
if(items[1]) {
items[1].name = items[1].name;
items[1].value =items[1].value + (items[1].name === '平均房价' ? '' : flag);
}
},
})
// 配置绘制图形
chart.line().position('date*value').color('#5B8FF9').shape('smooth');
return chart;
},
}
})
/**
* 渲染曲线图
* @param {Arrary} data
*/
renderCharts(data) {
let complexChart = this.data.complexChart;
// 是否已渲染
const rendered = complexChart.rendered;
complexChart.rendered = true;
complexChart.data = data;
clearInterval(complexChart.updateInterval);
complexChart.updateInterval = -1;
this.setData({ complexChart });
// 获取 chart 实例
const chartIns = this.selectComponent('#complexChartNew');
chartIns?.chart?.guide()?.clear();
// 初次加载可能存在 chartIns.chart 实例不存在问题,循环判断在正确获取到实例后渲染
let updateInterval = setInterval(() => {
if (chartIns && chartIns.chart) {
chartIns.chart.changeData(data);
if(this.data.realTime) {
//实时数据有预测部分
const futureData = data.filter(item => item.predict);
futureData.forEach(obj => {
// 预测数据点添加point和label
chartIns.chart.guide().point({ // 预测 数据 原点
position: [ obj.date, obj.value ],
style: {
stroke: '#1890ff',
lineWidth: 1,
fill: '#fff',
r: ['去年同期', '上周此时'].includes(obj.name) ? 0 : 2
}
})
})
} else {
chartIns.chart.guide().clear();
}
chartIns.chart.legend({
position: 'bottom',
align: 'center',
});
if (rendered) {
chartIns.chart.repaint();
} else {
chartIns.chart.render();
}
clearInterval(updateInterval);
complexChart.updateInterval = -1;
}
}, 300);
complexChart.updateInterval = updateInterval;
},
结果展示:
环形图
<f2 id="guestChart" class="chart-view__f2" onInit="{{onInitGuestChartLineChart}}" />
page({
data:{
guestChart: {
// 分类数据
data: [],
// 是否已渲染
rendered: false,
// 渲染图表 interval 标识
updateInterval: -1
},
onInitGuestChartLineChart(F2, config){
const data = [];
config.appendPadding = [12, 11, 8, 11];
const chart = new F2.Chart(config);
chart.source(data, { //设置数据格式
value: {
formatter: function formatter(val) {
return val + '%';
}
}
});
chart.coord('polar', { //设置为极坐标polar(分为直角坐标系和极坐标两种类型)
transposed: true, //极坐标转置
radius: 1.2, //实心圆的半径大小设置
innerRadius: 0.518 // 用于空心部分的半径设置
});
chart.axis(false); // 关闭XY轴等线条
// 配置 tooltip
chart.tooltip({
onShow(obj) {
const items = obj.items;
items[0].name = items[0].name.split(' ')[0];
items[0].value = items[0].value;
},
});
// 配置 legend
chart.legend({
position: 'right',
align: 'center',
// 图例项宽度根据自身的宽度计算
itemWidth: null,
// 图例项水平方向上的间距
itemGap: 25,
// marker 和文本之间的间距
wordSpace: 10,
nameStyle: {
fill: '#797B82',
fontSize: 12,
fontWeight: 500
},
})
// 配置绘制图形
chart.interval().position('a*value').color('name', ['#945FB9','#F6BD16','#FF833C','#5B8FF9']).adjust('stack').style({
lineWidth: 1,
stroke: '#fff',
lineJoin: 'round',
lineCap: 'round'
}).animate({
appear: {
duration: 1200,
easing: 'bounceOut'
}
});
return chart;
},
}
})
/**
* 渲染环形图
* @param { Object } data 数据源
*/
renderRealGuestChart:function(){
let datas = this.data.realGuest.map(item => {
return {
value: item.room_rate,
name:item.name+' '+item.room_rate+' %',
a:'1',
}
})
let guestChart = this.data.guestChart;
// 是否已渲染
const rendered = guestChart.rendered;
guestChart.rendered = true;
guestChart.data = datas;
clearInterval(guestChart.updateInterval);
guestChart.updateInterval = -1;
this.setData({ guestChart });
// 获取 chart 实例
const chartIns = this.selectComponent('#guestChart');
// 初次加载可能存在 chartIns.chart 实例不存在问题,循环判断在正确获取到实例后渲染
let updateInterval = setInterval(() => {
if (chartIns && chartIns.chart) {
chartIns.chart.changeData(datas);
if (rendered) {
chartIns.chart.repaint();
} else {
chartIns.chart.render();
}
clearInterval(updateInterval);
guestChart.updateInterval = -1;
}
}, 500);
guestChart.updateInterval = updateInterval;
},
结果展示:
条形图
<f2 id="occChart" class="chart-view__f2" onInit="{{onInitOccChartLineChart}}" />
page({
data:{
// 出租率分析
occChart: {
// 分类数据
data: [],
// 是否已渲染
rendered: false,
// 渲染图表 interval 标识
updateInterval: -1
},
onInitOccChartLineChart(F2, config){
const data = [];
config.appendPadding = [11, 11, 8, 11];
const chart = new F2.Chart(config);
chart.source(data, {
room_night: {
tickCount: 5
}
});
chart.legend(false);
chart.tooltip({
// 不展示记录前的 marker
showItemMarker: true,
showTitle: true,
layout: 'vertical',
onShow(obj) {
const items = obj.items;
items[0].name = items[0].title;
items[0].value = items[0].value
}
})
chart.coord({
transposed: true
});
chart.interval().position('rName*rNight');
chart.render();
return chart;
},
}
})
/**
* 渲染“出租率分析”条形图
*/
renderRealOccChart:function(){
const realNs = this.data.realNights
const len = realNs.length
let datas = realNs?.map((item, i) => {
item.rName = realNs[len - i - 1]?.name
item.rNight = realNs[len - i - 1]?.room_night
return item
});
let occChart = this.data.occChart;
// 是否已渲染
const rendered = occChart.rendered;
occChart.rendered = true;
occChart.data = datas;
clearInterval(occChart.updateInterval);
occChart.updateInterval = -1;
this.setData({ occChart });
// 获取 chart 实例
const chartIns = this.selectComponent('#occChart');
// 初次加载可能存在 chartIns.chart 实例不存在问题,循环判断在正确获取到实例后渲染
let updateInterval = setInterval(() => {
if (chartIns && chartIns.chart) {
chartIns.chart.changeData(datas);
if (rendered) {
chartIns.chart.repaint();
} else {
chartIns.chart.render();
}
clearInterval(updateInterval);
occChart.updateInterval = -1;
}
}, 500);
occChart.updateInterval = updateInterval;
},
结果展示: