diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/data/BarEntry.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/data/BarEntry.kt index 23040f8a5a..88558af3a6 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/data/BarEntry.kt +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/data/BarEntry.kt @@ -20,7 +20,7 @@ open class BarEntry : Entry { /** * Returns the ranges of the individual stack-entries. Will return null if this entry is not stacked. */ - var ranges: Array = arrayOfNulls(0) + var ranges: Array = arrayOf() private set /** @@ -196,7 +196,7 @@ open class BarEntry : Entry { if (values == null || values.isEmpty()) return - this.ranges = arrayOfNulls(values.size) + this.ranges = arrayOf() var negRemain = -this.negativeSum var posRemain = 0f diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/BarHighlighter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/BarHighlighter.java deleted file mode 100644 index 8f219c3e50..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/BarHighlighter.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.github.mikephil.charting.highlight; - -import com.github.mikephil.charting.data.BarData; -import com.github.mikephil.charting.data.BarEntry; -import com.github.mikephil.charting.data.BarLineScatterCandleBubbleData; -import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider; -import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; -import com.github.mikephil.charting.utils.MPPointD; - -/** - * Created by Philipp Jahoda on 22/07/15. - */ -public class BarHighlighter extends ChartHighlighter { - - public BarHighlighter(BarDataProvider chart) { - super(chart); - } - - @Override - public Highlight getHighlight(float x, float y) { - Highlight high = super.getHighlight(x, y); - - if(high == null) { - return null; - } - - MPPointD pos = getValsForTouch(x, y); - - BarData barData = mChart.getBarData(); - - IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex()); - if (set.isStacked()) { - - return getStackedHighlight(high, - set, - (float) pos.x, - (float) pos.y); - } - - MPPointD.recycleInstance(pos); - - return high; - } - - /** - * This method creates the Highlight object that also indicates which value of a stacked BarEntry has been - * selected. - * - * @param high the Highlight to work with looking for stacked values - */ - public Highlight getStackedHighlight(Highlight high, IBarDataSet set, float xVal, float yVal) { - - BarEntry entry = set.getEntryForXValue(xVal, yVal); - - if (entry == null) - return null; - - // not stacked - if (entry.getYVals() == null) { - return high; - } else { - Range[] ranges = entry.getRanges(); - - if (ranges.length > 0) { - int stackIndex = getClosestStackIndex(ranges, yVal); - - MPPointD pixels = mChart.getTransformer(set.getAxisDependency()).getPixelForValues(high.getX(), ranges[stackIndex].to); - - Highlight stackedHigh = new Highlight( - entry.getX(), - entry.getY(), - (float) pixels.x, - (float) pixels.y, - high.getDataSetIndex(), - stackIndex, - high.getAxis() - ); - - MPPointD.recycleInstance(pixels); - - return stackedHigh; - } - } - - return null; - } - - /** - * Returns the index of the closest value inside the values array / ranges (stacked barchart) to the value - * given as a parameter. - */ - protected int getClosestStackIndex(Range[] ranges, float value) { - - if (ranges == null || ranges.length == 0) - return 0; - - int stackIndex = 0; - - for (Range range : ranges) { - if (range.contains(value)) - return stackIndex; - else - stackIndex++; - } - - int length = Math.max(ranges.length - 1, 0); - - return (value > ranges[length].to) ? length : 0; - } - - @Override - protected float getDistance(float x1, float y1, float x2, float y2) { - return Math.abs(x1 - x2); - } - - @Override - protected BarLineScatterCandleBubbleData getData() { - return mChart.getBarData(); - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/BarHighlighter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/BarHighlighter.kt new file mode 100644 index 0000000000..93f65dc794 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/BarHighlighter.kt @@ -0,0 +1,93 @@ +package com.github.mikephil.charting.highlight + +import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider +import com.github.mikephil.charting.interfaces.datasets.IBarDataSet +import com.github.mikephil.charting.utils.MPPointD +import kotlin.math.abs +import kotlin.math.max + +open class BarHighlighter(barDataProvider: BarDataProvider?) : ChartHighlighter(barDataProvider) { + override fun getHighlight(x: Float, y: Float): Highlight? { + val high = super.getHighlight(x, y) ?: return null + + val pos = getValsForTouch(x, y) + + val barData = provider!!.barData + + val set = barData.getDataSetByIndex(high.dataSetIndex) + if (set.isStacked()) { + return getStackedHighlight( + high, + set, + pos.x.toFloat(), + pos.y.toFloat() + ) + } + + MPPointD.recycleInstance(pos) + + return high + } + + /** + * This method creates the Highlight object that also indicates which value of a stacked BarEntry has been + * selected. + * + * @param high the Highlight to work with looking for stacked values + */ + fun getStackedHighlight(high: Highlight, set: IBarDataSet, xVal: Float, yVal: Float): Highlight? { + set.getEntryForXValue(xVal, yVal)?.let { entry -> + // not stacked + if (entry.yVals == null) { + return high + } else { + val ranges: Array = entry.ranges + + if (ranges.isNotEmpty()) { + val stackIndex = getClosestStackIndex(ranges, yVal) + + val pixels = provider!!.getTransformer(set.axisDependency)!!.getPixelForValues(high.x, ranges[stackIndex].to) + + val stackedHigh = Highlight( + entry.x, + entry.y, + pixels.x.toFloat(), + pixels.y.toFloat(), + high.dataSetIndex, + stackIndex, + high.axis + ) + + MPPointD.recycleInstance(pixels) + + return stackedHigh + } + } + } + return null + } + + /** + * Returns the index of the closest value inside the values array / ranges (stacked barchart) to the value given as a parameter. + */ + protected fun getClosestStackIndex(ranges: Array?, value: Float): Int { + if (ranges == null || ranges.isEmpty()) + return 0 + + var stackIndex = 0 + + for (range in ranges) { + if (range.contains(value)) return stackIndex + else stackIndex++ + } + + val length = max(ranges.size - 1, 0) + + return if (value > ranges[length].to) length else 0 + } + + override fun getDistance(x1: Float, y1: Float, x2: Float, y2: Float): Float { + return abs(x1 - x2) + } + +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/ChartHighlighter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/ChartHighlighter.java deleted file mode 100644 index e622a43b3a..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/ChartHighlighter.java +++ /dev/null @@ -1,212 +0,0 @@ -package com.github.mikephil.charting.highlight; - -import com.github.mikephil.charting.components.YAxis; -import com.github.mikephil.charting.data.BarLineScatterCandleBubbleData; -import com.github.mikephil.charting.data.DataSet; -import com.github.mikephil.charting.data.Entry; -import com.github.mikephil.charting.interfaces.dataprovider.BarLineScatterCandleBubbleDataProvider; -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 21/07/15. - */ -public class ChartHighlighter implements IHighlighter -{ - - /** - * instance of the data-provider - */ - protected T mChart; - - /** - * buffer for storing previously highlighted values - */ - protected List mHighlightBuffer = new ArrayList<>(); - - public ChartHighlighter(T chart) { - this.mChart = chart; - } - - @Override - public Highlight getHighlight(float x, float y) { - - MPPointD pos = getValsForTouch(x, y); - float xVal = (float) pos.x; - MPPointD.recycleInstance(pos); - - Highlight high = getHighlightForX(xVal, x, y); - return high; - } - - /** - * Returns a recyclable MPPointD instance. - * Returns the corresponding xPos for a given touch-position in pixels. - */ - protected MPPointD getValsForTouch(float x, float y) { - - // take any transformer to determine the x-axis value - return mChart.getTransformer(YAxis.AxisDependency.LEFT).getValuesByTouchPoint(x, y); - } - - /** - * Returns the corresponding Highlight for a given xVal and x- and y-touch position in pixels. - */ - protected Highlight getHighlightForX(float xVal, float x, float y) { - - List closestValues = getHighlightsAtXValue(xVal, x, y); - - if(closestValues.isEmpty()) { - return null; - } - - float leftAxisMinDist = getMinimumDistance(closestValues, y, YAxis.AxisDependency.LEFT); - float rightAxisMinDist = getMinimumDistance(closestValues, y, YAxis.AxisDependency.RIGHT); - - YAxis.AxisDependency axis = leftAxisMinDist < rightAxisMinDist ? YAxis.AxisDependency.LEFT : YAxis.AxisDependency.RIGHT; - - return getClosestHighlightByPixel(closestValues, x, y, axis, mChart.getMaxHighlightDistance()); - } - - /** - * Returns the minimum distance from a touch value (in pixels) to the - * closest value (in pixels) that is displayed in the chart. - */ - protected float getMinimumDistance(List closestValues, float pos, YAxis.AxisDependency axis) { - - float distance = Float.MAX_VALUE; - - for (int i = 0; i < closestValues.size(); i++) { - - Highlight high = closestValues.get(i); - - if (high.getAxis() == axis) { - - float tempDistance = Math.abs(getHighlightPos(high) - pos); - if (tempDistance < distance) { - distance = tempDistance; - } - } - } - - return distance; - } - - protected float getHighlightPos(Highlight h) { - return h.getYPx(); - } - - /** - * Returns a list of Highlight objects representing the entries closest to the given xVal. - * The returned list contains two objects per DataSet (closest rounding up, closest rounding down). - * - * @param xVal the transformed x-value of the x-touch position - * @param x touch position - * @param y touch position - */ - protected List getHighlightsAtXValue(float xVal, float x, float y) { - - mHighlightBuffer.clear(); - - BarLineScatterCandleBubbleData data = getData(); - - if (data == null) - return mHighlightBuffer; - - for (int i = 0, dataSetCount = data.getDataSetCount(); i < dataSetCount; i++) { - - IDataSet dataSet = data.getDataSetByIndex(i); - - // don't include DataSets that cannot be highlighted - if (!dataSet.isHighlightEnabled()) - continue; - - mHighlightBuffer.addAll(buildHighlights(dataSet, i, xVal, DataSet.Rounding.CLOSEST)); - } - - return mHighlightBuffer; - } - - /** - * An array of `Highlight` objects corresponding to the selected xValue and dataSetIndex. - */ - protected List buildHighlights(IDataSet set, int dataSetIndex, float xVal, DataSet.Rounding rounding) { - - ArrayList highlights = new ArrayList<>(); - - //noinspection unchecked - List entries = set.getEntriesForXValue(xVal); - if (entries.isEmpty()) { - // 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()); - } - } - - if (entries.isEmpty()) - return highlights; - - 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; - } - - /** - * Returns the Highlight of the DataSet that contains the closest value on the - * y-axis. - * - * @param closestValues contains two Highlight objects per DataSet closest to the selected x-position (determined by - * rounding up an down) - * @param axis the closest axis - */ - public Highlight getClosestHighlightByPixel(List closestValues, float x, float y, - YAxis.AxisDependency axis, float minSelectionDistance) { - - Highlight closest = null; - float distance = minSelectionDistance; - - for (int i = 0; i < closestValues.size(); i++) { - - Highlight high = closestValues.get(i); - - if (axis == null || high.getAxis() == axis) { - - float cDistance = getDistance(x, y, high.getXPx(), high.getYPx()); - - if (cDistance < distance) { - closest = high; - distance = cDistance; - } - } - } - - return closest; - } - - /** - * Calculates the distance between the two given points. - */ - protected float getDistance(float x1, float y1, float x2, float y2) { - //return Math.abs(y1 - y2); - //return Math.abs(x1 - x2); - return (float) Math.hypot(x1 - x2, y1 - y2); - } - - protected BarLineScatterCandleBubbleData getData() { - return mChart.getData(); - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/ChartHighlighter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/ChartHighlighter.kt new file mode 100644 index 0000000000..0f11682692 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/ChartHighlighter.kt @@ -0,0 +1,188 @@ +package com.github.mikephil.charting.highlight + +import com.github.mikephil.charting.components.YAxis.AxisDependency +import com.github.mikephil.charting.data.BarLineScatterCandleBubbleData +import com.github.mikephil.charting.data.DataSet +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.interfaces.dataprovider.BarLineScatterCandleBubbleDataProvider +import com.github.mikephil.charting.interfaces.datasets.IDataSet +import com.github.mikephil.charting.utils.MPPointD +import kotlin.math.abs +import kotlin.math.hypot + +open class ChartHighlighter(protected var provider: T?) : IHighlighter { + /** + * buffer for storing previously highlighted values + */ + protected var mHighlightBuffer: MutableList = ArrayList() + + override fun getHighlight(x: Float, y: Float): Highlight? { + val pos = getValsForTouch(x, y) + val xVal = pos.x.toFloat() + MPPointD.recycleInstance(pos) + + val high = getHighlightForX(xVal, x, y) + return high + } + + /** + * Returns a recyclable MPPointD instance. + * Returns the corresponding xPos for a given touch-position in pixels. + */ + protected fun getValsForTouch(x: Float, y: Float): MPPointD { + // take any transformer to determine the x-axis value + + return provider!!.getTransformer(AxisDependency.LEFT)!!.getValuesByTouchPoint(x, y) + } + + /** + * Returns the corresponding Highlight for a given xVal and x- and y-touch position in pixels. + */ + protected fun getHighlightForX(xVal: Float, x: Float, y: Float): Highlight? { + val closestValues = getHighlightsAtXValue(xVal, x, y) + + if (closestValues!!.isEmpty()) { + return null + } + + val leftAxisMinDist = getMinimumDistance(closestValues, y, AxisDependency.LEFT) + val rightAxisMinDist = getMinimumDistance(closestValues, y, AxisDependency.RIGHT) + + val axis = if (leftAxisMinDist < rightAxisMinDist) AxisDependency.LEFT else AxisDependency.RIGHT + + return getClosestHighlightByPixel(closestValues, x, y, axis, provider!!.getMaxHighlightDistance()) + } + + /** + * Returns the minimum distance from a touch value (in pixels) to the + * closest value (in pixels) that is displayed in the chart. + */ + protected fun getMinimumDistance(closestValues: MutableList, pos: Float, axis: AxisDependency?): Float { + var distance = Float.MAX_VALUE + + for (i in closestValues.indices) { + val high = closestValues.get(i) + + if (high.axis == axis) { + val tempDistance = abs(getHighlightPos(high) - pos) + if (tempDistance < distance) { + distance = tempDistance + } + } + } + + return distance + } + + protected fun getHighlightPos(h: Highlight): Float { + return h.yPx + } + + /** + * Returns a list of Highlight objects representing the entries closest to the given xVal. + * The returned list contains two objects per DataSet (closest rounding up, closest rounding down). + * + * @param xVal the transformed x-value of the x-touch position + * @param x touch position + * @param y touch position + */ + protected open fun getHighlightsAtXValue(xVal: Float, x: Float, y: Float): MutableList? { + mHighlightBuffer.clear() + + val data = this.data + + var i = 0 + val dataSetCount = data.getDataSetCount() + while (i < dataSetCount) { + val dataSet: IDataSet<*> = data.getDataSetByIndex(i) + + // don't include DataSets that cannot be highlighted + if (!dataSet.isHighlightEnabled) { + i++ + continue + } + + mHighlightBuffer.addAll(buildHighlights(dataSet, i, xVal, DataSet.Rounding.CLOSEST)) + i++ + } + + return mHighlightBuffer + } + + /** + * An array of `Highlight` objects corresponding to the selected xValue and dataSetIndex. + */ + protected open fun buildHighlights(set: IDataSet<*>, dataSetIndex: Int, xVal: Float, rounding: DataSet.Rounding?): MutableList { + val highlights = ArrayList() + + var entries = set.getEntriesForXValue(xVal) + if (entries != null && entries.isEmpty()) { + // Try to find closest x-value and take all entries for that x-value + val closest: Entry? = set.getEntryForXValue(xVal, Float.NaN, rounding) + if (closest != null) { + entries = set.getEntriesForXValue(closest.x) + } + } + + if (entries != null && entries.isEmpty()) + return highlights + + if (entries != null) + for (e in entries) { + val pixels = provider!!.getTransformer(set.axisDependency)!!.getPixelForValues(e.x, e.y) + + highlights.add( + Highlight( + e.x, e.y, + pixels.x.toFloat(), pixels.y.toFloat(), + dataSetIndex, set.axisDependency + ) + ) + } + + return highlights + } + + /** + * Returns the Highlight of the DataSet that contains the closest value on the + * y-axis. + * + * @param closestValues contains two Highlight objects per DataSet closest to the selected x-position (determined by + * rounding up an down) + * @param axis the closest axis + */ + fun getClosestHighlightByPixel( + closestValues: MutableList, x: Float, y: Float, + axis: AxisDependency?, minSelectionDistance: Float + ): Highlight? { + var closest: Highlight? = null + var distance = minSelectionDistance + + for (i in closestValues.indices) { + val high = closestValues.get(i) + + if (axis == null || high.axis == axis) { + val cDistance = getDistance(x, y, high.xPx, high.yPx) + + if (cDistance < distance) { + closest = high + distance = cDistance + } + } + } + + return closest + } + + /** + * Calculates the distance between the two given points. + */ + protected open fun getDistance(x1: Float, y1: Float, x2: Float, y2: Float): Float { + //return Math.abs(y1 - y2); + //return Math.abs(x1 - x2); + return hypot((x1 - x2).toDouble(), (y1 - y2).toDouble()).toFloat() + } + + protected open val data: BarLineScatterCandleBubbleData<*> + get() = provider!!.getData() +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/CombinedHighlighter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/CombinedHighlighter.java deleted file mode 100644 index b17cb7eed2..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/CombinedHighlighter.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.github.mikephil.charting.highlight; - -import com.github.mikephil.charting.data.BarData; -import com.github.mikephil.charting.data.BarLineScatterCandleBubbleData; -import com.github.mikephil.charting.data.ChartData; -import com.github.mikephil.charting.data.DataSet; -import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider; -import com.github.mikephil.charting.interfaces.dataprovider.CombinedDataProvider; -import com.github.mikephil.charting.interfaces.datasets.IDataSet; - -import java.util.List; - -/** - * Created by Philipp Jahoda on 12/09/15. - */ -public class CombinedHighlighter extends ChartHighlighter implements IHighlighter { - - /** - * bar highlighter for supporting stacked highlighting - */ - protected BarHighlighter barHighlighter; - - public CombinedHighlighter(CombinedDataProvider chart, BarDataProvider barChart) { - super(chart); - - // if there is BarData, create a BarHighlighter - barChart.getBarData(); - barHighlighter = new BarHighlighter(barChart); - } - - @Override - protected List getHighlightsAtXValue(float xVal, float x, float y) { - - mHighlightBuffer.clear(); - - List dataObjects = mChart.getCombinedData().getAllData(); - - for (int i = 0; i < dataObjects.size(); i++) { - - ChartData dataObject = dataObjects.get(i); - - // in case of BarData, let the BarHighlighter take over - if (barHighlighter != null && dataObject instanceof BarData) { - Highlight high = barHighlighter.getHighlight(x, y); - - if (high != null) { - high.setDataIndex(i); - mHighlightBuffer.add(high); - } - } else { - - for (int j = 0, dataSetCount = dataObject.getDataSetCount(); j < dataSetCount; j++) { - - IDataSet dataSet = dataObjects.get(i).getDataSetByIndex(j); - - // don't include datasets that cannot be highlighted - if (!dataSet.isHighlightEnabled()) { - continue; - } - - List highs = buildHighlights(dataSet, j, xVal, DataSet.Rounding.CLOSEST); - for (Highlight high : highs) { - high.setDataIndex(i); - mHighlightBuffer.add(high); - } - } - } - } - - return mHighlightBuffer; - } - -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/CombinedHighlighter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/CombinedHighlighter.kt new file mode 100644 index 0000000000..61f3f9211c --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/CombinedHighlighter.kt @@ -0,0 +1,62 @@ +package com.github.mikephil.charting.highlight + +import com.github.mikephil.charting.data.BarData +import com.github.mikephil.charting.data.ChartData +import com.github.mikephil.charting.data.DataSet +import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider +import com.github.mikephil.charting.interfaces.dataprovider.CombinedDataProvider +import com.github.mikephil.charting.interfaces.datasets.IDataSet + +open class CombinedHighlighter(dataProvider: CombinedDataProvider?, barChart: BarDataProvider) : ChartHighlighter(dataProvider), IHighlighter { + /** + * bar highlighter for supporting stacked highlighting + */ + protected var barHighlighter: BarHighlighter? + + init { + // if there is BarData, create a BarHighlighter + barChart.barData + barHighlighter = BarHighlighter(barChart) + } + + override fun getHighlightsAtXValue(xVal: Float, x: Float, y: Float): MutableList? { + mHighlightBuffer.clear() + + val dataObjects = provider!!.combinedData!!.getAllData() + + for (i in dataObjects.indices) { + val dataObject: ChartData<*> = dataObjects[i] + + // in case of BarData, let the BarHighlighter take over + if (barHighlighter != null && dataObject is BarData) { + val high = barHighlighter!!.getHighlight(x, y) + + if (high != null) { + high.dataIndex = i + mHighlightBuffer.add(high) + } + } else { + var j = 0 + val dataSetCount = dataObject.getDataSetCount() + while (j < dataSetCount) { + val dataSet: IDataSet<*> = dataObjects[i].getDataSetByIndex(j) + + // don't include datasets that cannot be highlighted + if (!dataSet.isHighlightEnabled) { + j++ + continue + } + + val highs = buildHighlights(dataSet, j, xVal, DataSet.Rounding.CLOSEST) + for (high in highs) { + high.dataIndex = i + mHighlightBuffer.add(high) + } + j++ + } + } + } + + return mHighlightBuffer + } +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/HorizontalBarHighlighter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/HorizontalBarHighlighter.java deleted file mode 100644 index f02b4e212b..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/HorizontalBarHighlighter.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.github.mikephil.charting.highlight; - -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.MPPointD; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Philipp Jahoda on 22/07/15. - */ -public class HorizontalBarHighlighter extends BarHighlighter { - - public HorizontalBarHighlighter(BarDataProvider chart) { - super(chart); - } - - @Override - public Highlight getHighlight(float x, float y) { - - BarData barData = mChart.getBarData(); - - MPPointD pos = getValsForTouch(y, x); - - Highlight high = getHighlightForX((float) pos.y, y, x); - if (high == null) - return null; - - IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex()); - if (set.isStacked()) { - - return getStackedHighlight(high, - set, - (float) pos.y, - (float) pos.x); - } - - MPPointD.recycleInstance(pos); - - return high; - } - - @Override - protected List buildHighlights(IDataSet set, int dataSetIndex, float xVal, DataSet.Rounding rounding) { - - ArrayList highlights = new ArrayList<>(); - - //noinspection unchecked - List entries = set.getEntriesForXValue(xVal); - if (entries.isEmpty()) { - // 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()); - } - } - - if (entries.isEmpty()) - 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 - protected float getDistance(float x1, float y1, float x2, float y2) { - return Math.abs(y1 - y2); - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/HorizontalBarHighlighter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/HorizontalBarHighlighter.kt new file mode 100644 index 0000000000..863b65bd9d --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/HorizontalBarHighlighter.kt @@ -0,0 +1,65 @@ +package com.github.mikephil.charting.highlight + +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.IDataSet +import com.github.mikephil.charting.utils.MPPointD +import kotlin.math.abs + +class HorizontalBarHighlighter(dataProvider: BarDataProvider?) : BarHighlighter(dataProvider) { + override fun getHighlight(x: Float, y: Float): Highlight? { + val barData = provider!!.barData + + val pos = getValsForTouch(y, x) + + val high = getHighlightForX(pos.y.toFloat(), y, x) ?: return null + + val set = barData.getDataSetByIndex(high.dataSetIndex) + if (set.isStacked()) { + return getStackedHighlight( + high, + set, + pos.y.toFloat(), + pos.x.toFloat() + ) + } + + MPPointD.recycleInstance(pos) + + return high + } + + override fun buildHighlights(set: IDataSet<*>, dataSetIndex: Int, xVal: Float, rounding: DataSet.Rounding?): MutableList { + val highlights = ArrayList() + + var entries = set.getEntriesForXValue(xVal) + if (entries != null && entries.isEmpty()) { + // Try to find closest x-value and take all entries for that x-value + val closestEntry: Entry? = set.getEntryForXValue(xVal, Float.NaN, rounding) + closestEntry?.let { closestE -> + entries = set.getEntriesForXValue(closestE.x) + } + } + + if (entries != null && entries.isEmpty()) + return highlights + + if (entries != null) + for (entry in entries) { + val pixels = provider!!.getTransformer(set.axisDependency)!!.getPixelForValues(entry.y, entry.x) + + highlights.add( + Highlight( + entry.x, entry.y, + pixels.x.toFloat(), pixels.y.toFloat(), + dataSetIndex, set.axisDependency + ) + ) + } + + return highlights + } + + override fun getDistance(x1: Float, y1: Float, x2: Float, y2: Float) = abs(y1 - y2) +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/IHighlighter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/IHighlighter.java deleted file mode 100644 index 4dd0a086f2..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/IHighlighter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.mikephil.charting.highlight; - -/** - * Created by philipp on 10/06/16. - */ -public interface IHighlighter { - - /** - * Returns a Highlight object corresponding to the given x- and y- touch positions in pixels. - */ - Highlight getHighlight(float x, float y); -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/IHighlighter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/IHighlighter.kt new file mode 100644 index 0000000000..4b06631734 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/IHighlighter.kt @@ -0,0 +1,8 @@ +package com.github.mikephil.charting.highlight + +interface IHighlighter { + /** + * Returns a Highlight object corresponding to the given x- and y- touch positions in pixels. + */ + fun getHighlight(x: Float, y: Float): Highlight? +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/PieHighlighter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/PieHighlighter.kt index a1ecb565ce..728b7ae17a 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/PieHighlighter.kt +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/PieHighlighter.kt @@ -5,7 +5,7 @@ import com.github.mikephil.charting.data.Entry class PieHighlighter(chart: PieChart) : PieRadarHighlighter(chart) { override fun getClosestHighlight(index: Int, x: Float, y: Float): Highlight? { - val pieDataSet = mChart!!.data!!.dataSet + val pieDataSet = chart!!.data!!.dataSet val entry: Entry? = pieDataSet.getEntryForIndex(index) diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/PieRadarHighlighter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/PieRadarHighlighter.java deleted file mode 100644 index f6a9c8fcfd..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/PieRadarHighlighter.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.github.mikephil.charting.highlight; - -import com.github.mikephil.charting.charts.PieChart; -import com.github.mikephil.charting.charts.PieRadarChartBase; - -import java.util.ArrayList; -import java.util.List; - -/** - * Created by philipp on 12/06/16. - */ -public abstract class PieRadarHighlighter implements IHighlighter { - - protected T mChart; - - /** - * buffer for storing previously highlighted values - */ - protected List mHighlightBuffer = new ArrayList<>(); - - public PieRadarHighlighter(T chart) { - this.mChart = chart; - } - - @Override - public Highlight getHighlight(float x, float y) { - - float touchDistanceToCenter = mChart.distanceToCenter(x, y); - - // check if a slice was touched - if (touchDistanceToCenter > mChart.getRadius()) { - - // if no slice was touched, highlight nothing - return null; - - } else { - - float angle = mChart.getAngleForPoint(x, y); - - if (mChart instanceof PieChart) { - angle /= mChart.getAnimator().getPhaseY(); - } - - int index = mChart.getIndexForAngle(angle); - - // check if the index could be found - if (index < 0 || index >= mChart.getData().getMaxEntryCountSet().getEntryCount()) { - return null; - - } else { - return getClosestHighlight(index, x, y); - } - } - } - - /** - * Returns the closest Highlight object of the given objects based on the touch position inside the chart. - */ - protected abstract Highlight getClosestHighlight(int index, float x, float y); -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/PieRadarHighlighter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/PieRadarHighlighter.kt new file mode 100644 index 0000000000..6da22656c2 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/PieRadarHighlighter.kt @@ -0,0 +1,42 @@ +package com.github.mikephil.charting.highlight + +import com.github.mikephil.charting.charts.PieChart +import com.github.mikephil.charting.charts.PieRadarChartBase + +abstract class PieRadarHighlighter?>(protected var chart: T?) : IHighlighter { + /** + * buffer for storing previously highlighted values + */ + protected var mHighlightBuffer: MutableList = ArrayList() + + override fun getHighlight(x: Float, y: Float): Highlight? { + val touchDistanceToCenter = chart!!.distanceToCenter(x, y) + + // check if a slice was touched + if (touchDistanceToCenter > chart!!.getRadius()) { + // if no slice was touched, highlight nothing + + return null + } else { + var angle = chart!!.getAngleForPoint(x, y) + + if (chart is PieChart) { + angle /= chart!!.animator.phaseY + } + + val index = chart!!.getIndexForAngle(angle) + + // check if the index could be found + return if (index < 0 || index >= chart!!.getData()!!.getMaxEntryCountSet().entryCount) { + null + } else { + getClosestHighlight(index, x, y) + } + } + } + + /** + * Returns the closest Highlight object of the given objects based on the touch position inside the chart. + */ + protected abstract fun getClosestHighlight(index: Int, x: Float, y: Float): Highlight? +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/RadarHighlighter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/RadarHighlighter.java deleted file mode 100644 index d9c64f6672..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/RadarHighlighter.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.github.mikephil.charting.highlight; - -import com.github.mikephil.charting.charts.RadarChart; -import com.github.mikephil.charting.data.Entry; -import com.github.mikephil.charting.interfaces.datasets.IDataSet; -import com.github.mikephil.charting.utils.MPPointF; -import com.github.mikephil.charting.utils.Utils; - -import java.util.List; - -/** - * Created by philipp on 12/06/16. - */ -public class RadarHighlighter extends PieRadarHighlighter { - - public RadarHighlighter(RadarChart chart) { - super(chart); - } - - @Override - protected Highlight getClosestHighlight(int index, float x, float y) { - - List highlights = getHighlightsAtIndex(index); - - float distanceToCenter = mChart.distanceToCenter(x, y) / mChart.getFactor(); - - Highlight closest = null; - float distance = Float.MAX_VALUE; - - for (int i = 0; i < highlights.size(); i++) { - - Highlight high = highlights.get(i); - - float cdistance = Math.abs(high.getY() - distanceToCenter); - if (cdistance < distance) { - closest = high; - distance = cdistance; - } - } - - return closest; - } - - /** - * Returns an array of Highlight objects for the given index. The Highlight - * objects give information about the value at the selected index and the - * DataSet it belongs to. INFORMATION: This method does calculations at - * runtime. Do not over-use in performance critical situations. - */ - protected List getHighlightsAtIndex(int index) { - - mHighlightBuffer.clear(); - - float phaseX = mChart.getAnimator().getPhaseX(); - float phaseY = mChart.getAnimator().getPhaseY(); - float sliceangle = mChart.getSliceAngle(); - float factor = mChart.getFactor(); - - MPPointF pOut = MPPointF.getInstance(0, 0); - for (int i = 0; i < mChart.getData().getDataSetCount(); i++) { - - IDataSet dataSet = mChart.getData().getDataSetByIndex(i); - - final Entry entry = dataSet.getEntryForIndex(index); - - float y = (entry.getY() - mChart.getYChartMin()); - - Utils.getPosition( - mChart.getCenterOffsets(), y * factor * phaseY, - sliceangle * index * phaseX + mChart.getRotationAngle(), pOut - ); - - mHighlightBuffer.add(new Highlight(index, entry.getY(), pOut.x, pOut.y, i, dataSet.getAxisDependency())); - } - - return mHighlightBuffer; - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/RadarHighlighter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/RadarHighlighter.kt new file mode 100644 index 0000000000..f0d2ac305d --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/RadarHighlighter.kt @@ -0,0 +1,64 @@ +package com.github.mikephil.charting.highlight + +import com.github.mikephil.charting.charts.RadarChart +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.interfaces.datasets.IDataSet +import com.github.mikephil.charting.utils.MPPointF +import com.github.mikephil.charting.utils.Utils +import kotlin.math.abs + +open class RadarHighlighter(chart: RadarChart?) : PieRadarHighlighter(chart) { + override fun getClosestHighlight(index: Int, x: Float, y: Float): Highlight? { + val highlights = getHighlightsAtIndex(index) + + val distanceToCenter = chart!!.distanceToCenter(x, y) / chart!!.getFactor() + + var closest: Highlight? = null + var distance = Float.MAX_VALUE + + for (i in highlights.indices) { + val high = highlights[i] + + val cDistance = abs(high.y - distanceToCenter) + if (cDistance < distance) { + closest = high + distance = cDistance + } + } + + return closest + } + + /** + * Returns an array of Highlight objects for the given index. The Highlight + * objects give information about the value at the selected index and the + * DataSet it belongs to. INFORMATION: This method does calculations at + * runtime. Do not over-use in performance critical situations. + */ + protected fun getHighlightsAtIndex(index: Int): MutableList { + mHighlightBuffer.clear() + + val phaseX = chart!!.animator.phaseX + val phaseY = chart!!.animator.phaseY + val sliceAngle = chart!!.sliceAngle + val factor = chart!!.getFactor() + + val pOut = MPPointF.getInstance(0f, 0f) + for (i in 0.. = chart!!.data!!.getDataSetByIndex(i) + + val entry: Entry? = dataSet.getEntryForIndex(index) + + val y = (entry!!.y - chart!!.yChartMin) + + Utils.getPosition( + chart!!.centerOffsets, y * factor * phaseY, + sliceAngle * index * phaseX + chart!!.rotationAngle, pOut + ) + + mHighlightBuffer.add(Highlight(index.toFloat(), entry.y, pOut.x, pOut.y, i, dataSet.axisDependency)) + } + + return mHighlightBuffer + } +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/Range.java b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/Range.java deleted file mode 100644 index 39363f4a5b..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/Range.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.github.mikephil.charting.highlight; - -/** - * Created by Philipp Jahoda on 24/07/15. Class that represents the range of one value in a stacked bar entry. e.g. - * stack values are -10, 5, 20 -> then ranges are (-10 - 0, 0 - 5, 5 - 25). - */ -public final class Range { - - public float from; - public float to; - - public Range(float from, float to) { - this.from = from; - this.to = to; - } - - /** - * Returns true if this range contains (if the value is in between) the given value, false if not. - */ - public boolean contains(float value) { - - if (value > from && value <= to) - return true; - else - return false; - } - - public boolean isLarger(float value) { - return value > to; - } - - public boolean isSmaller(float value) { - return value < from; - } -} \ No newline at end of file diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/Range.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/Range.kt new file mode 100644 index 0000000000..5250cd4ace --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/Range.kt @@ -0,0 +1,22 @@ +package com.github.mikephil.charting.highlight + +/** + * Class that represents the range of one value in a stacked bar entry. e.g. + * stack values are -10, 5, 20 -> then ranges are (-10 - 0, 0 - 5, 5 - 25). + */ +class Range(var from: Float, @JvmField var to: Float) { + /** + * Returns true if this range contains (if the value is in between) the given value, false if not. + */ + fun contains(value: Float): Boolean { + return value > from && value <= to + } + + fun isLarger(value: Float): Boolean { + return value > to + } + + fun isSmaller(value: Float): Boolean { + return value < from + } +}