的
@@ -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/
|
||||
@@ -0,0 +1 @@
|
||||
/build
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 325 B |
|
After Width: | Height: | Size: 328 B |
|
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>
|
||||
|
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);
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 161 B |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 142 B |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 174 B |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 202 B |
|
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>
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||

|
||||
|
||||
```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
|
||||
|
||||

|
||||
|
||||
```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
|
||||
|
||||

|
||||
|
||||
```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
|
||||
|
||||

|
||||
|
||||
```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
|
||||
@@ -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'
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
# Set Gradle settings which apply to all modules here.
|
||||
@@ -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
|
||||
@@ -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 "$@"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 "$@"
|
||||
@@ -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
|
||||
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 38 KiB |
@@ -0,0 +1 @@
|
||||
include ':AndroidCharts', ':AndroidChartsExample'
|
||||