2014-03-06 116 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; 
} 
}