mpandroidchart - 如何避免Y轴中的重复值?

时间:2015-09-14 16:32:05

标签: android pinchzoom mpandroidchart

我想避免重复值和Y轴中的-0值,避免图像情况。

我有这些想法来解决这个问题,但任何解决方案:

  1. 限制缩放,然后在YAxis中重复显示值,因此停止图表上的无限放大
  2. 获取YAxis值并删除重复值。
  3. YAxis with duplicate values

6 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

像这样的代码:

    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 :(得分:2)

虽然这是一个较旧的问题,但我想添加它以供将来参考。较新版本的库具有一些鲜为人知的功能,可以解析重复的标签,称为粒度。这比使用旧解决方案更简单(虽然公平地说,这些在发布时不可用)。

您可以随时查看最新的AxisBase Javadocs(3.0.0-beta1)以获取更详细的说明。以下是相关方法:

  

因此,在您的情况下,您需要将粒度设置为0.1f,因为您有一个小数点。以下代码片段应避免轴上的重复值:

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

答案 3 :(得分:1)

如果您使用的是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);

希望有帮助

答案 4 :(得分:0)

我之前从未使用过MPAndroidCharts,但只是在这里进行了一点搜索,我认为这种方法对我有用。

public void setLabelCount(int count, boolean force) {

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

        mLabelCount = count;
        mForceLabels = force;
    }

描述说&#34;标签的精确指定数量将被绘制并均匀分布在轴&#34;旁边。如果你能使它对你有利,你可以限制缩放。

此外,还有另一种方法 -

public int getLabelCount() {
        return mLabelCount;
    }

返回轴上的标签数。希望这会有所帮助。

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

答案 5 :(得分:0)

您可以将粒度设置为所需的值,以防止缩放时重复。

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

如果差异不均匀,则必须使用数组来存储差异,并使用平均值来获得正确的粒度。