如何在AndroidPlot中显示XYPlot的X和Y轴

时间:2015-07-02 17:23:20

标签: android androidplot

背景

我正在开发一款适用于Android的应用,它使用AndroidPlot将数据绘制为线图。由于数据的性质,重要的是它是可空的和可缩放的。我在bitbucket上使用AndroidPlot的示例代码panning and zooming,修改为允许在X和Y方向平移和缩放。

除了没有X和Y轴线外,一切都按预期工作。没有它们看数据是非常迷惑的。网格有帮助,但不能保证网格线实际上会落在轴上。

为了解决这个问题,我尝试添加两个系列,一个只落在X轴上,另一个落在Y上。这个问题是如果一个缩小得太远,轴就会结束,很明显我申请了'黑客'。

问题

是否可以将X和Y轴线添加到AndroidPlot?或者我的悲伤黑客必须做什么?

修改 添加了标签

1 个答案:

答案 0 :(得分:0)

我明白了。这不是一件轻而易举的事情,与合作者共同努力,耗费了我们很多时间。

从我的问题中提到的示例开始,我不得不扩展XYPlot(我称之为GraphView)并覆盖onPreInit方法。请注意,我有两个PointF,minXY和maxXY,它们在我重写的XYPlot中定义,并在我缩放或滚动时进行操作。

@Override
protected void onPreInit() {
    super.onPreInit();

    final Paint axisPaint = new Paint();
    axisPaint.setColor(getResources().getColor(R.color.MY_AXIS_COLOR));
    axisPaint.setStrokeWidth(3); //or whatever stroke width you want

    XYGraphWidget oldWidget = getGraphWidget();
    XYGraphWidget widget = new XYGraphWidget(getLayoutManager(),
            this,
            new SizeMetrics(
                    oldWidget.getHeightMetric(),
                    oldWidget.getWidthMetric())) {
        //We now override XYGraphWidget methods
        RectF mGridRect;
        @Override
        protected void doOnDraw(Canvas canvas, RectF widgetRect)
                throws PlotRenderException {
            //In order to draw the x axis, we must obtain gridRect. I believe this is the only
            //way to do so as the more convenient routes have private rather than protected access.
            mGridRect = new RectF(widgetRect.left + ((isRangeAxisLeft())?getRangeLabelWidth():1),
                    widgetRect.top + ((isDomainAxisBottom())?1:getDomainLabelWidth()),
                    widgetRect.right - ((isRangeAxisLeft())?1:getRangeLabelWidth()),
                    widgetRect.bottom - ((isDomainAxisBottom())?getDomainLabelWidth():1));
            super.doOnDraw(canvas, widgetRect);
        }
        @Override
        protected void drawGrid(Canvas canvas) {
            super.drawGrid(canvas);
            if(mGridRect == null) return;
            //minXY and maxXY are PointF's defined elsewhere. See my comment in the answer.
            if(minXY.y <= 0 && maxXY.y >= 0) { //Draw the x axis
                RectF paddedGridRect = getGridRect();
                //Note: GraphView.this is the extended XYPlot instance.
                XYStep rangeStep = XYStepCalculator.getStep(GraphView.this, XYAxisType.RANGE,
                        paddedGridRect, getCalculatedMinY().doubleValue(),
                        getCalculatedMaxY().doubleValue());
                double rangeOriginF = paddedGridRect.bottom;
                float yPix = (float) (rangeOriginF + getRangeOrigin().doubleValue() * rangeStep.getStepPix() /
                        rangeStep.getStepVal());
                //Keep things consistent with drawing y axis even though drawRangeTick is public
                //drawRangeTick(canvas, yPix, 0, getRangeLabelPaint(), axisPaint, true);
                canvas.drawLine(mGridRect.left, yPix, mGridRect.right, yPix, axisPaint);
            }
            if(minXY.x <= 0 && maxXY.x >= 0) { //Draw the y axis
                RectF paddedGridRect = getGridRect();
                XYStep domianStep = XYStepCalculator.getStep(GraphView.this, XYAxisType.DOMAIN,
                        paddedGridRect, getCalculatedMinX().doubleValue(),
                        getCalculatedMaxX().doubleValue());
                double domainOriginF = paddedGridRect.left;
                float xPix = (float) (domainOriginF - getDomainOrigin().doubleValue() * domianStep.getStepPix() /
                        domianStep.getStepVal());
                //Unfortunately, drawDomainTick has private access in XYGraphWidget
                canvas.drawLine(xPix, mGridRect.top, xPix, mGridRect.bottom, axisPaint);
            }
        }
    };
    widget.setBackgroundPaint(oldWidget.getBackgroundPaint());
    widget.setMarginTop(oldWidget.getMarginTop());
    widget.setMarginRight(oldWidget.getMarginRight());
    widget.setPositionMetrics(oldWidget.getPositionMetrics());
    getLayoutManager().remove(oldWidget);
    getLayoutManager().addToTop(widget);
    setGraphWidget(widget);
    //More customizations can go here
}

就是这样。我确定希望这是内置于AndroidPlot中;当它在AndroidPlot更新中断时,尝试解决这个问题会很讨厌......