目錄:
前言
本組件是基於安卓平台的圖表繪制組件MPAndroidChart( https://github.com/PhilJay/MPAndroidChart)
實現了其核心功能的鴻蒙化遷移和重構。目前代碼已經開源到(https://gitee.com/isrc_ohos/mpandroid-chart_ohos)
歡迎各位下載使用並提出寶貴意見!
背景
安卓版本的MPAndroidChart在GitHub上有超過3.3萬個Star和8.3k個Fork,應該說是目前使用最廣,體驗最佳的開源圖表庫。它具繪制折線圖、餅圖、雷達圖等圖表的能力,用戶只需要自己寫一個數據接口,即可實現各種精美數據曲線的繪制,在一定程度上滿足了大部分業務的需求。
本組件是MPAndroidChart的鴻蒙化版本,名為MPAndroidChart_ohos,實現了其核心功能。
組件效果展示
目前MPAndroidChart_ohos具有折線圖和直方圖兩種圖表繪制能力。下面將分別展示其折線圖和直方圖的繪制效果。
1、折線圖
圖1展示了一個由隨機數據生成的折線圖。MPAndroidChart_ohos繼承了原版MPAndroidChart的優秀特性,提供了多種多樣的用戶自定義接口,例如:
(1) X、Y軸自定義。使用者可以自定義X、Y軸的位置,例如在這個sample里就繪制了左Y軸和上X軸。
(2)輔助線自定義。使用者可以選擇是否顯示輔助線(或格點線),也可以自由設定輔助線的位置。
(3)圖表美化。使用者可以設置圖表曲線的各種屬性(顏色、粗細等),還可以對曲線包裹區域進行填充。
圖1 折線圖繪制效果
2、直方圖
圖2是基於假設場景“2020年1月1日 ~ 15日的小賣部收益情況”繪制的圖表。基於這個背景,使用MPAndroidChart_ohos制作了一張直方圖。
圖2 直方圖繪制效果
Sample解析
圖3 Sample工程結構
圖1和圖2主要依靠調用Library中的能力繪制,在Sample中的實現主要由圖3中紅框所示的兩個文件來完成。
如果用戶想要繪制圖表,只需要完成以下幾個步驟即可:
(1)選擇圖表種類。
(2)設置屬性。
(3)導入數據。
1、 選擇圖表種類
MPAndroidChart_ohos提供了折線圖和直方圖的繪制能力,使用者只需要根據自身需求選擇需要使用的能力即可。
2、設置屬性
MPAndroidChart_ohos提供了圖表樣式自定義的能力,使用者可以通過調用Library暴露的接口來給圖表添加、修改、刪除各項屬性。例如使用者想要自定義軸線,可以通過實例化XAxis 類的對象,然后通過對象的各種方法實現修改X軸的顏色,設置最大值、最小值等:
除了軸線設置以外還可以在圖表中加入各種輔助線,例如想要在x = 2處添加一條輔助線,可以通過實例化LimitLine 類的對象,然后通過對象的各種方法實現修改輔助線的寬度、標簽位置、文本大小等:
3、導入數據
在MPAndroidChart_ohos中,不同類型的圖表有着不同的數據類,例如折線圖的數據類為LineData,直方圖的數據類為BarData,為什么不能僅僅通過一個簡單int[]或者float[]作為數據類呢?這是因為在MPAndroidChart_ohos中數據類的作用不僅僅是承載數據,同時還需要承載一些圖表相關的屬性,例如曲線顏色、曲線粗細、數據點顏色、大小等,這樣做的意圖在后續Library分析時會講到。
以折線圖為例,導入數據的過程如下:
(1)創建LineDataSet類:
其中values是使用者想要繪制的一類數據,一般是float[],label是這類數據的標簽。
(2)將一類或者幾類數據放置到一個ArrayList中
(3)將ArrayList做成LineData數據類,並傳遞給chart
Library解析
1、工程結構對比
圖 4 MPAndroidChart_ohos(上)與MPAndroidChart (下)的工程結構對比
從圖4中的兩張圖的對比可以看出,MPAndroidChart_ohos是按照MPAndroidChart工程的結構開發的,實現了其主要功能。相較於MPAndroidChart,雖然MPAndroidChart_ohos缺少exception、highlight、jobs這幾個文件夾,但並不影響其主要功能的使用。
2、多設備適配
為了增加多設備適配性,MPAndroidChart內部以dp(density independent pixels)為單位來計算圖表中各個部件的相對位置,在繪制圖表時,統一將dp數據轉化為pixel數據,在這個過程中就需要系統提供一些顯示信息。在安卓中,這些信息由DisplayMetrics來提供,如下代碼可以通過上下文獲取到DisplayMetrics:
接下來通過DisplayMetrics可以獲取到屏幕的DPI,dp * DPI即為屏幕的pixel:
在鴻蒙系統中,顯示信息通過DisplayAttribute類來獲取,以下代碼可以獲取到DisplayAttribute:
可以看出與安卓還是有些許不同的。得到DisplayAttribute后即可得到屏幕DPI,需要注意的是代表DPI的接口與安卓不同:
3、軸線繪制
軸線是一張圖的基准,在MPAndroidChart中,軸線甚至作為了圖表種類的分類基准!看似MPAndroidChart提供了十余種圖表繪制的能力,其實這十余種圖表是依托於兩種軸線制作的,這兩種軸線分別是平面直角坐標系和極坐標系。
在直角坐標系下,MPAndroidChart實現了折線圖、散點圖、直方圖、氣泡圖、蠟燭圖等。
在極坐標系下,MPAndroidChart實現了餅圖、雷達圖。
在MPAndroidChart_ohos中,和軸線相關的類主要分布在components文件夾和renderer文件夾中:
圖5 軸線類與軸線繪制類
其中AxisBase類主要定義了軸應具備的屬性,例如顏色、粗細、位置、刻度、標簽、最值等。XAxis和YAxis繼承自AxisBase,並分別定義了X、Y軸所應具備的屬性,例如:X軸的位置屬性應是“Top”、“BOTTOM”、“TOP_INSIDE”、“BOTTOM_INSIDE”或“BOTH_SIDED”中的一種;而Y軸與X軸不同,其位置屬性應為“LEFT”或“RIGHT”。
AxisRenderer類是繪制軸線的基類,其定義了繪制軸線所必備的屬性和方法,例如用於繪制軸線、標簽、輔助線、格點的幾種畫筆(Paint)和對應的方法接口。XAxisRenderer和YAxisRenderer繼承自AxisRenderer,實現了其中用於繪制的接口,真正實現了軸線的繪制。其他的諸如XAxisRenderHorizontalBarChart類從名字上看也容易得知是在一些特殊圖表上繪制軸線用的。
4、數據繪制
圖6 折線圖相關的數據類
在Sample解析中提到對於不同類型的圖表,需要不同的數據類去承載數據和屬性。數據類的繼承關系是MPAndroidChart中比較復雜的一部分內容,舉一個例子來說,我們繪制折線圖所需的LineData類,它繼承自:
類名有點長,不過沒關系,繼續向下尋找:
ChartData類應該就是根了:
看似三級繼承關系並不算多,但是值得注意的是期間需要實現的接口和泛型參數是非常多的,這些接口和泛型往往還都能繼續向下嵌套好多層,這着實給移植工作帶來了一些困難。下面來看看這些數據類是做什么的。
ChartData類是數據類的基類,在其中首先定義了數據的上界和下界分別是浮點數所能代表的最大和最小值,同時該類提供了一些數據處理方法,例如如果發現任何數超過了上、下界,都將這些數強制賦值為上、下界,避免溢出帶來的數據錯誤。同時這個類還提供了諸如查詢數據點個數、查詢數據X、Y值、查詢標簽、查詢最大、最小值等數據查詢方法。
BarLineScatterCandleBubbleData和LineData分別是對ChartData的一次和二次封裝,本身並沒有添加任何方法,只是通過實現接口與各種泛型參數對存入其中的數據格式加以限制。
圖 7 折線圖的繪制類
那么數據點和曲線是如何繪制到圖表中的?DataRenderer是數據繪制的基類,其中寫出了繪制數據、曲線、標簽等的抽象方法。繼續以折線圖為例,這些抽象方法將在DataRendereràBarLineScatterCandleBubbleRendereràLineScatterCandleRadarRendereràLineRadarRendereràLineChartRenderer這個繼承路徑中被逐步實現,最終LineChartRenderer實現了繪制折線圖的全部能力。
項目貢獻人
吳聖垚 鄭森文 朱偉 陳美汝 張馨心
作者:朱偉ISRC
想了解更多內容,請訪問51CTO和華為合作共建的鴻蒙社區:https://harmonyos.51cto.com