![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?08b1c8b)
No.3ベストアンサー
- 回答日時:
html5ならcanvasが使えるのでは?
扇形を作るものを用意しておけば、それで事足りそう。
html5もcanvasも使ったことはありませんが、お勉強のためにサンプルを。
参考にしたサイト
https://developer.mozilla.org/ja/Canvas_tutorial
fx6.0でしか確認していません。
数値の意味が不明でしたので、角度などは適当です。
(全角空白は半角に)
<!DOCTYPE html>
<html lang="ja">
<head>
<title>sample</title>
</head>
<body>
<canvas id="graph" width="400" height="400"></canvas>
<script type="text/javascript">
(function(){
var fanShape = (function(rad){
return function(ctx, r, ang1, ang2, col, frame){
ctx.fillStyle = col;
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.arc(0, 0, r, rad(ang1), rad(ang2));
ctx.fill();
if(frame){
ctx.closePath();
ctx.stroke();
}
}
})(function(a){
return Math.PI*(a-90)/180;
});
var context, graph = document.getElementById("graph");
if(graph.getContext && (context = graph.getContext("2d"))){
context.translate(200, 200);
fanShape(context, 180, 0, 360, "#ddd");
fanShape(context, 160, 0, 10, "#0c0", true);
fanShape(context, 90, 10, 240, "#c00", true);
fanShape(context, 60, 240, 360, "#00c", true);
}
})();
</script>
</body>
</html>
![「html5で複雑な円グラフを描画」の回答画像3](http://oshiete.xgoo.jp/_/bucket/oshietegoo/images/media/1/587726_5497e547daf69/M.jpg)
ご回答ありがとうございます。正常に動きました!
コードも非常に簡潔でしたので、取り入れてみたいと思ってます!ちなみにNo2さんのほうにも記載させて頂きましたが、
http://elycharts.com/examples#example_p1
こうしたサンプルのように、ひとつひとつの扇形に対してアニメーションもつけたいんです。。
また、ひとつひとつの扇形をオフジェクトとして取り出して、クリックしたらajaxを使って該当データを引っ張ってきて、ツールチップに表示、こうしたことをやっていきたいとおもっているんですね。
どうかfujillin様からも知識をご教授頂けないでしょうか?
No.13
- 回答日時:
[ANo.10] 改変
まじめに SVG 要素でアニメーションバージョン。
https://ideone.com/l5Rjx
Firefox 8 だと意図したとおりに気持ちわるく動いてくれるけど、
Google Chrome 15 だと、mouseover と mouseout の順番が逆転してヘンテコ。
そういえば、円グラフの項目が一つで 100% のときはどうするか考えてないけど、
やっぱり『動かない』が正解かなぁ?
ありがとうございます。
いまひとつひとつ確認をさせてもらっているのですが、firefox8だとうまくうごきますね!!
100%の場合確かに「動かない」がいいとはおもいますが、他の比率の場合は「動く」ので「動く」で統一しようかなとはおもってます。
No.12
- 回答日時:
function PieChart (canvas, ctx, offsetX, offsetY, radius, data) {
this.canvas = canvas;
this.ctx = ctx;
this.offsetX = offsetX;
this.offsetY = offsetY;
this.radius = radius;
this.data = data;
this.parts = [];
}
PieChart.prototype.check = function (parm) {
if (this.canvas === parm.canvas)
this.parts.forEach (function (p) { p.check (this.x, this.y) }, parm);
};
PieChart.prototype.draw = function () {
var total = this.data.reduce (function (r, d) { return r + d.value; }, 0);
var square0 = 0;
var square1;
var i = 0;
var d;
var obj;
this.parts = [];
while (d = this.data[i++]) {
square1 = square0 + (360 / 100) * (d.value / total) * 100;
obj = Arc.create (this.ctx, this.offsetX, this.offsetY, this.radius, square0, square1, d);
this.parts.push (obj);
square0 = square1;
}
};
PieChart.create = function (canvas, offsetX, offsetY, radius, data) {
if (arguments.length < 5)
return null;
var ctx = canvas.getContext ('2d');
var chart = new PieChart (canvas, ctx, offsetX, offsetY, radius, data);
chart.draw ();
return chart;
};
this.PieChart = PieChart;
//_______________________
var Manager = new function () {
this.x = null;
this.y = null;
this.stock = [];
};
Manager.check = function (e) {
var offset = getElementPosition (e);
var parm = { canvas: e, x: this.x - offset.x, y: this.y - offset.y };
this.stock.forEach (function (s) { s.check (this); }, parm);
};
Manager.add = function (obj) {
this.stock.push (obj);
};
Manager.handleEvent = function (event) {
var e = event.target;
var v = e.ownerDocument.defaultView;
var offset = { x: null, y: null };
switch (event.type) {
case 'mousemove' :
case 'mouseover' :
this.x = event.clientX + v.pageXOffset;
this.y = event.clientY + v.pageYOffset;
if ('CANVAS' === e.nodeName) {
this.check (e);
}
break;
case 'click' :
break;
}
}
document.addEventListener ('mousemove', Manager, false);
document.addEventListener ('mouseover', Manager, false);
document.addEventListener ('click', Manager, false);
this.Manager = Manager;
})();
//__________________________
var data = [
{ caption: 'A', value: 512, radius: 90, color: '#080' },
{ caption: 'B', value: 6534, radius: 60, color: '#f00' },
{ caption: 'C', value: 3056, radius: 30, color: '#008' }
];
var data2 = [
{ caption: 'A', value: 12, radius: 40, color: '#080' },
{ caption: 'B', value: 34, radius: 80, color: '#f00' },
{ caption: 'C', value: 56, radius: 20, color: '#008' }
];
var canvas = document.getElementById ('HOGE');
Manager.add (PieChart.create (canvas, 200, 200, 180, data));
Manager.add (PieChart.create (canvas, 400, 200, 180, data2));
</script>
ぜんかくくうはくは、はんかくに。
そして、「弧」のぶぶんは、いつものようにちからつきてぐだぐだです。
わたしも、Fujillinさんとどうよう、みようみまねでかいているので、ごしどうのほど・・・
No.11
- 回答日時:
かなりじかんをさいて canvas でかいてみた。
ぜんたいをかいてけすのではなく、うわがきでけしているのですが、ごみがのこります。
くにくのさくとして、せんをふとくしてごまかしています。
たぶん、ながいのでぶんかつです。
<!DOCTYPE html>
<html lang="ja">
<title>Test</title>
<meta charset="utf-8">
<style>
canvas { background : #FFC; }
</style>
<body>
<canvas id="HOGE" width="800" height="400">
canvas による描画
</canvas>
<script>
(function () {
var DEG = Math.PI / 180;
var HOVER_SCALE = 1.5;
var HOVER_MOVE = 20; //px
var HOVER_STEP = 10;
function getElementPosition (e) {
for (var x = 0, y = 0; e; e = e.offsetParent) {
x += e.offsetLeft;
y += e.offsetTop;
}
return { 'x': x, 'y': y };
}
function Arc (ctx, x, y, r, sq0, sq1, data) {
this.ctx = ctx;
this.x = x;
this.y = y;
this.r = r;
this.sq0 = sq0;
this.sq1 = sq1;
this.sq2 = (sq0 + sq1) / 2;
this.data = data;
this.timerId = null;
this.direction = 0;
this.scale = 1;
}
Arc.prototype.check = function (x, y) {
var result;
var ctx = this.ctx;
ctx.save ();
ctx.beginPath ();
this.trace ();
result = ctx.isPointInPath (x, y);
ctx.closePath ();
ctx.restore ();
(result)
? this.focus ()
: this.focusout ();
};
Arc.prototype.trace = function () {
var ctx = this.ctx;
ctx.translate (this.x, this.y);
ctx.scale (this.scale, this.scale);
ctx.moveTo (0,0);
ctx.arc (0, 0, this.r, this.sq0, this.sq1, false);
};
Arc.prototype.draw = function () {
var ctx = this.ctx;
ctx.save ();
ctx.fillStyle = this.data.color;
ctx.strokeStyle = 'black';
ctx.beginPath ();
this.trace ();
ctx.fill ();
ctx.closePath ();
ctx.stroke ();
ctx.restore ();
};
Arc.prototype.focus = function () {
this.direction = 1;
if (! this.timerId)
this.timerId = setInterval (changer, 50, this);
};
Arc.prototype.focusout = function () {
this.direction = -1;
if (! this.timerId)
this.timerId = setInterval (changer, 50, this);
};
function changer (that) {
var ctx = that.ctx;
ctx.globalCompositeOperation = 'destination-out';
ctx.save ();
ctx.fillStyle = that.data.color;
ctx.strokeStyle = 'black';
ctx.lineWidth = 2;
ctx.beginPath ();
that.trace ();
ctx.closePath ();
ctx.fill ();
ctx.stroke ();
ctx.restore ();
that.scale += that.direction * (HOVER_SCALE / HOVER_STEP);
if (that.scale < 1) {
that.scale = 1;
clearInterval (that.timerId);
that.timerId = null;
}
if (HOVER_SCALE < that.scale) {
that.scale = HOVER_SCALE
clearInterval (that.timerId);
that.timerId = null;
}
ctx.globalCompositeOperation = 'source-over';
ctx.save ();
ctx.fillStyle = that.data.color;
ctx.strokeStyle = 'black';
ctx.beginPath ();
that.trace ();
ctx.closePath ();
ctx.fill ();
ctx.stroke ();
ctx.restore ();
}
Arc.create = function (ctx, x, y, r, sq0, sq1, data) {
var obj = new Arc (ctx, x, y, r * data.radius / 100, (sq0 - 90) * DEG, (sq1 - 90) * DEG, data);
obj.draw ();
return obj;
};
//________________________
No.10
- 回答日時:
ちょっと時間できたから書いてみた。
<svg id="svg" width="150px" height="150px" viewBox="-150 -150 300 300"
xmlns="http://www.w3.org/2000/svg" version="1.1">
<script type="text/ecmascript"><![CDATA[
window.onload = function () {
var svg = document.getElementById("svg");
var pie = null;
pie = createPieceOfPie(0, 90, 120, {
onmouseout:"pie_mouseout(evt);", onmouseover:"pie_mouseover(evt);"
, fill:"#fcc", stroke:"white", "stroke-width":"2" })
svg.appendChild(pie);
pie = createPieceOfPie(90, 60, 100, {
onmouseout:"pie_mouseout(evt);", onmouseover:"pie_mouseover(evt);"
, fill:"#ccf", stroke:"white", "stroke-width":"2" })
svg.appendChild(pie);
pie = createPieceOfPie(150, 30, 80, {
onmouseout:"pie_mouseout(evt);", onmouseover:"pie_mouseover(evt);"
, fill:"#cec", stroke:"white", "stroke-width":"2" })
svg.appendChild(pie);
pie = createPieceOfPie(180, 180, 60, {
onmouseout:"pie_mouseout(evt);", onmouseover:"pie_mouseover(evt);"
, fill:"#ccc", stroke:"white", "stroke-width":"2" })
svg.appendChild(pie);
}
function createSVGElement(tagName, attrs) {
var path = document.createElementNS("http://www.w3.org/2000/svg",tagName);
for (var name in attrs) {
path.setAttribute(name, attrs[name]);
}
return path;
}
function createPieceOfPie(start, deg, r, attrs) {
// 座標計算が面倒なので、扇形の頂上を y 軸の - 方向に作成
var large_arc_flag = (deg > 180)? 1: 0;
var sweep_flag = 1;
var rad = Math.PI * deg / 360.0; //角度を半分で計算
var y = -(r * Math.cos(rad)); //座標系が SVG は特殊なので
var x = (r * Math.sin(rad)); //座標系が SVG は特殊なので
attrs["d"] = "M0,0 L" + (-x).toFixed(3) + "," + y.toFixed(3)
+ "A" + r + "," + r
+ " 0 " + large_arc_flag + "," + sweep_flag + " "
+ x.toFixed(3) + "," + y.toFixed(3) + " z";
var pie = createSVGElement("path", attrs);
var g = document.createElementNS("http://www.w3.org/2000/svg","g");
g.appendChild(pie);
g.setAttribute("transform", "rotate(" + (deg/2+start) + ")");
return g;
}
function pie_mouseover(evt) {
// 親要素の g を rotate してるから
// y 座標を -20 だけ移動すれば、
// 自動で移動して欲しい方向に移動する。
var pie = evt.target;
var fill = pie.setAttribute("transform", "translate(0,-20)");
}
function pie_mouseout(evt) {
var pie = evt.target;
pie.removeAttribute("transform");
}
]]></script>
</svg>
No.8
- 回答日時:
No5と3です。
たぶん canvas でもいけるとおもっているひとりです。
しかし、そのえんぐらふのぷれぜんほうほうが、いけてないとおもいます。
そもそもえんぐらふは、にかよったあたいをはんべつしにくい。
そのうえ、たかさ(はんけい)のちがいでも、2じてきなすうちをひょうげんしようとしています。
それなのに、まうすがかさなると、おおきくなるのでは、その2じてきすうちがいみをうしなってしまいます。
ご指摘ありがとうございます。
確かにご指摘の通り、この円グラフにこのアニメーションでは意味が薄れてしまいますね。。。
もう一度UIも考えながら作業を進めたいと思います。
babu_babooさんも最後までアドバイス頂きありがとうございました!
No.7
- 回答日時:
#3です。
>知識をご教授頂けないでしょうか?
もともと知識がないので、canvasも自分のお勉強のために調べて書いてみた次第。
アニメーションはcanvasでも可能は可能ですが、全体を消して再度書き直すというのが基本みたいです。
それなので、画像そのものをオブジェクトっぽくは扱えない。
多少なりとも似せるなら、各画像を個別のcanvasに描いておいて重ねて表示をすれば、移動(もしかすると拡大・縮小も?←調べていません)程度ならば再描画しなくても可能になるかと思います。
いずれにしても、マウスの位置から画像を特定する部分は作成しないとならないでしょうから、そのあたりが面倒そうですね。
その点、#1様、#4様はさすがに読みが深く、SVGなら描画画像がオブジェクトになっているのでご希望のようなものには適しているかと。
私は、SVGも知らないのでハードルが高いけれど、またまた、にわか勉強で…
とは思ったものの、さすがにドキュメントが多くて、素から作成するには短時間ではとても無理そう。
てーことで、質問者様が御紹介のraphaelに走ってみました。
基本的には、#1様、#4様がご指摘のサイトにサンプルがあるので、半分コピペみたいなものですが…
それなので、詳しく知りたい時は御両者が提示なさっているサイトあたりを参照なさるのがよろしいかと。
<参考サイト>
http://www.w3.org/TR/2003/REC-SVG11-20030114/pat …
(pathのあたりを超斜め読みだけなので、↓は相当にいい加減。きちんと直してください。)
<!DOCTYPE html>
<html lang="ja">
<head>
<title>sample</title>
<script type="text/javascript" src="js/raphael/raphael.js"></script>
</head>
<body>
<div id="holder" style="width:400px; height:400px;"></div>
<script type="text/javascript">
(function(){
// 角度変換関数
var radian = function(a){ return ((a-90) % 360) * Math.PI / 180; }
// アニメーション定義用関数
var move = function(e, a){
a = a?"t" + 15*Math.cos(a) + " " + 15*Math.sin(a) : "";
return function(){ e.stop().animate({transform:a}, 100); }
}
// 扇形描画+アニメーション設定
var setFan = function(r, ang1, ang2, color1, color2){
var x = center.x, y = center.y;
var LAflag = (ang2 - ang1) > 180;
var ang = radian((ang1 + ang2) / 2);
ang1 = radian(ang1);
ang2 = radian(ang2);
var f = paper.path(["M", x, y, "l", r*Math.cos(ang1), r*Math.sin(ang1), "A", r, r, 0, +LAflag, 1, x+r*Math.cos(ang2), y+r*Math.sin(ang2), "Z"]);
f.attr({fill:color1, stroke:color2}).hover(move(f, ang), move(f));
}
// 初期設定
var holder = document.getElementById("holder");
var center = {
x: parseInt(holder.clientWidth)/2 | 0,
y: parseInt(holder.clientHeight)/2 | 0
}
var paper = Raphael(holder, center.x*2, center.y*2);
paper.circle(center.x, center.y, 200).attr({fill:"#ddd", stroke:"#ddd"});
setFan(180, 0, 10, "#0c0", "#060");
setFan(140, 10, 240, "#c00", "#600");
setFan(100, 240, 360, "#00c", "#006");
})();
</script>
</body>
</html>
ご丁寧にありがとうございます。
現在は開発に費用をかけられない関係で1から勉強するのは正直厳しい状況です。
このコードをベースに改良を加えていきたいと思います。
本当にご丁寧にありがとうございました!
No.6
- 回答日時:
Raphael.js を出してきたからあやしいとおもっけど、やっぱりアニメーションかぁ
「ひとつひとつの扇形をオフジェクトとして取り出して、クリックしたらajaxを使って該当データを引っ張ってきて、ツールチップに表示、こうしたこと」は canvas は得意じゃないから、やっぱり SVG だとおもうよ?
と推してみる。
ご返事ありがとうございます。
アニメーション難しいですね。。
初めてのコンタクトなのに大変恐縮なんですが、
http://elycharts.com/examples#example_p1
のようなアニメーション付きの、しかも今回のようなちょっと特殊な円グラフの、動くコードをなんとか頂けないでしょうか?もしくは作成の手順を、教えて頂けないでしょうか?
本当に簡素なもので大丈夫ですので、知識をご教授下さい。
No.5
- 回答日時:
さらに、あにめーしょん!?
あとだしじゃんけんのようなものには・・・
きっと、Fujillin さんならやるっ!とふってみる。(きっとだいすきだろうから^^;)
ところで、えんぐらふの value でぐらふのかくどがへんかするのだけれど、 radius のきじゅんはなに?
さいしゅうてきなもくてきをたっせいするために、うごくこーどがほしいの?
てじゅんだとか、かんがえかた、あるごりずむだとかを、まなびたいの?
ご返事ありがとうございます。
説明が足らず申し訳ありませんでした。。
半径は、90%~100%の人,80%~89%の人,70%~79%の人,60%~69%の人,50%~59%の人,40%~49%の人,30%~39%の人,20%~29%の人,10%~19%の人,0%~9%の人という10個の半径を取ります。なので順に200px,180px,160px,140px,120px,100px,80px,60px,40px,20pxという値を半径にしようと思っています。
質問の量が多すぎるので、ある程度は手順だけでも仕方ないかともおもっていますが
できれば、先ほど載せたサイトの円グラフのようなアニメーションのついた動くコードを頂けたら幸いです。。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) <スプレッドシート>採用進捗 グラフ作成について 3 2022/10/23 15:52
- Excel(エクセル) Excelの複合グラフ(棒グラフと折れ線グラフ)で各棒グラフに名称を表示させたい 1 2022/08/14 23:26
- 数学 効用関数と直線:なぜ直線になる? 3 2022/06/04 20:39
- Excel(エクセル) EXCELのグラフを画像(JPG形式)で保存、通常実行がうまく行かない。ステップインはうまく行く 3 2022/08/30 12:06
- 数学 写真の(1)の問題についてですが、解説を見るとグラフを使って示しているのですが、解説の文章はグラフを 1 2023/02/09 17:48
- 計算機科学 エクセルのデータの表すことについて 2 2023/03/05 20:49
- Word(ワード) 数値に差のあるデータを分かりやすく比較する方法について。医療現場におけるヒヤリハットの発生件数を事例 3 2022/07/18 14:24
- 数学 高校数学で質問があります。 2 2023/02/13 15:49
- Excel(エクセル) エクセルの大きなシートでグラフを見つける 4 2022/07/28 10:07
- 数学 絶対値の入った一次方程式とグラフ 添付の問題、解答ではグラフを描いて 解いていました。 私はaを場合 2 2022/10/26 17:23
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・「これはヤバかったな」という遅刻エピソード
- ・初めて自分の家と他人の家が違う、と意識した時
- ・いちばん失敗した人決定戦
- ・思い出すきっかけは 音楽?におい?景色?
- ・あなたなりのストレス発散方法を教えてください!
- ・もし10億円当たったら何に使いますか?
- ・何回やってもうまくいかないことは?
- ・今年はじめたいことは?
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C#OpenCv V4にのエラーに関する...
-
C#で、ContextMenuStripに動的...
-
jqGridについて
-
ローカルにあるファイルを検索...
-
定積分の近似値を計算する関数c...
-
ASP.NETのコントロールの値をJa...
-
html javascript リンク先アド...
-
Google Apps Script で添付ファ...
-
GASでundefinedエラーが出ます
-
GASでGoogleフォームの自動返信...
-
Javascript での符号付き変数の...
-
Jscriptからのオープン
-
setTimeoutによる繰り返しが途...
-
APIを使って埋め込んだグーグル...
-
getElementByIdでASP.NETのText...
-
シンプルなweb版スタンプラリー...
-
時間帯によってデスクトップ背...
-
翌月を取得するGASが分かりません
-
gas スプレッドシートがアクテ...
-
ボタンを押すことでテキストエ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
google apps scriptの終了のさせ方
-
C#で、ContextMenuStripに動的...
-
C#OpenCv V4にのエラーに関する...
-
GASでundefinedエラーが出ます
-
ジェネレーターの作り方
-
ASP.NET MVCでObjectをjsに渡す
-
翌月を取得するGASが分かりません
-
gas スプレッドシートがアクテ...
-
ASP.NETのコントロールの値をJa...
-
シンプルなweb版スタンプラリー...
-
ローカルにあるファイルを検索...
-
なぜmatchメソッドがエラーにな...
-
jqGridについて
-
APIを使って埋め込んだグーグル...
-
イラレでナンバリングする方法
-
JavaScriptで文字列の特定文字...
-
VSCODE[Python]の設定について
-
【javascript】正規表現で括弧...
-
JAVASCRIPTで万年カレンダーを...
-
毎日日付の変わるタイミングを...
おすすめ情報