@Antv F2双柱状图和折线图的混合写法
第一次写博客,原因很简单,来公司后要学习F2,除了官方api发现网上对这个介绍很少,刚好今天遇到双柱图和折线图写法,捣鼓了好久才明白,打算记录在博客中。
import F2 from '@antv/wx-f2';
let chart = null;
// 数值显示在柱状图上方得自定义图形,具体参加官方api
var Shape = F2.Shape;
var Util = F2.Util;
// 自定义图形:interval指定义的类型可以是三角形,此处是柱状图
Shape.registerShape('interval', 'text', {
// draw:是个方法,里面俩参数固定
draw: function draw(cfg, container) {
// 通过此方法获取绘制图形的关键点
var points = this.parsePoints(cfg.points);
// Util.mix方法:浅拷贝
var style = Util.mix({
fill: cfg.color,
z: true // 需要闭合
}, cfg.style);
// rect:interval提供的内置shape类型具体参考 https://www.yuque.com/antv/f2/geometry
var intervalShape = container.addShape('rect', {
attrs: Util.mix({
x: points[1].x,
y: points[1].y,
width: points[2].x - points[1].x,
height: points[0].y - points[1].y
}, style)
});
// // 获取对应的原始数据记录
var origin = cfg.origin._origin;
// 添加到容器中不然无法渲染
var textShape = container.addShape('text', {
zIndex: 13,
// text:显示在柱状图上方文本样式
attrs: {
x: (points[1].x + points[2].x) / 2,
y: points[1].y - 5, // 往上偏移 5 像素
text: origin['sales'],
fill: '#808080',
textAlign: 'center',
textBaseline: 'bottom',
fontSize: 10 // 字体大小
}
});
// 返回渲染内容
container.sort();
return [intervalShape, textShape];
}
});
// 开始绘制图表
function initChart(canvas, width, height, F2) { // 使用 F2 绘制图表
const data = [
// 混合图的关键:数据要对应,type为区分同一name下不同数值;totalSales指折线图数值,这里要注意同一个name下要写一样的
{type: "blue", name: '舒悦', sales: 138, totalSales: 176 },
{type: "gray", name: '舒悦', sales: 38, totalSales: 176},
{type: "gray", name: '夏玲', sales: 152, totalSales: 204},
{type: "blue", name: '夏玲', sales: 52, totalSales: 204 },
{type: "blue", name: '张三', sales: 61, totalSales: 112},
{type: "gray", name: '张三', sales: 51, totalSales: 112},
{type: "blue", name: '李四', sales: 145, totalSales: 112},
{ type: "gray", name: '李四', sales: 45, totalSales: 112},
{type: "blue", name: '网二', sales: 48, totalSales: 190},
{type: "gray", name: '网二', sales: 60, totalSales: 190},
{ type: "blue", name: '超肥', sales: 38, totalSales: 108 },
{ type: "gray", name: '超肥', sales: 50, totalSales: 108},
];
// 创建表格实例
var chart = new F2.Chart({
el: canvas,
// 控制双y轴的出现,返回bool
syncY: true,
width,
height,
});
// 载入数据
chart.source(data, {
// 控制x轴的刻度点
sales: {
tickCount: 6
},
totalSales:{
tickCount: 6
}
});
// 清除图例
chart.legend(false);
// 改变纵轴刻度值
chart.scale("sales", {
min: 0,//手动设置最小值
ticks: [0, 50, 100, 150, 200, 250],
});
// 清除提示信息
chart.tooltip(false);
// 清除网格线
chart.axis("name",{
grid:null,
// 该表坐标轴上文本的样式
label(text) {
return {
fill: '#969696',
fontSize: 12
};
}
})
// 清除y轴上的网格线
chart.axis("sales", {
grid: null,
// 该表坐标轴上的样式
label(text) {
return {
fill: '#969696',
fontSize: 12
};
}
})
chart.interval().position('name*sales').color("type", ["#17BBEF", "#969696"]).shape('text').adjust({
type: 'dodge',
// 控制双柱图的间距
marginRatio: 0.05
});
chart.line().position('name*totalSales').shape('smooth').color();
// 映射加上控制点的样式
chart.point().position('name*totalSales').style({
stroke: '#38AF4A',
fill: '#38AF4A',
// 圆点大小
lineWidth: 1
});
// 渲染
chart.render();
// 返回渲染的图
return chart;
}
如果你认真读完这篇代码将会有很大收获,代码很容易理解,大部分来自官方api文档,最关键的就是数据在同一个一人名下要一致,因为是双柱图。