import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TimeChartView extends GridChartView {
/**
* 分时数据
*/
private Vector<TimeData> data;
/**
* 时间段数据
*/
private List<TRADETIME> tradetimes;
/**
* 昨收价
*/
private float preClose;
/**
* 记录列表中设置到上表中的数据的最大值
*/
private float upMaxData;
/**
* 记录列表中设置到上表中的数据的最小值
*/
private float upMinData;
/**
* 记录列表中设置到下表中的数据最大值
*/
private float downMaxData;
/**
* 记录列表中设置到下表中的数据最小值
*/
private float downMinData;
/**
* 上表与下表中间的日期时间文字的默认大小
*/
protected final float DEFAULT_textSize = 9;
/**
* 文字大小
*/
protected float textSize;
/**
* 上表与下表间距
*/
protected float spacing;
/**
* 默认经线条数
*/
private final int DEFAULT_LONGITUDE_NUM = 3;
/**
* 默认经线类型(24小时)
*/
private final int DEFAULT_THEME = LongitudesTheme.theme0;
/**
* 默认上表纬线条数
*/
private final int DEFAULT_LATITUDE_UP_NUM = 4;
/**
* 默认下表纬线条数
*/
private final int DEFAULT_LATITUDE_DOWN_NUM = 2;
/**
* 默认经线颜色
*/
private final int DEFAULT_LONGITUDE_COLOR = 0xffb7b7b7;
/**
* 默认纬线颜色
*/
private final int MIDDLE_LONGITUDE_LATITUDE_COLOR = 0xffff4700;
/**
* 中心的经纬线颜色
*/
private final int DEFAULT_LATITUDE_COLOR = 0xffeeeeee;
/**
* 默认经、纬线宽
*/
private final float DEFAULT_LATITUDE_LONGITUDE_WIDTH = 0.8f;
/**
* 经线间距
*/
protected float longitudesSpacing;
/**
* 纬线间距
*/
protected float latitudesSpacing;
/**
* 经线条数
*/
private int longitudesNum = DEFAULT_LONGITUDE_NUM;
/**
* 经线类型
*/
private int longitudesTheme = DEFAULT_THEME;
/**
* 上表纬线条数
*/
protected int latitudesUpNum = DEFAULT_LATITUDE_UP_NUM;
/**
* 下表纬线条数
*/
protected int latitudesDownNum = DEFAULT_LATITUDE_DOWN_NUM;
/**
* 经线颜色
*/
private int longitudesColor = DEFAULT_LONGITUDE_COLOR;
private int midLongitudesColor = 0xffff4700;
/**
* 纬线颜色
*/
private int latitudesColor = DEFAULT_LATITUDE_COLOR;
/**
* 经、纬线宽
*/
private float latLongWidth = DEFAULT_LATITUDE_LONGITUDE_WIDTH;
/**
* 是否绘制经线
*/
private boolean isDrawLongitudes;
/**
* 是否绘制纬线
*/
private boolean isDrawLatitudes;
/**
* 上表底部
*/
protected float upChartBottom;
/**
* 下表底部
*/
protected float downChartBottom;
/**
* 上表高度
*/
protected float upChartHeight;
/**
* 下表高度
*/
protected float downChartHeight;
/**
* 分时默认最大时间
*/
private final int MAX_DATE = 60 * 4 + 1;
/**
* 分时最大时间(默认24个小时)
*/
private int maxDate = MAX_DATE;
/**
* 各个数据点的间距
*/
private float dataSpacing;
/**
* 上表的尺寸与数据比例
*/
private float upRatio;
/**
* 下表的尺寸与数据比例
*/
private float downRatio;
/**
* 下表柱形图宽
*/
private float columnWidth;
/**
* 是否显示十字光标
*/
private boolean isShowCross;
/**
* 十字光标X坐标
*/
private float crossX;
/**
* 十字光标Y坐标
*/
private float crossY;
/**
* 长按事件的Runnable
*/
private Runnable mRunnable;
/**
* 手指是否离开屏幕
*/
private boolean isReleased;
/**
* 手指是否移动了
*/
private boolean isMoved;
/**
* 是否可以执行OnTouch中的Move事件了
*/
private boolean isStartMoved;
/**
* 按下时的X坐标
*/
private float touchDownX;
/**
* 按下时的Y坐标
*/
private float touchDownY;
/**
* 触摸点 X
*/
private float movedX;
/**
* 触摸点 Y
*/
private float movedY;
private float moveRawX;// 触摸中的X坐标
private float moveRawY;// 触摸中的Y坐标
/**
* 设置是否将两边坐标值绘制在边框线外(注:如果设置成true,必须设置strokeLeft和strokeRight)
*/
private boolean isDrawOutside;
/**
* 传递数据的接口
*/
private OnTimeListener l;
/**
* 单击事件接口
*/
private OnTimeChartClickListener mOnTimeChartClickListener;
/**
* 左边要显示当前十字光标中心点的数据
*/
private float leftData;
/**
* 右边要显示当前十字光标中心点的数据
*/
private float rightData;
/**
* 底部要显示当前十字光标中心点点数据
*/
private float bottomData;
/**
* 中间时间
*/
private long time;
ExecutorService executorService = Executors.newCachedThreadPool();
/**
* 小数保留位数
*/
private int num = 2;// 默认保留两位
/**
* 经线类型
*
* @author dingrui
*/
public static class LongitudesTheme {
public static final int theme0 = 0;// 9:30-11:30(2h) 13:00-15:00(2h)
public static final int theme1 = 1;// 6:00-次日6:00(24h)
public static final int theme2 = 2;// 昨日20:00-2:30(6.5h),9:00-11:30(2.5h),13:30-15:30(2h)
public static final int theme3 = 3;// 8:00-次日2:00(18h)
public static final int theme4 = 4;// 9:00-10:15(1.5h),10:30-11:30(1h),13:30-15:00(1.5h),21:00-次日2:30(5.5h)
public static final int theme5 = 5;// 9:00-10:15(1.25h),10:30-11:30(1h),13:30-15:00(1.5h)
public static final int theme6 = 6;// 9:00-10:15(1.25h),10:30-11:30(1h),13:30-15:00(1.5h),21:00-23:30(2.5h)
public static final int theme7 = 7;// 9:00-10:15(1.25h),10:30-11:30(1h),13:30-15:00(1.5h),21:00-23:00(2h)
public static final int theme8 = 8;// 9:00-10:15(1.25h),10:30-11:30(1h),13:30-15:00(1.5h),21:00-次日1:00(4h)
}
private boolean isDrawDownChart = true; //是否画下表
// private TimeListThread mTimeListThread;
Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0x1:
postInvalidate();
break;
case 0x2:
Bundle bundle = msg.getData();
data = (Vector<TimeData>) bundle.getSerializable("data");
tradetimes = (List<TRADETIME>) bundle.getSerializable("tradetimes");
upMaxData = bundle.getFloat("upMaxData");
upMinData = bundle.getFloat("upMinData");
downMinData = bundle.getFloat("downMinData");
downMaxData = bundle.getFloat("downMaxData");
preClose = bundle.getFloat("preClose");
if (!isShowCross)
postInvalidate();
break;
default:
break;
}
}
};
public TimeChartView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
public TimeChartView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
public TimeChartView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
init();
}
/**
* 初始化
*/
private void init() {
upMaxData = 0;
downMaxData = 0;
isShowCross = false;
textSize = MyUtils.getInstance().dp2px(getContext(), DEFAULT_textSize);
spacing = textSize * 2;// 比文字高度高一半
isDrawLongitudes = true;
isDrawLatitudes = true;
isDrawOutside = false;
mRunnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if (isMoved || isReleased)
return;
isStartMoved = true;
}
};
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
float viewHight = getHeight();
float viewWidth = getWidth();
// 文字画笔
TextPaint tp = new TextPaint();
tp.setTextSize(textSize);
// tp.setTypeface(Typeface.DEFAULT_BOLD);
int upLength = Parse.getInstance().parse2String(upMaxData, num)
.length();
int downLength = Parse.getInstance().parse2CNString(downMaxData)
.length();
int defaultLength = "0000.00".length();
float dataWidth = 0;
if (upLength > downLength) {
if (defaultLength > upLength) {
dataWidth = tp.measureText("0000.00");
} else {
dataWidth = tp.measureText(Parse.getInstance().parse2String(
upMaxData, num));
}
} else {
if (defaultLength > downLength) {
dataWidth = tp.measureText("0000.00");
} else {
dataWidth = tp.measureText(Parse.getInstance().parse2CNString(
downMaxData));
}
}
if (spacing == 0.0f) {
setStrokeBottom(textSize);
}
if(!isDrawDownChart) {
latitudesDownNum = 0;
}
latitudesSpacing = (viewHight - getStrokeWidth() * 2 - spacing
- getStrokeTop() - getStrokeBottom())
/ (latitudesUpNum + latitudesDownNum);
upChartHeight = latitudesSpacing * latitudesUpNum;
upChartBottom = latitudesSpacing * latitudesUpNum + getStrokeTop()
+ getStrokeWidth();
downChartHeight = latitudesSpacing * latitudesDownNum;
downChartBottom = viewHight - getStrokeBottom() - getStrokeWidth();
columnWidth = (getWidth() - getStrokeWidth() * 2 - getStrokeLeft() - getStrokeRight())
/ maxDate;
if (columnWidth > 2.0f) {
columnWidth = 2.0f;
}
dataSpacing = (getWidth() - getStrokeWidth() * 2 - getStrokeLeft()
- getStrokeRight() - 2.0f)
/ (maxDate - 1);
if (upMaxData >= preClose && upMinData <= preClose) {
if (upMaxData - preClose >= preClose - upMinData) {
upMinData = preClose - (upMaxData - preClose);
} else {
upMaxData = preClose + (preClose - upMinData);
}
} else if (upMaxData >= preClose && upMinData >= preClose) {
upMinData = preClose - (upMaxData - preClose);
} else {
upMaxData = preClose + (preClose - upMinData);
}
upRatio = upChartHeight / (upMaxData - upMinData);
downRatio = downChartHeight / (downMaxData - downMinData);
// 画笔
Paint paint = new Paint();
if (isDrawLatitudes) {
// 绘制纬线
drawLatitudes(canvas, paint);
}
if (isDrawLongitudes)
// 绘制经线
{
if (tradetimes != null && tradetimes.size() > 0) {
drawLongitudes1(canvas, paint);
} else {
drawLongitudes(canvas, paint);
}
}
paint.reset();
// 绘制上表折线
drawUpLine(canvas, paint);
// drawCubicUpLine(canvas, paint);
// 绘制上表Y坐标上的X数据
drawUpAxisXTitle(canvas, tp, dataWidth);
if(isDrawDownChart) {
// 绘制下表柱形图
drawDownColumnChart(canvas, paint);
// 绘制下表刻度
drawDownAxisXTitle(canvas, tp, dataWidth);
}
// 绘制时间
// drawTime(canvas, tp);
// 绘制十字线
drawCrossLine(canvas, paint);
}
/**
* 绘制纬线
*
* @param canvas 画布
* @param paint
*/
private void drawLatitudes(Canvas canvas, Paint paint) {
paint.reset();
PathEffect pe = new DashPathEffect(new float[]{4, 4}, 1);
paint.setColor(latitudesColor);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(latLongWidth);
paint.setAntiAlias(true);
Path path = new Path();
this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
for (int i = 1; i <= latitudesUpNum; i++) {
if(i == (latitudesUpNum + 1) / 2){
paint.setColor(MIDDLE_LONGITUDE_LATITUDE_COLOR);
paint.setStrokeWidth(1);
}else {
paint.setColor(latitudesColor);
paint.setStrokeWidth(latLongWidth);
}
// paint1.setColor(MIDDLE_LONGITUDE_LATITUDE_COLOR);
if (i == latitudesUpNum || i == latitudesUpNum / 2) {
paint.setPathEffect(pe);
}
else {
paint.setPathEffect(pe);
}
canvas.drawLine(getStrokeLeft(), latitudesSpacing * i
+ getStrokeWidth() + getStrokeTop(), getWidth()
-
getStrokeRight(),
latitudesSpacing * i + getStrokeWidth()
+ getStrokeTop(), paint);
/* path.moveTo(getStrokeLeft(), latitudesSpacing * i
+ getStrokeWidth() + getStrokeTop());
path.lineTo(getWidth()
-
getStrokeRight(),
latitudesSpacing * i + getStrokeWidth()
+ getStrokeTop());
*/
}
if(isDrawDownChart) {
for (int i = 1; i <= latitudesDownNum; i++) {
if (i == latitudesDownNum)
paint.setPathEffect(null);
else
paint.setPathEffect(pe);
canvas.drawLine(getStrokeLeft(),
(getHeight() - getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * i, getWidth()
- getStrokeRight(),
(getHeight() - getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * i, paint);
}
}
}
/**
* 绘制经线
*
* @param canvas 画布
* @param paint
*/
private void drawLongitudes(Canvas canvas, Paint paint) {
Paint paint1 = new Paint();
PathEffect pe = new DashPathEffect(new float[] { 4, 4 }, 1);
TextPaint tp = new TextPaint();
tp.setTextSize(textSize / 4 * 3);
tp.setTypeface(Typeface.DEFAULT_BOLD);
paint1.setColor(longitudesColor);
paint1.setStyle(Paint.Style.STROKE);
paint1.setStrokeWidth(latLongWidth);
paint1.setAntiAlias(true);
paint1.setPathEffect(pe);
Path path1 = new Path();
float width = getWidth() - getStrokeWidth() * 2 - getStrokeLeft()
- getStrokeRight() - 2.0f;
if (longitudesTheme == LongitudesTheme.theme0) {
// 4H
longitudesSpacing = width / (longitudesNum + 1);
for (int i = 1; i <= longitudesNum; i++) {
/* canvas.drawLine(longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), getStrokeWidth() + getStrokeTop(),
longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), latitudesSpacing
* latitudesUpNum + getStrokeWidth()
+ getStrokeTop(), paint); */
if(i == latitudesUpNum / 2){
paint1.setColor(midLongitudesColor);
}else{
paint1.setColor(longitudesColor);
}
path1.moveTo(longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), getStrokeWidth() + getStrokeTop());
path1.lineTo(longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), latitudesSpacing
* latitudesUpNum + getStrokeWidth()
+ getStrokeTop());
/* canvas.drawLine(longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), getHeight() - getStrokeWidth()
- getStrokeBottom(), longitudesSpacing * i
+ getStrokeWidth() +
getStrokeLeft(),
(getHeight()
- getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * latitudesDownNum, paint); */
path1.moveTo(longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), getHeight() - getStrokeWidth()
- getStrokeBottom());
path1.lineTo(longitudesSpacing * i
+ getStrokeWidth() +
getStrokeLeft(),
(getHeight()
- getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * latitudesDownNum);
}
canvas.drawPath(path1, paint1);
ArrayList<String> date = new ArrayList<String>();// 大小必须比经线数多2
date.add("09:30");
date.add("10:30");
date.add("11:30/13:00");
date.add("14:00");
date.add("15:00");
drawTime(canvas, tp, date);
} else if (longitudesTheme == LongitudesTheme.theme1) {
// 24H
longitudesSpacing = width / (longitudesNum + 1);
for (int i = 1; i <= longitudesNum; i++) {
// if (i == longitudesNum / 2 + 1)
// paint.setPathEffect(null);
// else
// paint.setPathEffect(pe);
canvas.drawLine(longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), getStrokeWidth() + getStrokeTop(),
longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), latitudesSpacing
* latitudesUpNum + getStrokeWidth()
+ getStrokeTop(), paint);
if(isDrawDownChart) {
canvas.drawLine(longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), getHeight() - getStrokeWidth()
- getStrokeBottom(), longitudesSpacing * i
+ getStrokeWidth() +
getStrokeLeft(),
(getHeight()
- getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * latitudesDownNum, paint);
}
}
ArrayList<String> date = new ArrayList<String>();// 大小必须比经线数多2
date.add("06:00");
date.add("12:00");
date.add("18:00");
date.add("00:00");
date.add("06:00");
drawTime(canvas, tp, date);
} else if (longitudesTheme == LongitudesTheme.theme2) {
// 昨日20:00-2:30(6.5h),9:00-11:30(2.5h),13:30-15:30(2h)
float total = 6.5f + 2.5f + 2f;
float no1 = width / total * 6.5f;
float no2 = width / total * (6.5f + 2.5f);
for (int i = 0; i < longitudesNum; i++) {
float x;
if (i == 0) {
x = no1;
} else
x = no2;
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getStrokeWidth() + getStrokeTop(), getStrokeLeft()
+ getStrokeWidth() / 2 + x,
latitudesSpacing
* latitudesUpNum + getStrokeWidth()
+ getStrokeTop(), paint);
if(isDrawDownChart) {
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getHeight() - getStrokeWidth() - getStrokeBottom(),
getStrokeLeft() + getStrokeWidth() / 2 + x,
(getHeight() - getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * latitudesDownNum, paint);
}
}
tp.setColor(getResources().getColor(R.color.text_color_5c5f66));
tp.setAntiAlias(true);
ArrayList<String> date = new ArrayList<String>();// 大小必须比经线数多2
date.add("20:00");
date.add("02:30/09:00");
date.add("13:30");
date.add("15:30");
float Y = 0.0f;
if (spacing != 0.0f) {
Y = upChartBottom + textSize;
} else {
Y = getHeight();
}
for (int i = 0; i < date.size(); i++) {
if (i == date.size() - 1) {
canvas.drawText(date.get(i),
getWidth() - getStrokeWidth() - getStrokeRight()
- 2 - tp.measureText(date.get(i)), Y, tp);
} else if (i == 0) {
canvas.drawText(date.get(i), getStrokeLeft()
+ getStrokeWidth() + 2, Y, tp);
} else {
float x;
if (i == 1) {
x = no1;
} else {
x = no2;
}
canvas.drawText(date.get(i), getStrokeWidth() / 2
+ getStrokeLeft() + x - tp.measureText(date.get(i))
/ 2, Y, tp);
}
}
} else if (longitudesTheme == LongitudesTheme.theme3) {
// 8:00-次日2:00(18h)
longitudesSpacing = width / (longitudesNum + 1);
for (int i = 1; i <= longitudesNum; i++) {
canvas.drawLine(longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), getStrokeWidth() + getStrokeTop(),
longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), latitudesSpacing
* latitudesUpNum + getStrokeWidth()
+ getStrokeTop(), paint);
if(isDrawDownChart) {
canvas.drawLine(longitudesSpacing * i + getStrokeWidth()
+ getStrokeLeft(), getHeight() - getStrokeWidth()
- getStrokeBottom(), longitudesSpacing * i
+ getStrokeWidth() +
getStrokeLeft(),
(getHeight()
- getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * latitudesDownNum, paint);
}
}
ArrayList<String> date = new ArrayList<String>();// 大小必须比经线数多2
date.add("08:00");
date.add("14:00");
date.add("20:00");
date.add("02:00");
drawTime(canvas, tp, date);
} else if (longitudesTheme == LongitudesTheme.theme4) {
// 9:00-10:15(1.5h),10:30-11:30(1h),13:30-15:00(1.5h),21:00-次日2:30(5.5h)
float total = 1.5f + 1f + 1.5f + 5.5f;
float no1 = width / total * 1.5f;
float no2 = width / total * (1.5f + 1f);
float no3 = width / total * (1.5f + 1f + 1.5f);
for (int i = 0; i < longitudesNum; i++) {
float x;
if (i == 0) {
x = no1;
} else if (i == 1)
x = no2;
else
x = no3;
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getStrokeWidth() + getStrokeTop(), getStrokeLeft()
+ getStrokeWidth() / 2 + x,
latitudesSpacing
* latitudesUpNum + getStrokeWidth()
+ getStrokeTop(), paint);
if(isDrawDownChart) {
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getHeight() - getStrokeWidth() - getStrokeBottom(),
getStrokeLeft() + getStrokeWidth() / 2 + x,
(getHeight() - getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * latitudesDownNum, paint);
}
}
tp.setColor(getResources().getColor(R.color.text_color_5c5f66));
tp.setAntiAlias(true);
ArrayList<String> date = new ArrayList<String>();// 大小必须比经线数多2
date.add("09:00");
date.add("10:30");
date.add("13:30");
date.add("21:00");
date.add("02:00");
float Y = 0.0f;
if (spacing != 0.0f) {
Y = upChartBottom + textSize;
} else {
Y = getHeight();
}
for (int i = 0; i < date.size(); i++) {
if (i == date.size() - 1) {
canvas.drawText(date.get(i),
getWidth() - getStrokeWidth() - getStrokeRight()
- 2 - tp.measureText(date.get(i)), Y, tp);
} else if (i == 0) {
canvas.drawText(date.get(i), getStrokeLeft()
+ getStrokeWidth() + 2, Y, tp);
} else {
float x;
if (i == 1) {
x = no1;
} else if (i == 2) {
x = no2;
} else {
x = no3;
}
canvas.drawText(date.get(i), getStrokeWidth() / 2
+ getStrokeLeft() + x - tp.measureText(date.get(i))
/ 2, Y, tp);
}
}
} else if (longitudesTheme == LongitudesTheme.theme5) {
// 9:00-10:15(1.25h),10:30-11:30(1h),13:30-15:00(1.5h)
float total = 1.25f + 1f + 1.5f;
float no1 = width / total * 1.25f;
float no2 = width / total * (1.25f + 1f);
for (int i = 0; i < longitudesNum; i++) {
float x;
if (i == 0) {
x = no1;
} else
x = no2;
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getStrokeWidth() + getStrokeTop(), getStrokeLeft()
+ getStrokeWidth() / 2 + x,
latitudesSpacing
* latitudesUpNum + getStrokeWidth()
+ getStrokeTop(), paint);
if(isDrawDownChart) {
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getHeight() - getStrokeWidth() - getStrokeBottom(),
getStrokeLeft() + getStrokeWidth() / 2 + x,
(getHeight() - getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * latitudesDownNum, paint);
}
}
tp.setColor(getResources().getColor(R.color.text_color_5c5f66));
tp.setAntiAlias(true);
ArrayList<String> date = new ArrayList<String>();// 大小必须比经线数多2
date.add("09:00");
date.add("10:30");
date.add("13:30");
date.add("15:00");
float Y = 0.0f;
if (spacing != 0.0f) {
Y = upChartBottom + textSize;
} else {
Y = getHeight();
}
for (int i = 0; i < date.size(); i++) {
if (i == date.size() - 1) {
canvas.drawText(date.get(i),
getWidth() - getStrokeWidth() - getStrokeRight()
- 2 - tp.measureText(date.get(i)), Y, tp);
} else if (i == 0) {
canvas.drawText(date.get(i), getStrokeLeft()
+ getStrokeWidth() + 2, Y, tp);
} else {
float x;
if (i == 1) {
x = no1;
} else {
x = no2;
}
canvas.drawText(date.get(i), getStrokeWidth() / 2
+ getStrokeLeft() + x - tp.measureText(date.get(i))
/ 2, Y, tp);
}
}
} else if (longitudesTheme == LongitudesTheme.theme6) {
// 9:00-10:15(1.25h),10:30-11:30(1h),13:30-15:00(1.5h),21:00-23:30(2.5h)
float total = 1.25f + 1f + 1.5f + 2.5f;
float no1 = width / total * 1.25f;
float no2 = width / total * (1.25f + 1f);
float no3 = width / total * (1.25f + 1f + 1.5f);
for (int i = 0; i < longitudesNum; i++) {
float x;
if (i == 0) {
x = no1;
} else if (i == 1)
x = no2;
else
x = no3;
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getStrokeWidth() + getStrokeTop(), getStrokeLeft()
+ getStrokeWidth() / 2 + x,
latitudesSpacing
* latitudesUpNum + getStrokeWidth()
+ getStrokeTop(), paint);
if(isDrawDownChart) {
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getHeight() - getStrokeWidth() - getStrokeBottom(),
getStrokeLeft() + getStrokeWidth() / 2 + x,
(getHeight() - getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * latitudesDownNum, paint);
}
}
tp.setColor(getResources().getColor(R.color.text_color_5c5f66));
tp.setAntiAlias(true);
ArrayList<String> date = new ArrayList<String>();// 大小必须比经线数多2
date.add("09:00");
date.add("10:30");
date.add("13:30");
date.add("21:00");
date.add("23:30");
float Y = 0.0f;
if (spacing != 0.0f) {
Y = upChartBottom + textSize;
} else {
Y = getHeight();
}
for (int i = 0; i < date.size(); i++) {
if (i == date.size() - 1) {
canvas.drawText(date.get(i),
getWidth() - getStrokeWidth() - getStrokeRight()
- 2 - tp.measureText(date.get(i)), Y, tp);
} else if (i == 0) {
canvas.drawText(date.get(i), getStrokeLeft()
+ getStrokeWidth() + 2, Y, tp);
} else {
float x;
if (i == 1) {
x = no1;
} else if (i == 2) {
x = no2;
} else
x = no3;
canvas.drawText(date.get(i), getStrokeWidth() / 2
+ getStrokeLeft() + x - tp.measureText(date.get(i))
/ 2, Y, tp);
}
}
} else if (longitudesTheme == LongitudesTheme.theme7) {
// 9:00-10:15(1.25h),10:30-11:30(1h),13:30-15:00(1.5h),21:00-23:00(2h)
float total = 1.25f + 1f + 1.5f + 2f;
float no1 = width / total * 1.25f;
float no2 = width / total * (1.25f + 1f);
float no3 = width / total * (1.25f + 1f + 1.5f);
for (int i = 0; i < longitudesNum; i++) {
float x;
if (i == 0) {
x = no1;
} else if (i == 1)
x = no2;
else
x = no3;
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getStrokeWidth() + getStrokeTop(), getStrokeLeft()
+ getStrokeWidth() / 2 + x,
latitudesSpacing
* latitudesUpNum + getStrokeWidth()
+ getStrokeTop(), paint);
if(isDrawDownChart) {
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getHeight() - getStrokeWidth() - getStrokeBottom(),
getStrokeLeft() + getStrokeWidth() / 2 + x,
(getHeight() - getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * latitudesDownNum, paint);
}
}
tp.setColor(getResources().getColor(R.color.text_color_5c5f66));
tp.setAntiAlias(true);
ArrayList<String> date = new ArrayList<String>();// 大小必须比经线数多2
date.add("09:00");
date.add("10:30");
date.add("13:30");
date.add("21:00");
date.add("23:00");
float Y = 0.0f;
if (spacing != 0.0f) {
Y = upChartBottom + textSize;
} else {
Y = getHeight();
}
for (int i = 0; i < date.size(); i++) {
if (i == date.size() - 1) {
canvas.drawText(date.get(i),
getWidth() - getStrokeWidth() - getStrokeRight()
- 2 - tp.measureText(date.get(i)), Y, tp);
} else if (i == 0) {
canvas.drawText(date.get(i), getStrokeLeft()
+ getStrokeWidth() + 2, Y, tp);
} else {
float x;
if (i == 1) {
x = no1;
} else if (i == 2) {
x = no2;
} else
x = no3;
canvas.drawText(date.get(i), getStrokeWidth() / 2
+ getStrokeLeft() + x - tp.measureText(date.get(i))
/ 2, Y, tp);
}
}
} else if (longitudesTheme == LongitudesTheme.theme8) {
// 9:00-10:15(1.25h),10:30-11:30(1h),13:30-15:00(1.5h),21:00-次日1:00(4h)
float total = 1.25f + 1f + 1.5f + 4f;
float no1 = width / total * 1.25f;
float no2 = width / total * (1.25f + 1f);
float no3 = width / total * (1.25f + 1f + 1.5f);
for (int i = 0; i < longitudesNum; i++) {
float x;
if (i == 0) {
x = no1;
} else if (i == 1)
x = no2;
else
x = no3;
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getStrokeWidth() + getStrokeTop(), getStrokeLeft()
+ getStrokeWidth() / 2 + x,
latitudesSpacing
* latitudesUpNum + getStrokeWidth()
+ getStrokeTop(), paint);
if(isDrawDownChart) {
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getHeight() - getStrokeWidth() - getStrokeBottom(),
getStrokeLeft() + getStrokeWidth() / 2 + x,
(getHeight() - getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * latitudesDownNum, paint);
}
}
tp.setColor(getResources().getColor(R.color.text_color_5c5f66));
tp.setAntiAlias(true);
ArrayList<String> date = new ArrayList<String>();// 大小必须比经线数多2
date.add("09:00");
date.add("10:30");
date.add("13:30");
date.add("21:00");
date.add("01:00");
float Y = 0.0f;
if (spacing != 0.0f) {
Y = upChartBottom + textSize;
} else {
Y = getHeight();
}
for (int i = 0; i < date.size(); i++) {
if (i == date.size() - 1) {
canvas.drawText(date.get(i),
getWidth() - getStrokeWidth() - getStrokeRight()
- 2 - tp.measureText(date.get(i)), Y, tp);
} else if (i == 0) {
canvas.drawText(date.get(i), getStrokeLeft()
+ getStrokeWidth() + 2, Y, tp);
} else {
float x;
if (i == 1) {
x = no1;
} else if (i == 2) {
x = no2;
} else
x = no3;
canvas.drawText(date.get(i), getStrokeWidth() / 2
+ getStrokeLeft() + x - tp.measureText(date.get(i))
/ 2, Y, tp);
}
}
}
}
/**
* 绘制经线
*
* @param canvas 画布
* @param paint
*/
private void drawLongitudes1(Canvas canvas, Paint paint) {
PathEffect pe = new DashPathEffect(new float[] { 4, 4 }, 1);
TextPaint tp = new TextPaint();
tp.setTextSize(textSize / 2);
tp.setTypeface(Typeface.DEFAULT_BOLD);
paint.reset();
paint.setColor(longitudesColor);
paint.setStrokeWidth(latLongWidth);
paint.setAntiAlias(true);
paint.setPathEffect(pe);
Path path = new Path();
this.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
float width = getWidth() - getStrokeWidth() * 2 - getStrokeLeft()
- getStrokeRight() - 2.0f;
float total = 0.0f;
ArrayList<String> date = new ArrayList<String>();// 大小必须比经线数多2
for (int i = 0; i < tradetimes.size() + 1; i++) {
if (i != tradetimes.size())
total += tradetimes.get(i).getTimeSlot();
if (i == 0 && i != tradetimes.size())
date.add(MyUtils.getInstance().date2String("HH:mm", tradetimes.get(i).getOpenTimeMillis()));
else if (i == tradetimes.size() && i != 0)
date.add(MyUtils.getInstance().date2String("HH:mm", tradetimes.get(
i - 1).getEndTimeMillis()));
else if (i != 0) {
date.add(
MyUtils.getInstance().date2String("HH:mm", tradetimes.get(
i - 1).getEndTimeMillis()) + "/" +
MyUtils.getInstance().date2String("HH:mm", tradetimes.get(i).getOpenTimeMillis()));
}
}
float index = 0.0f;
for (int i = 0; i < tradetimes.size(); i++) {
float x = width / total * index;
if (i != 0) {
if(i == (tradetimes.size() ) / 2){
// paint.setColor(MIDDLE_LONGITUDE_LATITUDE_COLOR);
paint.setColor(longitudesColor);
}else {
paint.setColor(longitudesColor);
}
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getStrokeWidth() + getStrokeTop(), getStrokeLeft()
+ getStrokeWidth() / 2 + x,
latitudesSpacing
* latitudesUpNum + getStrokeWidth()
+ getStrokeTop(), paint);
if(isDrawDownChart) {
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + x,
getHeight() - getStrokeWidth() - getStrokeBottom(),
getStrokeLeft() + getStrokeWidth() / 2 + x,
(getHeight() - getStrokeWidth() - getStrokeBottom())
- latitudesSpacing * latitudesDownNum, paint);
}
}
index += tradetimes.get(i).getTimeSlot();
}
canvas.drawPath(path, paint);
tp.setColor(getResources().getColor(R.color.text_color_5c5f66));
tp.setAntiAlias(true);
float Y = 0.0f;
if (spacing != 0.0f) {
Y = upChartBottom + textSize;
} else {
Y = getHeight();
}
index = 0.0f;
for (int i = 0; i < date.size(); i++) {
float x = width / total * index;
if (i == date.size() - 1) {
canvas.drawText(date.get(i),
getWidth() - getStrokeWidth() - getStrokeRight()
- 2 - tp.measureText(date.get(i)), Y, tp);
} else if (i == 0) {
canvas.drawText(date.get(i), getStrokeLeft()
+ getStrokeWidth() + 2, Y, tp);
} else {
canvas.drawText(date.get(i), getStrokeWidth() / 2
+ getStrokeLeft() + x - tp.measureText(date.get(i))
/ 2, Y, tp);
}
if (i != date.size() - 1)
index += tradetimes.get(i).getTimeSlot();
}
}
/**
* 绘制上表中的折线
*
* @param canvas
*/
private void drawUpLine(Canvas canvas, Paint paint) {
if (data == null || data.size() == 0)
return;
paint.setStrokeWidth(1);
paint.setAntiAlias(true);
float startWhiteX = getStrokeWidth() + getStrokeLeft() + 1f;
float startWhiteY = (float) (upChartBottom - (data.get(0).getClose() - upMinData)
* upRatio);
paint.setColor(getContext().getResources().getColor(R.color.timechart_line_yellow));
/* */
int dataSize = data.size();
if (dataSize == 1) {
canvas.drawCircle(startWhiteX, startWhiteY, 3, paint);
} else {
Path path = new Path();
Path path1 = new Path();
for (int i = 1; i < data.size() && i < maxDate; i++) {
float endWhiteY = (float) (upChartBottom - (data.get(i)
.getClose() - upMinData) *
upRatio);
float endWhiteX = getStrokeWidth() + getStrokeLeft() + 1f
+ dataSpacing * i;
// canvas.drawLine(startWhiteX, startWhiteY, endWhiteX, endWhiteY,
// paint);
if (i == 1) {
path.moveTo(startWhiteX, startWhiteY);
path1.moveTo(startWhiteX, startWhiteY);
} else {
path.lineTo(startWhiteX, startWhiteY);
path1.lineTo(startWhiteX, startWhiteY);
}
if (i == data.size() - 1 || i == maxDate - 1) {
path.lineTo(endWhiteX, endWhiteY);
path1.lineTo(endWhiteX, endWhiteY);
path1.lineTo(endWhiteX, upChartBottom);
path1.lineTo(getStrokeWidth() + getStrokeLeft() + 1f,
upChartBottom);
path1.lineTo(
getStrokeWidth() + getStrokeLeft() + 1f,
(float) (upChartBottom - (data.get(0).getClose() - upMinData)
* upRatio));
}
startWhiteX = endWhiteX;
startWhiteY = endWhiteY;
}
path1.close();
paint.setStyle(Style.STROKE);
canvas.drawPath(path, paint);
Paint LinerPaint = new Paint();
LinearGradient lg=new LinearGradient(0,0,0,getHeight(),getContext().getResources().getColor(R.color.timechart_line_yellow_start),getContext().getResources().getColor(R.color.timechart_line_yellow_end), Shader.TileMode.MIRROR);
LinerPaint.setShader(lg);
LinerPaint.setStyle(Style.FILL);
LinerPaint.setAlpha(80);
canvas.drawPath(path1, LinerPaint);
}
paint.setColor(getContext().getResources()
.getColor(R.color.timechart_yellow));
startWhiteX = getStrokeWidth() + getStrokeLeft() + 1f;
startWhiteY = (float) (upChartBottom - (data.get(0).getStockMeanLine() - upMinData)
* upRatio);
if (dataSize == 1) {
canvas.drawCircle(startWhiteX, startWhiteY, 2, paint);
} else {
Path path = new Path();
for (int i = 1; i < data.size() && i < maxDate; i++) {
float endWhiteY = (float) (upChartBottom - (data.get(i)
.getStockMeanLine() -
upMinData) * upRatio);
float endWhiteX = getStrokeWidth() + getStrokeLeft() + 1f
+ dataSpacing * i;
// Log.w("TimeChartView", "startWhiteX=" + startWhiteX + " startWhiteY=" + startWhiteY + " endWhiteX=" + endWhiteX + " endWhiteY=" + endWhiteY);
// canvas.drawLine(startWhiteX, startWhiteY, endWhiteX, endWhiteY,
// paint);
if (i == 1) {
path.moveTo(startWhiteX, startWhiteY);
} else {
path.lineTo(startWhiteX, startWhiteY);
}
if (i == data.size() - 1 || i == maxDate - 1) {
path.lineTo(endWhiteX, endWhiteY);
}
startWhiteX = endWhiteX;
startWhiteY = endWhiteY;
}
paint.setStyle(Style.STROKE);
canvas.drawPath(path, paint);
}
}
Path path = new Path();
Path fillpath = new Path();
/**
* 绘制上表中的折线。 使曲线更加平滑
*
* @param canvas
*/
private void drawCubicUpLine(Canvas canvas, Paint paint) {
if (data == null)
return;
paint.setStrokeWidth(1);
paint.setAntiAlias(true);
float startWhiteX = getStrokeWidth() + getStrokeLeft() + 1f;
float startWhiteY = (float) (upChartBottom - (data.get(0).getClose() - upMinData)
* upRatio);
paint.setColor(getContext().getResources().getColor(R.color.line_blue));
int dataSize = data.size();
// 画分时线
if (dataSize == 1) {
canvas.drawCircle(startWhiteX, startWhiteY, 3, paint);
} else {
path.reset();
float prevDx = 0f;
float prevDy = 0f;
float curDx = 0f;
float curDy = 0f;
float preWhiteX = startWhiteX;
float preWhiteY = startWhiteY;
float endWhiteX = 0f;
float endWhiteY = 0f;
path.moveTo(startWhiteX, startWhiteY);
for (int i = 1; i < data.size() && i < maxDate; i++) {
endWhiteX = getStrokeWidth() + getStrokeLeft() + 1f
+ dataSpacing * i;
endWhiteY = (float) (upChartBottom - (data.get(i).getClose() - upMinData)
* upRatio);
// paint.setColor(getContext().getResources().getColor(
// R.color.line_blue));
prevDx = (startWhiteX - preWhiteX) * 0.2f;
prevDy = (startWhiteY - preWhiteY) * 0.2f;
curDx = (endWhiteX - startWhiteX) * 0.2f;
curDy = (endWhiteY - startWhiteY) * 0.2f;
path.cubicTo(startWhiteX + prevDx, startWhiteY + prevDy,
endWhiteX - curDx, endWhiteY - curDy, endWhiteX,
endWhiteY);
// if (i == 1)
// path.moveTo(startWhiteX, startWhiteY);
// path.lineTo(startWhiteX, startWhiteY);
// if (i == data.size() - 1 || i == maxDate - 1) {
// path.lineTo(endWhiteX, endWhiteY);
// path.lineTo(endWhiteX, upChartBottom);
// path.lineTo(getStrokeWidth() + getStrokeLeft() + 1f,
// upChartBottom);
// path.lineTo(getStrokeWidth() + getStrokeLeft() + 1f,
// (float) (upChartBottom - (data.get(0).getClose() - upMinData)
// * upRatio));
// }
preWhiteX = startWhiteX;
preWhiteY = startWhiteY;
startWhiteX = endWhiteX;
startWhiteY = endWhiteY;
}
fillpath.reset();
fillpath.addPath(path);
drawFill(canvas, paint, fillpath, getStrokeWidth()
+ getStrokeLeft() + 1f, endWhiteX, upChartBottom);
// path.close();
// paint.setStyle(Style.FILL);
// paint.setAlpha(50);
// canvas.drawPath(path, paint);
paint.setStyle(Style.STROKE);
canvas.drawPath(path, paint);
}
// 画分时均线
paint.setColor(getContext().getResources()
.getColor(R.color.line_yellow));
startWhiteX = getStrokeWidth() + getStrokeLeft() + 1f;
startWhiteY = (float) (upChartBottom - (data.get(0).getStockMeanLine() - upMinData)
* upRatio);
if (dataSize == 1) {
canvas.drawCircle(startWhiteX, startWhiteY, 2, paint);
} else {
for (int i = 1; i < data.size() && i < maxDate; i++) {
float endWhiteY = (float) (upChartBottom - (data.get(i)
.getStockMeanLine() -
upMinData) * upRatio);
float endWhiteX = getStrokeWidth() + getStrokeLeft() + 1f
+ dataSpacing * i;
canvas.drawLine(startWhiteX, startWhiteY, endWhiteX, endWhiteY,
paint);
startWhiteX = endWhiteX;
startWhiteY = endWhiteY;
}
}
}
protected void drawFill(Canvas canvas, Paint paint, Path spline,
float from, float to, float bottom) {
spline.lineTo(to, bottom);
spline.lineTo(from, bottom);
spline.close();
paint.setStyle(Style.FILL);
paint.setAlpha(50);
canvas.drawPath(spline, paint);
paint.setAlpha(255);
}
/**
* 绘制上表Y轴文字
*
* @param canvas
* @param paint
*/
private void drawUpAxisXTitle(Canvas canvas, TextPaint paint,
float dataWidth) {
paint.setColor(getResources().getColor(R.color.text_color_5c5f66));
paint.setAntiAlias(true);
if (!isDrawOutside) {
float YData = upMaxData;
float zDF = 0;
if (preClose != 0)
zDF = ((YData - preClose) / preClose) * 100;
float spacing = (upMaxData - upMinData) / (latitudesUpNum);
for (int i = 0; i < latitudesUpNum + 1; i++) {
String zdf = Parse.getInstance().parse2String(zDF) + "%";
if ("-0.00%".equals(zdf))
zdf = "0.00%";
if (i > 2)
paint.setColor(getContext().getResources().getColor(
R.color.green1));
else if (i < 2)
paint.setColor(getContext().getResources().getColor(
R.color.red));
else
paint.setColor(getContext().getResources().getColor(
R.color.text_color_5c5f66));
if (i == 0) {
canvas.drawText(
Parse.getInstance().parse2String(upMaxData, num),
getStrokeWidth() + getStrokeLeft() + 2,
getStrokeWidth() + getStrokeTop() + textSize, paint);
// 绘制右边刻度
canvas.drawText(zdf,
getWidth() - getStrokeRight() - getStrokeWidth()
/ 2 - paint.measureText(zdf) - 2,
getStrokeWidth() + getStrokeTop() + textSize
+ latitudesSpacing * i, paint);
} else if (i == latitudesUpNum) {
canvas.drawText(
Parse.getInstance().parse2String(upMinData, num),
getStrokeWidth() + getStrokeLeft() + 2,
(getStrokeWidth() + getStrokeTop() + latitudesSpacing
* latitudesUpNum) - 2, paint);
// 绘制右边的
canvas.drawText(
zdf,
getWidth() - getStrokeRight() - getStrokeWidth()
/ 2 - paint.measureText(zdf) - 2,
(getStrokeWidth() + getStrokeTop() + latitudesSpacing
* i) - 2, paint);
} else {
canvas.drawText(Parse.getInstance()
.parse2String(YData, num), getStrokeWidth()
+ getStrokeLeft() + 2, getStrokeWidth()
+ getStrokeTop() +
textSize / 2 +
latitudesSpacing
* i, paint);
// 绘制右边的
canvas.drawText(zdf,
getWidth() - getStrokeRight() - getStrokeWidth()
/ 2 - paint.measureText(zdf) - 2,
getStrokeWidth() + getStrokeTop() + textSize / 2
+ latitudesSpacing * i, paint);
}
YData -= spacing;
if (preClose != 0)
zDF = ((YData - preClose) / preClose) * 100;
}
} else {
float YData = upMaxData;
float zDF = 0;
if (preClose != 0)
zDF = ((YData - preClose) / preClose) * 100;
float spacing = (upMaxData - upMinData) / (latitudesUpNum);
for (int i = 0; i < latitudesUpNum + 1; i++) {
String zdf = Parse.getInstance().parse2String(zDF) + "%";
if ("-0.00%".equals(zdf))
zdf = "0.00%";
if (i > 2)
paint.setColor(getContext().getResources().getColor(
R.color.green1));
else if (i < 2)
paint.setColor(getContext().getResources().getColor(
R.color.red));
else
paint.setColor(getContext().getResources().getColor(
R.color.text_color_5c5f66));
if (i == 0) {
canvas.drawText(
Parse.getInstance().parse2String(YData, num),
getStrokeLeft()
- getStrokeWidth()
/ 2
- 2
- paint.measureText(Parse.getInstance()
.parse2String(YData, num)),
getStrokeWidth() + getStrokeTop() + textSize
+ latitudesSpacing * i, paint);
// 绘制右边刻度
canvas.drawText(zdf, getWidth() - getStrokeRight() + 2,
getStrokeWidth() + getStrokeTop() + textSize
+ latitudesSpacing * i, paint);
} else if (i == latitudesUpNum) {
canvas.drawText(
Parse.getInstance().parse2String(YData, num),
getStrokeLeft()
- getStrokeWidth()
/ 2
- 2
- paint.measureText(Parse.getInstance()
.parse2String(YData, num)),
(getStrokeWidth() + getStrokeTop() + latitudesSpacing
* i) - 2, paint);
// 绘制右边的
canvas.drawText(
zdf,
getWidth() - getStrokeRight() + 2,
(getStrokeWidth() + getStrokeTop() + latitudesSpacing
* i) - 2, paint);
} else {
canvas.drawText(
Parse.getInstance().parse2String(YData, num),
getStrokeLeft()
- getStrokeWidth()
/ 2
- 2
- paint.measureText(Parse.getInstance()
.parse2String(YData, num)),
getStrokeWidth() + getStrokeTop() + textSize / 2
+ latitudesSpacing * i, paint);
// 绘制右边的
canvas.drawText(zdf, getWidth() - getStrokeRight() + 2,
getStrokeWidth() + getStrokeTop() + textSize / 2
+ latitudesSpacing * i, paint);
}
YData -= spacing;
if (preClose != 0)
zDF = ((YData - preClose) / preClose) * 100;
}
}
}
/**
* 绘制下表柱形图
*
* @param canvas 画布
*/
private void drawDownColumnChart(Canvas canvas, Paint paint) {
if (data == null)
return;
paint.setStrokeWidth(columnWidth);
paint.setAntiAlias(true);
// Map<String, Object> map = timesList.get(0);
// float zuoShow = Float.parseFloat(map.get("zuoShow").toString());
for (int i = 0; i < data.size() && i < maxDate; i++) {
float chengJiaoLiang = (float) data.get(i).getCjl();
paint.setColor(data.get(i).getColor());
float x = getStrokeWidth() + getStrokeLeft() + 1.0f + dataSpacing
* i;
canvas.drawLine(x, downChartBottom, x, downChartBottom
- chengJiaoLiang * downRatio, paint);
}
}
/**
* 绘制下表Y轴X坐标
*
* @param canvas
* @param paint
* @param dataWidth
*/
private void drawDownAxisXTitle(Canvas canvas, TextPaint paint,
float dataWidth) {
paint.setColor(getResources().getColor(R.color.text_color_5c5f66));
paint.setAntiAlias(true);
if (!isDrawOutside) {
float YData = downMinData;
float spacing = (downMaxData - downMinData) / (latitudesDownNum);
for (int i = 0; i < latitudesDownNum + 1; i++) {
if (i == latitudesDownNum) {
canvas.drawText(
Parse.getInstance().parse2CNStringWan(YData, 2,
false), getStrokeWidth() + getStrokeLeft()
+ 2, downChartBottom + textSize
- latitudesSpacing * i, paint);
} else if (i == 0) {
canvas.drawText("0"
/* Parse.getInstance().parse2CNString(YData) */,
getStrokeWidth() + getStrokeLeft() + 2,
downChartBottom - latitudesSpacing * i - 2, paint);
} else {
canvas.drawText(
Parse.getInstance().parse2CNStringWan(YData, 2,
false), getStrokeWidth() + getStrokeLeft()
+ 2, downChartBottom + textSize / 2
- latitudesSpacing * i, paint);
}
YData += spacing;
}
} else {
float YData = downMinData;
float spacing = (downMaxData - downMinData) / (latitudesDownNum);
for (int i = 0; i < latitudesDownNum + 1; i++) {
if (i == latitudesDownNum) {
canvas.drawText(
Parse.getInstance().parse2CNStringWan(YData, 2,
false),
getStrokeLeft()
- getStrokeWidth()
/ 2
- 2
- paint.measureText(Parse.getInstance()
.parse2CNStringWan(YData, 2, false)),
downChartBottom + textSize - latitudesSpacing * i,
paint);
} else if (i == 0) {
canvas.drawText(
"0"
/* Parse.getInstance().parse2CNString(YData) */,
getStrokeLeft() - getStrokeWidth() / 2 - 2
- paint.measureText("0"/*
* Parse.getInstance(
* )
* .parse2CNString(
* YData)
*/),
downChartBottom - latitudesSpacing * i - 2, paint);
} else {
canvas.drawText(
Parse.getInstance().parse2CNStringWan(YData, 2,
false),
getStrokeLeft()
- getStrokeWidth()
/ 2
- 2
- paint.measureText(Parse.getInstance()
.parse2CNStringWan(YData, 2, false)),
downChartBottom + textSize / 2 - latitudesSpacing
* i, paint);
}
YData += spacing;
}
}
}
/**
* 绘制时间
*
* @param canvas
* @param paint
*/
private void drawTime(Canvas canvas, TextPaint paint, ArrayList<String> date) {
paint.setColor(getResources().getColor(R.color.text_color_5c5f66));
paint.setAntiAlias(true);
float Y = 0.0f;
if (spacing != 0.0f) {
Y = upChartBottom + textSize;
} else {
Y = getHeight();
}
for (int i = 0; i < date.size(); i++) {
if (i == date.size() - 1) {
canvas.drawText(date.get(i),
getWidth() - getStrokeWidth() - getStrokeRight() - 2
- paint.measureText(date.get(i)), Y, paint);
} else if (i == 0) {
canvas.drawText(date.get(i), getStrokeLeft() + getStrokeWidth()
+ 2, Y, paint);
} else {
// if ("18:00".equals(date.get(i))) {
// canvas.drawText(
// date.get(i),
// getStrokeWidth() + getStrokeLeft()
// + longitudesSpacing
// * ((longitudesNum + 2 - 1) / 2)
// - paint.measureText(date.get(i)) / 2, Y,
// paint);
// } else {
canvas.drawText(date.get(i),
getStrokeWidth() + getStrokeLeft() + longitudesSpacing
* i -
paint.measureText(date.get(i)) / 2, Y,
paint);
// }
}
}
}
/**
* 绘制十字光标
*
* @param canvas 画布
*/
private void drawCrossLine(Canvas canvas, Paint paint) {
if (!isShowCross)
return;
paint.setStrokeWidth(1);
paint.setColor(getContext().getResources().getColor(
R.color.cross_line_color));
paint.setAntiAlias(true);
int rSpacing = 12;
// 绘制十字光标横线
canvas.drawLine(getStrokeLeft() + getStrokeWidth(), crossY, crossX
- rSpacing >= getStrokeLeft() +
getStrokeWidth() ?
crossX
- rSpacing : getStrokeLeft() +
getStrokeWidth(), crossY, paint);
// 绘制十字光标横线
canvas.drawLine(crossX + rSpacing <= getWidth() - getStrokeWidth()
- getStrokeRight() ? crossX + rSpacing : getWidth()
-
getStrokeWidth() -
getStrokeRight(), crossY,
getWidth()
- getStrokeWidth() - getStrokeRight(), crossY, paint);
// 绘制上表十字光标竖线
canvas.drawLine(crossX, getStrokeWidth() + getStrokeTop(), crossX,
crossY - rSpacing >= getStrokeWidth() + getStrokeTop() ? crossY
- rSpacing
: getStrokeWidth() +
getStrokeTop(), paint);
// 绘制上表十字光标竖线
canvas.drawLine(crossX, crossY + rSpacing <= upChartBottom ? crossY
+ rSpacing
: upChartBottom, crossX, upChartBottom, paint);
if(isDrawDownChart) {
// 绘制下表十字光标竖线
canvas.drawLine(crossX, getHeight() - getStrokeWidth()
- getStrokeBottom(), crossX, downChartBottom - downChartHeight,
paint);
}
// 绘制十字光标交叉小圆点
Paint p = new Paint();
p.setColor(getContext().getResources().getColor(R.color.cross_line_color));
p.setAntiAlias(true);
p.setAlpha(150);
canvas.drawCircle(crossX, crossY, 12, p);
p.setAlpha(255);
canvas.drawCircle(crossX, crossY, 6, p);
// 绘制十字光标中心数据
TextPaint tp = new TextPaint();
tp.setColor(Color.WHITE);
tp.setTextSize(textSize);
tp.setAntiAlias(true);
tp.setTypeface(Typeface.DEFAULT_BOLD);
paint.setColor(getResources().getColor(R.color.cross_line_color));
paint.setStrokeWidth(textSize + 6);
String leftDatas = Parse.getInstance().parse2String(leftData, num);
String rightDatas = Parse.getInstance().parse2String(rightData) + "%";
if (!isDrawOutside) {
float topS = crossY - (textSize + 6) / 2 <= getStrokeTop()
+ getStrokeWidth() ? getStrokeTop() +
getStrokeWidth()
+ (textSize + 6) / 2
: crossY;
topS = topS + (textSize + 6) / 2 >= upChartBottom ? upChartBottom
- (textSize + 6) / 2 : topS;
float size = MyUtils.getInstance().dp2px(getContext(), 10);
float dataWidth = tp.measureText(leftDatas);
canvas.drawLine(getStrokeLeft() + getStrokeWidth() / 2 + dataWidth
+ size, topS, getStrokeLeft() + getStrokeWidth() / 2, topS,
paint);
canvas.drawText(leftDatas, getStrokeLeft() + getStrokeWidth() / 2
+ size / 2, topS + textSize / 2 - 3, tp);
if (rightData > 0.0f) {
rightDatas = "+" + rightDatas;
}
dataWidth = tp.measureText(rightDatas);
canvas.drawLine(getWidth() - getStrokeRight() - getStrokeWidth()
/ 2 - dataWidth - size, topS,
getWidth() - getStrokeWidth()
/ 2 - getStrokeRight(), topS, paint);
canvas.drawText(rightDatas, getWidth() - getStrokeRight()
- getStrokeWidth() / 2 - dataWidth - size / 2, topS
+ textSize /
2 - 3, tp);
String bottomDatas = Parse.getInstance().parse2CNStringWan(
bottomData, 2, false);
dataWidth = tp.measureText(bottomDatas);
float Y = downChartBottom - textSize / 2 - 3;
float drawX = crossX - (dataWidth + size) / 2;
if (drawX <= getStrokeLeft() + getStrokeWidth() / 2) {
drawX = getStrokeLeft() + getStrokeWidth() / 2;
} else if (drawX >= getWidth() - getStrokeRight()
- getStrokeWidth() / 2 - dataWidth - size) {
drawX = getWidth() - getStrokeRight() - getStrokeWidth() / 2
- dataWidth - size;
}
canvas.drawLine(drawX, Y, drawX + dataWidth + size, Y, paint);
canvas.drawText(bottomDatas, drawX + size / 2, Y + textSize / 2, tp);
/**
* 绘制时间
*/
String timeDatas = MyUtils.getInstance().date2String("HH:mm", time);
dataWidth = tp.measureText(timeDatas);
float timeY = upChartBottom + textSize / 2;
float drawTimeX = crossX - (dataWidth + size) / 2;
if (drawTimeX <= getStrokeLeft() + getStrokeWidth() / 2) {
drawTimeX = getStrokeLeft() + getStrokeWidth() / 2;
} else if (drawTimeX >= getWidth() - getStrokeRight()
- getStrokeWidth() / 2 - dataWidth - size) {
drawTimeX = getWidth() - getStrokeRight() - getStrokeWidth() / 2
- dataWidth - size;
}
canvas.drawLine(drawTimeX, timeY, drawTimeX + dataWidth + size, timeY, paint);
canvas.drawText(timeDatas, drawTimeX + size / 2, timeY + textSize / 2, tp);
} else {
float topS = crossY - (textSize + 6) / 2 <= getStrokeTop()
+ getStrokeWidth() ? getStrokeTop() +
getStrokeWidth()
+ (textSize + 6) / 2
: crossY;
topS = topS + (textSize + 6) / 2 >= upChartBottom ? upChartBottom
- (textSize + 6) / 2 : topS;
float size = MyUtils.getInstance().dp2px(getContext(), 1);
float dataWidth = tp.measureText(leftDatas);
canvas.drawLine(getStrokeLeft() - getStrokeWidth() / 2 - dataWidth
- size, topS, getStrokeLeft() - getStrokeWidth() / 2, topS,
paint);
canvas.drawText(leftDatas, getStrokeLeft() - getStrokeWidth() / 2
- dataWidth - size / 2, topS + textSize / 2 - 3, tp);
if (rightData > 0.0f) {
rightDatas = "+" + rightDatas;
}
dataWidth = tp.measureText(rightDatas);
canvas.drawLine(getWidth() - getStrokeRight(), topS, getWidth()
- getStrokeRight() + dataWidth +
size, topS, paint);
canvas.drawText(rightDatas, getWidth() - getStrokeRight() + size
/ 2,
topS + textSize / 2 - 3, tp);
String bottomDatas = Parse.getInstance().parse2CNStringWan(
bottomData, 2, false);
dataWidth = tp.measureText(bottomDatas);
float Y = downChartBottom - textSize / 2 - 3;
float drawX = crossX - (dataWidth + size) / 2;
if (drawX <= getStrokeLeft() + getStrokeWidth() / 2) {
drawX = getStrokeLeft() + getStrokeWidth() / 2;
} else if (drawX >= getWidth() - getStrokeRight()
- getStrokeWidth() / 2 - dataWidth - size) {
drawX = getWidth() - getStrokeRight() - getStrokeWidth() / 2
- dataWidth - size;
}
canvas.drawLine(drawX, Y, drawX + dataWidth + size, Y, paint);
canvas.drawText(bottomDatas, drawX + size / 2, Y + textSize / 2, tp);
/**
* 绘制时间
*/
String timeDatas = MyUtils.getInstance().date2String("HH:mm", time);
dataWidth = tp.measureText(timeDatas);
float timeY = upChartBottom + textSize / 2;
float drawTimeX = crossX - (dataWidth + size) / 2;
if (drawTimeX <= getStrokeLeft() + getStrokeWidth() / 2) {
drawTimeX = getStrokeLeft() + getStrokeWidth() / 2;
} else if (drawTimeX >= getWidth() - getStrokeRight()
- getStrokeWidth() / 2 - dataWidth - size) {
drawTimeX = getWidth() - getStrokeRight() - getStrokeWidth() / 2
- dataWidth - size;
}
canvas.drawLine(drawTimeX, timeY, drawTimeX + dataWidth + size, timeY, paint);
canvas.drawText(timeDatas, drawTimeX + size / 2, timeY + textSize / 2, tp);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 按下
touchDownX = event.getX();
touchDownY = event.getY();
if (touchDownX < getStrokeLeft()
|| touchDownX > getWidth() - getStrokeRight()) {
return super.onTouchEvent(event);
}
movedX = touchDownX;
movedY = touchDownY;
moveRawX = event.getRawX();
moveRawY = event.getRawY();
isMoved = false;
isReleased = false;
isStartMoved = false;
if (mRunnable != null) {
removeCallbacks(mRunnable);
postDelayed(mRunnable, 200);
}
getParent().requestDisallowInterceptTouchEvent(true);
return true;
case MotionEvent.ACTION_POINTER_DOWN:
// 多点
if (touchDownX < getStrokeLeft()
|| touchDownX > getWidth() - getStrokeRight()) {
return super.onTouchEvent(event);
}
return true;
case MotionEvent.ACTION_MOVE:
// 触摸中
if (touchDownX < getStrokeLeft()
|| touchDownX > getWidth() - getStrokeRight()) {
return super.onTouchEvent(event);
}
// 子控件相对于父布局若达到滚动条件,则让父布局拦截触摸事件
/* if (Math.abs(event.getRawY() - moveRawY) > 50 && Math.abs(event.getRawX() - moveRawX) < 150) {
isMoved = true;
getParent().requestDisallowInterceptTouchEvent(false);
}*/
isMoved = false;
if (isStartMoved && !isMoved) {
movedX = event.getX();
movedY = event.getY();
viewCrossLine();
}
break;
case MotionEvent.ACTION_UP:
// 拿起
if (touchDownX < getStrokeLeft()
|| touchDownX > getWidth() - getStrokeRight()) {
return super.onTouchEvent(event);
}
if (!isStartMoved && !isMoved) {
if (Math.abs(Math.abs(event.getX()) - Math.abs(touchDownX)) < 30
&& Math.abs(Math.abs(event.getY())
- Math.abs(touchDownY)) < 30) {
if (mOnTimeChartClickListener != null)
mOnTimeChartClickListener.click(this);
}
}
isReleased = true;
isShowCross = false;
isStartMoved = false;
if (l != null)
l.isMove(this, isShowCross, crossX);
invalidate();
return true;
default:
break;
}
return super.onTouchEvent(event);
}
/**
* 设置数据
*
* @param data 分时数据
* @param upMaxData 最大价
* @param upMinData 最小价
* @param downMinData 成交量数据
* @param downMinData 最小成交量
* @param preClose 昨收价
* @param isHighLow 是否将最高最低价作为基准,否则取收盘价中的最高最低
*/
public void setTimesList(Vector<TimeData> data, List<TRADETIME> tradetimes, float upMaxData,
float upMinData, float downMinData, float preClose,
boolean isHighLow) {
// handler.removeCallbacks(mTimeListThread);
// mTimeListThread.setData(data, upMaxData, upMinData, downMinData,
// preClose, isHighLow);
// handler.post(mTimeListThread);
/*
* if (!isAlive(mTimeListThread)) { mTimeListThread = new
* TimeListThread(data, upMaxData, upMinData, downMinData, preClose,
* isHighLow); mTimeListThread.start(); }
*/
executorService.execute(new TimeListThread(data, tradetimes, upMaxData, upMinData,
downMinData, preClose, isHighLow));
}
/**
* 计算
*
* @author dingrui
*/
boolean running = false;
class TimeListThread implements Runnable {
private Vector<TimeData> dataOld;
private List<TRADETIME> tradetimesOld;// 时间段
private float upMaxData;
private float upMinData;
private float downMinData;
private float downMaxData;
private float preClose;
private boolean isHighLow;// 是否直接取最高最低
public TimeListThread(Vector<TimeData> data, List<TRADETIME> tradetimes, float upMaxData,
float upMinData, float downMinData, float preClose,
boolean isHighLow) {
this.dataOld = data;
this.tradetimesOld = tradetimes;
this.upMaxData = upMaxData;
this.upMinData = upMinData;
this.downMinData = downMinData;
this.preClose = preClose;
this.isHighLow = isHighLow;
}
@Override
public void run() {
if (running)
return;
synchronized (this) {
if (tradetimesOld == null || tradetimesOld.size() <= 0) {
return;
}
running = true;
List<Long> timeMillis = new ArrayList<>();
float timeS = 0.0f;
List<TRADETIME> tradetimes = new ArrayList<>();
for (int i = 0; i < tradetimesOld.size(); i++) {
TRADETIME oldItem = tradetimesOld.get(i);
TRADETIME item = new TRADETIME();
item.setOpenTime(oldItem.getOpenTime());
item.setEndTime(oldItem.getEndTime());
tradetimes.add(item);
}
for (int i = 0; i < tradetimes.size(); i++) {
String openTime = Parse.getInstance().isNull(tradetimes.get(i).getOpenTime());
String endTime = Parse.getInstance().isNull(tradetimes.get(i).getEndTime());
int openH, openM;
int endH, endM;
if (openTime.length() == 1) {
openH = 0;
openM = 0;
} else if (openTime.length() == 3) {
openH = Parse.getInstance().parseInt(openTime.substring(0, 1));
openM = Parse.getInstance().parseInt(openTime.substring(1, openTime.length()));
} else {
openH = Parse.getInstance().parseInt(openTime.substring(0, 2));
openM = Parse.getInstance().parseInt(openTime.substring(2, openTime.length()));
}
if (endTime.length() == 1) {
endH = 0;
endM = 0;
} else if (endTime.length() == 3) {
endH = Parse.getInstance().parseInt(endTime.substring(0, 1));
endM = Parse.getInstance().parseInt(endTime.substring(1, endTime.length()));
} else {
endH = Parse.getInstance().parseInt(endTime.substring(0, 2));
endM = Parse.getInstance().parseInt(endTime.substring(2, endTime.length()));
}
float min;
int hour;
int openH1 = openH, openM1 = openM;
int endH1 = endH, endM1 = endM;
if (endM1 < openM1) {
min = (endM1 + 60 - openM1) / 60.0f;
endH1 = endH1 - 1;
} else {
min = (endM1 - openM1) / 60.0f;
}
if (endH1 <= openH1) {
hour = endH1 + 24 - openH1;
tradetimes.get(i).setOpenTimes(String.format("2016-01-01 %02d:%02d:00", openH, openM));
tradetimes.get(i).setEndTimes(String.format("2016-01-02 %02d:%02d:00", endH, endM));
} else {
hour = endH1 - openH1;
tradetimes.get(i).setOpenTimes(String.format("2016-01-02 %02d:%02d:00", openH, openM));
tradetimes.get(i).setEndTimes(String.format("2016-01-02 %02d:%02d:00", endH, endM));
}
String minS = String.format("%.2f", hour + min);
tradetimes.get(i).setTimeSlot(Parse.getInstance().parseFloat(minS));
timeS += tradetimes.get(i).getTimeSlot();
for (long j = tradetimes.get(i).getOpenTimeMillis();
j <= tradetimes.get(i).getEndTimeMillis(); j += 60000) {// 60000毫秒=1分钟
if (i == 0) {
timeMillis.add(j);
} else {
if (j != tradetimes.get(i).getOpenTimeMillis()) {
timeMillis.add(j);
}
}
}
}
maxDate = (int) (timeS * 60) + 1;
Vector<TimeData> data = new Vector<>();
try {
if (dataOld != null && dataOld.size() > 0 && timeMillis.size() > 0) {
for (int i = 0; i < dataOld.size() && i < timeMillis.size(); i++) {
TimeData oldItem = dataOld.get(i);
double close;
if (i > 0) {
close = data.get(i - 1).getClose();
} else {
close = preClose;
}
TimeData item = new TimeData();
item.setTime(timeMillis.get(i));
item.setClose(oldItem.getClose());
item.setCjlYS(oldItem.getCjlYS());
item.setCjeYS(oldItem.getCjeYS());
item.setCjl(oldItem.getCjl());
item.setCje(oldItem.getCje());
item.setStockMeanLine(oldItem.getStockMeanLine());
double zde = oldItem.getClose() - preClose;
double zdf = zde / preClose * 100;
item.setZde(zde);
item.setZdf(zdf);
if (item.getClose() > close) {
item.setColor(getResources().getColor(R.color.red));
} else if (item.getClose() < close) {
item.setColor(getResources().getColor(R.color.green));
} else {
item.setColor(Color.WHITE);
}
data.add(item);
}
if (!isHighLow) {
upMaxData = (float) data.get(0).getClose();
upMinData = upMaxData;
}
downMaxData = (float) data.get(0).getCjl();
for (int i = 1; i < data.size() && i < maxDate; i++) {
if (!isHighLow) {
upMaxData = (float) (data.get(i).getClose() < upMaxData ? upMaxData
: data.get(i).getClose());
upMinData = (float) (data.get(i).getClose() > upMinData ? upMinData
: data.get(i).getClose());
upMaxData = (float) (data.get(i).getStockMeanLine() < upMaxData ? upMaxData
: data.get(i).getStockMeanLine());
upMinData = (float) (data.get(i).getStockMeanLine() > upMinData ? upMinData
: data.get(i).getStockMeanLine());
}
// 下表相关
if (data.size() == 0) {
return;
}
downMaxData = (float) (data.get(i).getCjl() < downMaxData ? downMaxData
: data.get(i).getCjl());
}
} else {
downMaxData = 0;
}
} catch (ArrayIndexOutOfBoundsException ex) {
ex.printStackTrace();
}
Bundle bundle = new Bundle();
bundle.putSerializable("data",
data);
bundle.putSerializable("tradetimes", (Serializable) tradetimes);
bundle.putFloat("upMaxData", upMaxData);
bundle.putFloat("upMinData", upMinData);
bundle.putFloat("downMinData", downMinData);
bundle.putFloat("downMaxData", downMaxData);
bundle.putFloat("preClose", preClose);
// TimeChartView.this.data = data;
// TimeChartView.this.upMaxData = upMaxData;
// TimeChartView.this.upMinData = upMinData;
// TimeChartView.this.downMinData = downMinData;
// TimeChartView.this.downMaxData = downMaxData;
// TimeChartView.this.preClose = preClose;
// if (!isShowCross)
// postInvalidate();
Message msg = handler.obtainMessage();
msg.what = 0x2;
msg.setData(bundle);
handler.sendMessage(msg);
running = false;
}
}
}
/**
* 设置上表与下表中间的日期与时间的文字大小
*
* @param textSize 像素单位
* @return
*/
public GridChartView settextSize(float textSize) {
this.textSize = textSize;
return this;
}
/**
* 获取上表与下表中间的日期与时间的文字大小
*
* @return 像素单位
*/
public float gettextSize() {
return textSize;
}
/**
* 设置上表纬线条数
*
* @param latitudesUpNum
* @return
*/
public GridChartView setLatitudesUpNum(int latitudesUpNum) {
if (latitudesUpNum < 3) {
latitudesUpNum = DEFAULT_LATITUDE_UP_NUM;
}
this.latitudesUpNum = latitudesUpNum;
return this;
}
/**
* 设置经纬线颜色
*
* @param longitudesColor
* @return
*/
public GridChartView setLongitudesColor(int longitudesColor) {
this.longitudesColor = longitudesColor;
return this;
}
/**
* 设置经、纬线宽度
*
* @param latLongWidth
* @return
*/
public GridChartView setLatLongWidth(float latLongWidth) {
if (latLongWidth < DEFAULT_LATITUDE_LONGITUDE_WIDTH) {
latLongWidth = DEFAULT_LATITUDE_LONGITUDE_WIDTH;
}
this.latLongWidth = latLongWidth;
return this;
}
/**
* 返回是否绘制经线
*
* @return
*/
public boolean isDrawLongitudes() {
return isDrawLongitudes;
}
/**
* 获取上表高度
*
* @return
*/
public float getUpChartHeight() {
return Math.abs(upChartHeight);
}
/**
* 设置是否绘制经线
*
* @param isDrawLongitudes true绘制,false不绘制
* @return
*/
public GridChartView setDrawLongitudes(boolean isDrawLongitudes) {
this.isDrawLongitudes = isDrawLongitudes;
return this;
}
/**
* 返回是否绘制纬线
*
* @return
*/
public boolean isDrawLatitudes() {
return isDrawLatitudes;
}
/**
* 设置是否显示纬线
*
* @param isDrawLatitudes true绘制,false不绘制
* @return
*/
public GridChartView setDrawLatitudes(boolean isDrawLatitudes) {
this.isDrawLatitudes = isDrawLatitudes;
return this;
}
/**
* 设置上表与下表间距(如果设置值小于默认字体大小,则设置成默认字体大小大5像素;如果设置值大于默认字体大小+5大小,那么字体也随之变化;
* 如果设置值等于0.0f,那么时间文字将绘制则底部,并且上表与下表间距为0,底部高度为默认字体高度)
*
* @param spacing
*/
public void setSpacing(float spacing) {
if (spacing < DEFAULT_textSize && spacing > 0) {
spacing = DEFAULT_textSize * 2;
} else if (spacing > DEFAULT_textSize * 2) {
this.spacing = spacing;
textSize = spacing / 2;
} else {
this.spacing = spacing;
}
}
/**
* 设置经线类型
*
* @param longitudesTheme
*/
/* public void setLongitudesTheme(int longitudesTheme) {
if (longitudesTheme < DEFAULT_THEME
&& longitudesTheme > LongitudesTheme.theme8) {
longitudesTheme = DEFAULT_THEME;
}
if (longitudesTheme == LongitudesTheme.theme0) {
longitudesNum = DEFAULT_LONGITUDE_NUM;
maxDate = MAX_DATE;
} else if (longitudesTheme == LongitudesTheme.theme1) {
longitudesNum = DEFAULT_LONGITUDE_NUM;
maxDate = 60 * 24;
} else if (longitudesTheme == LongitudesTheme.theme2) {
longitudesNum = 2;
maxDate = 11 * 60;
} else if (longitudesTheme == LongitudesTheme.theme3) {
longitudesNum = 2;
maxDate = 18 * 60;
} else if (longitudesTheme == LongitudesTheme.theme4) {
longitudesNum = DEFAULT_LONGITUDE_NUM;
maxDate = (int) (9.5 * 60);
} else if (longitudesTheme == LongitudesTheme.theme5) {
longitudesNum = 2;
maxDate = (int) (3.75 * 60);
} else if (longitudesTheme == LongitudesTheme.theme6) {
longitudesNum = DEFAULT_LONGITUDE_NUM;
maxDate = (int) (6.25 * 60);
} else if (longitudesTheme == LongitudesTheme.theme7) {
longitudesNum = DEFAULT_LONGITUDE_NUM;
maxDate = (int) (5.75 * 60);
} else if (longitudesTheme == LongitudesTheme.theme8) {
longitudesNum = DEFAULT_LONGITUDE_NUM;
maxDate = (int) (7.75 * 60);
}
this.longitudesTheme = longitudesTheme;
} */
/**
* 设置是否将两边坐标值绘制在边框线外(注:如果设置成true,必须设置strokeLeft和strokeRight)
*
* @param isDrawOutside
* @param strokeLeft 左边距
* @param strokeRight 右边距
*/
public void setDrawOutside(boolean isDrawOutside, float strokeLeft,
float strokeRight) {
this.isDrawOutside = isDrawOutside;
if (isDrawOutside == false) {
setStrokeLeft(1.0f);
setStrokeRight(1.0f);
} else {
setStrokeLeft(strokeLeft);
setStrokeRight(strokeRight);
}
invalidate();
}
/**
* 设置小数保留位数
*
* @param num
*/
public void setNum(int num) {
this.num = num;
invalidate();
}
/**
* 设置接口
*/
public void setOnTimeListener(OnTimeListener l) {
this.l = l;
}
/**
* 通知外部接口
*
* @author 锐
*/
public interface OnTimeListener extends OnTimeDataChangeListener {
/**
* 是否显示指标详情
*/
void isMove(View view, boolean isMove, float TouchX);
}
public interface OnTimeDataChangeListener {
/**
* 传递数据
*
* @param view
* @param data
* @param position
* @param preClose 昨收价
*/
void listener(View view, Vector<TimeData> data, int position, double preClose, int num);
}
/**
* 计算十字光标位置
*/
private void viewCrossLine() {
// TODO Auto-generated method stub
if (data != null && data.size() > 0) {
getParent().requestDisallowInterceptTouchEvent(true);
movedX = movedX - (getStrokeWidth() + getStrokeLeft() + 1f);
if (movedX < 0f) {
movedX = 0f;
} else if (movedX >
getWidth() - (getStrokeWidth() + getStrokeLeft() + getStrokeRight() + 2f)) {
movedX = getWidth() - (getStrokeWidth() + getStrokeLeft() + getStrokeRight() + 2f);
}
int index = (int) (movedX / dataSpacing);
if (data == null || data.size() == 0) {
return;
} else if (index > data.size() - 1) {
index = data.size() - 1;
}
crossX = getStrokeWidth() + getStrokeLeft() + 1f + dataSpacing
* index;
crossY = (float) (upChartBottom - (data.get(index).getClose() - upMinData)
* upRatio);
leftData = (float) data.get(index).getClose();
rightData = (float) data.get(index).getZdf();
bottomData = (float) data.get(index).getCjl();
time = data.get(index).getTime();
isShowCross = true;
invalidate();
if (l != null) {
l.listener(this, data, index, preClose, num);
l.isMove(this, isShowCross, crossX);
}
// for (int i = 0; i < data.size() - 1 && i < maxDate - 1; i++) {
// float Y = (float) (upChartBottom - (data.get(i).getClose() - upMinData)
// * upRatio);
// float endY = (float) (upChartBottom - (data.get(i + 1)
// .getClose() - upMinData) * upRatio);
// float X = getStrokeWidth() + getStrokeLeft() + 1f + dataSpacing
// * i;
// float endX = getStrokeWidth() + getStrokeLeft() + 1f
// + dataSpacing * (i + 1);
// float spacing = endX - X;
// float positionX = movedX - X;
// if (movedX >= X && movedX < endX) {
// isShowCross = true;
// if (positionX <= spacing / 2) {
// crossX = X;
// crossY = Y;
// leftData = (float) data.get(i).getClose();
// rightData = (float) data.get(i).getZdf();
// bottomData = (float) data.get(i).getCjl();
// time = data.get(i).getTime();
// if (l != null) {
// l.listener(this, data, i, preClose);
// l.isMove(this, isShowCross, crossX);
// }
// } else {
// if (data.size() == 0) {
// return;
// }
// crossX = endX;
// crossY = endY;
// leftData = (float) data.get(i + 1).getClose();
// rightData = (float) data.get(i + 1).getZdf();
// bottomData = (float) data.get(i + 1).getCjl();
// time = data.get(i + 1).getTime();
// if (l != null) {
// l.listener(this, data, i + 1, preClose);
// l.isMove(this, isShowCross, crossX);
// }
// }
// invalidate();
// return;
// } else if (movedX >= endX
// && (i + 1 == data.size() - 1 || i + 1 == maxDate - 1)) {
// isShowCross = true;
// crossX = endX;
// crossY = endY;
// leftData = (float) data.get(i + 1).getClose();
// rightData = (float) data.get(i + 1).getZdf();
// bottomData = (float) data.get(i + 1).getCjl();
// time = data.get(i + 1).getTime();
// if (l != null) {
// l.listener(this, data, i + 1, preClose);
// l.isMove(this, isShowCross, crossX);
// }
// invalidate();
// return;
// }
// }
}
}
public void setOnTimeChartClickListener(OnTimeChartClickListener l) {
this.mOnTimeChartClickListener = l;
}
/**
* 单击事件
*
* @author dingrui
*/
public interface OnTimeChartClickListener {
public void click(View v);
}
/**
* 判断线程是否活动
*
* @param thread
* @return
*/
private boolean isAlive(Thread thread) {
if (thread == null)
return false;
else {
if (thread.isAlive())
return true;
else
return false;
}
}
public boolean isDrawDownChart() {
return isDrawDownChart;
}
public void setDrawDownChart(boolean drawDownChart) {
isDrawDownChart = drawDownChart;
}
}