【问题标题】:mpandroidchart - How can I avoid the repeated values in Y-Axis?mpandroidchart - 如何避免 Y 轴中的重复值?
【发布时间】:2015-12-10 17:44:20
【问题描述】:

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

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

  1. 限制缩放在 YAxis 中有重复值之前,因此停止图表上的无限放大
  2. 获取 YAxis 值并删除重复值。

【问题讨论】:

  • 设置 x 和 y 最大值的限制
  • 我认为在iOS中是在最后一个版本中解决的,chart.getViewPortHandler().setMaximumScaleX(4f); chart.getViewPortHandler().setMaximumScaleY(4f);但它仍然无法在 Android 中运行

标签: android pinchzoom mpandroidchart


【解决方案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);

希望对你有帮助

【讨论】:

  • 您可以使用Math.round,而不是Math.ceil。为什么?阅读我的answer here
【解决方案2】:

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

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

如果要动态设置粒度,则实现 IAxisValueFormatter 并比较返回值以获取差异并将 Granularity 设置为该差异。

    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

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

【讨论】:

    【解决方案3】:

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

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

    因此,在您的情况下,您需要将粒度设置为 0.1f,因为您有一位小数点。下面的sn-p代码应该避免轴上的重复值:

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

    【讨论】:

      【解决方案4】:

      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

      【讨论】:

      • 我可以看到两次 15.8ºC。这在哪里解决了重复的值?你只是在轴上放了两个值
      • @rguerra 您不能在轴上设置 很多 时。所以你可以另外限制缩放级别,但我怀疑你可以使用 MPChart 做得比这更好;)
      • 我不认为我需要使用另一个库 :) 因为,这已经在 iOS 版本中工作了。他们已经可以在重复值之前限制缩放,设置axisMax和axisMin值。但在 Android 中,我们缩放的区域一直向右移动
      • 它是开源的。你可以改变它。你的意思是在 android chart.getViewPortHandler().setMaximumScaleY(4f) 不起作用?
      • 可能设置PinchZoom(false)。
      【解决方案5】:

      这样的代码:

          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);
      

      我手头没有代码。

      【讨论】:

      • 这改变了我的视口,当我尝试放大时,将视口向右移动
      【解决方案6】:

      我以前从未使用过 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-31
        • 2018-12-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-02
        • 2019-03-30
        • 1970-01-01
        相关资源
        最近更新 更多