Fixes and testing related to dynamic data adding and removing from chartdata

This commit is contained in:
Philipp Jahoda 2016-06-06 23:54:54 +02:00
parent dc03cf2593
commit 0a55308975
2 changed files with 206 additions and 180 deletions

View file

@ -41,18 +41,18 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
*/
protected float mXMin = 0f;
protected float mLeftAxisMax = 0.0f;
protected float mLeftAxisMax = Float.MIN_VALUE;
protected float mLeftAxisMin = 0.0f;
protected float mLeftAxisMin = Float.MAX_VALUE;
protected float mRightAxisMax = 0.0f;
protected float mRightAxisMax = Float.MIN_VALUE;
protected float mRightAxisMin = 0.0f;
protected float mRightAxisMin = Float.MAX_VALUE;
/**
* total number of y-values across all DataSet objects
* total number of values (entries) across all DataSet objects
*/
private int mYValCount = 0;
private int mValueCount = 0;
/**
* contains the maximum length (in characters) an entry in the x-vals array
@ -70,10 +70,27 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
}
public ChartData(T... dataSets) {
mDataSets = Arrays.asList(dataSets);
mDataSets = arrayToList(dataSets);
init();
}
/**
* Created because Arrays.asList(...) does not support modification.
*
* @param array
* @return
*/
private List<T> arrayToList(T[] array) {
List<T> list = new ArrayList<>();
for (T set : array) {
list.add(set);
}
return list;
}
/**
* constructor for chart data
*
@ -126,20 +143,8 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
for (int i = 0; i < mDataSets.size(); i++) {
IDataSet set = mDataSets.get(i);
set.calcMinMax();
if (set.getYMin() < mYMin)
mYMin = set.getYMin();
if (set.getYMax() > mYMax)
mYMax = set.getYMax();
if (set.getXMin() < mXMin)
mXMin = set.getXMin();
if (set.getXMax() > mXMax)
mXMax = set.getXMax();
T set = mDataSets.get(i);
calcMinMax(set);
}
if (mYMin == Float.MAX_VALUE) {
@ -184,9 +189,6 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
}
}
}
// in case there is only one axis, adjust the second axis
handleEmptyAxis(firstLeft, firstRight);
}
}
@ -198,7 +200,7 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
*/
protected void calcYValueCount() {
mYValCount = 0;
mValueCount = 0;
if (mDataSets == null)
return;
@ -209,7 +211,7 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
count += mDataSets.get(i).getEntryCount();
}
mYValCount = count;
mValueCount = count;
}
/** ONLY GETTERS AND SETTERS BELOW THIS */
@ -241,10 +243,18 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
* @return
*/
public float getYMin(AxisDependency axis) {
if (axis == AxisDependency.LEFT)
return mLeftAxisMin;
else
return mRightAxisMin;
if (axis == AxisDependency.LEFT) {
if (mLeftAxisMin == Float.MAX_VALUE) {
return mRightAxisMin;
} else
return mLeftAxisMin;
} else {
if (mRightAxisMin == Float.MAX_VALUE) {
return mLeftAxisMin;
} else
return mRightAxisMin;
}
}
/**
@ -263,10 +273,18 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
* @return
*/
public float getYMax(AxisDependency axis) {
if (axis == AxisDependency.LEFT)
return mLeftAxisMax;
else
return mRightAxisMax;
if (axis == AxisDependency.LEFT) {
if (mLeftAxisMax == Float.MIN_VALUE) {
return mRightAxisMax;
} else
return mLeftAxisMax;
} else {
if (mRightAxisMax == Float.MIN_VALUE) {
return mLeftAxisMax;
} else
return mRightAxisMax;
}
}
/**
@ -304,7 +322,7 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
* @return
*/
public int getYValCount() {
return mYValCount;
return mValueCount;
}
public List<T> getDataSets() {
@ -367,23 +385,6 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
return mDataSets.get(highlight.getDataSetIndex()).getEntryForXPos(highlight.getX());
}
}
// public Entry getEntryForHighlight(Highlight highlight) {
// if (highlight.getDataSetIndex() >= mDataSets.size())
// return null;
// else {
// // The value of the highlighted entry could be NaN -
// // if we are not interested in highlighting a specific value.
//
// List<?> entries = mDataSets.get(highlight.getDataSetIndex())
// .getEntriesForXPos(highlight.getX());
// for (Object entry : entries)
// if (((Entry)entry).getY() == highlight.getY() ||
// Float.isNaN(highlight.getY()))
// return (Entry)entry;
//
// return null;
// }
// }
/**
* Returns the DataSet object with the given label. Search can be case
@ -422,63 +423,11 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
if (d == null)
return;
mYValCount += d.getEntryCount();
mValueCount += d.getEntryCount();
if (mDataSets.size() <= 0) {
mYMax = d.getYMax();
mYMin = d.getYMin();
if (d.getAxisDependency() == AxisDependency.LEFT) {
mLeftAxisMax = d.getYMax();
mLeftAxisMin = d.getYMin();
} else {
mRightAxisMax = d.getYMax();
mRightAxisMin = d.getYMin();
}
} else {
if (mYMax < d.getYMax())
mYMax = d.getYMax();
if (mYMin > d.getYMin())
mYMin = d.getYMin();
if (d.getAxisDependency() == AxisDependency.LEFT) {
if (mLeftAxisMax < d.getYMax())
mLeftAxisMax = d.getYMax();
if (mLeftAxisMin > d.getYMin())
mLeftAxisMin = d.getYMin();
} else {
if (mRightAxisMax < d.getYMax())
mRightAxisMax = d.getYMax();
if (mRightAxisMin > d.getYMin())
mRightAxisMin = d.getYMin();
}
}
calcMinMax(d);
mDataSets.add(d);
handleEmptyAxis(getFirstLeft(), getFirstRight());
}
/**
* This adjusts the other axis if one axis is empty and the other is not.
*
* @param firstLeft
* @param firstRight
*/
private void handleEmptyAxis(T firstLeft, T firstRight) {
// in case there is only one axis, adjust the second axis
if (firstLeft == null) {
mLeftAxisMax = mRightAxisMax;
mLeftAxisMin = mRightAxisMin;
} else if (firstRight == null) {
mRightAxisMax = mLeftAxisMax;
mRightAxisMin = mLeftAxisMin;
}
}
/**
@ -498,7 +447,7 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
// if a DataSet was removed
if (removed) {
mYValCount -= d.getEntryCount();
mValueCount -= d.getEntryCount();
calcMinMax();
}
@ -538,50 +487,67 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
if (!set.addEntry(e))
return;
float val = e.getY();
calcMinMax(e, set.getAxisDependency());
if (mYValCount == 0) {
mYMin = val;
mYMax = val;
if (set.getAxisDependency() == AxisDependency.LEFT) {
mLeftAxisMax = e.getY();
mLeftAxisMin = e.getY();
} else {
mRightAxisMax = e.getY();
mRightAxisMin = e.getY();
}
} else {
if (mYMax < val)
mYMax = val;
if (mYMin > val)
mYMin = val;
if (set.getAxisDependency() == AxisDependency.LEFT) {
if (mLeftAxisMax < e.getY())
mLeftAxisMax = e.getY();
if (mLeftAxisMin > e.getY())
mLeftAxisMin = e.getY();
} else {
if (mRightAxisMax < e.getY())
mRightAxisMax = e.getY();
if (mRightAxisMin > e.getY())
mRightAxisMin = e.getY();
}
}
mYValCount += 1;
handleEmptyAxis(getFirstLeft(), getFirstRight());
mValueCount += 1;
} else {
Log.e("addEntry", "Cannot add Entry because dataSetIndex too high or too low.");
}
}
protected void calcMinMax(Entry e, AxisDependency axis) {
if (mYMax < e.getY())
mYMax = e.getY();
if (mYMin > e.getY())
mYMin = e.getY();
if (mXMax < e.getX())
mXMax = e.getX();
if (mXMin > e.getX())
mXMin = e.getX();
if (axis == AxisDependency.LEFT) {
if (mLeftAxisMax < e.getY())
mLeftAxisMax = e.getY();
if (mLeftAxisMin > e.getY())
mLeftAxisMin = e.getY();
} else {
if (mRightAxisMax < e.getY())
mRightAxisMax = e.getY();
if (mRightAxisMin > e.getY())
mRightAxisMin = e.getY();
}
}
protected void calcMinMax(T d) {
if (mYMax < d.getYMax())
mYMax = d.getYMax();
if (mYMin > d.getYMin())
mYMin = d.getYMin();
if (mXMax < d.getXMax())
mXMax = d.getXMax();
if (mXMin > d.getXMin())
mXMin = d.getXMin();
if (d.getAxisDependency() == AxisDependency.LEFT) {
if (mLeftAxisMax < d.getYMax())
mLeftAxisMax = d.getYMax();
if (mLeftAxisMin > d.getYMin())
mLeftAxisMin = d.getYMin();
} else {
if (mRightAxisMax < d.getYMax())
mRightAxisMax = d.getYMax();
if (mRightAxisMin > d.getYMin())
mRightAxisMin = d.getYMin();
}
}
/**
* Removes the given Entry object from the DataSet at the specified index.
*
@ -601,7 +567,7 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
boolean removed = set.removeEntry(e);
if (removed) {
mYValCount -= 1;
mValueCount -= 1;
calcMinMax();
}
@ -731,23 +697,6 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
return null;
}
// /**
// * Generates an x-values array filled with numbers in range specified by the
// * parameters. Can be used for convenience.
// *
// * @return
// */
// public static List<XAxisValue> generateXVals(int from, int to) {
//
// List<XAxisValue> xvals = new ArrayList<XAxisValue>();
//
// for (int i = from; i < to; i++) {
// xvals.add(new XAxisValue(i, i + ""));
// }
//
// return xvals;
// }
/**
* Sets a custom ValueFormatter for all DataSets this data object contains.
*
@ -857,24 +806,6 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
notifyDataChanged();
}
// /**
// * Checks if this data object contains the specified Entry. Returns true if
// * so, false if not. NOTE: Performance is pretty bad on this one, do not
// * over-use in performance critical situations.
// *
// * @param e
// * @return
// */
// public boolean contains(Entry e) {
//
// for (T set : mDataSets) {
// if (set.contains(e))
// return true;
// }
//
// return false;
// }
/**
* Checks if this data object contains the specified DataSet. Returns true
* if so, false if not.

View file

@ -0,0 +1,95 @@
package com.github.mikephil.charting.test;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.ScatterData;
import com.github.mikephil.charting.data.ScatterDataSet;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static junit.framework.Assert.assertEquals;
/**
* Created by philipp on 06/06/16.
*/
public class ChartDataTest {
@Test
public void testDynamicChartData() {
List<Entry> entries1 = new ArrayList<Entry>();
entries1.add(new Entry(10, 10));
entries1.add(new Entry(15, -2));
entries1.add(new Entry(21, 50));
ScatterDataSet set1 = new ScatterDataSet(entries1, "");
List<Entry> entries2 = new ArrayList<Entry>();
entries2.add(new Entry(-1, 10));
entries2.add(new Entry(10, 2));
entries2.add(new Entry(20, 5));
ScatterDataSet set2 = new ScatterDataSet(entries2, "");
ScatterData data = new ScatterData(set1, set2);
assertEquals(-2, data.getYMin(YAxis.AxisDependency.LEFT), 0.01f);
assertEquals(50f, data.getYMax(YAxis.AxisDependency.LEFT), 0.01f);
assertEquals(6, data.getEntryCount());
assertEquals(-1f, data.getXMin(), 0.01f);
assertEquals(21f, data.getXMax(), 0.01f);
assertEquals(-2f, data.getYMin(), 0.01f);
assertEquals(50f, data.getYMax(), 0.01f);
assertEquals(3, data.getMaxEntryCountSet().getEntryCount());
// now add and remove values
data.addEntry(new Entry(-10, -10), 0);
assertEquals(set1, data.getMaxEntryCountSet());
assertEquals(4, data.getMaxEntryCountSet().getEntryCount());
assertEquals(-10f, data.getYMin(YAxis.AxisDependency.LEFT), 0.01f);
assertEquals(50f, data.getYMax(YAxis.AxisDependency.LEFT), 0.01f);
assertEquals(-10f, data.getXMin(), 0.01f);
assertEquals(21f, data.getXMax(), 0.01f);
assertEquals(-10f, data.getYMin(), 0.01f);
assertEquals(50f, data.getYMax(), 0.01f);
data.addEntry(new Entry(-100, 100), 0);
data.addEntry(new Entry(0, -100), 0);
assertEquals(-100f, data.getYMin(YAxis.AxisDependency.LEFT), 0.01f);
assertEquals(100f, data.getYMax(YAxis.AxisDependency.LEFT), 0.01f);
// right axis will adapt left axis values if no right axis values are present
assertEquals(-100, data.getYMin(YAxis.AxisDependency.RIGHT), 0.01f);
assertEquals(100f, data.getYMax(YAxis.AxisDependency.RIGHT), 0.01f);
List<Entry> entries3 = new ArrayList<Entry>();
entries3.add(new Entry(0, 200));
entries3.add(new Entry(0, -50));
ScatterDataSet set3 = new ScatterDataSet(entries3, "");
set3.setAxisDependency(YAxis.AxisDependency.RIGHT);
data.addDataSet(set3);
assertEquals(3, data.getDataSetCount());
assertEquals(-100f, data.getYMin(YAxis.AxisDependency.LEFT), 0.01f);
assertEquals(100f, data.getYMax(YAxis.AxisDependency.LEFT), 0.01f);
assertEquals(-50f, data.getYMin(YAxis.AxisDependency.RIGHT), 0.01f);
assertEquals(200f, data.getYMax(YAxis.AxisDependency.RIGHT), 0.01f);
}
}