Android 极坐标绘图

标签 android graph achartengine

我正在尝试做类似 this 的事情, 但我对它的外观有一点灵 active 。本质上,要么是只填充了部分饼图(其余部分留空)的饼图,要么是某种刻度盘图。

使用极坐标图绘制两个箭头也相对容易,一个在 0 度,一个在 -92 度,但我找不到任何库可以让您为 Android 执行此操作。我确实需要它来使 0 度实际上看起来像 0 极度。

我使用了 AChartEngine DialChart 并设法接近了一些东西,但我不知道如何让标签显示每个箭头。我试过 renderer.setDisplayValues(true);series.setDisplayChartValues(true); 但它不会显示我的两个箭头的值,所以我不确定是否可以使用 DialChart。我意识到,如果我在后台显示表盘的标签,我的用户就不需要在箭头上贴标签,但我正在旋转添加了 DialChart 的 LinearLayout,以使 0 看起来像 0 度在极坐标图中。尽管使用了 renderer.setShowLabels(false); 并将几乎所有其他你可以显示的东西都设置为 false,但我也很难在后台隐藏表盘的标签。我的技巧是将标签颜色设置为背景颜色,但如果有更好的方法,请告诉我。

这是我的 DialChart 代码。

CategorySeries category = new CategorySeries("Angle");
category.add("Extension", 0);
category.add("Flexion", 90);

renderer = new DialRenderer();
renderer.setLabelsColor(getActivity().getResources().getColor(R.color.background));

renderer.setInScroll(true);
renderer.setDisplayValues(true);

renderer.setShowLegend(false);
renderer.setShowAxes(false);
renderer.setShowLabels(false);
renderer.setShowGrid(false);
renderer.setMargins(new int[] {20, 30, 15, 0});
renderer.setVisualTypes(new DialRenderer.Type[] {Type.ARROW, Type.ARROW});
renderer.setMinValue(-20);
renderer.setMaxValue(280);
renderer.setPanEnabled(false);
renderer.setZoomEnabled(false);

SimpleSeriesRenderer r = new SimpleSeriesRenderer();
series.setColor(getActivity().getResources().getColor(R.color.green));
series.setDisplayChartValues(true);
series.setChartValuesTextSize(30);
visualizationRenderer.addSeriesRenderer(r);

r = new SimpleSeriesRenderer();
series.setColor(getActivity().getResources().getColor(R.color.green));
series.setDisplayChartValues(true);
series.setChartValuesTextSize(30);
renderer.addSeriesRenderer(r);

visualization = ChartFactory.getDialChartView(getActivity(), category, renderer);

LinearLayout layout = (LinearLayout) this.getView().findViewById(R.id.sessions_visualization);
layout.addView(visualization);

layout.setRotation(220.0f);

我愿意修改此代码以获得有用的东西,或者其他库可以帮助我完成我想做的事情。谢谢!

最佳答案

我正在为以后想做类似事情的任何人回答我自己的问题。

您可以在 Android 中创建自定义 View 并绘制您想要显示的任何内容。有很好的文档here .

这是一个相关的代码 fragment 。它并不完美,但可以胜任。

public class AngleVisualization extends View {
    private Paint textPaint;
    private Paint arcPaint;
    private Paint linePaint;
    RectF oval;
    private float extension;
    private float flexion;
    private int textColor;
    private int arcColor;
    private float extensionLabelX;
    private float extensionLabelY;
    private float flexionLabelX;
    private float flexionLabelY;

    private Rect extensionBounds = new Rect();


    public AngleVisualization(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.getTheme().obtainStyledAttributes(
            attrs,
            R.styleable.AngleVisualization,
            0, 0);

    try {
        extension = a.getFloat(R.styleable.AngleVisualization_extensionValue, 0);
        flexion = a.getFloat(R.styleable.AngleVisualization_flexionValue, 0);
        textColor = a.getColor(R.styleable.AngleVisualization_textColor, Color.BLACK);
        arcColor = a.getColor(R.styleable.AngleVisualization_arcColor, context.getResources().getColor(R.color.green));
        extensionLabelX = a.getDimension(R.styleable.AngleVisualization_extensionLabelX, 190);
        extensionLabelY = a.getDimension(R.styleable.AngleVisualization_extensionLabelY, 150);
        flexionLabelX = a.getDimension(R.styleable.AngleVisualization_flexionLabelX, 50);
        extensionLabelY = a.getDimension(R.styleable.AngleVisualization_flexionLabelY, 190);

    } finally {
        a.recycle();
    }

    oval = new RectF();

    init();
}

private void init() {
    textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    textPaint.setColor(textColor);
    textPaint.setTextSize(30);

    arcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    arcPaint.setColor(arcColor);

    linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    linePaint.setColor(arcColor);
    linePaint.setStrokeWidth(3);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    String extensionString = decimalFormat.format(extension) + "˚";
    textPaint.getTextBounds(extensionString, 0, extensionString.length(), extensionBounds);

    canvas.drawArc(oval, extension, flexion - extension, true, arcPaint);
    canvas.drawLine(0.0f, extensionBounds.height(), oval.right / 2, extensionBounds.height(), linePaint);
    canvas.drawText(extensionString, extensionLabelX, extensionLabelY, textPaint);
    canvas.drawText(decimalFormat.format(flexion) + "˚", flexionLabelX, flexionLabelY, textPaint);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    // Account for padding
    float xpad = (float)(getPaddingLeft() + getPaddingRight());
    float ypad = (float)(getPaddingTop() + getPaddingBottom());

    float ww = (float)w - xpad;
    float hh = (float)h - ypad;

    String extensionString = decimalFormat.format(extension) + "˚";
    textPaint.getTextBounds(extensionString, 0, extensionString.length(), extensionBounds);
    float diameter = Math.min(ww, (hh - extensionBounds.height()) * 2.0f) - extensionBounds.height();

    oval = new RectF(
            0,
            diameter / -2.0f,
            diameter,
            diameter / 2.0f);
    oval.offsetTo(getPaddingLeft(), getPaddingTop() - diameter / 2.0f + extensionBounds.height());
    flexionLabelY = diameter / 2.0f + extensionBounds.height();
    flexionLabelX = 0;
    extensionLabelY = extensionBounds.height();
    extensionLabelX = ww / 2;
}
}

关于Android 极坐标绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22235964/

相关文章:

android - 如何从 ListView 项更新 SQLite 行?

android - AChartEngine 最大 x 标签可见

android - 如何从Android中的aChartEngine制作自定义圆环图?

android - 在 AchartEngine 中禁用平移后的性能问题

android - 如何使edittext看起来像android中的页面

未找到同步样式属性时出现 Android gradle 错误

java - 将自定义标记添加到 Android 中的 Google map

vba - 从图表中删除空系列(使用 VBA)

java - 交互式图表和显示选项

c++ - 在图的隐式表示中查找连通分量