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);
}
}
}
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();
}
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;
}
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);
}
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);
}
}
Aggregations