web-dev-qa-db-ja.com

mpandroidchart-Y軸で繰り返される値を回避するにはどうすればよいですか?

画像の状況を避けて、Y軸で繰り返される値と-0の値を避けたいと思います。

私はこれを解決するためにこれらのアイデアを持っていますが、どんな解決策もあります:

  1. YAxisで値を繰り返す前に、ズームを制限します。したがって、グラフの無限ズームインを停止します。
  2. YAxis値を取得し、重複する値を削除します。

YAxis with duplicate values

24
rafaelasguerra

tl; drこれを行うには、onChartScaleのラベル数を変更します。

まず、リスナーを設定します。

chart.setOnChartGestureListener(this); // set a listener ;)

上/下の描画値を取得して、画面に何が描画されるかを確認しようとします。いくつかの基本的な計算を適用すれば、準備は完了です。

次のコードは、ズームレベルが(高すぎる)場合は2つのラベルを描画し、それ以外の場合は最大9つのラベルを描画します。

@Override
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
    final YAxis yAxis = mChart.getAxisLeft();
    final Transformer transformer = mChart.getTransformer(YAxis.AxisDependency.LEFT);

    // ...minor dirty hack
    final PointD top = transformer.getValuesByTouchPoint(0, 0);
    final PointD bottom = transformer.getValuesByTouchPoint(0, mChart.getHeight());
    final int diff = (int)(top.y - bottom.y);

    // draw 2-9 axis labels
    final int count = Math.min(9, Math.max(diff, 2));

    Log.d("scale", String.format("scale %f: diff %d and count %d", scaleY, diff, count));

    // "force" the count, for there are drawing issues where none get drawn on high zoom levels (just try it out)
    yAxis.setLabelCount(count, true);
}

// todo implement other interface methods

バリューフォーマッターと他のすべては同じままです。

そして、それが機能することを示すいくつかの醜いスクリーンショット:D

Zoomed in chart with 2 labels

3
David Medenjak

これは古い質問ですが、今後の参考のために追加したいと思います。ライブラリの新しいバージョンには、粒度と呼ばれる、重複したラベルを解決するほとんど知られていない機能があります。これは、古いソリューションよりもはるかに簡単に使用できます(公平を期すために、これらが投稿された時点では利用できませんでした)。

詳細な説明については、いつでも最新の AxisBase Javadocs (3.0.0-beta1)を確認できます。関連する方法は次のとおりです。

  • setGranularity(float granularity) :ズームインするときの軸の最小間隔を設定します。軸がその制限を下回ることはできません。これは、ズームイン時にラベルが重複しないようにするために使用できます。
  • setGranularityEnabled(boolean enabled) :軸値間隔の粒度制御を有効/無効にします。有効にすると、軸間隔が特定の粒度を下回ることはできません。

したがって、あなたの場合、小数点が1つあるため、粒度を0.1fに設定する必要があります。次のコードスニペットは、軸上で繰り返される値を回避する必要があります。

YAxis yAxis = mChart.getAxisLeft();
yAxis.setGranularityEnabled(true);
yAxis.setGranularity(0.1f);
2
TR4Android

このようなコード:

    mchart.setAutoScaleMinMaxEnabled(false);
    mchart.getAxisLeft().setAxisMaxValue(10);
    mchart.getAxisLeft().setAxisMinValue(5);
    mchart.getAxisRight().setAxisMaxValue(10);
    mchart.getAxisRight().setAxisMinValue(5);

または:

boolean a = isReady;
 mchart.getAxisLeft().setFormater(new format(float b){ return "" ;})

データを取得するとき:

    mchart.setAutoScaleMinMaxEnabled(true);
    mchart.getAxisLeft().resetAxisMaxValue();
    mchart.getAxisLeft().resetAxisMinValue();
    mchart.getAxisRight().resetAxisMaxValue();
    mchart.getAxisRight().resetAxisMinValue(5);

手元にコードはありません。

2
tiny sunlight

IAxisValueFormatterを使用している場合、values配列にアクセスしようとしたときにfloatをIntに変換することに問題がある可能性があります。

私にとっての解決策は

IAxisValueFormatter numAppointmentsXAxisFormatter = new IAxisValueFormatter() {
    @Override
    public String getFormattedValue(float value, AxisBase axis) {

        int index = (int)Math.ceil(value);
        if(index < 0){
            index = 0;
        }else if(index >= numAppointmentsLabels.size()){
            index = numAppointmentsLabels.size()-1;
        }

        return numAppointmentsLabels.get(index);
    }
};

ラベル数にも+1を追加しました

chart.getXAxis().setLabelCount(numValue+1, true);

それが役に立てば幸い

1
tsik

私はこれまでMPAndroidChartsを使用したことがありませんが、ここを少し検索するだけで、この方法が役立つと思います。

public void setLabelCount(int count, boolean force) {

        if (count > 25)
            count = 25;
        if (count < 2)
            count = 2;

        mLabelCount = count;
        mForceLabels = force;
    }

説明には、「正確に指定された数のラベルが描画され、軸に沿って均等に分散される」と記載されています。あなたがそれをあなたに有利に働かせることができれば、あなたはズームを制限することができるかもしれません。

また、別の方法があります-

public int getLabelCount() {
        return mLabelCount;
    }

これにより、軸上のラベルの数が返されます。お役に立てれば。

https://github.com/PhilJay/MPAndroidChart/blob/5a15715b25991e3d61d27d552f9eba45975d65e7/MPChartLib/src/com/github/mikephil/charting/components/YAxis.Java

0
Pallavi

粒度を必要な値に設定して、ズームしたときに繰り返されないようにすることができます。

mBarChart.getAxisLeft().setGranularity(1f);  // y-axis scale will be 0,1,2,3,4....
mBarChart.getAxisLeft().setGranularityEnabled(true);

粒度を動的に設定する場合は、IAxisValueFormatterを実装し、戻り値を比較して差を取得し、粒度をその差に設定します。

    private float yAxisScaleDifference = -1;
    private boolean granularitySet = false;
    //say the values returned by IAxisFormatter is in hundreds: 100, 200, 300...
    mBarChart.getAxisLeft.setValueFormatter(new IAxisValueFormatter() {
    @Override
    public String getFormattedValue(float v, AxisBase axisBase) {
        if(!granularitySet) {

            if(yAxisScaleDifference == -1) {
                yAxisScaleDifference = v;  //10
            }
            else {
                float diff = v - yAxisScaleDifference;  //200 - 100 = 100
                if(diff >= 1000) {
                    yAxisLeft.setGranularity(1000f);  
                }
                else if(diff >= 100) {
                    yAxisLeft.setGranularity(100f);  //set to 100
                }
                else if(diff >= 1f) {
                    yAxisLeft.setGranularity(1f);
                }
                granularitySet =true;
            }
        }
        return val;
    }
});

もう一つの例:

say Y-Axis returns [1200,3400,8000,9000....]
  first time: 1200
  second time: 3400 - 1200 = 2200
  granularity set to 1000

差が均一でない場合は、配列を使用して差を格納し、平均をとって適切な粒度を取得する必要があります。

0
sudesh