hakobera's blog

技術メモ。たまに雑談

簡単にレーダーチャートが描けるライブラリ Raphael-Radar

最近は Google Chart ToolsHighcharts のように綺麗なグラフがかけるライブラリが増えてきましたが、レーダーチャートをサポートしているものがあまりなく、あっても用途にマッチしなかったので jQueryRaphael を使って、レーダーチャートが描けるライブラリを作ってみました。

作ってみましたといっても、正確には fork して改造になります。

ソース: hakobera/raphael-radar · GitHub
デモ: Raphaël Radar Chart Plugin Sample

サンプル

こんな感じのチャートが書けます。

f:id:scalar:20120509150547p:image

ソースは以下のような感じです。

var objects = [
    { title: "Real Madrid C.F.", 
      offense: 80,
      defense: 90,
      technique: 70,
      strategy: 90,
      physicality: 70,
      mentality: 60,
      draw_options: {
        lines: {'stroke-width':'2', 'stroke':'#39b549','stroke-dasharray':'- '},
        points: {'fill':'#39b549','stroke-width':'0'},
        text: {}
      }
    },
    { title: "FC Barcelona", 
      offense: 100,
      defense: 70,
      technique: 100,
      strategy: 70,
      physicality: 60,
      mentality: 80,
      draw_options: {
        lines: {'stroke-width':'4','stroke':'#0070bb','stroke-opacity':0.7,'fill':'#f7d2a8','fill-opacity':0.6},
        points: {'fill':'#f05a23','stroke-width':'1.5','stroke':'#333', 'size': 6},
        text: {}
      }
    }
];

var paper = Raphael( "id_of_some_div", 460, 360);
paper.radarchart(221, 160, 120, labels, 50, 100, objects);

吹き出し部分はイベントハンドラを設定して書いています。標準機能として取り込むかは検討中です。

      paper.scores.forEach(function(s) {
        s.points.forEach(function (p) {
          console.log(p.score);

          var side = "right";
          var offset = p.attrs.r;
          var popupLabel = paper5.text(p.attrs.cx, p.attrs.cy, p.title + '\n' + p.score.label + ': ' + p.score.rawValue).hide();
          if (p.attrs.cx + popupLabel.getBBox().width > paper5.width) {
            side = "left";
            offset = -offset;
          }
          var popup = paper5.popup(p.attrs.cx + offset, p.attrs.cy, popupLabel, side).attr({fill: "#fff", stroke: "#666", "stroke-width": 2 }).hide();

          p.mouseover(function () {
            popup.toFront().show();
            popupLabel.toFront().show();
          });

          p.mouseout(function () {
            popup.hide();
            popupLabel.hide();
          });

          p.toFront();
        });
      });