HTML5 画扇形图

2023-11-02

求评论啊!!!! 也写了 一些东西。。咋就没人评论一下的呢。 。。。。


HTML5  画扇形图

最近 有个需求 做了个平衡论应用 因为是需要打包成 android 和 ios的 用了phonegap 技术。 就是直接开发html5 然后直接生成 ios和android'项目。

然后写代码的时候。 自己写了个花扇形图的类。

(function() {
	function Wheel(canvas, options) {
		this.canvas = canvas;
		this.ctx = canvas.getContext('2d');
		this.option = {
			radius : 311, //半径
			centerPoint : {
				x : 0,
				y : 0
			},
			data : [{score:0,name:''}],
			startRadian : 0,//开始弧度 0-2*Math.PI
			color:['#a84ae8','#d04ae7','#e94aae','#e74a77','#e84a49','#e8644b','#e8884b',
			'#e8ae4a','#e8d04a','#e2e84a','#bae84a','#7ee84a','#4be859','#4ae889','#4ae8b7','#4ae8e7',
			'#4abde9','#4a91e9','#4a59e8','#734ae8'],
			needText:true,
			needScoreText:true,
			font:'16px bold',
			bigRate:1.05,
			smallRate:0.91 
		}

		this.setOptions(options);
		_init.call(this);
	}

	/**
	 * 设置值 可以通过设置整个值的json数组 直接绘制出图形
	 */
	Wheel.prototype.setData = function(data) {
		this.option.data = data;
		_draw.call(this);
	}
	
	Wheel.prototype.getData = function() {
		return this.option.data;
	}
	
	Wheel.prototype.editName = function(index,name) {
		 this.option.data[index].name=name;
		 this.draw();
	}
	
	Wheel.prototype.editScore = function(index,score) {
		  this.option.data[index].score=score;
		  this.draw();
	}
	
	/**设置参数
	 * 
	 */
	Wheel.prototype.setOptions = function(options) {
		for (var i in this.option) {
			if (options && options[i]!=undefined) {
				this.option[i] = options[i];
			}
		}
	}
	
	/**
	 *调用画图 进行画图 如修改设置 等需要立即生效时 可以手动调用 
	 */
	Wheel.prototype.draw = function() {
		_draw.call(this);
	}
	
	Wheel.prototype.deleteSector = function(index) {
		 this.option.data.splice(index,1);
		this.draw();
	}

	/**
	 *根据坐标 获取是哪个扇形 
	 */
	Wheel.prototype.getIndexByPoint = function(x, y) {
		//471,322
		//alert(x+':'+y)
		//$('.balanceWheel_logo').text(x+':'+y)
		var data = this.option.data;
		var defRadian = 2 * Math.PI / data.length;
		var index = -1;
		for (var i in data) {
			var start = this.option.startRadian + defRadian * i;
			var end = this.option.startRadian + defRadian * (i - 0 + 1);
			if (_drawSector.call(this, data[i].score, data[i].name, start, end,this.option.color[i], x, y)) {
				//return i;
				index = i;
			}
		}
		return index;
	}
	
	Wheel.prototype.addData = function(data) {
		this.isd=true;
		if(this.option.data.length>=20){
			return false;
		}
		if(!data){
			//data={score:0,name:this.option.data.length+1+''}
			data={score:0,name:''}
		}
		this.option.data.push(data);
		_draw.call(this);
	}
	Wheel.prototype.getCanvas = function() {
		return this.canvas;
	}
	Wheel.prototype.setCanvas = function(canvas) {
		this.canvas = canvas;
		this.ctx = canvas.getContext('2d');
		this.draw();
	}
	Wheel.prototype.beginChange = function(index) {
		this.changeIndex=index;
	}
	Wheel.prototype.endChange = function() {
		this.changeIndex=-1;
	}
	Wheel.prototype.changeScore = function(point) {
		var x=point.x-this.option.centerPoint.x;
		var y=point.y-this.option.centerPoint.y;
		var len=Math.sqrt(x*x+y*y);
		var score=Math.round(len/(this.option.radius/10));
		if(this.changeIndex>=0){
			this.option.data[this.changeIndex].score=Math.min(score,10);
		}
		this.draw();		
	}
	
	//初始化数据
	function _init() {
		_draw.call(this);

	}

	//画的核心方法
	function _draw() {
		
		var ctx = this.ctx;
		ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
		var data = this.option.data;
		var defRadian = 2 * Math.PI / data.length;

	
		//画外轮廓线 并且填充背景色
		ctx.beginPath();
		//ctx.moveTo(this.option.centerPoint.x, this.option.centerPoint.y);
		ctx.strokeStyle = '#FFFFFF';
		ctx.fillStyle = '#f4f4f4';
		ctx.lineWidth = 2;
		ctx.arc(this.option.centerPoint.x, this.option.centerPoint.y, this.option.radius, 0, 2*Math.PI, false);
		ctx.stroke();
		ctx.fill();

		for (var i in data) {
			var start = this.option.startRadian + defRadian * i;
			var end = this.option.startRadian + defRadian * (i - 0 + 1);
			_drawSector.call(this, data[i].score, data[i].name, start, end,this.option.color[i]);

		}

	}

	//
	/**
	 * 画扇形
	 * @param {Object} score 分数 用来控制 扇形半径
	 * @param {Object} name 名称用来写字
	 * @param {Object} startRadian 开始弧度
	 * @param {Object} endRadian 结束弧度
	 * @param {Object} x 当前点击坐标 用来判断 点击区域
	 * @param {Object} y
	 */
	function _drawSector(score, name, startRadian, endRadian,color, x, y) {
		var ctx = this.ctx;
		//画外轮廓线 并且填充背景色
		ctx.beginPath();
		ctx.moveTo(this.option.centerPoint.x, this.option.centerPoint.y);
		//ctx.strokeStyle = '#FFFFFF';
		ctx.fillStyle = '#f4f4f4';
		ctx.lineWidth = 2;
		ctx.arc(this.option.centerPoint.x, this.option.centerPoint.y, this.option.radius, startRadian, endRadian, false);
		ctx.lineTo(this.option.centerPoint.x, this.option.centerPoint.y);
		//ctx.stroke();
		ctx.fill();

		var isPointAted = ctx.isPointInPath(x, y);

		//ctx.save();
		//画内扇形 填充颜色
		ctx.beginPath();
		ctx.moveTo(this.option.centerPoint.x, this.option.centerPoint.y);
		ctx.arc(this.option.centerPoint.x, this.option.centerPoint.y, score * this.option.radius / 10, startRadian, endRadian, false);
		ctx.fillStyle = color;//'#654321';
		//color[this.index];
		ctx.fill();
		_drawText.call(this,score,name,startRadian+(endRadian-startRadian)/2)
		
		
		if(this.option.data.length>1){
			ctx.beginPath();
		ctx.moveTo(this.option.centerPoint.x, this.option.centerPoint.y);
		ctx.strokeStyle = '#FFFFFF';
		ctx.lineWidth = 2;
		ctx.arc(this.option.centerPoint.x, this.option.centerPoint.y, this.option.radius, startRadian, endRadian, false);
		ctx.lineTo(this.option.centerPoint.x, this.option.centerPoint.y);
		ctx.stroke();		
		}

		return isPointAted;
	}

	function _drawText(score,name,radian) {
	
		var text_inc_x = Math.cos(radian) * (this.option.radius);
		var text_inc_y = Math.sin(radian) * (this.option.radius);
		var ctx=this.ctx;
		ctx.font = this.option.font;//"16px bold";
		//ctx.fillStyle = ;
		if (text_inc_x >= 0) {
			ctx.textAlign = "left";
		} else {
			ctx.textAlign = "right";
		}
		if(this.option.needText){
			ctx.fillStyle="#b6b6b6";
			ctx.fillText(name,text_inc_x*this.option.bigRate+this.option.centerPoint.x,text_inc_y*this.option.bigRate+this.option.centerPoint.y,100);
		}
		if(this.option.needScoreText){
			if (score==10) {
				ctx.fillStyle="#ffffff";
			}else{
				ctx.fillStyle="#b6b6b6";
			}
			//this.option.font
			var textY=ctx.font.substring(0,2)/2;
			var offX=0;
			ctx.fillText(score,text_inc_x*this.option.smallRate+this.option.centerPoint.x+offX,text_inc_y*this.option.smallRate+this.option.centerPoint.y+textY,100);
		}		
		// 
	}


	window.Wheel = Wheel;
})()

使用方法

		var canvas = $('#canvas')[0];
		var wheel = new Wheel(canvas, optioons);
					
有2个参数 第一个是canvas 对象。 第二个是配置 设置。
配置主要有


radius : 311, //半径

centerPoint : {x : 0,y : 0}// 圆形坐标 注意 这个坐标是指圆形相对canvas 左上角的坐标

data : [{score:0,name:''}] 扇形数据  这是一个数组 是有每个数据对象组成 数据对象有2个属性。 分数和名称。 分数是1-10分。

startRadian : 0,//开始弧度 就是第一个扇形的起始位置。 数值范围 0-2*Math.PI

color:['#a84ae8','#d04ae7','#e94aae','#e74a77','#e84a49','#e8644b','#e8884b','#e8ae4a','#e8d04a','#e2e84a','#bae84a','#7ee84a','#4be859','#4ae889','#4ae8b7','#4ae8e7','#4abde9','#4a91e9','#4a59e8','#734ae8'],//扇形颜色 因为这个项目做多分20份 并且颜色固定了。 所以用了这个参数。

needText:true 是否需要在外面写上名称。就是数据的 name值。

needScoreText:是否需要在内环写上分数。就是数据的 score值。

font:'16px bold', 字体大小

bigRate:1.05, 就是外面的字的坐标 是由这个值乘以 半径的出来的。

smallRate:0.91 这是里面的字。


另外提过了一些方法:

setData(data) :设置data值

getData() :获取data值

editName(index,name) 修改某个扇形的名称

 editScore (index,score) 修改某个扇形的值(同时改变扇形大小)

setOptions(options) 设置属性。

draw() 画canvas的主方法。 可以手动调用刷新

deleteSector(index) 删除某个扇形

getIndexByPoint(x,y) 获取点击的坐标的扇形index。(注意 这个坐标是相对canvas'的左上角)

addData(data) 增加一个扇形

getCanvas

setCanvas

beginChange :这个事用来标记作用的。 我的项目需要手动拖动 改变扇形大小。 于是 我添加了这个方法。 当touchstart(mousedown)的时候 获取扇形index 并且 调用这个方法 设置index 这样touchmove(mousemove)的时候就知道改变哪个扇形了。即使拖动到外部 或者其他扇形区域 也能记住之前的index。当然 touchend(mouseup)的时候调用下面的 endChange方法。清清除index

endChange

changeScore(point) 这个方法 仍然需要上面2个方法 合作的。 (这里设置的很不合理 暂时 不知道如何改进。) 就是根据touchmove的 坐标 改变 之前几下的扇形的值。 实现拖动打分的效果。


下面附上我对坐标的一些处理 因为各种事件只能获取外部坐标 没法获取canvas内部的坐标 所以需要转化。

	function getRealPoint(x, y, canvas) {
		
		
		var scollTop = getScollPostion();
		x = x - canvas.offsetLeft - ($(document).width() - $('.balanceWheel_wrappe').width()) / 2 + scollTop.left;//balanceWheel_wrappe是主界面。  
                                                                                                          //实际上($(document).width() - $('.balanceWheel_wrappe').width()) / 2就是得到canvas距离左边的距离
		// + margin_left;
		y = y - canvas.offsetTop + scollTop.top - $('.balanceWheel_top').height(); //跟上面基本一个意思
		return {
			x : x,
			y : y
		}
	}
//获取滚动条的属性
function getScollPostion() {//滚动条位置
    var t, l, w, h;
    if (document.documentElement && document.documentElement.scrollTop) {
        t = document.documentElement.scrollTop;
        l = document.documentElement.scrollLeft;
        w = document.documentElement.scrollWidth;
        h = document.documentElement.scrollHeight;
    } else if (document.body) {
        t = document.body.scrollTop;
        l = document.body.scrollLeft;
        w = document.body.scrollWidth;
        h = document.body.scrollHeight;
    }
    return {
        top : t,
        left : l,
        width : w,
        height : h
    };
}







本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HTML5 画扇形图 的相关文章

  • HTML5本地存储

    1 背景 在HTML4 01中 想要在浏览器中存储用户的数据时 我们一般只能用Cookie来实现 不过Cookie有很多限制 大小限制 最大4KB 数量限制 每个站点只允许存储20个Cookie 如果想要存储更多Cookie 则要把旧的Co
  • 【H5】 svg内text、image、path标签的使用

    H5 svg内text image path标签的使用 text标签 div style width 500px height 500px border 2px solid pink margin 50px auto 0 div
  • 开发日志:微信公众号网页开发的调试工具

    在这里记录一下开发时有用到的一些工具 VConcole调试工具 手机端的H5调试工具 http debugx5 qq com
  • 用html+css给女朋友写一个爱心

    这是最后的样子 用一个div 再用before和after就行了 这是html div class ax div 再加上css padding 0px margin
  • JSP通用分页

    通用分页核心思路 将上一次查询请求再发一次 只不过页码变了 实现步骤 1 先查询全部数据 baseDao
  • 前端学习之常见标签的使用(2)

    目录 h标签 p标签 br标签 字符实体 img标签 a标签 mailto链接 base标签 锚点 div span video H5新增 audio H5新增 h标签 h标签 标题标签 在HTML中 一共有六级标题标签 h1 h6 在显示
  • 利用原生js实现随机颜色画布

    这几天复习了一下js的DOM 文档对象模型 部分 看到鼠标事件的时候想到可以试着写一个js画布的案例 一 实现思路 1 利用js绑定鼠标按下事件 鼠标放开事件 在通过鼠标移动事件 获取鼠标所在位置 2 通过鼠标移动事件动态创建节点挂载到页面
  • HTML5编程简介及示例代码

    HTML5是一种用于构建网页和Web应用程序的标准 它引入了许多新的元素 属性和API 为开发者提供了更多的功能和灵活性 在本文中 我们将探讨HTML5编程的一些不同方面 并提供相应的示例代码 标题 Headings HTML5引入了新的标
  • 移动端页面禁止放大缩小

    安卓 在index html文件中添加meta标签 IOS 在 src app vue 中 script 标签内添加代码
  • 看天气WeatherCan V1.0 ---气象数据分析系统web版

    版权声明 本文为CSDN博主 老郭1 的原创文章 遵循CC 4 0 BY SA版权协议 转载请附上原文出处链接及本声明 原文链接 https blog csdn net HZGJF article details 104772394 Wea
  • 前端基础之ES6

    1 前后端对比 2 ES6 ECMAScript6 0 以下简称ES6 ECMAScript是一种由Ecma国际通过ECMA 262标准化的脚本 是JavaScript语言的下一代标准 2015年6月正式发布 从ES6开始的版本号采用年号
  • EduCoder_web实训作业--文本层次语义元素

    第一关 A D B B 第二关 strong 重要通知 strong
  • H5监听移动端物理/浏览器返回键

    JavaScript没有监听物理返回键的API 所以只能使用 popstate 事件监听 工具类如下 export function handleBrowserGoBack back console log back pushHistory
  • 58同城 -- 前端一面

    面我的是一个小哥哥 面试体验挺好的 大概进行了35分钟左右 自我介绍 面试内容 为什么向做前端 怎么学习的前端 本人非科班哈 然后问我项目 直接问项目 没问笔试令我有点意外 问我印象最深的项目 印象最深的功能 遇到的难点 前端存储的区别 C
  • BugkuCTF-WEB题文件上传

    启动场景 发现是文件上传 只能上传图像 不能上传PHP文件 那应该是寻找漏洞上传PHP文件 PHP文件里写入一句话木马 使用burp抓包 不断尝试发现发现需要修改的地方有三个 一个是http head里的Content Type multi
  • elementui 禁止浏览器自动填充用户名密码

    浏览器这功能在登录的时候挺好用的 但是在注册和管理的时候就很难受了 所以 在普通的input上直接off就行了
  • 【HTML】HTML5的拖放你用了吗

    HTML HTML5的拖放你用了吗 引言 github HTML HTML5的拖放你用了吗 内容速递 看了本文您能了解到的知识 在 HTML5 中 拖放是标准的一部分 任何元素都能够拖放 拖放的操作 多用在拖拽排序列表 游戏拼图等 下文中出
  • 基于html5的国家历史文物网站的设计与实现-计算机毕业设计源码63653

    目 录 摘 要 Abstract 第 1 章
  • 第8章 多媒体嵌入

    学习目标 了解视频 音频嵌入技术 能够总结HTML5视频 音频嵌入技术的优点 了解常用的视频文件格式和音频文件格式 能够归纳HTML5支持的视频和音频格式 掌握HTML5中视频的嵌入方法 能够在HTML5页面中添加视频文件 掌握HTML5中
  • 网页订货系统的诸多优势|企业APP订单管理软件

    1 订单信息 发货信息 账目信息一目了然 生产企业 总代理 和分销商之间可以清楚直观的了解到商品和货款的实时状态 以便高效的订货 发货 进行货款催收以及商品的物流跟踪 2 建立稳固的客户关系 避免客户被竞争对手挖墙脚 有了网上订货系统 企业

随机推荐