如何使用AndroidPlot的圆形(平滑)角线

我有一个小问题,打搅我的图表.在下面的图片上我已经做了.

图表应该表示可用Wi-Fi网络的实际信号强度.这是一个简单的XYPlot,这里的数据用SimpleXYSeries表示(值是动态创建的).

以下是一小段代码(仅举例):

plot = (XYPlot) findViewById(R.id.simplexyPlot);
series1 = new SimpleXYSeries(Arrays.asList(series1Numbers),SimpleXYSeries.ArrayFormat.Y_VALS_ONLY,"Link 1");
f1 = new LineAndPointFormatter(color.getColor(),null,Color.argb(60,color.getRed(),color.getGreen(),color.getBlue()),null);
plot.addSeries(series1,f1);

图中的例子是dB变化的动态模拟.一切正常,我猜,正确的是,但我想要实现的是具有“圆角”的角落(见图片看看我的意思).

我已经尝试自定义LineFormatter:

f1.getFillPaint().setstrokeJoin(Join.ROUND);
f1.getFillPaint().setstrokeWidth(8);

但这没有按预期的方式工作.

注意:Wifi Analyzer应用程序具有相似的图形,其图形具有我想要的圆角.看起来像这样:

解决方法

您可以使用 Path.cubicTo()方法.它使用三次样条算法绘制一条线,其导致所需的平滑效果.

结束一个similar question here的答案,一个人在谈论三次样条.有一个简短的算法显示如何计算Path.cubicTo()方法的输入参数.您可以使用分频值来实现所需的平滑度.例如,在下面的图片中,我除以5而不是3.希望这有帮助.

我花了一些时间,并实现了一个SplineLineAndPointFormatter类,它在androidplot库中完成所需的工作.它使用相同的技术.这是androidplot示例应用程序的样子.你只需要使用它而不是LineAndPointFormatter.

这里是代码示例和我写的类.

f1 = new SplineLineAndPointFormatter(color.getColor(),f1);

这是做魔术的班.它基于androidplot库的0.6.1版本.

package com.androidplot.xy;

import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.RectF;

import com.androidplot.ui.SeriesRenderer;
import com.androidplot.util.ValPixConverter;

public class SplineLineAndPointFormatter extends LineAndPointFormatter {

    public SplineLineAndPointFormatter() { }

    public SplineLineAndPointFormatter(Integer lineColor,Integer vertexColor,Integer fillColor) {
        super(lineColor,vertexColor,fillColor,null);
    }

    public SplineLineAndPointFormatter(Integer lineColor,Integer fillColor,FillDirection fillDir) {
        super(lineColor,fillDir);
    }

    @Override
    public Class<? extends SeriesRenderer> getRendererClass() {
        return SplineLineAndPointRenderer.class;
    }

    @Override
    public SeriesRenderer getRendererInstance(XYPlot plot) {
        return new SplineLineAndPointRenderer(plot);
    }

    public static class SplineLineAndPointRenderer extends LineAndPointRenderer<BezierLineAndPointFormatter> {

        static class Point {
            public float x,y,dx,dy;
            public Point(PointF pf) { x = pf.x; y = pf.y; }
        }

        private Point prev,point,next;
        private int pointsCounter;

        public SplineLineAndPointRenderer(XYPlot plot) {
            super(plot);
        }

        @Override
        protected void appendToPath(Path path,final PointF thisPoint,PointF lastPoint) {
            pointsCounter--;

            if (point == null) {
                point = new Point(thisPoint);
                point.dx = ((point.x - prev.x) / 5);
                point.dy = ((point.y - prev.y) / 5);
                return;

            } else if (next == null) {
                next = new Point(thisPoint);
            } else {
                prev = point;
                point = next;
                next = new Point(thisPoint);
            }

            point.dx = ((next.x - prev.x) / 5);
            point.dy = ((next.y - prev.y) / 5);
            path.cubicTo(prev.x + prev.dx,prev.y + prev.dy,point.x - point.dx,point.y - point.dy,point.x,point.y);

            if (pointsCounter == 1) { // last point
                next.dx = ((next.x - point.x) / 5);
                next.dy = ((next.y - point.y) / 5);
                path.cubicTo(point.x + point.dx,point.y + point.dy,next.x - next.dx,next.y - next.dy,next.x,next.y);
            }

        }

        @Override
        protected void drawSeries(Canvas canvas,RectF plotArea,XYSeries series,LineAndPointFormatter formatter) {

            Number y = series.getY(0);
            Number x = series.getX(0);
            if (x == null || y == null) throw new IllegalArgumentException("no null values in xyseries permitted");

            XYPlot p = getPlot();
            PointF thisPoint = ValPixConverter.valToPix(x,plotArea,p.getCalculatedMinX(),p.getCalculatedMaxX(),p.getCalculatedMinY(),p.getCalculatedMaxY());

            prev = new Point(thisPoint);
            point = next = null;
            pointsCounter = series.size();

            super.drawSeries(canvas,series,formatter);
        }
    }
}

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...