html5jp_graphs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.gitigore +2 -0
  2. data/README.rdoc +82 -0
  3. data/Rakefile +22 -0
  4. data/html5jp_graphs.gemspec +17 -0
  5. data/lib/examples/sample_graph_circle_1.html +54 -0
  6. data/lib/examples/sample_graph_circle_2.html +61 -0
  7. data/lib/examples/sample_graph_line_1.html +44 -0
  8. data/lib/examples/sample_graph_line_2.html +53 -0
  9. data/lib/examples/sample_graph_radar_1.html +47 -0
  10. data/lib/examples/sample_graph_radar_2.html +52 -0
  11. data/lib/examples/sample_graph_vbar_1.html +51 -0
  12. data/lib/examples/sample_graph_vbar_2.html +52 -0
  13. data/lib/examples/sample_graph_vbar_3.html +52 -0
  14. data/lib/examples/sample_graph_vbar_4.html +52 -0
  15. data/lib/generators/html5jp_graphs/USAGE +8 -0
  16. data/lib/generators/html5jp_graphs/html5jp_graphs_generator.rb +12 -0
  17. data/lib/generators/html5jp_graphs/templates/excanvas/AUTHORS +10 -0
  18. data/lib/generators/html5jp_graphs/templates/excanvas/COPYING +202 -0
  19. data/lib/generators/html5jp_graphs/templates/excanvas/README +22 -0
  20. data/lib/generators/html5jp_graphs/templates/excanvas/examples/example1.html +93 -0
  21. data/lib/generators/html5jp_graphs/templates/excanvas/examples/example2.html +513 -0
  22. data/lib/generators/html5jp_graphs/templates/excanvas/examples/example3.html +284 -0
  23. data/lib/generators/html5jp_graphs/templates/excanvas/examples/ff.jpg +0 -0
  24. data/lib/generators/html5jp_graphs/templates/excanvas/excanvas-compressed.js +19 -0
  25. data/lib/generators/html5jp_graphs/templates/excanvas/excanvas.js +785 -0
  26. data/lib/generators/html5jp_graphs/templates/excanvas/testcases/arc.html +49 -0
  27. data/lib/generators/html5jp_graphs/templates/excanvas/testcases/linewidth.html +47 -0
  28. data/lib/generators/html5jp_graphs/templates/excanvas/testcases/overflow.html +37 -0
  29. data/lib/generators/html5jp_graphs/templates/excanvas/testcases/quadraticcurve.html +74 -0
  30. data/lib/generators/html5jp_graphs/templates/excanvas/testcases/resizing.html +65 -0
  31. data/lib/generators/html5jp_graphs/templates/graph/circle.js +407 -0
  32. data/lib/generators/html5jp_graphs/templates/graph/line.js +577 -0
  33. data/lib/generators/html5jp_graphs/templates/graph/radar.js +545 -0
  34. data/lib/generators/html5jp_graphs/templates/graph/vbar.js +1156 -0
  35. data/lib/html5jp_graphs.rb +1 -0
  36. data/lib/html5jp_graphs/version.rb +3 -0
  37. data/lib/html5jp_graphs_helper.rb +255 -0
  38. data/tasks/html5jp_graphs_tasks.rake +4 -0
  39. data/test/html5jp_graphs_test.rb +8 -0
  40. metadata +88 -0
@@ -0,0 +1,545 @@
1
+ // Copyright 2007 futomi http://www.html5.jp/
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ if( typeof html5jp == 'undefined' ) {
16
+ html5jp = new Object();
17
+ }
18
+ if( typeof html5jp.graph == 'undefined' ) {
19
+ html5jp.graph = new Object();
20
+ }
21
+
22
+ /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
23
+ * コンストラクタ
24
+ * ---------------------------------------------------------------- */
25
+ html5jp.graph.radar = function (id) {
26
+ var elm = document.getElementById(id);
27
+ if(! elm) { return; }
28
+ if(elm.nodeName != "CANVAS") { return; }
29
+ if(elm.parentNode.nodeName != "DIV") { return; };
30
+ this.canvas = elm;
31
+ /* CANVAS要素 */
32
+ if ( ! this.canvas ){ return; }
33
+ if ( ! this.canvas.getContext ){ return; }
34
+ /* 2D コンテクストの生成 */
35
+ this.ctx = this.canvas.getContext('2d');
36
+ this.canvas.style.margin = "0";
37
+ this.canvas.parentNode.style.position = "relative";
38
+ this.canvas.parentNode.style.padding = "0";
39
+ };
40
+ /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
41
+ * 描画
42
+ * ---------------------------------------------------------------- */
43
+ html5jp.graph.radar.prototype.draw = function(items, inparams) {
44
+ if( ! this.ctx ) {return;}
45
+ /* パラメータの初期化 */
46
+ var params = {
47
+ aCap: [],
48
+ aCapColor: "#000000",
49
+ aCapFontSize: "12px",
50
+ aCapFontFamily: "Arial,sans-serif",
51
+ aMax: null,
52
+ aMin: 0,
53
+ backgroundColor: "#ffffff",
54
+ cBackgroundColor: "#eeeeee",
55
+ cBackgroundGradation: true,
56
+ chartShape: "polygon",
57
+ faceColors: null,
58
+ _faceColors: ["rgb(24,41,206)", "rgb(198,0,148)", "rgb(214,0,0)", "rgb(255,156,0)", "rgb(33,156,0)", "rgb(33,41,107)", "rgb(115,0,90)", "rgb(132,0,0)", "rgb(165,99,0)", "rgb(24,123,0)"],
59
+ faceAlpha: 0.1,
60
+ borderAlpha: 0.5,
61
+ borderWidth: 1,
62
+ axisColor: "#aaaaaa",
63
+ axisWidth: 1,
64
+ aLinePositions: "auto",
65
+ aLineWidth: 1,
66
+ aLineColor: "#cccccc",
67
+ sLabel: true,
68
+ sLabelColor: "#000000",
69
+ sLabelFontSize: "10px",
70
+ sLabelFontFamily: "Arial,sans-serif",
71
+ legend: true,
72
+ legendFontSize: "12px",
73
+ legendFontFamily: "Arial,sans-serif",
74
+ legendColor: "#000000"
75
+ };
76
+ if( inparams && typeof(inparams) == 'object' ) {
77
+ for( var key in inparams ) {
78
+ if( key.match(/^_/) ) { continue; }
79
+ params[key] = inparams[key];
80
+ }
81
+ }
82
+ if( params.faceColors != null && params.faceColors.length > 0 ) {
83
+ for( var i=0; i<params._faceColors.length; i++ ) {
84
+ var c = params.faceColors[i];
85
+ var co = this._csscolor2rgb(c);
86
+ if( co == null ) {
87
+ params.faceColors[i] = params._faceColors[i];
88
+ } else {
89
+ params.faceColors[i] = c;
90
+ }
91
+ }
92
+ } else {
93
+ params.faceColors = params._faceColors;
94
+ }
95
+ this.params = params;
96
+ /* CANVASの背景を塗る */
97
+ if( params.backgroundColor ) {
98
+ this.ctx.beginPath();
99
+ this.ctx.fillStyle = params.backgroundColor;
100
+ this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
101
+ }
102
+ /* CANVAS要素の横幅が縦幅の1.5倍未満、または縦幅が200未満であれば凡例は強制的に非表示 */
103
+ if(this.canvas.width / this.canvas.height < 1.5 || this.canvas.height < 200) {
104
+ params.legend == false;
105
+ }
106
+ /* CANVAS要素の座標 */
107
+ var canvas_pos = this._getElementAbsPos(this.canvas);
108
+ /* チャートの中心座標と半径 */
109
+ var cpos = {
110
+ x: this.canvas.width / 2,
111
+ y: this.canvas.height / 2,
112
+ r: Math.min(this.canvas.width, this.canvas.height) * 0.75 / 2
113
+ };
114
+ if(params.legend == true) {
115
+ cpos.r = Math.min(this.canvas.width, this.canvas.height) * 0.7 / 2
116
+ cpos.x = this.canvas.height * 0.1 + cpos.r;
117
+ }
118
+ /* 項目の数(最大10個)*/
119
+ var item_num = items.length;
120
+ if(item_num > 10) { item_num = 10; }
121
+ params.itemNum = item_num;
122
+ /* 指標の最大数を算出(多角形の角数) 最小3角・最大24角*/
123
+ var angle_num = 0;
124
+ for(var i=0; i<items.length; i++) {
125
+ var n = items[i].length;
126
+ if(angle_num <= n - 1) {
127
+ angle_num = n - 1;
128
+ }
129
+ }
130
+ if(angle_num < 3) {
131
+ angle_num = 3;
132
+ } else if(angle_num > 24) {
133
+ angle_num = 24;
134
+ }
135
+ params.angleNum = angle_num;
136
+ /* 各軸の角度(ラジアン)を算出(右方向を0度とし反時計回りの角度) */
137
+ var axis_angles = [Math.PI/2];
138
+ for(var i=1; i<angle_num; i++) {
139
+ axis_angles.push( Math.PI / 2 - Math.PI * 2 * i / angle_num );
140
+ }
141
+ /* チャートの形状を描画 */
142
+ this._draw_chart_shape(params, cpos, axis_angles);
143
+ /* 全項目の最大値・最小値と項目数を算出 */
144
+ var max_v = null;
145
+ var min_v = null;
146
+ var max_n = 0;
147
+ for(var i=0; i<item_num; i++) {
148
+ var n = items[i].length;
149
+ for(var j=1; j<n; j++) {
150
+ var v = items[i][j];
151
+ if( isNaN(v) ) {
152
+ throw new Error('Item data is invalid. : ' + n);
153
+ }
154
+ if(max_v == null) {
155
+ max_v = v;
156
+ } else if(v >= max_v) {
157
+ max_v = v;
158
+ }
159
+ if(min_v == null) {
160
+ min_v = v;
161
+ } else if(v <= min_v) {
162
+ min_v = v;
163
+ }
164
+ }
165
+ if(n - 1 >= max_n) {
166
+ max_n = n - 1;
167
+ }
168
+ }
169
+ if( typeof(params.aMin) != "number" ) {
170
+ params.aMin = 0;
171
+ }
172
+ if( typeof(params.aMax) != "number" ) {
173
+ params.aMax = max_v;
174
+ }
175
+ /* 補助線の位置を自動算出 */
176
+ if( typeof(params.aLinePositions) == "string" && params.aLinePositions == "auto" ) {
177
+ params.aLinePositions = this._aline_positions_auto_calc(params.aMin, params.aMax);
178
+ }
179
+ /* 補助線を描画 */
180
+ this._draw_aline(params, cpos, axis_angles);
181
+ /* 軸を描画 */
182
+ this._draw_axis(params, cpos, axis_angles);
183
+ /* スケールラベルを描画 */
184
+ this._draw_scale_label(params, cpos);
185
+ /* 各項目のデフォルト色を定義 */
186
+ /* チャートを描写 */
187
+ for(var i=0; i<items.length; i++) {
188
+ this._draw_radar_chart(params, cpos, axis_angles, items[i], params.faceColors[i]);
189
+ }
190
+ /* キャプションを描画 */
191
+ this._draw_caption(params, cpos, axis_angles);
192
+ /* 凡例を描画 */
193
+ this._draw_legend(items, params, cpos);
194
+ };
195
+
196
+ /* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
197
+ * 以下、内部関数
198
+ * ──────────────────────────────── */
199
+
200
+ /* ------------------------------------------------------------------
201
+ 補助線の位置を自動算出
202
+ * ---------------------------------------------------------------- */
203
+ html5jp.graph.radar.prototype._aline_positions_auto_calc = function(min, max) {
204
+ var range = max - min;
205
+ var power10 = Math.floor( Math.log(range) / Math.log(10) );
206
+ var unit = Math.pow( 10, power10);
207
+ if( (Math.log(range) / Math.log(10)) % 1 == 0 ) {
208
+ unit = unit / 10;
209
+ }
210
+ var keta_age = 1;
211
+ if(unit < 1) {
212
+ keta_age += Math.abs(power10);
213
+ }
214
+ var p = Math.pow(10, keta_age);
215
+ range = range * p;
216
+ unit = unit * p;
217
+ min = min * p;
218
+ max = max * p;
219
+ var array = [min];
220
+ var unum = range / unit;
221
+ if( unum > 5 ) {
222
+ unit = unit * 2;
223
+ } else if( unum <= 2 ) {
224
+ unit = unit * 3 / 10
225
+ }
226
+ var i = 1;
227
+ while(min+unit*i<=max) {
228
+ array.push(min+unit*i);
229
+ i++;
230
+ }
231
+ for(var i=0; i<array.length; i++) {
232
+ array[i] = array[i] / p;
233
+ }
234
+ return array;
235
+ };
236
+ /* ------------------------------------------------------------------
237
+ 凡例を描画
238
+ * ---------------------------------------------------------------- */
239
+ html5jp.graph.radar.prototype._draw_legend = function(items, params, cpos) {
240
+ if(params.legend != true) { return; }
241
+ /* DIV要素を仮に挿入してみて高さを調べる(1行分の高さ) */
242
+ var s = this._getTextBoxSize('あTEST', params.legendFontSize, params.legendFontFamily);
243
+ /* 凡例の各種座標を算出 */
244
+ var lpos = {
245
+ x: Math.round( cpos.x + cpos.r + this.canvas.width * 0.15 ),
246
+ y: Math.round( ( this.canvas.height - ( s.h * params.itemNum + s.h * 0.2 * (params.itemNum - 1) ) ) / 2 ),
247
+ h: s.h
248
+ };
249
+ lpos.cx = lpos.x + Math.round( lpos.h * 1.5 ); // 文字表示開始位置(x座標)
250
+ lpos.cw = this.canvas.width - lpos.cx; // 文字表示幅
251
+ /* 描画 */
252
+ for(var i=0; i<params.itemNum; i++) {
253
+ /* 文字 */
254
+ this._drawText(lpos.cx, lpos.y, items[i][0], params.legendFontSize, params.legendFontFamily, params.legendColor);
255
+ /* 記号(背景) */
256
+ this._make_path_legend_mark(lpos.x, lpos.y, s.h, s.h);
257
+ this.ctx.fillStyle = params.cBackgroundColor;
258
+ this.ctx.fill();
259
+ /* 記号(塗り) */
260
+ this._make_path_legend_mark(lpos.x, lpos.y, s.h, s.h);
261
+ this.ctx.fillStyle = params.faceColors[i];
262
+ this.ctx.globalAlpha = params.faceAlpha;
263
+ this.ctx.fill();
264
+ /* 枠線 */
265
+ this._make_path_legend_mark(lpos.x, lpos.y, s.h, s.h);
266
+ this.ctx.strokeStyle = params.faceColors[i];
267
+ this.ctx.globalAlpha = params.borderAlpha;
268
+ this.ctx.stroke();
269
+ /* */
270
+ lpos.y = lpos.y + lpos.h * 1.2;
271
+ }
272
+ };
273
+ html5jp.graph.radar.prototype._make_path_legend_mark = function(x,y,w,h) {
274
+ this.ctx.beginPath();
275
+ this.ctx.moveTo(x, y);
276
+ this.ctx.lineTo(x+w, y);
277
+ this.ctx.lineTo(x+w, y+h);
278
+ this.ctx.lineTo(x, y+h);
279
+ this.ctx.closePath();
280
+ };
281
+ /* ------------------------------------------------------------------
282
+ キャプションを描画
283
+ * ---------------------------------------------------------------- */
284
+ html5jp.graph.radar.prototype._draw_caption = function(params, cpos, axis_angles) {
285
+ if( typeof(params.aCap) != "object" || params.aCap.length < 1 ) { return; }
286
+ var n = params.aCap.length;
287
+ if(n > params.angleNum) { n = params.angleNum; }
288
+ for(var i=0; i<n; i++) {
289
+ var text = params.aCap[i];
290
+ /* テキスト領域のサイズを算出 */
291
+ var s = this._getTextBoxSize(text, params.aCapFontSize, params.aCapFontFamily);
292
+ /* テキストを描画すべき左上端の座標を算出 */
293
+ var ang = axis_angles[i];
294
+ var x = cpos.x + cpos.r * 1.15 * Math.cos(ang) - s.w / 2;
295
+ var y = cpos.y - cpos.r * 1.15 * Math.sin(ang) - s.h / 2;
296
+ if( x < this.canvas.width * 0.02 ) { x = this.canvas.width * 0.02; }
297
+ if( x + s.w > this.canvas.width * 0.98 ) { x = this.canvas.width * 0.98 - s.w; }
298
+ if( y < this.canvas.height * 0.02 ) { y = this.canvas.height * 0.02; }
299
+ if( y + s.h > this.canvas.height * 0.98 ) { y = this.canvas.height * 0.98 - s.h; }
300
+ x = Math.round(x);
301
+ y = Math.round(y);
302
+ /* テキストを描画 */
303
+ this._drawText(x, y, text, params.aCapFontSize, params.aCapFontFamily, params.aCapColor);
304
+ }
305
+ };
306
+ /* ------------------------------------------------------------------
307
+ スケールラベルを描画
308
+ * ---------------------------------------------------------------- */
309
+ html5jp.graph.radar.prototype._draw_scale_label = function(params, cpos) {
310
+ if( params.sLabel != true) { return; }
311
+ if( typeof(params.aLinePositions) != "object" || params.aLinePositions.length < 1 ) { return; }
312
+ for(var i=0; i<params.aLinePositions.length; i++) {
313
+ if( typeof(params.aLinePositions[i]) != "number" ) { continue; }
314
+ if( params.aLinePositions[i] < params.aMin ) { continue; }
315
+ var text = params.aLinePositions[i].toString();
316
+ /* テキスト領域のサイズを算出 */
317
+ var s = this._getTextBoxSize(text, params.sLabelFontSize, params.sLabelFontFamily);
318
+ /* テキストを描画すべき左上端の座標を算出 */
319
+ var x = Math.round( cpos.x - s.w - 3 );
320
+ var y = Math.round( cpos.y - ( ( params.aLinePositions[i] - params.aMin ) * cpos.r / ( params.aMax - params.aMin ) ) - ( s.h / 2 ) );
321
+ /* テキストを描画 */
322
+ this._drawText(x, y, text, params.sLabelFontSize, params.sLabelFontFamily, params.sLabelColor);
323
+ }
324
+ };
325
+ /* ------------------------------------------------------------------
326
+ チャートを描画
327
+ * ---------------------------------------------------------------- */
328
+ html5jp.graph.radar.prototype._draw_radar_chart = function(params, cpos, axis_angles, values, color) {
329
+ /* チャート面を塗りつぶす */
330
+ this._make_path_for_radar_chart(params, cpos, axis_angles, values);
331
+ this.ctx.globalAlpha = params.faceAlpha;
332
+ this.ctx.fillStyle = color;
333
+ this.ctx.fill();
334
+ /* チャート境界線を引く */
335
+ this._make_path_for_radar_chart(params, cpos, axis_angles, values);
336
+ this.ctx.globalAlpha = params.borderAlpha;
337
+ this.ctx.lineWidth = params.borderWidth;
338
+ this.ctx.strokeStyle = color;
339
+ this.ctx.stroke();
340
+ /* this.ctx.globalAlpha の値を初期値に戻す */
341
+ this.ctx.globalAlpha = 1;
342
+ };
343
+ html5jp.graph.radar.prototype._make_path_for_radar_chart = function(params, cpos, axis_angles, values) {
344
+ var r0 = 0;
345
+ if( typeof(values[1]) == "number" ) {
346
+ r0 = cpos.r * (values[1] - params.aMin ) / (params.aMax - params.aMin);
347
+ if( r0 < 0 ) { r0 = 0; }
348
+ }
349
+ this.ctx.beginPath();
350
+ this.ctx.moveTo( Math.round( cpos.x + r0 * Math.cos(axis_angles[0]) ), Math.round( cpos.y - r0 * Math.sin(axis_angles[0]) ) );
351
+ for(var i=1; i<axis_angles.length; i++) {
352
+ var r = 0;
353
+ if( typeof(values[i+1]) == "number" ) {
354
+ r = cpos.r * ( values[i+1] - params.aMin ) / (params.aMax - params.aMin);
355
+ if( r < 0 ) { r = 0; }
356
+ }
357
+ this.ctx.lineTo( Math.round( cpos.x + r * Math.cos(axis_angles[i]) ), Math.round( cpos.y - r * Math.sin(axis_angles[i]) ) );
358
+ }
359
+ this.ctx.closePath();
360
+ };
361
+ /* ------------------------------------------------------------------
362
+ 軸を描画
363
+ * ---------------------------------------------------------------- */
364
+ html5jp.graph.radar.prototype._draw_axis = function(params, cpos, axis_angles) {
365
+ if( typeof(params.axisWidth) != "number" || params.axisWidth <= 0 ) {
366
+ return;
367
+ }
368
+ for(var i=0; i<axis_angles.length; i++) {
369
+ this.ctx.beginPath();
370
+ this.ctx.lineWidth = params.axisWidth;
371
+ this.ctx.strokeStyle = params.axisColor;
372
+ this.ctx.moveTo(cpos.x, cpos.y);
373
+ this.ctx.lineTo( Math.round( cpos.x + cpos.r * Math.cos(axis_angles[i]) ), Math.round( cpos.y - cpos.r * Math.sin(axis_angles[i]) ) );
374
+ this.ctx.stroke();
375
+ }
376
+ };
377
+ /* ------------------------------------------------------------------
378
+ 補助線を描画
379
+ * ---------------------------------------------------------------- */
380
+ html5jp.graph.radar.prototype._draw_aline = function(params, cpos, axis_angles) {
381
+ if( typeof(params.aLineWidth) != "number" || params.aLineWidth <= 0 ) {
382
+ return;
383
+ }
384
+ if( typeof(params.aLinePositions) != "object" || params.aLinePositions.length < 1 ) {
385
+ return;
386
+ }
387
+ for(var i=0; i<params.aLinePositions.length; i++) {
388
+ if(params.aLinePositions[i] < params.aMin) { continue; }
389
+ var r = cpos.r * ( params.aLinePositions[i] - params.aMin ) / (params.aMax - params.aMin);
390
+ if( r <= 0 ) { continue; }
391
+ this.ctx.beginPath();
392
+ this.ctx.lineWidth = params.aLineWidth;
393
+ this.ctx.strokeStyle = params.aLineColor;
394
+ if(params.chartShape == "polygon") {
395
+ this.ctx.moveTo( Math.round( cpos.x + r * Math.cos(axis_angles[0]) ), Math.round( cpos.y - r * Math.sin(axis_angles[0]) ) );
396
+ for(var j=1; j<axis_angles.length; j++) {
397
+ this.ctx.lineTo( Math.round( cpos.x + r * Math.cos(axis_angles[j]) ), Math.round( cpos.y - r * Math.sin(axis_angles[j]) ) );
398
+ }
399
+ this.ctx.closePath();
400
+ } else if(params.chartShape == "circle") {
401
+ this.ctx.arc(cpos.x, cpos.y, r, 0, Math.PI*2, false);
402
+ } else {
403
+ throw new Error('Option parameter [chartChape] is invalid. : ' + params.chartShape);
404
+ }
405
+ this.ctx.stroke();
406
+ }
407
+ };
408
+ /* ------------------------------------------------------------------
409
+ チャートの形状を描画
410
+ * ---------------------------------------------------------------- */
411
+ html5jp.graph.radar.prototype._draw_chart_shape = function(params, cpos, axis_angles) {
412
+ /* チャート形状の塗り */
413
+ this._make_path_chart_shape(params, cpos, axis_angles);
414
+ this.ctx.fillStyle = params.cBackgroundColor;
415
+ this.ctx.fill();
416
+ /* チャート形状のグラデーション */
417
+ if( params.cBackgroundGradation == true && ! document.uniqueID ) {
418
+ this._make_path_chart_shape(params, cpos, axis_angles);
419
+ var radgrad = this.ctx.createRadialGradient(cpos.x,cpos.y,0,cpos.x,cpos.y,cpos.r);
420
+ radgrad.addColorStop(0, "rgba(0,0,0,0)");
421
+ radgrad.addColorStop(0.8, "rgba(0,0,0,0.01)");
422
+ radgrad.addColorStop(1, "rgba(0,0,0,0.1)");
423
+ this.ctx.fillStyle = radgrad;
424
+ this.ctx.fill();
425
+ }
426
+ };
427
+ html5jp.graph.radar.prototype._make_path_chart_shape = function(params, cpos, axis_angles) {
428
+ this.ctx.beginPath();
429
+ if(params.chartShape == "circle") {
430
+ this.ctx.arc(cpos.x, cpos.y, cpos.r, 0, Math.PI*2, false);
431
+ } else if(params.chartShape == "polygon") {
432
+ this.ctx.moveTo(cpos.x, cpos.y-cpos.r);
433
+ for(var i=0; i<axis_angles.length; i++) {
434
+ var edge_x = Math.round( cpos.x + cpos.r * Math.cos(axis_angles[i]) );
435
+ var edge_y = Math.round( cpos.y - cpos.r * Math.sin(axis_angles[i]) );
436
+ this.ctx.lineTo(edge_x, edge_y);
437
+ }
438
+ this.ctx.closePath();
439
+ } else {
440
+ throw new Error('Option parameter [chartChape] is invalid. : ' + params.chartShape);
441
+ }
442
+ };
443
+ /* ------------------------------------------------------------------
444
+ 文字列を描画
445
+ * ---------------------------------------------------------------- */
446
+ html5jp.graph.radar.prototype._drawText = function(x, y, text, font_size, font_family, color) {
447
+ var div = document.createElement('DIV');
448
+ div.appendChild( document.createTextNode(text) );
449
+ div.style.fontSize = font_size;
450
+ div.style.fontFamily = font_family;
451
+ div.style.color = color;
452
+ div.style.margin = "0";
453
+ div.style.padding = "0";
454
+ div.style.position = "absolute";
455
+ div.style.left = x.toString() + "px";
456
+ div.style.top = y.toString() + "px";
457
+ this.canvas.parentNode.appendChild(div);
458
+ }
459
+ /* ------------------------------------------------------------------
460
+ 文字列表示領域のサイズを取得
461
+ * ---------------------------------------------------------------- */
462
+ html5jp.graph.radar.prototype._getTextBoxSize = function(text, font_size, font_family) {
463
+ var tmpdiv = document.createElement('DIV');
464
+ tmpdiv.appendChild( document.createTextNode(text) );
465
+ tmpdiv.style.fontSize = font_size;
466
+ tmpdiv.style.fontFamily = font_family;
467
+ tmpdiv.style.margin = "0";
468
+ tmpdiv.style.padding = "0";
469
+ tmpdiv.style.visible = "hidden";
470
+ tmpdiv.style.position = "absolute";
471
+ tmpdiv.style.left = "0px";
472
+ tmpdiv.style.top = "0px";
473
+ this.canvas.parentNode.appendChild(tmpdiv);
474
+ var o = {
475
+ w: tmpdiv.offsetWidth,
476
+ h: tmpdiv.offsetHeight
477
+ };
478
+ tmpdiv.parentNode.removeChild(tmpdiv);
479
+ return o;
480
+ }
481
+ /* ------------------------------------------------------------------
482
+ ブラウザー表示領域左上端を基点とする座標系におけるelmの左上端の座標
483
+ * ---------------------------------------------------------------- */
484
+ html5jp.graph.radar.prototype._getElementAbsPos = function(elm) {
485
+ var obj = new Object();
486
+ obj.x = elm.offsetLeft;
487
+ obj.y = elm.offsetTop;
488
+ while(elm.offsetParent) {
489
+ elm = elm.offsetParent;
490
+ obj.x += elm.offsetLeft;
491
+ obj.y += elm.offsetTop;
492
+ }
493
+ return obj;
494
+ };
495
+ /* ------------------------------------------------------------------
496
+ * CSS色文字列をRGBに変換
497
+ * ---------------------------------------------------------------- */
498
+ html5jp.graph.radar.prototype._csscolor2rgb = function (c) {
499
+ if( ! c ) { return null; }
500
+ var color_map = {
501
+ black: "#000000",
502
+ gray: "#808080",
503
+ silver: "#c0c0c0",
504
+ white: "#ffffff",
505
+ maroon: "#800000",
506
+ red: "#ff0000",
507
+ purple: "#800080",
508
+ fuchsia: "#ff00ff",
509
+ green: "#008000",
510
+ lime: "#00FF00",
511
+ olive: "#808000",
512
+ yellow: "#FFFF00",
513
+ navy: "#000080",
514
+ blue: "#0000FF",
515
+ teal: "#008080",
516
+ aqua: "#00FFFF"
517
+ };
518
+ c = c.toLowerCase();
519
+ var o = new Object();
520
+ if( c.match(/^[a-zA-Z]+$/) && color_map[c] ) {
521
+ c = color_map[c];
522
+ }
523
+ var m = null;
524
+ if( m = c.match(/^\#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i) ) {
525
+ o.r = parseInt(m[1], 16);
526
+ o.g = parseInt(m[2], 16);
527
+ o.b = parseInt(m[3], 16);
528
+ } else if( m = c.match(/^\#([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})$/i) ) {
529
+ o.r = parseInt(m[1]+"0", 16);
530
+ o.g = parseInt(m[2]+"0", 16);
531
+ o.b = parseInt(m[3]+"0", 16);
532
+ } else if( m = c.match(/^rgba*\(\s*(\d+),\s*(\d+),\s*(\d+)/i) ) {
533
+ o.r = m[1];
534
+ o.g = m[2];
535
+ o.b = m[3];
536
+ } else if( m = c.match(/^rgba*\(\s*(\d+)\%,\s*(\d+)\%,\s*(\d+)\%/i) ) {
537
+ o.r = Math.round(m[1] * 255 / 100);
538
+ o.g = Math.round(m[2] * 255 / 100);
539
+ o.b = Math.round(m[3] * 255 / 100);
540
+ } else {
541
+ return null;
542
+ }
543
+ return o;
544
+ };
545
+