2011-12-30 31 views
0

可能嗎?有沒有人曾經這樣做過?我不知道從哪裏開始。aChartengine圖表的菜單和上下文菜單

我大多需要菜單,而不是上下文菜單。

我 「BudgetPieChart」 類

public class ExpensesByCategoriesPieChart extends AbstractChart{ 

    private DataToArray dta; 

    @Override 
    public String getName() { 
     return MyApplication.getContext().getString(R.string.ExpensesByCategoriesPieChartName); 
    } 

    @Override 
    public String getDesc() { 
     return "The budget per project for this year (pie chart)";  
    } 

    @Override 
    public Intent execute(Context context) { 

     dta = new DataToArray(); 
     String[] categories = dta.expenseByCategoriesToArray(); 
     double[] values = dta.expensesValuesByCategoriesToArray();  
     int[] colors = dta.getColorsArray(categories.length); 

     DefaultRenderer renderer = buildCategoryRenderer(colors); 
     renderer.setZoomButtonsVisible(true); 
     renderer.setZoomEnabled(true); 
     renderer.setChartTitleTextSize(20); 
     return ChartFactory.getPieChartIntent(context, buildCategoryDataset("Wydatki kategoriami", categories, values), renderer, "Wydatki"); 
    } 

    public CustomGraphicalView createView(
      CustomGraphicalView customGraphicalView) { 
     // what do I do here? 
     return null; 
    } 
} 
+0

設置菜單是什麼意思? – androidu 2011-12-30 18:40:01

+0

只是想打開菜單與菜單按鈕,在圖表活動 – 2011-12-30 18:41:22

+0

聽起來我需要實現一個上下文菜單http://stackoverflow.com/questions/5351631/context-menu-in-android這是你需要嗎? – androidu 2011-12-30 18:43:58

回答

2

行,所以在這兒呢。在我的情況下CustomGraphicalView擴展org.achartengine.GraphicalView,但你可以擴展你需要的任何類。

private CustomGraphicalView mGraphicalView = new BudgetPieChart().createView(this); // you edit the createView() with your input data for the graph 
private RelativeLayout chart_layout = (RelativeLayout) findViewById(R.id.chart_layout); 
android.widget.RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(width, height); 
chart_layout.setGravity(Gravity.CENTER); 
chart_layout.addView(mGraphicalView, param); 

public CustomGraphicalView createView(Context context) { 
    double[] values = new double[] { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; //your desired values 
    int[] colors = new int[] { // Color.BLUE, Color.GREEN, Color.MAGENTA, Color.YELLOW, Color.CYAN (your desired colors) 
    Color.parseColor("#ff3399ff"), Color.parseColor("#ff0066cc"), Color.parseColor("#ff613592"), Color.parseColor("#ff7d3493"), Color.parseColor("#ffe81f53"), Color.parseColor("#ffeb5531"), Color.parseColor("#fff6bb2d"), Color.parseColor("#fff39f2f"), Color.parseColor("#ffe0d347"), Color.parseColor("#ff78c200") }; 
    // remember to have enough colors to match the number of elements from the data array for each pie slice 
    DefaultRenderer renderer = buildCategoryRenderer(colors); 
    renderer.setZoomButtonsVisible(false); 
    renderer.setZoomEnabled(false); 
    renderer.setChartTitleTextSize(20); 
    renderer.setAntialiasing(true); 
    renderer.setApplyBackgroundColor(false); 
    renderer.setBackgroundColor(Color.TRANSPARENT); 
    renderer.setPanEnabled(false); 
    renderer.setShowLabels(false); 
    renderer.setShowLegend(false); 

    return CustomChartFactory.getPieChartView(context, buildCategoryDataset("Project budget", values), renderer); 
} 

@Override 
public Intent execute(Context arg0) { 
    // NOT USED 
    return null; 
} 

public class CustomChartFactory { 
/** The key for the chart data. */ 
public static final String CHART = "chart"; 

/** The key for the chart graphical activity title. */ 
public static final String TITLE = "title"; 

private CustomChartFactory() { 
    // empty for now 
} 

/** 
* Creates a pie chart intent that can be used to start the graphical view activity. 
* 
* @param context 
*   the context 
* @param dataset 
*   the category series dataset (cannot be null) 
* @param renderer 
*   the series renderer (cannot be null) 
* @return a pie chart view 
* @throws IllegalArgumentException 
*    if dataset is null or renderer is null or if the dataset number of items is different than the number of series renderers 
*/ 
public static final CustomGraphicalView getPieChartView(Context context, CategorySeries dataset, DefaultRenderer renderer) { 
    checkParameters(dataset, renderer); 
    CustomPieChart chart = new CustomPieChart(dataset, renderer); 
    return new CustomGraphicalView(context, chart); 
} 

/** 
* Checks the validity of the dataset and renderer parameters. 
* 
* @param dataset 
*   the category series dataset (cannot be null) 
* @param renderer 
*   the series renderer (cannot be null) 
* @throws IllegalArgumentException 
*    if dataset is null or renderer is null or if the dataset number of items is different than the number of series renderers 
*/ 
private static void checkParameters(CategorySeries dataset, DefaultRenderer renderer) { 
    if (dataset == null || renderer == null || dataset.getItemCount() != renderer.getSeriesRendererCount()) { 
     throw new IllegalArgumentException("Dataset and renderer should be not null and the dataset number of items should be equal to the number of series renderers"); 
    } 
} 
} 

這應該讓你與你的項目的進一步打算:)祝你好運!


public class CustomGraphicalView extends org.achartengine.GraphicalView { 
/** The chart to be drawn. */ 
private final AbstractChart mChart; 

/** The chart renderer. */ 
private DefaultRenderer mRenderer; 

/** The view bounds. */ 
private final Rect mRect = new Rect(); 

/** The user interface thread handler. */ 
private final Handler mHandler; 

/** The zoom buttons rectangle. */ 
private final RectF mZoomR = new RectF(); 

/** The zoom in icon. */ 
private Bitmap zoomInImage; 

/** The zoom out icon. */ 
private Bitmap zoomOutImage; 

/** The fit zoom icon. */ 
private Bitmap fitZoomImage; 

/** The zoom area size. */ 
private final int zoomSize = 50; 

/** The zoom buttons background color. */ 
private static final int ZOOM_BUTTONS_COLOR = Color.argb(175, 150, 150, 150); 

/** The zoom in tool. */ 
private Zoom mZoomIn; 

/** The zoom out tool. */ 
private Zoom mZoomOut; 

/** The fit zoom tool. */ 
private FitZoom mFitZoom; 

/** The paint to be used when drawing the chart. */ 
private final Paint mPaint = new Paint(); 

/** The touch handler. */ 
private ITouchHandler mTouchHandler; 

/** The old x coordinate. */ 
private float oldX; 

/** The old y coordinate. */ 
private float oldY; 

public boolean isRotating; 

private float mX1, mY1, pY1, pX1, mX2, mY2, py, px, lastAngle, angle_rotation, rotation; 

/** 
* Creates a new graphical view. 
* 
* @param context 
*   the context 
* @param chart 
*   the chart to be drawn 
*/ 
public CustomGraphicalView(Context context, AbstractChart chart) { 
    super(context, chart); 
    setOnTouchListener(this); 
    mChart = chart; 
    mHandler = new Handler(); 
    if (mChart instanceof XYChart) { 
     mRenderer = ((XYChart) mChart).getRenderer(); 
    } else { 
     mRenderer = ((RoundChart) mChart).getRenderer(); 
    } 
    if (mRenderer.isZoomButtonsVisible()) { 
     zoomInImage = BitmapFactory.decodeStream(CustomGraphicalView.class.getResourceAsStream("image/zoom_in.png")); 
     zoomOutImage = BitmapFactory.decodeStream(CustomGraphicalView.class.getResourceAsStream("image/zoom_out.png")); 
     fitZoomImage = BitmapFactory.decodeStream(CustomGraphicalView.class.getResourceAsStream("image/zoom-1.png")); 
    } 

    if ((mRenderer instanceof XYMultipleSeriesRenderer) && (((XYMultipleSeriesRenderer) mRenderer).getMarginsColor() == XYMultipleSeriesRenderer.NO_COLOR)) { 
     ((XYMultipleSeriesRenderer) mRenderer).setMarginsColor(mPaint.getColor()); 
    } 
    if ((mRenderer.isZoomEnabled() && mRenderer.isZoomButtonsVisible()) || mRenderer.isExternalZoomEnabled()) { 
     mZoomIn = new Zoom(mChart, true, mRenderer.getZoomRate()); 
     mZoomOut = new Zoom(mChart, false, mRenderer.getZoomRate()); 
     mFitZoom = new FitZoom(mChart); 
    } 
    int version = 7; 
    try { 
     version = Integer.valueOf(Build.VERSION.SDK); 
    } catch (Exception e) { 
     // do nothing 
    } 
    if (version < 7) { 
     mTouchHandler = new TouchHandlerOld(this, mChart); 
    } else { 
     mTouchHandler = new TouchHandler(this, mChart); 
    } 
} 

/** 
* Returns the current series selection object. 
* 
* @return the series selection 
*/ 
@Override 
public SeriesSelection getCurrentSeriesAndPoint() { 
    return mChart.getSeriesAndPointForScreenCoordinate(new Point(oldX, oldY)); 
} 

/** 
* Transforms the currently selected screen point to a real point. 
* 
* @param scale 
*   the scale 
* @return the currently selected real point 
*/ 
@Override 
public double[] toRealPoint(int scale) { 
    if (mChart instanceof XYChart) { 
     XYChart chart = (XYChart) mChart; 
     return chart.toRealPoint(oldX, oldY, scale); 
    } 
    return null; 
} 

@Override 
protected void onDraw(Canvas canvas) { 
    // super.onDraw(canvas); 
    canvas.save(); 
    canvas.getClipBounds(mRect); 
    int top = mRect.top; 
    int left = mRect.left; 
    int width = mRect.width(); 
    int height = mRect.height(); 
    if (mRenderer.isInScroll()) { 
     top = 0; 
     left = 0; 
     width = getMeasuredWidth(); 
     height = getMeasuredHeight(); 
    } 
    mChart.draw(canvas, left, top, width, height, mPaint); 
    if ((mRenderer != null) && mRenderer.isZoomEnabled() && mRenderer.isZoomButtonsVisible()) { 
     mPaint.setColor(ZOOM_BUTTONS_COLOR); 
     // zoomSize = Math.max(zoomSize, Math.min(width, height)/7); 
     mZoomR.set((left + width) - (zoomSize * 3), (top + height) - (zoomSize * 0.775f), left + width, top + height); 
     canvas.drawRoundRect(mZoomR, zoomSize/3, zoomSize/3, mPaint); 
     float buttonY = (top + height) - (zoomSize * 0.625f); 
     canvas.drawBitmap(zoomInImage, (left + width) - (zoomSize * 2.75f), buttonY, null); 
     canvas.drawBitmap(zoomOutImage, (left + width) - (zoomSize * 1.75f), buttonY, null); 
     canvas.drawBitmap(fitZoomImage, (left + width) - (zoomSize * 0.75f), buttonY, null); 
    } 
    canvas.restore(); 
} 

/** 
* Sets the zoom rate. 
* 
* @param rate 
*   the zoom rate 
*/ 
@Override 
public void setZoomRate(float rate) { 
    if ((mZoomIn != null) && (mZoomOut != null)) { 
     mZoomIn.setZoomRate(rate); 
     mZoomOut.setZoomRate(rate); 
    } 
} 

/** 
* Do a chart zoom in. 
*/ 
@Override 
public void zoomIn() { 
    if (mZoomIn != null) { 
     mZoomIn.apply(); 
     repaint(); 
    } 
} 

/** 
* Do a chart zoom out. 
*/ 
@Override 
public void zoomOut() { 
    if (mZoomOut != null) { 
     mZoomOut.apply(); 
     repaint(); 
    } 
} 

/** 
* Do a chart zoom reset/fit zoom. 
*/ 
@Override 
public void zoomReset() { 
    if (mFitZoom != null) { 
     mFitZoom.apply(); 
     mZoomIn.notifyZoomResetListeners(); 
     repaint(); 
    } 
} 

/** 
* Adds a new zoom listener. 
* 
* @param listener 
*   zoom listener 
*/ 
@Override 
public void addZoomListener(ZoomListener listener, boolean onButtons, boolean onPinch) { 
    if (onButtons) { 
     if (mZoomIn != null) { 
      mZoomIn.addZoomListener(listener); 
      mZoomOut.addZoomListener(listener); 
     } 
     if (onPinch) { 
      mTouchHandler.addZoomListener(listener); 
     } 
    } 
} 

/** 
* Removes a zoom listener. 
* 
* @param listener 
*   zoom listener 
*/ 
@Override 
public synchronized void removeZoomListener(ZoomListener listener) { 
    if (mZoomIn != null) { 
     mZoomIn.removeZoomListener(listener); 
     mZoomOut.removeZoomListener(listener); 
    } 
    mTouchHandler.removeZoomListener(listener); 
} 

/** 
* Adds a new pan listener. 
* 
* @param listener 
*   pan listener 
*/ 
@Override 
public void addPanListener(PanListener listener) { 
    mTouchHandler.addPanListener(listener); 
} 

/** 
* Removes a pan listener. 
* 
* @param listener 
*   pan listener 
*/ 
@Override 
public void removePanListener(PanListener listener) { 
    mTouchHandler.removePanListener(listener); 
} 

@Override 
protected RectF getZoomRectangle() { 
    return mZoomR; 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if (event.getAction() == MotionEvent.ACTION_DOWN) { 
     // save the x and y so they can be used in the click and long press 
     // listeners 
     oldX = event.getX(); 
     oldY = event.getY(); 
    } 
    if ((mRenderer != null) && (mRenderer.isPanEnabled() || mRenderer.isZoomEnabled())) { 
     if (mTouchHandler.handleTouch(event)) { 
      return true; 
     } 
    } 
    return super.onTouchEvent(event); 
} 

/** 
* Schedule a view content repaint. 
*/ 
@Override 
public void repaint() { 
    mHandler.post(new Runnable() { 
     @Override 
     public void run() { 
      invalidate(); 
     } 
    }); 
} 

/** 
* Schedule a view content repaint, in the specified rectangle area. 
* 
* @param left 
*   the left position of the area to be repainted 
* @param top 
*   the top position of the area to be repainted 
* @param right 
*   the right position of the area to be repainted 
* @param bottom 
*   the bottom position of the area to be repainted 
*/ 
@Override 
public void repaint(final int left, final int top, final int right, final int bottom) { 
    mHandler.post(new Runnable() { 
     @Override 
     public void run() { 
      invalidate(left, top, right, bottom); 
     } 
    }); 
} 

/** 
* Saves the content of the graphical view to a bitmap. 
* 
* @return the bitmap 
*/ 
@Override 
public Bitmap toBitmap() { 
    setDrawingCacheEnabled(false); 
    if (!isDrawingCacheEnabled()) { 
     setDrawingCacheEnabled(true); 
    } 
    if (mRenderer.isApplyBackgroundColor()) { 
     setDrawingCacheBackgroundColor(mRenderer.getBackgroundColor()); 
    } 
    setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH); 
    return getDrawingCache(true); 
} 

} 

public class CustomPieChart extends RoundChart { 
public static int radius = 115; 

float currentAngle; 

/** Handles returning values when tapping on PieChart. */ 
private final PieMapper mPieMapper; 

/** 
* Builds a new pie chart instance. 
* 
* @param dataset 
*   the series dataset 
* @param renderer 
*   the series renderer 
*/ 
public CustomPieChart(CategorySeries dataset, DefaultRenderer renderer) { 
    super(dataset, renderer); 
    mPieMapper = new PieMapper(); 
} 

/** 
* The graphical representation of the pie chart. 
* 
* @param canvas 
*   the canvas to paint to 
* @param x 
*   the top left x value of the view to draw to 
* @param y 
*   the top left y value of the view to draw to 
* @param width 
*   the width of the view to draw to 
* @param height 
*   the height of the view to draw to 
* @param paint 
*   the paint 
*/ 
@Override 
public void draw(Canvas canvas, int x, int y, int width, int height, Paint paint) { 
    // paint.setAntiAlias(mRenderer.isAntialiasing()); 
    paint.setAntiAlias(true); 
    paint.setStyle(Style.FILL); 
    paint.setTextSize(mRenderer.getLabelsTextSize()); 
    int legendSize = getLegendSize(mRenderer, height/5, 0); 
    int left = x; 
    int top = y; 
    int right = x + width; 
    int sLength = mDataset.getItemCount(); 
    double total = 0; 
    String[] titles = new String[sLength]; 
    for (int i = 0; i < sLength; i++) { 
     total += mDataset.getValue(i); 
     titles[i] = mDataset.getCategory(i); 
    } 
    if (mRenderer.isFitLegend()) { 
     legendSize = drawLegend(canvas, mRenderer, titles, left, right, y, width, height, legendSize, paint, true); 
    } 
    int bottom = y + height - legendSize; 
    drawBackground(mRenderer, canvas, x, y, width, height, paint, false, DefaultRenderer.NO_COLOR); 

    currentAngle = 0; 
    int mRadius = Math.min(Math.abs(right - left), Math.abs(bottom - top)); 

    // radius = (int) (mRadius * 0.35 * mRenderer.getScale()); 
    if (mCenterX == NO_VALUE) { 
     mCenterX = (left + right)/2; 
    } 
    if (mCenterY == NO_VALUE) { 
     mCenterY = (bottom + top)/2; 
    } 

    // Hook in clip detection after center has been calculated 
    mPieMapper.setDimensions(mRadius, mCenterX, mCenterY); 
    boolean loadPieCfg = !mPieMapper.areAllSegmentPresent(sLength); 
    if (loadPieCfg) { 
     mPieMapper.clearPieSegments(); 
    } 

    // float shortRadius = radius * 0.9f; 
    // float longRadius = radius * 1.1f; 

    RectF oval = new RectF(mCenterX - radius, mCenterY - radius, mCenterX + radius, mCenterY + radius); 
    // List<RectF> prevLabelsBounds = new ArrayList<RectF>(); 

    for (int i = 0; i < sLength; i++) { 
     paint.setColor(mRenderer.getSeriesRendererAt(i).getColor()); 
     float value = (float) mDataset.getValue(i); 
     float angle = (float) (value/total * 360); 
     canvas.drawArc(oval, currentAngle, angle, true, paint); 
     // drawLabel(canvas, mDataset.getCategory(i), mRenderer, prevLabelsBounds, mCenterX, mCenterY, 
     // shortRadius, longRadius, currentAngle, angle, left, right, paint); 

     // Save details for getSeries functionality 
     if (loadPieCfg) { 
      mPieMapper.addPieSegment(i, value, currentAngle, angle); 
     } 
     currentAngle += angle; 
    } 
    // prevLabelsBounds.clear(); 
    // drawLegend(canvas, mRenderer, titles, left, right, y, width, height, legendSize, paint, false); 
    // drawTitle(canvas, x, y, width, paint); 

} 

public static int getRadius() { 
    return radius; 
} 

@Override 
public SeriesSelection getSeriesAndPointForScreenCoordinate(Point screenPoint) { 
    return mPieMapper.getSeriesAndPointForScreenCoordinate(screenPoint); 
} 

} 
+1

我會再次這樣做,你應得的品脫:)我發誓我會給你信用,當我完成我的應用程序只是讓我有一個煙,完成我的啤酒:P – 2012-01-03 18:33:27

+0

:))歡呼的朋友 – androidu 2012-01-03 18:41:20

+0

血腥編輯再次消失。發佈它作爲答案。無論如何我都會接受你的回答。再次感謝:) – 2012-01-03 20:47:28

1

爲了讓你只需要一樣東西的菜單。你必須在你自己的活動中使用GraphicalView。爲了做到這一點,你需要:

前BudgetPieChart類

public class ExpByCatPieChartHelper extends AbstractChart{ 

    private DataToArray dta; 

    @Override 
    public String getName() { 
     return MyApplication.getContext().getString(R.string.ExpensesByCategoriesPieChartName); 
    } 

    @Override 
    public String getDesc() { 
     return "The budget per project for this year (pie chart)";  
    } 


    public GraphicalView createView(Context context) { 

      dta = new DataToArray(); 
      String[] categories = dta.expenseByCategoriesToArray(); 
      double[] values = dta.expensesValuesByCategoriesToArray();  
      int[] colors = dta.getColorsArray(categories.length);   

      DefaultRenderer renderer = buildCategoryRenderer(colors);   
      renderer.setZoomButtonsVisible(true); 
      renderer.setZoomEnabled(true); 
      renderer.setChartTitleTextSize(20); 

      return ChartFactory.getPieChartView(context, buildCategoryDataset("Wydatki kategoriami", categories, values), renderer); 
     } 

    @Override 
    public Intent execute(Context context) { 
     return null; 
    } 


} 

用自己的活動的附加類:

public class ExpByCatPieChart extends Activity{ 

    private IACharts pieChart = new ExpByCatPieChartHelper(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     GraphicalView mGraphicalView = new ExpByCatPieChartHelper().createView(this); 
     setContentView(mGraphicalView); 
     super.onCreate(savedInstanceState); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     MenuInflater inflater = getMenuInflater(); 
     inflater.inflate(R.menu.chart_settings_menu, menu); 
     return true; 
    } 

    @Override 
    public boolean onMenuItemSelected(int featureId, MenuItem item) { 
     switch(item.getItemId()) { 
     case R.id.chart_settings: 
      Intent i = new Intent(this, PieChartSettings.class); 
      startActivityForResult(i, 0); 
      return true; 
     case R.id.home: 
      finish(); 
      return true; 
     } 
     return super.onMenuItemSelected(featureId, item); 
    } 



} 

而這幾乎是一切。你會得到一個默認的achart視圖並將其作爲新活動的內容進行分類。 Viola :)

+0

Achartengine是一個非常有用的圖書館。我確信將來會更多地使用它:) – androidu 2012-01-03 20:52:41

0

我找到了創建上下文菜單here的解決方案。一旦渲染器(XYMultipleSeriesRenderer)爲setClickEnabled(true);,您可以按慣例使用onCreateContextMenuListener