复杂设计面前,代码开源是真大佬。
话不多说,此篇主要记录图表类HorizontalBarChart的样式定制:圆角及渐变。
app.gradle 升级到此版本
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
自定义HorizontalBarChartRenderer设置圆角
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Build;
import com.github.mikephil.charting.animation.ChartAnimator;
import com.github.mikephil.charting.buffer.BarBuffer;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
import com.github.mikephil.charting.model.GradientColor;
import com.github.mikephil.charting.renderer.HorizontalBarChartRenderer;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.Utils;
import com.github.mikephil.charting.utils.ViewPortHandler;
import androidx.annotation.RequiresApi;
public class MyHorBarchartRender extends HorizontalBarChartRenderer {
MyHorBarchartRender(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
}
private RectF mBarShadowRectBuffer = new RectF();
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) {
super.drawDataSet(c, dataSet, index);
c.drawColor(Color.parseColor("#1e2c48"));//默认画布背景,为透明色时圆角失效,为纯色时画布内网格被覆盖
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
mBarBorderPaint.setColor(dataSet.getBarBorderColor());
mBarBorderPaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getBarBorderWidth()));
final boolean drawBorder = dataSet.getBarBorderWidth() > 0.f;
float phaseX = mAnimator.getPhaseX();
float phaseY = mAnimator.getPhaseY();
// draw the bar shadow before the values
if (mChart.isDrawBarShadowEnabled()) {
mShadowPaint.setColor(dataSet.getBarShadowColor());
BarData barData = mChart.getBarData();
final float barWidth = barData.getBarWidth();
final float barWidthHalf = barWidth / 2.0f;
float x;
for (int i = 0, count = Math.min((int) (Math.ceil((float) (dataSet.getEntryCount()) * phaseX)), dataSet.getEntryCount());
i < count;
i++) {
BarEntry e = dataSet.getEntryForIndex(i);
x = e.getX();
mBarShadowRectBuffer.left = x - barWidthHalf;
mBarShadowRectBuffer.right = x + barWidthHalf;
trans.rectValueToPixel(mBarShadowRectBuffer);
if (!mViewPortHandler.isInBoundsLeft(mBarShadowRectBuffer.right))
continue;
if (!mViewPortHandler.isInBoundsRight(mBarShadowRectBuffer.left))
break;
mBarShadowRectBuffer.top = mViewPortHandler.contentTop();
mBarShadowRectBuffer.bottom = mViewPortHandler.contentBottom();
c.drawRect(mBarShadowRectBuffer, mShadowPaint);
}
}
// initialize the buffer
BarBuffer buffer = mBarBuffers[index];
buffer.setPhases(phaseX, phaseY);
buffer.setDataSet(index);
buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency()));
buffer.setBarWidth(mChart.getBarData().getBarWidth());
buffer.feed(dataSet);
trans.pointValuesToPixel(buffer.buffer);
final boolean isSingleColor = dataSet.getColors().size() == 1;
if (isSingleColor) {
mRenderPaint.setColor(dataSet.getColor());
}
for (int j = 0; j < buffer.size(); j += 4) {
if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2]))
continue;
if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j]))
break;
if (!isSingleColor) {
mRenderPaint.setColor(dataSet.getColor(j / 4));
}
if (dataSet.getGradientColor() != null) {
GradientColor gradientColor = dataSet.getGradientColor();
mRenderPaint.setShader(
new LinearGradient(
buffer.buffer[j],
buffer.buffer[j + 3],
buffer.buffer[j],
buffer.buffer[j + 1],
gradientColor.getStartColor(),
gradientColor.getEndColor(),
android.graphics.Shader.TileMode.MIRROR));
}
if (dataSet.getGradientColors() != null) {
mRenderPaint.setShader(
new LinearGradient(
buffer.buffer[j],
buffer.buffer[j+3],
buffer.buffer[j+2],
buffer.buffer[j+1],
dataSet.getGradientColor(j / 4).getEndColor(),
dataSet.getGradientColor(j / 4).getStartColor(),
android.graphics.Shader.TileMode.MIRROR));
}
//圆角
RectF rectF = new RectF(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], buffer.buffer[j + 3]);
Path path = new Path();
//float数组中4个角分别是左上、右上、右下、左下
path.addRoundRect(rectF, new float[]{0, 0, 40, 40, 40, 40, 0, 0}, Path.Direction.CCW);
c.drawPath(path, mRenderPaint);
if (drawBorder) {
c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2],
buffer.buffer[j + 3], mBarBorderPaint);
}
}
}
}
自定义HorizontalBarChart调用Render
import com.github.mikephil.charting.charts.HorizontalBarChart;
public class MyHorBarchart extends HorizontalBarChart {
public MyHorBarchart(Context context) {
super(context);
}
public MyHorBarchart(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyHorBarchart(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void init() {
super.init();
this.mRenderer = new MyHorBarchartRender(this, this.mAnimator, this.mViewPortHandler);
}
}
Java代码调用 属性设置
List<GradientColor> gradientColors = new ArrayList<>();
for (Map<String,String> map :colors) {
gradientColors.add(new GradientColor(Color.parseColor(map.get("startcolor")),Color.parseColor(map.get("endcolor"))));
}
barDataSet.setGradientColors(gradientColors);//设置渐变色值,在barChart.setData前调用
xml
<your.packagename.MyHorBarchart
android:id="@+id/horbarchart"
android:layout_width="match_parent"
android:layout_height="300dp" />
Github:https://github.com/PhilJay/MPAndroidChart
非常感谢开源的作者,请在Github上为作者点个Star,嘿哈~