目錄:javascript
一、前言java
二、背景android
三、組件效果展現git
四、sample解析github
五、library解析post
前言url
本組件是基於安卓平臺的圖表繪製組件MPAndroidChart( https://github.com/PhilJay/MPAndroidChart),實現了其核心功能的鴻蒙化遷移和重構。目前代碼已經開源到(https://gitee.com/isrc_ohos/mpandroid-chart_ohos),歡迎各位下載使用並提出寶貴意見!spa
背景.net
安卓版本的MPAndroidChart在GitHub上有超過3.3萬個Star和8.3k個Fork,應該說是目前使用最廣,體驗最佳的開源圖表庫。它具繪製折線圖、餅圖、雷達圖等圖表的能力,用戶只須要本身寫一個數據接口,便可實現各類精美數據曲線的繪製,在必定程度上知足了大部分業務的需求。
本組件是MPAndroidChart的鴻蒙化版本,名爲MPAndroidChart_ohos,實現了其核心功能。
組件效果展現
目前MPAndroidChart_ohos具備折線圖和直方圖兩種圖表繪製能力。下面將分別展現其折線圖和直方圖的繪製效果。
一、折線圖
圖1展現了一個由隨機數據生成的折線圖。MPAndroidChart_ohos繼承了原版MPAndroidChart的優秀特性,提供了多種多樣的用戶自定義接口,例如:
(1) X、Y軸自定義。使用者能夠自定義X、Y軸的位置,例如在這個sample裏就繪製了左Y軸和上X軸。
(2)輔助線自定義。使用者能夠選擇是否顯示輔助線(或格點線),也能夠自由設定輔助線的位置。
(3)圖表美化。使用者能夠設置圖表曲線的各類屬性(顏色、粗細等),還能夠對曲線包裹區域進行填充。
圖1 折線圖繪製效果
二、直方圖
圖2是基於假設場景「2020年1月1日 ~ 15日的小賣部收益狀況」繪製的圖表。基於這個背景,使用MPAndroidChart_ohos製做了一張直方圖。
圖2 直方圖繪製效果
Sample解析
圖3 Sample工程結構
圖1和圖2主要依靠調用Library中的能力繪製,在Sample中的實現主要由圖3中紅框所示的兩個文件來完成。
若是用戶想要繪製圖表,只須要完成如下幾個步驟便可:
(1)選擇圖表種類。
(2)設置屬性。
(3)導入數據。
一、 選擇圖表種類
MPAndroidChart_ohos提供了折線圖和直方圖的繪製能力,使用者只須要根據自身需求選擇須要使用的能力便可。
LineChart chart = new LineChart(context); //折線圖的初始化 BarChart chart = new BarChart(context); // 直方圖的初始化
二、設置屬性
MPAndroidChart_ohos提供了圖表樣式自定義的能力,使用者能夠經過調用Library暴露的接口來給圖表添加、修改、刪除各項屬性。例如使用者想要自定義軸線,能夠經過實例化XAxis 類的對象,而後經過對象的各類方法實現修改X軸的顏色,設置最大值、最小值等:
XAxis xAxis = chart.getXAxis(); // 實例化 xAxis.setAxisMaximum(20f); //屬性設置 xAxis.setAxisMinimum(0f); xAxis.setAxisLineColor(Color.BLACK.getValue());
除了軸線設置之外還能夠在圖表中加入各類輔助線,例如想要在x = 2處添加一條輔助線,能夠經過實例化LimitLine 類的對象,而後經過對象的各類方法實現修改輔助線的寬度、標籤位置、文本大小等:
LimitLine llXAxis = new LimitLine(2f, "輔助線:x=2"); // 實例化 llXAxis.setLineWidth(4f); //屬性設置 llXAxis.setLabelPosition(LimitLabelPosition.RIGHT_BOTTOM); llXAxis.setTextSize(10f); llXAxis.setTypeface(Font.DEFAULT);
三、導入數據
在MPAndroidChart_ohos中,不一樣類型的圖表有着不一樣的數據類,例如折線圖的數據類爲LineData,直方圖的數據類爲BarData,爲何不能僅僅經過一個簡單int[]或者float[]做爲數據類呢?這是由於在MPAndroidChart_ohos中數據類的做用不只僅是承載數據,同時還須要承載一些圖表相關的屬性,例如曲線顏色、曲線粗細、數據點顏色、大小等,這樣作的意圖在後續Library分析時會講到。
以折線圖爲例,導入數據的過程以下:
(1)建立LineDataSet類:
LineDataSet set1 = new LineDataSet(values, label);
其中values是使用者想要繪製的一類數據,通常是float[],label是這類數據的標籤。
(2)將一類或者幾類數據放置到一個ArrayList中
ArrayList<ILineDataSet> dataSets = new ArrayList<>(); dataSets.add(set1);
(3)將ArrayList作成LineData數據類,並傳遞給chart
LineData data = new LineData(dataSets); chart.setData(data);
Library解析
一、工程結構對比
圖 4 MPAndroidChart_ohos(上)與MPAndroidChart (下)的工程結構對比
從圖4中的兩張圖的對比能夠看出,MPAndroidChart_ohos是按照MPAndroidChart工程的結構開發的,實現了其主要功能。相較於MPAndroidChart,雖然MPAndroidChart_ohos缺乏exception、highlight、jobs這幾個文件夾,但並不影響其主要功能的使用。
二、多設備適配
爲了增長多設備適配性,MPAndroidChart內部以dp(density independent pixels)爲單位來計算圖表中各個部件的相對位置,在繪製圖表時,統一將dp數據轉化爲pixel數據,在這個過程當中就須要系統提供一些顯示信息。在安卓中,這些信息由DisplayMetrics來提供,以下代碼能夠經過上下文獲取到DisplayMetrics:
Resources res = context.getResources(); mMetrics = res.getDisplayMetrics();
接下來經過DisplayMetrics能夠獲取到屏幕的DPI,dp * DPI即爲屏幕的pixel:
public static float convertDpToPixel(float dp) { return dp * mMetrics.density; }
在鴻蒙系統中,顯示信息經過DisplayAttribute類來獲取,如下代碼能夠獲取到DisplayAttribute:
Display display = DisplayManager.getInstance().getDefaultDisplay(this.getContext()).get(); DisplayAttribute displayAttribute = display. getAttributes()
能夠看出與安卓仍是有些許不一樣的。獲得DisplayAttribute後便可獲得屏幕DPI,須要注意的是表明DPI的接口與安卓不一樣:
public static float convertDpToPixel(float dp) { return dp * mMetrics.densityPixels; }
三、軸線繪製
軸線是一張圖的基準,在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類從名字上看也容易得知是在一些特殊圖表上繪製軸線用的。
四、數據繪製
圖6 折線圖相關的數據類
在Sample解析中提到對於不一樣類型的圖表,須要不一樣的數據類去承載數據和屬性。數據類的繼承關係是MPAndroidChart中比較複雜的一部份內容,舉一個例子來講,咱們繪製折線圖所需的LineData類,它繼承自:
public class LineData extends BarLineScatterCandleBubbleData<ILineDataSet> {
類名有點長,不過不要緊,繼續向下尋找:
public abstract class BarLineScatterCandleBubbleData<T extends IBarLineScatterCandleBubbleDataSet<? extends Entry>> extends ChartData<T> {
ChartData類應該就是根了:
public abstract class ChartData<T extends IDataSet<? extends Entry>> {
看似三級繼承關係並不算多,可是值得注意的是期間須要實現的接口和泛型參數是很是多的,這些接口和泛型每每還都能繼續向下嵌套好多層,這着實給移植工做帶來了一些困難。下面來看看這些數據類是作什麼的。
ChartData類是數據類的基類,在其中首先定義了數據的上界和下界分別是浮點數所能表明的最大和最小值,同時該類提供了一些數據處理方法,例如若是發現任何數超過了上、下界,都將這些數強制賦值爲上、下界,避免溢出帶來的數據錯誤。同時這個類還提供了諸如查詢數據點個數、查詢數據X、Y值、查詢標籤、查詢最大、最小值等數據查詢方法。
BarLineScatterCandleBubbleData和LineData分別是對ChartData的一次和二次封裝,自己並無添加任何方法,只是經過實現接口與各類泛型參數對存入其中的數據格式加以限制。
圖 7 折線圖的繪製類
那麼數據點和曲線是如何繪製到圖表中的?DataRenderer是數據繪製的基類,其中寫出了繪製數據、曲線、標籤等的抽象方法。繼續以折線圖爲例,這些抽象方法將在DataRendereràBarLineScatterCandleBubbleRendereràLineScatterCandleRadarRendereràLineRadarRendereràLineChartRenderer這個繼承路徑中被逐步實現,最終LineChartRenderer實現了繪製折線圖的所有能力。
項目貢獻人
吳聖垚 鄭森文 朱偉 陳美汝 張馨心
做者:朱偉ISRC
想了解更多內容,請訪問51CTO和華爲合做共建的鴻蒙社區:https://harmonyos.51cto.com