是否可以使用MPChart Library在折线图上的特定点显示小图像/图标?
答案 0 :(得分:0)
使用以下CusotomLineDataSet
课程代替LineDataSet
public class CusotomLineDataSet extends LineRadarDataSet<Entry> implements ILineDataSet {
private CusotomLineDataSet.Mode mMode = Mode.LINEAR;
private List<Integer> mCircleColors = null;
private int mCircleColorHole = Color.WHITE;
private float mCircleRadius = 8f;
private Bitmap mBitmap = null;
private float mCircleHoleRadius = 4f;
private float mCubicIntensity = 0.2f;
private DashPathEffect mDashPathEffect = null;
private IFillFormatter mFillFormatter = new DefaultFillFormatter();
private boolean mDrawCircles = true;
private boolean mDrawCircleHole = true;
public CusotomLineDataSet(List<Entry> yVals, String label) {
super(yVals, label);
// mCircleRadius = Utils.convertDpToPixel(4f);
// mLineWidth = Utils.convertDpToPixel(1f);
if (mCircleColors == null) {
mCircleColors = new ArrayList<Integer>();
}
mCircleColors.clear();
// default colors
// mColors.add(Color.rgb(192, 255, 140));
// mColors.add(Color.rgb(255, 247, 140));
mCircleColors.add(Color.rgb(140, 234, 255));
}
@Override
public DataSet<Entry> copy() {
List<Entry> yVals = new ArrayList<Entry>();
for (int i = 0; i < mValues.size(); i++) {
yVals.add(mValues.get(i).copy());
}
CusotomLineDataSet copied = new CusotomLineDataSet(yVals, getLabel());
copied.mMode = mMode;
copied.mColors = mColors;
copied.mCircleRadius = mCircleRadius;
copied.mBitmap = mBitmap;
copied.mCircleHoleRadius = mCircleHoleRadius;
copied.mCircleColors = mCircleColors;
copied.mDashPathEffect = mDashPathEffect;
copied.mDrawCircles = mDrawCircles;
copied.mDrawCircleHole = mDrawCircleHole;
copied.mHighLightColor = mHighLightColor;
return copied;
}
@Override
public CusotomLineDataSet.Mode getMode() {
return mMode;
}
public void setMode(CusotomLineDataSet.Mode mode) {
mMode = mode;
}
public void setCubicIntensity(float intensity) {
if (intensity > 1f)
intensity = 1f;
if (intensity < 0.05f)
intensity = 0.05f;
mCubicIntensity = intensity;
}
@Override
public float getCubicIntensity() {
return mCubicIntensity;
}
public void setCircleRadius(float radius) {
if (radius >= 1f) {
mCircleRadius = Utils.convertDpToPixel(radius);
} else {
Log.e("CusotomLineDataSet", "Circle radius cannot be < 1");
}
}
public void setCircleBitmap(Bitmap circleBitmap) {
mBitmap = circleBitmap;
}
@Override
public Bitmap getCircleBitmap() {
return mBitmap;
}
@Override
public float getCircleRadius() {
return mCircleRadius;
}
public void setCircleHoleRadius(float holeRadius) {
if (holeRadius >= 0.5f) {
mCircleHoleRadius = Utils.convertDpToPixel(holeRadius);
} else {
Log.e("CusotomLineDataSet", "Circle radius cannot be < 0.5");
}
}
@Override
public float getCircleHoleRadius() {
return mCircleHoleRadius;
}
@Deprecated
public void setCircleSize(float size) {
setCircleRadius(size);
}
@Deprecated
public float getCircleSize() {
return getCircleRadius();
}
public void enableDashedLine(float lineLength, float spaceLength, float phase) {
mDashPathEffect = new DashPathEffect(new float[]{
lineLength, spaceLength
}, phase);
}
public void disableDashedLine() {
mDashPathEffect = null;
}
@Override
public boolean isDashedLineEnabled() {
return mDashPathEffect == null ? false : true;
}
@Override
public DashPathEffect getDashPathEffect() {
return mDashPathEffect;
}
public void setDrawCircles(boolean enabled) {
this.mDrawCircles = enabled;
}
@Override
public boolean isDrawCirclesEnabled() {
return mDrawCircles;
}
@Deprecated
@Override
public boolean isDrawCubicEnabled() {
return mMode == Mode.CUBIC_BEZIER;
}
@Deprecated
@Override
public boolean isDrawSteppedEnabled() {
return mMode == Mode.STEPPED;
}
public List<Integer> getCircleColors() {
return mCircleColors;
}
@Override
public int getCircleColor(int index) {
return mCircleColors.get(index);
}
@Override
public int getCircleColorCount() {
return mCircleColors.size();
}
public void setCircleColors(List<Integer> colors) {
mCircleColors = colors;
}
public void setCircleColors(int... colors) {
this.mCircleColors = ColorTemplate.createColors(colors);
}
public void setCircleColors(int[] colors, Context c) {
List<Integer> clrs = mCircleColors;
if (clrs == null) {
clrs = new ArrayList<>();
}
clrs.clear();
for (int color : colors) {
clrs.add(c.getResources().getColor(color));
}
mCircleColors = clrs;
}
public void setCircleColor(int color) {
resetCircleColors();
mCircleColors.add(color);
}
public void resetCircleColors() {
if (mCircleColors == null) {
mCircleColors = new ArrayList<Integer>();
}
mCircleColors.clear();
}
public void setCircleColorHole(int color) {
mCircleColorHole = color;
}
@Override
public int getCircleHoleColor() {
return mCircleColorHole;
}
public void setDrawCircleHole(boolean enabled) {
mDrawCircleHole = enabled;
}
@Override
public boolean isDrawCircleHoleEnabled() {
return mDrawCircleHole;
}
public void setFillFormatter(IFillFormatter formatter) {
if (formatter == null)
mFillFormatter = new DefaultFillFormatter();
else
mFillFormatter = formatter;
}
@Override
public IFillFormatter getFillFormatter() {
return mFillFormatter;
}
public enum Mode {
LINEAR,
STEPPED,
CUBIC_BEZIER,
HORIZONTAL_BEZIER
}
}
答案 1 :(得分:0)
现在,对于设定的图像,您必须设置如下。
CusotomLineDataSet set = new CusotomLineDataSet(entries, "");
set.setCircleBitmap(BitmapFactory.decodeResource(getResources(), R.mipmap.icon_temp));
,您的LineChartRenderer
应如下所示。
public class LineChartRenderer extends LineRadarRenderer {
protected LineDataProvider mChart;
protected Paint mCirclePaintInner;
protected WeakReference<Bitmap> mDrawBitmap;
protected Canvas mBitmapCanvas;
protected Bitmap.Config mBitmapConfig = Bitmap.Config.ARGB_8888;
protected Path cubicPath = new Path();
protected Path cubicFillPath = new Path();
public LineChartRenderer(LineDataProvider chart, ChartAnimator animator,
ViewPortHandler viewPortHandler) {
super(animator, viewPortHandler);
mChart = chart;
mCirclePaintInner = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePaintInner.setStyle(Paint.Style.FILL);
mCirclePaintInner.setColor(Color.WHITE);
}
@Override
public void initBuffers() {
}
@Override
public void drawData(Canvas c) {
int width = (int) mViewPortHandler.getChartWidth();
int height = (int) mViewPortHandler.getChartHeight();
if (mDrawBitmap == null
|| (mDrawBitmap.get().getWidth() != width)
|| (mDrawBitmap.get().getHeight() != height)) {
if (width > 0 && height > 0) {
mDrawBitmap = new WeakReference<Bitmap>(Bitmap.createBitmap(width, height, mBitmapConfig));
mBitmapCanvas = new Canvas(mDrawBitmap.get());
} else
return;
}
mDrawBitmap.get().eraseColor(Color.TRANSPARENT);
LineData lineData = mChart.getLineData();
for (ILineDataSet set : lineData.getDataSets()) {
if (set.isVisible())
drawDataSet(c, set);
}
c.drawBitmap(mDrawBitmap.get(), 0, 0, mRenderPaint);
}
protected void drawDataSet(Canvas c, ILineDataSet dataSet) {
if (dataSet.getEntryCount() < 1)
return;
mRenderPaint.setStrokeWidth(dataSet.getLineWidth());
mRenderPaint.setPathEffect(dataSet.getDashPathEffect());
switch (dataSet.getMode()) {
default:
case LINEAR:
case STEPPED:
drawLinear(c, dataSet);
break;
case CUBIC_BEZIER:
drawCubicBezier(dataSet);
break;
case HORIZONTAL_BEZIER:
drawHorizontalBezier(dataSet);
break;
}
mRenderPaint.setPathEffect(null);
}
protected void drawHorizontalBezier(ILineDataSet dataSet) {
float phaseY = mAnimator.getPhaseY();
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
mXBounds.set(mChart, dataSet);
cubicPath.reset();
if (mXBounds.range >= 1) {
Entry prev = dataSet.getEntryForIndex(mXBounds.min);
Entry cur = prev;
// let the spline start
cubicPath.moveTo(cur.getX(), cur.getY() * phaseY);
for (int j = mXBounds.min + 1; j <= mXBounds.range + mXBounds.min; j++) {
prev = cur;
cur = dataSet.getEntryForIndex(j);
final float cpx = (prev.getX())
+ (cur.getX() - prev.getX()) / 2.0f;
cubicPath.cubicTo(
cpx, prev.getY() * phaseY,
cpx, cur.getY() * phaseY,
cur.getX(), cur.getY() * phaseY);
}
}
// if filled is enabled, close the path
if (dataSet.isDrawFilledEnabled()) {
cubicFillPath.reset();
cubicFillPath.addPath(cubicPath);
// create a new path, this is bad for performance
drawCubicFill(mBitmapCanvas, dataSet, cubicFillPath, trans, mXBounds);
}
mRenderPaint.setColor(dataSet.getColor());
mRenderPaint.setStyle(Paint.Style.STROKE);
trans.pathValueToPixel(cubicPath);
mBitmapCanvas.drawPath(cubicPath, mRenderPaint);
mRenderPaint.setPathEffect(null);
}
protected void drawCubicBezier(ILineDataSet dataSet) {
float phaseX = Math.max(0.f, Math.min(1.f, mAnimator.getPhaseX()));
float phaseY = mAnimator.getPhaseY();
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
mXBounds.set(mChart, dataSet);
float intensity = dataSet.getCubicIntensity();
cubicPath.reset();
if (mXBounds.range >= 1) {
float prevDx = 0f;
float prevDy = 0f;
float curDx = 0f;
float curDy = 0f;
Entry prevPrev = dataSet.getEntryForIndex(mXBounds.min);
Entry prev = prevPrev;
Entry cur = prev;
Entry next = dataSet.getEntryForIndex(mXBounds.min + 1);
if (cur == null || next == null) return;
// let the spline start
cubicPath.moveTo(cur.getX(), cur.getY() * phaseY);
for (int j = mXBounds.min + 1; j <= mXBounds.range + mXBounds.min; j++) {
prevPrev = dataSet.getEntryForIndex(j == 1 ? 0 : j - 2);
prev = dataSet.getEntryForIndex(j - 1);
cur = dataSet.getEntryForIndex(j);
next = mXBounds.max > j + 1 ? dataSet.getEntryForIndex(j + 1) : cur;
prevDx = (cur.getX() - prevPrev.getX()) * intensity;
prevDy = (cur.getY() - prevPrev.getY()) * intensity;
curDx = (next.getX() - prev.getX()) * intensity;
curDy = (next.getY() - prev.getY()) * intensity;
cubicPath.cubicTo(prev.getX() + prevDx, (prev.getY() + prevDy) * phaseY,
cur.getX() - curDx,
(cur.getY() - curDy) * phaseY, cur.getX(), cur.getY() * phaseY);
}
}
// if filled is enabled, close the path
if (dataSet.isDrawFilledEnabled()) {
cubicFillPath.reset();
cubicFillPath.addPath(cubicPath);
drawCubicFill(mBitmapCanvas, dataSet, cubicFillPath, trans, mXBounds);
}
mRenderPaint.setColor(dataSet.getColor());
mRenderPaint.setStyle(Paint.Style.STROKE);
trans.pathValueToPixel(cubicPath);
mBitmapCanvas.drawPath(cubicPath, mRenderPaint);
mRenderPaint.setPathEffect(null);
}
protected void drawCubicFill(Canvas c, ILineDataSet dataSet, Path spline, Transformer trans, XBounds bounds) {
float fillMin = dataSet.getFillFormatter()
.getFillLinePosition(dataSet, mChart);
spline.lineTo(dataSet.getEntryForIndex(bounds.min + bounds.range).getX(), fillMin);
spline.lineTo(dataSet.getEntryForIndex(bounds.min).getX(), fillMin);
spline.close();
trans.pathValueToPixel(spline);
final Drawable drawable = dataSet.getFillDrawable();
if (drawable != null) {
drawFilledPath(c, spline, drawable);
} else {
drawFilledPath(c, spline, dataSet.getFillColor(), dataSet.getFillAlpha());
}
}
private float[] mLineBuffer = new float[4];
protected void drawLinear(Canvas c, ILineDataSet dataSet) {
int entryCount = dataSet.getEntryCount();
final boolean isDrawSteppedEnabled = dataSet.isDrawSteppedEnabled();
final int pointsPerEntryPair = isDrawSteppedEnabled ? 4 : 2;
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
float phaseY = mAnimator.getPhaseY();
mRenderPaint.setStyle(Paint.Style.STROKE);
Canvas canvas = null;
// if the data-set is dashed, draw on bitmap-canvas
if (dataSet.isDashedLineEnabled()) {
canvas = mBitmapCanvas;
} else {
canvas = c;
}
mXBounds.set(mChart, dataSet);
// if drawing filled is enabled
if (dataSet.isDrawFilledEnabled() && entryCount > 0) {
drawLinearFill(c, dataSet, trans, mXBounds);
}
// more than 1 color
if (dataSet.getColors().size() > 1) {
if (mLineBuffer.length <= pointsPerEntryPair * 2)
mLineBuffer = new float[pointsPerEntryPair * 4];
for (int j = mXBounds.min; j <= mXBounds.range + mXBounds.min; j++) {
Entry e = dataSet.getEntryForIndex(j);
if (e == null) continue;
mLineBuffer[0] = e.getX();
mLineBuffer[1] = e.getY() * phaseY;
if (j < mXBounds.max) {
e = dataSet.getEntryForIndex(j + 1);
if (e == null) break;
if (isDrawSteppedEnabled) {
mLineBuffer[2] = e.getX();
mLineBuffer[3] = mLineBuffer[1];
mLineBuffer[4] = mLineBuffer[2];
mLineBuffer[5] = mLineBuffer[3];
mLineBuffer[6] = e.getX();
mLineBuffer[7] = e.getY() * phaseY;
} else {
mLineBuffer[2] = e.getX();
mLineBuffer[3] = e.getY() * phaseY;
}
} else {
mLineBuffer[2] = mLineBuffer[0];
mLineBuffer[3] = mLineBuffer[1];
}
trans.pointValuesToPixel(mLineBuffer);
if (!mViewPortHandler.isInBoundsRight(mLineBuffer[0]))
break;
// make sure the lines don't do shitty things outside
// bounds
if (!mViewPortHandler.isInBoundsLeft(mLineBuffer[2])
|| (!mViewPortHandler.isInBoundsTop(mLineBuffer[1]) && !mViewPortHandler
.isInBoundsBottom(mLineBuffer[3]))
|| (!mViewPortHandler.isInBoundsTop(mLineBuffer[1]) && !mViewPortHandler
.isInBoundsBottom(mLineBuffer[3])))
continue;
// get the color that is set for this line-segment
mRenderPaint.setColor(dataSet.getColor(j));
canvas.drawLines(mLineBuffer, 0, pointsPerEntryPair * 2, mRenderPaint);
}
} else { // only one color per dataset
if (mLineBuffer.length < Math.max((entryCount) * pointsPerEntryPair, pointsPerEntryPair) * 2)
mLineBuffer = new float[Math.max((entryCount) * pointsPerEntryPair, pointsPerEntryPair) * 4];
Entry e1, e2;
e1 = dataSet.getEntryForIndex(mXBounds.min);
if (e1 != null) {
int j = 0;
for (int x = mXBounds.min; x <= mXBounds.range + mXBounds.min; x++) {
e1 = dataSet.getEntryForIndex(x == 0 ? 0 : (x - 1));
e2 = dataSet.getEntryForIndex(x);
if (e1 == null || e2 == null) continue;
mLineBuffer[j++] = e1.getX();
mLineBuffer[j++] = e1.getY() * phaseY;
if (isDrawSteppedEnabled) {
mLineBuffer[j++] = e2.getX();
mLineBuffer[j++] = e1.getY() * phaseY;
mLineBuffer[j++] = e2.getX();
mLineBuffer[j++] = e1.getY() * phaseY;
}
mLineBuffer[j++] = e2.getX();
mLineBuffer[j++] = e2.getY() * phaseY;
}
if (j > 0) {
trans.pointValuesToPixel(mLineBuffer);
final int size = Math.max((mXBounds.range + 1) * pointsPerEntryPair, pointsPerEntryPair) * 2;
mRenderPaint.setColor(dataSet.getColor());
canvas.drawLines(mLineBuffer, 0, size, mRenderPaint);
}
}
}
mRenderPaint.setPathEffect(null);
}
protected Path mGenerateFilledPathBuffer = new Path();
protected void drawLinearFill(Canvas c, ILineDataSet dataSet, Transformer trans, XBounds bounds) {
final Path filled = mGenerateFilledPathBuffer;
final int startingIndex = bounds.min;
final int endingIndex = bounds.range + bounds.min;
final int indexInterval = 128;
int currentStartIndex = 0;
int currentEndIndex = indexInterval;
int iterations = 0;
// Doing this iteratively in order to avoid OutOfMemory errors that can happen on large bounds sets.
do {
currentStartIndex = startingIndex + (iterations * indexInterval);
currentEndIndex = currentStartIndex + indexInterval;
currentEndIndex = currentEndIndex > endingIndex ? endingIndex : currentEndIndex;
if (currentStartIndex <= currentEndIndex) {
generateFilledPath(dataSet, currentStartIndex, currentEndIndex, filled);
trans.pathValueToPixel(filled);
final Drawable drawable = dataSet.getFillDrawable();
if (drawable != null) {
drawFilledPath(c, filled, drawable);
} else {
drawFilledPath(c, filled, dataSet.getFillColor(), dataSet.getFillAlpha());
}
}
iterations++;
} while (currentStartIndex <= currentEndIndex);
}
private void generateFilledPath(final ILineDataSet dataSet, final int startIndex, final int endIndex, final Path outputPath) {
final float fillMin = dataSet.getFillFormatter().getFillLinePosition(dataSet, mChart);
final float phaseY = mAnimator.getPhaseY();
final boolean isDrawSteppedEnabled = dataSet.getMode() == LineDataSet.Mode.STEPPED;
final Path filled = outputPath;
filled.reset();
final Entry entry = dataSet.getEntryForIndex(startIndex);
filled.moveTo(entry.getX(), fillMin);
filled.lineTo(entry.getX(), entry.getY() * phaseY);
// create a new path
Entry currentEntry = null;
Entry previousEntry = null;
for (int x = startIndex + 1; x <= endIndex; x++) {
currentEntry = dataSet.getEntryForIndex(x);
if (isDrawSteppedEnabled && previousEntry != null) {
filled.lineTo(currentEntry.getX(), previousEntry.getY() * phaseY);
}
filled.lineTo(currentEntry.getX(), currentEntry.getY() * phaseY);
previousEntry = currentEntry;
}
// close up
if (currentEntry != null) {
filled.lineTo(currentEntry.getX(), fillMin);
}
filled.close();
}
@Override
public void drawValues(Canvas c) {
if (isDrawingValuesAllowed(mChart)) {
List<ILineDataSet> dataSets = mChart.getLineData().getDataSets();
for (int i = 0; i < dataSets.size(); i++) {
ILineDataSet dataSet = dataSets.get(i);
if (!shouldDrawValues(dataSet))
continue;
// apply the text-styling defined by the DataSet
applyValueTextStyle(dataSet);
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
// make sure the values do not interfear with the circles
int valOffset = (int) (dataSet.getCircleBitmap().getHeight() + 1.75f);
if (!dataSet.isDrawCirclesEnabled())
valOffset = valOffset / 2;
mXBounds.set(mChart, dataSet);
float[] positions = trans.generateTransformedValuesLine(dataSet, mAnimator.getPhaseX(), mAnimator
.getPhaseY(), mXBounds.min, mXBounds.max);
for (int j = 0; j < positions.length; j += 2) {
float x = positions[j];
float y = positions[j + 1];
if (!mViewPortHandler.isInBoundsRight(x))
break;
if (!mViewPortHandler.isInBoundsLeft(x) || !mViewPortHandler.isInBoundsY(y))
continue;
Entry entry = dataSet.getEntryForIndex(j / 2 + mXBounds.min);
drawValue(c, dataSet.getValueFormatter(), entry.getY(), entry, i, x,
y - valOffset, dataSet.getValueTextColor(j / 2));
}
}
}
}
@Override
public void drawExtras(Canvas c) {
drawCircles(c);
}
private HashMap<IDataSet, DataSetImageCache> mImageCaches = new HashMap<>();
private float[] mCirclesBuffer = new float[2];
protected void drawCircles(Canvas c) {
mRenderPaint.setStyle(Paint.Style.FILL);
float phaseY = mAnimator.getPhaseY();
mCirclesBuffer[0] = 0;
mCirclesBuffer[1] = 0;
List<ILineDataSet> dataSets = mChart.getLineData().getDataSets();
for (int i = 0; i < dataSets.size(); i++) {
ILineDataSet dataSet = dataSets.get(i);
if (!dataSet.isVisible() || !dataSet.isDrawCirclesEnabled() ||
dataSet.getEntryCount() == 0)
continue;
mCirclePaintInner.setColor(dataSet.getCircleHoleColor());
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
mXBounds.set(mChart, dataSet);
float circleRadius = dataSet.getCircleRadius();
float circleHoleRadius = dataSet.getCircleHoleRadius();
boolean drawCircleHole = dataSet.isDrawCircleHoleEnabled() &&
circleHoleRadius < circleRadius &&
circleHoleRadius > 0.f;
boolean drawTransparentCircleHole = drawCircleHole &&
dataSet.getCircleHoleColor() == ColorTemplate.COLOR_NONE;
DataSetImageCache imageCache;
if (mImageCaches.containsKey(dataSet)) {
imageCache = mImageCaches.get(dataSet);
} else {
imageCache = new DataSetImageCache();
mImageCaches.put(dataSet, imageCache);
}
boolean changeRequired = imageCache.init(dataSet);
// only fill the cache with new bitmaps if a change is required
if (changeRequired) {
imageCache.fill(dataSet, drawCircleHole, drawTransparentCircleHole);
}
int boundsRangeCount = mXBounds.range + mXBounds.min;
for (int j = mXBounds.min; j <= boundsRangeCount; j++) {
Entry e = dataSet.getEntryForIndex(j);
if (e == null) break;
mCirclesBuffer[0] = e.getX();
mCirclesBuffer[1] = e.getY() * phaseY;
trans.pointValuesToPixel(mCirclesBuffer);
if (!mViewPortHandler.isInBoundsRight(mCirclesBuffer[0]))
break;
if (!mViewPortHandler.isInBoundsLeft(mCirclesBuffer[0]) ||
!mViewPortHandler.isInBoundsY(mCirclesBuffer[1]))
continue;
// Bitmap circleBitmap = imageCache.getBitmap(j);
Bitmap circleBitmap = dataSet.getCircleBitmap();
if (circleBitmap != null) {
c.drawBitmap(circleBitmap, mCirclesBuffer[0] - circleBitmap.getWidth() / 2, mCirclesBuffer[1] - circleBitmap.getHeight() / 2, mRenderPaint);
}
}
}
}
@Override
public void drawHighlighted(Canvas c, Highlight[] indices) {
LineData lineData = mChart.getLineData();
for (Highlight high : indices) {
ILineDataSet set = lineData.getDataSetByIndex(high.getDataSetIndex());
if (set == null || !set.isHighlightEnabled())
continue;
Entry e = set.getEntryForXValue(high.getX());
if (!isInBoundsX(e, set))
continue;
MPPointD pix = mChart.getTransformer(set.getAxisDependency()).getPixelForValues(e.getX(), e.getY() * mAnimator
.getPhaseY());
high.setDraw((float) pix.x, (float) pix.y);
// draw the lines
drawHighlightLines(c, (float) pix.x, (float) pix.y, set);
}
}
public void setBitmapConfig(Bitmap.Config config) {
mBitmapConfig = config;
releaseBitmap();
}
public Bitmap.Config getBitmapConfig() {
return mBitmapConfig;
}
public void releaseBitmap() {
if (mBitmapCanvas != null) {
mBitmapCanvas.setBitmap(null);
mBitmapCanvas = null;
}
if (mDrawBitmap != null) {
mDrawBitmap.get().recycle();
mDrawBitmap.clear();
mDrawBitmap = null;
}
}
private class DataSetImageCache {
private Path mCirclePathBuffer = new Path();
private Bitmap[] circleBitmaps;
protected boolean init(ILineDataSet set) {
int size = set.getCircleColorCount();
boolean changeRequired = false;
if (circleBitmaps == null) {
circleBitmaps = new Bitmap[size];
changeRequired = true;
} else if (circleBitmaps.length != size) {
circleBitmaps = new Bitmap[size];
changeRequired = true;
}
return changeRequired;
}
protected void fill(ILineDataSet set, boolean drawCircleHole, boolean drawTransparentCircleHole) {
int colorCount = set.getCircleColorCount();
float circleRadius = set.getCircleRadius();
float circleHoleRadius = set.getCircleHoleRadius();
for (int i = 0; i < colorCount; i++) {
Bitmap.Config conf = Bitmap.Config.ARGB_4444;
Bitmap circleBitmap = Bitmap.createBitmap((int) (circleRadius * 2.1), (int) (circleRadius * 2.1), conf);
Canvas canvas = new Canvas(circleBitmap);
circleBitmaps[i] = circleBitmap;
mRenderPaint.setColor(set.getCircleColor(i));
if (drawTransparentCircleHole) {
// Begin path for circle with hole
mCirclePathBuffer.reset();
mCirclePathBuffer.addCircle(
circleRadius,
circleRadius,
circleRadius,
Path.Direction.CW);
// Cut hole in path
mCirclePathBuffer.addCircle(
circleRadius,
circleRadius,
circleHoleRadius,
Path.Direction.CCW);
// Fill in-between
canvas.drawPath(mCirclePathBuffer, mRenderPaint);
} else {
canvas.drawCircle(
circleRadius,
circleRadius,
circleRadius,
mRenderPaint);
if (drawCircleHole) {
canvas.drawCircle(
circleRadius,
circleRadius,
circleHoleRadius,
mCirclePaintInner);
}
}
}
}
protected Bitmap getBitmap(int index) {
return circleBitmaps[index % circleBitmaps.length];
}
}
}