mpandroidchart - 如何避免 Y 轴中的重复值?
Posted
技术标签:
【中文标题】mpandroidchart - 如何避免 Y 轴中的重复值?【英文标题】:mpandroidchart - How can I avoid the repeated values in Y-Axis? 【发布时间】:2015-12-10 17:44:20 【问题描述】:我想避免Y轴的重复值和-0值,避免图像情况。
我有这些想法来解决这个问题,但任何解决方案:
-
限制缩放在 YAxis 中有重复值之前,因此停止图表上的无限放大
获取 YAxis 值并删除重复值。
【问题讨论】:
设置 x 和 y 最大值的限制 我认为在ios中是在最后一个版本中解决的,chart.getViewPortHandler().setMaximumScaleX(4f); chart.getViewPortHandler().setMaximumScaleY(4f);但它仍然无法在 android 中运行 【参考方案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) 以获得更详细的说明。以下是相关方法:
setGranularity(float granularity)
: 设置放大时轴的最小间隔。轴不 允许低于该限制。这可以用来避免标签 放大时重复。setGranularityEnabled(boolean enabled)
: 启用/禁用轴值间隔的粒度控制。如果 启用,轴间隔不允许低于某个 粒度。
因此,在您的情况下,您需要将粒度设置为 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
【讨论】:
以上是关于mpandroidchart - 如何避免 Y 轴中的重复值?的主要内容,如果未能解决你的问题,请参考以下文章