protected void drawHole(Canvas c) { if (mChart.isDrawHoleEnabled()) { float transparentCircleRadius = mChart.getTransparentCircleRadius(); float holeRadius = mChart.getHoleRadius(); float radius = mChart.getRadius(); PointF center = mChart.getCenterCircleBox(); // only draw the circle if it can be seen (not covered by the hole) if (transparentCircleRadius > holeRadius) { // get original alpha int alpha = mTransparentCirclePaint.getAlpha(); mTransparentCirclePaint.setAlpha( (int) ((float) alpha * mAnimator.getPhaseX() * mAnimator.getPhaseY())); // draw the transparent-circle mBitmapCanvas.drawCircle( center.x, center.y, radius / 100 * transparentCircleRadius, mTransparentCirclePaint); // reset alpha mTransparentCirclePaint.setAlpha(alpha); } // draw the hole-circle mBitmapCanvas.drawCircle(center.x, center.y, radius / 100 * holeRadius, mHolePaint); } }
protected void drawDataSet(Canvas c, PieDataSet dataSet) { float angle = mChart.getRotationAngle(); List<Entry> entries = dataSet.getYVals(); float[] drawAngles = mChart.getDrawAngles(); for (int j = 0; j < entries.size(); j++) { float newangle = drawAngles[j]; float sliceSpace = dataSet.getSliceSpace(); Entry e = entries.get(j); // draw only if the value is greater than zero if ((Math.abs(e.getVal()) > 0.000001)) { if (!mChart.needsHighlight(e.getXIndex(), mChart.getData().getIndexOfDataSet(dataSet))) { mRenderPaint.setColor(dataSet.getColor(j)); mBitmapCanvas.drawArc( mChart.getCircleBox(), (angle + sliceSpace / 2f) * mAnimator.getPhaseY(), (newangle - sliceSpace / 2f) * mAnimator.getPhaseY(), true, mRenderPaint); } } angle += newangle * mAnimator.getPhaseX(); } }
protected void drawCenterText(Canvas c) { SpannableString centerText = mChart.getCenterText(); if (mChart.isDrawCenterTextEnabled() && centerText != null) { PointF center = mChart.getCenterCircleBox(); float innerRadius = mChart.isDrawHoleEnabled() && mChart.isHoleTransparent() ? mChart.getRadius() * (mChart.getHoleRadius() / 100f) : mChart.getRadius(); RectF holeRect = mRectBuffer[0]; holeRect.left = center.x - innerRadius; holeRect.top = center.y - innerRadius; holeRect.right = center.x + innerRadius; holeRect.bottom = center.y + innerRadius; RectF boundingRect = mRectBuffer[1]; boundingRect.set(holeRect); float radiusPercent = mChart.getCenterTextRadiusPercent(); if (radiusPercent > 0.0) { boundingRect.inset( (boundingRect.width() - boundingRect.width() * radiusPercent) / 2.f, (boundingRect.height() - boundingRect.height() * radiusPercent) / 2.f); } if (!centerText.equals(mCenterTextLastValue) || !boundingRect.equals(mCenterTextLastBounds)) { // Next time we won't recalculate StaticLayout... mCenterTextLastBounds.set(boundingRect); mCenterTextLastValue = centerText; float width = mCenterTextLastBounds.width(); // If width is 0, it will crash. Always have a minimum of 1 mCenterTextLayout = new StaticLayout( centerText, 0, centerText.length(), mCenterTextPaint, (int) Math.max(Math.ceil(width), 1.f), Layout.Alignment.ALIGN_CENTER, 1.f, 0.f, false); } float layoutHeight = mCenterTextLayout.getHeight(); c.save(); c.translate( boundingRect.left, boundingRect.top + (boundingRect.height() - layoutHeight) / 2.f); mCenterTextLayout.draw(c); c.restore(); } }
@Override public void drawHighlighted(Canvas c, Highlight[] indices) { float rotationAngle = mChart.getRotationAngle(); float angle = 0f; float[] drawAngles = mChart.getDrawAngles(); float[] absoluteAngles = mChart.getAbsoluteAngles(); for (int i = 0; i < indices.length; i++) { // get the index to highlight int xIndex = indices[i].getXIndex(); if (xIndex >= drawAngles.length) continue; PieDataSet set = mChart.getData().getDataSetByIndex(indices[i].getDataSetIndex()); if (set == null || !set.isHighlightEnabled()) continue; if (xIndex == 0) angle = rotationAngle; else angle = rotationAngle + absoluteAngles[xIndex - 1]; angle *= mAnimator.getPhaseY(); float sliceDegrees = drawAngles[xIndex]; float shift = set.getSelectionShift(); RectF circleBox = mChart.getCircleBox(); RectF highlighted = new RectF( circleBox.left - shift, circleBox.top - shift, circleBox.right + shift, circleBox.bottom + shift); mRenderPaint.setColor(set.getColor(xIndex)); // redefine the rect that contains the arc so that the // highlighted pie is not cut off mBitmapCanvas.drawArc( highlighted, angle + set.getSliceSpace() / 2f, sliceDegrees * mAnimator.getPhaseY() - set.getSliceSpace() / 2f, true, mRenderPaint); } }
@Override public void drawData(Canvas c) { int width = (int) mViewPortHandler.getChartWidth(); int height = (int) mViewPortHandler.getChartHeight(); if (mDrawBitmap == null || (mDrawBitmap.getWidth() != width) || (mDrawBitmap.getHeight() != height)) { if (width > 0 && height > 0) { mDrawBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444); mBitmapCanvas = new Canvas(mDrawBitmap); } else return; } mDrawBitmap.eraseColor(Color.TRANSPARENT); PieData pieData = mChart.getData(); for (PieDataSet set : pieData.getDataSets()) { if (set.isVisible() && set.getEntryCount() > 0) drawDataSet(c, set); } }
protected void drawRoundedSlices(Canvas c) { if (!mChart.isDrawRoundedSlicesEnabled()) return; PieDataSet dataSet = mChart.getData().getDataSet(); if (!dataSet.isVisible()) return; PointF center = mChart.getCenterCircleBox(); float r = mChart.getRadius(); // calculate the radius of the "slice-circle" float circleRadius = (r - (r * mChart.getHoleRadius() / 100f)) / 2f; List<Entry> entries = dataSet.getYVals(); float[] drawAngles = mChart.getDrawAngles(); float angle = mChart.getRotationAngle(); for (int j = 0; j < entries.size(); j++) { float newangle = drawAngles[j]; Entry e = entries.get(j); // draw only if the value is greater than zero if ((Math.abs(e.getVal()) > 0.000001)) { float x = (float) ((r - circleRadius) * Math.cos(Math.toRadians((angle + newangle) * mAnimator.getPhaseY())) + center.x); float y = (float) ((r - circleRadius) * Math.sin(Math.toRadians((angle + newangle) * mAnimator.getPhaseY())) + center.y); mRenderPaint.setColor(dataSet.getColor(j)); mBitmapCanvas.drawCircle(x, y, circleRadius, mRenderPaint); } angle += newangle * mAnimator.getPhaseX(); } }
@Override public void drawValues(Canvas c) { PointF center = mChart.getCenterCircleBox(); // get whole the radius float r = mChart.getRadius(); float rotationAngle = mChart.getRotationAngle(); float[] drawAngles = mChart.getDrawAngles(); float[] absoluteAngles = mChart.getAbsoluteAngles(); float off = r / 10f * 3.6f; if (mChart.isDrawHoleEnabled()) { off = (r - (r / 100f * mChart.getHoleRadius())) / 2f; } r -= off; // offset to keep things inside the chart PieData data = mChart.getData(); List<PieDataSet> dataSets = data.getDataSets(); boolean drawXVals = mChart.isDrawSliceTextEnabled(); int cnt = 0; for (int i = 0; i < dataSets.size(); i++) { PieDataSet dataSet = dataSets.get(i); if (!dataSet.isDrawValuesEnabled() && !drawXVals) continue; // apply the text-styling defined by the DataSet applyValueTextStyle(dataSet); float lineHeight = Utils.calcTextHeight(mValuePaint, "Q") + Utils.convertDpToPixel(4f); List<Entry> entries = dataSet.getYVals(); for (int j = 0, maxEntry = Math.min((int) Math.ceil(entries.size() * mAnimator.getPhaseX()), entries.size()); j < maxEntry; j++) { Entry entry = entries.get(j); // offset needed to center the drawn text in the slice float offset = drawAngles[cnt] / 2; // calculate the text position float x = (float) (r * Math.cos( Math.toRadians( (rotationAngle + absoluteAngles[cnt] - offset) * mAnimator.getPhaseY())) + center.x); float y = (float) (r * Math.sin( Math.toRadians( (rotationAngle + absoluteAngles[cnt] - offset) * mAnimator.getPhaseY())) + center.y); float value = mChart.isUsePercentValuesEnabled() ? entry.getVal() / data.getYValueSum() * 100f : entry.getVal(); ValueFormatter formatter = dataSet.getValueFormatter(); boolean drawYVals = dataSet.isDrawValuesEnabled(); // draw everything, depending on settings if (drawXVals && drawYVals) { drawValue(c, formatter, value, entry, 0, x, y); if (j < data.getXValCount()) c.drawText(data.getXVals().get(j), x, y + lineHeight, mValuePaint); } else if (drawXVals && !drawYVals) { if (j < data.getXValCount()) c.drawText(data.getXVals().get(j), x, y + lineHeight / 2f, mValuePaint); } else if (!drawXVals && drawYVals) { drawValue(c, formatter, value, entry, 0, x, y + lineHeight / 2f); } cnt++; } } }