tutorial studio piechart mpchart mpa graficar docs datos android charts mpandroidchart

studio - MPAndroidChart: ¿Cómo obtengo el valor x de gráfico correspondiente para un punto de píxel?



mpchart docs (1)

¿Cómo puedo obtener el valor del eje x correspondiente (xIndex) de un punto de píxel en un ScatterChart?

He estado buscando en el código fuente de la biblioteca y creo que uno de los métodos a continuación (que copio / pegué desde el código fuente de la biblioteca aquí ) puede ayudar. Parece que getValuesByTouchPoint es el método correcto, pero no sé cómo usarlo.

/** * Transformer class that contains all matrices and is responsible for * transforming values into pixels on the screen and backwards. * * @author Philipp Jahoda */ public class Transformer { /** * matrix to map the values to the screen pixels */ protected Matrix mMatrixValueToPx = new Matrix(); /** * matrix for handling the different offsets of the chart */ protected Matrix mMatrixOffset = new Matrix(); protected ViewPortHandler mViewPortHandler; public Transformer(ViewPortHandler viewPortHandler) { this.mViewPortHandler = viewPortHandler; } /** * Prepares the matrix that transforms values to pixels. Calculates the * scale factors from the charts size and offsets. * * @param xChartMin * @param deltaX * @param deltaY * @param yChartMin */ public void prepareMatrixValuePx(float xChartMin, float deltaX, float deltaY, float yChartMin) { float scaleX = (float) ((mViewPortHandler.contentWidth()) / deltaX); float scaleY = (float) ((mViewPortHandler.contentHeight()) / deltaY); if (Float.isInfinite(scaleX)) { scaleX = 0; } if (Float.isInfinite(scaleY)) { scaleY = 0; } // setup all matrices mMatrixValueToPx.reset(); mMatrixValueToPx.postTranslate(-xChartMin, -yChartMin); mMatrixValueToPx.postScale(scaleX, -scaleY); } /** * Prepares the matrix that contains all offsets. * * @param inverted */ public void prepareMatrixOffset(boolean inverted) { mMatrixOffset.reset(); // offset.postTranslate(mOffsetLeft, getHeight() - mOffsetBottom); if (!inverted) mMatrixOffset.postTranslate(mViewPortHandler.offsetLeft(), mViewPortHandler.getChartHeight() - mViewPortHandler.offsetBottom()); else { mMatrixOffset .setTranslate(mViewPortHandler.offsetLeft(), -mViewPortHandler.offsetTop()); mMatrixOffset.postScale(1.0f, -1.0f); } } protected float[] valuePointsForGenerateTransformedValuesScatter = new float[1]; /** * Transforms an List of Entry into a float array containing the x and * y values transformed with all matrices for the SCATTERCHART. * * @param data * @return */ public float[] generateTransformedValuesScatter(IScatterDataSet data, float phaseX, float phaseY, int from, int to) { final int count = (int) ((to - from) * phaseX + 1) * 2; if (valuePointsForGenerateTransformedValuesScatter.length != count) { valuePointsForGenerateTransformedValuesScatter = new float[count]; } float[] valuePoints = valuePointsForGenerateTransformedValuesScatter; for (int j = 0; j < count; j += 2) { Entry e = data.getEntryForIndex(j / 2 + from); if (e != null) { valuePoints[j] = e.getX(); valuePoints[j + 1] = e.getY() * phaseY; } else { valuePoints[j] = 0; valuePoints[j + 1] = 0; } } getValueToPixelMatrix().mapPoints(valuePoints); return valuePoints; } protected float[] valuePointsForGenerateTransformedValuesBubble = new float[1]; /** * Transforms an List of Entry into a float array containing the x and * y values transformed with all matrices for the BUBBLECHART. * * @param data * @return */ public float[] generateTransformedValuesBubble(IBubbleDataSet data, float phaseY, int from, int to) { final int count = (to - from + 1) * 2; // (int) Math.ceil((to - from) * phaseX) * 2; if (valuePointsForGenerateTransformedValuesBubble.length != count) { valuePointsForGenerateTransformedValuesBubble = new float[count]; } float[] valuePoints = valuePointsForGenerateTransformedValuesBubble; for (int j = 0; j < count; j += 2) { Entry e = data.getEntryForIndex(j / 2 + from); if (e != null) { valuePoints[j] = e.getX(); valuePoints[j + 1] = e.getY() * phaseY; } else { valuePoints[j] = 0; valuePoints[j + 1] = 0; } } getValueToPixelMatrix().mapPoints(valuePoints); return valuePoints; } protected float[] valuePointsForGenerateTransformedValuesLine = new float[1]; /** * Transforms an List of Entry into a float array containing the x and * y values transformed with all matrices for the LINECHART. * * @param data * @return */ public float[] generateTransformedValuesLine(ILineDataSet data, float phaseX, float phaseY, int from, int to) { final int count = (int) ((to - from) * phaseX + 1) * 2; if (valuePointsForGenerateTransformedValuesLine.length != count) { valuePointsForGenerateTransformedValuesLine = new float[count]; } float[] valuePoints = valuePointsForGenerateTransformedValuesLine; for (int j = 0; j < count; j += 2) { Entry e = data.getEntryForIndex(j / 2 + from); if (e != null) { valuePoints[j] = e.getX(); valuePoints[j + 1] = e.getY() * phaseY; } else { valuePoints[j] = 0; valuePoints[j + 1] = 0; } } getValueToPixelMatrix().mapPoints(valuePoints); return valuePoints; } protected float[] valuePointsForGenerateTransformedValuesCandle = new float[1]; /** * Transforms an List of Entry into a float array containing the x and * y values transformed with all matrices for the CANDLESTICKCHART. * * @param data * @return */ public float[] generateTransformedValuesCandle(ICandleDataSet data, float phaseX, float phaseY, int from, int to) { final int count = (int) ((to - from) * phaseX + 1) * 2; if (valuePointsForGenerateTransformedValuesCandle.length != count) { valuePointsForGenerateTransformedValuesCandle = new float[count]; } float[] valuePoints = valuePointsForGenerateTransformedValuesCandle; for (int j = 0; j < count; j += 2) { CandleEntry e = data.getEntryForIndex(j / 2 + from); if (e != null) { valuePoints[j] = e.getX(); valuePoints[j + 1] = e.getHigh() * phaseY; } else { valuePoints[j] = 0; valuePoints[j + 1] = 0; } } getValueToPixelMatrix().mapPoints(valuePoints); return valuePoints; } /** * transform a path with all the given matrices VERY IMPORTANT: keep order * to value-touch-offset * * @param path */ public void pathValueToPixel(Path path) { path.transform(mMatrixValueToPx); path.transform(mViewPortHandler.getMatrixTouch()); path.transform(mMatrixOffset); } /** * Transforms multiple paths will all matrices. * * @param paths */ public void pathValuesToPixel(List<Path> paths) { for (int i = 0; i < paths.size(); i++) { pathValueToPixel(paths.get(i)); } } /** * Transform an array of points with all matrices. VERY IMPORTANT: Keep * matrix order "value-touch-offset" when transforming. * * @param pts */ public void pointValuesToPixel(float[] pts) { mMatrixValueToPx.mapPoints(pts); mViewPortHandler.getMatrixTouch().mapPoints(pts); mMatrixOffset.mapPoints(pts); } /** * Transform a rectangle with all matrices. * * @param r */ public void rectValueToPixel(RectF r) { mMatrixValueToPx.mapRect(r); mViewPortHandler.getMatrixTouch().mapRect(r); mMatrixOffset.mapRect(r); } /** * Transform a rectangle with all matrices with potential animation phases. * * @param r * @param phaseY */ public void rectToPixelPhase(RectF r, float phaseY) { // multiply the height of the rect with the phase r.top *= phaseY; r.bottom *= phaseY; mMatrixValueToPx.mapRect(r); mViewPortHandler.getMatrixTouch().mapRect(r); mMatrixOffset.mapRect(r); } public void rectToPixelPhaseHorizontal(RectF r, float phaseY) { // multiply the height of the rect with the phase r.left *= phaseY; r.right *= phaseY; mMatrixValueToPx.mapRect(r); mViewPortHandler.getMatrixTouch().mapRect(r); mMatrixOffset.mapRect(r); } /** * Transform a rectangle with all matrices with potential animation phases. * * @param r */ public void rectValueToPixelHorizontal(RectF r) { mMatrixValueToPx.mapRect(r); mViewPortHandler.getMatrixTouch().mapRect(r); mMatrixOffset.mapRect(r); } /** * Transform a rectangle with all matrices with potential animation phases. * * @param r * @param phaseY */ public void rectValueToPixelHorizontal(RectF r, float phaseY) { // multiply the height of the rect with the phase r.left *= phaseY; r.right *= phaseY; mMatrixValueToPx.mapRect(r); mViewPortHandler.getMatrixTouch().mapRect(r); mMatrixOffset.mapRect(r); } /** * transforms multiple rects with all matrices * * @param rects */ public void rectValuesToPixel(List<RectF> rects) { Matrix m = getValueToPixelMatrix(); for (int i = 0; i < rects.size(); i++) m.mapRect(rects.get(i)); } protected Matrix mPixelToValueMatrixBuffer = new Matrix(); /** * Transforms the given array of touch positions (pixels) (x, y, x, y, ...) * into values on the chart. * * @param pixels */ public void pixelsToValue(float[] pixels) { Matrix tmp = mPixelToValueMatrixBuffer; tmp.reset(); // invert all matrixes to convert back to the original value mMatrixOffset.invert(tmp); tmp.mapPoints(pixels); mViewPortHandler.getMatrixTouch().invert(tmp); tmp.mapPoints(pixels); mMatrixValueToPx.invert(tmp); tmp.mapPoints(pixels); } /** * buffer for performance */ float[] ptsBuffer = new float[2]; /** * Returns a recyclable MPPointD instance. * returns the x and y values in the chart at the given touch point * (encapsulated in a MPPointD). This method transforms pixel coordinates to * coordinates / values in the chart. This is the opposite method to * getPixelForValues(...). * * @param x * @param y * @return */ public MPPointD getValuesByTouchPoint(float x, float y) { MPPointD result = MPPointD.getInstance(0, 0); getValuesByTouchPoint(x, y, result); return result; } public void getValuesByTouchPoint(float x, float y, MPPointD outputPoint) { ptsBuffer[0] = x; ptsBuffer[1] = y; pixelsToValue(ptsBuffer); outputPoint.x = ptsBuffer[0]; outputPoint.y = ptsBuffer[1]; } /** * Returns a recyclable MPPointD instance. * Returns the x and y coordinates (pixels) for a given x and y value in the chart. * * @param x * @param y * @return */ public MPPointD getPixelForValues(float x, float y) { ptsBuffer[0] = x; ptsBuffer[1] = y; pointValuesToPixel(ptsBuffer); double xPx = ptsBuffer[0]; double yPx = ptsBuffer[1]; return MPPointD.getInstance(xPx, yPx); } public Matrix getValueMatrix() { return mMatrixValueToPx; } public Matrix getOffsetMatrix() { return mMatrixOffset; } private Matrix mMBuffer1 = new Matrix(); public Matrix getValueToPixelMatrix() { mMBuffer1.set(mMatrixValueToPx); mMBuffer1.postConcat(mViewPortHandler.mMatrixTouch); mMBuffer1.postConcat(mMatrixOffset); return mMBuffer1; } private Matrix mMBuffer2 = new Matrix(); public Matrix getPixelToValueMatrix() { getValueToPixelMatrix().invert(mMBuffer2); return mMBuffer2; } }


Usando MPAndroidChart 3.0.1

Creo que el método que quieres es:

public MPPointD getValuesByTouchPoint(float x, float y);

Aquí hay un recorte del javadoc:

/** * Returns a recyclable MPPointD instance. * returns the x and y values in the chart at the given touch point * (encapsulated in a MPPointD). This method transforms pixel coordinates to * coordinates / values in the chart. This is the opposite method to * getPixelsForValues(...).

Para usarlo en tu aplicación, haz algo como esto:

MPPointD point = mChart.getTransformer(AxisDependency.LEFT).getValuesByTouchPoint(x,y); double xValue = point.x; double yValue = point.y;

Los parámetros pasados ​​al método (float x, float y) son sus coordenadas de píxeles que desea convertir en valores xey en su gráfico.