blob: 07f130ecbd109705db8bfb404d268daf2944791f [file] [log] [blame]
package com.github.mikephil.charting;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.util.AttributeSet;
import java.util.ArrayList;
public class LineChart extends BarLineChartBase {
/** the radius of the circle-shaped value indicators */
protected float mCircleSize = 4f;
/** the width of the drawn data lines */
protected float mLineWidth = 1f;
/** the width of the highlighning line */
protected float mHighlightWidth = 3f;
/** if true, the data will also be drawn filled */
protected boolean mDrawFilled = false;
/** if true, drawing circles is enabled */
protected boolean mDrawCircles = true;
/** paint for the lines of the chart */
protected Paint mLinePaint;
/** paint for the filled are (if enabled) below the chart line */
protected Paint mFilledPaint;
/** paint for the outer circle of the value indicators */
protected Paint mCirclePaintOuter;
/** paint for the inner circle of the value indicators */
protected Paint mCirclePaintInner;
public LineChart(Context context) {
super(context);
}
public LineChart(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LineChart(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void init() {
super.init();
mCircleSize = Utils.convertDpToPixel(mCircleSize);
mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLinePaint.setStrokeWidth(mLineWidth);
mLinePaint.setStyle(Paint.Style.STROKE);
mLinePaint.setColor(mColorDarkBlue);
// mLinePaint.setColor(mDrawColor);
mFilledPaint = new Paint();
mFilledPaint.setStyle(Paint.Style.FILL);
mFilledPaint.setColor(mColorDarkBlue);
mFilledPaint.setAlpha(130); // alpha ~55%
mCirclePaintOuter = new Paint(Paint.ANTI_ALIAS_FLAG);
// mCirclePaint.setStrokeWidth(5f);
mCirclePaintOuter.setStyle(Paint.Style.FILL);
mCirclePaintOuter.setColor(mColorDarkBlue);
mCirclePaintInner = new Paint(Paint.ANTI_ALIAS_FLAG);
mCirclePaintInner.setStyle(Paint.Style.FILL);
mCirclePaintInner.setColor(Color.WHITE);
mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mHighlightPaint.setStyle(Paint.Style.STROKE);
mHighlightPaint.setStrokeWidth(2f);
mHighlightPaint.setColor(Color.rgb(255, 187, 115));
}
@Override
protected void prepareDataPaints(ColorTemplate ct) {
if (ct == null)
return;
mDrawPaints = new Paint[ct.getColors().size()];
for (int i = 0; i < ct.getColors().size(); i++) {
mDrawPaints[i] = new Paint(Paint.ANTI_ALIAS_FLAG);
mDrawPaints[i].setStrokeWidth(mLineWidth);
mDrawPaints[i].setStyle(Style.STROKE);
mDrawPaints[i].setColor(ct.getColors().get(i));
}
}
@Override
protected void drawHighlights() {
// if there are values to highlight and highlighnting is enabled, do it
if (mHighlightEnabled && valuesToHighlight()) {
for (int i = 0; i < mIndicesToHightlight.length; i++) {
// RectF highlight = new RectF(mIndicesToHightlight[i] -
// mHighlightWidth / 2,
// mYChartMax, mIndicesToHightlight[i] + mHighlightWidth / 2,
// mYChartMin);
// transformRect(highlight);
// mDrawCanvas.drawRect(highlight, mHighlightPaint);
int index = mIndicesToHightlight[i];
// check outofbounds
if (index < mYVals.size() && index >= 0) {
float[] pts = new float[] {
index, mYChartMax, index, mYChartMin,
0, mYVals.get(index).getVal(), mDeltaX, mYVals.get(index).getVal()
};
transformPointArray(pts);
// draw the highlight lines
mDrawCanvas.drawLines(pts, mHighlightPaint);
}
}
}
}
/**
* draws the given y values to the screen
*/
@Override
protected void drawData() {
Path p = new Path();
p.moveTo(0, mYVals.get(0).getVal());
for (int x = 1; x < mYVals.size(); x++) {
p.lineTo(x, mYVals.get(x).getVal());
}
transformPath(p);
mDrawCanvas.drawPath(p, mLinePaint);
// if data is drawn filled
if (mDrawFilled) {
Path filled = new Path();
filled.moveTo(0, mYVals.get(0).getVal());
// create a new path
for (int x = 1; x < mYVals.size(); x++) {
filled.lineTo(x, mYVals.get(x).getVal());
}
// close up
filled.lineTo(mXVals.size() - 1, mYChartMin);
filled.lineTo(0f, mYChartMin);
filled.close();
transformPath(filled);
mDrawCanvas.drawPath(filled, mFilledPaint);
}
}
@Override
protected void drawValues() {
// if values are drawn
if (mDrawYValues && mYVals.size() < mMaxVisibleCount * mScaleX) {
float[] valuePoints = new float[mYVals.size() * 2];
for (int i = 0; i < valuePoints.length; i += 2) {
valuePoints[i] = i / 2;
valuePoints[i + 1] = mYVals.get(i / 2).getVal();
}
transformPointArray(valuePoints);
for (int i = 0; i < valuePoints.length; i += 2) {
if (mDrawUnitInChart) {
mDrawCanvas.drawText(
mFormatValue.format(mYVals.get(i / 2).getVal()) + mUnit,
valuePoints[i], valuePoints[i + 1] - 12, mValuePaint);
} else {
mDrawCanvas.drawText(
mFormatValue.format(mYVals.get(i / 2).getVal()),
valuePoints[i], valuePoints[i + 1] - 12, mValuePaint);
}
}
}
}
/**
* draws the circle value indicators
*/
@Override
protected void drawAdditional() {
// if drawing circles is enabled
if (mDrawCircles) {
float[] positions = new float[mYVals.size() * 2];
for (int i = 0; i < positions.length; i += 2) {
positions[i] = i / 2;
positions[i + 1] = mYVals.get(i / 2).getVal();
}
transformPointArray(positions);
for (int i = 0; i < positions.length; i += 2) {
mDrawCanvas.drawCircle(positions[i], positions[i + 1], mCircleSize,
mCirclePaintOuter);
mDrawCanvas.drawCircle(positions[i], positions[i + 1], mCircleSize / 2,
mCirclePaintInner);
}
}
}
/**
* set this to true to enable the drawing of circle indicators
*
* @param enabled
*/
public void setDrawCircles(boolean enabled) {
this.mDrawCircles = enabled;
}
/**
* returns true if drawing circles is enabled, false if not
*
* @return
*/
public boolean isDrawCirclesEnabled() {
return mDrawCircles;
}
/**
* sets the size (radius) of the circle shpaed value indicators, default
* size = 4f
*
* @param size
*/
public void setCircleSize(float size) {
mCircleSize = Utils.convertDpToPixel(size);
}
/**
* returns the circlesize
*
* @param size
*/
public float getCircleSize(float size) {
return Utils.convertPixelsToDp(mCircleSize);
}
/**
* set if the chartdata should be drawn as a line or filled default = line /
* default = false, disabling this will give up to 20% performance boost on
* large datasets
*
* @param filled
*/
public void setDrawFilled(boolean filled) {
mDrawFilled = filled;
}
/**
* returns true if filled drawing is enabled, false if not
*
* @return
*/
public boolean isDrawFilledEnabled() {
return mDrawFilled;
}
/**
* set the line width of the chart (min = 0.5f, max = 10f); default 1f NOTE:
* thinner line == better performance, thicker line == worse performance
*
* @param width
*/
public void setLineWidth(float width) {
if (width < 0.5f)
width = 0.5f;
if (width > 10.0f)
width = 10.0f;
mLineWidth = width;
mLinePaint.setStrokeWidth(mLineWidth);
}
/**
* returns the width of the drawn chart line
*
* @return
*/
public float getLineWidth() {
return mLineWidth;
}
/**
* sets the color for the line paint
*
* @param color
*/
public void setLineColor(int color) {
mLinePaint.setColor(color);
}
/**
* sets the color for the outer circle paint
* @param color
*/
public void setCircleColor(int color) {
mCirclePaintOuter.setColor(color);
}
/**
* sets the color for the fill-paint
*
* @param color
*/
public void setFillColor(int color) {
mFilledPaint.setColor(color);
}
/**
* set the width of the highlightning lines, default 3f
*
* @param width
*/
public void setHighlightLineWidth(float width) {
mHighlightWidth = width;
}
/**
* returns the width of the highlightning line, default 3f
*
* @return
*/
public float getHighlightLineWidth() {
return mHighlightWidth;
}
@Override
public void setPaint(Paint p, int which) {
super.setPaint(p, which);
switch (which) {
case PAINT_FILLED:
mFilledPaint = p;
break;
case PAINT_LINE:
mLinePaint = p;
break;
case PAINT_CIRCLES_INNER:
mCirclePaintInner = p;
break;
case PAINT_CIRCLES_OUTER:
mCirclePaintOuter = p;
break;
case PAINT_HIGHLIGHT_LINE:
mHighlightPaint = p;
break;
}
}
}