Get the correct position of a point in AndroidPlot

这一生的挚爱 提交于 2019-12-01 09:19:25

I don't know if there's a better built-in solution, but here's a manual approach.
The following code places the cursor at the X coordinate where the user touched the screen and the corresponding Y coordinate of the first data series of the plot.

//NOTE about XYPlotZoomPan: when an OnTouchListener is set, zooming is disabled. Subclass to avoid it.
mPlot.setOnTouchListener(new View.OnTouchListener(){
    @Override
    public boolean onTouch(View v, MotionEvent me) {
        float touchX = me.getX();
        float touchY = me.getY();
        XYGraphWidget widget = mPlot.getGraphWidget();
        RectF gridRect = widget.getGridRect();
        if(gridRect.contains(touchX, touchY)){ //Check the touch event is in the grid
            XYSeries xyData = mPlot.getSeriesSet().iterator().next();
            long targetValX = Math.round(widget.getXVal(touchX));
            Log.d(TAG, "Touched at " + touchX + ", " + touchY + ". Target val X: " + targetValX);
            Long targetValY = null; 
            Long prevValX = null;
            if(mPlot.getSeriesSet().size() > 1){
                Log.w(TAG, "More than one series in plot. Using only the first one");
            }
            for(int i = 0; i < xyData.size(); ++i){
                long currValX = xyData.getX(i).longValue();
                long currValY = xyData.getY(i).longValue();
                //Calculate the range value of the closest domain value (assumes xyData is sorted in ascending X order)
                if(currValX >= targetValX){
                    long currDiff = currValX - targetValX; 
                    if(prevValX != null && (targetValX - prevValX) < currDiff){
                        targetValY = xyData.getY(i-1).longValue();
                    }else{
                        targetValY = currValY;
                    }
                    break;
                }
                prevValX = currValX;
            }
            if(targetValY != null){
                long maxValY = mPlot.getCalculatedMaxY().longValue();
                long minValY = mPlot.getCalculatedMinY().longValue();
                float pixelPosY = gridRect.top + ValPixConverter.valToPix(
                        (double)targetValY, (double)minValY, (double)maxValY, (float)gridRect.height(), true);
                widget.setRangeCursorPosition(pixelPosY);
                widget.setDomainCursorPosition(touchX);
                Log.d(TAG, String.format("Domain cursor set at Y %.2f, val %.2f = %d, min-maxValY (%d, %d)",
                        pixelPosY,
                        widget.getRangeCursorVal(), targetValY,
                        minValY, maxValY));
            }else{
                Log.w(TAG, "Couldn't find the closest range to the selected domain coordinate");
            }
            mPlot.invalidate();
        }else{
            Log.d(TAG, "Touched outside the plot grid");
        }

        return false;
    }
});

i`ve found a solution. My intent was to find the value for a given pixel (for example by tapping on the plot, i wanted the representing value). So, after a bit of searching i found the helper-class ValPixConverter. It provides a few methods that fit my needs. Unfortunately there is no documentation of the methods, but i found a solution:

    private float pixelToValueY(float y) {
    //Parameters: 1=input y-value, 2=minmal y-value that is shown,  3=maximal y-value that is shown, 4=Hight of the view, 5=flip
    return (float) ValPixConverter.pixToVal(y, minXY.y, maxXY.y, mySimpleXYPlot.getHeight(), false);
    }

    private float pixelToValueX(float x) {
    //Parameters: 1=input y-value, 2=minmal y-value that is shown,  3=maximal y-value that is shown, 4=Hight of the view, 5=flip
    return (float) ValPixConverter.pixToVal(x, minXY.x, maxXY.x, mySimpleXYPlot.getWidth(), false);
    }

You need just the other way. The method valToPix() will do this. It`s then very similar with the Code above.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!