Search code examples
androidandroidplot

Customizing Label and points in android plot


I am developing app using android plot , I am trying to beautify it I want it like in the image

one

But I am getting like below

two


Solution

  • (This answer addresses drawing the inner circles for the individual points as in your example image above)

    Normally this would be a 2 or 3 line job where simply re-adding the series with a properly configured instance of LineAndPointFormatter would do the trick but there's a bug in recent releases that prevents the same series from being added more than once using the same Renderer, regardless of whether or not a different Formatter is supplied. (Will be fixed in the 1.2.3 release)

    If you dont mind having a complete duplicate of your series data you can still do this fairly easily:

            XYSeries series2b = new SimpleXYSeries(
                    Arrays.asList(series2Numbers), SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "Series2");
    
            LineAndPointFormatter series2bFormat = new LineAndPointFormatter(null, Color.WHITE, null, null);
    
            // this adjusts the size of the inner circle:
            series2bFormat.getVertexPaint().setStrokeWidth(PixelUtils.dpToPix(7));
    
            ...
    
            // make sure this line comes AFTER the addSeries call for the copied series:
            plot.addSeries(series2b, series2bFormat);
    

    A limitation of the above implementation is that it will draw a duplicate legend icon (also addressed in the upcoming 1.2.3 release). An alternative approach that avoids the duplicate icon is to make a custom extends of LineAndPointRenderer along with a custom LineAndPointFormatter:

        // a custom renderer to draw an second smaller circle for each rendered vertex
        static class MyLineAndPointRenderer extends LineAndPointRenderer<MyLineAndPointFormatter> {
    
    
            public MyLineAndPointRenderer(XYPlot plot) {
                super(plot);
            }
    
            @Override
            protected void renderPoints(Canvas canvas, RectF plotArea, XYSeries series, List<PointF> points,
                    LineAndPointFormatter formatter) {
                // draw points as normal:
                super.renderPoints(canvas, plotArea, series, points, formatter);
    
                // now draw our inner vertices on top of the previously drawn vertices:
                for (PointF p : points) {
                    Paint paint = ((MyLineAndPointFormatter) formatter).getInnerPointPaint();
                    canvas.drawPoint(p.x, p.y, paint);
                }
            }
        }
    
        // defines the format for our custom renderer:
        static class MyLineAndPointFormatter extends LineAndPointFormatter {
    
            Paint innerPointPaint = new Paint();
    
            {
                // setup innPointPaint to draw a white circle a little smaller than the 
                // typical circle drawn for each vertex:
                innerPointPaint.setAntiAlias(true);
                innerPointPaint.setStrokeCap(Paint.Cap.ROUND);
                innerPointPaint.setColor(Color.WHITE);
                innerPointPaint.setStrokeWidth(PixelUtils.dpToPix(7));
            }
    
            public MyLineAndPointFormatter(Context context, int xmlCfgId) {
                super(context, xmlCfgId);
            }
    
            @Override
            public Class<? extends SeriesRenderer> getRendererClass() {
                return MyLineAndPointRenderer.class;
            }
    
            @Override
            public SeriesRenderer getRendererInstance(XYPlot plot) {
                return new MyLineAndPointRenderer(plot);
            }
    
            public Paint getInnerPointPaint() {
                return innerPointPaint;
            }
        }
    

    Then, use the above instead of LineAndPointFormatter when adding your series to the plot:

    MyLineAndPointFormatter series1Format =
                    new MyLineAndPointFormatter(this, R.xml.my_format);
    

    While this last approach is more code, its also the most efficient and extensible.