Skip to content

Instantly share code, notes, and snippets.

@fnk0
Created September 27, 2016 17:16
Show Gist options
  • Save fnk0/b80d883db6b1260ee5cad0de5cbbec1a to your computer and use it in GitHub Desktop.
Save fnk0/b80d883db6b1260ee5cad0de5cbbec1a to your computer and use it in GitHub Desktop.
An oblique chart data renderer for MpAndroidChart
package com.gabilheri.fithub.ui.views.charts;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Path;
import android.graphics.Shader;
import com.gabilheri.fithub.helpers.ColorUtils;
import com.github.mikephil.charting.animation.ChartAnimator;
import com.github.mikephil.charting.buffer.BarBuffer;
import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
import com.github.mikephil.charting.renderer.BarChartRenderer;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.ViewPortHandler;
/**
* Created by <a href="mailto:[email protected]">Marcus Gabilheri</a>
*
* @author Marcus Gabilheri
* @version 1.0
* @since 2/26/16.
*/
public class ObliqueDataRenderer extends BarChartRenderer {
float angleSize;
LinearGradient mLinearGradient;
int[] mColors;
public ObliqueDataRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
}
@Override
protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) {
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
mShadowPaint.setColor(dataSet.getBarShadowColor());
float phaseX = mAnimator.getPhaseX();
float phaseY = mAnimator.getPhaseY();
// initialize the buffer
BarBuffer buffer = mBarBuffers[index];
buffer.setPhases(phaseX, phaseY);
buffer.setBarSpace(dataSet.getBarSpace());
buffer.setDataSet(index);
buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency()));
buffer.feed(dataSet);
trans.pointValuesToPixel(buffer.buffer);
// draw the bar shadow before the values
if (mChart.isDrawBarShadowEnabled()) {
for (int j = 0; j < buffer.size(); j += 4) {
if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) {
continue;
}
if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) {
break;
}
float top = buffer.buffer[j + 1];
float bottom = buffer.buffer[j + 3];
if (bottom == top) {
continue;
}
c.drawPath(getObliquePath(buffer.buffer[j], mViewPortHandler.contentTop(),
buffer.buffer[j + 2],
mViewPortHandler.contentBottom()), mShadowPaint);
}
}
// if multiple colors
if (dataSet.getColors().size() > 1) {
for (int j = 0; j < buffer.size(); j += 4) {
if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) {
continue;
}
if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) {
break;
}
float left = buffer.buffer[j];
float top = buffer.buffer[j + 1];
float right = buffer.buffer[j + 2];
float bottom = buffer.buffer[j + 3];
if (bottom == top) {
continue;
}
// Set the color for the currently drawn value. If the index
// is
// out of bounds, reuse colors.
mRenderPaint.setColor(dataSet.getColor(j / 4));
mColors = ColorUtils.getChartGradient(dataSet.getColor(j / 4));
mLinearGradient = new LinearGradient(0, 0, 0, c.getHeight(), mColors, null, Shader.TileMode.MIRROR);
mRenderPaint.setShader(mLinearGradient);
c.drawPath(getObliquePath(left, top, right, bottom), mRenderPaint);
}
} else {
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;
}
float left = buffer.buffer[j];
float top = buffer.buffer[j + 1];
float right = buffer.buffer[j + 2];
float bottom = buffer.buffer[j + 3];
if (bottom == top) {
continue;
}
mColors = ColorUtils.getChartGradient(dataSet.getColor());
mLinearGradient = new LinearGradient(left, top, right, bottom, mColors, null, Shader.TileMode.MIRROR);
mRenderPaint.setShader(mLinearGradient);
c.drawPath(getObliquePath(left, top, right, bottom), mRenderPaint);
}
}
}
public ObliqueDataRenderer setAngleSize(float angleSize) {
this.angleSize = angleSize;
return this;
}
public Path getObliquePath(float left, float top, float right, float bottom) {
Path barPath = new Path();
barPath.moveTo(left, bottom);
barPath.lineTo(left, top + angleSize);
barPath.lineTo(right, top);
barPath.lineTo(right, bottom);
barPath.lineTo(left, bottom);
return barPath;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment