标签:
1 /** 2 * Author : yanbo 3 * Date : 2015-06-03 4 * Time : 09:22 5 * Description : 自定义区域描述图表View 6 */ 7 public class AreaChartsView extends View { 8 private Paint mPaint; 9 10 private int[] mZeroPos = new int[2]; 11 private int[] mMaxYPos = new int[2]; 12 private int[] mMaxXPos = new int[2]; 13 14 private int mWidth, mHight; 15 private int mRealWidth, mRealHight; 16 private String mTitleY, mTitleX; 17 18 private ArrayList<Integer> mXLevel = new ArrayList<>(); 19 private ArrayList<Integer> mYLevel = new ArrayList<>(); 20 private ArrayList<String> mGridLevelText = new ArrayList<>(); 21 private ArrayList<Integer> mGridColorLevel = new ArrayList<>(); 22 private ArrayList<Integer> mGridTxtColorLevel = new ArrayList<>(); 23 24 private int mGridLevel = mXLevel.size() - 1; 25 26 //title字符大小 27 private int mXYTitleTextSize = 40; 28 29 private int mMeasureXpos, mMeasureYpos; 30 31 public AreaChartsView(Context context, AttributeSet attrs) { 32 super(context, attrs); 33 34 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); 35 mPaint.setAntiAlias(true); 36 mPaint.setFilterBitmap(true); 37 } 38 39 @Override 40 protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 41 super.onLayout(changed, left, top, right, bottom); 42 mWidth = getWidth(); 43 mHight = getHeight(); 44 } 45 46 @Override 47 protected void onDraw(Canvas canvas) { 48 super.onDraw(canvas); 49 50 initPosition(); 51 drawXYTitle(canvas); 52 drawXYLine(canvas); 53 drawContent(canvas); 54 } 55 56 private void initPosition() { 57 //初始化坐标图的xy交点原点坐标 58 mZeroPos[0] = mXYTitleTextSize * 2; 59 mZeroPos[1] = mHight - mXYTitleTextSize * 4; 60 //初始化坐标图的X轴最大值坐标 61 mMaxXPos[0] = mWidth; 62 mMaxXPos[1] = mHight - mXYTitleTextSize * 4; 63 //初始化坐标图的Y轴最大值坐标 64 mMaxYPos[0] = mXYTitleTextSize * 2; 65 mMaxYPos[1] = mXYTitleTextSize * 2; 66 } 67 68 private void drawXYTitle(Canvas canvas) { 69 mPaint.setColor(Color.parseColor("#1FB0E7")); 70 mPaint.setTextSize(mXYTitleTextSize); 71 mPaint.setTextAlign(Paint.Align.LEFT); 72 //画Y轴顶的title 73 canvas.drawText(mTitleY, mMaxYPos[0] - mXYTitleTextSize * 2, mMaxYPos[1] - mXYTitleTextSize, mPaint); 74 mPaint.setTextAlign(Paint.Align.RIGHT); 75 //画X轴顶的title 76 canvas.drawText(mTitleX, mMaxXPos[0], mMaxXPos[1] + mXYTitleTextSize * 2, mPaint); 77 } 78 79 private void drawXYLine(Canvas canvas) { 80 mPaint.setColor(Color.DKGRAY); 81 mPaint.setTextAlign(Paint.Align.RIGHT); 82 //画XY轴 83 canvas.drawLine(mMaxYPos[0], mMaxYPos[1], mZeroPos[0], mZeroPos[1], mPaint); 84 canvas.drawLine(mZeroPos[0], mZeroPos[1], mMaxXPos[0], mMaxXPos[1], mPaint); 85 } 86 87 private void drawContent(Canvas canvas) { 88 mGridLevel = mXLevel.size() - 1; 89 //计算出偏移title等显示尺标后的真实XY轴长度,便于接下来等分 90 mRealWidth = (mWidth - mXYTitleTextSize * 2); 91 mRealHight = (mHight - mXYTitleTextSize * 4); 92 //算出等分间距 93 int offsetX = mRealWidth/(mGridLevel); 94 int offsetY = mRealHight/(mGridLevel+1); 95 //循环绘制content 96 for (int index=0; index<mGridLevel+1; index++) { 97 mPaint.setColor(Color.DKGRAY); 98 mPaint.setTextAlign(Paint.Align.RIGHT); 99 mPaint.setTextSize(mXYTitleTextSize-5); 100 //绘制X轴的那些坐标区间点,包含0点坐标 101 canvas.drawText(String.valueOf(mXLevel.get(index)), mZeroPos[0]+(index*offsetX), mZeroPos[1] + mXYTitleTextSize, mPaint); 102 103 if (index != 0) { 104 //绘制Y轴坐标区间点,不包含0点坐标,X轴已经画过了 105 canvas.drawText(String.valueOf(mYLevel.get(index)), mZeroPos[0], mZeroPos[1]-(index*offsetY), mPaint); 106 } 107 108 if (index == mGridLevel) { 109 //坐标区间 = 真实区间 + 1 110 break; 111 } 112 113 mPaint.setColor(mGridColorLevel.get(mGridLevel - 1 - index)); 114 mPaint.setStyle(Paint.Style.FILL); 115 //绘制区间叠加图谱方块,从远到0坐标,因为小的图会覆盖大的图 116 canvas.drawRect(mMaxYPos[0], mMaxYPos[1] + index*offsetY, mMaxXPos[0]-index*offsetX, mMaxXPos[1], mPaint); 117 118 mPaint.setColor(mGridTxtColorLevel.get(index)); 119 mPaint.setTextAlign(Paint.Align.RIGHT); 120 mPaint.setTextSize(mXYTitleTextSize); 121 //绘制每个方块状态区间的提示文字 122 canvas.drawText(mGridLevelText.get(index), mMaxXPos[0] - index * offsetX - mXYTitleTextSize, 123 mMaxYPos[1] + index * offsetY + mXYTitleTextSize, mPaint); 124 } 125 //绘制当前坐标 126 drawNotice(canvas, offsetX, offsetY); 127 } 128 129 private void drawNotice(Canvas canvas, int offsetX, int offsetY) { 130 int realPosX = 0; 131 int realPosY = 0; 132 //计算传入的x值与真实屏幕坐标的像素值的百分比差值转换 133 for (int index=0; index<mGridLevel; index++) { 134 if (mMeasureXpos >= mXLevel.get(index) && mMeasureXpos < mXLevel.get(index+1)) { 135 int subValue = mMeasureXpos - mXLevel.get(index); 136 int offset = mXLevel.get(index+1) - mXLevel.get(index); 137 realPosX = mZeroPos[0] + index*offsetX + (subValue / offset); 138 break; 139 } 140 } 141 //计算传入的y值与真实屏幕坐标的像素值的百分比差值转换 142 for (int index=0; index<mGridLevel; index++) { 143 if (mMeasureYpos >= mYLevel.get(index) && mMeasureYpos < mYLevel.get(index+1)) { 144 int subValue = mMeasureYpos - mYLevel.get(index); 145 int offset = mYLevel.get(index+1) - mYLevel.get(index); 146 realPosY = mZeroPos[1] - index*offsetY - (offsetY - (subValue / offset)); 147 break; 148 } 149 } 150 //画我们传入的坐标点的标记小红点 151 mPaint.setColor(Color.RED); 152 mPaint.setStyle(Paint.Style.FILL); 153 canvas.drawCircle(realPosX, realPosY, 8, mPaint); 154 155 int[] centerPos = {mZeroPos[0] + mRealWidth/2, mZeroPos[1] - mRealHight/2}; 156 157 mPaint.setColor(Color.WHITE); 158 mPaint.setStyle(Paint.Style.FILL_AND_STROKE); 159 RectF rectF = null; 160 Path path = new Path(); 161 //画红点旁边的提示框和文字,有四个区域,然后提示框的小三角指标方位不同 162 if (realPosX <= centerPos[0] && realPosY >= centerPos[1]) { 163 //left-bottom 164 //画三角形 165 path.moveTo(realPosX+5, realPosY+5); 166 path.lineTo(realPosX+15, realPosY+15); 167 path.lineTo(realPosX+15, realPosY-15); 168 //画矩形背景 169 rectF = new RectF(realPosX+15, realPosY-40, realPosX+200, realPosY + 30); 170 canvas.drawRoundRect(rectF, 15, 15, mPaint); 171 //画提示框的文字 172 mPaint.reset(); 173 mPaint.setColor(Color.RED); 174 mPaint.setTextSize(mXYTitleTextSize - 5); 175 canvas.drawText("("+mMeasureXpos+", "+mMeasureYpos+")", realPosX+30, realPosY, mPaint); 176 } 177 else if (realPosX <= centerPos[0] && realPosY < centerPos[1]) { 178 //left-top 179 path.moveTo(realPosX+5, realPosY+5); 180 path.lineTo(realPosX+15, realPosY+15); 181 path.lineTo(realPosX + 15, realPosY - 15); 182 183 rectF = new RectF(realPosX+15, realPosY - 20, realPosX+200, realPosY + 50); 184 canvas.drawRoundRect(rectF, 15, 15, mPaint); 185 186 mPaint.reset(); 187 mPaint.setColor(Color.RED); 188 mPaint.setTextSize(mXYTitleTextSize - 5); 189 canvas.drawText("("+mMeasureXpos+", "+mMeasureYpos+")", realPosX+30, realPosY+20, mPaint); 190 } 191 else if (realPosX > centerPos[0] && realPosY >= centerPos[1]) { 192 //right-bottom 193 path.moveTo(realPosX-5, realPosY+5); 194 path.lineTo(realPosX-15, realPosY+15); 195 path.lineTo(realPosX - 15, realPosY - 15); 196 197 rectF = new RectF(realPosX-200, realPosY-40, realPosX-15, realPosY + 30); 198 canvas.drawRoundRect(rectF, 15, 15, mPaint); 199 200 mPaint.reset(); 201 mPaint.setColor(Color.RED); 202 mPaint.setTextSize(mXYTitleTextSize - 5); 203 canvas.drawText("("+mMeasureXpos+", "+mMeasureYpos+")", realPosX-180, realPosY, mPaint); 204 } 205 else if (realPosX > centerPos[0] && realPosY < centerPos[1]) { 206 //right-top 207 path.moveTo(realPosX-5, realPosY+5); 208 path.lineTo(realPosX-15, realPosY+15); 209 path.lineTo(realPosX - 15, realPosY - 15); 210 211 rectF = new RectF(realPosX-200, realPosY - 20, realPosX-15, realPosY + 50); 212 canvas.drawRoundRect(rectF, 15, 15, mPaint); 213 214 mPaint.reset(); 215 mPaint.setColor(Color.RED); 216 mPaint.setTextSize(mXYTitleTextSize - 5); 217 canvas.drawText("("+mMeasureXpos+", "+mMeasureYpos+")", realPosX-180, realPosY+30, mPaint); 218 } 219 220 path.close(); 221 mPaint.setColor(Color.WHITE); 222 mPaint.setStyle(Paint.Style.FILL_AND_STROKE); 223 canvas.drawPath(path, mPaint); 224 } 225 226 //设置当前比值 227 public void updateValues(int x, int y) { 228 mMeasureXpos = x; 229 mMeasureYpos = y; 230 231 postInvalidate(); 232 } 233 234 //设置XY轴顶角的title字体大小 235 public void setTitleTextSize(int size) { 236 mXYTitleTextSize = size; 237 } 238 239 //初始化X轴的坐标区间点值,可以不均等分 240 public void initXLevelOffset(ArrayList<Integer> list) { 241 mXLevel.clear(); 242 mXLevel.addAll(list); 243 } 244 245 //初始化Y轴的坐标区间点值,可以不均等分 246 public void initYLevelOffset(ArrayList<Integer> list) { 247 mYLevel.clear(); 248 mYLevel.addAll(list); 249 } 250 251 //初始化每个区间的提示文字,如果不想显示可以设置"" 252 public void initGridLevelText(ArrayList<String> list) { 253 mGridLevelText.clear(); 254 mGridLevelText.addAll(list); 255 } 256 257 //初始化每个区间的颜色 258 public void initGridColorLevel(ArrayList<Integer> list) { 259 mGridColorLevel.clear(); 260 mGridColorLevel.addAll(list); 261 } 262 263 //初始化每个区间的提示文字颜色 264 public void initGridTxtColorLevel(ArrayList<Integer> list) { 265 mGridTxtColorLevel.clear(); 266 mGridTxtColorLevel.addAll(list); 267 } 268 269 //初始化XY轴title 270 public void initTitleXY(String x, String y) { 271 mTitleX = x; 272 mTitleY = y; 273 } 274 }
标签:
原文地址:http://www.cnblogs.com/linlin-meimei/p/4626682.html