How do MPAndroidChart renderings work and how can I write my own render?

I use the MPAndroidChart library, but it does not have all the functions that I want out of the box.

I heard that you can implement the functionality that I want by writing my own renderer.

I looked at the source code for rendering in the MPAndroidChart GitHub repo, but I don't understand the concepts.

How do MPAndroidChart renderings work?

What is the high level procedure for writing a custom renderer?

Note: for many questions posted on SO for solution is to implement some kind of custom renderer. The comment on such issues “you can solve this problem by writing a custom renderer” is unsatisfactory if there is no manual. Writing an answer that includes a complete solution for an unusual and unusual requirement can take a long time. There is no existing guide for writing a custom visualization tool, and there is hope that this issue may be useful to users who can help themselves if they don’t duplicate the goal. Although I tried to answer this question, other answers, corrections and comments are welcome.

+4
source share
1 answer

General information about representations and canvas

First, you should study the Canvas and Drawables Guide from the official Android documentation. In particular, it is important to note that LineChart, BarChartetc. Are subclasses Viewthat display themselves by overriding the callback of the onDraw(Canvas c)View superclass. Note also the definition of "canvas":

The canvas works for you as a pretense or an interface on the actual surface on which your graphics will be drawn - it contains all your calls to "draw".

When you work with renderers, you will deal with the functionality of drawing lines, bars, etc. on canvas.

Translation between values ​​on a chart and pixels on a canvas

x y . , x = 0. y- 52.28.

barchart MPAndroidChart

. x = 0 , . , y = 0, 52.28 ( y ). / , , x = 165 y = 1150.

A Transformer ( ) . ( ), .

, . , , . ViewPortHandler, , . ViewPortHandler#isInBoundsLeft(float x) isInBoundsRight(float x) , .

BarChart " " BarEntry 6 , , , 6 . , x- 0 5 .

ChartAnimator

ChartAnimator , . . , , , y 1 . phaseY, , 0.000 0ms 1.000 1000ms.

, , LineChartRenderer:

protected void drawHorizontalBezier(ILineDataSet dataSet) {

    float phaseY = mAnimator.getPhaseY(); 

    Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());

    mXBounds.set(mChart, dataSet);

    cubicPath.reset();

    if (mXBounds.range >= 1) {

        Entry prev = dataSet.getEntryForIndex(mXBounds.min);
        Entry cur = prev;

        // let the spline start
        cubicPath.moveTo(cur.getX(), cur.getY() * phaseY);

        for (int j = mXBounds.min + 1; j <= mXBounds.range + mXBounds.min; j++) {

            prev = cur;
            cur = dataSet.getEntryForIndex(j);

            final float cpx = (prev.getX())
                    + (cur.getX() - prev.getX()) / 2.0f;

            cubicPath.cubicTo(
                    cpx, prev.getY() * phaseY,
                    cpx, cur.getY() * phaseY,
                    cur.getX(), cur.getY() * phaseY);
        }
    }

    // if filled is enabled, close the path
    if (dataSet.isDrawFilledEnabled()) {

        cubicFillPath.reset();
        cubicFillPath.addPath(cubicPath);
        // create a new path, this is bad for performance
        drawCubicFill(mBitmapCanvas, dataSet, cubicFillPath, trans, mXBounds);
    }

    mRenderPaint.setColor(dataSet.getColor());

    mRenderPaint.setStyle(Paint.Style.STROKE);

    trans.pathValueToPixel(cubicPath);

    mBitmapCanvas.drawPath(cubicPath, mRenderPaint);

    mRenderPaint.setPathEffect(null);
}

for - . , phaseY ChartAnimator, Transformer .

for " , ". x-, .

x y- dataSet.getEntryForIndex(j) . , phaseY .

, , , trans.pathValueToPixel(cubicPath);, mBitmapCanvas.drawPath(cubicPath, mRenderPaint);

- . com.github.mikephil.charting.renderer XAxisRenderer LineChartRenderer .. . void drawHorizontalBezier(ILineDataSet dataSet) super ( ) . , , :

  • ,
  • x ( x, )
  • Canvas

Canvas class (drawBitmap ..), , .

, , , , LineRadarRenderer, .

, , Chart#setRenderer(DataRenderer renderer) BarLineChartBase#setXAxisRenderer(XAxisRenderer renderer) .

+6

Source: https://habr.com/ru/post/1674936/


All Articles