yaxis-transformer已經發布到npm, 點擊查看源碼, 歡迎star。git
前不久筆者分享過y軸數據處理方案的基本思路,當時需求比較緊張,苦於沒有時間去整理代碼。如今恰好空閒下來,回頭看看以前的代碼,發現存在幾個問題:業務侵入性太強, 定製化能力太弱和方案設計不夠合理。因此決定這一次趁熱打鐵,對整個方案從新設計,將y軸的數據變換能力抽成底層功能庫,而且提供足夠強的定製化能力。這樣的好處是能夠移出以前的業務邏輯代碼,避免庫邏輯混亂和過於累贅,將業務邏輯的處理轉交給使用者。github
整個方案大體能夠分四個步驟:npm
如下例子使用的count=3,即總共生成四個數據。數組
首先是處理最小值minData, 首先根據原始的interval獲得規整的基準值baseInterval, baseInterval的做用是找出minData須要處理的部分remainPart,例如minData爲1542,baseInterval爲200,那麼可知remainPart爲542,接着再對remainPart進行查找基準值的操做,假定結果爲500,那麼處理以後的minData就爲1000 + 500 = 1500。bash
找出規整間距interval,根據前面處理的minData和原始的maxData,再根據基準值生成的策略獲得新的間距,如minData=1000, maxData=6100, interval=1700, 生成的基準值數組爲1000, 2000, 5000, 生成的策略以下:post
defaultBaseGenStrategy = (originInterval: number) => {
let base = AxisHelper.genPowNum(originInterval)
return [10 * base, 5 * base, 2 * base, base]
}
複製代碼
那對於間距來講,須要取出第一個比它大的數,因此可算出interval就是2000。ui
一般會預設一組用於格式化的單位,例如:[{range: 10000, unit: "萬"}, {range: 100000000, unit: "億"}]
若是超過range,則使用相對應的unit。
特別地,對於百分數的狀況使用的單位以下:{range:0.01, unit:"%"}
對於單位的格式化,主要在於使用哪一個值用來作單位的查找,所以我提供了maxData和minData兩種選擇。spa
因此建議的小數位數,我這裏的定義是指在單位unit的格式化下,仍然能完整顯示出全部有效的小數位數。例如一組數據[100, 10100, 20100],單位是{range: 10000, unit: "萬"}
, 那麼建議的小數位數就是2,這樣格式化出來的數據就是[0.01萬, 1.01萬,2.01萬]。
關鍵的地方在於找出最小值min和參考值reference,最小值是爲了保證有效的數據輸出,而reference則是min用於參考的值。如上,min爲100,reference爲20100, 那麼單位就爲萬,小數位數爲2。設計
當完成上述步驟,結果就已經呼之欲出。最後就是生成相應的數組,格式大體以下:code
{
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即爲3withUnitSet
設置格式化單位,默認爲 [{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的庫,自然就是封閉的,因此開放就須要提供足夠的定製化能力,減小本身業務邏輯的侵入。