Android Polar Graphing

时间:2014-03-06 21:06:30

标签: android graph achartengine

我正在尝试做this这样的事情,但我对它的外观有一点灵活性。基本上是饼图只填充部分饼图(其余部分留空)或某种表盘图表。

使用极坐标图绘制两个箭头也是相对容易的,一个在0度,一个在-92度,但我找不到任何可以让你为Android做这个的库。我确实需要它使0度看起来像0极度。

我使用了AChartEngine DialChart并设法让一些东西接近,但我无法弄清楚如何让标签显示每个箭头。我试过了renderer.setDisplayValues(true);series.setDisplayChartValues(true); 但它不会显示我的两个箭头的值,所以我不确定它是否可以使用DialChart。我意识到,如果我在后台显示表盘的标签,我的用户就不需要在箭头上有标签了,但我正在旋转添加DialChart的LinearLayout,以使0看起来像0度在极坐标图中。尽管使用了renderer.setShowLabels(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);

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

1 个答案:

答案 0 :(得分:0)

我已经回答了我自己的问题,希望以后再做这样的事情。

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

这是相关的代码段。它并不完美,但它确实起到了作用。

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