Improved the highlighting/selecting. New object Highlight that contains the x-index and the DataSet index of the selected value.
This commit is contained in:
parent
c73d50dc51
commit
1ab90fe1bc
13 changed files with 1453 additions and 1223 deletions
|
@ -46,8 +46,8 @@ public class LineChartActivity extends Activity implements OnSeekBarChangeListen
|
|||
// mChart.setRoundedYLegend(false);
|
||||
// mChart.setStartAtZero(true);
|
||||
mChart.setDrawYValues(false);
|
||||
mChart.setLineWidth(4f);
|
||||
mChart.setCircleSize(4f);
|
||||
mChart.setLineWidth(5f);
|
||||
mChart.setCircleSize(5f);
|
||||
// mChart.setSpacePercent(20, 10);
|
||||
mChart.setYLegendCount(6);
|
||||
mChart.setTouchEnabled(true);
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.example.mpchartexample;
|
|||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
@ -16,11 +17,13 @@ import com.github.mikephil.charting.Approximator.ApproximatorType;
|
|||
import com.github.mikephil.charting.ChartData;
|
||||
import com.github.mikephil.charting.ColorTemplate;
|
||||
import com.github.mikephil.charting.DataSet;
|
||||
import com.github.mikephil.charting.Highlight;
|
||||
import com.github.mikephil.charting.LineChart;
|
||||
import com.github.mikephil.charting.OnChartValueSelectedListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class MultiLineChartActivity extends Activity implements OnSeekBarChangeListener {
|
||||
public class MultiLineChartActivity extends Activity implements OnSeekBarChangeListener, OnChartValueSelectedListener {
|
||||
|
||||
private LineChart mChart;
|
||||
private SeekBar mSeekBarX, mSeekBarY;
|
||||
|
@ -44,6 +47,7 @@ public class MultiLineChartActivity extends Activity implements OnSeekBarChangeL
|
|||
mChart = (LineChart) findViewById(R.id.chart1);
|
||||
mChart.setColorTemplate(new ColorTemplate(ColorTemplate.getColors(this, ColorTemplate.JOYFUL_COLORS)));
|
||||
mChart.setDrawTopYLegendEntry(false);
|
||||
mChart.setOnChartValueSelectedListener(this);
|
||||
|
||||
// mChart.setDrawFilled(true);
|
||||
// mChart.setRoundedYLegend(false);
|
||||
|
@ -191,6 +195,17 @@ public class MultiLineChartActivity extends Activity implements OnSeekBarChangeL
|
|||
mChart.setData(data);
|
||||
mChart.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValuesSelected(float[] values, Highlight[] highlights) {
|
||||
Log.i("VALS SELECTED", "Value: " + values[0] + ", xIndex: " + highlights[0].getXIndex() + ", DataSet index: " + highlights[0].getDataSetIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.example.mpchartexample;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
@ -15,10 +13,13 @@ import android.widget.TextView;
|
|||
import com.github.mikephil.charting.ChartData;
|
||||
import com.github.mikephil.charting.ColorTemplate;
|
||||
import com.github.mikephil.charting.DataSet;
|
||||
import com.github.mikephil.charting.Highlight;
|
||||
import com.github.mikephil.charting.OnChartValueSelectedListener;
|
||||
import com.github.mikephil.charting.PieChart;
|
||||
import com.github.mikephil.charting.Series;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PieChartActivity extends Activity implements OnSeekBarChangeListener, OnChartValueSelectedListener {
|
||||
|
||||
private PieChart mChart;
|
||||
|
@ -151,16 +152,14 @@ public class PieChartActivity extends Activity implements OnSeekBarChangeListene
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onValuesSelected(float[] values, int[] indices) {
|
||||
StringBuffer a = new StringBuffer();
|
||||
public void onValuesSelected(float[] values, Highlight[] highs) {
|
||||
|
||||
StringBuffer a = new StringBuffer();
|
||||
|
||||
for (int i = 0; i < values.length; i++)
|
||||
a.append("val: " + values[i] + ", ind: " + indices[i] + "\n");
|
||||
for (int i = 0; i < values.length; i++)
|
||||
a.append("val: " + values[i] + ", x-ind: " + highs[i].getXIndex() + ", dataset-ind: " + highs[i].getDataSetIndex() + "\n");
|
||||
|
||||
Log.i("PieChart", "Selected: " + a.toString());
|
||||
|
||||
// immediately unselect
|
||||
// mChart.highlightValues(null);
|
||||
Log.i("PieChart", "Selected: " + a.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -127,7 +127,7 @@ public class BarChart extends BarLineChartBase {
|
|||
|
||||
for (int i = 0; i < mIndicesToHightlight.length; i++) {
|
||||
|
||||
int index = mIndicesToHightlight[i];
|
||||
int index = mIndicesToHightlight[i].getXIndex();
|
||||
|
||||
// check outofbounds
|
||||
if (index < mData.getYValCount() && index >= 0) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -248,9 +248,9 @@ public class BarLineChartTouchListener extends SimpleOnGestureListener implement
|
|||
@Override
|
||||
public boolean onSingleTapConfirmed(MotionEvent e) {
|
||||
|
||||
int highlightindex = mChart.getIndexByTouchPoint(e.getX(), e.getY());
|
||||
Highlight h = mChart.getIndexByTouchPoint(e.getX(), e.getY());
|
||||
|
||||
mChart.highlightValues(new int[] {highlightindex});
|
||||
mChart.highlightValues(new Highlight[] { h });
|
||||
|
||||
return super.onSingleTapConfirmed(e);
|
||||
}
|
||||
|
|
|
@ -8,12 +8,12 @@ import android.graphics.Canvas;
|
|||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.util.AttributeSet;
|
||||
|
@ -200,7 +200,7 @@ public abstract class Chart extends View {
|
|||
mInfoPaint.setTextSize(Utils.convertDpToPixel(12f));
|
||||
|
||||
mValuePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mValuePaint.setColor(Color.rgb(186, 89, 248)); // orange
|
||||
mValuePaint.setColor(Color.rgb(63, 63, 63));
|
||||
mValuePaint.setTextAlign(Align.CENTER);
|
||||
mValuePaint.setTextSize(Utils.convertDpToPixel(9f));
|
||||
|
||||
|
@ -550,9 +550,10 @@ public abstract class Chart extends View {
|
|||
/** BELOW THIS CODE FOR HIGHLIGHTING */
|
||||
|
||||
/**
|
||||
* array of integers that reference the highlighted slices in the pie chart
|
||||
* array of Highlight objects that reference the highlighted slices in the
|
||||
* pie chart
|
||||
*/
|
||||
protected int[] mIndicesToHightlight = new int[0];
|
||||
protected Highlight[] mIndicesToHightlight = new Highlight[0];
|
||||
|
||||
/**
|
||||
* checks if the given index is set for highlighting or not
|
||||
|
@ -560,14 +561,17 @@ public abstract class Chart extends View {
|
|||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public boolean needsHighlight(int index) {
|
||||
public boolean needsHighlight(int index, int dataSet) {
|
||||
|
||||
// no highlight
|
||||
if (!valuesToHighlight())
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < mIndicesToHightlight.length; i++)
|
||||
if (mIndicesToHightlight[i] == index)
|
||||
|
||||
// check if the xvalue for the given dataset needs highlight
|
||||
if (mIndicesToHightlight[i].getXIndex() == index
|
||||
&& mIndicesToHightlight[i].getDataSetIndex() == dataSet)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -581,20 +585,19 @@ public abstract class Chart extends View {
|
|||
* @return
|
||||
*/
|
||||
public boolean valuesToHighlight() {
|
||||
return mIndicesToHightlight == null || mIndicesToHightlight.length == 0
|
||||
|| mIndicesToHightlight[0] < 0 ? false
|
||||
return mIndicesToHightlight == null || mIndicesToHightlight.length == 0 ? false
|
||||
: true;
|
||||
}
|
||||
|
||||
/**
|
||||
* highlights the value at the given index of the values list
|
||||
*
|
||||
* @param indices
|
||||
* @param highs
|
||||
*/
|
||||
public void highlightValues(int[] indices) {
|
||||
public void highlightValues(Highlight[] highs) {
|
||||
|
||||
// set the indices to highlight
|
||||
mIndicesToHightlight = indices;
|
||||
mIndicesToHightlight = highs;
|
||||
|
||||
// redraw the chart
|
||||
invalidate();
|
||||
|
@ -605,13 +608,13 @@ public abstract class Chart extends View {
|
|||
mSelectionListener.onNothingSelected();
|
||||
else {
|
||||
|
||||
float[] values = new float[indices.length];
|
||||
float[] values = new float[highs.length];
|
||||
|
||||
for (int i = 0; i < values.length; i++)
|
||||
values[i] = getYValue(indices[i]);
|
||||
values[i] = getYValueByDataSetIndex(highs[i].getXIndex(), highs[i].getDataSetIndex());
|
||||
|
||||
// notify the listener
|
||||
mSelectionListener.onValuesSelected(values, indices);
|
||||
mSelectionListener.onValuesSelected(values, highs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -639,31 +642,29 @@ public abstract class Chart extends View {
|
|||
protected void drawMarkerView() {
|
||||
|
||||
// if there is no marker view or no values are to highlight, return
|
||||
if (mMarkerView == null || !mDrawMarkerView || !valuesToHighlight()
|
||||
|| mIndicesToHightlight[0] < 0
|
||||
|| mIndicesToHightlight[0] >= mData.getYValCount())
|
||||
if (mMarkerView == null || !mDrawMarkerView || !valuesToHighlight())
|
||||
return;
|
||||
|
||||
int index = mIndicesToHightlight[0];
|
||||
float value = getYValue(index);
|
||||
|
||||
// position of the marker depends on selected value index and value
|
||||
float[] pts = new float[] {
|
||||
index, value
|
||||
};
|
||||
transformPointArray(pts);
|
||||
|
||||
mMarkerPosX = pts[0] - mMarkerView.getWidth() / 2f;
|
||||
mMarkerPosY = pts[1] - mMarkerView.getHeight();
|
||||
|
||||
Log.i("", "h: " + mMarkerView.getHeight() + ", w: " + mMarkerView.getWidth());
|
||||
|
||||
// translate to marker position
|
||||
mDrawCanvas.translate(mMarkerPosX, mMarkerPosY);
|
||||
mMarkerView.draw(mDrawCanvas);
|
||||
|
||||
// translate back
|
||||
mDrawCanvas.translate(-mMarkerPosX, -mMarkerPosY);
|
||||
// int index = mIndicesToHightlight[0];
|
||||
// float value = getYValue(index);
|
||||
//
|
||||
// // position of the marker depends on selected value index and value
|
||||
// float[] pts = new float[] {
|
||||
// index, value
|
||||
// };
|
||||
// transformPointArray(pts);
|
||||
//
|
||||
// mMarkerPosX = pts[0] - mMarkerView.getWidth() / 2f;
|
||||
// mMarkerPosY = pts[1] - mMarkerView.getHeight();
|
||||
//
|
||||
// Log.i("", "h: " + mMarkerView.getHeight() + ", w: " + mMarkerView.getWidth());
|
||||
//
|
||||
// // translate to marker position
|
||||
// mDrawCanvas.translate(mMarkerPosX, mMarkerPosY);
|
||||
// mMarkerView.draw(mDrawCanvas);
|
||||
//
|
||||
// // translate back
|
||||
// mDrawCanvas.translate(-mMarkerPosX, -mMarkerPosY);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1107,6 +1108,17 @@ public abstract class Chart extends View {
|
|||
DataSet set = mData.getDataSetByType(type);
|
||||
return set.getYVals().get(index).getVal();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the y-value for the given x-index and DataSet index
|
||||
* @param index
|
||||
* @param dataSet
|
||||
* @return
|
||||
*/
|
||||
public float getYValueByDataSetIndex(int index, int dataSet) {
|
||||
DataSet set = mData.getDataSetByIndex(dataSet);
|
||||
return set.getYVals().get(index).getVal();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the DataSet with the given index in the DataSet array held by the
|
||||
|
@ -1153,6 +1165,29 @@ public abstract class Chart extends View {
|
|||
return mData.getDataSetByType(type).getYVals().get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the y-values from the Series object at the given index across all
|
||||
* DataSets
|
||||
*
|
||||
* @param xIndex
|
||||
* @return
|
||||
*/
|
||||
public ArrayList<Float> getYValsAtIndex(int xIndex) {
|
||||
|
||||
ArrayList<Float> vals = new ArrayList<Float>();
|
||||
|
||||
for (int i = 0; i < mData.getDataSetCount(); i++) {
|
||||
|
||||
// extract all y-values from all DataSets at the given x-index
|
||||
float yVal = mData.getDataSetByIndex(i).getYValForXIndex(xIndex);
|
||||
|
||||
if (!Float.isNaN(yVal))
|
||||
vals.add(yVal);
|
||||
}
|
||||
|
||||
return vals;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the chartdata object the chart represents
|
||||
*
|
||||
|
|
|
@ -81,6 +81,36 @@ public class DataSet {
|
|||
return mYVals.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the value of the Series object at the given xIndex
|
||||
*
|
||||
* @param xIndex
|
||||
* @return
|
||||
*/
|
||||
public float getYValForXIndex(int xIndex) {
|
||||
|
||||
Series s = getSeriesForXIndex(xIndex);
|
||||
|
||||
if(s != null) return s.getVal();
|
||||
else return Float.NaN;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the Series object at the given xIndex
|
||||
*
|
||||
* @param xIndex
|
||||
* @return
|
||||
*/
|
||||
public Series getSeriesForXIndex(int xIndex) {
|
||||
|
||||
for (int i = 0; i < mYVals.size(); i++) {
|
||||
if (xIndex == mYVals.get(i).getXIndex())
|
||||
return mYVals.get(i);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ArrayList<Series> getYVals() {
|
||||
return mYVals;
|
||||
}
|
||||
|
@ -115,7 +145,7 @@ public class DataSet {
|
|||
ArrayList<DataSet> dataSets = new ArrayList<DataSet>();
|
||||
|
||||
for (int i = 0; i < yValues.size(); i++) {
|
||||
|
||||
|
||||
Double[] curValues = yValues.get(i);
|
||||
|
||||
ArrayList<Series> series = new ArrayList<Series>();
|
||||
|
|
45
MPChartLib/src/com/github/mikephil/charting/Highlight.java
Normal file
45
MPChartLib/src/com/github/mikephil/charting/Highlight.java
Normal file
|
@ -0,0 +1,45 @@
|
|||
|
||||
package com.github.mikephil.charting;
|
||||
|
||||
/**
|
||||
* Contains information needed to determine the highlighted value.
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
public class Highlight {
|
||||
|
||||
/** the x-index of the highlighted value */
|
||||
private int mXIndex;
|
||||
|
||||
/** the index of the dataset the highlighted value is in */
|
||||
private int mDataSetIndex;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*
|
||||
* @param x the index of the highlighted value on the x-axis
|
||||
* @param dataSet the index of the DataSet the highlighted value belongs to
|
||||
*/
|
||||
public Highlight(int x, int dataSet) {
|
||||
this.mXIndex = x;
|
||||
this.mDataSetIndex = dataSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the index of the DataSet the highlighted value is in
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getDataSetIndex() {
|
||||
return mDataSetIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the index of the highlighted value on the x-axis
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getXIndex() {
|
||||
return mXIndex;
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
package com.github.mikephil.charting;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -11,370 +12,384 @@ import android.util.AttributeSet;
|
|||
|
||||
public class LineChart extends BarLineChartBase {
|
||||
|
||||
/** the radius of the circle-shaped value indicators */
|
||||
protected float mCircleSize = 4f;
|
||||
/** the radius of the circle-shaped value indicators */
|
||||
protected float mCircleSize = 4f;
|
||||
|
||||
/** the width of the drawn data lines */
|
||||
protected float mLineWidth = 1f;
|
||||
/** the width of the drawn data lines */
|
||||
protected float mLineWidth = 1f;
|
||||
|
||||
/** the width of the highlighning line */
|
||||
protected float mHighlightWidth = 3f;
|
||||
/** the width of the highlighning line */
|
||||
protected float mHighlightWidth = 3f;
|
||||
|
||||
/** if true, the data will also be drawn filled */
|
||||
protected boolean mDrawFilled = false;
|
||||
/** if true, the data will also be drawn filled */
|
||||
protected boolean mDrawFilled = false;
|
||||
|
||||
/** if true, drawing circles is enabled */
|
||||
protected boolean mDrawCircles = true;
|
||||
/** if true, drawing circles is enabled */
|
||||
protected boolean mDrawCircles = true;
|
||||
|
||||
/** paint for the filled are (if enabled) below the chart line */
|
||||
protected Paint mFilledPaint;
|
||||
/** paint for the filled are (if enabled) below the chart line */
|
||||
protected Paint mFilledPaint;
|
||||
|
||||
/** paint for the outer circle of the value indicators */
|
||||
protected Paint mCirclePaintOuter;
|
||||
/** paint for the inner circle of the value indicators */
|
||||
protected Paint mCirclePaintInner;
|
||||
|
||||
/** paint for the inner circle of the value indicators */
|
||||
protected Paint mCirclePaintInner;
|
||||
public LineChart(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public LineChart(Context context) {
|
||||
super(context);
|
||||
}
|
||||
public LineChart(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public LineChart(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
public LineChart(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
public LineChart(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
mCircleSize = Utils.convertDpToPixel(mCircleSize);
|
||||
|
||||
mCircleSize = Utils.convertDpToPixel(mCircleSize);
|
||||
mFilledPaint = new Paint();
|
||||
mFilledPaint.setStyle(Paint.Style.FILL);
|
||||
mFilledPaint.setColor(mColorDarkBlue);
|
||||
mFilledPaint.setAlpha(130); // alpha ~55%
|
||||
|
||||
mFilledPaint = new Paint();
|
||||
mFilledPaint.setStyle(Paint.Style.FILL);
|
||||
mFilledPaint.setColor(mColorDarkBlue);
|
||||
mFilledPaint.setAlpha(130); // alpha ~55%
|
||||
mCirclePaintInner = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mCirclePaintInner.setStyle(Paint.Style.FILL);
|
||||
mCirclePaintInner.setColor(Color.WHITE);
|
||||
|
||||
mCirclePaintOuter = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
// mCirclePaint.setStrokeWidth(5f);
|
||||
mCirclePaintOuter.setStyle(Paint.Style.FILL);
|
||||
mCirclePaintOuter.setColor(mColorDarkBlue);
|
||||
mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mHighlightPaint.setStyle(Paint.Style.STROKE);
|
||||
mHighlightPaint.setStrokeWidth(2f);
|
||||
mHighlightPaint.setColor(Color.rgb(255, 187, 115));
|
||||
}
|
||||
|
||||
mCirclePaintInner = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mCirclePaintInner.setStyle(Paint.Style.FILL);
|
||||
mCirclePaintInner.setColor(Color.WHITE);
|
||||
@Override
|
||||
protected void prepareDataPaints(ColorTemplate ct) {
|
||||
|
||||
mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mHighlightPaint.setStyle(Paint.Style.STROKE);
|
||||
mHighlightPaint.setStrokeWidth(2f);
|
||||
mHighlightPaint.setColor(Color.rgb(255, 187, 115));
|
||||
}
|
||||
if (ct == null)
|
||||
return;
|
||||
|
||||
@Override
|
||||
protected void prepareDataPaints(ColorTemplate ct) {
|
||||
mDrawPaints = new Paint[ct.getColors().size()];
|
||||
|
||||
if (ct == null)
|
||||
return;
|
||||
for (int i = 0; i < ct.getColors().size(); i++) {
|
||||
mDrawPaints[i] = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mDrawPaints[i].setStrokeWidth(mLineWidth);
|
||||
mDrawPaints[i].setStyle(Style.FILL);
|
||||
mDrawPaints[i].setColor(ct.getColors().get(i));
|
||||
}
|
||||
}
|
||||
|
||||
mDrawPaints = new Paint[ct.getColors().size()];
|
||||
@Override
|
||||
protected void drawHighlights() {
|
||||
|
||||
for (int i = 0; i < ct.getColors().size(); i++) {
|
||||
mDrawPaints[i] = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mDrawPaints[i].setStrokeWidth(mLineWidth);
|
||||
mDrawPaints[i].setStyle(Style.FILL);
|
||||
mDrawPaints[i].setColor(ct.getColors().get(i));
|
||||
}
|
||||
}
|
||||
// if there are values to highlight and highlighnting is enabled, do it
|
||||
if (mHighlightEnabled && valuesToHighlight()) {
|
||||
|
||||
@Override
|
||||
protected void drawHighlights() {
|
||||
for (int i = 0; i < mIndicesToHightlight.length; i++) {
|
||||
|
||||
// if there are values to highlight and highlighnting is enabled, do it
|
||||
if (mHighlightEnabled && valuesToHighlight()) {
|
||||
int xIndex = mIndicesToHightlight[i].getXIndex();
|
||||
DataSet set = getDataSetByIndex(mIndicesToHightlight[i].getDataSetIndex());
|
||||
|
||||
for (int i = 0; i < mIndicesToHightlight.length; i++) {
|
||||
// check outofbounds
|
||||
if (xIndex < set.getYValCount() && xIndex >= 0) {
|
||||
|
||||
// RectF highlight = new RectF(mIndicesToHightlight[i] -
|
||||
// mHighlightWidth / 2,
|
||||
// mYChartMax, mIndicesToHightlight[i] + mHighlightWidth / 2,
|
||||
// mYChartMin);
|
||||
// transformRect(highlight);
|
||||
// mDrawCanvas.drawRect(highlight, mHighlightPaint);
|
||||
float[] pts = new float[] {
|
||||
xIndex, mYChartMax, xIndex, mYChartMin, 0,
|
||||
set.getYValForXIndex(xIndex), mDeltaX, set.getYValForXIndex(xIndex)
|
||||
};
|
||||
|
||||
int index = mIndicesToHightlight[i];
|
||||
transformPointArray(pts);
|
||||
// draw the highlight lines
|
||||
mDrawCanvas.drawLines(pts, mHighlightPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check outofbounds
|
||||
if (index < mData.getYValCount() && index >= 0) {
|
||||
/**
|
||||
* draws the given y values to the screen
|
||||
*/
|
||||
@Override
|
||||
protected void drawData() {
|
||||
|
||||
float[] pts = new float[] { index, mYChartMax, index, mYChartMin, 0,
|
||||
getYValue(index), mDeltaX, getYValue(index) };
|
||||
ArrayList<DataSet> dataSets = mData.getDataSets();
|
||||
|
||||
transformPointArray(pts);
|
||||
// draw the highlight lines
|
||||
mDrawCanvas.drawLines(pts, mHighlightPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < mData.getDataSetCount(); i++) {
|
||||
|
||||
/**
|
||||
* draws the given y values to the screen
|
||||
*/
|
||||
@Override
|
||||
protected void drawData() {
|
||||
DataSet dataSet = dataSets.get(i);
|
||||
ArrayList<Series> series = dataSet.getYVals();
|
||||
|
||||
ArrayList<DataSet> dataSets = mData.getDataSets();
|
||||
float[] valuePoints = new float[series.size() * 2];
|
||||
|
||||
for (int i = 0; i < mData.getDataSetCount(); i++) {
|
||||
for (int j = 0; j < valuePoints.length; j += 2) {
|
||||
valuePoints[j] = series.get(j / 2).getXIndex();
|
||||
valuePoints[j + 1] = series.get(j / 2).getVal();
|
||||
}
|
||||
|
||||
DataSet dataSet = dataSets.get(i);
|
||||
ArrayList<Series> series = dataSet.getYVals();
|
||||
transformPointArray(valuePoints);
|
||||
|
||||
float[] valuePoints = new float[series.size() * 2];
|
||||
for (int j = 0; j < valuePoints.length - 2; j += 2) {
|
||||
|
||||
for (int j = 0; j < valuePoints.length; j += 2) {
|
||||
valuePoints[j] = series.get(j / 2).getXIndex();
|
||||
valuePoints[j + 1] = series.get(j / 2).getVal();
|
||||
}
|
||||
if (isOffCanvasRight(valuePoints[j]))
|
||||
break;
|
||||
|
||||
transformPointArray(valuePoints);
|
||||
// make sure the lines don't do shitty things outside bounds
|
||||
if (j != 0 && isOffCanvasLeft(valuePoints[j - 1]))
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < valuePoints.length - 2; j += 2) {
|
||||
mDrawCanvas.drawLine(valuePoints[j], valuePoints[j + 1], valuePoints[j + 2],
|
||||
valuePoints[j + 3],
|
||||
mDrawPaints[i % mDrawPaints.length]);
|
||||
}
|
||||
}
|
||||
|
||||
if (valuePoints[j] > mContentRect.right)
|
||||
break;
|
||||
// if data is drawn filled
|
||||
if (mDrawFilled) {
|
||||
|
||||
// make sure the lines don't do shitty things outside bounds
|
||||
if (j != 0 && valuePoints[j - 1] < mContentRect.left)
|
||||
continue;
|
||||
Path filled = new Path();
|
||||
filled.moveTo(0, getYValue(0));
|
||||
|
||||
mDrawCanvas.drawLine(valuePoints[j], valuePoints[j + 1], valuePoints[j + 2], valuePoints[j + 3],
|
||||
mDrawPaints[i % mDrawPaints.length]);
|
||||
}
|
||||
}
|
||||
// create a new path
|
||||
for (int x = 1; x < mData.getYValCount(); x++) {
|
||||
|
||||
// if data is drawn filled
|
||||
if (mDrawFilled) {
|
||||
filled.lineTo(x, getYValue(x));
|
||||
}
|
||||
|
||||
Path filled = new Path();
|
||||
filled.moveTo(0, getYValue(0));
|
||||
// close up
|
||||
filled.lineTo(mData.getXValCount() - 1, mYChartMin);
|
||||
filled.lineTo(0f, mYChartMin);
|
||||
filled.close();
|
||||
|
||||
// create a new path
|
||||
for (int x = 1; x < mData.getYValCount(); x++) {
|
||||
transformPath(filled);
|
||||
|
||||
filled.lineTo(x, getYValue(x));
|
||||
}
|
||||
mDrawCanvas.drawPath(filled, mFilledPaint);
|
||||
}
|
||||
}
|
||||
|
||||
// close up
|
||||
filled.lineTo(mData.getXValCount() - 1, mYChartMin);
|
||||
filled.lineTo(0f, mYChartMin);
|
||||
filled.close();
|
||||
@Override
|
||||
protected void drawValues() {
|
||||
|
||||
transformPath(filled);
|
||||
// if values are drawn
|
||||
if (mDrawYValues && mData.getYValCount() < mMaxVisibleCount * mScaleX) {
|
||||
|
||||
mDrawCanvas.drawPath(filled, mFilledPaint);
|
||||
}
|
||||
}
|
||||
// make sure the values do not interfear with the circles
|
||||
int valOffset = (int) (mCircleSize * 1.7f);
|
||||
|
||||
@Override
|
||||
protected void drawValues() {
|
||||
|
||||
// if values are drawn
|
||||
if (mDrawYValues && mData.getYValCount() < mMaxVisibleCount * mScaleX) {
|
||||
if (!mDrawCircles)
|
||||
valOffset = valOffset / 2;
|
||||
|
||||
float[] valuePoints = new float[mData.getYValCount() * 2];
|
||||
ArrayList<DataSet> dataSets = mData.getDataSets();
|
||||
|
||||
for (int i = 0; i < valuePoints.length; i += 2) {
|
||||
valuePoints[i] = i / 2;
|
||||
valuePoints[i + 1] = getYValue(i / 2);
|
||||
}
|
||||
|
||||
transformPointArray(valuePoints);
|
||||
|
||||
for (int i = 0; i < valuePoints.length; i += 2) {
|
||||
|
||||
float val = getYValue(i / 2);
|
||||
|
||||
if (mDrawUnitInChart) {
|
||||
|
||||
mDrawCanvas.drawText(mFormatValue.format(val) + mUnit,
|
||||
valuePoints[i], valuePoints[i + 1] - 12, mValuePaint);
|
||||
} else {
|
||||
|
||||
mDrawCanvas.drawText(mFormatValue.format(val), valuePoints[i],
|
||||
valuePoints[i + 1] - 12, mValuePaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* draws the circle value indicators
|
||||
*/
|
||||
@Override
|
||||
protected void drawAdditional() {
|
||||
// if drawing circles is enabled
|
||||
if (mDrawCircles) {
|
||||
|
||||
ArrayList<DataSet> dataSets = mData.getDataSets();
|
||||
|
||||
for (int i = 0; i < mData.getDataSetCount(); i++) {
|
||||
|
||||
DataSet dataSet = dataSets.get(i);
|
||||
ArrayList<Series> series = dataSet.getYVals();
|
||||
|
||||
float[] positions = new float[dataSet.getYValCount() * 2];
|
||||
|
||||
for (int j = 0; j < positions.length; j += 2) {
|
||||
positions[j] = series.get(j / 2).getXIndex();
|
||||
positions[j + 1] = series.get(j / 2).getVal();
|
||||
}
|
||||
|
||||
transformPointArray(positions);
|
||||
|
||||
for (int j = 0; j < positions.length; j += 2) {
|
||||
|
||||
// make sure the circles don't do shitty things outside bounds
|
||||
if (positions[j] < mContentRect.left || positions[j] > mContentRect.right)
|
||||
continue;
|
||||
|
||||
mDrawCanvas.drawCircle(positions[j], positions[j + 1], mCircleSize, mDrawPaints[i % mDrawPaints.length]);
|
||||
mDrawCanvas.drawCircle(positions[j], positions[j + 1], mCircleSize / 2, mCirclePaintInner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set this to true to enable the drawing of circle indicators
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void setDrawCircles(boolean enabled) {
|
||||
this.mDrawCircles = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if drawing circles is enabled, false if not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isDrawCirclesEnabled() {
|
||||
return mDrawCircles;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the size (radius) of the circle shpaed value indicators, default size = 4f
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
public void setCircleSize(float size) {
|
||||
mCircleSize = Utils.convertDpToPixel(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the circlesize
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
public float getCircleSize(float size) {
|
||||
return Utils.convertPixelsToDp(mCircleSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* set if the chartdata should be drawn as a line or filled default = line / default = false, disabling this will
|
||||
* give up to 20% performance boost on large datasets
|
||||
*
|
||||
* @param filled
|
||||
*/
|
||||
public void setDrawFilled(boolean filled) {
|
||||
mDrawFilled = filled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if filled drawing is enabled, false if not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isDrawFilledEnabled() {
|
||||
return mDrawFilled;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the line width of the chart (min = 0.5f, max = 10f); default 1f NOTE: thinner line == better performance,
|
||||
* thicker line == worse performance
|
||||
*
|
||||
* @param width
|
||||
*/
|
||||
public void setLineWidth(float width) {
|
||||
|
||||
if (width < 0.5f)
|
||||
width = 0.5f;
|
||||
if (width > 10.0f)
|
||||
width = 10.0f;
|
||||
mLineWidth = width;
|
||||
|
||||
for (int i = 0; i < mDrawPaints.length; i++) {
|
||||
mDrawPaints[i].setStrokeWidth(mLineWidth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the width of the drawn chart line
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getLineWidth() {
|
||||
return mLineWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the color for the fill-paint
|
||||
*
|
||||
* @param color
|
||||
*/
|
||||
public void setFillColor(int color) {
|
||||
mFilledPaint.setColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* set the width of the highlightning lines, default 3f
|
||||
*
|
||||
* @param width
|
||||
*/
|
||||
public void setHighlightLineWidth(float width) {
|
||||
mHighlightWidth = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the width of the highlightning line, default 3f
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getHighlightLineWidth() {
|
||||
return mHighlightWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaint(Paint p, int which) {
|
||||
super.setPaint(p, which);
|
||||
|
||||
switch (which) {
|
||||
case PAINT_FILLED:
|
||||
mFilledPaint = p;
|
||||
break;
|
||||
case PAINT_CIRCLES_INNER:
|
||||
mCirclePaintInner = p;
|
||||
break;
|
||||
case PAINT_CIRCLES_OUTER:
|
||||
mCirclePaintOuter = p;
|
||||
break;
|
||||
case PAINT_HIGHLIGHT_LINE:
|
||||
mHighlightPaint = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < mData.getDataSetCount(); i++) {
|
||||
|
||||
DataSet dataSet = dataSets.get(i);
|
||||
ArrayList<Series> series = dataSet.getYVals();
|
||||
|
||||
float[] positions = new float[dataSet.getYValCount() * 2];
|
||||
|
||||
for (int j = 0; j < positions.length; j += 2) {
|
||||
positions[j] = series.get(j / 2).getXIndex();
|
||||
positions[j + 1] = series.get(j / 2).getVal();
|
||||
}
|
||||
|
||||
transformPointArray(positions);
|
||||
|
||||
for (int j = 0; j < positions.length; j += 2) {
|
||||
|
||||
if (isOffCanvasRight(positions[j]))
|
||||
break;
|
||||
|
||||
if (isOffCanvasLeft(positions[j]))
|
||||
continue;
|
||||
|
||||
float val = series.get(j / 2).getVal();
|
||||
|
||||
if (mDrawUnitInChart) {
|
||||
|
||||
mDrawCanvas.drawText(mFormatValue.format(val) + mUnit,
|
||||
positions[j], positions[j + 1] - valOffset, mValuePaint);
|
||||
} else {
|
||||
|
||||
mDrawCanvas.drawText(mFormatValue.format(val), positions[j],
|
||||
positions[j + 1] - valOffset, mValuePaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* draws the circle value indicators
|
||||
*/
|
||||
@Override
|
||||
protected void drawAdditional() {
|
||||
// if drawing circles is enabled
|
||||
if (mDrawCircles) {
|
||||
|
||||
ArrayList<DataSet> dataSets = mData.getDataSets();
|
||||
|
||||
for (int i = 0; i < mData.getDataSetCount(); i++) {
|
||||
|
||||
DataSet dataSet = dataSets.get(i);
|
||||
ArrayList<Series> series = dataSet.getYVals();
|
||||
|
||||
float[] positions = new float[dataSet.getYValCount() * 2];
|
||||
|
||||
for (int j = 0; j < positions.length; j += 2) {
|
||||
positions[j] = series.get(j / 2).getXIndex();
|
||||
positions[j + 1] = series.get(j / 2).getVal();
|
||||
}
|
||||
|
||||
transformPointArray(positions);
|
||||
|
||||
for (int j = 0; j < positions.length; j += 2) {
|
||||
|
||||
if (isOffCanvasRight(positions[j]))
|
||||
break;
|
||||
|
||||
// make sure the circles don't do shitty things outside
|
||||
// bounds
|
||||
if (isOffCanvasLeft(positions[j]))
|
||||
continue;
|
||||
|
||||
mDrawCanvas.drawCircle(positions[j], positions[j + 1], mCircleSize,
|
||||
mDrawPaints[i % mDrawPaints.length]);
|
||||
mDrawCanvas.drawCircle(positions[j], positions[j + 1], mCircleSize / 2,
|
||||
mCirclePaintInner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* set this to true to enable the drawing of circle indicators
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void setDrawCircles(boolean enabled) {
|
||||
this.mDrawCircles = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if drawing circles is enabled, false if not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isDrawCirclesEnabled() {
|
||||
return mDrawCircles;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the size (radius) of the circle shpaed value indicators, default
|
||||
* size = 4f
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
public void setCircleSize(float size) {
|
||||
mCircleSize = Utils.convertDpToPixel(size);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the circlesize
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
public float getCircleSize(float size) {
|
||||
return Utils.convertPixelsToDp(mCircleSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* set if the chartdata should be drawn as a line or filled default = line /
|
||||
* default = false, disabling this will give up to 20% performance boost on
|
||||
* large datasets
|
||||
*
|
||||
* @param filled
|
||||
*/
|
||||
public void setDrawFilled(boolean filled) {
|
||||
mDrawFilled = filled;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if filled drawing is enabled, false if not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isDrawFilledEnabled() {
|
||||
return mDrawFilled;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the line width of the chart (min = 0.5f, max = 10f); default 1f NOTE:
|
||||
* thinner line == better performance, thicker line == worse performance
|
||||
*
|
||||
* @param width
|
||||
*/
|
||||
public void setLineWidth(float width) {
|
||||
|
||||
if (width < 0.5f)
|
||||
width = 0.5f;
|
||||
if (width > 10.0f)
|
||||
width = 10.0f;
|
||||
mLineWidth = width;
|
||||
|
||||
for (int i = 0; i < mDrawPaints.length; i++) {
|
||||
mDrawPaints[i].setStrokeWidth(mLineWidth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the width of the drawn chart line
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getLineWidth() {
|
||||
return mLineWidth;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the color for the fill-paint
|
||||
*
|
||||
* @param color
|
||||
*/
|
||||
public void setFillColor(int color) {
|
||||
mFilledPaint.setColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* set the width of the highlightning lines, default 3f
|
||||
*
|
||||
* @param width
|
||||
*/
|
||||
public void setHighlightLineWidth(float width) {
|
||||
mHighlightWidth = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the width of the highlightning line, default 3f
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getHighlightLineWidth() {
|
||||
return mHighlightWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPaint(Paint p, int which) {
|
||||
super.setPaint(p, which);
|
||||
|
||||
switch (which) {
|
||||
case PAINT_FILLED:
|
||||
mFilledPaint = p;
|
||||
break;
|
||||
case PAINT_CIRCLES_INNER:
|
||||
mCirclePaintInner = p;
|
||||
break;
|
||||
case PAINT_HIGHLIGHT_LINE:
|
||||
mHighlightPaint = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@ package com.github.mikephil.charting;
|
|||
|
||||
public interface OnChartValueSelectedListener {
|
||||
|
||||
public void onValuesSelected(float[] values, int[] indices);
|
||||
public void onValuesSelected(float[] values, Highlight[] highlights);
|
||||
public void onNothingSelected();
|
||||
}
|
||||
|
|
|
@ -289,7 +289,7 @@ public class PieChart extends Chart {
|
|||
for (int i = 0; i < mIndicesToHightlight.length; i++) {
|
||||
|
||||
// get the index to highlight
|
||||
int index = mIndicesToHightlight[i];
|
||||
int index = mIndicesToHightlight[i].getXIndex();
|
||||
|
||||
if (index == 0)
|
||||
angle = mChartAngle;
|
||||
|
@ -322,7 +322,7 @@ public class PieChart extends Chart {
|
|||
|
||||
float newangle = mDrawAngles[i];
|
||||
|
||||
if (!needsHighlight(i)) {
|
||||
if (!needsHighlight(i, 0)) {
|
||||
|
||||
mDrawCanvas.drawArc(mCircleBox, angle, newangle, true, mDrawPaints[i % mDrawPaints.length]);
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ public class PieChartTouchListener extends SimpleOnGestureListener implements On
|
|||
|
||||
int index = mChart.getIndexForAngle(mChart.getAngleForPoint(e.getX(), e.getY()));
|
||||
|
||||
mChart.highlightValues(new int[] {index});
|
||||
mChart.highlightValues(new Highlight[] { new Highlight(index, 0) });
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Add table
Reference in a new issue