Major improvements to the Legend, Legend now groups colors of the same DataSet. Worked on examples.
This commit is contained in:
parent
ff01a15210
commit
a6f35d574e
15 changed files with 223 additions and 72 deletions
|
@ -41,6 +41,7 @@ public class BarChartActivityMultiDataset extends Activity implements OnSeekBarC
|
|||
mSeekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
mChart = (BarChart) findViewById(R.id.chart1);
|
||||
mChart.setDescription("");
|
||||
|
||||
ColorTemplate ct = new ColorTemplate();
|
||||
|
||||
|
@ -182,9 +183,9 @@ public class BarChartActivityMultiDataset extends Activity implements OnSeekBarC
|
|||
}
|
||||
|
||||
// create 3 datasets with different types
|
||||
DataSet set1 = new DataSet(yVals1, "DS 1");
|
||||
DataSet set2 = new DataSet(yVals2, "DS 2");
|
||||
DataSet set3 = new DataSet(yVals3, "DS 3");
|
||||
DataSet set1 = new DataSet(yVals1, "Company A");
|
||||
DataSet set2 = new DataSet(yVals2, "Company B");
|
||||
DataSet set3 = new DataSet(yVals3, "Company C");
|
||||
|
||||
ArrayList<DataSet> dataSets = new ArrayList<DataSet>();
|
||||
dataSets.add(set1);
|
||||
|
|
|
@ -139,8 +139,6 @@ public class LineChartActivity extends Activity implements OnSeekBarChangeListen
|
|||
// l.setPosition(LegendPosition.LEFT_OF_CHART);
|
||||
l.setForm(LegendForm.LINE);
|
||||
|
||||
mChart.setOffsets(100, 100, 200, 200);
|
||||
|
||||
// dont forget to refresh the drawing
|
||||
mChart.invalidate();
|
||||
}
|
||||
|
|
|
@ -22,8 +22,9 @@ public class BarChartFrag extends SimpleFragment {
|
|||
View v = inflater.inflate(R.layout.frag_simple_bar, container, false);
|
||||
|
||||
mChart = (BarChart) v.findViewById(R.id.barChart1);
|
||||
mChart.setYLabelCount(6);
|
||||
|
||||
mChart.setData(generateData());
|
||||
mChart.setData(generateData(1, 2000000));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package com.example.mpchartexample.simple;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.example.mpchartexample.R;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
|
||||
public class LineChartFrag extends SimpleFragment {
|
||||
|
@ -23,7 +25,20 @@ public class LineChartFrag extends SimpleFragment {
|
|||
|
||||
mChart = (LineChart) v.findViewById(R.id.lineChart1);
|
||||
|
||||
mChart.setData(generateData());
|
||||
ColorTemplate ct = new ColorTemplate();
|
||||
ct.addColorsForDataSets(new int[] { R.color.vordiplom_1, R.color.vordiplom_4 }, getActivity());
|
||||
|
||||
Log.i("TEST", "size: " + ct.getColors().size());
|
||||
|
||||
mChart.setColorTemplate(ct);
|
||||
|
||||
mChart.setDescription("");
|
||||
mChart.setDrawFilled(true);
|
||||
mChart.setDrawYValues(false);
|
||||
mChart.setLineWidth(3.5f);
|
||||
mChart.setCircleSize(5f);
|
||||
|
||||
mChart.setData(generateData(2, 10000));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
|
@ -5,9 +5,12 @@ import android.view.LayoutInflater;
|
|||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.example.mpchartexample.MyMarkerView;
|
||||
import com.example.mpchartexample.R;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.charts.ScatterChart;
|
||||
import com.github.mikephil.charting.charts.BarLineChartBase.BorderStyle;
|
||||
import com.github.mikephil.charting.charts.ScatterChart.ScatterShape;
|
||||
import com.github.mikephil.charting.utils.ColorTemplate;
|
||||
|
||||
|
||||
public class ScatterChartFrag extends SimpleFragment {
|
||||
|
@ -23,8 +26,32 @@ public class ScatterChartFrag extends SimpleFragment {
|
|||
View v = inflater.inflate(R.layout.frag_simple_scatter, container, false);
|
||||
|
||||
mChart = (ScatterChart) v.findViewById(R.id.scatterChart1);
|
||||
mChart.setDrawYValues(false);
|
||||
mChart.setDescription("");
|
||||
|
||||
mChart.setData(generateData());
|
||||
ColorTemplate ct = new ColorTemplate();
|
||||
ct.addDataSetColors(ColorTemplate.VORDIPLOM_COLORS, getActivity());
|
||||
ct.addDataSetColors(new int[] { R.color.colorful_1, R.color.colorful_2, R.color.colorful_3 } , getActivity());
|
||||
ct.addDataSetColors(ColorTemplate.PASTEL_COLORS, getActivity());
|
||||
|
||||
mChart.setColorTemplate(ct);
|
||||
|
||||
MyMarkerView mv = new MyMarkerView(getActivity(), R.layout.custom_marker_view);
|
||||
mv.setOffsets(-mv.getMeasuredWidth() / 2, -mv.getMeasuredHeight());
|
||||
|
||||
mChart.setMarkerView(mv);
|
||||
|
||||
mChart.setScatterShapes(new ScatterShape[] {ScatterShape.CIRCLE, ScatterShape.SQUARE, ScatterShape.TRIANGLE });
|
||||
mChart.setScatterShapeSize(18f);
|
||||
|
||||
mChart.setHighlightIndicatorEnabled(false);
|
||||
mChart.setDrawBorder(false);
|
||||
// mChart.setBorderStyles(new BorderStyle[] { BorderStyle.LEFT });
|
||||
mChart.setDrawGridBackground(false);
|
||||
mChart.setDrawVerticalGrid(false);
|
||||
mChart.setDrawXLabels(false);
|
||||
|
||||
mChart.setData(generateData(3, 1000));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.support.v4.app.FragmentActivity;
|
|||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentPagerAdapter;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.view.WindowManager;
|
||||
|
||||
/**
|
||||
* Demonstrates how to keep your charts straight forward, simple and beautiful with the MPAndroidChart library.
|
||||
|
@ -18,6 +19,8 @@ public class SimpleChartDemo extends FragmentActivity {
|
|||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
|
||||
ViewPager pager = new ViewPager(this);
|
||||
pager.setId(1000);
|
||||
|
|
|
@ -11,32 +11,28 @@ import java.util.ArrayList;
|
|||
public abstract class SimpleFragment extends Fragment {
|
||||
|
||||
/**
|
||||
* generates some random data, (2 DataSets, 2x20 values)
|
||||
* generates some random data
|
||||
* @return
|
||||
*/
|
||||
protected ChartData generateData() {
|
||||
protected ChartData generateData(int dataSets, float range) {
|
||||
|
||||
int count = 20;
|
||||
|
||||
ArrayList<String> xVals = new ArrayList<String>();
|
||||
ArrayList<Entry> entries1 = new ArrayList<Entry>();
|
||||
ArrayList<Entry> entries2 = new ArrayList<Entry>();
|
||||
|
||||
for(int i = 0; i < count; i++) {
|
||||
xVals.add("entry" + (i+1));
|
||||
|
||||
entries1.add(new Entry((float) (Math.random() * 10000), i));
|
||||
entries2.add(new Entry((float) (Math.random() * 10000), i));
|
||||
}
|
||||
|
||||
DataSet ds1 = new DataSet(entries1, "Company A");
|
||||
DataSet ds2 = new DataSet(entries1, "Company B");
|
||||
int count = 12;
|
||||
|
||||
ArrayList<DataSet> sets = new ArrayList<DataSet>();
|
||||
sets.add(ds1);
|
||||
sets.add(ds2);
|
||||
|
||||
ChartData d = new ChartData(xVals, sets);
|
||||
for(int i = 0; i < dataSets; i++) {
|
||||
|
||||
ArrayList<Entry> entries = new ArrayList<Entry>();
|
||||
|
||||
for(int j = 0; j < count; j++) {
|
||||
entries.add(new Entry((float) (Math.random() * range), j));
|
||||
}
|
||||
|
||||
DataSet ds = new DataSet(entries, getLabel(i));
|
||||
sets.add(ds);
|
||||
}
|
||||
|
||||
ChartData d = new ChartData(getXVals(), sets);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
@ -67,4 +63,15 @@ public abstract class SimpleFragment extends Fragment {
|
|||
ChartData d = new ChartData(xVals, ds1);
|
||||
return d;
|
||||
}
|
||||
|
||||
private String[] mLabels = new String[] { "Company A", "Company B", "Company C", "Company D", "Company E", "Company F" };
|
||||
private String[] mXVals = new String[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec" };
|
||||
|
||||
private String getLabel(int i) {
|
||||
return mLabels[i];
|
||||
}
|
||||
|
||||
private String[] getXVals() {
|
||||
return mXVals;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ import com.github.mikephil.charting.utils.ColorTemplate;
|
|||
public class BarChart extends BarLineChartBase {
|
||||
|
||||
/** space indicator between the bars 0.1f == 10 % */
|
||||
private float mBarSpace = 0.1f;
|
||||
private float mBarSpace = 0.15f;
|
||||
|
||||
/** indicates the angle of the 3d effect */
|
||||
private float mSkew = 0.3f;
|
||||
|
|
|
@ -447,23 +447,33 @@ public abstract class BarLineChartBase extends Chart {
|
|||
*/
|
||||
public void prepareLegend() {
|
||||
|
||||
String[] labels = new String[mCt.getColorCount()];
|
||||
int cnt = 0;
|
||||
ArrayList<String> labels = new ArrayList<String>();
|
||||
ArrayList<Integer> colors = new ArrayList<Integer>();
|
||||
|
||||
for (int i = 0; i < mCt.getColors().size(); i++) {
|
||||
for (int j = 0; j < mCt.getColors().get(i).size(); j++) {
|
||||
for (int i = 0; i < mOriginalData.getDataSetCount(); i++) {
|
||||
|
||||
if (i < mOriginalData.getDataSetCount()) {
|
||||
ArrayList<Integer> clrs = mCt.getDataSetColors(i % mCt.getColors().size());
|
||||
|
||||
labels[cnt] = mOriginalData.getDataSetByIndex(i).getLabel();
|
||||
cnt++;
|
||||
for (int j = 0; j < clrs.size(); j++) {
|
||||
|
||||
// if multiple colors are set for a DataSet, group them
|
||||
if(j < clrs.size()-1) {
|
||||
|
||||
labels.add(null);
|
||||
} else { // add label to the last entry
|
||||
|
||||
String label = mOriginalData.getDataSetByIndex(i).getLabel();
|
||||
labels.add(label);
|
||||
}
|
||||
|
||||
colors.add(clrs.get(j));
|
||||
}
|
||||
}
|
||||
|
||||
Legend l = new Legend(mCt.getColorsAsArray(), labels);
|
||||
Legend l = new Legend(colors, labels);
|
||||
|
||||
if (mLegend != null) {
|
||||
// apply the old legend settings to a potential new legend
|
||||
l.apply(mLegend);
|
||||
}
|
||||
|
||||
|
@ -508,17 +518,16 @@ public abstract class BarLineChartBase extends Chart {
|
|||
|
||||
for (int i = 0; i < labels.length; i++) {
|
||||
|
||||
if (labels[i] == null)
|
||||
break;
|
||||
|
||||
mLegend.drawForm(mDrawCanvas, posX, posY, mLegendFormPaint, i);
|
||||
|
||||
// make a step to the left
|
||||
posX += formToTextSpace;
|
||||
|
||||
mLegend.drawLabel(mDrawCanvas, posX, posY + textDrop, mLegendLabelPaint, i);
|
||||
|
||||
posX += Utils.calcTextWidth(mLegendLabelPaint, labels[i]) + entrySpace;
|
||||
if(labels[i] != null) {
|
||||
|
||||
mLegend.drawLabel(mDrawCanvas, posX, posY + textDrop, mLegendLabelPaint, i);
|
||||
posX += Utils.calcTextWidth(mLegendLabelPaint, labels[i]) + entrySpace;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -526,19 +535,32 @@ public abstract class BarLineChartBase extends Chart {
|
|||
|
||||
posX = getWidth() - mOffsetRight + formSize;
|
||||
posY = mOffsetTop;
|
||||
float stack = 0f;
|
||||
boolean wasStacked = false;
|
||||
|
||||
for (int i = 0; i < labels.length; i++) {
|
||||
|
||||
if (labels[i] == null)
|
||||
break;
|
||||
mLegend.drawForm(mDrawCanvas, posX + stack, posY, mLegendFormPaint, i);
|
||||
|
||||
if(labels[i] != null) {
|
||||
|
||||
if(!wasStacked) {
|
||||
mLegend.drawLabel(mDrawCanvas, posX + formToTextSpace, posY + textDrop,
|
||||
mLegendLabelPaint, i);
|
||||
} else {
|
||||
|
||||
mLegend.drawLabel(mDrawCanvas, posX, posY + textDrop + entrySpace,
|
||||
mLegendLabelPaint, i);
|
||||
posY += entrySpace;
|
||||
}
|
||||
|
||||
mLegend.drawForm(mDrawCanvas, posX, posY, mLegendFormPaint, i);
|
||||
|
||||
mLegend.drawLabel(mDrawCanvas, posX + formToTextSpace, posY + textDrop,
|
||||
mLegendLabelPaint, i);
|
||||
|
||||
// make a step down
|
||||
posY += entrySpace;
|
||||
// make a step down
|
||||
posY += entrySpace;
|
||||
stack = 0f;
|
||||
} else {
|
||||
stack += formSize + 4f;
|
||||
wasStacked = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -1249,7 +1271,7 @@ public abstract class BarLineChartBase extends Chart {
|
|||
public boolean hasFixedYValues() {
|
||||
return mFixedYValues;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* sets the color for the grid lines
|
||||
*
|
||||
|
|
|
@ -245,7 +245,7 @@ public abstract class Chart extends View {
|
|||
yVals.add(new Entry(val, j));
|
||||
}
|
||||
|
||||
DataSet set = new DataSet(yVals, "DS " + i);
|
||||
DataSet set = new DataSet(yVals, "DataSet " + i);
|
||||
dataSets.add(set); // add the datasets
|
||||
}
|
||||
// create a data object with the datasets
|
||||
|
@ -913,6 +913,8 @@ public abstract class Chart extends View {
|
|||
*/
|
||||
public void setColorTemplate(ColorTemplate ct) {
|
||||
this.mCt = ct;
|
||||
|
||||
Log.i(LOG_TAG, "ColorTemplate set.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,7 +26,7 @@ public class DataSet {
|
|||
private float mYValueSum = 0f;
|
||||
|
||||
/** label that describes the DataSet or the data the DataSet represents */
|
||||
private String mLabel = "";
|
||||
private String mLabel = "DataSet";
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -128,6 +128,19 @@ public class ColorTemplate {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a single color for one DataSet. Each call of this method will add
|
||||
* one more color for one DataSet to the template.
|
||||
*
|
||||
* @param color
|
||||
* @param c
|
||||
*/
|
||||
public void addDataSetColor(int color, Context c) {
|
||||
addDataSetColors(new int[] {
|
||||
color
|
||||
}, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all color arrays the template represents.
|
||||
*
|
||||
|
|
|
@ -5,6 +5,8 @@ import android.graphics.Canvas;
|
|||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Class representing the legend of the chart.
|
||||
*
|
||||
|
@ -74,6 +76,28 @@ public class Legend {
|
|||
this.mLegendLabels = labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor. Provide colors and labels for the legend.
|
||||
*
|
||||
* @param colors
|
||||
* @param labels
|
||||
*/
|
||||
public Legend(ArrayList<Integer> colors, ArrayList<String> labels) {
|
||||
this();
|
||||
|
||||
if (colors == null || labels == null) {
|
||||
throw new IllegalArgumentException("colors array or labels array is NULL");
|
||||
}
|
||||
|
||||
if (colors.size() != labels.size()) {
|
||||
throw new IllegalArgumentException(
|
||||
"colors array and labels array need to be of same size");
|
||||
}
|
||||
|
||||
this.mColors = Utils.convertIntegers(colors);
|
||||
this.mLegendLabels = Utils.convertStrings(labels);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the maximum length in pixels over all legend labels + their forms
|
||||
*
|
||||
|
@ -85,9 +109,9 @@ public class Legend {
|
|||
int max = 0;
|
||||
|
||||
for (int i = 0; i < mLegendLabels.length; i++) {
|
||||
|
||||
if(mLegendLabels[i] != null) {
|
||||
|
||||
|
||||
if (mLegendLabels[i] != null) {
|
||||
|
||||
int length = Utils.calcTextWidth(p, mLegendLabels[i]);
|
||||
|
||||
if (length > max)
|
||||
|
@ -119,6 +143,7 @@ public class Legend {
|
|||
/**
|
||||
* Sets a custom array of labels for the legend. Make sure the labels array
|
||||
* has the same length as the colors array.
|
||||
*
|
||||
* @param labels
|
||||
*/
|
||||
public void setLegendLabels(String[] labels) {
|
||||
|
@ -286,13 +311,15 @@ public class Legend {
|
|||
|
||||
c.drawText(mLegendLabels[index], x, y, p);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* applies the state from the legend in the parameter to this legend (except colors and labels)
|
||||
* applies the state from the legend in the parameter to this legend (except
|
||||
* colors and labels)
|
||||
*
|
||||
* @param l
|
||||
*/
|
||||
public void apply(Legend l) {
|
||||
|
||||
|
||||
mPosition = l.mPosition;
|
||||
mShape = l.mShape;
|
||||
mTypeface = l.mTypeface;
|
||||
|
|
|
@ -7,6 +7,7 @@ import android.graphics.Rect;
|
|||
import android.util.DisplayMetrics;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* utilities class that has some helper methods
|
||||
|
@ -75,7 +76,7 @@ public abstract class Utils {
|
|||
float dp = px / (metrics.densityDpi / 160f);
|
||||
return dp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* calculates the approximate width of a text, depending on a demo text
|
||||
* avoid repeated calls (e.g. inside drawing methods)
|
||||
|
@ -209,20 +210,20 @@ public abstract class Utils {
|
|||
out[ind--] = ',';
|
||||
charCount++;
|
||||
decimalPointAdded = true;
|
||||
|
||||
// add thousand separators
|
||||
|
||||
// add thousand separators
|
||||
} else if (separateThousands && lval != 0 && charCount > digitCount) {
|
||||
|
||||
if(decimalPointAdded) {
|
||||
|
||||
if((charCount - digitCount) % 4 == 0) {
|
||||
|
||||
if (decimalPointAdded) {
|
||||
|
||||
if ((charCount - digitCount) % 4 == 0) {
|
||||
out[ind--] = '.';
|
||||
charCount++;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
if((charCount - digitCount) % 4 == 3) {
|
||||
|
||||
if ((charCount - digitCount) % 4 == 3) {
|
||||
out[ind--] = '.';
|
||||
charCount++;
|
||||
}
|
||||
|
@ -254,4 +255,38 @@ public abstract class Utils {
|
|||
final long shifted = Math.round(number * magnitude);
|
||||
return shifted / magnitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the provided Integer ArrayList to an int array.
|
||||
*
|
||||
* @param integers
|
||||
* @return
|
||||
*/
|
||||
public static int[] convertIntegers(ArrayList<Integer> integers) {
|
||||
|
||||
int[] ret = new int[integers.size()];
|
||||
|
||||
for (int i = 0; i < ret.length; i++) {
|
||||
ret[i] = integers.get(i).intValue();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the provided String ArrayList to a String array.
|
||||
*
|
||||
* @param labels
|
||||
* @return
|
||||
*/
|
||||
public static String[] convertStrings(ArrayList<String> strings) {
|
||||
|
||||
String[] ret = new String[strings.size()];
|
||||
|
||||
for (int i = 0; i < ret.length; i++) {
|
||||
ret[i] = strings.get(i);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
BIN
screenshots/smart_legends.png
Normal file
BIN
screenshots/smart_legends.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 81 KiB |
Loading…
Add table
Reference in a new issue