@Override public void renderAxisLabels(Canvas c) { if (!mYAxis.isEnabled() || !mYAxis.isDrawLabelsEnabled()) return; mAxisLabelPaint.setTypeface(mYAxis.getTypeface()); mAxisLabelPaint.setTextSize(mYAxis.getTextSize()); mAxisLabelPaint.setColor(mYAxis.getTextColor()); PointF center = mChart.getCenterOffsets(); float factor = mChart.getFactor(); int labelCount = mYAxis.mEntryCount; for (int j = 0; j < labelCount; j++) { if (j == labelCount - 1 && mYAxis.isDrawTopYLabelEntryEnabled() == false) break; float r = (mYAxis.mEntries[j] - mYAxis.mAxisMinimum) * factor; PointF p = Utils.getPosition(center, r, mChart.getRotationAngle()); String label = mYAxis.getFormattedLabel(j); c.drawText(label, p.x + 10, p.y, mAxisLabelPaint); } }
public PieChartRenderer(PieChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler) { super(animator, viewPortHandler); mChart = chart; mHolePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mHolePaint.setColor(Color.WHITE); mHolePaint.setStyle(Style.FILL); mTransparentCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mTransparentCirclePaint.setColor(Color.WHITE); mTransparentCirclePaint.setStyle(Style.FILL); mTransparentCirclePaint.setAlpha(105); mCenterTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); mCenterTextPaint.setColor(Color.BLACK); mCenterTextPaint.setTextSize(Utils.convertDpToPixel(12f)); // mCenterTextPaint.setTextAlign(Align.CENTER); mValuePaint.setTextSize(Utils.convertDpToPixel(13f)); mValuePaint.setColor(Color.WHITE); mValuePaint.setTextAlign(Align.CENTER); }
@Override public void renderLimitLines(Canvas c) { List<LimitLine> limitLines = mYAxis.getLimitLines(); if (limitLines == null) return; float sliceangle = mChart.getSliceAngle(); // calculate the factor that is needed for transforming the value to // pixels float factor = mChart.getFactor(); PointF center = mChart.getCenterOffsets(); for (int i = 0; i < limitLines.size(); i++) { LimitLine l = limitLines.get(i); if (!l.isEnabled()) continue; mLimitLinePaint.setColor(l.getLineColor()); mLimitLinePaint.setPathEffect(l.getDashPathEffect()); mLimitLinePaint.setStrokeWidth(l.getLineWidth()); float r = (l.getLimit() - mChart.getYChartMin()) * factor; Path limitPath = new Path(); for (int j = 0; j < mChart.getData().getXValCount(); j++) { PointF p = Utils.getPosition(center, r, sliceangle * j + mChart.getRotationAngle()); if (j == 0) limitPath.moveTo(p.x, p.y); else limitPath.lineTo(p.x, p.y); } limitPath.close(); c.drawPath(limitPath, mLimitLinePaint); } }
@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++; } } }
@Override protected void computeAxisValues(float min, float max) { float yMin = min; float yMax = max; int labelCount = mYAxis.getLabelCount(); double range = Math.abs(yMax - yMin); if (labelCount == 0 || range <= 0) { mYAxis.mEntries = new float[] {}; mYAxis.mEntryCount = 0; return; } double rawInterval = range / labelCount; double interval = Utils.roundToNextSignificant(rawInterval); double intervalMagnitude = Math.pow(10, (int) Math.log10(interval)); int intervalSigDigit = (int) (interval / intervalMagnitude); if (intervalSigDigit > 5) { // Use one order of magnitude higher, to avoid intervals like 0.9 or // 90 interval = Math.floor(10 * intervalMagnitude); } // force label count if (mYAxis.isForceLabelsEnabled()) { float step = (float) range / (float) (labelCount - 1); mYAxis.mEntryCount = labelCount; if (mYAxis.mEntries.length < labelCount) { // Ensure stops contains at least numStops elements. mYAxis.mEntries = new float[labelCount]; } float v = min; for (int i = 0; i < labelCount; i++) { mYAxis.mEntries[i] = v; v += step; } // no forced count } else { // if the labels should only show min and max if (mYAxis.isShowOnlyMinMaxEnabled()) { mYAxis.mEntryCount = 2; mYAxis.mEntries = new float[2]; mYAxis.mEntries[0] = yMin; mYAxis.mEntries[1] = yMax; } else { final double rawCount = yMin / interval; double first = rawCount < 0.0 ? Math.floor(rawCount) * interval : Math.ceil(rawCount) * interval; if (first < yMin && mYAxis.isStartAtZeroEnabled()) { // Force the first label to be at the 0 (or smallest negative value) first = yMin; } if (first == 0.0) // Fix for IEEE negative zero case (Where value == -0.0, and 0.0 == -0.0) first = 0.0; double last = Utils.nextUp(Math.floor(yMax / interval) * interval); double f; int i; int n = 0; for (f = first; f <= last; f += interval) { ++n; } if (Float.isNaN(mYAxis.getAxisMaxValue())) n += 1; mYAxis.mEntryCount = n; if (mYAxis.mEntries.length < n) { // Ensure stops contains at least numStops elements. mYAxis.mEntries = new float[n]; } for (f = first, i = 0; i < n; f += interval, ++i) { mYAxis.mEntries[i] = (float) f; } } } if (interval < 1) { mYAxis.mDecimals = (int) Math.ceil(-Math.log10(interval)); } else { mYAxis.mDecimals = 0; } if (!mYAxis.isStartAtZeroEnabled() && mYAxis.mEntries[0] < yMin) { // If startAtZero is disabled, and the first label is lower that the axis minimum, // Then adjust the axis minimum mYAxis.mAxisMinimum = mYAxis.mEntries[0]; } mYAxis.mAxisMaximum = mYAxis.mEntries[mYAxis.mEntryCount - 1]; mYAxis.mAxisRange = Math.abs(mYAxis.mAxisMaximum - mYAxis.mAxisMinimum); }