use of com.jjoe64.graphview.RectD in project GraphView by appsthatmatter.
the class BarGraphSeries method draw.
/**
* draws the bars on the canvas
*
* @param graphView corresponding graphview
* @param canvas canvas
* @param isSecondScale whether we are plotting the second scale or not
*/
@Override
public void draw(GraphView graphView, Canvas canvas, boolean isSecondScale) {
mPaint.setTextAlign(Paint.Align.CENTER);
if (mValuesOnTopSize == 0) {
mValuesOnTopSize = graphView.getGridLabelRenderer().getTextSize();
}
mPaint.setTextSize(mValuesOnTopSize);
resetDataPoints();
// get data
double maxX = graphView.getViewport().getMaxX(false);
double minX = graphView.getViewport().getMinX(false);
double maxY;
double minY;
if (isSecondScale) {
maxY = graphView.getSecondScale().getMaxY(false);
minY = graphView.getSecondScale().getMinY(false);
} else {
maxY = graphView.getViewport().getMaxY(false);
minY = graphView.getViewport().getMinY(false);
}
// Iterate through all bar graph series
// so we know how wide to make our bar,
// and in what position to put it in
int numBarSeries = 0;
int currentSeriesOrder = 0;
int numValues = 0;
boolean isCurrentSeries;
SortedSet<Double> xVals = new TreeSet<Double>();
for (Series inspectedSeries : graphView.getSeries()) {
if (inspectedSeries instanceof BarGraphSeries) {
isCurrentSeries = (inspectedSeries == this);
if (isCurrentSeries) {
currentSeriesOrder = numBarSeries;
}
numBarSeries++;
// calculate the number of slots for bars based on the minimum distance between
// x coordinates in the series. This is divided into the range to find
// the placement and width of bar slots
// (sections of the x axis for each bar or set of bars)
// TODO: Move this somewhere more general and cache it, so we don't recalculate it for each series
Iterator<E> curValues = inspectedSeries.getValues(minX, maxX);
if (curValues.hasNext()) {
xVals.add(curValues.next().getX());
if (isCurrentSeries) {
numValues++;
}
while (curValues.hasNext()) {
xVals.add(curValues.next().getX());
if (isCurrentSeries) {
numValues++;
}
}
}
}
}
if (numValues == 0) {
return;
}
double minGap = 0;
if (mDataWidth > 0.0) {
minGap = mDataWidth;
} else {
Double lastVal = null;
for (Double curVal : xVals) {
if (lastVal != null) {
double curGap = Math.abs(curVal - lastVal);
if (minGap == 0 || (curGap > 0 && curGap < minGap)) {
minGap = curGap;
}
}
lastVal = curVal;
}
}
int numBarSlots = (minGap == 0) ? 1 : (int) Math.round((maxX - minX) / minGap) + 1;
Iterator<E> values = getValues(minX, maxX);
// Calculate the overall bar slot width - this includes all bars across
// all series, and any spacing between sets of bars
int barSlotWidth = numBarSlots == 1 ? graphView.getGraphContentWidth() : graphView.getGraphContentWidth() / (numBarSlots - 1);
// Total spacing (both sides) between sets of bars
double spacing = Math.min(barSlotWidth * mSpacing / 100, barSlotWidth * 0.98f);
// Width of an individual bar
double barWidth = (barSlotWidth - spacing) / numBarSeries;
// Offset from the center of a given bar to start drawing
double offset = barSlotWidth / 2;
double diffY = maxY - minY;
double diffX = maxX - minX;
double contentHeight = graphView.getGraphContentHeight();
double contentWidth = graphView.getGraphContentWidth();
double contentLeft = graphView.getGraphContentLeft();
double contentTop = graphView.getGraphContentTop();
// draw data
int i = 0;
while (values.hasNext()) {
E value = values.next();
double valY = value.getY() - minY;
double ratY = valY / diffY;
double y = contentHeight * ratY;
double valY0 = 0 - minY;
double ratY0 = valY0 / diffY;
double y0 = contentHeight * ratY0;
double valueX = value.getX();
double valX = valueX - minX;
double ratX = valX / diffX;
double x = contentWidth * ratX;
// hook for value dependent color
if (getValueDependentColor() != null) {
mPaint.setColor(getValueDependentColor().get(value));
} else {
mPaint.setColor(getColor());
}
double left = x + contentLeft - offset + spacing / 2 + currentSeriesOrder * barWidth;
double top = (contentTop - y) + contentHeight;
double right = left + barWidth;
double bottom = (contentTop - y0) + contentHeight - (graphView.getGridLabelRenderer().isHighlightZeroLines() ? 4 : 1);
boolean reverse = top > bottom;
if (mAnimated) {
if ((Double.isNaN(mLastAnimatedValue) || mLastAnimatedValue < valueX)) {
long currentTime = System.currentTimeMillis();
if (mAnimationStart == 0) {
// start animation
mAnimationStart = currentTime;
mAnimationStartFrameNo = 0;
} else {
// anti-lag: wait a few frames
if (mAnimationStartFrameNo < 15) {
// second time
mAnimationStart = currentTime;
mAnimationStartFrameNo++;
}
}
float timeFactor = (float) (currentTime - mAnimationStart) / ANIMATION_DURATION;
float factor = mAnimationInterpolator.getInterpolation(timeFactor);
if (timeFactor <= 1.0) {
double barHeight = bottom - top;
barHeight = barHeight * factor;
top = bottom - barHeight;
ViewCompat.postInvalidateOnAnimation(graphView);
} else {
// animation finished
mLastAnimatedValue = valueX;
}
}
}
if (reverse) {
double tmp = top;
top = bottom + (graphView.getGridLabelRenderer().isHighlightZeroLines() ? 4 : 1);
bottom = tmp;
}
// overdraw
left = Math.max(left, contentLeft);
right = Math.min(right, contentLeft + contentWidth);
bottom = Math.min(bottom, contentTop + contentHeight);
top = Math.max(top, contentTop);
mDataPoints.put(new RectD(left, top, right, bottom), value);
Paint p;
if (mCustomPaint != null) {
p = mCustomPaint;
} else {
p = mPaint;
}
canvas.drawRect((float) left, (float) top, (float) right, (float) bottom, p);
// set values on top of graph
if (mDrawValuesOnTop) {
if (reverse) {
top = bottom + mValuesOnTopSize + 4;
if (top > contentTop + contentHeight)
top = contentTop + contentHeight;
} else {
top -= 4;
if (top <= contentTop)
top += contentTop + 4;
}
mPaint.setColor(mValuesOnTopColor);
canvas.drawText(graphView.getGridLabelRenderer().getLabelFormatter().formatLabel(value.getY(), false), (float) (left + right) / 2, (float) top, mPaint);
}
i++;
}
}