Android绘制股票k线图系列2-绘制分时图



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;
    }

}

关注公众号“大模型全栈程序员”回复“小程序”获取1000个小程序打包源码。更多免费资源在http://www.gitweixin.com/?p=2627

发表评论

邮箱地址不会被公开。 必填项已用*标注