This commit is contained in:
coco
2026-07-03 15:56:07 +08:00
commit caef23209c
5767 changed files with 1004268 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
.gradle
/.idea/workspace.xml
.DS_Store
# built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
build/
# Local configuration file (sdk path, etc)
local.properties
# Eclipse project files
.classpath
.project
# Proguard folder generated by Eclipse
proguard/
# Intellij project files
*.iml
*.ipr
*.iws
.idea/
.settings/
+1
View File
@@ -0,0 +1 @@
/build
+59
View File
@@ -0,0 +1,59 @@
apply plugin: 'com.android.library'
ext {
bintrayRepo = 'maven'
bintrayName = 'AndroidCharts'
publishedGroupId = 'im.dacer'
libraryName = 'AndroidCharts'
artifact = 'AndroidCharts'
libraryDescription = 'An easy-to-use Android charts library with animation.'
siteUrl = '//github.com/HackPlan/AndroidCharts'
gitUrl = '//github.com/HackPlan/AndroidCharts'
libraryVersion = '1.0.4'
developerId = 'Dacer'
developerName = 'Ding Wenhao'
developerEmail = 'dacerfeedback@gmail.com'
licenseName = 'The MIT License (MIT)'
licenseUrl = '//opensource.org/licenses/MIT'
allLicenses = ["MIT"]
}
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
}
}
repositories {
mavenCentral()
}
android {
compileSdkVersion 25
buildToolsVersion "25.0.1"
defaultConfig {
minSdkVersion 14
targetSdkVersion 25
}
buildTypes {
release {
minifyEnabled false
proguardFile 'proguard-rules.txt'
proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
}
}
}
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
@@ -0,0 +1,8 @@
<manifest
package="im.dacer.androidcharts">
<application>
</application>
</manifest>
@@ -0,0 +1,209 @@
package im.dacer.androidcharts;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
/**
* Created by Dacer on 11/11/13.
*/
public class BarView extends View {
private final int MINI_BAR_WIDTH;
private final int BAR_SIDE_MARGIN;
private final int TEXT_TOP_MARGIN;
private final int TEXT_COLOR = Color.parseColor("#9B9A9B");
private final int BACKGROUND_COLOR = Color.parseColor("#F6F6F6");
private final int FOREGROUND_COLOR = Color.parseColor("#FC496D");
private ArrayList<Float> percentList;
private ArrayList<Float> targetPercentList;
private Paint textPaint;
private Paint bgPaint;
private Paint fgPaint;
private Rect rect;
private int barWidth;
private int bottomTextDescent;
private boolean autoSetWidth = true;
private int topMargin;
private int bottomTextHeight;
private ArrayList<String> bottomTextList = new ArrayList<String>();
private Runnable animator = new Runnable() {
@Override public void run() {
boolean needNewFrame = false;
for (int i = 0; i < targetPercentList.size(); i++) {
if (percentList.get(i) < targetPercentList.get(i)) {
percentList.set(i, percentList.get(i) + 0.02f);
needNewFrame = true;
} else if (percentList.get(i) > targetPercentList.get(i)) {
percentList.set(i, percentList.get(i) - 0.02f);
needNewFrame = true;
}
if (Math.abs(targetPercentList.get(i) - percentList.get(i)) < 0.02f) {
percentList.set(i, targetPercentList.get(i));
}
}
if (needNewFrame) {
postDelayed(this, 20);
}
invalidate();
}
};
public BarView(Context context) {
this(context, null);
}
public BarView(Context context, AttributeSet attrs) {
super(context, attrs);
bgPaint = new Paint();
bgPaint.setAntiAlias(true);
bgPaint.setColor(BACKGROUND_COLOR);
fgPaint = new Paint(bgPaint);
fgPaint.setColor(FOREGROUND_COLOR);
rect = new Rect();
topMargin = MyUtils.dip2px(context, 5);
int textSize = MyUtils.sp2px(context, 15);
barWidth = MyUtils.dip2px(context, 22);
MINI_BAR_WIDTH = MyUtils.dip2px(context, 22);
BAR_SIDE_MARGIN = MyUtils.dip2px(context, 22);
TEXT_TOP_MARGIN = MyUtils.dip2px(context, 5);
textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setColor(TEXT_COLOR);
textPaint.setTextSize(textSize);
textPaint.setTextAlign(Paint.Align.CENTER);
percentList = new ArrayList<Float>();
}
/**
* dataList will be reset when called is method.
*
* @param bottomStringList The String ArrayList in the bottom.
*/
public void setBottomTextList(ArrayList<String> bottomStringList) {
// this.dataList = null;
this.bottomTextList = bottomStringList;
Rect r = new Rect();
bottomTextDescent = 0;
barWidth = MINI_BAR_WIDTH;
for (String s : bottomTextList) {
textPaint.getTextBounds(s, 0, s.length(), r);
if (bottomTextHeight < r.height()) {
bottomTextHeight = r.height();
}
if (autoSetWidth && (barWidth < r.width())) {
barWidth = r.width();
}
if (bottomTextDescent < (Math.abs(r.bottom))) {
bottomTextDescent = Math.abs(r.bottom);
}
}
setMinimumWidth(2);
postInvalidate();
}
/**
* @param list The ArrayList of Integer with the range of [0-max].
*/
public void setDataList(ArrayList<Integer> list, int max) {
targetPercentList = new ArrayList<Float>();
if (max == 0) max = 1;
for (Integer integer : list) {
targetPercentList.add(1 - (float) integer / (float) max);
}
// Make sure percentList.size() == targetPercentList.size()
if (percentList.isEmpty() || percentList.size() < targetPercentList.size()) {
int temp = targetPercentList.size() - percentList.size();
for (int i = 0; i < temp; i++) {
percentList.add(1f);
}
} else if (percentList.size() > targetPercentList.size()) {
int temp = percentList.size() - targetPercentList.size();
for (int i = 0; i < temp; i++) {
percentList.remove(percentList.size() - 1);
}
}
setMinimumWidth(2);
removeCallbacks(animator);
post(animator);
}
@Override protected void onDraw(Canvas canvas) {
int i = 1;
if (percentList != null && !percentList.isEmpty()) {
for (Float f : percentList) {
rect.set(BAR_SIDE_MARGIN * i + barWidth * (i - 1), topMargin,
(BAR_SIDE_MARGIN + barWidth) * i,
getHeight() - bottomTextHeight - TEXT_TOP_MARGIN);
canvas.drawRect(rect, bgPaint);
/*rect.set(BAR_SIDE_MARGIN*i+barWidth*(i-1),
topMargin+(int)((getHeight()-topMargin)*percentList.get(i-1)),
(BAR_SIDE_MARGIN+barWidth)* i,
getHeight()-bottomTextHeight-TEXT_TOP_MARGIN);*/
/**
* The correct total height is "getHeight()-topMargin-bottomTextHeight-TEXT_TOP_MARGIN",not "getHeight()-topMargin".
* fix by zhenghuiy@gmail.com on 11/11/13.
*/
rect.set(BAR_SIDE_MARGIN * i + barWidth * (i - 1), topMargin + (int) ((getHeight()
- topMargin
- bottomTextHeight
- TEXT_TOP_MARGIN) * percentList.get(i - 1)),
(BAR_SIDE_MARGIN + barWidth) * i,
getHeight() - bottomTextHeight - TEXT_TOP_MARGIN);
canvas.drawRect(rect, fgPaint);
i++;
}
}
if (bottomTextList != null && !bottomTextList.isEmpty()) {
i = 1;
for (String s : bottomTextList) {
canvas.drawText(s, BAR_SIDE_MARGIN * i + barWidth * (i - 1) + barWidth / 2,
getHeight() - bottomTextDescent, textPaint);
i++;
}
}
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int mViewWidth = measureWidth(widthMeasureSpec);
int mViewHeight = measureHeight(heightMeasureSpec);
setMeasuredDimension(mViewWidth, mViewHeight);
}
private int measureWidth(int measureSpec) {
int preferred = 0;
if (bottomTextList != null) {
preferred = bottomTextList.size() * (barWidth + BAR_SIDE_MARGIN);
}
return getMeasurement(measureSpec, preferred);
}
private int measureHeight(int measureSpec) {
int preferred = 222;
return getMeasurement(measureSpec, preferred);
}
private int getMeasurement(int measureSpec, int preferred) {
int specSize = MeasureSpec.getSize(measureSpec);
int measurement;
switch (MeasureSpec.getMode(measureSpec)) {
case MeasureSpec.EXACTLY:
measurement = specSize;
break;
case MeasureSpec.AT_MOST:
measurement = Math.min(preferred, specSize);
break;
default:
measurement = preferred;
break;
}
return measurement;
}
}
@@ -0,0 +1,82 @@
package im.dacer.androidcharts;
/**
* Created by Dacer on 11/14/13.
*/
public class ClockPieHelper {
int velocity = 5;
private float start;
private float end;
private float targetStart;
private float targetEnd;
ClockPieHelper(float startDegree, float endDegree, ClockPieHelper targetPie) {
start = startDegree;
end = endDegree;
targetStart = targetPie.getStart();
targetEnd = targetPie.getEnd();
}
public ClockPieHelper(int startHour, int startMin, int endHour, int endMin) {
start = 270 + startHour * 15 + startMin * 15 / 60;
end = 270 + endHour * 15 + endMin * 15 / 60;
while (end < start) {
end += 360;
}
}
public ClockPieHelper(int startHour, int startMin, int startSec, int endHour, int endMin,
int endSec) {
start = 270 + startHour * 15 + startMin * 15 / 60 + startSec * 15 / 3600;
end = 270 + endHour * 15 + endMin * 15 / 60 + endSec * 15 / 3600;
while (end < start) {
end += 360;
}
}
ClockPieHelper setTarget(float targetStart, float targetEnd) {
this.targetStart = targetStart;
this.targetEnd = targetEnd;
return this;
}
ClockPieHelper setTarget(ClockPieHelper targetPie) {
targetStart = targetPie.getStart();
targetEnd = targetPie.getEnd();
return this;
}
boolean isAtRest() {
return (start == targetStart) && (end == targetEnd);
}
void update() {
start = updateSelf(start, targetStart, velocity);
end = updateSelf(end, targetEnd, velocity);
}
public float getSweep() {
return end - start;
}
public float getStart() {
return start;
}
public float getEnd() {
return end;
}
private float updateSelf(float origin, float target, int velocity) {
if (origin < target) {
origin += velocity;
} else if (origin > target) {
origin -= velocity;
}
if (Math.abs(target - origin) < velocity) {
origin = target;
}
return origin;
}
}
@@ -0,0 +1,187 @@
package im.dacer.androidcharts;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
/**
* Created by Dacer on 11/13/13.
*/
public class ClockPieView extends View {
private final int TEXT_COLOR = Color.parseColor("#9B9A9B");
private final int GRAY_COLOR = Color.parseColor("#D4D3D4");
private final int RED_COLOR = Color.argb(50, 255, 0, 51);
private Paint textPaint;
private Paint redPaint;
private Paint linePaint;
private Paint whitePaint;
private int mViewWidth;
private int mViewHeight;
private int textSize;
private int pieRadius;
private Point pieCenterPoint;
private Point tempPoint;
private Point tempPointRight;
private int lineLength;
private float leftTextWidth;
private float rightTextWidth;
private float topTextHeight;
private int lineThickness;
private RectF cirRect;
private Rect textRect;
private ArrayList<ClockPieHelper> pieArrayList = new ArrayList<ClockPieHelper>();
private Runnable animator = new Runnable() {
@Override public void run() {
boolean needNewFrame = false;
for (ClockPieHelper pie : pieArrayList) {
pie.update();
if (!pie.isAtRest()) {
needNewFrame = true;
}
}
if (needNewFrame) {
postDelayed(this, 10);
}
invalidate();
}
};
public ClockPieView(Context context) {
this(context, null);
}
public ClockPieView(Context context, AttributeSet attrs) {
super(context, attrs);
textSize = MyUtils.sp2px(context, 15);
lineThickness = MyUtils.dip2px(context, 1);
lineLength = MyUtils.dip2px(context, 10);
textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setColor(TEXT_COLOR);
textPaint.setTextSize(textSize);
textPaint.setTextAlign(Paint.Align.CENTER);
Paint.FontMetrics fm = new Paint.FontMetrics();
textPaint.getFontMetrics(fm);
textRect = new Rect();
textPaint.getTextBounds("18", 0, 1, textRect);
redPaint = new Paint(textPaint);
redPaint.setColor(RED_COLOR);
linePaint = new Paint(textPaint);
linePaint.setColor(GRAY_COLOR);
linePaint.setStrokeWidth(lineThickness);
whitePaint = new Paint(linePaint);
whitePaint.setColor(Color.WHITE);
tempPoint = new Point();
pieCenterPoint = new Point();
tempPointRight = new Point();
cirRect = new RectF();
leftTextWidth = textPaint.measureText("18");
rightTextWidth = textPaint.measureText("6");
topTextHeight = textRect.height();
}
public void setDate(ArrayList<ClockPieHelper> helperList) {
if (helperList != null && !helperList.isEmpty()) {
int pieSize = pieArrayList.isEmpty() ? 0 : pieArrayList.size();
for (int i = 0; i < helperList.size(); i++) {
if (i > pieSize - 1) {
// float mStart = helperList.get(i).getStart();
pieArrayList.add(new ClockPieHelper(0, 0, helperList.get(i)));
} else {
pieArrayList.set(i, pieArrayList.get(i).setTarget(helperList.get(i)));
}
}
int temp = pieArrayList.size() - helperList.size();
for (int i = 0; i < temp; i++) {
pieArrayList.remove(pieArrayList.size() - 1);
}
} else {
pieArrayList.clear();
}
removeCallbacks(animator);
post(animator);
}
@Override protected void onDraw(Canvas canvas) {
drawBackground(canvas);
if (pieArrayList != null) {
for (ClockPieHelper helper : pieArrayList) {
canvas.drawArc(cirRect, helper.getStart(), helper.getSweep(), true, redPaint);
}
}
}
private void drawBackground(Canvas canvas) {
for (int i = 0; i < 12; i++) {
tempPoint.set(pieCenterPoint.x - (int) (Math.sin(Math.PI / 12 * i) * (pieRadius
+ lineLength)), pieCenterPoint.y - (int) (Math.cos(Math.PI / 12 * i) * (
pieRadius
+ lineLength)));
tempPointRight.set(pieCenterPoint.x + (int) (Math.sin(Math.PI / 12 * i) * (pieRadius
+ lineLength)), pieCenterPoint.y + (int) (Math.cos(Math.PI / 12 * i) * (
pieRadius
+ lineLength)));
canvas.drawLine(tempPoint.x, tempPoint.y, tempPointRight.x, tempPointRight.y,
linePaint);
}
canvas.drawCircle(pieCenterPoint.x, pieCenterPoint.y, pieRadius + lineLength / 2,
whitePaint);
canvas.drawCircle(pieCenterPoint.x, pieCenterPoint.y, pieRadius + lineThickness, linePaint);
canvas.drawCircle(pieCenterPoint.x, pieCenterPoint.y, pieRadius, whitePaint);
canvas.drawText("0", pieCenterPoint.x, topTextHeight, textPaint);
canvas.drawText("12", pieCenterPoint.x, mViewHeight, textPaint);
canvas.drawText("18", leftTextWidth / 2, pieCenterPoint.y + textRect.height() / 2,
textPaint);
canvas.drawText("6", mViewWidth - rightTextWidth / 2,
pieCenterPoint.y + textRect.height() / 2, textPaint);
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mViewWidth = measureWidth(widthMeasureSpec);
mViewHeight = measureHeight(heightMeasureSpec);
pieRadius = mViewWidth / 2 - lineLength * 2 - (int) (textPaint.measureText("18") / 2);
pieCenterPoint.set(mViewWidth / 2 - (int) rightTextWidth / 2 + (int) leftTextWidth / 2,
mViewHeight / 2 + textSize / 2 - (int) (textPaint.measureText("18") / 2));
cirRect.set(pieCenterPoint.x - pieRadius, pieCenterPoint.y - pieRadius,
pieCenterPoint.x + pieRadius, pieCenterPoint.y + pieRadius);
setMeasuredDimension(mViewWidth, mViewHeight);
}
private int measureWidth(int measureSpec) {
int preferred = 3;
return getMeasurement(measureSpec, preferred);
}
private int measureHeight(int measureSpec) {
int preferred = mViewWidth;
return getMeasurement(measureSpec, preferred);
}
private int getMeasurement(int measureSpec, int preferred) {
int specSize = View.MeasureSpec.getSize(measureSpec);
int measurement;
switch (View.MeasureSpec.getMode(measureSpec)) {
case View.MeasureSpec.EXACTLY:
measurement = specSize;
break;
case View.MeasureSpec.AT_MOST:
measurement = Math.min(preferred, specSize);
break;
default:
measurement = preferred;
break;
}
return measurement;
}
}
@@ -0,0 +1,585 @@
package im.dacer.androidcharts;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.drawable.NinePatchDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.Collections;
/**
* Created by Dacer on 11/4/13.
* Edited by Lee youngchan 21/1/14
* Edited by dector 30-Jun-2014
*/
public class LineView extends View {
public static final int SHOW_POPUPS_All = 1;
public static final int SHOW_POPUPS_MAXMIN_ONLY = 2;
public static final int SHOW_POPUPS_NONE = 3;
private final int bottomTriangleHeight = 12;
private final int popupTopPadding = MyUtils.dip2px(getContext(), 2);
private final int popupBottomMargin = MyUtils.dip2px(getContext(), 5);
private final int bottomTextTopMargin = MyUtils.sp2px(getContext(), 5);
private final int bottomLineLength = MyUtils.sp2px(getContext(), 22);
private final int DOT_INNER_CIR_RADIUS = MyUtils.dip2px(getContext(), 2);
private final int DOT_OUTER_CIR_RADIUS = MyUtils.dip2px(getContext(), 5);
private final int MIN_TOP_LINE_LENGTH = MyUtils.dip2px(getContext(), 12);
private final int MIN_VERTICAL_GRID_NUM = 4;
private final int MIN_HORIZONTAL_GRID_NUM = 1;
private final int BACKGROUND_LINE_COLOR = Color.parseColor("#EEEEEE");
private final int BOTTOM_TEXT_COLOR = Color.parseColor("#9B9A9B");
private final Point tmpPoint = new Point();
public boolean showPopup = true;
private int mViewHeight;
private boolean autoSetDataOfGird = true;
private boolean autoSetGridWidth = true;
private int dataOfAGird = 10;
private int bottomTextHeight = 0;
private ArrayList<String> bottomTextList = new ArrayList<String>();
private ArrayList<ArrayList<Float>> dataLists;
private ArrayList<Integer> xCoordinateList = new ArrayList<Integer>();
private ArrayList<Integer> yCoordinateList = new ArrayList<Integer>();
private ArrayList<ArrayList<Dot>> drawDotLists = new ArrayList<ArrayList<Dot>>();
private Paint bottomTextPaint = new Paint();
private int bottomTextDescent;
private Paint popupTextPaint = new Paint();
private boolean showFloatNumInPopup;
private Dot pointToSelect;
private Dot selectedDot;
private int popupBottomPadding = MyUtils.dip2px(getContext(), 2);
/*
| | ←topLineLength
--+--+--+--+--+--+--
--+--+--+--+--+--+--
↑sideLineLength
*/
private int topLineLength = MyUtils.dip2px(getContext(), 12);
private int sideLineLength = MyUtils.dip2px(getContext(), 45) / 3 * 2;
private int backgroundGridWidth = MyUtils.dip2px(getContext(), 45);
private int showPopupType = SHOW_POPUPS_NONE;
private Boolean drawDotLine = false;
private int[] colorArray = {
Color.parseColor("#e74c3c"), Color.parseColor("#2980b9"), Color.parseColor("#1abc9c")
};
private Runnable animator = new Runnable() {
@Override public void run() {
boolean needNewFrame = false;
for (ArrayList<Dot> data : drawDotLists) {
for (Dot dot : data) {
dot.update();
if (!dot.isAtRest()) {
needNewFrame = true;
}
}
}
if (needNewFrame) {
postDelayed(this, 25);
}
invalidate();
}
};
public LineView(Context context) {
this(context, null);
}
public LineView(Context context, AttributeSet attrs) {
super(context, attrs);
popupTextPaint.setAntiAlias(true);
popupTextPaint.setColor(Color.WHITE);
popupTextPaint.setTextSize(MyUtils.sp2px(getContext(), 13));
popupTextPaint.setStrokeWidth(5);
popupTextPaint.setTextAlign(Paint.Align.CENTER);
bottomTextPaint.setAntiAlias(true);
bottomTextPaint.setTextSize(MyUtils.sp2px(getContext(), 12));
bottomTextPaint.setTextAlign(Paint.Align.CENTER);
bottomTextPaint.setStyle(Paint.Style.FILL);
bottomTextPaint.setColor(BOTTOM_TEXT_COLOR);
refreshTopLineLength();
}
public void setShowPopup(int popupType) {
this.showPopupType = popupType;
}
public void setDrawDotLine(Boolean drawDotLine) {
this.drawDotLine = drawDotLine;
}
public void setColorArray(int[] colors) {
this.colorArray = colors;
}
/**
* dataList will be reset when called is method.
*
* @param bottomTextList The String ArrayList in the bottom.
*/
public void setBottomTextList(ArrayList<String> bottomTextList) {
this.bottomTextList = bottomTextList;
Rect r = new Rect();
int longestWidth = 0;
String longestStr = "";
bottomTextDescent = 0;
for (String s : bottomTextList) {
bottomTextPaint.getTextBounds(s, 0, s.length(), r);
if (bottomTextHeight < r.height()) {
bottomTextHeight = r.height();
}
if (autoSetGridWidth && (longestWidth < r.width())) {
longestWidth = r.width();
longestStr = s;
}
if (bottomTextDescent < (Math.abs(r.bottom))) {
bottomTextDescent = Math.abs(r.bottom);
}
}
if (autoSetGridWidth) {
if (backgroundGridWidth < longestWidth) {
backgroundGridWidth =
longestWidth + (int) bottomTextPaint.measureText(longestStr, 0, 1);
}
if (sideLineLength < longestWidth / 2) {
sideLineLength = longestWidth / 2;
}
}
refreshXCoordinateList(getHorizontalGridNum());
}
/**
* @param dataLists The Float ArrayLists for showing,
* dataList.size() must be smaller than bottomTextList.size()
*/
public void setFloatDataList(ArrayList<ArrayList<Float>> dataLists) {
setFloatDataList(dataLists, true);
}
public void setDataList(ArrayList<ArrayList<Integer>> dataLists) {
ArrayList<ArrayList<Float>> newList = new ArrayList<>();
for (ArrayList<Integer> list : dataLists) {
ArrayList<Float> tempList = new ArrayList<>();
for (int i : list) {
tempList.add((float) i);
}
newList.add(tempList);
}
setFloatDataList(newList, false);
}
public void setFloatDataList(ArrayList<ArrayList<Float>> dataLists,
boolean showFloatNumInPopup) {
selectedDot = null;
this.showFloatNumInPopup = showFloatNumInPopup;
this.dataLists = dataLists;
for (ArrayList<Float> list : dataLists) {
if (list.size() > bottomTextList.size()) {
throw new RuntimeException(
"dacer.LineView error:" + " dataList.size() > bottomTextList.size() !!!");
}
}
float biggestData = 0;
for (ArrayList<Float> list : dataLists) {
if (autoSetDataOfGird) {
for (Float i : list) {
if (biggestData < i) {
biggestData = i;
}
}
}
dataOfAGird = 1;
while (biggestData / 10 > dataOfAGird) {
dataOfAGird *= 10;
}
}
refreshAfterDataChanged();
showPopup = true;
setMinimumWidth(0); // It can help the LineView reset the Width,
// I don't know the better way..
postInvalidate();
}
private void refreshAfterDataChanged() {
int verticalGridNum = getVerticalGridlNum();
refreshYCoordinateList(verticalGridNum);
refreshDrawDotList(verticalGridNum);
}
private int getVerticalGridlNum() {
int verticalGridNum = MIN_VERTICAL_GRID_NUM;
if (dataLists != null && !dataLists.isEmpty()) {
for (ArrayList<Float> list : dataLists) {
for (Float f : list) {
if (verticalGridNum < (f + 1)) {
verticalGridNum = (int) Math.floor(f + 1);
}
}
}
}
return verticalGridNum;
}
private int getHorizontalGridNum() {
int horizontalGridNum = bottomTextList.size() - 1;
if (horizontalGridNum < MIN_HORIZONTAL_GRID_NUM) {
horizontalGridNum = MIN_HORIZONTAL_GRID_NUM;
}
return horizontalGridNum;
}
private void refreshXCoordinateList(int horizontalGridNum) {
xCoordinateList.clear();
for (int i = 0; i < (horizontalGridNum + 1); i++) {
xCoordinateList.add(sideLineLength + backgroundGridWidth * i);
}
}
private void refreshYCoordinateList(int verticalGridNum) {
yCoordinateList.clear();
for (int i = 0; i < (verticalGridNum + 1); i++) {
yCoordinateList.add(topLineLength + ((mViewHeight
- topLineLength
- bottomTextHeight
- bottomTextTopMargin
- bottomLineLength
- bottomTextDescent) * i / (verticalGridNum)));
}
}
private void refreshDrawDotList(int verticalGridNum) {
if (dataLists != null && !dataLists.isEmpty()) {
if (drawDotLists.size() == 0) {
for (int k = 0; k < dataLists.size(); k++) {
drawDotLists.add(new ArrayList<LineView.Dot>());
}
}
for (int k = 0; k < dataLists.size(); k++) {
int drawDotSize = drawDotLists.get(k).isEmpty() ? 0 : drawDotLists.get(k).size();
for (int i = 0; i < dataLists.get(k).size(); i++) {
int x = xCoordinateList.get(i);
float y = getYAxesOf(dataLists.get(k).get(i), verticalGridNum);
if (i > drawDotSize - 1) {
drawDotLists.get(k).add(new Dot(x, 0, x, y, dataLists.get(k).get(i), k));
} else {
drawDotLists.get(k)
.set(i, drawDotLists.get(k)
.get(i)
.setTargetData(x, y, dataLists.get(k).get(i), k));
}
}
int temp = drawDotLists.get(k).size() - dataLists.get(k).size();
for (int i = 0; i < temp; i++) {
drawDotLists.get(k).remove(drawDotLists.get(k).size() - 1);
}
}
}
removeCallbacks(animator);
post(animator);
}
private float getYAxesOf(float value, int verticalGridNum) {
return topLineLength + ((mViewHeight
- topLineLength
- bottomTextHeight
- bottomTextTopMargin
- bottomLineLength
- bottomTextDescent) * (verticalGridNum - value) / (getVerticalGridlNum()));
}
private void refreshTopLineLength() {
// For prevent popup can't be completely showed when backgroundGridHeight is too small.
topLineLength = getPopupHeight() + DOT_OUTER_CIR_RADIUS + DOT_INNER_CIR_RADIUS + 2;
}
@Override protected void onDraw(Canvas canvas) {
drawBackgroundLines(canvas);
drawLines(canvas);
drawDots(canvas);
for (int k = 0; k < drawDotLists.size(); k++) {
float maxValue = Collections.max(dataLists.get(k));
float minValue = Collections.min(dataLists.get(k));
for (Dot d : drawDotLists.get(k)) {
if (showPopupType == SHOW_POPUPS_All) {
drawPopup(canvas, d.data, d.setupPoint(tmpPoint),
colorArray[k % colorArray.length]);
} else if (showPopupType == SHOW_POPUPS_MAXMIN_ONLY) {
if (d.data == maxValue) {
drawPopup(canvas, d.data, d.setupPoint(tmpPoint),
colorArray[k % colorArray.length]);
}
if (d.data == minValue) {
drawPopup(canvas, d.data, d.setupPoint(tmpPoint),
colorArray[k % colorArray.length]);
}
}
}
}
if (showPopup && selectedDot != null) {
drawPopup(canvas, selectedDot.data, selectedDot.setupPoint(tmpPoint),
colorArray[selectedDot.linenumber % colorArray.length]);
}
}
/**
* @param canvas The canvas you need to draw on.
* @param point The Point consists of the x y coordinates from left bottom to right top.
* Like is
*
* 3
* 2
* 1
* 0 1 2 3 4 5
*/
private void drawPopup(Canvas canvas, float num, Point point, int PopupColor) {
String numStr = showFloatNumInPopup ? String.valueOf(num) : String.valueOf(Math.round(num));
boolean singularNum = (numStr.length() == 1);
int sidePadding = MyUtils.dip2px(getContext(), singularNum ? 8 : 5);
int x = point.x;
int y = point.y - MyUtils.dip2px(getContext(), 5);
Rect popupTextRect = new Rect();
popupTextPaint.getTextBounds(numStr, 0, numStr.length(), popupTextRect);
Rect r = new Rect(x - popupTextRect.width() / 2 - sidePadding, y
- popupTextRect.height()
- bottomTriangleHeight
- popupTopPadding * 2
- popupBottomMargin, x + popupTextRect.width() / 2 + sidePadding,
y + popupTopPadding - popupBottomMargin + popupBottomPadding);
NinePatchDrawable popup =
(NinePatchDrawable) getResources().getDrawable(R.drawable.popup_white);
popup.setColorFilter(new PorterDuffColorFilter(PopupColor, PorterDuff.Mode.MULTIPLY));
popup.setBounds(r);
popup.draw(canvas);
canvas.drawText(numStr, x, y - bottomTriangleHeight - popupBottomMargin, popupTextPaint);
}
private int getPopupHeight() {
Rect popupTextRect = new Rect();
popupTextPaint.getTextBounds("9", 0, 1, popupTextRect);
Rect r = new Rect(-popupTextRect.width() / 2, -popupTextRect.height()
- bottomTriangleHeight
- popupTopPadding * 2
- popupBottomMargin, +popupTextRect.width() / 2,
+popupTopPadding - popupBottomMargin + popupBottomPadding);
return r.height();
}
private void drawDots(Canvas canvas) {
Paint bigCirPaint = new Paint();
bigCirPaint.setAntiAlias(true);
Paint smallCirPaint = new Paint(bigCirPaint);
smallCirPaint.setColor(Color.parseColor("#FFFFFF"));
if (drawDotLists != null && !drawDotLists.isEmpty()) {
for (int k = 0; k < drawDotLists.size(); k++) {
bigCirPaint.setColor(colorArray[k % colorArray.length]);
for (Dot dot : drawDotLists.get(k)) {
canvas.drawCircle(dot.x, dot.y, DOT_OUTER_CIR_RADIUS, bigCirPaint);
canvas.drawCircle(dot.x, dot.y, DOT_INNER_CIR_RADIUS, smallCirPaint);
}
}
}
}
private void drawLines(Canvas canvas) {
Paint linePaint = new Paint();
linePaint.setAntiAlias(true);
linePaint.setStrokeWidth(MyUtils.dip2px(getContext(), 2));
for (int k = 0; k < drawDotLists.size(); k++) {
linePaint.setColor(colorArray[k % colorArray.length]);
for (int i = 0; i < drawDotLists.get(k).size() - 1; i++) {
canvas.drawLine(drawDotLists.get(k).get(i).x, drawDotLists.get(k).get(i).y,
drawDotLists.get(k).get(i + 1).x, drawDotLists.get(k).get(i + 1).y,
linePaint);
}
}
}
private void drawBackgroundLines(Canvas canvas) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(MyUtils.dip2px(getContext(), 1f));
paint.setColor(BACKGROUND_LINE_COLOR);
PathEffect effects = new DashPathEffect(new float[] { 10, 5, 10, 5 }, 1);
//draw vertical lines
for (int i = 0; i < xCoordinateList.size(); i++) {
canvas.drawLine(xCoordinateList.get(i), 0, xCoordinateList.get(i),
mViewHeight - bottomTextTopMargin - bottomTextHeight - bottomTextDescent,
paint);
}
//draw dotted lines
paint.setPathEffect(effects);
Path dottedPath = new Path();
for (int i = 0; i < yCoordinateList.size(); i++) {
if ((yCoordinateList.size() - 1 - i) % dataOfAGird == 0) {
dottedPath.moveTo(0, yCoordinateList.get(i));
dottedPath.lineTo(getWidth(), yCoordinateList.get(i));
canvas.drawPath(dottedPath, paint);
}
}
//draw bottom text
if (bottomTextList != null) {
for (int i = 0; i < bottomTextList.size(); i++) {
canvas.drawText(bottomTextList.get(i), sideLineLength + backgroundGridWidth * i,
mViewHeight - bottomTextDescent, bottomTextPaint);
}
}
if (!drawDotLine) {
//draw solid lines
for (int i = 0; i < yCoordinateList.size(); i++) {
if ((yCoordinateList.size() - 1 - i) % dataOfAGird == 0) {
canvas.drawLine(0, yCoordinateList.get(i), getWidth(), yCoordinateList.get(i),
paint);
}
}
}
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int mViewWidth = measureWidth(widthMeasureSpec);
mViewHeight = measureHeight(heightMeasureSpec);
// mViewHeight = MeasureSpec.getSize(measureSpec);
refreshAfterDataChanged();
setMeasuredDimension(mViewWidth, mViewHeight);
}
private int measureWidth(int measureSpec) {
int horizontalGridNum = getHorizontalGridNum();
int preferred = backgroundGridWidth * horizontalGridNum + sideLineLength * 2;
return getMeasurement(measureSpec, preferred);
}
private int measureHeight(int measureSpec) {
int preferred = 0;
return getMeasurement(measureSpec, preferred);
}
private int getMeasurement(int measureSpec, int preferred) {
int specSize = MeasureSpec.getSize(measureSpec);
int measurement;
switch (MeasureSpec.getMode(measureSpec)) {
case MeasureSpec.EXACTLY:
measurement = specSize;
break;
case MeasureSpec.AT_MOST:
measurement = Math.min(preferred, specSize);
break;
default:
measurement = preferred;
break;
}
return measurement;
}
@Override public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
pointToSelect = findPointAt((int) event.getX(), (int) event.getY());
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if (pointToSelect != null) {
selectedDot = pointToSelect;
pointToSelect = null;
postInvalidate();
}
}
return true;
}
private Dot findPointAt(int x, int y) {
if (drawDotLists.isEmpty()) {
return null;
}
final int width = backgroundGridWidth / 2;
final Region r = new Region();
for (ArrayList<Dot> data : drawDotLists) {
for (Dot dot : data) {
final int pointX = dot.x;
final int pointY = (int) dot.y;
r.set(pointX - width, pointY - width, pointX + width, pointY + width);
if (r.contains(x, y)) {
return dot;
}
}
}
return null;
}
class Dot {
int x;
float y;
float data;
int targetX;
float targetY;
int linenumber;
int velocity = MyUtils.dip2px(getContext(), 18);
Dot(int x, float y, int targetX, float targetY, float data, int linenumber) {
this.x = x;
this.y = y;
this.linenumber = linenumber;
setTargetData(targetX, targetY, data, linenumber);
}
Point setupPoint(Point point) {
point.set(x, (int) y);
return point;
}
Dot setTargetData(int targetX, float targetY, float data, int linenumber) {
this.targetX = targetX;
this.targetY = targetY;
this.data = data;
this.linenumber = linenumber;
return this;
}
boolean isAtRest() {
return (x == targetX) && (y == targetY);
}
void update() {
x = (int) updateSelf(x, targetX, velocity);
y = updateSelf(y, targetY, velocity);
}
private float updateSelf(float origin, float target, int velocity) {
if (origin < target) {
origin += velocity;
} else if (origin > target) {
origin -= velocity;
}
if (Math.abs(target - origin) < velocity) {
origin = target;
}
return origin;
}
}
}
@@ -0,0 +1,24 @@
package im.dacer.androidcharts;
import android.content.Context;
/**
* Created by Dacer on 10/8/13.
*/
public class MyUtils {
public static int dip2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
}
@@ -0,0 +1,118 @@
package im.dacer.androidcharts;
/**
* Created by Dacer on 11/14/13.
*/
public class PieHelper {
int velocity = 5;
private float startDegree;
private float endDegree;
private float targetStartDegree;
private float targetEndDegree;
private String title;
private int color;
private float sweepDegree;
/**
* @param percent from 0 to 100
*/
public PieHelper(float percent) {
this(percent, null, 0);
}
public PieHelper(float percent, int color) {
this(percent, null, color);
}
/**
* @param percent from 0 to 100
*/
PieHelper(float percent, String title) {
this(percent, title, 0);
}
/**
* @param percent from 0 to 100
*/
PieHelper(float percent, String title, int color) {
this.sweepDegree = percent * 360 / 100;
this.title = title;
this.color = color;
}
PieHelper(float startDegree, float endDegree, PieHelper targetPie) {
this.startDegree = startDegree;
this.endDegree = endDegree;
targetStartDegree = targetPie.getStartDegree();
targetEndDegree = targetPie.getEndDegree();
this.sweepDegree = targetPie.getSweep();
this.title = targetPie.getTitle();
this.color = targetPie.getColor();
}
PieHelper setTarget(PieHelper targetPie) {
this.targetStartDegree = targetPie.getStartDegree();
this.targetEndDegree = targetPie.getEndDegree();
this.title = targetPie.getTitle();
this.color = targetPie.getColor();
this.sweepDegree = targetPie.getSweep();
return this;
}
void setDegree(float startDegree, float endDegree) {
this.startDegree = startDegree;
this.endDegree = endDegree;
}
boolean isColorSetted() {
return color != 0;
}
boolean isAtRest() {
return (startDegree == targetStartDegree) && (endDegree == targetEndDegree);
}
void update() {
this.startDegree = updateSelf(startDegree, targetStartDegree, velocity);
this.endDegree = updateSelf(endDegree, targetEndDegree, velocity);
this.sweepDegree = endDegree - startDegree;
}
String getPercentStr() {
float percent = sweepDegree / 360 * 100;
return String.valueOf((int) percent) + "%";
}
public int getColor() {
return color;
}
public String getTitle() {
return title;
}
public float getSweep() {
return sweepDegree;
}
public float getStartDegree() {
return startDegree;
}
public float getEndDegree() {
return endDegree;
}
private float updateSelf(float origin, float target, int velocity) {
if (origin < target) {
origin += velocity;
} else if (origin > target) {
origin -= velocity;
}
if (Math.abs(target - origin) < velocity) {
origin = target;
}
return origin;
}
}
@@ -0,0 +1,272 @@
package im.dacer.androidcharts;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
/**
* Created by Dacer on 9/26/14.
*/
public class PieView extends View {
public static final int NO_SELECTED_INDEX = -1;
private final int[] DEFAULT_COLOR_LIST = {
Color.parseColor("#33B5E5"), Color.parseColor("#AA66CC"), Color.parseColor("#99CC00"),
Color.parseColor("#FFBB33"), Color.parseColor("#FF4444")
};
private Paint cirPaint;
private Paint whiteLinePaint;
private Point pieCenterPoint;
private Paint textPaint;
private RectF cirRect;
private RectF cirSelectedRect;
private int mViewWidth;
private int mViewHeight;
private int margin;
private int pieRadius;
private OnPieClickListener onPieClickListener;
private ArrayList<PieHelper> pieHelperList;
private int selectedIndex = NO_SELECTED_INDEX;
private boolean showPercentLabel = true;
private Runnable animator = new Runnable() {
@Override public void run() {
boolean needNewFrame = false;
for (PieHelper pie : pieHelperList) {
pie.update();
if (!pie.isAtRest()) {
needNewFrame = true;
}
}
if (needNewFrame) {
postDelayed(this, 10);
}
invalidate();
}
};
public PieView(Context context) {
this(context, null);
}
public PieView(Context context, AttributeSet attrs) {
super(context, attrs);
pieHelperList = new ArrayList<PieHelper>();
cirPaint = new Paint();
cirPaint.setAntiAlias(true);
cirPaint.setColor(Color.GRAY);
whiteLinePaint = new Paint(cirPaint);
whiteLinePaint.setColor(Color.WHITE);
whiteLinePaint.setStrokeWidth(2f);
textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.WHITE);
textPaint.setTextSize(MyUtils.sp2px(getContext(), 13));
textPaint.setStrokeWidth(5);
textPaint.setTextAlign(Paint.Align.CENTER);
pieCenterPoint = new Point();
cirRect = new RectF();
cirSelectedRect = new RectF();
}
public void showPercentLabel(boolean show) {
showPercentLabel = show;
postInvalidate();
}
public void setOnPieClickListener(OnPieClickListener listener) {
onPieClickListener = listener;
}
public void setDate(ArrayList<PieHelper> helperList) {
initPies(helperList);
pieHelperList.clear();
removeSelectedPie();
if (helperList != null && !helperList.isEmpty()) {
for (PieHelper pieHelper : helperList) {
pieHelperList.add(
new PieHelper(pieHelper.getStartDegree(), pieHelper.getStartDegree(),
pieHelper));
}
} else {
pieHelperList.clear();
}
removeCallbacks(animator);
post(animator);
// pieHelperList = helperList;
// postInvalidate();
}
/**
* Set startDegree and endDegree for each PieHelper
*/
private void initPies(ArrayList<PieHelper> helperList) {
float totalAngel = 270;
for (PieHelper pie : helperList) {
pie.setDegree(totalAngel, totalAngel + pie.getSweep());
totalAngel += pie.getSweep();
}
}
public void selectedPie(int index) {
selectedIndex = index;
if (onPieClickListener != null) onPieClickListener.onPieClick(index);
postInvalidate();
}
public void removeSelectedPie() {
selectedIndex = NO_SELECTED_INDEX;
if (onPieClickListener != null) onPieClickListener.onPieClick(NO_SELECTED_INDEX);
postInvalidate();
}
@Override protected void onDraw(Canvas canvas) {
if (pieHelperList.isEmpty()) {
return;
}
int index = 0;
for (PieHelper pieHelper : pieHelperList) {
boolean selected = (selectedIndex == index);
RectF rect = selected ? cirSelectedRect : cirRect;
if (pieHelper.isColorSetted()) {
cirPaint.setColor(pieHelper.getColor());
} else {
cirPaint.setColor(DEFAULT_COLOR_LIST[index % 5]);
}
canvas.drawArc(rect, pieHelper.getStartDegree(), pieHelper.getSweep(), true, cirPaint);
drawPercentText(canvas, pieHelper);
drawLineBesideCir(canvas, pieHelper.getStartDegree(), selected);
drawLineBesideCir(canvas, pieHelper.getEndDegree(), selected);
index++;
}
}
private void drawLineBesideCir(Canvas canvas, float angel, boolean selectedCir) {
int sth2 = selectedCir ? mViewHeight / 2
: pieRadius; // Sorry I'm really don't know how to name the variable..
int sth = 1; // And it's
if (angel % 360 > 180 && angel % 360 < 360) {
sth = -1;
}
float lineToX = (float) (mViewHeight / 2 + Math.cos(Math.toRadians(-angel)) * sth2);
float lineToY =
(float) (mViewHeight / 2 + sth * Math.abs(Math.sin(Math.toRadians(-angel))) * sth2);
canvas.drawLine(pieCenterPoint.x, pieCenterPoint.y, lineToX, lineToY, whiteLinePaint);
}
private void drawPercentText(Canvas canvas, PieHelper pieHelper) {
if (!showPercentLabel) return;
float angel = (pieHelper.getStartDegree() + pieHelper.getEndDegree()) / 2;
int sth = 1;
if (angel % 360 > 180 && angel % 360 < 360) {
sth = -1;
}
float x = (float) (mViewHeight / 2 + Math.cos(Math.toRadians(-angel)) * pieRadius / 2);
float y = (float) (mViewHeight / 2
+ sth * Math.abs(Math.sin(Math.toRadians(-angel))) * pieRadius / 2);
canvas.drawText(pieHelper.getPercentStr(), x, y, textPaint);
}
private void drawText(Canvas canvas, PieHelper pieHelper) {
if (pieHelper.getTitle() == null) return;
float angel = (pieHelper.getStartDegree() + pieHelper.getEndDegree()) / 2;
int sth = 1;
if (angel % 360 > 180 && angel % 360 < 360) {
sth = -1;
}
float x = (float) (mViewHeight / 2 + Math.cos(Math.toRadians(-angel)) * pieRadius / 2);
float y = (float) (mViewHeight / 2
+ sth * Math.abs(Math.sin(Math.toRadians(-angel))) * pieRadius / 2);
canvas.drawText(pieHelper.getTitle(), x, y, textPaint);
}
@Override public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
int clickedIndex = findPointAt((int) event.getX(), (int) event.getY());
if (clickedIndex == selectedIndex) {
selectedIndex = NO_SELECTED_INDEX;
} else {
selectedIndex = clickedIndex;
}
if (onPieClickListener != null) {
onPieClickListener.onPieClick(selectedIndex);
}
postInvalidate();
}
return true;
}
/**
* find pie index where point is
*/
private int findPointAt(int x, int y) {
double degree = Math.atan2(x - pieCenterPoint.x, y - pieCenterPoint.y) * 180 / Math.PI;
degree = -(degree - 180) + 270;
int index = 0;
for (PieHelper pieHelper : pieHelperList) {
if (degree >= pieHelper.getStartDegree() && degree <= pieHelper.getEndDegree()) {
return index;
}
index++;
}
return NO_SELECTED_INDEX;
}
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mViewWidth = measureWidth(widthMeasureSpec);
mViewHeight = measureHeight(heightMeasureSpec);
margin = mViewWidth / 16;
pieRadius = (mViewWidth) / 2 - margin;
pieCenterPoint.set(pieRadius + margin, pieRadius + margin);
cirRect.set(pieCenterPoint.x - pieRadius, pieCenterPoint.y - pieRadius,
pieCenterPoint.x + pieRadius, pieCenterPoint.y + pieRadius);
cirSelectedRect.set(2, //minor margin for bigger circle
2, mViewWidth - 2, mViewHeight - 2);
setMeasuredDimension(mViewWidth, mViewHeight);
}
private int measureWidth(int measureSpec) {
int preferred = 3;
return getMeasurement(measureSpec, preferred);
}
private int measureHeight(int measureSpec) {
int preferred = mViewWidth;
return getMeasurement(measureSpec, preferred);
}
private int getMeasurement(int measureSpec, int preferred) {
int specSize = View.MeasureSpec.getSize(measureSpec);
int measurement;
switch (View.MeasureSpec.getMode(measureSpec)) {
case View.MeasureSpec.EXACTLY:
measurement = specSize;
break;
case View.MeasureSpec.AT_MOST:
measurement = Math.min(preferred, specSize);
break;
default:
measurement = preferred;
break;
}
return measurement;
}
public interface OnPieClickListener {
void onPieClick(int index);
}
}
@@ -0,0 +1,20 @@
package im.dacer.androidcharts;
import android.util.Log;
/**
* Created by Dacer on 10/23/13.
*/
public class TempLog {
public static void show(String s) {
Log.e("Log--->", s);
}
public static void show(int i) {
Log.e("Log--->", String.valueOf(i));
}
public static void show(float i) {
Log.e("Log--->", String.valueOf(i));
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

@@ -0,0 +1,2 @@
<resources>
</resources>
@@ -0,0 +1 @@
/build
@@ -0,0 +1,48 @@
apply plugin: 'com.android.application'
buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
}
}
repositories {
jcenter()
mavenCentral()
}
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
defaultConfig {
minSdkVersion 14
targetSdkVersion 25
}
buildTypes {
release {
minifyEnabled false
proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
}
}
productFlavors {
defaultFlavor {
proguardFile 'proguard-rules.txt'
}
}
lintOptions {
abortOnError false
}
}
dependencies {
compile files('libs/android-support-v4.jar')
compile project(':AndroidCharts')
}
@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Applications/Android Studio.app/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.dacer.androidchartsexample">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="com.dacer.androidchartsexample.MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

@@ -0,0 +1,46 @@
package com.dacer.androidchartsexample;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import im.dacer.androidcharts.BarView;
import java.util.ArrayList;
/**
* Created by Dacer on 11/15/13.
*/
public class BarFragment extends Fragment {
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_bar, container, false);
final BarView barView = (BarView) rootView.findViewById(R.id.bar_view);
Button button = (Button) rootView.findViewById(R.id.bar_button);
button.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
randomSet(barView);
}
});
randomSet(barView);
return rootView;
}
private void randomSet(BarView barView) {
int random = (int) (Math.random() * 20) + 6;
ArrayList<String> test = new ArrayList<String>();
for (int i = 0; i < random; i++) {
test.add("test");
test.add("pqg");
// test.add(String.valueOf(i+1));
}
barView.setBottomTextList(test);
ArrayList<Integer> barDataList = new ArrayList<Integer>();
for (int i = 0; i < random * 2; i++) {
barDataList.add((int) (Math.random() * 100));
}
barView.setDataList(barDataList, 100);
}
}
@@ -0,0 +1,49 @@
package com.dacer.androidchartsexample;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import im.dacer.androidcharts.ClockPieHelper;
import im.dacer.androidcharts.ClockPieView;
import java.util.ArrayList;
/**
* Created by Dacer on 11/16/13.
*/
public class ClockPieFragment extends Fragment {
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_pie, container, false);
final ClockPieView clockPieView = (ClockPieView) rootView.findViewById(R.id.pie_view);
Button button = (Button) rootView.findViewById(R.id.pie_button);
button.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
randomSet(clockPieView);
}
});
set(clockPieView);
return rootView;
}
private void randomSet(ClockPieView clockPieView) {
ArrayList<ClockPieHelper> clockPieHelperArrayList = new ArrayList<ClockPieHelper>();
for (int i = 0; i < 20; i++) {
int startHour = (int) (24 * Math.random());
int startMin = (int) (60 * Math.random());
int duration = (int) (50 * Math.random());
clockPieHelperArrayList.add(
new ClockPieHelper(startHour, startMin, 0, startHour, startMin + duration, 0));
}
clockPieView.setDate(clockPieHelperArrayList);
}
private void set(ClockPieView clockPieView) {
ArrayList<ClockPieHelper> clockPieHelperArrayList = new ArrayList<ClockPieHelper>();
clockPieHelperArrayList.add(new ClockPieHelper(1, 50, 2, 30));
clockPieHelperArrayList.add(new ClockPieHelper(6, 50, 8, 30));
clockPieView.setDate(clockPieHelperArrayList);
}
}
@@ -0,0 +1,103 @@
package com.dacer.androidchartsexample;
import android.app.Fragment;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import im.dacer.androidcharts.LineView;
import java.util.ArrayList;
/**
* Created by Dacer on 11/15/13.
*/
public class LineFragment extends Fragment {
int randomint = 9;
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_line, container, false);
final LineView lineView = (LineView) rootView.findViewById(R.id.line_view);
final LineView lineViewFloat = (LineView) rootView.findViewById(R.id.line_view_float);
initLineView(lineView);
initLineView(lineViewFloat);
Button lineButton = (Button) rootView.findViewById(R.id.line_button);
lineButton.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
randomSet(lineView, lineViewFloat);
}
});
randomSet(lineView, lineViewFloat);
return rootView;
}
private void initLineView(LineView lineView) {
ArrayList<String> test = new ArrayList<String>();
for (int i = 0; i < randomint; i++) {
test.add(String.valueOf(i + 1));
}
lineView.setBottomTextList(test);
lineView.setColorArray(new int[] {
Color.parseColor("#F44336"), Color.parseColor("#9C27B0"),
Color.parseColor("#2196F3"), Color.parseColor("#009688")
});
lineView.setDrawDotLine(true);
lineView.setShowPopup(LineView.SHOW_POPUPS_NONE);
}
private void randomSet(LineView lineView, LineView lineViewFloat) {
ArrayList<Integer> dataList = new ArrayList<>();
float random = (float) (Math.random() * 9 + 1);
for (int i = 0; i < randomint; i++) {
dataList.add((int) (Math.random() * random));
}
ArrayList<Integer> dataList2 = new ArrayList<>();
random = (int) (Math.random() * 9 + 1);
for (int i = 0; i < randomint; i++) {
dataList2.add((int) (Math.random() * random));
}
ArrayList<Integer> dataList3 = new ArrayList<>();
random = (int) (Math.random() * 9 + 1);
for (int i = 0; i < randomint; i++) {
dataList3.add((int) (Math.random() * random));
}
ArrayList<ArrayList<Integer>> dataLists = new ArrayList<>();
dataLists.add(dataList);
dataLists.add(dataList2);
dataLists.add(dataList3);
lineView.setDataList(dataLists);
ArrayList<Float> dataListF = new ArrayList<>();
float randomF = (float) (Math.random() * 9 + 1);
for (int i = 0; i < randomint; i++) {
dataListF.add((float) (Math.random() * randomF));
}
ArrayList<Float> dataListF2 = new ArrayList<>();
randomF = (int) (Math.random() * 9 + 1);
for (int i = 0; i < randomint; i++) {
dataListF2.add((float) (Math.random() * randomF));
}
ArrayList<Float> dataListF3 = new ArrayList<>();
randomF = (int) (Math.random() * 9 + 1);
for (int i = 0; i < randomint; i++) {
dataListF3.add((float) (Math.random() * randomF));
}
ArrayList<ArrayList<Float>> dataListFs = new ArrayList<>();
dataListFs.add(dataListF);
dataListFs.add(dataListF2);
dataListFs.add(dataListF3);
lineViewFloat.setFloatDataList(dataListFs);
}
}
@@ -0,0 +1,88 @@
package com.dacer.androidchartsexample;
import android.app.ActionBar;
import android.app.Activity;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
;
public class MainActivity extends Activity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {@link #restoreActionBar()}.
*/
private CharSequence mTitle;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment =
(NavigationDrawerFragment) getFragmentManager().findFragmentById(
R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
@Override public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
switch (position) {
case 0:
fragmentManager.beginTransaction()
.replace(R.id.container, new LineFragment())
.commit();
break;
case 1:
fragmentManager.beginTransaction()
.replace(R.id.container, new BarFragment())
.commit();
break;
case 2:
fragmentManager.beginTransaction()
.replace(R.id.container, new ClockPieFragment())
.commit();
break;
case 3:
fragmentManager.beginTransaction()
.replace(R.id.container, new PieFragment())
.commit();
break;
}
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
case 4:
mTitle = getString(R.string.title_section4);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
}
@@ -0,0 +1,247 @@
package com.dacer.androidchartsexample;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
;
/**
* Fragment used for managing interactions for and presentation of a navigation drawer.
* See the <a href="https://developer.android.com/design/patterns/navigation-drawer.html#Interaction">
* design guidelines</a> for a complete explanation of the behaviors implemented here.
*/
public class NavigationDrawerFragment extends Fragment {
/**
* Remember the position of the selected item.
*/
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
/**
* Per the design guidelines, you should show the drawer on launch until the user manually
* expands it. This shared preference tracks this.
*/
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
/**
* A pointer to the current callbacks instance (the Activity).
*/
private NavigationDrawerCallbacks mCallbacks;
/**
* Helper component that ties the action bar to the navigation drawer.
*/
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private ListView mDrawerListView;
private View mFragmentContainerView;
private int mCurrentSelectedPosition = 0;
private boolean mFromSavedInstanceState;
private boolean mUserLearnedDrawer;
public NavigationDrawerFragment() {
}
@Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Read in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
// Select either the default item (0) or the last selected item.
selectItem(mCurrentSelectedPosition);
}
@Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Indicate that this fragment would like to influence the set of actions in the action bar.
setHasOptionsMenu(true);
}
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mDrawerListView =
(ListView) inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
});
mDrawerListView.setAdapter(new ArrayAdapter<String>(getActionBar().getThemedContext(),
android.R.layout.simple_list_item_activated_1, android.R.id.text1, new String[] {
getString(R.string.title_section1), getString(R.string.title_section2),
getString(R.string.title_section3), getString(R.string.title_section4)
}));
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
return mDrawerListView;
}
public boolean isDrawerOpen() {
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
}
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* @param fragmentId The android:id of this fragment in its activity's layout.
* @param drawerLayout The DrawerLayout containing this fragment's UI.
*/
public void setUp(int fragmentId, DrawerLayout drawerLayout) {
mFragmentContainerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the navigation drawer and the action bar app icon.
mDrawerToggle =
new ActionBarDrawerToggle(getActivity(), /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
R.string.navigation_drawer_close /* "close drawer" description for accessibility */) {
@Override public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
if (!isAdded()) {
return;
}
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
@Override public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (!isAdded()) {
return;
}
if (!mUserLearnedDrawer) {
// The user manually opened the drawer; store this flag to prevent auto-showing
// the navigation drawer automatically in the future.
mUserLearnedDrawer = true;
SharedPreferences sp =
PreferenceManager.getDefaultSharedPreferences(getActivity());
sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
}
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
// per the navigation drawer design guidelines.
if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
@Override public void run() {
mDrawerToggle.syncState();
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
private void selectItem(int position) {
mCurrentSelectedPosition = position;
if (mDrawerListView != null) {
mDrawerListView.setItemChecked(position, true);
}
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
if (mCallbacks != null) {
mCallbacks.onNavigationDrawerItemSelected(position);
}
}
@Override public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (NavigationDrawerCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
}
}
@Override public void onDetach() {
super.onDetach();
mCallbacks = null;
}
@Override public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
@Override public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Forward the new configuration the drawer toggle component.
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Per the navigation drawer design guidelines, updates the action bar to show the global app
* 'context', rather than just what's in the current screen.
*/
private void showGlobalContextActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setTitle(R.string.app_name);
}
private ActionBar getActionBar() {
return getActivity().getActionBar();
}
/**
* Callbacks interface that all activities using this fragment must implement.
*/
public static interface NavigationDrawerCallbacks {
/**
* Called when an item in the navigation drawer is selected.
*/
void onNavigationDrawerItemSelected(int position);
}
}
@@ -0,0 +1,76 @@
package com.dacer.androidchartsexample;
import android.app.Fragment;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import im.dacer.androidcharts.PieHelper;
import im.dacer.androidcharts.PieView;
import java.util.ArrayList;
/**
* Created by Dacer on 11/16/13.
*/
public class PieFragment extends Fragment {
private TextView textView;
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_pie_s, container, false);
textView = (TextView) rootView.findViewById(R.id.textView);
final PieView pieView = (PieView) rootView.findViewById(R.id.pie_view);
Button button = (Button) rootView.findViewById(R.id.pie_button);
button.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
randomSet(pieView);
}
});
set(pieView);
return rootView;
}
private void randomSet(PieView pieView) {
ArrayList<PieHelper> pieHelperArrayList = new ArrayList<PieHelper>();
ArrayList<Integer> intList = new ArrayList<Integer>();
int totalNum = (int) (5 * Math.random()) + 5;
int totalInt = 0;
for (int i = 0; i < totalNum; i++) {
int ranInt = (int) (Math.random() * 10) + 1;
intList.add(ranInt);
totalInt += ranInt;
}
for (int i = 0; i < totalNum; i++) {
pieHelperArrayList.add(new PieHelper(100f * intList.get(i) / totalInt));
}
pieView.selectedPie(PieView.NO_SELECTED_INDEX);
pieView.showPercentLabel(true);
pieView.setDate(pieHelperArrayList);
}
private void set(PieView pieView) {
ArrayList<PieHelper> pieHelperArrayList = new ArrayList<PieHelper>();
pieHelperArrayList.add(new PieHelper(20, Color.BLACK));
pieHelperArrayList.add(new PieHelper(6));
pieHelperArrayList.add(new PieHelper(30));
pieHelperArrayList.add(new PieHelper(12));
pieHelperArrayList.add(new PieHelper(32));
pieView.setDate(pieHelperArrayList);
pieView.setOnPieClickListener(new PieView.OnPieClickListener() {
@Override public void onPieClick(int index) {
if (index != PieView.NO_SELECTED_INDEX) {
textView.setText(index + " selected");
} else {
textView.setText("No selected pie");
}
}
});
pieView.selectedPie(2);
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

@@ -0,0 +1,34 @@
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<!-- android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
If you're not building against API 17 or higher, use
android:layout_gravity="left" instead. -->
<!-- The drawer is given a fixed width in dp and extends the full height of
the container. -->
<fragment
android:id="@+id/navigation_drawer"
android:name="com.dacer.androidchartsexample.NavigationDrawerFragment"
android:layout_width="@dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
/>
</android.support.v4.widget.DrawerLayout>
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
>
<HorizontalScrollView
android:id="@+id/horizontalScrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
>
<view
class="im.dacer.androidcharts.BarView"
android:id="@+id/bar_view"
android:layout_width="wrap_content"
android:layout_height="300dp"
/>
</HorizontalScrollView>
<Button
android:id="@+id/bar_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Random"
/>
</RelativeLayout>
@@ -0,0 +1,46 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
>
<HorizontalScrollView
android:id="@+id/horizontalScrollViewFloat"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/horizontalScrollView"
android:layout_alignParentRight="true"
>
<view
class="im.dacer.androidcharts.LineView"
android:id="@+id/line_view_float"
android:layout_width="wrap_content"
android:layout_height="200dp"
/>
</HorizontalScrollView>
<HorizontalScrollView
android:id="@+id/horizontalScrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/line_button"
android:layout_alignParentRight="true"
>
<view
class="im.dacer.androidcharts.LineView"
android:id="@+id/line_view"
android:layout_width="wrap_content"
android:layout_height="200dp"
/>
</HorizontalScrollView>
<Button
android:id="@+id/line_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Random"
/>
</RelativeLayout>
@@ -0,0 +1,10 @@
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
tools:context="com.dacer.androidchartsexample.NavigationDrawerFragment"
/>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
>
<view
class="im.dacer.androidcharts.ClockPieView"
android:id="@+id/pie_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
/>
<Button
android:id="@+id/pie_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Random"
/>
</RelativeLayout>
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
>
<view
class="im.dacer.androidcharts.PieView"
android:id="@+id/pie_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_margin="10dp"
/>
<Button
android:id="@+id/pie_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="Random"
/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/pie_button"
android:layout_centerHorizontal="true"
android:text="New Text"
/>
</RelativeLayout>
@@ -0,0 +1,6 @@
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
@@ -0,0 +1,9 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<!-- Per the design guidelines, navigation drawers should be between 240dp and 320dp:
https://developer.android.com/design/patterns/navigation-drawer.html -->
<dimen name="navigation_drawer_width">240dp</dimen>
</resources>
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">AndroidChartsExample</string>
<string name="title_section1">Line Chart</string>
<string name="title_section2">Bar Chart</string>
<string name="title_section3">Clock Pie View</string>
<string name="title_section4">Pie Chart</string>
<string name="navigation_drawer_open">Open navigation drawer</string>
<string name="navigation_drawer_close">Close navigation drawer</string>
</resources>
@@ -0,0 +1,8 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
+20
View File
@@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Ding Wenhao
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+143
View File
@@ -0,0 +1,143 @@
# AndroidCharts
A simple Android charts library.
## Known Uses in
* [Pomotodo](https://play.google.com/store/apps/details?id=com.pomotodo)
## Including in Your Project
#### Eclipse
* Import `/AndroidCharts` folder.
* Move `/java` folder to `/src` folder.
* `mkdir libs`, copy `android-support-v4.jar` to `/libs`.
#### Gradle
```groovy
repositories {
jcenter()
}
```
```groovy
compile 'im.dacer:AndroidCharts:1.0.4'
```
## Usage
#### Line Chart
![Line Chart](https://raw.github.com/dacer/AndroidCharts/master/pic/line.png)
```xml
<HorizontalScrollView>
<view
android:layout_width="wrap_content"
android:layout_height="300dp"
class="im.dacer.androidcharts.LineView"
android:id="@+id/line_view" />
</HorizontalScrollView>
```
```java
LineView lineView = (LineView)findViewById(R.id.line_view);
lineView.setDrawDotLine(false); //optional
lineView.setShowPopup(LineView.SHOW_POPUPS_MAXMIN_ONLY); //optional
lineView.setBottomTextList(strList);
lineView.setColorArray(new int[]{Color.BLACK,Color.GREEN,Color.GRAY,Color.CYAN});
lineView.setDataList(dataLists); //or lineView.setFloatDataList(floatDataLists)
```
#### Bar Chart
![Bar Chart](https://raw.github.com/dacer/AndroidCharts/master/pic/bar.png)
```xml
<HorizontalScrollView>
<view
android:layout_width="wrap_content"
android:layout_height="300dp"
class="im.dacer.androidcharts.BarView"
android:id="@+id/bar_view" />
</HorizontalScrollView>
```
```java
BarView barView = (BarView)findViewById(R.id.bar_view);\
barView.setBottomTextList(strList);
barView.setDataList(dataList,100);
```
#### Clock Pie Chart
![Clock Pie Chart](https://raw.github.com/dacer/AndroidCharts/master/pic/pie.png)
```xml
<view
android:layout_width="300dp"
android:layout_height="wrap_content"
class="im.dacer.androidcharts.ClockPieView"
android:id="@+id/clock_pie_view" />
```
```java
ClockPieView pieView = (ClockPieView)findViewById(R.id.clock_pie_view);
ArrayList<ClockPieHelper> pieHelperArrayList = new ArrayList<ClockPieHelper>();
pieView.setDate(pieHelperArrayList);
```
#### Pie Chart
![Pie Chart](https://raw.github.com/dacer/AndroidCharts/master/pic/pie2.png)
```xml
<view
android:layout_width="300dp"
android:layout_height="wrap_content"
class="im.dacer.androidcharts.PieView"
android:id="@+id/pie_view" />
```
```java
PieView pieView = (PieView)findViewById(R.id.pie_view);
ArrayList<PieHelper> pieHelperArrayList = new ArrayList<PieHelper>();
pieView.setDate(pieHelperArrayList);
pieView.selectedPie(2); //optional
pieView.setOnPieClickListener(listener) //optional
pieView.showPercentLabel(false); //optional
```
## License
The MIT License (MIT)
Copyright (c) 2013 Ding Wenhao
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
## Contributing
Please fork this repository and contribute back using
[pull requests](https://github.com/github/android/pulls).
Any contributions, large or small, major features, bug fixes, additional
language translations, unit/integration tests are welcomed
+19
View File
@@ -0,0 +1,19 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
}
}
allprojects {
repositories {
jcenter()
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.4'
}
+1
View File
@@ -0,0 +1 @@
# Set Gradle settings which apply to all modules here.
Binary file not shown.
@@ -0,0 +1,6 @@
#Wed Jul 02 21:18:32 KST 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-1.12-bin.zip
+164
View File
@@ -0,0 +1,164 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+90
View File
@@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
Binary file not shown.
@@ -0,0 +1,6 @@
#Fri Aug 25 15:12:07 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
+164
View File
@@ -0,0 +1,164 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+90
View File
@@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

+1
View File
@@ -0,0 +1 @@
include ':AndroidCharts', ':AndroidChartsExample'