native react 可伸缩背景_React Native下基于victory-native实现可缩放图表

我司的一个心率图需求 :

每5分钟采一个点,那么一天1440分钟,大概会有288个数据点, 所以在app上基本就是1dp 对应 1个数据点,看起来密密麻麻的,使用静态图表展示确实不够友好,这种情况下原本 react-native-svg-charts 这个库就无法满足需求了。

这个时候我有两个选择 :

- 使用第三方库

- 基于 `svg + d3` 手撸一个

项目中是自己手撸的,在iphone6下还是比较卡顿,那低端安卓机就不用讲了,能优化的都优化了,尽力了。

最近空下来。就试着尝试用 victory-native 这个库实现了一遍

先来介绍下这个库吧,从这个库的官网来看,是一个叫 FormidableLabs 的组织,开源了web端的基于svg实现的react图表库,该库能够交互式动态展现图表,可以说功能非常强大,然后他们在此基础上又推出了react-native的兼容版,强大之处就是缩放类功能完美移植。

最终效果图

简单来说,用victory-native构建一个图表

1、第一步就是用 VictoryChart包裹

{...}

2、要实现缩放,那么第二步则是

minDomain={{ x: 0 }}

maxDomain={{ x: 1440 }}

containerComponent={

zoomDimension="x"

onZoomDomainChange={this.handleDomainChange}

zoomDomain={{ x: xDomain, y: yDomain }}

minimumZoom={minimumZoom}

clipContainerComponent={

clipPadding={{ top: 10, right: 10, bottom: 10, left: 10 }}

/>

}

onTouchStart={(evt) => {

this.locationX = evt.nativeEvent.locationX;

}}

/>

}

>

{...children...}

说明

1、VictoryChart的 minDomain 和 maxDomain 一定要指定因为它能够确定图表最大的Domain

在数据点为空的情况下也能按正常情况缩放

2、容器指定为 VictoryZoomContainer

zoomDimension 指定需要缩放的轴系

onZoomDomainChange 缩放过程的响应回调

zoomDomain 指定图表初始显示的x轴和y轴 范围

minimumZoom 指定缩放的最小间距

clipContainerComponent 由于标记数据点可能被默认ClipPath

截断,所以根据自身情况添加一定 clipPadding使图表完全展现

onTouchStart 触摸开始的回调,可以用于实现自定义 tip

3、有了事件响应容器之后,就需要添加 X轴 和 Y轴

containerComponent={

}

>

axisComponent={} />}

tickFormat={this.xTickFormat}

style={{

grid: {

stroke: 'gray',

strokeDasharray: '5 5',

},

}}

/>

dependentAxis

axisComponent={} />}

style={{

grid: {

stroke: 'gray',

strokeDasharray: '5 5',

},

}}

/>

{...children...}

说明

1、由于 VictoryAxis 的 tickValues 官方默认只接受 数组 类型

则需要添加 WrapperComponent 接受一个函数来自定义 轴 的label 显示

2、若想不显示坐标系的坐标线,需要将axisComponent的LineSegment的lineComponent置为 ()=>null 的组件

3、通过style.grid来设置网图的样式,符合svg标准

4、dependentAxis ture表示Y轴,false表示X轴

4、添加曲线以及渐变色之后

containerComponent={

}

>

data={this._data}

interpolation="monotoneX"

style={{

data: {

stroke: lineColor,

strokeWidth: lineStroke,

fill: LinearGradient.fill,

},

}}

/>

data={this._data}

style={{ data: { stroke: lineColor, fill: lineColor } }}

/>

{...children...}

说明

1、添加一个LinearGradient 产生渐变效果,符合svg标准

2、interpolation monotoneX 曲线方式连接点,没有偏差

3、Area用来产生曲线以及下边沿的背景色,Scatter用于生成对应点

5、添加一个自定义的指示控件

containerComponent={

}

>

说明

自定义实现一个 指示控件,具体实现方式可以滑到 本文最后 github的demo地址

最终的总体结构是这样的

minDomain={{ x: 0 }}

maxDomain={{ x: 1440 }}

containerComponent={

zoomDimension="x"

onZoomDomainChange={this.handleDomainChange}

zoomDomain={{ x: xDomain, y: yDomain }}

minimumZoom={minimumZoom}

clipContainerComponent={

clipPadding={{ top: 10, right: 10, bottom: 10, left: 10 }}

/>

}

onTouchStart={(evt) => {

this.locationX = evt.nativeEvent.locationX;

}}

/>

}

>

axisComponent={} />}

ickFormat={this.xTickFormat}

style={{

grid: {

stroke: 'gray',

strokeDasharray: '5 5',

},

}}

/>

dependentAxis

axisComponent={} />}

style={{

grid: {

stroke: 'gray',

strokeDasharray: '5 5',

},

}}

/>

data={this._data}

interpolation="monotoneX"

style={{

data: {

stroke: lineColor,

strokeWidth: lineStroke,

fill: LinearGradient.fill,

},

}}

/>

data={this._data}

style={{ data: { stroke: lineColor, fill: lineColor } }}

/>

this} />

尝试了一番,在iphone6下还是卡顿,所以我之前手撸的纯js控件是真的尽力了。感觉是这个js回调机制还是耗能,对低端设备有高要求的同学还是手撸一个定制化原生控件,封装给RN层傻瓜式调用吧

对于victoryNative这个库的槽点就是文档偏少,官方给的案例都带点 案例仅供参考的感觉,上起手来偏生硬吧。不过确实是RN端图表类的一个解决方案。

以前看别人的博文,行云流水一气呵成,从来没考虑过会花多少时间,而当自己真心去总结的时候发现,篇幅再短可能都不止1个小时。

愿明天是 新的一天,大步走向前。─=≡Σ(((つ•̀ω•́)つ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值