Androidアプリ開発

MPAndroidChart 折れ線グラフの実装

MPAndroidChart の 折れ線グラフ を グラデーション 表示する
この記事は約26分で読めます。
記事内に広告が含まれています。
スポンサーリンク

この記事は Android スマホ用のアプリ開発の中で、
今後の開発で再使用性が高いと思われるコーディングをまとめたものです。
Java での開発経験、XML 構文規則、Android のアプリ開発経験がある方を対象としています。
Android のアプリ開発でお役にたててれば、嬉しいです。

(これから Android のアプリ開発や Java での開発を始めたい方への案内は、
記事の最後で紹介します)

この記事のテーマ


 MPAndroidChart を使用して、折れ線グラフを実装をする

MPAndroidChart は、Androidアプリでグラフを作るためのオープンソースライブラリです。
Andorid アプリでグラフを描画する場合のベストプラクティスといっても過言ではありません。
非常に多機能で細かい部分まで制御できる素晴らしいライブラリですが、使用方法について、詳しい日本語ドキュメントがなく、機能の一部しか利用されていない、残念な状況です。

MPAndroidChart は、さまざまなグラフを扱うことが可能です。
今回は、折れ線グラフ(
LineChart )にフォーカスを当てて、開発したアプリのソースを参考に、使用方法について説明します。

棒グラフ(BarChart)については、こちらです↓↓↓

円グラフ(PieChart)については、こちらです↓↓↓

散布図(ScatterChart)については、こちらです↓↓↓

MPAndroidChart を使用するための準備

MPAndroidChart を使用するには、プロジェクトおよび、モジュールの build.gradle ファイルに定義の追加が必要です。

◎build.gradle(プロジェクト)

:
allprojects {
    repositories {
    :
        maven { url "https://jitpack.io" }
    }
}
:

◎build.gradle(モジュール)
2022年11月現在の最新バージョンは 3.1.0 です。

dependencies {
    :
    implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
}

◎ライセンス表記
MPAndroidChart は Apache License, Version 2.0 です。
アプリで使用する場合、ライセンス表記が必要です。

ソース提供ではないため、ライセンス条文の記載がある公式サイトのリンクをアプリに実装しています

折れ線グラフ( LineChart )

折れ線グラフは、時系列など連続的な変化を捉えるときに使用するグラフです。
データをX軸に時間、Y軸に測定値を配置して、それぞれのデータを線で結んだグラフです。
MPAndroidChart には、直線で結ぶ方法以外に滑らかな曲線(ベジェ曲線)で結ぶことが可能です。

グラフ表示

MPAndroidChart のグラフ表示は、グラフに表示する折れ線をデータセット( LineDataSet )として作成、グラフ( LineChart )にラインデータ( LineData )を介して、セットします。
グラフの背景、表示範囲、振る舞いなどの属性は、グラフに定義します。
凡例、軸ラベル、線の太さや色などの属性は、データセットに定義します。
複数のデータセットをラインデータにセットすることで、1つのグラフに複数の線グラフを重ねて表示できます。

    private LineChart               acceleration;
    private String[]                labels = new String[]{
            "Speed(GPS)",
            "Longitudinal",
            "Lateral",
            "Pitch",
            "Roll",
            "Locus",
            "Position"};
    private LineDataSet             lineDataSet2X;
    private LineDataSet             lineDataSet2Y;

    :
  // 凡例(ラベル)を設定     
    lineDataSet2X = new LineDataSet(null,labels[2]);
    lineDataSet2Y = new LineDataSet(null,labels[1]);
    :
    // 加速度グラフ
    acceleration = findViewById(R.id.acceleration);
    acceleration.setOnChartGestureListener(new OnChartGestureListener() {
            @Override
            public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
                 // グラフに触れた時の処理
            }
            @Override
            public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {}
            @Override
            public void onChartLongPressed(MotionEvent me) {}
            @Override
            public void onChartDoubleTapped(MotionEvent me) {}
            @Override
            public void onChartSingleTapped(MotionEvent me) {
                // グラフをタップした時の処理
            }
            @Override
            public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {}
            @Override
            public void onChartScale(MotionEvent me, float scaleX, float scaleY) {}
            @Override
            public void onChartTranslate(MotionEvent me, float dX, float dY) {
                // グラフを左右に動かした時の処理 
            }
        });
        :     
   }
    :
    // データセットの属性セット
    lineDataSet2X.clear();
    lineDataSet2X.setColor(getColor(R.color.red));              // 線の色指定
    lineDataSet2X.setDrawCircles(false);                        // 点を描画しない 
    lineDataSet2X.setDrawValues(false);                         // 点の値を表示しない
    lineDataSet2X.setDrawHorizontalHighlightIndicator(false);   // X軸ハイライト線非表示
    lineDataSet2X.setDrawVerticalHighlightIndicator(false);     // Y軸ハイライト線非表示
    lineDataSet2X.setMode(LineDataSet.Mode.CUBIC_BEZIER);       // ベジェ曲線
    lineDataSet2Y.clear();
    lineDataSet2Y.setColor(getColor(R.color.blue600));
    lineDataSet2Y.setDrawCircles(false);
    lineDataSet2Y.setDrawValues(false);
    lineDataSet2Y.setDrawHorizontalHighlightIndicator(false);
    lineDataSet2Y.setDrawVerticalHighlightIndicator(false);
    lineDataSet2Y.setMode(LineDataSet.Mode.CUBIC_BEZIER);
    :
    // データセットをラインデータに追加
    LineData lineData2 = new LineData(lineDataSet2Y);
    lineData2.addDataSet(lineDataSet2X);
    : 
    acceleration.getDescription().setEnabled(false);            // 説明表示なし
    acceleration.setDrawGridBackground(true);                   // 罫線の表示 
    acceleration.setGridBackgroundColor(Color.TRANSPARENT);     // グラフの背景
    acceleration.setData(lineData2);                            // ラインデータをセット
  :
    // データをデータセットに追加
  {
        lineData2.addEntry(new Entry((float) nowTime / 1000, (float) bg[1]), 0);
        lineData2.addEntry(new Entry((float) nowTime / 1000, (float) bg[2]), 1);
  }
    :
    acceleration.setVisibleXRangeMaximum(12);                    // グラフのX軸の表示範囲 
    acceleration.notifyDataSetChanged();
    acceleration.invalidate();                   // グラフの再描画   
    acceleration.setDoubleTapToZoomEnabled(false);         // ダブルタップのズーム無効
  :
 }

X値、Y値、データセットに追加順 を設定したエントリ( Entry )をデータセットに追加( addRntry )します。

Layoutリソース

            <ScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fadeScrollbars="false">
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">
           : 
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="horizontal">
                        <com.github.mikephil.charting.charts.LineChart
                            android:id="@+id/acceleration"
                            android:layout_width="0dp"
                            android:layout_height="264dp"
                            android:layout_weight="1"
                            android:background="@android:color/transparent" />
                        <TextView
                            android:layout_width="16dp"
                            android:layout_height="264dp"
                            android:background="@android:color/transparent" />
                    </LinearLayout>
           :
                </LinearLayout>
            </ScrollView>

複数のグラフを表示、スクロールさせる場合、LinearLayout でグラフを囲み、さらにスクロール領域を ScrollView で囲みます。
スクロールがしやすいようにグラフの右側に
TextView を配置しています。
スクロールバーを常に表示にする場合は、
fadeScrollbars を false に設定します。

MPAndroidChart の折れ線グラフの背景を透過させる方法はこちらです↓↓↓

グラデーション表示

グラフ表示で折れ線の内側を塗りつぶすことが可能です。
塗りつぶす色に Drawableリソースを指定することで、グラデーション表示が可能になります。

MPAndroidChart の 折れ線グラフ を グラデーション 表示する
プラス値は青、マイナス値は赤でグラデーションで塗りつぶしています
    :    
    lineDataSet2Y.setDrawFilled(true);
    lineDataSet2Y.setFillDrawable(getDrawable(R.drawable.mp_grad422));
    :
    acceleration.getAxisLeft().setAxisMinimum(-1.5f);
    acceleration.getAxisLeft().setAxisMaximum(1.5f);
    :

プラス値は青、マイナス値は赤で分離するには、グラフのY軸下限とグラフのY軸上限の 絶対値を同じ にします。

Drawableリソース(mp_grad422)

<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <gradient
        android:angle="270"
        android:startColor="#FF3232B0"
        android:centerColor="#00000000"
        android:endColor="#FFFF5722" />
</shape>

リミット線の表示

グラフの罫線以外に目安となるリミット線( LimitLine )を設定することができます。
各軸で線を引く値を設定したリミット線
LimitLineを作成し、グラフ( LineChart )に追加( addLimitLine )します。
enableDashedLine を使用することで、破線が使用できます。

MPAndroidChart で リミット 線を 破線 で引く
Y軸のリミット線はスライダーで調整できるよう実装しています
        :
        // Y軸のリミット線
        LimitLine y= new LimitLine(deceleration ,null);
        y.enableDashedLine(5,3,0);                      // 破線(5:3:0) 
        y.setLineColor(getColor(R.color.grey));         // Limit Lineの色
        y.setLineWidth(1);                              // Limit Lineの太さ
        acceleration.getAxisLeft().addLimitLine(y);     // Y軸に追加
        :
        // X軸のリミット線
        LimitLine x = new LimitLine(start, getString(R.string.start));
        x.setLineColor(getColor(R.color.purple));       // Limit Lineの色
        x.setLineWidth(3);                              // Limit Lineの太さ
        x.setTextSize(10);                              // テキストサイズ
        x.setTextColor(getColor(R.color.grey));         // テキスト色 
        acceleration.getXAxis().addLimitLine(x);        // X軸に追加
        acceleration.moveViewToX(startPos);             // X軸の初期値を設定 
        :

リミット線の作成時、decelerationstart は線を引く値、第2引数にテキスト表示する文字列を指定します。
moveViewToX を使用することでグラフ表示の開始位置を指定できます。

軸ラベルの表示位置と書式

グラフ( LineChart )の軸( Axis )を操作することで、軸ラベルの表示・非表示、位置、書式を設定できます。