protected void drawChart(CanvasDrawingSession canvas)
        {
            if (chartData == null)
            {
                return;
            }

            float fullWidth = chartWidth / (pickerDelegate.pickerEnd - pickerDelegate.pickerStart);
            float offset    = fullWidth * pickerDelegate.pickerStart - HORIZONTAL_PADDING;

            float p;
            float lineWidth;

            if (chartData.xPercentage.Length < 2)
            {
                p         = 1f;
                lineWidth = 1f;
            }
            else
            {
                p         = chartData.xPercentage[1] * fullWidth;
                lineWidth = chartData.xPercentage[1] * (fullWidth - p);
            }
            int additionalPoints = (int)(HORIZONTAL_PADDING / p) + 1;
            int localStart       = Math.Max(0, startXIndex - additionalPoints - 2);
            int localEnd         = Math.Min(chartData.xPercentage.Length - 1, endXIndex + additionalPoints + 2);

            for (int k = 0; k < lines.Count; k++)
            {
                LineViewData line = lines[k];
                line.linesPathBottomSize = 0;
            }

            float transitionAlpha = 1f;

            //canvas.save();
            if (transitionMode == TRANSITION_MODE_PARENT)
            {
                postTransition  = true;
                selectionA      = 0f;
                transitionAlpha = 1f - transitionParams.progress;

                canvas.Transform = Matrix3x2.CreateScale(
                    new Vector2(1 + 2 * transitionParams.progress, 1f),
                    new Vector2(transitionParams.pX, transitionParams.pY)
                    );
            }
            else if (transitionMode == TRANSITION_MODE_CHILD)
            {
                transitionAlpha = transitionParams.progress;

                canvas.Transform = Matrix3x2.CreateScale(
                    new Vector2(transitionParams.progress, 1f),
                    new Vector2(transitionParams.pX, transitionParams.pY)
                    );
            }
            else if (transitionMode == TRANSITION_MODE_ALPHA_ENTER)
            {
                transitionAlpha = transitionParams.progress;
            }

            bool selected = selectedIndex >= 0 && legendShowing;

            for (int i = localStart; i <= localEnd; i++)
            {
                float stackOffset = 0;
                if (selectedIndex == i && selected)
                {
                    continue;
                }

                for (int k = 0; k < lines.Count; k++)
                {
                    LineViewData line = lines[k];
                    if (!line.enabled && line.alpha == 0)
                    {
                        continue;
                    }

                    int[] y = line.line.y;


                    float xPoint      = p / 2 + chartData.xPercentage[i] * (fullWidth - p) - offset;
                    float yPercentage = y[i] / currentMaxHeight;

                    float height = yPercentage * (MeasuredHeight - chartBottom - SIGNATURE_TEXT_HEIGHT) * line.alpha;
                    float yPoint = MeasuredHeight - chartBottom - height;

                    line.linesPath[line.linesPathBottomSize++] = xPoint;
                    line.linesPath[line.linesPathBottomSize++] = yPoint - stackOffset;

                    line.linesPath[line.linesPathBottomSize++] = xPoint;
                    line.linesPath[line.linesPathBottomSize++] = MeasuredHeight - chartBottom - stackOffset;

                    stackOffset += height;
                }
            }

            for (int k = 0; k < lines.Count; k++)
            {
                StackBarViewData line = lines[k];

                Paint paint = selected || postTransition ? line.unselectedPaint : line.paint;
                if (selected)
                {
                    line.unselectedPaint.Color = Extensions.blendARGB(line.lineColor, line.blendColor, selectionA);
                }

                if (postTransition)
                {
                    line.unselectedPaint.Color = Extensions.blendARGB(line.lineColor, line.blendColor, 1f);
                }

                paint.A           = (byte)(255 * transitionAlpha);
                paint.StrokeWidth = lineWidth;
                paint.StrokeCap   = Microsoft.Graphics.Canvas.Geometry.CanvasCapStyle.Flat;
                canvas.DrawLines(line.linesPath, 0, line.linesPathBottomSize, paint);
            }

            if (selected)
            {
                float stackOffset = 0;
                for (int k = 0; k < lines.Count; k++)
                {
                    LineViewData line = lines[k];
                    if (!line.enabled && line.alpha == 0)
                    {
                        continue;
                    }

                    int[] y = line.line.y;


                    float xPoint      = p / 2 + chartData.xPercentage[selectedIndex] * (fullWidth - p) - offset;
                    float yPercentage = y[selectedIndex] / currentMaxHeight;

                    float height = yPercentage * (MeasuredHeight - chartBottom - SIGNATURE_TEXT_HEIGHT) * line.alpha;
                    float yPoint = MeasuredHeight - chartBottom - height;

                    line.paint.StrokeWidth = lineWidth;
                    line.paint.A           = (byte)(255 * transitionAlpha);
                    canvas.DrawLine(xPoint, yPoint - stackOffset,
                                    xPoint, MeasuredHeight - chartBottom - stackOffset, line.paint);

                    stackOffset += height;
                }
            }
            //canvas.restore();
        }
        protected override void drawChart(CanvasDrawingSession canvas)
        {
            if (chartData != null)
            {
                float fullWidth = (chartWidth / (pickerDelegate.pickerEnd - pickerDelegate.pickerStart));
                float offset    = fullWidth * (pickerDelegate.pickerStart) - HORIZONTAL_PADDING;

                int start = startXIndex - 1;
                if (start < 0)
                {
                    start = 0;
                }
                int end = endXIndex + 1;
                if (end > chartData.lines[0].y.Length - 1)
                {
                    end = chartData.lines[0].y.Length - 1;
                }

                //canvas.save();
                //canvas.clipRect(chartStart, 0, chartEnd, getMeasuredHeight() - chartBottom);
                var transform = canvas.Transform;
                var clip      = canvas.CreateLayer(1, createRect(chartStart, 0, chartEnd, getMeasuredHeight() - chartBottom));

                float transitionAlpha = 1f;
                //canvas.save();
                if (transitionMode == TRANSITION_MODE_PARENT)
                {
                    postTransition  = true;
                    selectionA      = 0f;
                    transitionAlpha = 1f - transitionParams.progress;

                    canvas.Transform = Matrix3x2.CreateScale(
                        new Vector2(1 + 2 * transitionParams.progress, 1f),
                        new Vector2(transitionParams.pX, transitionParams.pY)
                        );
                }
                else if (transitionMode == TRANSITION_MODE_CHILD)
                {
                    transitionAlpha = transitionParams.progress;

                    canvas.Transform = Matrix3x2.CreateScale(
                        new Vector2(transitionParams.progress, 1f),
                        new Vector2(transitionParams.pX, transitionParams.pY)
                        );
                }


                for (int k = 0; k < lines.Count; k++)
                {
                    BarViewData line = lines[k];
                    if (!line.enabled && line.alpha == 0)
                    {
                        continue;
                    }

                    float p;
                    if (chartData.xPercentage.Length < 2)
                    {
                        p = 1f;
                    }
                    else
                    {
                        p = chartData.xPercentage[1] * fullWidth;
                    }
                    int[] y = line.line.y;
                    int   j = 0;

                    float selectedX = 0f;
                    float selectedY = 0f;
                    bool  selected  = false;
                    float a         = line.alpha;
                    for (int i = start; i <= end; i++)
                    {
                        float xPoint      = p / 2 + chartData.xPercentage[i] * fullWidth - offset;
                        float yPercentage = y[i] / currentMaxHeight * a;

                        float yPoint = getMeasuredHeight() - chartBottom - (yPercentage) * (getMeasuredHeight() - chartBottom - SIGNATURE_TEXT_HEIGHT);

                        if (i == selectedIndex && legendShowing)
                        {
                            selected  = true;
                            selectedX = xPoint;
                            selectedY = yPoint;
                            continue;
                        }

                        line.linesPath[j++] = xPoint;
                        line.linesPath[j++] = yPoint;

                        line.linesPath[j++] = xPoint;
                        line.linesPath[j++] = getMeasuredHeight() - chartBottom;
                    }

                    Paint paint = selected || postTransition ? line.unselectedPaint : line.paint;
                    paint.StrokeWidth = p;
                    //paint.setStrokeWidth(p);


                    if (selected)
                    {
                        line.unselectedPaint.Color = Extensions.blendARGB(
                            line.line.color, line.blendColor, 1f - selectionA);
                    }

                    if (postTransition)
                    {
                        line.unselectedPaint.Color = Extensions.blendARGB(
                            line.line.color, line.blendColor, 0);
                    }

                    paint.A = (byte)(transitionAlpha * 255);
                    //canvas.drawLines(line.linesPath, 0, j, paint);
                    canvas.DrawLines(line.linesPath, 0, j, paint);

                    if (selected)
                    {
                        //line.paint.setStrokeWidth(p);
                        line.paint.StrokeWidth = p;
                        line.paint.A           = (byte)(transitionAlpha * 255);
                        //canvas.drawLine(selectedX, selectedY,
                        //        selectedX, getMeasuredHeight() - chartBottom,
                        //        line.paint
                        //);
                        canvas.DrawLine(selectedX, selectedY, selectedX, getMeasuredHeight() - chartBottom, line.paint);
                        line.paint.A = 255;
                    }
                }

                //canvas.restore();
                //canvas.restore();
                clip.Dispose();
                canvas.Transform = transform;
            }
        }