package com.github.mikephil.charting.data;
import android.content.Context;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Typeface;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.formatter.DefaultValueFormatter;
import com.github.mikephil.charting.formatter.IValueFormatter;
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
import com.github.mikephil.charting.utils.ColorTemplate;
import com.github.mikephil.charting.utils.MPPointF;
import com.github.mikephil.charting.utils.Utils;
import java.lang.annotation.Documented;
import java.lang.annotation.Inherited;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Philipp Jahoda on 21/10/15.
* This is the base dataset of all DataSets. It's purpose is to implement critical methods
* provided by the IDataSet interface.
*/
public abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
/**
* List representing all colors that are used for this DataSet
*/
protected List<Integer> mColors = null;
/**
* List representing all colors that are used for drawing the actual values for this DataSet
*/
protected List<Integer> mValueColors = null;
/**
* label that describes the DataSet or the data the DataSet represents
*/
private String mLabel = "DataSet";
/**
* this specifies which axis this DataSet should be plotted against
*/
protected YAxis.AxisDependency mAxisDependency = YAxis.AxisDependency.LEFT;
/**
* if true, value highlightning is enabled
*/
protected boolean mHighlightEnabled = true;
/**
* custom formatter that is used instead of the auto-formatter if set
*/
protected transient IValueFormatter mValueFormatter;
/**
* the typeface used for the value text
*/
protected Typeface mValueTypeface;
private Legend.LegendForm mForm = Legend.LegendForm.DEFAULT;
private float mFormSize = Float.NaN;
private float mFormLineWidth = Float.NaN;
private DashPathEffect mFormLineDashEffect = null;
/**
* if true, y-values are drawn on the chart
*/
protected boolean mDrawValues = true;
/**
* if true, y-icons are drawn on the chart
*/
protected boolean mDrawIcons = true;
/**
* the offset for drawing icons (in dp)
*/
protected MPPointF mIconsOffset = new MPPointF();
/**
* the size of the value-text labels
*/
protected float mValueTextSize = 17f;
/**
* flag that indicates if the DataSet is visible or not
*/
protected boolean mVisible = true;
/**
* Default constructor.
*/
public BaseDataSet() {
mColors = new ArrayList<Integer>();
mValueColors = new ArrayList<Integer>();
// default color
mColors.add(Color.rgb(140, 234, 255));
mValueColors.add(Color.BLACK);
}
/**
* Constructor with label.
*
* @param label
*/
public BaseDataSet(String label) {
this();
this.mLabel = label;
}
/**
* Use this method to tell the data set that the underlying data has changed.
*/
public void notifyDataSetChanged() {
calcMinMax();
}
/**
* ###### ###### COLOR GETTING RELATED METHODS ##### ######
*/
@Override
public List<Integer> getColors() {
return mColors;
}
public List<Integer> getValueColors() {
return mValueColors;
}
@Override
public int getColor() {
return mColors.get(0);
}
@Override
public int getColor(int index) {
return mColors.get(index % mColors.size());
}
/**
* ###### ###### COLOR SETTING RELATED METHODS ##### ######
*/
/**
* Sets the colors that should be used fore this DataSet. Colors are reused
* as soon as the number of Entries the DataSet represents is higher than
* the size of the colors array. If you are using colors from the resources,
* make sure that the colors are already prepared (by calling
* getResources().getColor(...)) before adding them to the DataSet.
*
* @param colors
*/
public void setColors(List<Integer> colors) {
this.mColors = colors;
}
/**
* Sets the colors that should be used fore this DataSet. Colors are reused
* as soon as the number of Entries the DataSet represents is higher than
* the size of the colors array. If you are using colors from the resources,
* make sure that the colors are already prepared (by calling
* getResources().getColor(...)) before adding them to the DataSet.
*
* @param colors
*/
public void setColors(int... colors) {
this.mColors = ColorTemplate.createColors(colors);
}
/**
* Sets the colors that should be used fore this DataSet. Colors are reused
* as soon as the number of Entries the DataSet represents is higher than
* the size of the colors array. You can use
* "new int[] { R.color.red, R.color.green, ... }" to provide colors for
* this method. Internally, the colors are resolved using
* getResources().getColor(...)
*
* @param colors
*/
public void setColors(int[] colors, Context c) {
if(mColors == null){
mColors = new ArrayList<>();
}
mColors.clear();
for (int color : colors) {
mColors.add(c.getResources().getColor(color));
}
}
/**
* Adds a new color to the colors array of the DataSet.
*
* @param color
*/
public void addColor(int color) {
if (mColors == null)
mColors = new ArrayList<Integer>();
mColors.add(color);
}
/**
* Sets the one and ONLY color that should be used for this DataSet.
* Internally, this recreates the colors array and adds the specified color.
*
* @param color
*/
public void setColor(int color) {
resetColors();
mColors.add(color);
}
/**
* Sets a color with a specific alpha value.
*
* @param color
* @param alpha from 0-255
*/
public void setColor(int color, int alpha) {
setColor(Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)));
}
/**
* Sets colors with a specific alpha value.
*
* @param colors
* @param alpha
*/
public void setColors(int[] colors, int alpha) {
resetColors();
for (int color : colors) {
addColor(Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color)));
}
}
/**
* Resets all colors of this DataSet and recreates the colors array.
*/
public void resetColors() {
if(mColors == null) {
mColors = new ArrayList<Integer>();
}
mColors.clear();
}
/**
* ###### ###### OTHER STYLING RELATED METHODS ##### ######
*/
@Override
public void setLabel(String label) {
mLabel = label;
}
@Override
public String getLabel() {
return mLabel;
}
@Override
public void setHighlightEnabled(boolean enabled) {
mHighlightEnabled = enabled;
}
@Override
public boolean isHighlightEnabled() {
return mHighlightEnabled;
}
@Override
public void setValueFormatter(IValueFormatter f) {
if (f == null)
return;
else
mValueFormatter = f;
}
@Override
public IValueFormatter getValueFormatter() {
if (needsFormatter())
return Utils.getDefaultValueFormatter();
return mValueFormatter;
}
@Override
public boolean needsFormatter() {
return mValueFormatter == null;
}
@Override
public void setValueTextColor(int color) {
mValueColors.clear();
mValueColors.add(color);
}
@Override
public void setValueTextColors(List<Integer> colors) {
mValueColors = colors;
}
@Override
public void setValueTypeface(Typeface tf) {
mValueTypeface = tf;
}
@Override
public void setValueTextSize(float size) {
mValueTextSize = Utils.convertDpToPixel(size);
}
@Override
public int getValueTextColor() {
return mValueColors.get(0);
}
@Override
public int getValueTextColor(int index) {
return mValueColors.get(index % mValueColors.size());
}
@Override
public Typeface getValueTypeface() {
return mValueTypeface;
}
@Override
public float getValueTextSize() {
return mValueTextSize;
}
public void setForm(Legend.LegendForm form) {
mForm = form;
}
@Override
public Legend.LegendForm getForm() {
return mForm;
}
public void setFormSize(float formSize) {
mFormSize = formSize;
}
@Override
public float getFormSize() {
return mFormSize;
}
public void setFormLineWidth(float formLineWidth) {
mFormLineWidth = formLineWidth;
}
@Override
public float getFormLineWidth() {
return mFormLineWidth;
}
public void setFormLineDashEffect(DashPathEffect dashPathEffect) {
mFormLineDashEffect = dashPathEffect;
}
@Override
public DashPathEffect getFormLineDashEffect() {
return mFormLineDashEffect;
}
@Override
public void setDrawValues(boolean enabled) {
this.mDrawValues = enabled;
}
@Override
public boolean isDrawValuesEnabled() {
return mDrawValues;
}
@Override
public void setDrawIcons(boolean enabled) {
mDrawIcons = enabled;
}
@Override
public boolean isDrawIconsEnabled() {
return mDrawIcons;
}
@Override
public void setIconsOffset(MPPointF offsetDp) {
mIconsOffset.x = offsetDp.x;
mIconsOffset.y = offsetDp.y;
}
@Override
public MPPointF getIconsOffset() {
return mIconsOffset;
}
@Override
public void setVisible(boolean visible) {
mVisible = visible;
}
@Override
public boolean isVisible() {
return mVisible;
}
@Override
public YAxis.AxisDependency getAxisDependency() {
return mAxisDependency;
}
@Override
public void setAxisDependency(YAxis.AxisDependency dependency) {
mAxisDependency = dependency;
}
/**
* ###### ###### DATA RELATED METHODS ###### ######
*/
@Override
public int getIndexInEntries(int xIndex) {
for (int i = 0; i < getEntryCount(); i++) {
if (xIndex == getEntryForIndex(i).getX())
return i;
}
return -1;
}
@Override
public boolean removeFirst() {
if (getEntryCount() > 0) {
T entry = getEntryForIndex(0);
return removeEntry(entry);
} else
return false;
}
@Override
public boolean removeLast() {
if (getEntryCount() > 0) {
T e = getEntryForIndex(getEntryCount() - 1);
return removeEntry(e);
} else
return false;
}
@Override
public boolean removeEntryByXValue(float xValue) {
T e = getEntryForXValue(xValue, Float.NaN);
return removeEntry(e);
}
@Override
public boolean removeEntry(int index) {
T e = getEntryForIndex(index);
return removeEntry(e);
}
@Override
public boolean contains(T e) {
for (int i = 0; i < getEntryCount(); i++) {
if (getEntryForIndex(i).equals(e))
return true;
}
return false;
}
}