封装构造函数,用canvas写饼状图和柱状图

封装函数

// 场景
function XDLScence( options ) {
this.stage = options.stage;
//执行场景的初始化
this.init = options.init || XDLScence.voidFn;
//执行场景的进场动画
this.pre = options.pre || XDLScence.voidFn;
//执行场景的出场动画
this.post = options.post || XDLScence.voidFn; this.layers = options.layers || [new Konva.Layer()];
this.name = options.name || '';
this.init();
} XDLScence.prototype = {
constructor: XDLScence,
voidFn: function() {},
CurrentScence: null,
//场景要进入舞台,只需要调用场景的 play方法。
play: function () {
var _this = this;
// doPre,
var doPre = function doPre() {
// stage.add(_this.layer);// 把当前层添加到舞台
_this.layers.forEach(function( val ){
_this.stage.add( val );
});
XDLScence.currentScene = _this;
_this.pre();
}; //如果不是第一个场景,先执行当前场景的出场动画,然后执行下一个场景的入场动画
//需要在场景的post方法中执行传进去的 next 方法。
if (XDLScence.currentScene) {
//执行上一个场景的出场动画
XDLScence.currentScene.post(doPre);
} else {
//如果是第一个场景直接执行入场动画
doPre();
}
}// play
}; //=============>S=============柱状图数据demo
// var data = [{
// name: '百度', value: .2, color: 'lightgreen'
// },{
// name: '阿里', value: .4, color: 'lightgreen'
// },{
// name: '新浪', value: .1, color: 'lightgreen'
// },{
// name: '搜狐', value: .1, color: 'lightgreen'
// },{
// name: '360', value: .2, color: 'lightgreen'
// }]; //柱状图构造函数
function Histogram(option) {
this.group = new Konva.Group({
x: option.x,
y: option.y
});
this.init(option);
} //柱状图的原型对象
Histogram.prototype = {
constructor: Histogram,
init: function( option ) {
option.data = option.data || [];
//底线的宽度
option.blWidth = option.blWidth || 2;
option.blColor = option.blColor || 'lightgreen';
option.width = option.width || 200;
option.height = option.height || 200;
option.fontSize = option.fontSize || 12; //把最高的柱状图的高度换算成 柱状图要求的高度。
var maxValue = 0;
for(var i = 0; i < option.data.length; i++ ) {
maxValue = maxValue > option.data[i].value ? maxValue : option.data[i].value;
}
option.height = option.height / maxValue; //创建底线
var bottomLine = new Konva.Line({
strokeWidth: option.blWidth,
stroke: option.blColor,
points: [ 0, 0, option.width, 0 ],
lineCap: 'round',
lineJoin: 'round'
});
this.group.add( bottomLine ); //rectWidth
var rectAllWidth = option.width / option.data.length;
for(var i = 0; i < option.data.length; i++ ) {
var tempData = option.data[i];
//创建每个柱状图
var rect = new Konva.Rect({
x: rectAllWidth * (1/4 + i),
y: -1 * (option.height * tempData.value) - 1/2*option.blWidth,
width: 1/2 * rectAllWidth,
height: option.height * tempData.value,
fill: tempData.color,
shadowBlur: 5,
shadowColor: tempData.color,
// shadowOffset: {x : 10, y : 10},
shadowOpacity: 0.5,
opacity: .5,
name: 'histogramRect',
cornerRadius: 5
}); //创建 柱状图百分比文本
var text = new Konva.Text({
x: rectAllWidth * i,
y: -1 * (option.height * tempData.value) - 1/2*option.blWidth - option.fontSize -3,
fontSize: option.fontSize,
fill: tempData.color,
fontFamily: '微软雅黑',
text: tempData.value * 100 + '%',
name: 'txt',
width: rectAllWidth,
align: 'center'
}); //创建 柱状图名字文本
var nameText = new Konva.Text({
x: rectAllWidth * (1/2 + i),
y: option.blWidth + 3,
fontSize: option.fontSize,
fill: tempData.color,
fontFamily: '微软雅黑',
text: tempData.name,
rotation: 30
}); this.group.add( rect );
this.group.add( text );
this.group.add( nameText );
} },
playAnimate: function() {
this.group.to({
duration: .1,
opacity: 1
}); this.group.find('.histogramRect').each(function( value, index ) {
var oldY = value.y();
var oldHeight = value.height();
value.y(0);
value.height(0); value.to({
duration: .8,
y: oldY,
height: oldHeight,
opacity: .9
});
}); this.group.find(".txt").each(function(val){
var oldY = val.y();
val.y(0);
val.opacity(.1);
val.to({
duration: .8,
y: oldY,
opacity: 1
});
});
},
addToGroupOrLayer: function( group ) {
group.add(this.group);
}
};
/*
使用案例dmeo:
var data = [{
name: '阿里', value: .2, color: 'lightgreen'
},{
name: '百度', value: .4, color: 'red'
},{
name: '新浪', value: .1, color: 'blue'
},{
name: '盛大', value: .1, color: '#8E8E38'
},{
name: '360', value: .2, color: 'purple'
}]; var his = new Histogram({
data: data,
x: 1/8 * stage.width(),
y: 3/4 * stage.height(),
blWidth: 2,
blColor: 'lightblue',
width: 3/4 * stage.width(),
height: 1 * stage.height(),
fontSize: 14
});
his.addToGroupOrLayer(layer);
layer.draw();
his.playAnimate(); layer.on('click',function(){
his.playAnimate();
});
*/ //=============>E 柱状图============= //=============>S 进度条============= function ProgressBar(option) {
this.group = new Konva.Group({
x: option.x,
y: option.y
});
this.maxWidth = option.width; this.drawLayer = null; this.init(option);
} ProgressBar.prototype = {
constructor: ProgressBar,
init: function( option ) {
var innerRect = new Konva.Rect({
x: 0,
y: 0,
width: 0,
height: option.height,
fill: option.fillColor,
name: 'innerRect',
cornerRadius: 1/2 * option.height
});
this.group.add( innerRect ); var outerRect = new Konva.Rect({
x: 0,
y: 0,
width: option.width,
height: option.height,
strokeWidth: option.strokeWidth,
stroke: option.strokeColor,
name: 'outerRect',
cornerRadius: 1/2 * option.height
});
this.group.add( outerRect ); var drawText = new Konva.Text({
text: '努力加载中:0%',
x: this.maxWidth / 2 - 14 * 3,
y: -outerRect.height(),
fontSize: 14,
fontStyle: 'bold',
fontFamily: '微软雅黑',
align: 'center',
name: 'txt'
});
this.group.add( drawText );
}, addToLayerOrGroup: function( layer ) {
layer.add( this.group );
this.drawLayer = layer;
}, changeValue: function( val ) {
if(val > 1) {
val /= 100;
}
var rect = this.group.findOne(".innerRect");
// rect.width(this.maxWidth * val);
rect.to({
duration: .2,
width: this.maxWidth * val
}); var txt = this.group.findOne('.txt');
txt.text( '努力加载中:' + Number(val).toFixed(2) * 100 + '%'); this.drawLayer.batchDraw();
},
pre: function() {
var tween = new Konva.Tween({
node: this.group,
// scaleX: 1.2,
// scaleY: 1.2,
duration: .5,
opacity: .8,
onFinish: function() {
}
});
tween.play();
}
};
/*
使用方法: var bgLayer = new Konva.Layer();
var progressBar = new ProgressBar({
x: stage.width() / 8,
y: stage.height() / 2,
width: stage.width() * 3/4,
height: stage.height() / 20,
fillColor: '#cdcd00',
strokeColor: '#e0ffff',
strokeWidth: 6
});
progressBar.addToLayerOrGroup(bgLayer);
stage.add(bgLayer);
bgLayer.batchDraw(); progressBar.changeValue(.56); */
//=============>E 进度条============= //=============>S 加载动画=============
function LoadingAnimate( option ) {
this.loadingGroup = null;
this.circleArr = []; //初始化动画组件
this.init( option );
} LoadingAnimate.prototype = {
constructor: LoadingAnimate,
init: function( option ) {
option.radius = option.radius || 30;
option.cenX = option.cenX;
option.cenY = option.cenY;
option.colors = option.colors || ["orange", "lightgreen", "lightblue"];
option.duration = option.duration || 1;
option.opactiy = option.opacity || .6;
option.scaleRange = option.scaleRange || .2; this.loadingGroup = new Konva.Group({
x: option.cenX,
y: option.cenY
}); // var colors = ["orange", "lightgreen", "lightblue"];
for( var i = 0; i < 3; i++ ) {
var tempCircle = new Konva.Circle({
x: ( i-1 ) * option.radius * 2,
y: 0,
fill: colors[i],
radius: option.radius
});
this.loadingGroup.add(tempCircle);
this.circleArr[i] = tempCircle;
} },
//把动画加载到层中
addToLayerOrGroup: function( layer ) {
layer.add( this.loadingGroup );
},
//开始动画
playAnimate: function() {
var c1 = this.circleArr[0];
var c3 = this.circleArr[2];
var _this = this; c1.setZIndex(2);
c3.setZIndex(0);
c1.to({
duration: .8,
x: 2 * c1.radius(),
y: 0,
opacity: .8,
scaleY: 1.2,
scaleX: 1.2,
onFinish : function() {
c1.setZIndex(0);
c1.to({
duration: .8,
x: - 2 * c1.radius(),
y: 0,
opacity: .8,
scaleY: 1,
scaleX: 1,
});
}
}); c3.to({
duration: .8,
x: - 2 * c3.radius(),
y: 0,
opacity: .8,
scaleY: .8,
scaleX: .8,
onFinish : function() {
c3.setZIndex(2);
c3.to({
duration: .8,
x: 2 * c3.radius(),
y: 0,
opacity: .8,
scaleY: 1,
scaleX: 1,
onFinish: function() {
_this.playAnimate();
}
});
}
});
}
}; /*
使用方法:
var loadingDemo2 = new LoadingAnimate({
radius: 40,
cenX: 100,
cenY: 300,
colors: ["orange", "lightgreen", "lightblue"],
duration: 1,
opacity: .8,
scaleRange: .3
}); loadingDemo2.addToLayerOrGroup(layer);
loadingDemo2.playAnimate();
*/ //=============>E 加载动画============= //=============>S 饼状图=============
function PieChart(option) {
var _this = this;
if( !option ) {
throw new Error('请初始化饼状图的参数');
}
this.animageIndex = 0;
this.playAnimateCallee = null;
this.group = null;
this.txtGroup = null;
this.animateDuration = .8;
this.outerCircle = null;
this.data = null;
this.init(option);//初始化
} PieChart.prototype = {
constructor: PieChart,
init: function(option) {
//饼状图数据:[{name:'',value:.2,color:'red'},...]
option.data = option.data || []; //动画执行的时间
option.animateDuration = option.animateDuration || .8;
this.animateDuration = option.animateDuration;
//动画执行的效果
option.easing = option.easing || Konva.Easings.Linear;
//x,y坐标
option.x = option.x || 0;
option.y = option.y || 0;
//饼状图半径
option.radius = option.radius === 0 ? 0 : option.radius || 100; option.txtAwayFromWedge = option.txtAwayFromWedge || 20; this.data = option.data;
//扇区的组
this.group = new Konva.Group({
x: option.x,
y: option.y
}); //文字的组
this.txtGroup = new Konva.Group({
x: option.x,
y: option.y
}); //默认的旋转角度
var tempAngel = -90;
//遍历生成所有扇形的对象
for(var i = 0; i < option.data.length; i++ ) {
var wedgeAngel = option.data[i].value * 360;
var wedge = new Konva.Wedge({
x: 0,
y: 0,
radius: option.radius,
fill: option.data[i].color,
angle: 0,//后面有计算出角度放到数组中
opacity: .6,
id: option.data[i].name,
name: wedgeAngel + '',
rotation: tempAngel,
visible: true
});
this.group.add(wedge); //当前 扇形的对象 和扇形的需要旋转的角度
// arr.push({value: wedge, angle: option.data[i].value * 360}); //绘制 文字
//扇形区域的中间
var rotationAngle = 0;
var totalAngle = tempAngel + 1/2 * wedgeAngel;
//设置文字的x坐标
var txtX = Math.cos( totalAngle * Math.PI / 180) * (option.radius + option.txtAwayFromWedge);
// 设置文字的y坐标
var txtY = Math.sin( totalAngle * Math.PI / 180) * (option.radius + option.txtAwayFromWedge);
var txtTitle = option.data[i].name +' ' + option.data[i].value * 100 + '%';
var txt = new Konva.Text({
x: txtX,
y: txtY,
fill: option.data[i].color,
fontSize: '16px',
fontFamily: '微软雅黑',
fontStyle: 'bold',
align: 'left',
id: 'txt_' + option.data[i].name,
text: txtTitle,
rotation: rotationAngle,
visible: false //默认隐藏
}); this.txtGroup.add(txt); //下面这段代码是根据 文字的位置设置一下文字的距离原型的位置
if( totalAngle > 90 && totalAngle < 270 ) {
// rotationAngle = -30;
txt.x( txt.x()-txt.getWidth() );
} //设置下一个元素旋转到具体的位置
tempAngel += option.data[i].value * 360;
} // 绘制外圆
this.outerCircle = new Konva.Circle({
stroke: '#a0a0a0',
strokeWidth: 1,
radius: option.radius + 5,
x: option.x,
y: option.y
}); },
//展示动画
playAnimate: function() {
_this = this;
if(this.animageIndex >= this.data.length) {
_this.animageIndex = 0;
return;
} //先初始化到0的状态,然后进行绘制。
if(this.animageIndex == 0) {
_this.group.getChildren().each(function(value, index){
value.angle(0);
});
_this.txtGroup.getChildren().each(function(value,index){
value.hide();
});
}
this.playAnimateCallee= arguments.callee;//当前函数 //绘制一个 扇区的动画
var wedge = this.group.getChildren()[this.animageIndex];
var angel = Number(wedge.name());//扇区的度数
wedge.to({
angle: angel,
duration: angel * this.animateDuration / 360,
onFinish: function() {
_this.txtGroup.getChildren()[_this.animageIndex].show();
_this.txtGroup.getParent().draw();
_this.animageIndex++;
_this.playAnimateCallee();//调用当前函数自身,形成动画队列。
}
});
},
//把当前 饼状图添加到 层
addToLayer: function(layer) {
layer.add(this.group);
layer.add(this.txtGroup);
layer.add(this.outerCircle);
layer.draw();
},
}; /*
用法:
//饼状图数据
var data = [{
name: "前端",
value: .25,
color: 'lightblue'
},{
name: "php",
value: .2,
color: 'orange'
},{
name: "UI",
value: .3,
color: 'blue'
},{
name: "C++",
value: .05,
color: 'green'
},{
name: "游戏",
value: .1,
color: 'purple'
},{
name: "Java",
value: .1,
color: 'red'
}]; //创建饼状图
var pieChart = new PieChart({
data: data,//扇形区域的数据
animateDuration: 2,//扇形动画的时间
easing: Konva.Easings.EaseIn,//扇形动画的速度规格
x: cenX,
y: cenY,
radius: .14 * stage.width(),//半径
txtAwayFromWedge: .2 * .14 * stage.width()//扇形上的文字的距离圆形的距离
});
pieChart.addToLayer(layer);
pieChart.playAnimate();
layer.draw(); layer.on('click tap', function(){
pieChart.playAnimate();
});
*/ //=============E 饼状图=============

饼状图

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>饼状图</title>
<style>
body {
padding: 0;
margin: 0;
background-color: #f0f0f0;
overflow: hidden;
}
</style>
<script src="./konva.js"></script>
<script src="./KonvaExtend.js"></script>
</head>
<body>
<div id="container">
</div> <script>
//创建舞台
var stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,//全屏
height: window.innerHeight
}); //创建层
var layer = new Konva.Layer();
stage.add(layer); //中心点坐标
var cenX = stage.width() / 2;
var cenY = stage.height() / 2; //创建加载层动画
//饼状图数据
var data = data = [
{name:"apple", value:0.24, color:"pink"},
{name:"三星", value:0.26, color:"skyblue"},
{name:"华为", value:0.13, color:"orange"},
{name:"锤子", value:0.17, color:"#333"},
{name:"小米", value:0.08, color:"purple"},
{name:"其他", value:0.12, color:"cyan"}
]; //创建饼状图
var maxSize = stage.width() > stage.height() ? stage.height() : stage.width();
var pieChart = new PieChart({
data: data,//扇形区域的数据
animateDuration: 2,//扇形动画的时间
easing: Konva.Easings.EaseIn,//扇形动画的速度规格
x: cenX,
y: cenY,
radius: .3 * maxSize,//半径
txtAwayFromWedge: .3 * .3 * maxSize//扇形上的文字的距离圆形的距离
});
pieChart.addToLayer(layer);
pieChart.playAnimate();
layer.draw(); layer.on('click tap', function(){
pieChart.playAnimate();
}); </script>
</body>
</html>

柱状图

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>柱状图</title>
<style>
body {
padding: 0;
margin: 0;
background-color: #f0f0f0;
overflow: hidden;
}
</style>
<script src="./konva.js"></script>
<script src="./KonvaExtend.js" charset="utf-8"></script>
</head>
<body>
<div id="container">
</div> <script>
var stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight
}); var layer = new Konva.Layer();
stage.add(layer); var cenX = stage.width() / 2;
var cenY = stage.height() / 2; var data = [
{ name: '百度', value: 2, color: 'blue' },
{ name: '阿里', value: 4, color: 'red' },
{ name: '新浪', value: 1, color: 'purple' },
{ name: '搜狐', value: 1, color: 'navy' },
{ name: '兄弟连', value: 2, color: 'orange' }
]; var his = new Histogram({
data: data,
x: 1/8 * stage.width(),
y: 3/4 * stage.height(),
blWidth: 2,
blColor: 'lightblue',
width: 3/4 * stage.width(),
height: 1/3 * stage.height(),
fontSize: 14
});
his.addToGroupOrLayer(layer);
layer.draw();
his.playAnimate(); layer.on('click',function(){
his.playAnimate();
});
</script>
</body>
</html>

封装构造函数,用canvas写饼状图和柱状图的更多相关文章

  1. arcgis api for flex之专题图制作(饼状图,柱状图等)

    最近公司给我一个任务,就是利用arcgis api for flex实现在地图上点(业务数据)直接显示饼状图以及柱状图的专题图制作,而不是通过点击点显示气泡窗口的形式来实现,这个公司已经实现了. 经过 ...

  2. FusionCharts数据展示成饼状图、柱状图和折线图

    FusionCharts数据展示成饼状图.柱状图和折线图 本文以展示柱状图为例进行介绍,当然这仅仅是一种方法而已:还有很多方法可以用于展示图表,例如echarts,自定义图表标签.使用jfreecha ...

  3. Java-jfree报表(学习整理)----饼状图、柱状图、折线统计图

    1.使用的报表工具: jfree报表 2.下载网址: http://www.jfree.org/ 下载之后先解压:如下图 下载后:需要的jar包!如下图: 打开:找到以下的两个jar包 再导入开发项目 ...

  4. jasper(二):制作饼状图和柱状图

    在新建一个框架之后 我们也是要执行 add dataset,来添加一个链接数据库的语句,因为这是个饼状图,所以要用group by 全部放入右边的框架 点完成 接下来,就是要创建饼状图,就要点击 窗口 ...

  5. PHP实现动态生成饼状图、柱状图和折线图(转载)

    PHP在图像操作方面的表现非常出色,我们只需借助可以免费得到的GD库便可以轻松实现图.表勾画.下面将分别介绍PHP实现的饼状图.折线图和柱状图以 及他们的使用方法,这几段代码的特点就是不需要再把它们复 ...

  6. 用FusionChartsFree做饼状图、柱状图、折线图的实例

    1.先来看看要进行表现的页面:myChart.jsp <%@ page language="java" contentType="text/html; charse ...

  7. canvas实现饼状图

    效果图如下: html: <canvas id="myCanvas" width="500" height="500">< ...

  8. C#的WinForm中制作饼状图和柱状图

    using System; using System.IO;//用于文件存取 using System.Data;//用于数据访问 using System.Drawing;//提供画GDI+图形的基 ...

  9. DevExpress使用之ChartControl控件绘制图表(多坐标折线图、柱状图、饼状图)

    最近因为公司项目需要用到WinForm的DecExpress控件,在这里把一些使用方法总结一下. DevExpress中有一个专门用来绘制图表的插件ChartControl,可以绘制折线图.饼状图.柱 ...

随机推荐

  1. [洛谷P5057][CQOI2006]简单题

    题目大意:有一个长度为$n$的$01$串,两个操作: $1\;l\;r:$把区间$[l,r]$翻转($0->1,1->0$) $2\;p:$求第$p$位是什么 题解:维护前缀异或和,树状数 ...

  2. [NOIP2017]逛公园 最短路图 拓扑序DP

    ---题面--- 题解: 挺好的一道题. 首先我们将所有边反向,跑出n到每个点的最短路,然后f[i][j]表示从i号节点出发,路径长比最短路大j的方案数. 观察到,如果图中出现了0环,那么我们可以通过 ...

  3. Android APP性能优化(最新总结)

    导语   安卓大军浩浩荡荡,发展已近十个年头,技术优化日异月新,如今Android 8.0 Oreo 都发布了,Android系统性能已经非常流畅了.但是,到了各大厂商手里,改源码自定系统,使得And ...

  4. Android 内核--Binder架构分析

    一.Binder架构 在Android中,Binder用于完成进程间通信(IPC),即把多个进程关联在一起.比如,普通应用程序可以调用音乐播放服务提供的播放.暂停.停止等功能.Binder工作在Lin ...

  5. ContestHunter暑假欢乐赛 SRM 06

    T1二分check...为什么这么显然的我没看出来TAT,还在想倒着加入并查集check什么的,题写太多思维定势啦QAQ T2是NOIP题的弱化版...当时没看出来,写了个DP.可以看出这一位比上一位 ...

  6. Java的各种中文乱码解决方法

    一.Servlet输出乱码 1. 用servlet.getOutStream字节流输出中文,假设要输出的是String str ="钓鱼岛是中国的,无耻才是日本的". 1.1 若是 ...

  7. HDU2444 :The Accomodation of Students(二分图染色+二分图匹配)

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  8. kafka 命令笔记

    以下命令都是在kafka根目录下 启动自带的zookeeper bin/zookeeper-server-start.sh config/zookeeper.properties 启动kafka(启动 ...

  9. 让ie8、ie9支持媒体查询

    <!-- 让IE8/9支持媒体查询,从而兼容栅格 --> <!--[if lt IE 9]> <script src="https://cdn.staticfi ...

  10. 【洛谷 P3187】 [HNOI2007]最小矩形覆盖 (二维凸包,旋转卡壳)

    题目链接 嗯,毒瘤题. 首先有一个结论,就是最小矩形一定有条边和凸包重合.脑补一下就好了. 然后枚举凸包的边,用旋转卡壳维护上顶点.左端点.右端点就好了. 上顶点用叉积,叉积越大三角形面积越大,对应的 ...