2014-03-06 117 views
1

我正在尝试做类似this的操作,但我对它的外观有一点灵活性。基本上是一个只填充部分饼图的饼图(其余部分留空)或某种拨号图。Android极坐标图形

使用极坐标图绘制两个箭头也是相对容易的,一个是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); 

我接受任何修改这个代码,以获得一些作品,或其他库,将帮助我完成我要做的。谢谢!

+0

看起来你似乎找到了解决办法:你问题中的最后一段。 –

+0

我不知道其他人是否做了类似的事情(并且在搜索几个小时后找不到任何东西),所以最后一段是询问是否有人知道哪个库更好用,因为我无法获得AChartEngine做我想做的事。我最终创建了一个自定义视图(我不知道你现在可以在Android中完成)。 – laberle

回答

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