博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
y轴数据变换利器——yaxis-transformer
阅读量:7052 次
发布时间:2019-06-28

本文共 2800 字,大约阅读时间需要 9 分钟。

仓库

yaxis-transformer已经发布到npm, , 欢迎star。

前言

前不久笔者分享过的基本思路,当时需求比较紧张,苦于没有时间去整理代码。现在刚好空闲下来,回头看看之前的代码,发现存在几个问题:业务侵入性太强, 定制化能力太弱和方案设计不够合理。所以决定这一次趁热打铁,对整个方案重新设计,将y轴的数据变换能力抽成底层功能库,并且提供足够强的定制化能力。这样的好处是可以移出之前的业务逻辑代码,避免库逻辑混乱和过于累赘,将业务逻辑的处理转交给使用者。

分析

整个方案大致可以分四个步骤:

  • 处理最小值minData,找出规整间距interval,计算最大值maxData;
  • 找出需要格式化的单位unit;
  • 计算建议小数位数adviseDecimal;
  • 生成最终结果transformResult。

1. 数据处理

以下例子使用的count=3,即总共生成四个数据。

  • 首先是处理最小值minData, 首先根据原始的interval得到规整的基准值baseInterval, baseInterval的作用是找出minData需要处理的部分remainPart,例如minData为1542,baseInterval为200,那么可知remainPart为542,接着再对remainPart进行查找基准值的操作,假定结果为500,那么处理之后的minData就为1000 + 500 = 1500。

  • 找出规整间距interval,根据前面处理的minData和原始的maxData,再根据基准值生成的策略得到新的间距,如minData=1000, maxData=6100, interval=1700, 生成的基准值数组为1000, 2000, 5000, 生成的策略如下:

defaultBaseGenStrategy = (originInterval: number) =>  {        let base = AxisHelper.genPowNum(originInterval)        return [10 * base, 5 * base, 2 * base, base]  }复制代码

那对于间距来说,需要取出第一个比它大的数,所以可算出interval就是2000。

  • 最大值就等于 minData + count * interval

2. 找出格式化单位

通常会预设一组用于格式化的单位,例如:[{range: 10000, unit: "万"}, {range: 100000000, unit: "亿"}]

如果超过range,则使用相对应的unit。
特别地,对于百分数的情况使用的单位如下:{range:0.01, unit:"%"}
对于单位的格式化,主要在于使用哪个值用来做单位的查找,因此我提供了maxData和minData两种选择。

3. 计算建议小数位数

所以建议的小数位数,我这里的定义是指在单位unit的格式化下,仍然能完整显示出所有有效的小数位数。例如一组数据[100, 10100, 20100],单位是{range: 10000, unit: "万"}, 那么建议的小数位数就是2,这样格式化出来的数据就是[0.01万, 1.01万,2.01万]。

关键的地方在于找出最小值min和参考值reference,最小值是为了保证有效的数据输出,而reference则是min用于参考的值。如上,min为100,reference为20100, 那么单位就为万,小数位数为2。

4. 生成结果

当完成上述步骤,结果就已经呼之欲出。最后就是生成相应的数组,格式大致如下:

{   data: [0, 10000, 20000, 30000],   dataUnit: ['0.00', '1.00万', '2.00万', '3.00万'],    adviseDecimal: 1  }复制代码

使用

const yaxisTransformer = new YaxisTransformer([1542, 6100])    let transformResult  = yaxisTransformer     .withCount(3)     .withMinToZero(false)     .withUnitFollowMax(false)     .withFormatRuler((data, decimal) => {         return data.toFixed(decimal)     })     .withUnitSet([{range:10000, unit:"万"}])     .transform()复制代码

通过建造者模式,增加灵活的定制化配置,目前有的配置如下:

  • withCount 设置生成间距的数量,四个数的数组count即为3
  • withUnitSet 设置格式化单位,默认为 [{range: 10000, unit: "万"}, {range: 100000000, unit: "亿"}]
  • withPercentUnit 使用百分比做格式化
  • withMinMaxData 设置最大值最小值
  • withBaseGenStrategy 设置基准值生成策略,默认为
defaultBaseGenStrategy = (originInterval: number) =>  {        let base = AxisHelper.genPowNum(originInterval)        return [10 * base, 5 * base, 2 * base, base]  }复制代码
  • withFormatRuler 设置格式化小数位数的规则,默认为 number.toFixed(decimal)

  • withForceDecimal 强制设置小数位数

  • withKeepZeroUnit 是否保留0的单位

  • withKeepUnitSame 数组里的每个值单位是否保持单位一致

  • withUnitFollowMax 格式化的单位否是参考最大值

  • withMinToZero 最小值< 间距时,是否取0, 如min=100,interval为1000,是否令min = 0

  • withKeepZeroDecimal 是否保持0的小数位数,如0.00是否格式化为0

提供了大量能想到用以配置的属性。

总结

对于底层通用库,亟需遵守开闭原则,对扩展开放,对修改封闭,对于npm的库,天然就是封闭的,所以开放就需要提供足够的定制化能力,减少自己业务逻辑的侵入。

致谢

转载于:https://juejin.im/post/5d0a43cc6fb9a07ebb053842

你可能感兴趣的文章
模拟jquery底层链式编程
查看>>
如何实现Qlikview的增量数据加载
查看>>
Notepad++ 代码格式化
查看>>
裁切图片,
查看>>
[转]跟我一起写 Makefile
查看>>
作业-继承5
查看>>
修改 android 的 framework 层操作小记.转载
查看>>
图片鼠标滑过图片半透明(jquery特效)
查看>>
windows下安装和配置mongoDB
查看>>
最新工作积累记录
查看>>
java初始化构造函数调用顺序
查看>>
swift 之xib自定义view可视化到storyboard
查看>>
抓包工具fiddler
查看>>
系统引导一些区别
查看>>
leetcode 189. Rotate Array
查看>>
C# 保留2位小数
查看>>
画caffe训练loss曲线
查看>>
笔试题 (三)
查看>>
fastjson生成JSON字符串的时候出现$ref [转]
查看>>
[SpringBoot] - 发送带附件的邮件
查看>>