首页 > 代码库 > XCL-Charts强大的仪表盘

XCL-Charts强大的仪表盘

XCL-Charts中的仪表盘是我封装的最麻烦的图之一。原因嘛,用过的人都知道,这类图太有特色了,要弄出一个适用于大部份情况的封装出来实在不容易。

还好,经过一翻折腾,总算搞出来一套自已感觉还行的方法。

   先展示下效果:

   还可以吧。

     这类图封装分开看,从总布局角度看分为180,270,90,360等不同角度的仪表盘。从内容看则主要有两个部份的难点,丰富多彩的各类环与各类指针。

    大家注意观察下上图demo中的环与指针就明白有多少类吧。

     我在封装时,把不同风格的环分为8大类. 来绘制处理大部份各类环形风格,然后用户可通过属性的细调来画出适合自已需求的图。

因为类别太多,我就不在这一一对每个环形轴显示成什么样举例了。

    

   至于指针,如demo所见,我在这展示了几种不同风格的指针,及其多指针叠加显示的方法。 这当然不包含全部,通过属性的组合设置及与环形轴的配合。

   用户可以定制各种类型的指针。因为基本的计算和绘制要素图表库已经搭建好并开放出来了。所以不用担心没合适的指针可绘制。

        

    指针是一方面,回到我们的主要问题点。demo中有各种各类的图,是不是我在图表库中每一个都独立封装一个呢?

  答案当然是不,我的解决方法如下:

前面提过,我封装了8大类的轴风格。在实现绘制时,用户可以自己决定add哪些轴,并显示在图中的哪个位置。

    我的方法很明显了,把所有的决定权交给用户,通过用户自己的add,再通过相关的轴的属性设置来画出他们自己满意的效果。

    他们有多少创意,都可以通过自由组合方式绘制出来。

         

    噢,忘记了,还有一个仪表盘中文字的显示。常要定制各种不同的文字,对于这个,我的解决方法同样是,把决定权交给用户。

    让用户定好文字及设置好paint画笔属性后,传入用户指定的显示位置即可。 想怎么弄就怎么弄吧,我上图的demo已经证明了。


      说这么多没用,我拿上面demo其中混合图(包含了270,180,90三种仪表盘及不同轴的add方法)的例子的代码在这展示下吧。

      

/**
 * Copyright 2014  XCL-Charts
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 	
 * @Project XCL-Charts 
 * @Description Android图表基类库演示
 * @author XiongChuanLiang<br/>(xcl_168@aliyun.com)
 * @license http://www.apache.org/licenses/  Apache v2 License
 * @version 1.3
 */
package com.demo.xclcharts.view;

import java.util.ArrayList;
import java.util.List;

import org.xclcharts.chart.DialChart;
import org.xclcharts.common.DensityUtil;
import org.xclcharts.common.MathHelper;
import org.xclcharts.renderer.XEnum;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.util.Log;

public class DialChart07View extends GraphicalView {

	private String TAG = "DialChart07View";	
	
	private DialChart chart = new DialChart();
	private DialChart chart180 = new DialChart();
	private DialChart chart90 = new DialChart();		
	private float mPercentage = 0.9f;
	
	public DialChart07View(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		initView();
	}
	
	public DialChart07View(Context context, AttributeSet attrs){   
        super(context, attrs);   
        initView();
	 }
	 
	 public DialChart07View(Context context, AttributeSet attrs, int defStyle) {
			super(context, attrs, defStyle);
			initView();
	 }
	 
	 
	 private void initView()
	 {
		chartRender();
		chartRender90();
		chartRender180();
	 }
	 
	 @Override  
	    protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
	        super.onSizeChanged(w, h, oldw, oldh);  
	        chart.setChartRange(w ,h ); 
	        chart180.setChartRange(w/2 ,h/3 ); 
	        chart90.setChartRange(w ,h/3 ); 
	    }  		
						
		public void chartRender()
		{
			try {								
							
				chart.setPadding(0, DensityUtil.dip2px(getContext(), 100), 0, 0);
				
				//设置标题背景			
				chart.setApplyBackgroundColor(true);
				chart.setBackgroundColor( (int)Color.rgb(28, 129, 243) );
				//绘制边框
				chart.showRoundBorder();
				
				chart.setTotalAngle(270f);
						
				//设置当前百分比
				chart.getPointer().setPercentage(mPercentage);
				
				//设置指针长度
				chart.getPointer().setLength(0.65f,0.2f);	
				
				//增加轴承
				addAxis();						
				/////////////////////////////////////////////////////////////
				//增加指针
				addPointer();
				//设置附加信息
				addAttrInfo();
				/////////////////////////////////////////////////////////////
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				Log.e(TAG, e.toString());
			}
			
		}
		
				
		public void chartRender180()
		{
			try {	
				chart180.setTotalAngle(180f);
				chart180.setStartAngle(180f);
						
				//设置当前百分比
				chart180.getPointer().setPercentage(mPercentage);
				
				//设置指针长度
				chart180.getPointer().setPointerStyle(XEnum.PointerStyle.TRIANGLE);
				chart180.getPointer().setLength(0.65f,0.2f);	
				
				List<Float> ringPercentage = new ArrayList<Float>();			
				float rper = MathHelper.getInstance().div(1, 4); //相当于40%	//270, 4
				ringPercentage.add(rper);
				ringPercentage.add(rper);
				ringPercentage.add(rper);
				ringPercentage.add(rper);
				
				List<Integer> rcolor  = new ArrayList<Integer>();			
				rcolor.add((int)Color.rgb(242, 110, 131));
				rcolor.add((int)Color.rgb(238, 204, 71));
				rcolor.add((int)Color.rgb(42, 231, 250));
				rcolor.add((int)Color.rgb(140, 196, 27));						
				chart180.addStrokeRingAxis(0.75f,0.6f, ringPercentage, rcolor);
				chart180.getPlotAxis().get(0).getFillAxisPaint().setColor((int)Color.rgb(28, 129, 243) );
				
				Paint paintTB = new Paint();
				paintTB.setColor(Color.WHITE);
				paintTB.setTextAlign(Align.CENTER);
				paintTB.setTextSize(22);	
				paintTB.setAntiAlias(true);	
				chart180.addAttributeInfo(XEnum.Location.BOTTOM, "180度仪表盘", 0.5f, paintTB);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				Log.e(TAG, e.toString());
			}
			
		}
		
		public void chartRender90()
		{
			try {
				
				chart90.setPadding(DensityUtil.dip2px(getContext(), 150),0, 0, 0);
				chart90.setTotalAngle(90f);
				chart90.setStartAngle(270f);
								
				List<Float> ringPercentage = new ArrayList<Float>();			
				float rper = MathHelper.getInstance().div(1, 2); //相当于40%	//270, 4
				ringPercentage.add(rper);
				ringPercentage.add(rper);
				
				List<Integer> rcolor  = new ArrayList<Integer>();			
				rcolor.add((int)Color.rgb(242, 110, 131));
				rcolor.add((int)Color.rgb(238, 204, 71));				
				chart90.addStrokeRingAxis(0.75f,0.6f, ringPercentage, rcolor);				
				chart90.getPlotAxis().get(0).getFillAxisPaint().setColor((int)Color.rgb(28, 129, 243) );			
				chart90.getPointer().setLength(0.65f);	

				Paint paintTB = new Paint();
				paintTB.setColor(Color.WHITE);
				paintTB.setTextAlign(Align.CENTER);
				paintTB.setTextSize(22);	
				paintTB.setAntiAlias(true);	
				chart90.addAttributeInfo(XEnum.Location.BOTTOM, "90度仪表盘", 0.5f, paintTB);
				
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				Log.e(TAG, e.toString());
			}
			
		}
		
		public void addAxis()
		{
			
			List<String> rlabels2  = new ArrayList<String>();
			for(int i=0;i<7;i++)
			{						
				rlabels2.add(Integer.toString(i * 10));			
			}
			chart.addInnerTicksAxis(0.7f, rlabels2);
			chart.getPlotAxis().get(0).getAxisPaint().setColor(Color.WHITE);
			chart.getPlotAxis().get(0).getAxisPaint().setStrokeWidth(8);
			chart.getPlotAxis().get(0).getTickMarksPaint().setColor(Color.WHITE);
			chart.getPlotAxis().get(0).getTickLabelPaint().setColor(Color.WHITE);
			
			List<String> rlabels3  = new ArrayList<String>();
			for(int i=0;i<5;i++)
			{
				if(0 == i)
				{
					rlabels3.add("");	
				}else					
					rlabels3.add(Integer.toString(i * 10));			
			}
			
			chart.addOuterTicksAxis(0.8f, rlabels3);
			chart.getPlotAxis().get(1).getAxisPaint().setColor(Color.RED);
			chart.getPlotAxis().get(1).getAxisPaint().setStrokeWidth(5);
													
			chart.getPointer().setPointerStyle(XEnum.PointerStyle.TRIANGLE);			
			chart.getPointer().getPointerPaint().setStrokeWidth(3);			
			chart.getPointer().getPointerPaint().setStyle(Style.FILL);		
	
			chart.getPointer().getPointerPaint().setColor((int)Color.rgb(242, 110, 131));		
			chart.getPointer().getBaseCirclePaint().setColor((int)Color.rgb(238, 204, 71));
			chart.getPointer().setBaseRadius(10f);
			
		}
		
		//增加指针
		public void addPointer()
		{							
		}
		
		
		private void addAttrInfo()
		{			
			Paint paintTB = new Paint();
			paintTB.setColor(Color.WHITE);
			paintTB.setTextAlign(Align.CENTER);
			paintTB.setTextSize(22);	
			paintTB.setAntiAlias(true);	
			chart.addAttributeInfo(XEnum.Location.BOTTOM, "270度仪表盘", 0.5f, paintTB);
		}
		
		public void setCurrentStatus(float percentage)
		{								
			mPercentage =  percentage;
			
			//清理
			chart.clearAll();
			chart90.clearAll();
			chart180.clearAll();
			
			//设置当前百分比
			chart.getPointer().setPercentage(mPercentage);
			addAxis();
			//增加指针
			addPointer();
			addAttrInfo();
			
			chartRender180();
			chartRender90();
			chart90.getPointer().setPercentage(mPercentage);
			chart180.getPointer().setPercentage(mPercentage);
		}


		@Override
		public void render(Canvas canvas) {
			// TODO Auto-generated method stub
			 try{
				 	chart.render(canvas);
		            chart90.render(canvas);
		            chart180.render(canvas);
		            		           
		        } catch (Exception e){
		        	Log.e(TAG, e.toString());
		        }
		}

}

        代码有点乱,但用于展示功能足够了。

好了,不多说了,想要了具体了解的,自己上github或开源中国下代码看吧。

         相信我,我弄的这个图表库,总有一点功能会是你所需要的。 嘿嘿。

       


    BLOG:http://blog.csdn.net/xcl168

    Mail: xcl_168@aliyun.com