The default highlight on MPAndroidChart is as follows:
Only the color was deepened, and the design wanted to achieve the following effect:
Similar to shadow effect, and the display width needs to be increased.
First, whether MPAndroidChart is supported
Looking at the external interface of the framework, we find the following two methods:
BarDataSet set1 = new BarDataSet(yValues, "");
set1.setHighLightColor(ContextCompat.getColor(this, R.color.black));
set1.setHighLightAlpha(40);
Copy the code
We can only change the highlight color and transparency, but there is no way to change the width and height to achieve the desired effect. There is no way but to look at the source code is how to implement, and then try to modify it.
Two, view the source code implementation
Start with the setHighLightAlpha() method:
//BarDataSet.java
public void setHighLightAlpha(int alpha) {
mHighLightAlpha = alpha;
}
@Override
public int getHighLightAlpha(a) {
return mHighLightAlpha;
}
Copy the code
See where the getHighLightAlpha() method is called:
//BarChartRenderer.java
@Override
public void drawHighlighted(Canvas c, Highlight[] indices) {
BarData barData = mChart.getBarData();
for(Highlight high : indices) { IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex()); . prepareBarHighlight(e.getX(), y1, y2, barData.getBarWidth() /2f, trans);
setHighlightDrawPos(high, mBarRect);
// To highlight the background is to draw a rectanglec.drawRect(mBarRect, mHighlightPaint); }}Copy the code
From the source can be seen, click the effect is by clicking the position, redraw a rectangle. So the point is the assignment of mBarRect.
//BarChartRenderer.java
protected void prepareBarHighlight(float x, float y1, float y2, float barWidthHalf, Transformer trans) {
float left = x - barWidthHalf;
float right = x + barWidthHalf;
float top = y1;
float bottom = y2;
mBarRect.set(left, top, right, bottom);
trans.rectToPixelPhase(mBarRect, mAnimator.getPhaseY());
}
Copy the code
You can see that you can change the width and height of the highlighted rectangle simply by overwriting the method and modifying the parameters.
Three, code implementation
3.1 Rewrite the BarChartRenderer class
BarChartRenderer initialization location, and support customization:
//BarChart.java
@Override
protected void init(a) {
super.init();
// Initialize the place
mRenderer = new BarChartRenderer(this, mAnimator, mViewPortHandler);
setHighlighter(new BarHighlighter(this));
getXAxis().setSpaceMin(0.5 f);
getXAxis().setSpaceMax(0.5 f);
}
// Support developer customization
public void setRenderer(DataRenderer renderer) {
if(renderer ! =null)
mRenderer = renderer;
}
Copy the code
Custom BarChartRenderer:
public class TestBarChartRenderer extends BarChartRenderer {
private Transformer transformer;
public TestBarChartRenderer( BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
}
@Override
protected void prepareBarHighlight(float x, float y1, float y2, float barWidthHalf,
Transformer trans) {
transformer = trans;
// Change the height and width of the highlight effect. GetYChartMax gets the maximum value of the table
super.prepareBarHighlight(x, mChart.getYChartMax(), y2, barWidthHalf + 0.2 f, trans); }}// Set the custom Renderer
barChart.setRenderer(
new TestBarChartRenderer(barChart, barChart.getAnimator(), barChart.getViewPortHandler()));
// Click on the entire data highlight
barChart.setHighlightFullBarEnabled(true);
Copy the code
3.2 Modify all markup views at the same height problem
After clicking on the data, all the labeled views of the data are at the same height:
View the source code found:
//BarChartRenderer.java
@Override
public void drawHighlighted(Canvas c, Highlight[] indices) {
BarData barData = mChart.getBarData();
for(Highlight high : indices) { IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex()); . prepareBarHighlight(e.getX(), y1, y2, barData.getBarWidth() /2f, trans);
// Modify the highlighted data
setHighlightDrawPos(high, mBarRect);
// To highlight the background is to draw a rectanglec.drawRect(mBarRect, mHighlightPaint); }}protected void setHighlightDrawPos(Highlight high, RectF bar) {
// This position will affect the display position of the tag view
high.setDraw(bar.centerX(), bar.top);
}
Copy the code
So after modifying the data in prepareBarHighlight(), you need to restore the real data in setHighlightDrawPos(). The final code is as follows:
public class TestBarChartRenderer extends BarChartRenderer {
private Transformer transformer;
public TestBarChartRenderer( BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
}
@Override
protected void prepareBarHighlight(float x, float y1, float y2, float barWidthHalf,
Transformer trans) {
transformer = trans;
// Modify the height and width of the highlighted background
super.prepareBarHighlight(x, mChart.getYChartMax(), y2, barWidthHalf + 0.2 f, trans);
}
@Override
protected void setHighlightDrawPos(Highlight high, RectF bar) {
if(transformer ! =null) {
// Restore the real click data
float barWidthHalf = mChart.getBarData().getBarWidth() / 2f;
float x = high.getX();
RectF rectF = new RectF();
rectF.set(x - barWidthHalf, high.getY(), x + barWidthHalf, 0f);
transformer.rectToPixelPhase(rectF, mAnimator.getPhaseY());
super.setHighlightDrawPos(high, rectF);
} else {
super.setHighlightDrawPos(high, bar); }}}Copy the code
The implementation of the bar chart can refer to:
MPAndroidChart implements stacked bar charts
MPAndroidChart custom MarkerView