第167天:canvas绘制柱状图

canvas绘制柱状图

1、HTML

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
 6     <title>06柱状图面向对象版本</title>
 7     <style>
 8         body {
 9             padding: 0;
10             margin: 0;
11             background-color: #f0f0f0;
12             overflow: hidden;
13         }
14     </style>
15     <script src="bower_components/konva/konva.min.js"></script>
16     <script src="js/HistogramChart.js"></script>
17     
18 </head>
19 <body>
20     <div id="container">
21     </div>
22 
23     <script>
24         //创建舞台
25         var stage = new Konva.Stage({
26             container: 'container',
27             width: window.innerWidth,//全屏
28             height: window.innerHeight
29         });
30 
31         //创建层
32         var layer = new Konva.Layer();
33         stage.add(layer);
34     
35         //中心点坐标
36         var cenX = stage.width() / 2;
37         var cenY = stage.height() / 2;
38 
39         //柱状图的数据
40         var data = [
41             { name: '前端', value: '.8', color: 'green'},
42             { name: 'PHP', value: '.3', color: 'blue'},
43             { name: 'Java', value: '.7', color: 'red'},
44             { name: 'UI', value: '.9', color: 'orange'},
45             { name: 'IOS', value: '.4', color: 'purple'},
46             { name: 'Android', value: '.9', color: 'pink'}
47         ];
48 
49 
50         var h  = new HistogramChart({
51             x: 1/8 * stage.width(),
52             y: 3/4 * stage.height(),
53             w: 3/4 * stage.width(),
54             h: 1/2 * stage.height(),
55             data: data
56         });
57 
58         h.addToGroupOrLayer( layer );
59 
60         layer.draw();
61 
62         stage.on('contentClick', function(){
63             h.playAnimate();
64         });
65 
66         
67     </script>
68 
69 
70 </body>
71 </html>

2、HistogramChart.js

  1 // Histogram:柱状图的意思 英 ['hɪstəgræm]  美 ['hɪstəɡræm]
  2 function HistogramChart( option ) {
  3     // zzt
  4     this._init( option );
  5     // JQJB:警情级别
  6 }
  7 
  8 HistogramChart.prototype = {
  9     _init: function( option ) {
 10         this.x = option.x || 0;
 11         this.y = option.y || 0; //柱状图的原点坐标
 12         this.w = option.w || 0; //柱状图的总宽度
 13         this.h = option.h || 0; //柱状图高度
 14 
 15         this.data = option.data || [];
 16 
 17         var x0 = 0;
 18         var y0 = 0;
 19 
 20         // 柱状图中所有的元素的组
 21         this.group = new Konva.Group({
 22             x: this.x,
 23             y: this.y
 24         });
 25 
 26         //放矩形的组
 27         this.rectGroup = new Konva.Group({
 28             x: 0,
 29             y: 0
 30         });
 31         this.group.add( this.rectGroup );
 32 
 33         //添加一个放百分比文字的组
 34         this.textPercentGroup = new Konva.Group({
 35             x: 0,
 36             y: 0
 37         });
 38         this.group.add( this.textPercentGroup );
 39 
 40         //初始化底线
 41         var bsLine = new Konva.Line({
 42             //x:从 1/8 x,  3/4
 43             //y: 3/4 高度处
 44             points: [x0,y0, x0+this.w, y0], //要求 底线按照画布的左上角顶点进行定位。
 45             strokeWidth: 1,
 46             stroke: 'lightgreen',
 47         });
 48 
 49         this.group.add( bsLine );
 50 
 51         var rectWidth = this.w / this.data.length; //每个矩形占用的总宽度
 52         var height = this.h;
 53 
 54 
 55         var self = this;// 当前柱状图的对象
 56         //初始化 矩形
 57         //初始化 文字%
 58         //初始化 底部文字
 59         this.data.forEach(function(item, index) {// item:数组中元素,index是索引值
 60             //生成一个矩形
 61             var rect = new Konva.Rect({
 62                 x: x0 + (1/4 + index ) * rectWidth,//
 63                 y: y0 - item.value * height,
 64                 width: 1/2 * rectWidth,
 65                 height: item.value * height,
 66                 fill: item.color,
 67                 opacity: .8,         //设置透明度
 68                 cornerRadius: 10,     //设置圆角
 69                 shadowBlur: 10,          //设置阴影的模糊级别
 70                 shadowColor: 'black',//设置阴影的颜色
 71                 // shadowOffsetX: 4, //设置阴影的X偏移量
 72                 // shadowOffsetY: 4     //设置应用的Y偏移量
 73             });
 74             self.rectGroup.add( rect );
 75 
 76             //把百分比的文字放到 柱状图的顶部
 77             var text = new Konva.Text({
 78                 x: x0 + (index ) * rectWidth,//
 79                 y: y0 - item.value * height - 14,
 80                 fontSize: 14,
 81                 text: item.value * 100 + '%',
 82                 fill: item.color,
 83                 width: rectWidth,// 配合让文字居中
 84                 align: 'center',  //
 85                 name: 'textPercent'  //设置文字的name后,可以通过类选择器进行选取。
 86             });
 87             self.textPercentGroup.add( text );
 88 
 89             //把百分比的文字放到 柱状图的顶部
 90             var textBottom = new Konva.Text({
 91                 x: x0 + (1/4 + index ) * rectWidth,//
 92                 y: y0,
 93                 fontSize: 14,
 94                 text: item.name,
 95                 fill: item.color,
 96                 // width: rectWidth,// 配合让文字居中
 97                 // align: 'center',  //
 98                 rotation: 30
 99             });
100             self.group.add( textBottom );
101         });
102     },
103     addToGroupOrLayer: function( arg ) {
104         arg.add( this.group );
105     },
106     playAnimate: function() {
107         var self = this;
108         // 让柱状图 y→ y0  height:0
109         this.rectGroup.getChildren().each(function(item, index){
110             item.y(0);
111             item.height(0);
112             //经过一个动画还原
113             item.to({
114                 duration: 1,
115                 y: - self.data[index].value * self.h,
116                 height: self.data[index].value * self.h
117             });
118         });
119         //让文字有个动画
120         this.textPercentGroup.getChildren().each(function( item, index ){
121             item.y(-14);
122             item.to({
123                 duration: 1,
124                 y: - self.data[index].value * self.h -14
125             });
126         });
127     }
128 }

运行效果:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏搞前端的李蚊子

使用canvas实现一个圆球的触壁反弹

HTML <canvas id="canvas" width="500" height="500" style="border: 1px solid #FF00...

2875
来自专栏GIS讲堂

Arcgis for JavaSctipt之常用Layer详解

概述:Arcgis for Javasctipt中常见的layer有动态图层(ArcGISDynamicMapServiceLayer

1475
来自专栏我分享我快乐

web前端设计基础单词表

A align 对齐 active 激活 absolute 绝对 alpha 图像通道 animate 动画 animation 动画片 alert 提醒 ad...

3838
来自专栏Google Dart

AngularDart Material Design 图标 顶

确保考虑RTL。 具体来说,如果要为RTL UI翻转图标,请使用flip属性。 阅读这些指南,了解何时翻转何时不翻转图标。

1206
来自专栏猛牛哥的博客

HTMLayout 界面贴图技术

2544
来自专栏阮一峰的网络日志

Flex 布局教程:实例篇

上一篇文章介绍了Flex布局的语法,今天介绍常见布局的Flex写法。 你会看到,不管是什么布局,Flex往往都可以几行命令搞定。 ? 我只列出代码,详细的语法解...

41412
来自专栏WindCoder

11/20Android开发笔记

901
来自专栏黑泽君的专栏

4道html笔试小题

1435
来自专栏一“技”之长

Android开发之LinearLayout布局详解

        LinaerLayout又被称为线性布局,是Android界面开发中常用的一种容器视图控件。可以使用XML布局文件配置和代码动态创建两种方式来使...

953
来自专栏HTML5学堂

“鼠标移入显示悬浮框”特效,也可以“高大上”

HTML5学堂(码匠):网站中最为常见的一种特效——鼠标移入元素,出现介绍信息的悬浮框,要么是淡入,要么是单方向的滑入,总觉得太单一了有木有?其实,稍微调整一下...

4629

扫码关注云+社区