Search in sources :

Example 1 with IValueFormatter

use of com.github.mikephil.charting.formatter.IValueFormatter in project MPAndroidChart by PhilJay.

the class PieChartRenderer method drawValues.

@Override
public void drawValues(Canvas c) {
    MPPointF center = mChart.getCenterCircleBox();
    // get whole the radius
    float radius = mChart.getRadius();
    float rotationAngle = mChart.getRotationAngle();
    float[] drawAngles = mChart.getDrawAngles();
    float[] absoluteAngles = mChart.getAbsoluteAngles();
    float phaseX = mAnimator.getPhaseX();
    float phaseY = mAnimator.getPhaseY();
    final float holeRadiusPercent = mChart.getHoleRadius() / 100.f;
    float labelRadiusOffset = radius / 10f * 3.6f;
    if (mChart.isDrawHoleEnabled()) {
        labelRadiusOffset = (radius - (radius * holeRadiusPercent)) / 2f;
    }
    final float labelRadius = radius - labelRadiusOffset;
    PieData data = mChart.getData();
    List<IPieDataSet> dataSets = data.getDataSets();
    float yValueSum = data.getYValueSum();
    boolean drawEntryLabels = mChart.isDrawEntryLabelsEnabled();
    float angle;
    int xIndex = 0;
    c.save();
    float offset = Utils.convertDpToPixel(5.f);
    for (int i = 0; i < dataSets.size(); i++) {
        IPieDataSet dataSet = dataSets.get(i);
        final boolean drawValues = dataSet.isDrawValuesEnabled();
        if (!drawValues && !drawEntryLabels)
            continue;
        final PieDataSet.ValuePosition xValuePosition = dataSet.getXValuePosition();
        final PieDataSet.ValuePosition yValuePosition = dataSet.getYValuePosition();
        // apply the text-styling defined by the DataSet
        applyValueTextStyle(dataSet);
        float lineHeight = Utils.calcTextHeight(mValuePaint, "Q") + Utils.convertDpToPixel(4f);
        IValueFormatter formatter = dataSet.getValueFormatter();
        int entryCount = dataSet.getEntryCount();
        mValueLinePaint.setColor(dataSet.getValueLineColor());
        mValueLinePaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getValueLineWidth()));
        final float sliceSpace = getSliceSpace(dataSet);
        MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
        iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
        iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
        for (int j = 0; j < entryCount; j++) {
            PieEntry entry = dataSet.getEntryForIndex(j);
            if (xIndex == 0)
                angle = 0.f;
            else
                angle = absoluteAngles[xIndex - 1] * phaseX;
            final float sliceAngle = drawAngles[xIndex];
            final float sliceSpaceMiddleAngle = sliceSpace / (Utils.FDEG2RAD * labelRadius);
            // offset needed to center the drawn text in the slice
            final float angleOffset = (sliceAngle - sliceSpaceMiddleAngle / 2.f) / 2.f;
            angle = angle + angleOffset;
            final float transformedAngle = rotationAngle + angle * phaseY;
            float value = mChart.isUsePercentValuesEnabled() ? entry.getY() / yValueSum * 100f : entry.getY();
            final float sliceXBase = (float) Math.cos(transformedAngle * Utils.FDEG2RAD);
            final float sliceYBase = (float) Math.sin(transformedAngle * Utils.FDEG2RAD);
            final boolean drawXOutside = drawEntryLabels && xValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
            final boolean drawYOutside = drawValues && yValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
            final boolean drawXInside = drawEntryLabels && xValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
            final boolean drawYInside = drawValues && yValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
            if (drawXOutside || drawYOutside) {
                final float valueLineLength1 = dataSet.getValueLinePart1Length();
                final float valueLineLength2 = dataSet.getValueLinePart2Length();
                final float valueLinePart1OffsetPercentage = dataSet.getValueLinePart1OffsetPercentage() / 100.f;
                float pt2x, pt2y;
                float labelPtx, labelPty;
                float line1Radius;
                if (mChart.isDrawHoleEnabled())
                    line1Radius = (radius - (radius * holeRadiusPercent)) * valueLinePart1OffsetPercentage + (radius * holeRadiusPercent);
                else
                    line1Radius = radius * valueLinePart1OffsetPercentage;
                final float polyline2Width = dataSet.isValueLineVariableLength() ? labelRadius * valueLineLength2 * (float) Math.abs(Math.sin(transformedAngle * Utils.FDEG2RAD)) : labelRadius * valueLineLength2;
                final float pt0x = line1Radius * sliceXBase + center.x;
                final float pt0y = line1Radius * sliceYBase + center.y;
                final float pt1x = labelRadius * (1 + valueLineLength1) * sliceXBase + center.x;
                final float pt1y = labelRadius * (1 + valueLineLength1) * sliceYBase + center.y;
                if (transformedAngle % 360.0 >= 90.0 && transformedAngle % 360.0 <= 270.0) {
                    pt2x = pt1x - polyline2Width;
                    pt2y = pt1y;
                    mValuePaint.setTextAlign(Align.RIGHT);
                    if (drawXOutside)
                        mEntryLabelsPaint.setTextAlign(Align.RIGHT);
                    labelPtx = pt2x - offset;
                    labelPty = pt2y;
                } else {
                    pt2x = pt1x + polyline2Width;
                    pt2y = pt1y;
                    mValuePaint.setTextAlign(Align.LEFT);
                    if (drawXOutside)
                        mEntryLabelsPaint.setTextAlign(Align.LEFT);
                    labelPtx = pt2x + offset;
                    labelPty = pt2y;
                }
                if (dataSet.getValueLineColor() != ColorTemplate.COLOR_NONE) {
                    c.drawLine(pt0x, pt0y, pt1x, pt1y, mValueLinePaint);
                    c.drawLine(pt1x, pt1y, pt2x, pt2y, mValueLinePaint);
                }
                // draw everything, depending on settings
                if (drawXOutside && drawYOutside) {
                    drawValue(c, formatter, value, entry, 0, labelPtx, labelPty, dataSet.getValueTextColor(j));
                    if (j < data.getEntryCount() && entry.getLabel() != null) {
                        drawEntryLabel(c, entry.getLabel(), labelPtx, labelPty + lineHeight);
                    }
                } else if (drawXOutside) {
                    if (j < data.getEntryCount() && entry.getLabel() != null) {
                        drawEntryLabel(c, entry.getLabel(), labelPtx, labelPty + lineHeight / 2.f);
                    }
                } else if (drawYOutside) {
                    drawValue(c, formatter, value, entry, 0, labelPtx, labelPty + lineHeight / 2.f, dataSet.getValueTextColor(j));
                }
            }
            if (drawXInside || drawYInside) {
                // calculate the text position
                float x = labelRadius * sliceXBase + center.x;
                float y = labelRadius * sliceYBase + center.y;
                mValuePaint.setTextAlign(Align.CENTER);
                // draw everything, depending on settings
                if (drawXInside && drawYInside) {
                    drawValue(c, formatter, value, entry, 0, x, y, dataSet.getValueTextColor(j));
                    if (j < data.getEntryCount() && entry.getLabel() != null) {
                        drawEntryLabel(c, entry.getLabel(), x, y + lineHeight);
                    }
                } else if (drawXInside) {
                    if (j < data.getEntryCount() && entry.getLabel() != null) {
                        drawEntryLabel(c, entry.getLabel(), x, y + lineHeight / 2f);
                    }
                } else if (drawYInside) {
                    drawValue(c, formatter, value, entry, 0, x, y + lineHeight / 2f, dataSet.getValueTextColor(j));
                }
            }
            if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
                Drawable icon = entry.getIcon();
                float x = (labelRadius + iconsOffset.y) * sliceXBase + center.x;
                float y = (labelRadius + iconsOffset.y) * sliceYBase + center.y;
                y += iconsOffset.x;
                Utils.drawImage(c, icon, (int) x, (int) y, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
            }
            xIndex++;
        }
        MPPointF.recycleInstance(iconsOffset);
    }
    MPPointF.recycleInstance(center);
    c.restore();
}
Also used : PieEntry(com.github.mikephil.charting.data.PieEntry) IPieDataSet(com.github.mikephil.charting.interfaces.datasets.IPieDataSet) MPPointF(com.github.mikephil.charting.utils.MPPointF) Drawable(android.graphics.drawable.Drawable) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) IValueFormatter(com.github.mikephil.charting.formatter.IValueFormatter) IPieDataSet(com.github.mikephil.charting.interfaces.datasets.IPieDataSet) PieDataSet(com.github.mikephil.charting.data.PieDataSet) PieData(com.github.mikephil.charting.data.PieData)

Example 2 with IValueFormatter

use of com.github.mikephil.charting.formatter.IValueFormatter in project MPAndroidChart by PhilJay.

the class HorizontalBarChartRenderer method drawValues.

@Override
public void drawValues(Canvas c) {
    // if values are drawn
    if (isDrawingValuesAllowed(mChart)) {
        List<IBarDataSet> dataSets = mChart.getBarData().getDataSets();
        final float valueOffsetPlus = Utils.convertDpToPixel(5f);
        float posOffset = 0f;
        float negOffset = 0f;
        final boolean drawValueAboveBar = mChart.isDrawValueAboveBarEnabled();
        for (int i = 0; i < mChart.getBarData().getDataSetCount(); i++) {
            IBarDataSet dataSet = dataSets.get(i);
            if (!shouldDrawValues(dataSet))
                continue;
            boolean isInverted = mChart.isInverted(dataSet.getAxisDependency());
            // apply the text-styling defined by the DataSet
            applyValueTextStyle(dataSet);
            final float halfTextHeight = Utils.calcTextHeight(mValuePaint, "10") / 2f;
            IValueFormatter formatter = dataSet.getValueFormatter();
            // get the buffer
            BarBuffer buffer = mBarBuffers[i];
            final float phaseY = mAnimator.getPhaseY();
            MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
            iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
            iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
            // if only single values are drawn (sum)
            if (!dataSet.isStacked()) {
                for (int j = 0; j < buffer.buffer.length * mAnimator.getPhaseX(); j += 4) {
                    float y = (buffer.buffer[j + 1] + buffer.buffer[j + 3]) / 2f;
                    if (!mViewPortHandler.isInBoundsTop(buffer.buffer[j + 1]))
                        break;
                    if (!mViewPortHandler.isInBoundsX(buffer.buffer[j]))
                        continue;
                    if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[j + 1]))
                        continue;
                    BarEntry entry = dataSet.getEntryForIndex(j / 4);
                    float val = entry.getY();
                    String formattedValue = formatter.getFormattedValue(val, entry, i, mViewPortHandler);
                    // calculate the correct offset depending on the draw position of the value
                    float valueTextWidth = Utils.calcTextWidth(mValuePaint, formattedValue);
                    posOffset = (drawValueAboveBar ? valueOffsetPlus : -(valueTextWidth + valueOffsetPlus));
                    negOffset = (drawValueAboveBar ? -(valueTextWidth + valueOffsetPlus) : valueOffsetPlus);
                    if (isInverted) {
                        posOffset = -posOffset - valueTextWidth;
                        negOffset = -negOffset - valueTextWidth;
                    }
                    if (dataSet.isDrawValuesEnabled()) {
                        drawValue(c, formattedValue, buffer.buffer[j + 2] + (val >= 0 ? posOffset : negOffset), y + halfTextHeight, dataSet.getValueTextColor(j / 2));
                    }
                    if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
                        Drawable icon = entry.getIcon();
                        float px = buffer.buffer[j + 2] + (val >= 0 ? posOffset : negOffset);
                        float py = y;
                        px += iconsOffset.x;
                        py += iconsOffset.y;
                        Utils.drawImage(c, icon, (int) px, (int) py, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
                    }
                }
            // if each value of a potential stack should be drawn
            } else {
                Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
                int bufferIndex = 0;
                int index = 0;
                while (index < dataSet.getEntryCount() * mAnimator.getPhaseX()) {
                    BarEntry entry = dataSet.getEntryForIndex(index);
                    int color = dataSet.getValueTextColor(index);
                    float[] vals = entry.getYVals();
                    // in between
                    if (vals == null) {
                        if (!mViewPortHandler.isInBoundsTop(buffer.buffer[bufferIndex + 1]))
                            break;
                        if (!mViewPortHandler.isInBoundsX(buffer.buffer[bufferIndex]))
                            continue;
                        if (!mViewPortHandler.isInBoundsBottom(buffer.buffer[bufferIndex + 1]))
                            continue;
                        float val = entry.getY();
                        String formattedValue = formatter.getFormattedValue(val, entry, i, mViewPortHandler);
                        // calculate the correct offset depending on the draw position of the value
                        float valueTextWidth = Utils.calcTextWidth(mValuePaint, formattedValue);
                        posOffset = (drawValueAboveBar ? valueOffsetPlus : -(valueTextWidth + valueOffsetPlus));
                        negOffset = (drawValueAboveBar ? -(valueTextWidth + valueOffsetPlus) : valueOffsetPlus);
                        if (isInverted) {
                            posOffset = -posOffset - valueTextWidth;
                            negOffset = -negOffset - valueTextWidth;
                        }
                        if (dataSet.isDrawValuesEnabled()) {
                            drawValue(c, formattedValue, buffer.buffer[bufferIndex + 2] + (entry.getY() >= 0 ? posOffset : negOffset), buffer.buffer[bufferIndex + 1] + halfTextHeight, color);
                        }
                        if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
                            Drawable icon = entry.getIcon();
                            float px = buffer.buffer[bufferIndex + 2] + (entry.getY() >= 0 ? posOffset : negOffset);
                            float py = buffer.buffer[bufferIndex + 1];
                            px += iconsOffset.x;
                            py += iconsOffset.y;
                            Utils.drawImage(c, icon, (int) px, (int) py, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
                        }
                    } else {
                        float[] transformed = new float[vals.length * 2];
                        float posY = 0f;
                        float negY = -entry.getNegativeSum();
                        for (int k = 0, idx = 0; k < transformed.length; k += 2, idx++) {
                            float value = vals[idx];
                            float y;
                            if (value == 0.0f && (posY == 0.0f || negY == 0.0f)) {
                                // Take care of the situation of a 0.0 value, which overlaps a non-zero bar
                                y = value;
                            } else if (value >= 0.0f) {
                                posY += value;
                                y = posY;
                            } else {
                                y = negY;
                                negY -= value;
                            }
                            transformed[k] = y * phaseY;
                        }
                        trans.pointValuesToPixel(transformed);
                        for (int k = 0; k < transformed.length; k += 2) {
                            final float val = vals[k / 2];
                            String formattedValue = formatter.getFormattedValue(val, entry, i, mViewPortHandler);
                            // calculate the correct offset depending on the draw position of the value
                            float valueTextWidth = Utils.calcTextWidth(mValuePaint, formattedValue);
                            posOffset = (drawValueAboveBar ? valueOffsetPlus : -(valueTextWidth + valueOffsetPlus));
                            negOffset = (drawValueAboveBar ? -(valueTextWidth + valueOffsetPlus) : valueOffsetPlus);
                            if (isInverted) {
                                posOffset = -posOffset - valueTextWidth;
                                negOffset = -negOffset - valueTextWidth;
                            }
                            final boolean drawBelow = (val == 0.0f && negY == 0.0f && posY > 0.0f) || val < 0.0f;
                            float x = transformed[k] + (drawBelow ? negOffset : posOffset);
                            float y = (buffer.buffer[bufferIndex + 1] + buffer.buffer[bufferIndex + 3]) / 2f;
                            if (!mViewPortHandler.isInBoundsTop(y))
                                break;
                            if (!mViewPortHandler.isInBoundsX(x))
                                continue;
                            if (!mViewPortHandler.isInBoundsBottom(y))
                                continue;
                            if (dataSet.isDrawValuesEnabled()) {
                                drawValue(c, formattedValue, x, y + halfTextHeight, color);
                            }
                            if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
                                Drawable icon = entry.getIcon();
                                Utils.drawImage(c, icon, (int) (x + iconsOffset.x), (int) (y + iconsOffset.y), icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
                            }
                        }
                    }
                    bufferIndex = vals == null ? bufferIndex + 4 : bufferIndex + 4 * vals.length;
                    index++;
                }
            }
            MPPointF.recycleInstance(iconsOffset);
        }
    }
}
Also used : Transformer(com.github.mikephil.charting.utils.Transformer) MPPointF(com.github.mikephil.charting.utils.MPPointF) Drawable(android.graphics.drawable.Drawable) BarEntry(com.github.mikephil.charting.data.BarEntry) BarBuffer(com.github.mikephil.charting.buffer.BarBuffer) HorizontalBarBuffer(com.github.mikephil.charting.buffer.HorizontalBarBuffer) IValueFormatter(com.github.mikephil.charting.formatter.IValueFormatter) IBarDataSet(com.github.mikephil.charting.interfaces.datasets.IBarDataSet)

Example 3 with IValueFormatter

use of com.github.mikephil.charting.formatter.IValueFormatter in project Gadgetbridge by Freeyourgadget.

the class SleepChartFragment method refreshSleepAmounts.

private MySleepChartsData refreshSleepAmounts(GBDevice mGBDevice, List<? extends ActivitySample> samples) {
    ActivityAnalysis analysis = new ActivityAnalysis();
    ActivityAmounts amounts = analysis.calculateActivityAmounts(samples);
    PieData data = new PieData();
    List<PieEntry> entries = new ArrayList<>();
    List<Integer> colors = new ArrayList<>();
    //        int index = 0;
    long totalSeconds = 0;
    for (ActivityAmount amount : amounts.getAmounts()) {
        if ((amount.getActivityKind() & ActivityKind.TYPE_SLEEP) != 0) {
            long value = amount.getTotalSeconds();
            totalSeconds += value;
            //                entries.add(new PieEntry(value, index++));
            entries.add(new PieEntry(value, amount.getName(getActivity())));
            colors.add(getColorFor(amount.getActivityKind()));
        //                data.addXValue(amount.getName(getActivity()));
        }
    }
    String totalSleep = DateTimeUtils.formatDurationHoursMinutes(totalSeconds, TimeUnit.SECONDS);
    PieDataSet set = new PieDataSet(entries, "");
    set.setValueFormatter(new IValueFormatter() {

        @Override
        public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
            return DateTimeUtils.formatDurationHoursMinutes((long) value, TimeUnit.SECONDS);
        }
    });
    set.setColors(colors);
    data.setDataSet(set);
    //setupLegend(pieChart);
    return new MySleepChartsData(totalSleep, data);
}
Also used : PieEntry(com.github.mikephil.charting.data.PieEntry) ArrayList(java.util.ArrayList) ActivityAmount(nodomain.freeyourgadget.gadgetbridge.model.ActivityAmount) ViewPortHandler(com.github.mikephil.charting.utils.ViewPortHandler) Entry(com.github.mikephil.charting.data.Entry) LegendEntry(com.github.mikephil.charting.components.LegendEntry) PieEntry(com.github.mikephil.charting.data.PieEntry) IValueFormatter(com.github.mikephil.charting.formatter.IValueFormatter) ActivityAmounts(nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts) PieDataSet(com.github.mikephil.charting.data.PieDataSet) PieData(com.github.mikephil.charting.data.PieData)

Aggregations

IValueFormatter (com.github.mikephil.charting.formatter.IValueFormatter)3 Drawable (android.graphics.drawable.Drawable)2 PieData (com.github.mikephil.charting.data.PieData)2 PieDataSet (com.github.mikephil.charting.data.PieDataSet)2 PieEntry (com.github.mikephil.charting.data.PieEntry)2 MPPointF (com.github.mikephil.charting.utils.MPPointF)2 Paint (android.graphics.Paint)1 TextPaint (android.text.TextPaint)1 BarBuffer (com.github.mikephil.charting.buffer.BarBuffer)1 HorizontalBarBuffer (com.github.mikephil.charting.buffer.HorizontalBarBuffer)1 LegendEntry (com.github.mikephil.charting.components.LegendEntry)1 BarEntry (com.github.mikephil.charting.data.BarEntry)1 Entry (com.github.mikephil.charting.data.Entry)1 IBarDataSet (com.github.mikephil.charting.interfaces.datasets.IBarDataSet)1 IPieDataSet (com.github.mikephil.charting.interfaces.datasets.IPieDataSet)1 Transformer (com.github.mikephil.charting.utils.Transformer)1 ViewPortHandler (com.github.mikephil.charting.utils.ViewPortHandler)1 ArrayList (java.util.ArrayList)1 ActivityAmount (nodomain.freeyourgadget.gadgetbridge.model.ActivityAmount)1 ActivityAmounts (nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts)1