Search in sources :

Example 11 with IBarDataSet

use of com.github.mikephil.charting.interfaces.datasets.IBarDataSet 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 12 with IBarDataSet

use of com.github.mikephil.charting.interfaces.datasets.IBarDataSet in project MPAndroidChart by PhilJay.

the class BarData method groupBars.

/**
     * Groups all BarDataSet objects this data object holds together by modifying the x-value of their entries.
     * Previously set x-values of entries will be overwritten. Leaves space between bars and groups as specified
     * by the parameters.
     * Do not forget to call notifyDataSetChanged() on your BarChart object after calling this method.
     *
     * @param fromX      the starting point on the x-axis where the grouping should begin
     * @param groupSpace the space between groups of bars in values (not pixels) e.g. 0.8f for bar width 1f
     * @param barSpace   the space between individual bars in values (not pixels) e.g. 0.1f for bar width 1f
     */
public void groupBars(float fromX, float groupSpace, float barSpace) {
    int setCount = mDataSets.size();
    if (setCount <= 1) {
        throw new RuntimeException("BarData needs to hold at least 2 BarDataSets to allow grouping.");
    }
    IBarDataSet max = getMaxEntryCountSet();
    int maxEntryCount = max.getEntryCount();
    float groupSpaceWidthHalf = groupSpace / 2f;
    float barSpaceHalf = barSpace / 2f;
    float barWidthHalf = mBarWidth / 2f;
    float interval = getGroupWidth(groupSpace, barSpace);
    for (int i = 0; i < maxEntryCount; i++) {
        float start = fromX;
        fromX += groupSpaceWidthHalf;
        for (IBarDataSet set : mDataSets) {
            fromX += barSpaceHalf;
            fromX += barWidthHalf;
            if (i < set.getEntryCount()) {
                BarEntry entry = set.getEntryForIndex(i);
                if (entry != null) {
                    entry.setX(fromX);
                }
            }
            fromX += barWidthHalf;
            fromX += barSpaceHalf;
        }
        fromX += groupSpaceWidthHalf;
        float end = fromX;
        float innerInterval = end - start;
        float diff = interval - innerInterval;
        // correct rounding errors
        if (diff > 0 || diff < 0) {
            fromX += diff;
        }
    }
    notifyDataChanged();
}
Also used : IBarDataSet(com.github.mikephil.charting.interfaces.datasets.IBarDataSet)

Example 13 with IBarDataSet

use of com.github.mikephil.charting.interfaces.datasets.IBarDataSet in project MPAndroidChart by PhilJay.

the class HorizontalBarHighlighter method getHighlight.

@Override
public Highlight getHighlight(float x, float y) {
    BarData barData = mChart.getBarData();
    MPPointD pos = getValsForTouch(y, x);
    Highlight high = getHighlightForX((float) pos.y, y, x);
    if (high == null)
        return null;
    IBarDataSet set = barData.getDataSetByIndex(high.getDataSetIndex());
    if (set.isStacked()) {
        return getStackedHighlight(high, set, (float) pos.y, (float) pos.x);
    }
    MPPointD.recycleInstance(pos);
    return high;
}
Also used : BarData(com.github.mikephil.charting.data.BarData) IBarDataSet(com.github.mikephil.charting.interfaces.datasets.IBarDataSet) MPPointD(com.github.mikephil.charting.utils.MPPointD)

Example 14 with IBarDataSet

use of com.github.mikephil.charting.interfaces.datasets.IBarDataSet in project Gadgetbridge by Freeyourgadget.

the class AbstractChartFragment method refresh.

protected DefaultChartsData<CombinedData> refresh(GBDevice gbDevice, List<? extends ActivitySample> samples) {
    //        Calendar cal = GregorianCalendar.getInstance();
    //        cal.clear();
    TimestampTranslation tsTranslation = new TimestampTranslation();
    //        Date date;
    //        String dateStringFrom = "";
    //        String dateStringTo = "";
    //        ArrayList<String> xLabels = null;
    LOG.info("" + getTitle() + ": number of samples:" + samples.size());
    CombinedData combinedData;
    if (samples.size() > 1) {
        boolean annotate = true;
        boolean use_steps_as_movement;
        int last_type = ActivityKind.TYPE_UNKNOWN;
        int numEntries = samples.size();
        List<BarEntry> activityEntries = new ArrayList<>(numEntries);
        boolean hr = supportsHeartrate(gbDevice);
        List<Entry> heartrateEntries = hr ? new ArrayList<Entry>(numEntries) : null;
        // this is kinda inefficient...
        List<Integer> colors = new ArrayList<>(numEntries);
        int lastHrSampleIndex = -1;
        for (int i = 0; i < numEntries; i++) {
            ActivitySample sample = samples.get(i);
            int type = sample.getKind();
            int ts = tsTranslation.shorten(sample.getTimestamp());
            //                System.out.println(ts);
            //                ts = i;
            // determine start and end dates
            //                if (i == 0) {
            //                    cal.setTimeInMillis(ts * 1000L); // make sure it's converted to long
            //                    date = cal.getTime();
            //                    dateStringFrom = dateFormat.format(date);
            //                } else if (i == samples.size() - 1) {
            //                    cal.setTimeInMillis(ts * 1000L); // same here
            //                    date = cal.getTime();
            //                    dateStringTo = dateFormat.format(date);
            //                }
            float movement = sample.getIntensity();
            float value = movement;
            switch(type) {
                case ActivityKind.TYPE_DEEP_SLEEP:
                    value += SleepUtils.Y_VALUE_DEEP_SLEEP;
                    colors.add(akDeepSleep.color);
                    break;
                case ActivityKind.TYPE_LIGHT_SLEEP:
                    colors.add(akLightSleep.color);
                    break;
                case ActivityKind.TYPE_NOT_WORN:
                    //a small value, just to show something on the graphs
                    value = SleepUtils.Y_VALUE_DEEP_SLEEP;
                    colors.add(akNotWorn.color);
                    break;
                default:
                    //                        short steps = sample.getSteps();
                    //                        if (use_steps_as_movement && steps != 0) {
                    //                            // I'm not sure using steps for this is actually a good idea
                    //                            movement = steps;
                    //                        }
                    //                        value = ((float) movement) / movement_divisor;
                    colors.add(akActivity.color);
            }
            activityEntries.add(createBarEntry(value, ts));
            if (hr && isValidHeartRateValue(sample.getHeartRate())) {
                if (lastHrSampleIndex > -1 && ts - lastHrSampleIndex > 60 * HeartRateUtils.MAX_HR_MEASUREMENTS_GAP_MINUTES) {
                    heartrateEntries.add(createLineEntry(0, lastHrSampleIndex + 1));
                    heartrateEntries.add(createLineEntry(0, ts - 1));
                }
                heartrateEntries.add(createLineEntry(sample.getHeartRate(), ts));
                lastHrSampleIndex = ts;
            }
            String xLabel = "";
            if (annotate) {
            //                    cal.setTimeInMillis((ts + tsOffset) * 1000L);
            //                    date = cal.getTime();
            //                    String dateString = annotationDateFormat.format(date);
            //                    xLabel = dateString;
            //                    if (last_type != type) {
            //                        if (isSleep(last_type) && !isSleep(type)) {
            //                            // woken up
            //                            LimitLine line = new LimitLine(i, dateString);
            //                            line.enableDashedLine(8, 8, 0);
            //                            line.setTextColor(Color.WHITE);
            //                            line.setTextSize(15);
            //                            chart.getXAxis().addLimitLine(line);
            //                        } else if (!isSleep(last_type) && isSleep(type)) {
            //                            // fallen asleep
            //                            LimitLine line = new LimitLine(i, dateString);
            //                            line.enableDashedLine(8, 8, 0);
            //                            line.setTextSize(15);
            //                            line.setTextColor(Color.WHITE);
            //                            chart.getXAxis().addLimitLine(line);
            //                        }
            //                    }
            //                    last_type = type;
            }
        }
        BarDataSet activitySet = createActivitySet(activityEntries, colors, "Activity");
        // create a data object with the datasets
        //            combinedData = new CombinedData(xLabels);
        combinedData = new CombinedData();
        List<IBarDataSet> list = new ArrayList<>();
        list.add(activitySet);
        BarData barData = new BarData(list);
        barData.setBarWidth(100f);
        //            barData.setGroupSpace(0);
        combinedData.setData(barData);
        if (hr && heartrateEntries.size() > 0) {
            LineDataSet heartrateSet = createHeartrateSet(heartrateEntries, "Heart Rate");
            LineData lineData = new LineData(heartrateSet);
            combinedData.setData(lineData);
        }
    //            chart.setDescription(getString(R.string.sleep_activity_date_range, dateStringFrom, dateStringTo));
    //            chart.setDescriptionPosition(?, ?);
    } else {
        combinedData = new CombinedData();
    }
    IAxisValueFormatter xValueFormatter = new SampleXLabelFormatter(tsTranslation);
    return new DefaultChartsData(combinedData, xValueFormatter);
}
Also used : AbstractActivitySample(nodomain.freeyourgadget.gadgetbridge.entities.AbstractActivitySample) ActivitySample(nodomain.freeyourgadget.gadgetbridge.model.ActivitySample) BarDataSet(com.github.mikephil.charting.data.BarDataSet) IBarDataSet(com.github.mikephil.charting.interfaces.datasets.IBarDataSet) LineDataSet(com.github.mikephil.charting.data.LineDataSet) ArrayList(java.util.ArrayList) IAxisValueFormatter(com.github.mikephil.charting.formatter.IAxisValueFormatter) CombinedData(com.github.mikephil.charting.data.CombinedData) BarEntry(com.github.mikephil.charting.data.BarEntry) Entry(com.github.mikephil.charting.data.Entry) BarEntry(com.github.mikephil.charting.data.BarEntry) LineData(com.github.mikephil.charting.data.LineData) BarData(com.github.mikephil.charting.data.BarData) IBarDataSet(com.github.mikephil.charting.interfaces.datasets.IBarDataSet)

Example 15 with IBarDataSet

use of com.github.mikephil.charting.interfaces.datasets.IBarDataSet in project MPAndroidChart by PhilJay.

the class BarChartActivity method setData.

private void setData(int count, float range) {
    float start = 1f;
    ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
    for (int i = (int) start; i < start + count + 1; i++) {
        float mult = (range + 1);
        float val = (float) (Math.random() * mult);
        if (Math.random() * 100 < 25) {
            yVals1.add(new BarEntry(i, val, getResources().getDrawable(R.drawable.star)));
        } else {
            yVals1.add(new BarEntry(i, val));
        }
    }
    BarDataSet set1;
    if (mChart.getData() != null && mChart.getData().getDataSetCount() > 0) {
        set1 = (BarDataSet) mChart.getData().getDataSetByIndex(0);
        set1.setValues(yVals1);
        mChart.getData().notifyDataChanged();
        mChart.notifyDataSetChanged();
    } else {
        set1 = new BarDataSet(yVals1, "The year 2017");
        set1.setDrawIcons(false);
        set1.setColors(ColorTemplate.MATERIAL_COLORS);
        ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
        dataSets.add(set1);
        BarData data = new BarData(dataSets);
        data.setValueTextSize(10f);
        data.setValueTypeface(mTfLight);
        data.setBarWidth(0.9f);
        mChart.setData(data);
    }
}
Also used : BarDataSet(com.github.mikephil.charting.data.BarDataSet) IBarDataSet(com.github.mikephil.charting.interfaces.datasets.IBarDataSet) BarData(com.github.mikephil.charting.data.BarData) IBarDataSet(com.github.mikephil.charting.interfaces.datasets.IBarDataSet) ArrayList(java.util.ArrayList) BarEntry(com.github.mikephil.charting.data.BarEntry) SuppressLint(android.annotation.SuppressLint)

Aggregations

IBarDataSet (com.github.mikephil.charting.interfaces.datasets.IBarDataSet)22 BarData (com.github.mikephil.charting.data.BarData)16 BarEntry (com.github.mikephil.charting.data.BarEntry)11 ArrayList (java.util.ArrayList)11 BarDataSet (com.github.mikephil.charting.data.BarDataSet)8 Paint (android.graphics.Paint)3 BarBuffer (com.github.mikephil.charting.buffer.BarBuffer)3 RealmBarDataSet (com.github.mikephil.charting.data.realm.implementation.RealmBarDataSet)3 Transformer (com.github.mikephil.charting.utils.Transformer)3 SuppressLint (android.annotation.SuppressLint)2 RectF (android.graphics.RectF)2 Drawable (android.graphics.drawable.Drawable)2 HorizontalBarBuffer (com.github.mikephil.charting.buffer.HorizontalBarBuffer)2 LineData (com.github.mikephil.charting.data.LineData)2 IAxisValueFormatter (com.github.mikephil.charting.formatter.IAxisValueFormatter)2 MPPointD (com.github.mikephil.charting.utils.MPPointD)2 MPPointF (com.github.mikephil.charting.utils.MPPointF)2 RealmDemoData (com.xxmassdeveloper.mpchartexample.custom.RealmDemoData)2 Typeface (android.graphics.Typeface)1 BarChart (com.github.mikephil.charting.charts.BarChart)1