`
dunhuangmi
  • 浏览: 26997 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

[HTML5系列实践之一]用HTML5做动态饼图

阅读更多

注:原创文章,转载注明原作者为dunhuangmi。

 

通常根据数据生成统计图,有柱状图,饼状图,折线图等等不同类型。柱状图可以通过js控制css的变化实现,比较简单。但是画圆必须用flash、svg或html5来实现。

下面介绍一下用html5实现如下饼图的原理



 

我们都知道,用html5绘图需要使用CanvasRenderingContext2D对象提供的各种API,画圆需要用到arc()。
它的写法是arc(x, y, radius, startAngle, endAngle, counterclockwise),具体含义可查手册。
于是我们画一个π/6(30度)扇形(从0度开始,逆时针)就会是这样:

funciton draw(){
	canvas = document.getElementById('tutorial');
 	if (canvas.getContext){
 		var ctx = canvas.getContext('2d');
		ctx.fillStyle ="#3666B0";  
		ctx.strokeStyle = "#3666B0"; 
		ctx.moveTo(300,200); 
		ctx.arc(300,200,150,0,-Math.PI*/6,true);
		ctx.fill();  
		ctx.stroke(); 
	}
}


body部分这样写:
<body onload="draw();">
    <canvas id="tutorial" width="700" height="400"><div class="nohtml5">你的浏览器不支持html5</div></canvas>
</body>



 

 需求是画饼图,因此要画一组扇形组成一个完整的圆。于是设置一组全局变量数组控制扇形的角度和颜色。

        var color = ["#27255F","#2F368F","#3666B0","#2CA8E0","#77D1F6"];  /*5组扇形,不同颜色*/
        var data = [5,30,15,30,20];   /*扇形的角度百分比,5组加起来正好是100*/
        var startPoint = 0;  /*其实点位置*/
        var ctx;
        var o={x:300,y:200}/*坐标原点*/,rectbox={ox:0,oy:0,wid:700,hei:400}/*画布大小*/,radius=150/*圆半径*/;

 在draw()函数中用循环来控制连续画扇区

	for (var i=0;i<data.length ; i++)
	{
		drawfan(i);
	}

 drawfun()代码

function drawfan(seq){
	ctx.fillStyle =color[seq];  
	ctx.strokeStyle = color[seq]; 
	ctx.moveTo(o.x,o.y); 
	ctx.arc(o.x,o.y,radius,startPoint,startPoint-Math.PI*2*(data[seq]/100),true);
	ctx.fill();  
	ctx.stroke(); 
	startPoint -= Math.PI*2*(data[seq]/100);
}

 饼图效果还不错哒:

 

下面要实现当鼠标位于某扇区之上,该扇区浮动放大的效果,如下图效果:


1、扇区放大,放大radius即可实现

2、要实现浮动效果,一方面在扇区外加画阴影,另一方面,应将放大的扇形原点偏移出原先的原点。新原点的x,y坐标应根据扇区的中心点角度与半径偏移量计算而得。因此必须还要计算每个扇形的始末角度值。还要用sin,cos函数分别计算坐标。这里有一系列的算法。不记得中学数学的要去查查书了啊。注意网页的x轴y轴与数学上的坐标系方向不同,网页坐标原点在左上角,y轴的方向与数学坐标系的相反。

3、要判断鼠标此时是否在某扇区内,如果在,则放大浮动该扇区。

4、还要实现扇区渐进放大的效果,用setInterval()来实现。

5、鼠标位于扇区之上时增加一个浮动说明框(div+css实现,很简单,不赘述,只是跟随鼠标做位置变化即可)

 

增加全局变量:

var angle=new Array(5);  /*扇形的始末角度*/
var hlnumber=3/*选中哪一块扇形*/,prenumber=-1/*已放大扇区序号*/,hlt,animating=false/*是否在动画中*/;
var distance=8,/*选中扇区浮出距离*/expand=1.08,/*放大倍数*/shadow={blur:10,x:10,y:10};/*阴影的参数*/
var diffinfo={x:20,y:10}/*信息浮动框与鼠标的距离*/

计算扇区角度区间

function init(){	//计算每个扇区的角度区间
	var sum=0;
	for (var i=0;i<data.length ;i++ )
	{
		angle[i]=new Array(2);
		angle[i][0]=sum;
		sum+=data[i]/100;
		angle[i][1]=sum;
	}
}

判断鼠标此时位于哪个扇区之上

function whichfan(x,y){	//计算某坐标点属于哪个扇区,圆外返回-1
	var nx=x-o.x, ny=o.y-y;
	if (((nx*nx)+(ny*ny))>radius*radius){
		return -1;
	}
	var ap=Math.atan2(ny,nx);
	if (ap<0)
	{
		ap+=Math.PI*2;
	}
	//alert(ap/Math.PI/2);
	for (var i=0;i<angle.length ;i++ )
	{
		if (((ap/Math.PI/2)>=angle[i][0])&&((ap/Math.PI/2)<=angle[i][1]))
		{
			return i;
		}
	}
	return angle.length;		
}
 

改写drawfan(),增加了两个参数:dist(放大扇区的偏移量),ifshadow(是否有阴影)

function drawfan(seq,dist,ifshadow){
	ctx.fillStyle =color[seq];  
	ctx.strokeStyle = color[seq]; 
	ctx.beginPath();  
			
	if (ifshadow){
		var ang=(angle[seq][0]+angle[seq][1])/2;
		var newox,newoy;
		newox=o.x+dist* Math.cos(ang*2*Math.PI);
		newoy=o.y-dist* Math.sin(ang*2*Math.PI);
		ctx.shadowColor =  '#cccccc';
		ctx.shadowBlur = shadow.blur;  //设置阴影模糊程度。此值越大,阴影越模糊
		ctx.shadowOffsetX = shadow.x * Math.cos(ang*2*Math.PI);   //阴影的x和y偏移量,单位是像素。
		ctx.shadowOffsetY = -shadow.y * Math.sin(ang*2*Math.PI);	
		ctx.moveTo(newox,newoy); 		
		ctx.arc(newox,newoy,radius*expand,startPoint,startPoint-Math.PI*2*(data[seq]/100),true); 
	}
	else{
		ctx.shadowBlur = 0;  //设置阴影模糊程度。此值越大,阴影越模糊
		ctx.shadowOffsetX = 0;   //阴影的x和y偏移量,单位是像素。
		ctx.shadowOffsetY = 0;	
		ctx.moveTo(o.x,o.y); 
		ctx.arc(o.x,o.y,radius,startPoint,startPoint-Math.PI*2*(data[seq]/100),true);
	}
	ctx.fill();  
	ctx.stroke(); 
	startPoint -= Math.PI*2*(data[seq]/100);
}

onMousemove触发的事件:

function draw(){
	....
	canvas.addEventListener('mousemove',showinfo,false);
}
 
function showinfo(){
	....
	if(window.event){
		mouse.innerHTML='x:'+(window.event.x)+';y:'+(window.event.y);
		p.x=window.event.x;
		p.y=window.event.y;
	}
	else{
		mouse.innerHTML='x:'+(event.pageX)+';y:'+(event.pageY);
		p.x=event.pageX;
		p.y=event.pageY;
	}
	
	var fnumber=whichfan(p.x,p.y);
	if ((fnumber!=-1) &&(fnumber!=data.length))
	{
		if (prenumber==fnumber)
		{
			infofan.style.left=p.x+diffinfo.x+'px';
			infofan.style.top=p.y+diffinfo.y+'px';
			return;
		}		
		var internal=0;
		animating=true;
		hlt=setInterval(function(){
			ctx.clearRect(rectbox.ox,rectbox.oy,rectbox.wid,rectbox.hei);
			if (internal>distance){
				clearInterval(hlt);
				animating=false;
			}
			for(var j=0;j<data.length;j++){
				if (j!=fnumber){
					drawfan(j,0);
				}
				else{
					drawfan(fnumber,internal,true);
					internal++;
				}
			}
		},20);
		prenumber=fnumber;
		infofan.style.left=p.x+diffinfo.x+'px';
		infofan.style.top=p.y+diffinfo.y+'px';
		infofan.innerHTML='这是一个扇区。它代表'+data[fnumber]+'%的统计类型。';
		infofan.style.display='block';
		//hlt=setInterval("drawhlfan(5,i);",500);
		return;				
	}			
	prenumber=-1;
	startPoint =0;// 1.5 * Math.PI;  
	ctx.clearRect(rectbox.ox,rectbox.oy,rectbox.wid,rectbox.hei);
	for(var j=0;j<data.length;j++){
		drawfan(j,0);
	}
	infofan.style.display='none'; 
}
 

代码和最终效果参见:http://dunhuang.a67.cnaaa1.com/html5/canvas-arc6.html,原创文章,转载注明原作者为dunhuangmi。

  • 大小: 2.8 KB
  • 大小: 12.3 KB
  • 大小: 27.4 KB
  • 大小: 31.3 KB
分享到:
评论

相关推荐

    html5饼图、柱状图、折线图,Html5+JS开发

    本资源包含了一系列使用HTML5和JavaScript技术实现的图表,包括饼图、柱状图和折线图,为数据可视化提供了直观且美观的解决方案。 饼图是一种常用于显示部分与整体之间关系的数据表示方式,通过扇形区域的大小来...

    HTML5绘制饼图实例(二)

    在这个实例中,我们将深入探讨如何使用HTML5的Canvas API创建一个饼图。 首先,我们需要在HTML文档中创建一个`&lt;canvas&gt;`元素,它是用于绘制图形的画布。例如: ```html &lt;!DOCTYPE html&gt; &lt;html lang="zh"&gt; ...

    EASY饼图数据统计特效

    在这个案例中,EASY饼图可能利用了HTML5的canvas元素或SVG(Scalable Vector Graphics)来绘制饼图,并通过JavaScript进行动态更新和交互处理。HTML5的canvas和SVG都可以实现矢量图形的绘制,它们提供了丰富的API来...

    jquery html5图表动画圆形饼图.zip

    在IT领域,尤其是在Web开发中,使用动态、交互式的图表是一种常见的数据可视化方式。"jQuery HTML5图表动画圆形饼图.zip"这个压缩包文件显然包含了关于如何使用jQuery、HTML5和CSS来创建带有动画效果的圆形饼图的...

    自定义双层嵌套饼图实现

    本文将深入探讨如何实现一个自定义的双层嵌套饼图,其中包括内层饼图、外层饼图的展示,以及动态动画和放大效果的添加。 首先,我们要了解饼图的基本原理。饼图是通过将圆周角分配给各个数据类别来表示比例关系的...

    用js实现的数据饼图

    在JavaScript(简称JS)中,实现数据饼图是一种常见的数据可视化技术,用于展示各项数据的比例关系。饼图通过分割扇形区域来表示每个部分占总体的百分比,它直观、简洁,非常适合用来展现数据分布。以下是一些关于...

    raphael饼图

    饼图由一系列扇形部分组成,每个扇形代表数据集中的一个类别,其大小与该类别的比例成正比。以下是关于使用Raphaël绘制饼图的关键知识点: 1. **引入Raphaël库**:首先,你需要在HTML文件中引入Raphaël库的JS...

    用js画简单饼图

    在JavaScript的世界里,绘制图表是一种常见的数据可视化方法,饼图是其中之一,用于显示部分与整体之间的比例关系。本文将深入探讨如何使用JavaScript来创建一个简单的饼图,以便于理解其基本原理和实现步骤。 首先...

    amchart饼图 asp.net版

    5. **交互性与动态更新**: amcharts饼图支持动态更新,可以通过Ajax从服务器获取新数据,或者响应用户操作如点击、悬停等更新图表内容。 6. **自定义饼图**: 开发者可以通过amcharts丰富的API进行定制,比如改变...

    html5饼状图和柱状图数据图表echarts插件

    在ECharts中,可以通过配置`series`来创建饼状图,每个系列对应一个饼图。可以设置`label`来显示数据名和值,使用`emphasis`突出高亮选中的部分。同时,饼图支持`roseType`选项,可以绘制环形图或南丁格尔玫瑰图。 ...

    Echars 饼图制作

    其中,饼图是 ECharts 提供的一种常见图表类型,它能够直观地展示各部分在整体中的占比情况。在本教程中,我们将深入探讨如何使用 ECharts 创建具有特效的饼图。 1. **基本配置** 要创建一个基本的饼图,首先需要...

    轻松使用JSP生成饼图

    【轻松使用JSP生成饼图】的教程主要介绍了如何利用JSP技术从数据库中获取数据并生成饼状图,以直观地展示不同类别数据的比例。以下是详细的步骤和知识点解析: 1. **JSP基础**:JSP(JavaServer Pages)是一种基于...

    asp.net 饼图控件demo

    ASP.NET饼图控件是一种常用于数据可视化工具,它能够以圆形的方式展示数据比例关系,每个扇区代表一种数据类别,其大小与该类别的数值成比例。在本"asp.net 饼图控件demo"中,我们将深入探讨如何在ASP.NET框架3.5下...

    Asp.net 直方图饼图实现方法WebChart实例

    在Asp.NET中,WebChart控件是一种强大的工具,用于创建动态、交互式的图表,包括直方图和饼图。本实例将详细讲解如何利用WebChart控件在VS2005开发环境下实现这两种常见的数据可视化图形。 首先,我们要了解Web...

    饼图html-分割圆形饼图-Vue可集成此charts插件

    本文将详细讲解如何使用HTML和Vue.js框架来创建一个可分割的圆形饼图,并介绍如何集成相应的charts插件。 首先,我们要明白饼图是一种表现部分与整体关系的数据图表,通过分割圆形来表示各个部分占总体的比例。在...

    asp制作直方图、饼图

    在IT行业中,Web开发是关键领域之一,而ASP(Active Server Pages)是微软推出的一种服务器端脚本环境,用于创建动态交互式网页。本话题主要关注如何使用ASP来制作直方图和饼图,这两种图表在数据分析和可视化中非常...

    itext报表类库 柱形图,饼图,折线图

    在iText中,可以通过创建一系列的矩形来构建柱形图,每个矩形代表一个数据项,矩形的高度或长度对应数据值。 - 使用iText的ColumnText类可以方便地控制矩形的位置和大小,调整颜色和标签,以实现美观且信息丰富的...

    jquery数据统计饼图+表格动态效果现实

    5. **动态效果**: 这个demo中的动态效果可能包括数据的实时更新、图表的动态过渡(如添加、删除或改变数据时饼图的平滑动画)以及用户交互响应(如点击饼图切片后高亮显示相关数据行)。这些效果可以通过jQuery的...

    页面图形(柱状图、饼图...)

    这里主要关注的是使用C#编程语言实现的柱状图和饼图。这两种图表在数据分析、报表展示以及各种Web应用程序中非常常见。 柱状图是一种条形图表,用于比较不同类别之间的数量差异或频率分布。在C#中,可以使用多种库...

    html54stock 开放源碼的HTML5股票工具

    五、项目实践与拓展 为了使用"HTML54stock",开发者需要具备HTML5、JavaScript和CSS的基础知识,同时也需要了解如何获取股票数据API。项目源码的分析和学习将有助于开发者掌握如何将这些技术应用于实际项目,以及...

Global site tag (gtag.js) - Google Analytics