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>
ご回答ありがとうございます。正常に動きました!
コードも非常に簡潔でしたので、取り入れてみたいと思ってます!ちなみに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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C#OpenCv V4にのエラーに関する...
-
ジェネレーターの作り方
-
ASP.NETのコントロールの値をJa...
-
google apps scriptの終了のさせ方
-
googleスプレッドシートのApps ...
-
JavaScriptの時計の表示
-
イベント座標の取り方について
-
JavaScriptエラーが出ます…
-
食材の期限を管理するためにGAS...
-
JavaScriptの値を表示するには
-
JavaScriptでスライドショーを2...
-
C#で、ContextMenuStripに動的...
-
翌月を取得するGASが分かりません
-
1日1回だけ引けるjavascriptお...
-
Javascriptで時刻に応じて画像...
-
Cookieで内容を保存するには
-
ジャバスプリクトについて
-
Jscriptからのオープン
-
毎日日付の変わるタイミングを...
-
なぜmatchメソッドがエラーにな...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C#OpenCv V4にのエラーに関する...
-
食材の期限を管理するためにGAS...
-
google apps scriptの終了のさせ方
-
このプログラムに、王手をかけ...
-
このプログラムに王様の逃げ道...
-
この将棋プログラムに王様ゲッ...
-
ASP.NETのコントロールの値をJa...
-
ジェネレーターの作り方
-
GASでundefinedエラーが出ます
-
なぜmatchメソッドがエラーにな...
-
ASP.NET MVCでObjectをjsに渡す
-
C#で、ContextMenuStripに動的...
-
html javascript リンク先アド...
-
HTMLで作った時報アプリが動き...
-
翌月を取得するGASが分かりません
-
イラレでナンバリングする方法
-
HTMLにWSHを組み込む
-
gas スプレッドシートがアクテ...
-
getElementByIdでASP.NETのText...
-
APIを使って埋め込んだグーグル...
おすすめ情報