背景
在做看板项目时,视觉想要实现如下的柱状图效果
需要做到几个交互点:
- 一页只显示部分内容,支持翻页查看其它数据。
- 右侧需要有个蒙层(或者按钮)提示用户还可以翻页,翻到底部或者数据只有一页时不显示遮罩。
- 翻页的动作由鼠标拖拽或手指触摸触发。
为了实现上述功能点,我们需要 g2 提供或自己手动实现以下相应的需求:
- 能够分页展示数据
- 能够监听鼠标和手指拖拽事件,控制页数变化,然后触发图表绘制当前页。
- 能够获取到当前页码和总页数,判断是否显示遮罩和是否已翻到最后一页
为了实现上述需求,我调研了 g2 自带的滚动条组件,结合业务方补充相应的控制逻辑,最终达到了视觉需要的效果。
g2 滚动条
g2 在官方文档中给出了滚动条的解决方案,实际使用效果如下:
可以看到,该滚动条功能可以实现需求点 1——能够分页显示数据和需求点 2 的一部分要求——控制页数变化更新当前页数据。但是,g2 只是提供 scrollbar 配置用以开放滚动条组件,让用户通过拖拽滚动条实现翻页效果。当前页和总页数的数据、绘制当前数据的逻辑和滚动条组件监听鼠标拖拽事件的逻辑都是在 scrollbar 内部实现的。用户并不能简单地通过官方文档拿到对应的数据。
为此,我们仍然需要在 g2 滚动条的基础上,在业务层进行控制。
业务层实现
scrollbar 的相关源码逻辑在@antv/component/scrollbar 中,首先我们可以很快地找到滚动条组件的相关属性:
export interface ScrollbarCfg extends GroupComponentCfg {
// scrollBar 的位置
x: number;
y: number;
// 滚动条的布局,横向 | 纵向, 非必传,默认为 false(纵向)
isHorizontal?: boolean;
// 滑道长度,必传
trackLen: number;
// 滑块长度,必传
thumbLen: number;
// 滑块的最小长度,非必传,默认值为 20
minThumbLen?: number;
// 滑块相对滑道的偏移, 非必传,默认值为 0
thumbOffset?: number;
// 滚动条样式,非必传
theme?: ScrollbarTheme;
minLimit?: number;
maxLimit?: number;
}
export class Scrollbar extends GroupComponent<ScrollbarCfg> implements ISlider {
public cfg: ScrollbarCfg;
...
}
通过上述属性,我们可以通过下面两个公式判断遮罩的显示逻辑:
初始化时是否需要翻页:滑轨长度是否等于滑块长度 Math.abs(thumbLen - trackLen) < 1e-5
是否已经翻到最后一页:滑块长度加上滑块相对于滑轨的偏移量是否等于滑轨长度 Math.abs(thumbLen + thumbOffset