Work on highlighting, introduced highlight max distance
This commit is contained in:
parent
423b885745
commit
ac3eafaba9
8 changed files with 157 additions and 137 deletions
|
@ -228,6 +228,7 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
|
||||
// initialize the utils
|
||||
Utils.init(getContext());
|
||||
mMaxHighlightDistance = Utils.convertDpToPixel(70f);
|
||||
|
||||
mDefaultFormatter = new DefaultValueFormatter(1);
|
||||
|
||||
|
@ -483,6 +484,26 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
*/
|
||||
protected Highlight[] mIndicesToHighlight;
|
||||
|
||||
/**
|
||||
* The maximum distance in screen pixels away from an entry causing it to highlight.
|
||||
*/
|
||||
protected float mMaxHighlightDistance = 0f;
|
||||
|
||||
@Override
|
||||
public float getMaxHighlightDistance() {
|
||||
return mMaxHighlightDistance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum distance in screen dp a touch can be away from an entry to cause it to get highlighted.
|
||||
* Default: 70dp
|
||||
*
|
||||
* @param distDp
|
||||
*/
|
||||
public void setMaxHighlightDistance(float distDp) {
|
||||
mMaxHighlightDistance = Utils.convertDpToPixel(distDp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of currently highlighted values. This might a null or
|
||||
* empty array if nothing is highlighted.
|
||||
|
@ -610,7 +631,7 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
high = null;
|
||||
} else {
|
||||
if (this instanceof BarLineChartBase
|
||||
&& ((BarLineChartBase)this).isHighlightFullBarEnabled())
|
||||
&& ((BarLineChartBase) this).isHighlightFullBarEnabled())
|
||||
high = new Highlight(high.getX(), Float.NaN, -1, -1, -1);
|
||||
|
||||
// set the indices to highlight
|
||||
|
@ -681,9 +702,9 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
float xVal = highlight.getX();
|
||||
int dataSetIndex = highlight.getDataSetIndex();
|
||||
|
||||
float deltaX = mXAxis != null
|
||||
? mXAxis.mAxisRange
|
||||
: 1f;
|
||||
float deltaX = mXAxis != null
|
||||
? mXAxis.mAxisRange
|
||||
: 1f;
|
||||
|
||||
if (xVal <= deltaX && xVal <= deltaX * mAnimator.getPhaseX()) {
|
||||
|
||||
|
@ -1539,7 +1560,8 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
* @param quality e.g. 50, min = 0, max = 100
|
||||
* @return returns true if saving was successful, false if not
|
||||
*/
|
||||
public boolean saveToGallery(String fileName, String subFolderPath, String fileDescription, Bitmap.CompressFormat format, int quality) {
|
||||
public boolean saveToGallery(String fileName, String subFolderPath, String fileDescription, Bitmap.CompressFormat
|
||||
format, int quality) {
|
||||
// restrain quality
|
||||
if (quality < 0 || quality > 100)
|
||||
quality = 50;
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
package com.github.mikephil.charting.formatter;
|
||||
|
||||
import com.github.mikephil.charting.data.DataSet;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
|
||||
/**
|
||||
* Interface that can be used to return a customized color instead of setting
|
||||
* colors via the setColor(...) method of the DataSet.
|
||||
*
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
public interface ColorFormatter {
|
||||
|
||||
int getColor(Entry e, int index);
|
||||
/**
|
||||
* Returns the color to be used for the given Entry at the given index (in the entries array)
|
||||
*
|
||||
* @param index index in the entries array
|
||||
* @param e the entry to color
|
||||
* @param set the DataSet the entry belongs to
|
||||
* @return
|
||||
*/
|
||||
int getColor(int index, Entry e, IDataSet set);
|
||||
}
|
|
@ -9,6 +9,9 @@ import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider;
|
|||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.utils.PointD;
|
||||
import com.github.mikephil.charting.utils.SelectionDetail;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Philipp Jahoda on 22/07/15.
|
||||
|
@ -47,42 +50,6 @@ public class BarHighlighter extends ChartHighlighter<BarDataProvider> {
|
|||
-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SelectionDetail getSelectionDetail(float xVal, float x, float y) {
|
||||
|
||||
BarData barData = mChart.getBarData();
|
||||
|
||||
int closestDataSetIndex = 0;
|
||||
float closestDistance = Float.MAX_VALUE;
|
||||
Entry closestEntry = null;
|
||||
|
||||
for (int i = 0; i < barData.getDataSets().size(); i++) {
|
||||
|
||||
IBarDataSet dataSet = barData.getDataSetByIndex(i);
|
||||
|
||||
final Entry entry = dataSet.getEntryForXPos(xVal);
|
||||
|
||||
if (entry != null) {
|
||||
|
||||
final float distance = Math.abs(xVal - entry.getX());
|
||||
|
||||
if (distance < closestDistance) {
|
||||
closestDataSetIndex = i;
|
||||
closestDistance = distance;
|
||||
closestEntry = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(closestEntry == null)
|
||||
return null;
|
||||
|
||||
return new SelectionDetail(x, y, closestEntry.getX(),
|
||||
closestEntry.getY(),
|
||||
closestDataSetIndex,
|
||||
barData.getDataSetByIndex(closestDataSetIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method creates the Highlight object that also indicates which yValue of a stacked BarEntry has been
|
||||
* selected.
|
||||
|
@ -190,4 +157,9 @@ public class BarHighlighter extends ChartHighlighter<BarDataProvider> {
|
|||
|
||||
return ranges;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getDistance(float x, float y, float selX, float selY) {
|
||||
return Math.abs(x - selX);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,18 +71,54 @@ public class ChartHighlighter<T extends BarLineScatterCandleBubbleDataProvider>
|
|||
|
||||
List<SelectionDetail> valsAtIndex = getSelectionDetailsAtIndex(xVal);
|
||||
|
||||
float leftdist = Utils.getMinimumDistance(valsAtIndex, y, YAxis.AxisDependency.LEFT);
|
||||
float rightdist = Utils.getMinimumDistance(valsAtIndex, y, YAxis.AxisDependency.RIGHT);
|
||||
float leftdist = getMinimumDistance(valsAtIndex, y, YAxis.AxisDependency.LEFT);
|
||||
float rightdist = getMinimumDistance(valsAtIndex, y, YAxis.AxisDependency.RIGHT);
|
||||
|
||||
YAxis.AxisDependency axis = leftdist < rightdist ? YAxis.AxisDependency.LEFT : YAxis.AxisDependency.RIGHT;
|
||||
|
||||
SelectionDetail detail = Utils.getClosestSelectionDetailByPixel(valsAtIndex, x, y, axis);
|
||||
SelectionDetail detail = getClosestSelectionDetailByPixel(valsAtIndex, x, y, axis, mChart
|
||||
.getMaxHighlightDistance());
|
||||
|
||||
return detail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of SelectionDetail object corresponding to the given xIndex.
|
||||
* Returns the minimum distance from a touch value (in pixels) to the
|
||||
* closest value (in pixels) that is displayed in the chart.
|
||||
*
|
||||
* @param valsAtIndex
|
||||
* @param pos
|
||||
* @param axis
|
||||
* @return
|
||||
*/
|
||||
protected float getMinimumDistance(List<SelectionDetail> valsAtIndex,
|
||||
float pos,
|
||||
YAxis.AxisDependency axis) {
|
||||
|
||||
float distance = Float.MAX_VALUE;
|
||||
|
||||
for (int i = 0; i < valsAtIndex.size(); i++) {
|
||||
|
||||
SelectionDetail sel = valsAtIndex.get(i);
|
||||
|
||||
if (sel.dataSet.getAxisDependency() == axis) {
|
||||
|
||||
float cdistance = Math.abs(getSelectionPos(sel) - pos);
|
||||
if (cdistance < distance) {
|
||||
distance = cdistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return distance;
|
||||
}
|
||||
|
||||
protected float getSelectionPos(SelectionDetail sel) {
|
||||
return sel.yPx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of SelectionDetail object corresponding to the given xVal.
|
||||
*
|
||||
* @param xVal
|
||||
* @return
|
||||
|
@ -116,4 +152,43 @@ public class ChartHighlighter<T extends BarLineScatterCandleBubbleDataProvider>
|
|||
|
||||
return new SelectionDetail((float) pixels.x, (float) pixels.y, e.getX(), e.getY(), dataSetIndex, set);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SelectionDetail of the DataSet that contains the closest yValue on the
|
||||
* yPx-axis.
|
||||
*
|
||||
* @param valsAtIndex all the values at a specific index
|
||||
* @return
|
||||
*/
|
||||
public SelectionDetail getClosestSelectionDetailByPixel(
|
||||
List<SelectionDetail> valsAtIndex,
|
||||
float x, float y,
|
||||
YAxis.AxisDependency axis, float minSelectionDistance) {
|
||||
|
||||
SelectionDetail closest = null;
|
||||
float distance = minSelectionDistance;
|
||||
|
||||
System.out.println(distance);
|
||||
|
||||
for (int i = 0; i < valsAtIndex.size(); i++) {
|
||||
|
||||
SelectionDetail sel = valsAtIndex.get(i);
|
||||
|
||||
if (axis == null || sel.dataSet.getAxisDependency() == axis) {
|
||||
|
||||
float cDistance = getDistance(x, y, sel.xPx, sel.yPx);
|
||||
|
||||
if (cDistance < distance) {
|
||||
closest = sel;
|
||||
distance = cDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
protected float getDistance(float x, float y, float selX, float selY) {
|
||||
return (float) Math.hypot(x - selX, y - selY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
package com.github.mikephil.charting.highlight;
|
||||
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.BarData;
|
||||
import com.github.mikephil.charting.data.DataSet;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
||||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.utils.PointD;
|
||||
import com.github.mikephil.charting.utils.SelectionDetail;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Philipp Jahoda on 22/07/15.
|
||||
|
@ -22,7 +29,7 @@ public class HorizontalBarHighlighter extends BarHighlighter {
|
|||
|
||||
PointD pos = getValsForTouch(y, x);
|
||||
|
||||
SelectionDetail selectionDetail = getSelectionDetail((float) pos.y, x, y);
|
||||
SelectionDetail selectionDetail = getSelectionDetail((float) pos.y, y, x);
|
||||
if (selectionDetail == null)
|
||||
return null;
|
||||
|
||||
|
@ -42,4 +49,19 @@ public class HorizontalBarHighlighter extends BarHighlighter {
|
|||
selectionDetail.dataSetIndex,
|
||||
-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SelectionDetail getDetails(IDataSet set, int dataSetIndex, float xVal, DataSet.Rounding rounding) {
|
||||
|
||||
final Entry e = set.getEntryForXPos(xVal, rounding);
|
||||
|
||||
PointD pixels = mChart.getTransformer(set.getAxisDependency()).getPixelsForValues(e.getY(), e.getX());
|
||||
|
||||
return new SelectionDetail((float) pixels.x, (float) pixels.y, e.getX(), e.getY(), dataSetIndex, set);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getDistance(float x, float y, float selX, float selY) {
|
||||
return Math.abs(y - selY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.graphics.RectF;
|
|||
|
||||
import com.github.mikephil.charting.data.ChartData;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.utils.Utils;
|
||||
|
||||
/**
|
||||
* Interface that provides everything there is to know about the dimensions,
|
||||
|
@ -44,6 +45,13 @@ public interface ChartInterface {
|
|||
*/
|
||||
float getYChartMax();
|
||||
|
||||
/**
|
||||
* Returns the maximum distance in scren dp a touch can be away from an entry to cause it to get highlighted.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
float getMaxHighlightDistance();
|
||||
|
||||
int getWidth();
|
||||
|
||||
int getHeight();
|
||||
|
|
|
@ -300,31 +300,6 @@ public class ScatterChartRenderer extends LineScatterCandleRadarRenderer {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// else { // draw the custom-shape
|
||||
//
|
||||
// Path customShape = dataSet.getCustomScatterShape();
|
||||
//
|
||||
// for (int j = 0; j < entries.size() * mAnimator.getPhaseX(); j += 2) {
|
||||
//
|
||||
// Entry e = entries.get(j / 2);
|
||||
//
|
||||
// if (!fitsBounds(e.getX(), mMinX, mMaxX))
|
||||
// continue;
|
||||
//
|
||||
// if (customShape == null)
|
||||
// return;
|
||||
//
|
||||
// mRenderPaint.setColor(dataSet.getColor(j));
|
||||
//
|
||||
// Path newPath = new Path(customShape);
|
||||
// newPath.offset(e.getX(), e.getY());
|
||||
//
|
||||
// // transform the provided custom path
|
||||
// trans.pathValueToPixel(newPath);
|
||||
// c.drawPath(newPath, mRenderPaint);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -431,70 +431,6 @@ public abstract class Utils {
|
|||
return closest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SelectionDetail of the DataSet that contains the closest yValue on the
|
||||
* yPx-axis.
|
||||
*
|
||||
* @param valsAtIndex all the values at a specific index
|
||||
* @return
|
||||
*/
|
||||
public static SelectionDetail getClosestSelectionDetailByPixel(
|
||||
List<SelectionDetail> valsAtIndex,
|
||||
float x, float y,
|
||||
AxisDependency axis) {
|
||||
|
||||
SelectionDetail closest = null;
|
||||
float distance = Float.MAX_VALUE;
|
||||
|
||||
for (int i = 0; i < valsAtIndex.size(); i++) {
|
||||
|
||||
SelectionDetail sel = valsAtIndex.get(i);
|
||||
|
||||
if (axis == null || sel.dataSet.getAxisDependency() == axis) {
|
||||
|
||||
float cDistance = (float) Math.hypot(x - sel.xPx, y - sel.yPx);
|
||||
|
||||
if (cDistance < distance) {
|
||||
closest = sel;
|
||||
distance = cDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum distance from a touch-yPx-yValue (in pixels) to the
|
||||
* closest yPx-yValue (in pixels) that is displayed in the chart.
|
||||
*
|
||||
* @param valsAtIndex
|
||||
* @param y
|
||||
* @param axis
|
||||
* @return
|
||||
*/
|
||||
public static float getMinimumDistance(List<SelectionDetail> valsAtIndex,
|
||||
float y,
|
||||
AxisDependency axis) {
|
||||
|
||||
float distance = Float.MAX_VALUE;
|
||||
|
||||
for (int i = 0; i < valsAtIndex.size(); i++) {
|
||||
|
||||
SelectionDetail sel = valsAtIndex.get(i);
|
||||
|
||||
if (sel.dataSet.getAxisDependency() == axis) {
|
||||
|
||||
float cdistance = Math.abs(sel.yPx - y);
|
||||
if (cdistance < distance) {
|
||||
distance = cdistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return distance;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this component has no ValueFormatter or is only equipped with the
|
||||
* default one (no custom set), return true.
|
||||
|
|
Loading…
Add table
Reference in a new issue