如何使圆角(平滑)角落AndroidPlot线 [英] How to make line with rounded (smooth) corners with AndroidPlot

查看:156
本文介绍了如何使圆角(平滑)角落AndroidPlot线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小问题,ploting我的图形。下面的图片是什么,我已经做了。

I have a small problem with ploting my graph. On a picture below is what I have already done.

该图应该重新present可用的Wi-Fi网络(S)的实际信号强度。这是一个简单的 XYPlot 这里的数据重新psented与 SimpleXYSeries $ P $(动态创建的值)。

The graph should represent the actual signal strength of available Wi-Fi network(s). It's a simple XYPlot here data are represented with SimpleXYSeries (values are dynamically created).

下面是code(例如只)一个小片段:

Here is a little snippet of code (only for example):

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);

图中的例子是分贝变化的动态模拟。一切正常,我猜,正确的,但我想实现的是有四舍五入边角线(见图片明白我的意思)。

The example in the picture is a dynamic simulation of dB changes. Everything works, I guess, correctly, but what I want to achieve is to have line with "rounded" corners (see the picture to see what I mean).

我已经尝试过定制LineFormatter:

I already tried to customize LineFormatter:

f1.getFillPaint().setStrokeJoin(Join.ROUND);
f1.getFillPaint().setStrokeWidth(8);

但是,这没有如预期正常工作。

But this didn't work as expected.

注:无线分析仪应用也有类似的图形和图形具有圆角我想要的。它看起来是这样的:

Note: The Wifi Analyzer application has a similar graph and its graph has the rounded corners I want. It looks like this:

推荐答案

您可以使用<一个href="http://developer.android.com/reference/android/graphics/Path.html#cubicTo%28float,%20float,%20float,%20float,%20float,%20float%29">Path.cubicTo()方法。它采用三次样条算法,这会导致你想要的平滑效果绘制一条线。

You can use Path.cubicTo() method. It draws a line using cubic spline algorithm which results in the smoothing effect you want.

签出答案的一个<一个href="http://stackoverflow.com/questions/8287949/android-how-to-draw-a-smooth-line-following-your-finger">similar这里的问题,其中一个人在谈论三次样条。有一个短暂的算法,展示了如何计算 Path.cubicTo()方法输入参数。您可以使用分频器值发挥,达到要求的光滑度。例如,在下面的图片我除以5而不是3。希望这会有所帮助。

Checkout the answer to a similar question here, where a guy is talking about cubic splines. There is a short algorithm showing how to calculate input parameters for Path.cubicTo() method. You can play with divider values to achieve required smoothness. For example, in the picture below I divided by 5 instead of 3. Hope this helps.

我已经花了一些时间,并实施了 SplineLineAndPointFormatter 类,这确实需要在androidplot库中的东西。它采用同样的工艺。下面是如何androidplot例如应用程序看起来像。你只需要使用 LineAndPointFormatter 它代替。

I have spent some time and implemented a SplineLineAndPointFormatter class, which does the stuff you need in androidplot library. It uses same technics. Here is how androidplot example applications looks like. You just need to use it instead of LineAndPointFormatter.

下面是code例子,我写的类。

Here is code example and the class I wrote.

f1 = new SplineLineAndPointFormatter(color.getColor(), null, 
      Color.argb(60, color.getRed(), color.getGreen(), color.getBlue()), null);
plot.addSeries(series1, f1);

下面是类做的魔力。它是基于 androidplot 的库0.6.1版本

Here is the class doing the magic. It is based on version 0.6.1 of androidplot library.

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 vertexColor, Integer fillColor, FillDirection fillDir) {
        super(lineColor, vertexColor, fillColor, null, 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, y, plotArea,
                    p.getCalculatedMinX(), p.getCalculatedMaxX(), p.getCalculatedMinY(), p.getCalculatedMaxY());

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

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

这篇关于如何使圆角(平滑)角落AndroidPlot线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆