-
Notifications
You must be signed in to change notification settings - Fork 0
/
pie.html
321 lines (307 loc) · 11.4 KB
/
pie.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
<!doctype html>
<html>
<head>
<title>扇形图</title>
<meta http-equiv="content-type" content="text/html;charset=GBK"/>
<script src="libs/util.js"></script>
<script src="libs/painter.js"></script>
<script type="text/javascript">
function getSectorData(){
return [
{name:'中国',value:10},//,color:'red'},
{name:'美国',value:30},//,color:'green'},
{name:'英国',value:15},//,color:'yellow'},
{name:'德国',value:15},//,color:'black'},
{name:'法国',value:10},//,color:'snow'},
{name:'日本',value:5},//,color:'white'}
];
}
function pie(canvasId){
this.canvasId = canvasId;
this.canvas = $id(canvasId);
this.ctx = this.canvas.getContext('2d');
}
pie.prototype = {
paint: function (options) {
if (!options) options = {};
if (!options.startAngle) options.startAngle = Math.PI * 1.5;
var data = options.data;
var sum = 0;
data.each(function (val) {
sum += val.value;
});
if (sum == 0) {
(options.noDataFunction || function () { alert('无数据'); })();
return;
}
data.each(function (val) {
val.percent = (val.value / sum);
});
//半径
var radius = options.radius || Math.min(this.canvas.width / 2, this.canvas.height / 2);
this.radius = radius;
var temp = Math.min(this.canvas.width / 2, this.canvas.height / 2);
var center = options.center || { x: temp, y: temp };
this.center = center; this.radium = radius;
//开始画扇形
var startAngle = options.startAngle;
this.startAngle = startAngle;
var painter = this;
var ctx = this.ctx;
data.each(function (item) {
var angle = item.percent * Math.PI * 2;
if (startAngle > Math.PI * 2) startAngle -= Math.PI * 2;
var endAngle = startAngle + angle;
if (endAngle > Math.PI * 2) endAngle -= Math.PI * 2;
ctx.fillStyle = item.color || painter.getRandomColor(item.name);
ctx.beginPath();
ctx.moveTo(center.x, center.y);
ctx.arc(center.x, center.y, radius, startAngle, endAngle, false);
ctx.closePath();
ctx.fill();
item.range = { start: startAngle, end: endAngle };
startAngle = endAngle;
});
this.data = data;
this.canvas.painter = this;
addEvent(this.canvas, 'click', this._click);
addEvent(this.canvas, 'mouseover', this._mouseOver);
addEvent(this.canvas, 'mousemove', this._mouseMove);
addEvent(this.canvas, 'mouseout', this._mouseOut);
},
_getTargetPartRelatedData: function (painter, ev) {
//转换成相对于圆心的坐标
var center = painter.center;
var offset = { x: ev.offsetX - center.x, y: ev.offsetY - center.y };
var angle = Math.atan2(offset.y, offset.x);
if (angle < 0) angle = Math.PI * 2 + angle;
var pointToCenter = offset.y / Math.sin(angle);
if (Math.abs(pointToCenter) > painter.radium) {
setDebugMsg('不在圆形范围内' + offset.x + ',' + offset.y, false);
return null;
}
setDebugMsg('在圆内,开始计算扇形区域' + offset.x + ',' + offset.y);
var mousePointData = null;
painter.data.each(function (item, arr) {
var range = item.range;
if (range.start <= range.end) {
if (range.start <= angle && range.end >= angle) {
arr.breakLoop = true;
mousePointData = item;
}
} else {
var ranges = [{ start: range.start, end: Math.PI * 2 }, { start: 0, end: range.end}];
ranges.each(
function (r, rs) {
if (r.start <= angle && r.end >= angle) {
rs.breakLoop = true;
mousePointData = item;
arr.breakLoop = true;
}
}
);
}
});
if (mousePointData) {
setDebugMsg('mouse point to:' + mousePointData.name);
} else {
setDebugMsg('mouse point to: null');
}
return mousePointData;
},
_mouseOver: function (ev) { },
_mouseMove: function (ev) {
ev = ev || event;
getOffset(ev);
var target = getEventTarget(ev);
var painter = target.painter;
var data = painter._getTargetPartRelatedData(painter, ev);
},
_mouseOut: function (ev) { },
_click: function (ev) {
ev = ev || event;
getOffset(ev);
var target = getEventTarget(ev);
var painter = target.painter;
var data = painter._getTargetPartRelatedData(painter, ev);
setDebugMsg('you click ' + data.name);
painter.clickedData = data;
var moveStep = painter.moveStep || 1;
painter.pieOffset = 0;
var startAngle = painter.startAngle;
var maxOffset = painter.radius / 10;
var radius = painter.radius;
painter.intervalHandler = setInterval(function () {
if (painter.pieOffset > maxOffset) {
clearInterval(painter.intervalHandler);
return;
}
painter.ctx.clearRect(0, 0, painter.canvas.width, painter.canvas.height);
painter.randomColorMaxIndex = false;
painter.usedColor = [];
painter.pieOffset += moveStep;
var ctx = painter.ctx;
painter.data.each(function (item) {
var angle = item.percent * Math.PI * 2;
if (startAngle > Math.PI * 2) startAngle -= Math.PI * 2;
var endAngle = startAngle + angle;
if (endAngle > Math.PI * 2) endAngle -= Math.PI * 2;
ctx.fillStyle = item.color || painter.getRandomColor(item.name);
ctx.beginPath();
var tempCenter = { x: painter.center.x, y: painter.center.y };
if (painter.clickedData && item == painter.clickedData) {
var middleAngle = startAngle <= endAngle ? (startAngle + endAngle) / 2 : (startAngle + endAngle + Math.PI * 2) / 2;
tempCenter.x = tempCenter.x + painter.pieOffset * Math.cos(middleAngle);
tempCenter.y = tempCenter.y + painter.pieOffset * Math.sin(middleAngle);
}
ctx.moveTo(tempCenter.x, tempCenter.y);
ctx.arc(tempCenter.x, tempCenter.y, radius, startAngle, endAngle, false);
ctx.closePath();
ctx.fill();
item.range = { start: startAngle, end: endAngle };
startAngle = endAngle;
});
}, 50);
},
getRandomColor: function (name) {
var fullName = this.canvasId + '$' + name;
//var storageColor = localStorage.getItem(fullName);
//if(storageColor) return storageColor;
var colors = this.colors || defaultColors;
if (!this.usedColor) this.usedColor = [];
var exists;
var tempColor = 'Red';
var painter = this;
var tempIndex = painter.randomColorMaxIndex || 0;
do {
tempColor = colors[tempIndex];
if (colors.length == painter.usedColor.length) break;
painter.usedColor.each(function (c, arr) { exists = (c == tempColor); if (exists) arr.breakLoop = true; });
tempIndex++;
} while (exists);
painter.randomColorMaxIndex = tempIndex;
//localStorage.setItem(fullName,tempColor);
painter.usedColor.push(tempColor);
return tempColor;
}
};
var defaultColors = [/*红色*/'#FF0000',
/*绿色*/'#00FF00',
/*蓝色*/'#0000FF',
/*牡丹红*/'#FF00FF',
/*青色*/'#00FFFF',
/*黄色*/'#FFFF00',
/*黑色*/'#000000',
/*海蓝*/'#70DB93',
/*巧克力色*/'#5C3317',
/*蓝紫色*/'#9F5F9F',
/*黄铜色*/'#B5A642',
/*亮金色*/'#D9D919',
/*棕色*/'#A67D3D',
/*青铜色*/'#8C7853',
/*士官服蓝色*/'#5F9F9F',
/*铜色*/'#B87333',
/*珊瑚红*/'#FF7F00',
/*紫蓝色*/'#42426F',
/*深棕*/'#5C4033',
/*深绿*/'#2F4F2F',
/*深铜绿色*/'#4A766E',
/*深橄榄绿*/'#4F4F2F',
/*深兰花色*/'#9932CD',
/*深紫色*/'#871F78',
/*深石板蓝*/'#6B238E',
/*深铅灰色*/'#2F4F4F',
/*深棕褐色*/'#97694F',
/*深绿松石色*/'#7093DB',
/*暗木色*/'#855E42',
/*淡灰色*/'#545454',
/*土灰玫瑰红色*/'#545454',
/*长石色*/'#D19275',
/*火砖色*/'#8E2323',
/*森林绿*/'#238E23',
/*金色*/'#CD7F32',
/*鲜黄色*/'#DBDB70',
/*灰色*/'#C0C0C0',
/*铜绿色*/'#527F76',
/*青黄色*/'#93DB70',
/*猎人绿*/'#215E21',
/*印度红*/'#4E2F2F',
/*土黄色*/'#9F9F5F',
/*浅蓝色*/'#C0D9D9',
/*浅灰色*/'#A8A8A8',
/*浅钢蓝色*/'#8F8FBD',
/*浅木色*/'#E9C2A6',
/*石灰绿色*/'#32CD32',
/*桔黄色*/'#E47833',
/*褐红色*/'#8E236B',
/*中海蓝色*/'#32CD99',
/*中蓝色*/'#3232CD',
/*中森林绿*/'#6B8E23',
/*中鲜黄色*/'#EAEAAE',
/*中兰花色*/'#9370DB',
/*中海绿色*/'#426F42',
/*中石板蓝色*/'#7F00FF',
/*中春绿色*/'#7FFF00',
/*中绿松石色*/'#70DBDB',
/*中紫红色*/'#DB7093',
/*中木色*/'#A68064',
/*深藏青色*/'#2F2F4F',
/*海军蓝*/'#23238E',
/*霓虹篮*/'#4D4DFF',
/*霓虹粉红*/'#FF6EC7',
/*新深藏青色*/'#00009C',
/*新棕褐色*/'#EBC79E',
/*暗金黄色*/'#CFB53B',
/*橙色*/'#FF7F00',
/*橙红色*/'#FF2400',
/*淡紫色*/'#DB70DB',
/*浅绿色*/'#8FBC8F',
/*粉红色*/'#BC8F8F',
/*李子色*/'#EAADEA',
/*石英色*/'#D9D9F3',
/*艳蓝色*/'#5959AB',
/*鲑鱼色*/'#6F4242',
/*猩红色*/'#BC1717',
/*海绿色*/'#238E68',
/*半甜巧克力色*/'#6B4226',
/*赭色*/'#8E6B23',
/*银色*/'#E6E8FA',
/*天蓝*/'#3299CC',
/*石板蓝*/'#007FFF',
/*艳粉红色*/'#FF1CAE',
/*春绿色*/'#00FF7F',
/*钢蓝色*/'#236B8E',
/*亮天蓝色*/'#38B0DE',
/*棕褐色*/'#DB9370',
/*紫红色*/'#D8BFD8',
/*石板蓝色*/'#ADEAEA',
/*浓深棕色*/'#5C4033',
/*淡浅灰色*/'#CDCDCD',
/*紫罗兰色*/'#4F2F4F',
/*紫罗兰红色*/'#CC3299',
/*麦黄色*/'#D8D8BF',
/*黄绿色*/'#99CC32'];
addLoadEvent(function(){
var s = new pie('canvasSector');
s.paint({radius:80,data:getSectorData()});
});
function setDebugMsg(msg) {
$id('debug').innerHTML = msg;
}
</script>
</head>
<body>
<canvas id="canvasSector" width="200" height="200" style="background:#f0f0f0;border:1px solid #eee;">
您的浏览器不支持哟
</canvas>
<div id="debug"></div>
<style>
pre{padding: 60px 0 0 30px;color: gray;font-size: .8em;line-height: 20px;}
</style>
<p><a href="./index.html">返回列表页</a></p>
<pre>
Author:yukaizhao http://www.cnblogs.com/yukaizhao/ http://weibo.com/yukaizhao/
参与项目或技术交流:<a href="mailto:[email protected]">[email protected]</a>
</pre>
</body>
</html>