blob: 81c7244f7b8cdd497e99f15199876bc2ca934974 [file] [log] [blame]
package com.github.mikephil.charting.data;
import java.util.ArrayList;
import com.github.mikephil.charting.utils.Highlight;
/**
* Class that holds all relevant data that represents the chart. That involves
* at least one (or more) DataSets, and an array of x-values.
*
* @author Philipp Jahoda
*/
public class ChartData {
/** maximum y-value in the y-value array */
private float mYMax = 0.0f;
/** the minimum y-value in the y-value array */
private float mYMin = 0.0f;
/** the total sum of all y-values */
private float mYValueSum = 0f;
/** holds all x-values the chart represents */
private ArrayList<String> mXVals;
/** holds all the datasets (e.g. different lines) the chart represents */
private ArrayList<DataSet> mDataSets;
/** array that holds all the different labels that are in the DataSet array */
private ArrayList<String> mDiffLabels;
/**
* constructor for chart data
*
* @param xVals The values describing the x-axis. Must be at least as long
* as the highest xIndex in the Entry objects across all
* DataSets.
* @param dataSets all DataSet objects the chart needs to represent
*/
public ChartData(ArrayList<String> xVals, ArrayList<DataSet> dataSets) {
init(xVals, dataSets);
}
/**
* constructor that takes string array instead of arraylist string
*
* @param xVals The values describing the x-axis. Must be at least as long
* as the highest xIndex in the Entry objects across all
* DataSets.
* @param dataSets all DataSet objects the chart needs to represent
*/
public ChartData(String[] xVals, ArrayList<DataSet> dataSets) {
ArrayList<String> newXVals = new ArrayList<String>();
for (int i = 0; i < xVals.length; i++) {
newXVals.add(xVals[i]);
}
init(newXVals, dataSets);
}
/**
* Constructor that takes only one DataSet
*
* @param xVals
* @param data
*/
public ChartData(ArrayList<String> xVals, DataSet data) {
ArrayList<DataSet> sets = new ArrayList<DataSet>();
sets.add(data);
init(xVals, sets);
}
private void init(ArrayList<String> xVals, ArrayList<DataSet> dataSets) {
this.mXVals = xVals;
this.mDataSets = dataSets;
calcTypes();
calcMinMax();
calcYValueSum();
for (int i = 0; i < mDataSets.size(); i++) {
if (mDataSets.get(i)
.getYVals()
.size() > xVals.size()) {
throw new IllegalArgumentException(
"One or more of the DataSet Entry arrays are longer than the x-values array.");
}
}
}
/**
* Call this method to let the CartData know that the underlying data has
* changed.
*/
public void notifyDataChanged() {
doCalculations();
}
/**
* Does all necessary calculations, if the underlying data has changed
*/
private void doCalculations() {
calcTypes();
calcMinMax();
calcYValueSum();
}
/**
* calculates all different labels that occur in the DataSets and stores
* them for fast access
*/
private void calcTypes() {
mDiffLabels = new ArrayList<String>();
// check which dataset to use
ArrayList<DataSet> dataSets = mDataSets;
for (int i = 0; i < dataSets.size(); i++) {
String label = dataSets.get(i).getLabel();
if (!alreadyCounted(mDiffLabels, label)) {
mDiffLabels.add(label);
}
}
}
/**
* calc minimum and maximum y value over all datasets
*/
private void calcMinMax() {
// check which dataset to use
ArrayList<DataSet> dataSets = mDataSets;
mYMin = dataSets.get(0).getYMin();
mYMax = dataSets.get(0).getYMax();
for (int i = 0; i < dataSets.size(); i++) {
if (dataSets.get(i).getYMin() < mYMin)
mYMin = dataSets.get(i).getYMin();
if (dataSets.get(i).getYMax() > mYMax)
mYMax = dataSets.get(i).getYMax();
}
}
/**
* calculates the sum of all y-values in all datasets
*/
private void calcYValueSum() {
mYValueSum = 0;
// check which dataset to use
ArrayList<DataSet> dataSets = mDataSets;
for (int i = 0; i < dataSets.size(); i++) {
mYValueSum += Math.abs(dataSets.get(i).getYValueSum());
}
}
private boolean alreadyCounted(ArrayList<String> countedLabels, String label) {
for (int i = 0; i < countedLabels.size(); i++) {
if (countedLabels.get(i).equals(label))
return true;
}
return false;
}
/**
* Corrects all values that are kept as member variables after a new entry
* was added. This saves recalculating all values.
*
* @param entry the new entry
*/
public void notifyDataForNewEntry(Entry entry) {
mYValueSum += Math.abs(entry.getVal());
if (mYMin > entry.getVal()) {
mYMin = entry.getVal();
}
if (mYMax < entry.getVal()) {
mYMax = entry.getVal();
}
if (mYMin == mYMax) {
mYMin--;
mYMax++;
}
}
public int getDataSetCount() {
return mDataSets.size();
}
public float getYMin() {
return mYMin;
}
public float getYMax() {
return mYMax;
}
public float getYValueSum() {
return mYValueSum;
}
/**
* Checks if the ChartData object contains valid data
*
* @return
*/
public boolean isValid() {
if (mXVals == null || mXVals.size() <= 1)
return false;
if (mDataSets == null || mDataSets.size() < 1)
return false;
return true;
}
/**
* returns the x-values the chart represents
*
* @return
*/
public ArrayList<String> getXVals() {
return mXVals;
}
/**
* returns the Entries array from the DataSet at the given index. If a
* filter is set, the filtered Entries are returned
*
* @param index
* @return
*/
public ArrayList<Entry> getYVals(int index) {
return mDataSets.get(index).getYVals();
}
/**
* Get the entry for a corresponding highlight object
*
* @param highlight
* @return the entry that is highlighted
*/
public Entry getEntryForHighlight(Highlight highlight) {
return getDataSetByIndex(highlight.getDataSetIndex()).getEntryForXIndex(
highlight.getXIndex());
}
/**
* returns the dataset at the given index.
*
* @param index
* @return
*/
public DataSet getDataSetByIndex(int index) {
return mDataSets.get(index);
}
/**
* Retrieve a DataSet with a specific label from the ChartData. Search can
* be case sensitive or not. IMPORTANT: This method does calculations at
* runtime, do not over-use in performance critical situations.
*
* @param type
* @param ignorecase if true, the search is not case-sensitive
* @return
*/
public DataSet getDataSetByLabel(String label, boolean ignorecase) {
// check which dataset to use
ArrayList<DataSet> dataSets = mDataSets;
if (ignorecase) {
for (int i = 0; i < dataSets.size(); i++)
if (label.equalsIgnoreCase(dataSets.get(i).getLabel()))
return dataSets.get(i);
} else {
for (int i = 0; i < dataSets.size(); i++)
if (label.equals(dataSets.get(i).getLabel()))
return dataSets.get(i);
}
return null;
}
/**
* returns all DataSet objects the ChartData represents. If a filter is set,
* the filtered DataSets are returned
*
* @return
*/
public ArrayList<DataSet> getDataSets() {
return mDataSets;
}
/**
* This returns the original data set, regardless of any filter options.
*
* @return
*/
public ArrayList<DataSet> getOriginalDataSets() {
return mDataSets;
}
/**
* returns all the different DataSet labels the chartdata represents
*
* @return
*/
public ArrayList<String> getLabels() {
return mDiffLabels;
}
/**
* returns the total number of x-values this chartdata represents (the size
* of the xvals array)
*
* @return
*/
public int getXValCount() {
return mXVals.size();
}
/**
* returns the total number of y-values across all DataSets the chartdata
* represents. If a filter is set, the filtered count is returned
*
* @return
*/
public int getYValCount() {
int count = 0;
// check which dataset to use
ArrayList<DataSet> dataSets = mDataSets;
for (int i = 0; i < dataSets.size(); i++) {
count += dataSets.get(i).getEntryCount();
}
return count;
}
/**
* Returns the labels of all DataSets as a string array.
*
* @return
*/
public String[] getDataSetLabels() {
String[] types = new String[mDataSets.size()];
for (int i = 0; i < mDataSets.size(); i++) {
types[i] = mDataSets.get(i).getLabel();
}
return types;
}
/**
* Generates an x-values array filled with numbers in range specified by the
* parameters. Can be used for convenience.
*
* @return
*/
public static ArrayList<String> generateXVals(int from, int to) {
ArrayList<String> xvals = new ArrayList<String>();
for (int i = from; i < to; i++) {
xvals.add("" + i);
}
return xvals;
}
}