由于项目需要使用表格,于是在Github上搜索到了一个比较好的开源控件。
现在我想实现一个表格,表格上每隔几秒增加一个点,表格上只会显示10条数据,所以效果就像动态更新数据一样,每加一个点,X轴像左移动一个点。
但是我现在想加一个Button,每次点击后就清除掉LineChart中的DataSet,然后重新设置一个DataSet,重新加载数据。也就是说X轴重新从0开始,但是就在这个时候出现了问题,与第一次设置LineChart之前一摸一样的代码,刷新之后,X轴上显示的数值不是我想象中的1,2,3,4…..9,10了,而是各种可能的数值,反正是带小数的数值。
第一次加载X轴是正常的0 - 10。
刷新后X轴的值是0.0-0.8:
这个问题困扰了好几天,最后在源码中查看到了蹊跷:
XAxisRenderer.java
@Override
public void computeAxis(float min, float max, boolean inverted) {
Log.e("info", "min = " + min + " max = " + max);
Log.e("info", "mScarlX = " + mViewPortHandler.getScaleX() + " minScaleX = " + mViewPortHandler.getMinScaleX());
// calculate the starting and entry point of the y-labels (depending on
// zoom / contentrect bounds)
if (mViewPortHandler.contentWidth() > 10 && !mViewPortHandler.isFullyZoomedOutX()) {
MPPointD p1 = mTrans.getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop());
MPPointD p2 = mTrans.getValuesByTouchPoint(mViewPortHandler.contentRight(), mViewPortHandler.contentTop());
if (inverted) {
min = (float) p2.x;
max = (float) p1.x;
} else {
min = (float) p1.x;
max = (float) p2.x;
}
MPPointD.recycleInstance(p1);
MPPointD.recycleInstance(p2);
}
Log.e("info", "转换后 min = " + min + " max = " + max);
Log.e("info", "***************************************************************************************************************");
computeAxisValues(min, max);
}
通过查看源码与调试,发现每次我设置了X轴的最大值和最小值后,x的取值都是在这个地方算出来的,第一次设置是正常的,但是一旦刷新数据之后,x轴的值就不正常了,原因就是mViewPortHandler
这个变量。
x轴的取值具体是用矩阵计算的,这个过程我就不分析了(其实是看不懂啊┑( ̄▽  ̄)┍ )。但是我只知道,它每次计算都会跟这个mViewPortHandler
对象有关系:
MPPointD p1 = mTrans.getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop());
MPPointD p2 = mTrans.getValuesByTouchPoint(mViewPortHandler.contentRight(), mViewPortHandler.contentTop());
最后进去看了下ViewPortHandler.java
的源码,发现它的很多计算都与一个Matrix
变量有关:
/**
* matrix used for touch events
*/
protected final Matrix mMatrixTouch = new Matrix();
然后又发现了这个类里面又一个public Matrix refresh(Matrix newMatrix, View chart, boolean invalidate)
方法。可以重置上面的mMatrixTouch
变量。于是我就调用这个方法,直接new了一个Matrix
进去,问题就解决了。
解决办法:
在清除数据后,调用:
chart.setScaleMinima(1.0f, 1.0f);
chart.getViewPortHandler().refresh(new Matrix(), chart, true);