/**
* This file is part of GraphView.
*
* GraphView is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GraphView is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GraphView. If not, see <http://www.gnu.org/licenses/lgpl.html>.
*
* Copyright Jonas Gehring
*/
package com.jjoe64.graphview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Paint.Align;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import com.jjoe64.graphview.GraphViewSeries.GraphViewSeriesStyle;
/**
* Line Graph View. This draws a line chart.
*/
public class LineGraphView extends GraphView {
private final Paint paintBackground;
private boolean drawBackground;
private boolean drawDataPoints;
private float dataPointsRadius = 10f;
public LineGraphView(Context context, AttributeSet attrs) {
super(context, attrs);
paintBackground = new Paint();
paintBackground.setColor(Color.rgb(20, 40, 60));
paintBackground.setStrokeWidth(4);
paintBackground.setAlpha(128);
}
public LineGraphView(Context context, String title) {
super(context, title);
paintBackground = new Paint();
paintBackground.setColor(Color.rgb(20, 40, 60));
paintBackground.setStrokeWidth(4);
paintBackground.setAlpha(128);
}
@Override
public void drawSeries(Canvas canvas, GraphViewDataInterface[] values,
float graphwidth, float graphheight, float border, double minX,
double minY, double diffX, double diffY, float horstart,
GraphViewSeriesStyle style) {
float colwidth = graphwidth / (values.length);
float offset = 0;
// draw background
double lastEndY = 0;
double lastEndX = 0;
// draw data
paint.setStrokeWidth(style.thickness);
paint.setColor(style.color);
Path bgPath = null;
if (drawBackground) {
bgPath = new Path();
}
lastEndY = 0;
lastEndX = 0;
float firstX = 0;
// draw data
for (int i = 0; i < values.length; i++) {
float valY = (float) (values[i].getY() - minY);
float ratY = (float) (valY / diffY);
float y = graphheight * ratY;
// hook for value dependent color
if (style.getValueDependentColor() != null) {
paint.setColor(style.getValueDependentColor().get(values[i]));
} else {
paint.setColor(style.color);
}
float left = (i * colwidth) + horstart - offset;
float right = ((i * colwidth) + horstart) + (colwidth - 1) - offset;
double x = (left + right)/2;
if (i > 0) {
float startX = (float) lastEndX;
float startY = (float) (border - lastEndY) + graphheight;
float endX = (float) x;
float endY = (float) (border - y) + graphheight;
// draw data point
if (drawDataPoints) {
// fix: last value was not drawn. Draw here now the end
// values
canvas.drawCircle(endX, endY, dataPointsRadius, paint);
}
canvas.drawLine(startX, startY, endX, endY, paint);
if (bgPath != null) {
if (i == 1) {
firstX = startX;
bgPath.moveTo(startX, startY);
}
bgPath.lineTo(endX, endY);
}
} else if (drawDataPoints) {
// fix: last value not drawn as datapoint. Draw first point
// here, and then on every step the end values (above)
float first_X = (float) x;
float first_Y = (float) (border - y) + graphheight;
canvas.drawCircle(first_X, first_Y, dataPointsRadius, paint);
}
lastEndY = y;
lastEndX = x;
}
// //draw data
// for (int i = 0; i < values.length; i++) {
// double valY = values[i].getY() - minY;
// double ratY = valY / diffY;
// double y = graphheight * ratY;
//
// double valX = values[i].getX() - minX;
// double ratX = valX / diffX;
// double x = graphwidth * ratX;
//
// if (i > 0) {
// float startX = (float) lastEndX + (horstart + 1);
// float startY = (float) (border - lastEndY) + graphheight;
// float endX = (float) x + (horstart + 1);
// float endY = (float) (border - y) + graphheight;
//
// // draw data point
// if (drawDataPoints) {
// // fix: last value was not drawn. Draw here now the end
// // values
// canvas.drawCircle(endX, endY, dataPointsRadius, paint);
// canvas.drawText(endX +"", endX, endY, paint);
// }
//
// canvas.drawLine(startX, startY, endX, endY, paint);
// if (bgPath != null) {
// if (i == 1) {
// firstX = startX;
// bgPath.moveTo(startX, startY);
// }
// bgPath.lineTo(endX, endY);
// }
// } else if (drawDataPoints) {
// // fix: last value not drawn as datapoint. Draw first point
// // here, and then on every step the end values (above)
// float first_X = (float) x + (horstart + 1);
// float first_Y = (float) (border - y) + graphheight;
// canvas.drawCircle(first_X, first_Y, dataPointsRadius, paint);
// }
// lastEndY = y;
// lastEndX = x;
// }
if (bgPath != null) {
// end / close path
bgPath.lineTo((float) lastEndX, graphheight + border);
bgPath.lineTo(firstX, graphheight + border);
bgPath.close();
canvas.drawPath(bgPath, paintBackground);
}
}
public int getBackgroundColor() {
return paintBackground.getColor();
}
public float getDataPointsRadius() {
return dataPointsRadius;
}
public boolean getDrawBackground() {
return drawBackground;
}
public boolean getDrawDataPoints() {
return drawDataPoints;
}
/**
* sets the background color for the series. This is not the background
* color of the whole graph.
*
* @see #setDrawBackground(boolean)
*/
@Override
public void setBackgroundColor(int color) {
paintBackground.setColor(color);
}
/**
* sets the radius of the circles at the data points.
*
* @see #setDrawDataPoints(boolean)
* @param dataPointsRadius
*/
public void setDataPointsRadius(float dataPointsRadius) {
this.dataPointsRadius = dataPointsRadius;
}
/**
* @param drawBackground
* true for a light blue background under the graph line
* @see #setBackgroundColor(int)
*/
public void setDrawBackground(boolean drawBackground) {
this.drawBackground = drawBackground;
}
/**
* You can set the flag to let the GraphView draw circles at the data points
*
* @see #setDataPointsRadius(float)
* @param drawDataPoints
*/
public void setDrawDataPoints(boolean drawDataPoints) {
this.drawDataPoints = drawDataPoints;
}
}