MPAndroidChart-是否可以控制图表元素的Z索引? [英] MPAndroidChart - is it possible to control z-index of the chart elements?

查看:104
本文介绍了MPAndroidChart-是否可以控制图表元素的Z索引?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的 MPAndroidChart 中按以下顺序绘制(从下到上) :

I would like to have the following order of drawing in my MPAndroidChart (from bottom to top):

  1. 数据连接线
  2. 限制线
  3. 数据点

有可能吗?我知道方法com.github.mikephil.charting.components.AxisBase#setDrawLimitLinesBehindData.除一种情况外,它均按预期工作.当所有数据点的Y值相同时,效果为:

Is it possible? I am aware of the method com.github.mikephil.charting.components.AxisBase#setDrawLimitLinesBehindData. It is working as expected except for one case. When the Y value of all data points is the same, the effect is:

或者这个:

我希望它看起来像:

前两张图片来自 MPAndroidChart Android库.第三个来自库的iOS端口:图表

The first 2 pictures are from MPAndroidChart Android library. The 3rd one is from iOS port of the library: Charts

我查看了订单或在

I looked at the order or drawing the chart in Android and iOS versions and they look the same.

问题:

  1. 可以控制绘图顺序吗?
  2. 系统版本之间有什么区别?
  3. 还有其他开源库可以做到吗?

其他信息:所有图像,线条,圆圈均由库绘制,未使用自定义图像.

Additional info: all images, lines, circles are drawn by the library, custom images are not used.

推荐答案

类似于

Similar to a previous answer here there is no public API exposed to directly set the z-index of the various drawing features.

相反,组件是在画布上按顺序绘制的,后面的组件是在较早的组件上绘制的.这意味着您可以更改渲染顺序,也可以更改z-index.

Instead, components are drawn in order on the canvas with later components being drawn over earlier ones. This means you change the rendering order, you can change the z-index.

您说您想要以下绘制顺序:

You say you would like the following drawing order:

  1. 数据连接线
  2. 限制线
  3. 数据点
  1. Data connecting line
  2. Limit line
  3. Data points

让我们在源代码中找到处理这些方法的方法:

Let's find the methods in the source code that deal with each of those:

  1. 数据连接线绘制在

  2. 限制线绘制在

  3. The limit line is drawn inside XAxisRenderer called:

    public void renderLimitLines(Canvas c)
    

  4. 数据点(圆圈)绘制在

  5. The data points (circles) are drawn inside LineChartRenderer in a method that looks like this:

    public void drawExtras(Canvas c)
    

  6. 这三种方法的调用顺序在

    The calling order of these three methods is determined inside BarLineChartBase in the method overriden from Android's View:

        protected onDraw(Canvas canvas);
    

    因此要获得所需的顺序,您只需简单地重新安排onDraw(Canvas canvas)中上述3个方法的调用顺序:

    So to get the order you want you will have to simply re-arrange the order of calling of the above 3 methods inside onDraw(Canvas canvas):

    这是应满足要求的自定义折线图的完整代码.按照设计,您仍然必须致电:

    Here is the complete code for a custom line chart that should meet the requirement. By design, you will still have to call:

    com.github.mikephil.charting.components.AxisBase#setDrawLimitLinesBehindData
    

    但是您可以轻松删除3个if语句,并根据需要对命令进行硬编码.

    But you could easily remove the 3 if statements and hard-code the order should you so desire.

    CustomZIndexBarLineBase.java

    import android.content.Context;
    import android.graphics.Canvas;
    import android.util.AttributeSet;
    
    import com.github.mikephil.charting.charts.BarLineChartBase;
    import com.github.mikephil.charting.data.LineData;
    
    /**
     * Created by David on 11/01/2017.
     */
    
    public class CustomZIndexLineChartBase extends BarLineChartBase<LineData> {
    
        public CustomZIndexLineChartBase(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public CustomZIndexLineChartBase(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomZIndexLineChartBase(Context context) {
            super(context);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            if (mData == null)
                return;
    
            // execute all drawing commands
            drawGridBackground(canvas);
    
            if (mAxisLeft.isEnabled())
                mAxisRendererLeft.computeAxis(mAxisLeft.mAxisMinimum, mAxisLeft.mAxisMaximum, mAxisLeft.isInverted());
            if (mAxisRight.isEnabled())
                mAxisRendererRight.computeAxis(mAxisRight.mAxisMinimum, mAxisRight.mAxisMaximum, mAxisRight.isInverted());
            if (mXAxis.isEnabled())
                mXAxisRenderer.computeAxis(mXAxis.mAxisMinimum, mXAxis.mAxisMaximum, false);
    
            mXAxisRenderer.renderAxisLine(canvas);
            mAxisRendererLeft.renderAxisLine(canvas);
            mAxisRendererRight.renderAxisLine(canvas);
    
            if (mAutoScaleMinMaxEnabled) {
                autoScale();
            }
    
            mXAxisRenderer.renderGridLines(canvas);
            mAxisRendererLeft.renderGridLines(canvas);
            mAxisRendererRight.renderGridLines(canvas);
    
            if (mXAxis.isDrawLimitLinesBehindDataEnabled())
                mXAxisRenderer.renderLimitLines(canvas);
    
            if (mAxisLeft.isDrawLimitLinesBehindDataEnabled())
                mAxisRendererLeft.renderLimitLines(canvas);
    
            if (mAxisRight.isDrawLimitLinesBehindDataEnabled())
                mAxisRendererRight.renderLimitLines(canvas);
    
            int clipRestoreCount = canvas.save();
            canvas.clipRect(mViewPortHandler.getContentRect());
    
            mRenderer.drawData(canvas); //NOTE: draws line between points
    
    
            if (valuesToHighlight())
                mRenderer.drawHighlighted(canvas, mIndicesToHighlight);
    
            canvas.restoreToCount(clipRestoreCount);
    
            //NOTE: draws limit line
            if (!mXAxis.isDrawLimitLinesBehindDataEnabled())
                mXAxisRenderer.renderLimitLines(canvas);
    
            if (!mAxisLeft.isDrawLimitLinesBehindDataEnabled())
                mAxisRendererLeft.renderLimitLines(canvas);
    
            if (!mAxisRight.isDrawLimitLinesBehindDataEnabled())
                mAxisRendererRight.renderLimitLines(canvas);
    
            mRenderer.drawExtras(canvas); //NOTE: draws circles
    
            mXAxisRenderer.renderAxisLabels(canvas);
            mAxisRendererLeft.renderAxisLabels(canvas);
            mAxisRendererRight.renderAxisLabels(canvas);
    
            if (isClipValuesToContentEnabled()) {
                clipRestoreCount = canvas.save();
                canvas.clipRect(mViewPortHandler.getContentRect());
    
                mRenderer.drawValues(canvas);
    
                canvas.restoreToCount(clipRestoreCount);
            } else {
                mRenderer.drawValues(canvas);
            }
    
            mLegendRenderer.renderLegend(canvas);
    
            drawDescription(canvas);
    
            drawMarkers(canvas);
        }
    }
    

    CustomZIndexLineChart.java

    import android.content.Context;
    import android.graphics.Canvas;
    import android.util.AttributeSet;
    
    import com.github.mikephil.charting.data.LineData;
    import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
    import com.github.mikephil.charting.renderer.LineChartRenderer;
    
    /**
     * Created by David on 11/01/2017.
     */
    
    public class CustomZIndexLineChart extends CustomZIndexLineChartBase implements LineDataProvider {
    
        public CustomZIndexLineChart(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public CustomZIndexLineChart(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomZIndexLineChart(Context context) {
            super(context);
        }
    
        @Override
        protected void init() {
            super.init();
    
            mRenderer = new LineChartRenderer(this, mAnimator, mViewPortHandler);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
        }
    
        @Override
        public LineData getLineData() {
            return mData;
        }
    
        @Override
        protected void onDetachedFromWindow() {
            // releases the bitmap in the renderer to avoid oom error
            if (mRenderer != null && mRenderer instanceof LineChartRenderer) {
                ((LineChartRenderer) mRenderer).releaseBitmap();
            }
            super.onDetachedFromWindow();
        }
    }
    

    这篇关于MPAndroidChart-是否可以控制图表元素的Z索引?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆