解決MPAndroidChart-LineChart清除資料重新整理後X軸取值不準確的問題
阿新 • • 發佈:2019-02-04
由於專案需要使用表格,於是在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);