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