MPAndroidChart-是否可以控制图表元素的Z索引? [英] MPAndroidChart - is it possible to control z-index of the chart elements?
问题描述
我想在我的 MPAndroidChart 中按以下顺序绘制(从下到上) :
I would like to have the following order of drawing in my MPAndroidChart (from bottom to top):
- 数据连接线
- 限制线
- 数据点
有可能吗?我知道方法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
我查看了订单或在 iOS 版本,它们看起来相同.
I looked at the order or drawing the chart in Android and iOS versions and they look the same.
问题:
- 可以控制绘图顺序吗?
- 系统版本之间有什么区别?
- 还有其他开源库可以做到吗?
其他信息:所有图像,线条,圆圈均由库绘制,未使用自定义图像.
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:
- 数据连接线
- 限制线
- 数据点
- Data connecting line
- Limit line
- Data points
让我们在源代码中找到处理这些方法的方法:
Let's find the methods in the source code that deal with each of those:
The limit line is drawn inside
XAxisRenderer
called:public void renderLimitLines(Canvas c)
The data points (circles) are drawn inside
LineChartRenderer
in a method that looks like this:public void drawExtras(Canvas c)
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屋!