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:
Philipp Jahoda 2014-05-27 18:46:32 +02:00
parent c73d50dc51
commit 1ab90fe1bc
13 changed files with 1453 additions and 1223 deletions

View file

@ -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);

View file

@ -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) {

View file

@ -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

View file

@ -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) {

View file

@ -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);
}

View file

@ -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
*

View file

@ -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>();

View 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;
}
}

View file

@ -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;
}
}
}

View file

@ -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();
}

View file

@ -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]);
}

View file

@ -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;