如何设置两个轴的刻度始终相同?

时间:2018-03-12 00:33:59

标签: mpandroidchart

MPAndroidChart允许您放大X轴,Y轴和两者。我想重新缩放剩余的轴(或两者)以匹配被缩放的轴。

为此,我创建了OnChartGestureListener

public class ZoomNotDistorting implements OnChartGestureListener {

    private Chart chart;
    private ViewPortHandler viewPortHandler;
    private float startDist = 1f;
    private float scaleX, scaleY;

    public ZoomNotDistorting(Chart chart) {
        this.chart = chart;
        this.viewPortHandler = chart.getViewPortHandler();
    }

    @Override
    public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
        int action = me.getAction() & MotionEvent.ACTION_MASK;
        if(action == MotionEvent.ACTION_POINTER_DOWN && me.getPointerCount() >= 2) {
            startDist = spacing(me);
        }
    }

    @Override
    public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
        switch (lastPerformedGesture) {
            case PINCH_ZOOM:
                float scale = spacing(me) / startDist; // total scale
                boolean isZoomingOut = (scale < 1);

                if(isZoomingOut) {
                    if(scaleX < scaleY) {
                        viewPortHandler.zoom(scaleX, scaleX);
                    } else {
                        viewPortHandler.zoom(scaleY, scaleY);
                    }
                } else {
                    if(scaleX > scaleY) {
                        viewPortHandler.zoom(scaleX, scaleX);
                    } else {
                        viewPortHandler.zoom(scaleY, scaleY);
                    }
                }

                break;
            case X_ZOOM:
                viewPortHandler.zoom(scaleX, scaleX);
                break;
            case Y_ZOOM:
                viewPortHandler.zoom(scaleY, scaleY);
                break;
        }

        chart.invalidate();
    }

    @Override
    public void onChartLongPressed(MotionEvent me) {}

    @Override
    public void onChartDoubleTapped(MotionEvent me) {}

    @Override
    public void onChartSingleTapped(MotionEvent me) {}

    @Override
    public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {}

    @Override
    public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
        this.scaleX = scaleX;
        this.scaleY = scaleY;
    }

    @Override
    public void onChartTranslate(MotionEvent me, float dX, float dY) {}

    /**
     * returns the distance between two pointer touch points
     */
    private static float spacing(MotionEvent event) {
        float x = event.getX(0) - event.getX(1);
        float y = event.getY(0) - event.getY(1);
        return (float) Math.sqrt(x * x + y * y);
    }

}

该课程似乎没有做任何事情,如何设置两个轴的音阶始终相同?

另外,这是我的图表类:

public class MathGraph extends LineChart {

    public static final int BOUNDARIES = 100;
    public static final int DATA_POINTS = 200;
    private static final int LINE_WIDTH = 2;

    private LineData data;

    public MathGraph(Context context, AttributeSet attrs) {
        super(context, attrs);

        super.setDescription(null);

        //Misc
        getLegend().setEnabled(false);
        setRenderer(new LineChatRendererNoData(this, mAnimator, mViewPortHandler));

        //Lines encasing the chart
        getXAxis().setAxisLineWidth(LINE_WIDTH);
        getAxisLeft().setAxisLineWidth(LINE_WIDTH);
        getAxisRight().setEnabled(false);

        //Line for (x; 0)
        getAxisLeft().setDrawZeroLine(true);
        getAxisLeft().setZeroLineWidth(LINE_WIDTH);
        getAxisRight().setDrawZeroLine(true);
        getAxisRight().setZeroLineWidth(LINE_WIDTH);

        //Line for (0; y)
        LimitLine limitLine = new LimitLine(0f);
        limitLine.setLineColor(Color.GRAY);
        limitLine.setLineWidth(LINE_WIDTH);
        getXAxis().addLimitLine(limitLine);

        setOnChartGestureListener(new ZoomNotDistorting(this));
    }

    public void setFunction(Function f) {
        if(!f.checkSyntax()) throw new IllegalStateException("Error in function: " + f.toString() + "!");

        setDescription(f);

        data = null;

        LoadFunctionAsyncTask l = new LoadFunctionAsyncTask(f, -BOUNDARIES, BOUNDARIES, DATA_POINTS,
                (List<Entry> pointList) -> {
                    if(data == null) {
                        ILineDataSet dataSet = new LineDataSet(new ArrayList<>(), null);
                        dataSet.setValueFormatter(new PointValueFormatter());
                        dataSet.setHighlightEnabled(true);

                        for (Entry dataPoint : pointList) {
                            dataSet.addEntry(dataPoint);
                        }

                        data = new LineData(dataSet);

                        setData(data);
                    } else {
                        for (Entry dataPoint : pointList) {
                            data.addEntry(dataPoint, 0);// 0 is the only dataset
                        }

                        data.notifyDataChanged();
                        notifyDataSetChanged();
                        invalidate();
                    }
        });

        l.execute();
    }

    private void setDescription(Function f) {
        Description desc = new Description();
        desc.setText(f.getDescription());
        desc.setPosition(16, getBottom() - 16);
        setDescription(desc);
    }

    private class PointValueFormatter implements IValueFormatter {
        @Override
        public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
            return "(" + entry.getX() + ", " + entry.getY() + ")";
        }
    }
}

1 个答案:

答案 0 :(得分:0)

好的,显然chart.invalidate()还不够,Matrix需要刷新:

Matrix matrix = null;

//...
matrix = viewPortHandler.zoom(scaleX, scaleX);
//...

if(matrix != null) {
    viewPortHandler.refresh(matrix, chart, true);
}

作为奖励,true中的最后一个refresh()用于无效,因此无需chart.invalidate();