欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中使用Canvas绘制南丁格尔玫瑰图(Nightingale rose diagram)

程序员文章站 2022-06-23 10:31:08
南丁格尔玫瑰图 在常规图表中实在很惊艳,但我初看没看懂,一查原来南丁格尔这么伟大,确实值得尊敬。 再仔细研究了下这种图的构成,发现原来就是把柱形图的柱形换成了扇形图的半径...

南丁格尔玫瑰图 在常规图表中实在很惊艳,但我初看没看懂,一查原来南丁格尔这么伟大,确实值得尊敬。

再仔细研究了下这种图的构成,发现原来就是把柱形图的柱形换成了扇形图的半径来表示,当然,变种有好多,我这只是说我理解的这种。

知道了其构成方式后就好实现了,依传入参数个数决定其扇形角度,依百分比决定其扇形的半径长度,然后就一切都水到渠成了。

漂亮的美图献上:

Android中使用Canvas绘制南丁格尔玫瑰图(Nightingale rose diagram)

附上实现代码:

package com.xcl.chart;


/**
 * canvas练习 
 * 	 自已画南丁格尔玫瑰图(nightingale rose diagram)
 *   
 * author:xiongchuanliang
 * date:2014-4-12
 */


import android.content.context;
import android.graphics.canvas;
import android.graphics.color;
import android.graphics.paint;
import android.graphics.paint.style;
import android.graphics.rectf;
import android.util.displaymetrics;
import android.view.view;

public class panelrosechart extends view{
	
	private int scrwidth,scrheight;	
	
	 //演示用的百分比例,实际使用中,即为外部传入的比例参数 
	private final float arrper[] = new float[]{40f,50f,60f,35f,70f,80f,90f}; 
	//演示用标签
	private final string arrperlabel[] = new string[]{"postgresql","sybase","db2","国产及其它","mysql","ms sql","oracle"}; 
	//rgb颜色数组
	private final int arrcolorrgb[][] = { {77, 83, 97}, 
							       {148, 159, 181}, 
							       {253, 180, 90},
							       {52, 194, 188},
							       {39, 51, 72},
							       {255, 135, 195},
							       {215, 124, 124}} ;
	
	
public panelrosechart(context context) {
		super(context);
		// todo auto-generated constructor stub
		
		//屏幕信息
		displaymetrics dm = getresources().getdisplaymetrics();
		scrheight = dm.heightpixels;
		scrwidth = dm.widthpixels;
	}

	
	public void ondraw(canvas canvas){
		//画布背景
		canvas.drawcolor(color.black);		     
     
    float cirx = scrwidth / 2; 
    float ciry = scrheight / 3 ; 
    float radius = scrheight / 5 ;//150; 
                 
    float arcleft = cirx - radius; 
    float arctop = ciry - radius ; 
    float arcright = cirx + radius ; 
    float arcbottom = ciry + radius ; 
    rectf arcrf0 = new rectf(arcleft ,arctop,arcright,arcbottom);  
    
    //画笔初始化
		paint paintarc = new paint(); 		
		paint paintlabel = new paint(); 
		paintlabel.setcolor(color.white);
		paintlabel.settextsize(16);     
		
		paintlabel.setantialias(true);
		paintarc.setantialias(true);
    //位置计算类 
    xchartcalc xcalc = new xchartcalc();	
		
    float percentage = 0.0f;
 		float currper = 0.0f;
 		float newraidus = 0.0f;
		int i= 0; 
		
		 //将百分比转换为扇形半径长度
		percentage = 360 / arrper.length;
		percentage = (float)(math.round(percentage *100))/100; 
		
    for(i=0; i<arrper.length; i++)  
    { 
      //将百分比转换为新扇区的半径 
      newraidus = radius * (arrper[i]/ 100); 
      newraidus = (float)(math.round(newraidus *100))/100; 
      
      float newarcleft = cirx - newraidus; 
      float newarctop = ciry - newraidus ; 
      float newarcright = cirx + newraidus ; 
      float newarcbottom = ciry + newraidus ; 
      rectf newarcrf = new rectf(newarcleft ,newarctop,newarcright,newarcbottom);  
            
      //分配颜色      
      paintarc.setargb(255,arrcolorrgb[i][0], arrcolorrgb[i][1], arrcolorrgb[i][2]);
        
      //在饼图中显示所占比例 
      canvas.drawarc(newarcrf, currper, percentage, true, paintarc);         
      //计算百分比标签
      xcalc.calcarcendpointxy(cirx, ciry, radius - radius/2/2, currper + percentage/2); 	
			//标识
		  canvas.drawtext(arrperlabel[i],xcalc.getposx(), xcalc.getposy() ,paintlabel);		  
      //下次的起始角度 
      currper += percentage; 
    } 
    //外环
    paintlabel.setstyle(style.stroke);
    paintlabel.setcolor(color.green);
    canvas.drawcircle(cirx,ciry,radius,paintlabel); 

    canvas.drawtext("author:xiongchuanliang", 10, scrheight - 200, paintlabel);
    		
	}

}

代码实现起来很容易,但这种图的设计创意确实非常好。 叹服。

一定要附上南丁格尔*的链接:      http://zh.wikipedia.org/wiki/%e5%bc%97%e7%be%85%e5%80%ab%e6%96%af%c2%b7%e5%8d%97%e4%b8%81%e6%a0%bc%e7%88%be

感兴趣的可以看看。