class FastLineAndPointRenderer extends XYSeriesRenderer<XYSeries, FastLineAndPointRenderer.Formatter> {

    @Override
    protected void onRender(Canvas canvas, RectF plotArea, XYSeries series, Formatter formatter, RenderStack stack) {

        segmentOffsets.clear();
        segmentLengths.clear();

        final int numPoints = series.size() * 2;
        if(points == null || points.length != numPoints) {
            // only allocate when necessary:
            points = new  float[series.size()*2];
        }

        int segmentLen = 0;
        boolean isLastPointNull = true;
        PointF resultPoint = new PointF();
        for (int i = 0, j = 0;  i < series.size(); i++, j+=2) {
            Number y = series.getY(i);
            Number x = series.getX(i);

            if (y != null && x != null) {
                if(isLastPointNull) {
                    segmentOffsets.add(j);
                    segmentLen = 0;
                    isLastPointNull = false;
                }

                getPlot().getBounds().transformScreen(resultPoint, x, y, plotArea);
                points[j] = resultPoint.x;
                points[j + 1] = resultPoint.y;
                segmentLen+=2;

                // if this is the last point, account for it in segment lengths:
                if(i == series.size()-1) {
                    segmentLengths.add(segmentLen);
                }
            } else if(!isLastPointNull) {
                segmentLengths.add(segmentLen);
                isLastPointNull = true;
            }
        }

        // draw segments
        if(formatter.linePaint != null || formatter.vertexPaint != null) {
            for (int i = 0; i < segmentOffsets.size(); i++) {
                final int len = segmentLengths.get(i);
                final int offset = segmentOffsets.get(i);
                drawSegment(canvas, points, offset, len, formatter);
            }
        }
    }

    public  FastLineAndPointRenderer(XYPlot plot);

}