MPAndroidChart - 是否可以控制图表元素的z-index?

时间:2016-09-08 09:34:59

标签: android charts mpandroidchart

我希望在MPAndroidChart(从下到上)中绘制以下顺序:

  1. 数据连接线
  2. 限制线
  3. 数据点
  4. 有可能吗?我知道方法com.github.mikephil.charting.components.AxisBase#setDrawLimitLinesBehindData。除了一个案例外,它正如预期的那样工作。当所有数据点的Y值相同时,效果为:

    enter image description here

    或者这个:

    enter image description here

    我希望它看起来像:

    enter image description here

    前2张图片来自MPAndroidChart Android库。第三个来自图书馆的iOS端口:Charts

    我查看了订单或在AndroidiOS版本中绘制图表,它们看起来一样。

    问题:

    1. 是否可以控制绘图顺序?
    2. 系统版本之间有什么区别?
    3. 是否还有其他开源库可以做到这一点?
    4. 其他信息:图书馆绘制所有图像,线条,圆圈,不使用自定义图像。

1 个答案:

答案 0 :(得分:1)

a previous answer here类似,没有公开API直接设置各种绘图功能的z-index。

相反,组件在画布上按顺序绘制,后面的组件被绘制在先前的组件上。这意味着您可以更改渲染顺序,您可以更改z-index。

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

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

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

  1. 数据连接线在LineChartRenderer内的名为:

    的方法中绘制
    protected drawLinear(Canvas c, ILineDataSet dataSet)
    
  2. 限制线位于XAxisRenderer内,名为:

    public void renderLimitLines(Canvas c)
    
  3. 数据点(圆圈)在LineChartRenderer内绘制,方法如下:

    public void drawExtras(Canvas c)
    
  4. 这三种方法的调用顺序是在Android View覆盖的方法中BarLineChartBase内确定的:

        protected onDraw(Canvas canvas);
    

    因此,要获得您想要的订单,您必须简单地重新安排在onDraw(Canvas canvas)内调用上述3种方法的顺序:

    以下是应符合要求的自定义折线图的完整代码。按照设计,您仍然需要致电:

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

    但是如果您愿意,可以轻松删除3 if个语句并对订单进行硬编码。

    <强> 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();
        }
    }