Improved highlight for scatter/bubble, and fixes highlightValueWithX
This commit is contained in:
parent
8d65596266
commit
e10628958f
19 changed files with 242 additions and 137 deletions
|
@ -87,7 +87,7 @@ public class DynamicalAddingActivity extends DemoBase implements OnChartValueSel
|
|||
|
||||
if (set != null) {
|
||||
|
||||
Entry e = set.getEntryForXValue(set.getEntryCount() - 1);
|
||||
Entry e = set.getEntryForXValue(set.getEntryCount() - 1, Float.NaN);
|
||||
|
||||
data.removeEntry(e, 0);
|
||||
// or remove by index
|
||||
|
|
|
@ -535,8 +535,8 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
/**
|
||||
* Highlights the values at the given indices in the given DataSets. Provide
|
||||
* null or an empty array to undo all highlighting. This should be used to
|
||||
* programmatically highlight values. This DOES NOT generate a callback to
|
||||
* the OnChartValueSelectedListener.
|
||||
* programmatically highlight values.
|
||||
* This method *will not* call the listener.
|
||||
*
|
||||
* @param highs
|
||||
*/
|
||||
|
@ -552,35 +552,59 @@ public abstract class Chart<T extends ChartData<? extends IDataSet<? extends Ent
|
|||
}
|
||||
|
||||
/**
|
||||
* Highlights the value at the given x-value in the given DataSet. Provide
|
||||
* -1 as the dataSetIndex to undo all highlighting. This will trigger a callback to the OnChartValueSelectedListener.
|
||||
*
|
||||
* @param x
|
||||
* @param dataSetIndex
|
||||
* Highlights any y-value at the given x-value in the given DataSet.
|
||||
* Provide -1 as the dataSetIndex to undo all highlighting.
|
||||
* This method will call the listener.
|
||||
* @param x The x-value to highlight
|
||||
* @param dataSetIndex The dataset index to search in
|
||||
*/
|
||||
public void highlightValue(float x, int dataSetIndex) {
|
||||
highlightValue(x, dataSetIndex, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights the value at the given x-value in the given DataSet. Provide
|
||||
* -1 as the dataSetIndex to undo all highlighting.
|
||||
*
|
||||
* @param x
|
||||
* @param dataSetIndex
|
||||
* Highlights the value at the given x-value and y-value in the given DataSet.
|
||||
* Provide -1 as the dataSetIndex to undo all highlighting.
|
||||
* This method will call the listener.
|
||||
* @param x The x-value to highlight
|
||||
* @param y The y-value to highlight. Supply `NaN` for "any"
|
||||
* @param dataSetIndex The dataset index to search in
|
||||
*/
|
||||
public void highlightValue(float x, float y, int dataSetIndex) {
|
||||
highlightValue(x, y, dataSetIndex, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights any y-value at the given x-value in the given DataSet.
|
||||
* Provide -1 as the dataSetIndex to undo all highlighting.
|
||||
* @param x The x-value to highlight
|
||||
* @param dataSetIndex The dataset index to search in
|
||||
* @param callListener Should the listener be called for this change
|
||||
*/
|
||||
public void highlightValue(float x, int dataSetIndex, boolean callListener) {
|
||||
highlightValue(x, Float.NaN, dataSetIndex, callListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights any y-value at the given x-value in the given DataSet.
|
||||
* Provide -1 as the dataSetIndex to undo all highlighting.
|
||||
* @param x The x-value to highlight
|
||||
* @param y The y-value to highlight. Supply `NaN` for "any"
|
||||
* @param dataSetIndex The dataset index to search in
|
||||
* @param callListener Should the listener be called for this change
|
||||
*/
|
||||
public void highlightValue(float x, float y, int dataSetIndex, boolean callListener) {
|
||||
|
||||
if (dataSetIndex < 0 || dataSetIndex >= mData.getDataSetCount()) {
|
||||
highlightValue(null, callListener);
|
||||
} else {
|
||||
highlightValue(new Highlight(x, dataSetIndex), callListener);
|
||||
highlightValue(new Highlight(x, y, dataSetIndex), callListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlights the values represented by the provided Highlight object
|
||||
* This DOES NOT generate a callback to the OnChartValueSelectedListener.
|
||||
* This method *will not* call the listener.
|
||||
*
|
||||
* @param highlight contains information about which entry should be highlighted
|
||||
*/
|
||||
|
|
|
@ -328,7 +328,7 @@ public class PieChart extends PieRadarChartBase<PieData> {
|
|||
List<IPieDataSet> dataSets = mData.getDataSets();
|
||||
|
||||
for (int i = 0; i < dataSets.size(); i++) {
|
||||
if (dataSets.get(i).getEntryForXValue(xIndex) != null)
|
||||
if (dataSets.get(i).getEntryForXValue(xIndex, Float.NaN) != null)
|
||||
return i;
|
||||
}
|
||||
|
||||
|
|
|
@ -432,7 +432,7 @@ public abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
|
|||
@Override
|
||||
public boolean removeEntryByXValue(float xValue) {
|
||||
|
||||
T e = getEntryForXValue(xValue);
|
||||
T e = getEntryForXValue(xValue, Float.NaN);
|
||||
return removeEntry(e);
|
||||
}
|
||||
|
||||
|
|
|
@ -338,7 +338,7 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
|
|||
if (highlight.getDataSetIndex() >= mDataSets.size())
|
||||
return null;
|
||||
else {
|
||||
return mDataSets.get(highlight.getDataSetIndex()).getEntryForXValue(highlight.getX());
|
||||
return mDataSets.get(highlight.getDataSetIndex()).getEntryForXValue(highlight.getX(), highlight.getY());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,7 +550,7 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
|
|||
return false;
|
||||
|
||||
IDataSet dataSet = mDataSets.get(dataSetIndex);
|
||||
Entry e = dataSet.getEntryForXValue(xValue);
|
||||
Entry e = dataSet.getEntryForXValue(xValue, Float.NaN);
|
||||
|
||||
if (e == null)
|
||||
return false;
|
||||
|
@ -575,7 +575,7 @@ public abstract class ChartData<T extends IDataSet<? extends Entry>> {
|
|||
T set = mDataSets.get(i);
|
||||
|
||||
for (int j = 0; j < set.getEntryCount(); j++) {
|
||||
if (e.equalTo(set.getEntryForXValue(e.getX())))
|
||||
if (e.equalTo(set.getEntryForXValue(e.getX(), e.getY())))
|
||||
return set;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,8 +83,8 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
mYMax = -Float.MAX_VALUE;
|
||||
mYMin = Float.MAX_VALUE;
|
||||
|
||||
int indexFrom = getEntryIndex(fromX, Rounding.DOWN);
|
||||
int indexTo = getEntryIndex(toX, Rounding.UP);
|
||||
int indexFrom = getEntryIndex(fromX, Float.NaN, Rounding.DOWN);
|
||||
int indexTo = getEntryIndex(toX, Float.NaN, Rounding.UP);
|
||||
|
||||
for (int i = indexFrom; i <= indexTo; i++) {
|
||||
|
||||
|
@ -213,7 +213,7 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
calcMinMax(e);
|
||||
|
||||
if (mValues.size() > 0 && mValues.get(mValues.size() - 1).getX() > e.getX()) {
|
||||
int closestIndex = getEntryIndex(e.getX(), Rounding.UP);
|
||||
int closestIndex = getEntryIndex(e.getX(), e.getY(), Rounding.UP);
|
||||
mValues.add(closestIndex, e);
|
||||
} else {
|
||||
mValues.add(e);
|
||||
|
@ -268,17 +268,17 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public T getEntryForXValue(float xValue, Rounding rounding) {
|
||||
public T getEntryForXValue(float xValue, float closestToY, Rounding rounding) {
|
||||
|
||||
int index = getEntryIndex(xValue, rounding);
|
||||
int index = getEntryIndex(xValue, closestToY, rounding);
|
||||
if (index > -1)
|
||||
return mValues.get(index);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getEntryForXValue(float xValue) {
|
||||
return getEntryForXValue(xValue, Rounding.CLOSEST);
|
||||
public T getEntryForXValue(float xValue, float closestToY) {
|
||||
return getEntryForXValue(xValue, closestToY, Rounding.CLOSEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -287,13 +287,14 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getEntryIndex(float xValue, Rounding rounding) {
|
||||
public int getEntryIndex(float xValue, float closestToY, Rounding rounding) {
|
||||
|
||||
if (mValues == null || mValues.isEmpty())
|
||||
return -1;
|
||||
|
||||
int low = 0;
|
||||
int high = mValues.size() - 1;
|
||||
int closest = high;
|
||||
|
||||
while (low < high) {
|
||||
int m = (low + high) / 2;
|
||||
|
@ -321,22 +322,53 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
low = m + 1;
|
||||
}
|
||||
}
|
||||
|
||||
closest = high;
|
||||
}
|
||||
|
||||
if (high != -1) {
|
||||
float closestXValue = mValues.get(high).getX();
|
||||
if (closest != -1) {
|
||||
float closestXValue = mValues.get(closest).getX();
|
||||
if (rounding == Rounding.UP) {
|
||||
if (closestXValue < xValue && high < mValues.size() - 1) {
|
||||
++high;
|
||||
// If rounding up, and found x-value is lower than specified x, and we can go upper...
|
||||
if (closestXValue < xValue && closest < mValues.size() - 1) {
|
||||
++closest;
|
||||
}
|
||||
} else if (rounding == Rounding.DOWN) {
|
||||
if (closestXValue > xValue && high > 0) {
|
||||
--high;
|
||||
// If rounding down, and found x-value is upper than specified x, and we can go lower...
|
||||
if (closestXValue > xValue && closest > 0) {
|
||||
--closest;
|
||||
}
|
||||
}
|
||||
|
||||
// Search by closest to y-value
|
||||
if (!Float.isNaN(closestToY)) {
|
||||
while (closest > 0 && mValues.get(closest - 1).getX() == closestXValue)
|
||||
closest -= 1;
|
||||
|
||||
float closestYValue = mValues.get(closest).getY();
|
||||
int closestYIndex = closest;
|
||||
|
||||
while (true) {
|
||||
closest += 1;
|
||||
if (closest >= mValues.size())
|
||||
break;
|
||||
|
||||
final Entry value = mValues.get(closest);
|
||||
|
||||
if (value.getX() != closestXValue)
|
||||
break;
|
||||
|
||||
if (Math.abs(value.getY() - closestToY) < Math.abs(closestYValue - closestToY)) {
|
||||
closestYValue = closestToY;
|
||||
closestYIndex = closest;
|
||||
}
|
||||
}
|
||||
|
||||
closest = closestYIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return high;
|
||||
return closest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -382,7 +414,7 @@ public abstract class DataSet<T extends Entry> extends BaseDataSet<T> {
|
|||
|
||||
/**
|
||||
* Determines how to round DataSet index values for
|
||||
* {@link DataSet#getEntryIndex(float, Rounding)} DataSet.getEntryIndex()}
|
||||
* {@link DataSet#getEntryIndex(float, float, Rounding)} DataSet.getEntryIndex()}
|
||||
* when an exact x-index is not found.
|
||||
*/
|
||||
public enum Rounding {
|
||||
|
|
|
@ -54,7 +54,7 @@ public class BarHighlighter extends ChartHighlighter<BarDataProvider> {
|
|||
*/
|
||||
public Highlight getStackedHighlight(Highlight high, IBarDataSet set, float xVal, float yVal) {
|
||||
|
||||
BarEntry entry = set.getEntryForXValue(xVal);
|
||||
BarEntry entry = set.getEntryForXValue(xVal, yVal);
|
||||
|
||||
if (entry == null)
|
||||
return null;
|
||||
|
|
|
@ -142,18 +142,14 @@ public class ChartHighlighter<T extends BarLineScatterCandleBubbleDataProvider>
|
|||
if (!dataSet.isHighlightEnabled())
|
||||
continue;
|
||||
|
||||
Highlight high = buildHighlight(dataSet, i, xVal, DataSet.Rounding.CLOSEST);
|
||||
|
||||
if(high != null)
|
||||
mHighlightBuffer.add(high);
|
||||
//vals.add(buildHighlight(dataSet, i, xVal, DataSet.Rounding.DOWN));
|
||||
mHighlightBuffer.addAll(buildHighlights(dataSet, i, xVal, DataSet.Rounding.CLOSEST));
|
||||
}
|
||||
|
||||
return mHighlightBuffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Highlight object corresponding to the selected xValue and dataSetIndex.
|
||||
* An array of `Highlight` objects corresponding to the selected xValue and dataSetIndex.
|
||||
*
|
||||
* @param set
|
||||
* @param dataSetIndex
|
||||
|
@ -161,16 +157,36 @@ public class ChartHighlighter<T extends BarLineScatterCandleBubbleDataProvider>
|
|||
* @param rounding
|
||||
* @return
|
||||
*/
|
||||
protected Highlight buildHighlight(IDataSet set, int dataSetIndex, float xVal, DataSet.Rounding rounding) {
|
||||
protected List<Highlight> buildHighlights(IDataSet set, int dataSetIndex, float xVal, DataSet.Rounding rounding) {
|
||||
|
||||
final Entry e = set.getEntryForXValue(xVal, rounding);
|
||||
ArrayList<Highlight> highlights = new ArrayList<>();
|
||||
|
||||
if (e == null)
|
||||
return null;
|
||||
//noinspection unchecked
|
||||
List<Entry> entries = set.getEntriesForXValue(xVal);
|
||||
if (entries.size() == 0) {
|
||||
// Try to find closest x-value and take all entries for that x-value
|
||||
final Entry closest = set.getEntryForXValue(xVal, Float.NaN, rounding);
|
||||
if (closest != null)
|
||||
{
|
||||
//noinspection unchecked
|
||||
entries = set.getEntriesForXValue(closest.getX());
|
||||
}
|
||||
}
|
||||
|
||||
MPPointD pixels = mChart.getTransformer(set.getAxisDependency()).getPixelForValues(e.getX(), e.getY());
|
||||
if (entries.size() == 0)
|
||||
return highlights;
|
||||
|
||||
return new Highlight(e.getX(), e.getY(), (float) pixels.x, (float) pixels.y, dataSetIndex, set.getAxisDependency());
|
||||
for (Entry e : entries) {
|
||||
MPPointD pixels = mChart.getTransformer(
|
||||
set.getAxisDependency()).getPixelForValues(e.getX(), e.getY());
|
||||
|
||||
highlights.add(new Highlight(
|
||||
e.getX(), e.getY(),
|
||||
(float) pixels.x, (float) pixels.y,
|
||||
dataSetIndex, set.getAxisDependency()));
|
||||
}
|
||||
|
||||
return highlights;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -57,13 +57,12 @@ public class CombinedHighlighter extends ChartHighlighter<CombinedDataProvider>
|
|||
if (!dataSet.isHighlightEnabled())
|
||||
continue;
|
||||
|
||||
Highlight s1 = buildHighlight(dataSet, j, xVal, DataSet.Rounding.CLOSEST);
|
||||
s1.setDataIndex(i);
|
||||
mHighlightBuffer.add(s1);
|
||||
|
||||
// Highlight s2 = buildHighlight(dataSet, j, xVal, DataSet.Rounding.DOWN);
|
||||
// s2.setDataIndex(i);
|
||||
// vals.add(s2);
|
||||
List<Highlight> highs = buildHighlights(dataSet, j, xVal, DataSet.Rounding.CLOSEST);
|
||||
for (Highlight high : highs)
|
||||
{
|
||||
high.setDataIndex(i);
|
||||
mHighlightBuffer.add(high);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,13 +60,14 @@ public class Highlight {
|
|||
*/
|
||||
private float mDrawY;
|
||||
|
||||
public Highlight(float x, int dataSetIndex) {
|
||||
public Highlight(float x, float y, int dataSetIndex) {
|
||||
this.mX = x;
|
||||
this.mY = y;
|
||||
this.mDataSetIndex = dataSetIndex;
|
||||
}
|
||||
|
||||
public Highlight(float x, int dataSetIndex, int stackIndex) {
|
||||
this(x, dataSetIndex);
|
||||
this(x, Float.NaN, dataSetIndex);
|
||||
this.mStackIndex = stackIndex;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,9 @@ import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
|
|||
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
|
||||
import com.github.mikephil.charting.utils.MPPointD;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Philipp Jahoda on 22/07/15.
|
||||
*/
|
||||
|
@ -43,13 +46,36 @@ public class HorizontalBarHighlighter extends BarHighlighter {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Highlight buildHighlight(IDataSet set, int dataSetIndex, float xVal, DataSet.Rounding rounding) {
|
||||
protected List<Highlight> buildHighlights(IDataSet set, int dataSetIndex, float xVal, DataSet.Rounding rounding) {
|
||||
|
||||
final Entry e = set.getEntryForXValue(xVal, rounding);
|
||||
ArrayList<Highlight> highlights = new ArrayList<>();
|
||||
|
||||
MPPointD pixels = mChart.getTransformer(set.getAxisDependency()).getPixelForValues(e.getY(), e.getX());
|
||||
//noinspection unchecked
|
||||
List<Entry> entries = set.getEntriesForXValue(xVal);
|
||||
if (entries.size() == 0) {
|
||||
// Try to find closest x-value and take all entries for that x-value
|
||||
final Entry closest = set.getEntryForXValue(xVal, Float.NaN, rounding);
|
||||
if (closest != null)
|
||||
{
|
||||
//noinspection unchecked
|
||||
entries = set.getEntriesForXValue(closest.getX());
|
||||
}
|
||||
}
|
||||
|
||||
return new Highlight(e.getX(), e.getY(), (float) pixels.x, (float) pixels.y, dataSetIndex, set.getAxisDependency());
|
||||
if (entries.size() == 0)
|
||||
return highlights;
|
||||
|
||||
for (Entry e : entries) {
|
||||
MPPointD pixels = mChart.getTransformer(
|
||||
set.getAxisDependency()).getPixelForValues(e.getY(), e.getX());
|
||||
|
||||
highlights.add(new Highlight(
|
||||
e.getX(), e.getY(),
|
||||
(float) pixels.x, (float) pixels.y,
|
||||
dataSetIndex, set.getAxisDependency()));
|
||||
}
|
||||
|
||||
return highlights;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -70,28 +70,36 @@ public interface IDataSet<T extends Entry> {
|
|||
|
||||
/**
|
||||
* Returns the first Entry object found at the given x-value with binary
|
||||
* search. If the no Entry at the specified x-value is found, this method
|
||||
* returns the Entry at the x-value according to the rounding.
|
||||
* search.
|
||||
* If the no Entry at the specified x-value is found, this method
|
||||
* returns the Entry at the closest x-value according to the rounding.
|
||||
* INFORMATION: This method does calculations at runtime. Do
|
||||
* not over-use in performance critical situations.
|
||||
*
|
||||
* @param xValue
|
||||
* @param rounding determine to round up/down/closest if there is no Entry matching the provided x-index
|
||||
* @param xValue the x-value
|
||||
* @param closestToY If there are multiple y-values for the specified x-value,
|
||||
* @param rounding determine whether to round up/down/closest
|
||||
* if there is no Entry matching the provided x-value
|
||||
* @return
|
||||
*
|
||||
*
|
||||
*/
|
||||
T getEntryForXValue(float xValue, DataSet.Rounding rounding);
|
||||
T getEntryForXValue(float xValue, float closestToY, DataSet.Rounding rounding);
|
||||
|
||||
/**
|
||||
* Returns the first Entry object found at the given x-value with binary
|
||||
* search. If the no Entry at the specified x-value is found, this method
|
||||
* returns the index at the closest x-value.
|
||||
* search.
|
||||
* If the no Entry at the specified x-value is found, this method
|
||||
* returns the Entry at the closest x-value.
|
||||
* INFORMATION: This method does calculations at runtime. Do
|
||||
* not over-use in performance critical situations.
|
||||
*
|
||||
* @param xValue
|
||||
*
|
||||
* @param xValue the x-value
|
||||
* @param closestToY If there are multiple y-values for the specified x-value,
|
||||
* @return
|
||||
*/
|
||||
T getEntryForXValue(float xValue);
|
||||
T getEntryForXValue(float xValue, float closestToY);
|
||||
|
||||
/**
|
||||
* Returns all Entry objects found at the given x-value with binary
|
||||
|
@ -114,16 +122,19 @@ public interface IDataSet<T extends Entry> {
|
|||
|
||||
/**
|
||||
* Returns the first Entry index found at the given x-value with binary
|
||||
* search. If the no Entry at the specified x-value is found, this method
|
||||
* returns the Entry at the closest x-value.
|
||||
* search.
|
||||
* If the no Entry at the specified x-value is found, this method
|
||||
* returns the Entry at the closest x-value according to the rounding.
|
||||
* INFORMATION: This method does calculations at runtime. Do
|
||||
* not over-use in performance critical situations.
|
||||
*
|
||||
* @param xValue
|
||||
* @param rounding determine to round up/down/closest if there is no Entry matching the provided x-index
|
||||
* @param xValue the x-value
|
||||
* @param closestToY If there are multiple y-values for the specified x-value,
|
||||
* @param rounding determine whether to round up/down/closest
|
||||
* if there is no Entry matching the provided x-value
|
||||
* @return
|
||||
*/
|
||||
int getEntryIndex(float xValue, DataSet.Rounding rounding);
|
||||
int getEntryIndex(float xValue, float closestToY, DataSet.Rounding rounding);
|
||||
|
||||
/**
|
||||
* Returns the position of the provided entry in the DataSets Entry array.
|
||||
|
|
|
@ -341,7 +341,7 @@ public class BarChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
if (set == null || !set.isHighlightEnabled())
|
||||
continue;
|
||||
|
||||
BarEntry e = set.getEntryForXValue(high.getX());
|
||||
BarEntry e = set.getEntryForXValue(high.getX(), high.getY());
|
||||
|
||||
if (!isInBoundsX(e, set))
|
||||
continue;
|
||||
|
|
|
@ -85,8 +85,8 @@ public abstract class BarLineScatterCandleBubbleRenderer extends DataRenderer {
|
|||
float low = chart.getLowestVisibleX();
|
||||
float high = chart.getHighestVisibleX();
|
||||
|
||||
Entry entryFrom = dataSet.getEntryForXValue(low, DataSet.Rounding.DOWN);
|
||||
Entry entryTo = dataSet.getEntryForXValue(high, DataSet.Rounding.UP);
|
||||
Entry entryFrom = dataSet.getEntryForXValue(low, Float.NaN, DataSet.Rounding.DOWN);
|
||||
Entry entryTo = dataSet.getEntryForXValue(high, Float.NaN, DataSet.Rounding.UP);
|
||||
|
||||
min = dataSet.getEntryIndex(entryFrom);
|
||||
max = dataSet.getEntryIndex(entryTo);
|
||||
|
|
|
@ -189,64 +189,60 @@ public class BubbleChartRenderer extends BarLineScatterCandleBubbleRenderer {
|
|||
if (set == null || !set.isHighlightEnabled())
|
||||
continue;
|
||||
|
||||
// In bubble charts - it makes sense to have multiple bubbles on the same X value in the same dataset.
|
||||
final List<BubbleEntry> entries = set.getEntriesForXValue(high.getX());
|
||||
final BubbleEntry entry = set.getEntryForXValue(high.getX(), high.getY());
|
||||
|
||||
for (BubbleEntry entry : entries) {
|
||||
if (entry.getY() != high.getY())
|
||||
continue;
|
||||
|
||||
if (entry.getY() != high.getY())
|
||||
continue;
|
||||
if (!isInBoundsX(entry, set))
|
||||
continue;
|
||||
|
||||
if (!isInBoundsX(entry, set))
|
||||
continue;
|
||||
Transformer trans = mChart.getTransformer(set.getAxisDependency());
|
||||
|
||||
Transformer trans = mChart.getTransformer(set.getAxisDependency());
|
||||
sizeBuffer[0] = 0f;
|
||||
sizeBuffer[2] = 1f;
|
||||
|
||||
sizeBuffer[0] = 0f;
|
||||
sizeBuffer[2] = 1f;
|
||||
trans.pointValuesToPixel(sizeBuffer);
|
||||
|
||||
trans.pointValuesToPixel(sizeBuffer);
|
||||
boolean normalizeSize = set.isNormalizeSizeEnabled();
|
||||
|
||||
boolean normalizeSize = set.isNormalizeSizeEnabled();
|
||||
// calcualte the full width of 1 step on the x-axis
|
||||
final float maxBubbleWidth = Math.abs(sizeBuffer[2] - sizeBuffer[0]);
|
||||
final float maxBubbleHeight = Math.abs(
|
||||
mViewPortHandler.contentBottom() - mViewPortHandler.contentTop());
|
||||
final float referenceSize = Math.min(maxBubbleHeight, maxBubbleWidth);
|
||||
|
||||
// calcualte the full width of 1 step on the x-axis
|
||||
final float maxBubbleWidth = Math.abs(sizeBuffer[2] - sizeBuffer[0]);
|
||||
final float maxBubbleHeight = Math.abs(
|
||||
mViewPortHandler.contentBottom() - mViewPortHandler.contentTop());
|
||||
final float referenceSize = Math.min(maxBubbleHeight, maxBubbleWidth);
|
||||
pointBuffer[0] = entry.getX();
|
||||
pointBuffer[1] = (entry.getY()) * phaseY;
|
||||
trans.pointValuesToPixel(pointBuffer);
|
||||
|
||||
pointBuffer[0] = entry.getX();
|
||||
pointBuffer[1] = (entry.getY()) * phaseY;
|
||||
trans.pointValuesToPixel(pointBuffer);
|
||||
high.setDraw(pointBuffer[0], pointBuffer[1]);
|
||||
|
||||
high.setDraw(pointBuffer[0], pointBuffer[1]);
|
||||
float shapeHalf = getShapeSize(entry.getSize(),
|
||||
set.getMaxSize(),
|
||||
referenceSize,
|
||||
normalizeSize) / 2f;
|
||||
|
||||
float shapeHalf = getShapeSize(entry.getSize(),
|
||||
set.getMaxSize(),
|
||||
referenceSize,
|
||||
normalizeSize) / 2f;
|
||||
if (!mViewPortHandler.isInBoundsTop(pointBuffer[1] + shapeHalf)
|
||||
|| !mViewPortHandler.isInBoundsBottom(pointBuffer[1] - shapeHalf))
|
||||
continue;
|
||||
|
||||
if (!mViewPortHandler.isInBoundsTop(pointBuffer[1] + shapeHalf)
|
||||
|| !mViewPortHandler.isInBoundsBottom(pointBuffer[1] - shapeHalf))
|
||||
continue;
|
||||
if (!mViewPortHandler.isInBoundsLeft(pointBuffer[0] + shapeHalf))
|
||||
continue;
|
||||
|
||||
if (!mViewPortHandler.isInBoundsLeft(pointBuffer[0] + shapeHalf))
|
||||
continue;
|
||||
if (!mViewPortHandler.isInBoundsRight(pointBuffer[0] - shapeHalf))
|
||||
break;
|
||||
|
||||
if (!mViewPortHandler.isInBoundsRight(pointBuffer[0] - shapeHalf))
|
||||
break;
|
||||
final int originalColor = set.getColor((int) entry.getX());
|
||||
|
||||
final int originalColor = set.getColor((int) entry.getX());
|
||||
Color.RGBToHSV(Color.red(originalColor), Color.green(originalColor),
|
||||
Color.blue(originalColor), _hsvBuffer);
|
||||
_hsvBuffer[2] *= 0.5f;
|
||||
final int color = Color.HSVToColor(Color.alpha(originalColor), _hsvBuffer);
|
||||
|
||||
Color.RGBToHSV(Color.red(originalColor), Color.green(originalColor),
|
||||
Color.blue(originalColor), _hsvBuffer);
|
||||
_hsvBuffer[2] *= 0.5f;
|
||||
final int color = Color.HSVToColor(Color.alpha(originalColor), _hsvBuffer);
|
||||
|
||||
mHighlightPaint.setColor(color);
|
||||
mHighlightPaint.setStrokeWidth(set.getHighlightCircleWidth());
|
||||
c.drawCircle(pointBuffer[0], pointBuffer[1], shapeHalf, mHighlightPaint);
|
||||
}
|
||||
mHighlightPaint.setColor(color);
|
||||
mHighlightPaint.setStrokeWidth(set.getHighlightCircleWidth());
|
||||
c.drawCircle(pointBuffer[0], pointBuffer[1], shapeHalf, mHighlightPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,7 +313,7 @@ public class CandleStickChartRenderer extends LineScatterCandleRadarRenderer {
|
|||
if (set == null || !set.isHighlightEnabled())
|
||||
continue;
|
||||
|
||||
CandleEntry e = set.getEntryForXValue(high.getX());
|
||||
CandleEntry e = set.getEntryForXValue(high.getX(), high.getY());
|
||||
|
||||
if (!isInBoundsX(e, set))
|
||||
continue;
|
||||
|
|
|
@ -670,7 +670,7 @@ public class LineChartRenderer extends LineRadarRenderer {
|
|||
if (set == null || !set.isHighlightEnabled())
|
||||
continue;
|
||||
|
||||
Entry e = set.getEntryForXValue(high.getX());
|
||||
Entry e = set.getEntryForXValue(high.getX(), high.getY());
|
||||
|
||||
if (!isInBoundsX(e, set))
|
||||
continue;
|
||||
|
|
|
@ -148,7 +148,7 @@ public class ScatterChartRenderer extends LineScatterCandleRadarRenderer {
|
|||
if (set == null || !set.isHighlightEnabled())
|
||||
continue;
|
||||
|
||||
Entry e = set.getEntryForXValue(high.getX());
|
||||
final Entry e = set.getEntryForXValue(high.getX(), high.getY());
|
||||
|
||||
if (!isInBoundsX(e, set))
|
||||
continue;
|
||||
|
|
|
@ -150,31 +150,31 @@ public class DataSetTest {
|
|||
|
||||
ScatterDataSet set = new ScatterDataSet(entries, "");
|
||||
|
||||
Entry closest = set.getEntryForXValue(17, DataSet.Rounding.CLOSEST);
|
||||
Entry closest = set.getEntryForXValue(17, Float.NaN, DataSet.Rounding.CLOSEST);
|
||||
assertEquals(15, closest.getX(), 0.01f);
|
||||
assertEquals(5, closest.getY(), 0.01f);
|
||||
|
||||
closest = set.getEntryForXValue(17, DataSet.Rounding.DOWN);
|
||||
closest = set.getEntryForXValue(17, Float.NaN, DataSet.Rounding.DOWN);
|
||||
assertEquals(15, closest.getX(), 0.01f);
|
||||
assertEquals(5, closest.getY(), 0.01f);
|
||||
|
||||
closest = set.getEntryForXValue(15, DataSet.Rounding.DOWN);
|
||||
closest = set.getEntryForXValue(15, Float.NaN, DataSet.Rounding.DOWN);
|
||||
assertEquals(15, closest.getX(), 0.01f);
|
||||
assertEquals(5, closest.getY(), 0.01f);
|
||||
|
||||
closest = set.getEntryForXValue(14, DataSet.Rounding.DOWN);
|
||||
closest = set.getEntryForXValue(14, Float.NaN, DataSet.Rounding.DOWN);
|
||||
assertEquals(10, closest.getX(), 0.01f);
|
||||
assertEquals(10, closest.getY(), 0.01f);
|
||||
|
||||
closest = set.getEntryForXValue(17, DataSet.Rounding.UP);
|
||||
closest = set.getEntryForXValue(17, Float.NaN, DataSet.Rounding.UP);
|
||||
assertEquals(21, closest.getX(), 0.01f);
|
||||
assertEquals(5, closest.getY(), 0.01f);
|
||||
|
||||
closest = set.getEntryForXValue(21, DataSet.Rounding.UP);
|
||||
closest = set.getEntryForXValue(21, Float.NaN, DataSet.Rounding.UP);
|
||||
assertEquals(21, closest.getX(), 0.01f);
|
||||
assertEquals(5, closest.getY(), 0.01f);
|
||||
|
||||
closest = set.getEntryForXValue(21, DataSet.Rounding.CLOSEST);
|
||||
closest = set.getEntryForXValue(21, Float.NaN, DataSet.Rounding.CLOSEST);
|
||||
assertEquals(21, closest.getX(), 0.01f);
|
||||
assertEquals(5, closest.getY(), 0.01f);
|
||||
}
|
||||
|
@ -199,27 +199,27 @@ public class DataSetTest {
|
|||
|
||||
ScatterDataSet set = new ScatterDataSet(values, "");
|
||||
|
||||
Entry closest = set.getEntryForXValue(0, DataSet.Rounding.CLOSEST);
|
||||
Entry closest = set.getEntryForXValue(0, Float.NaN, DataSet.Rounding.CLOSEST);
|
||||
assertEquals(0, closest.getX(), 0.01f);
|
||||
assertEquals(10, closest.getY(), 0.01f);
|
||||
|
||||
closest = set.getEntryForXValue(5, DataSet.Rounding.CLOSEST);
|
||||
closest = set.getEntryForXValue(5, Float.NaN, DataSet.Rounding.CLOSEST);
|
||||
assertEquals(5, closest.getX(), 0.01f);
|
||||
assertEquals(80, closest.getY(), 0.01f);
|
||||
|
||||
closest = set.getEntryForXValue(5.4f, DataSet.Rounding.CLOSEST);
|
||||
closest = set.getEntryForXValue(5.4f, Float.NaN, DataSet.Rounding.CLOSEST);
|
||||
assertEquals(5, closest.getX(), 0.01f);
|
||||
assertEquals(80, closest.getY(), 0.01f);
|
||||
|
||||
closest = set.getEntryForXValue(4.6f, DataSet.Rounding.CLOSEST);
|
||||
closest = set.getEntryForXValue(4.6f, Float.NaN, DataSet.Rounding.CLOSEST);
|
||||
assertEquals(5, closest.getX(), 0.01f);
|
||||
assertEquals(80, closest.getY(), 0.01f);
|
||||
|
||||
closest = set.getEntryForXValue(7, DataSet.Rounding.CLOSEST);
|
||||
closest = set.getEntryForXValue(7, Float.NaN, DataSet.Rounding.CLOSEST);
|
||||
assertEquals(7, closest.getX(), 0.01f);
|
||||
assertEquals(100, closest.getY(), 0.01f);
|
||||
|
||||
closest = set.getEntryForXValue(4f, DataSet.Rounding.CLOSEST);
|
||||
closest = set.getEntryForXValue(4f, Float.NaN, DataSet.Rounding.CLOSEST);
|
||||
assertEquals(4, closest.getX(), 0.01f);
|
||||
assertEquals(60, closest.getY(), 0.01f);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue