【JavaScript】 D3.js ~ SVG / D3.js のグラフを PNG 画像で 保存することを考える ~

方法

[1] SVGCanvas に変換し、その後、Canvas を画像として保存する
 => このブログで扱うのは[1]の方法。

[2] svgデータをbase64形式にして保存し、base64形式の画像データを保存する
 => 以下のサイトを参照のこと。
* javascriptsvgデータをbase64形式にして保存し、base64形式の画像データを画面上に表示する方法
http://qiita.com/okappy/items/bc20774aa08842adf4d7
* 画像保存できるD3 Plugin
http://qiita.com/_likr/items/d9439806198f4b61010d

使用ツール

SVGCanvas に変換する
[1-1] canvg ... SVGCanvas に変換するために必要
[1-2] rgbcolor.js ... canvg を使用する上で必要
[1-3] StackBlur.js ... canvg を使用する上で必要

■ 画像として保存
[2-1] FileSaver.js ... 画像保存するために必要
[2-2] canvas-toBlob.js ... FileSaver.jsを使用する上で必要

保存のためのロジック

  // SVGをテキスト形式で取得
  var svg = document.querySelector("#divIdForSvg svg");
  var svgData = new XMLSerializer().serializeToString(svg);

  // SVGCanvas に変換するために、一時的にCanvas を作成する(jQuery使った)
  $("body").append("<div id='divIdToSave' style='display: none;'><canvas id='canvasIdToSave'></canvas></div>");

  // Canvas要素取得
  var canvas = document.getElementById('canvasIdToSave');
  
  // canvgでSVGからCanvasを描画
  canvg('canvasIdToSave', svgData);
  
  // Blob形式に変換し、保存する
  canvas.toBlob(function(blob) {
      saveAs(blob, fileName);
  }, "image/png");

  // 一時的に作成した div / canvas を削除しておく
  $("#divIdToSave").remove();

注意

 * 外部CSSには対応していない。
  => そのため、以下のサンプルを同様に、
     C3.js で使用としても、CSS適用していない画像が保存されてしまう

サンプル

http://blogs.yahoo.co.jp/dk521123/35435961.html
で作成した円グラフをpng形式で保存する
<html>
<head>
<meta charset="UTF-8">
<style>
</style>
</head>
<body>
<button onClick="saveAsImage('#forSvg', 'SampleImage.png')">Save</button>
<div id="forSvg"></div>

<script src="">http://d3js.org/d3.v3.js">
<script src="">https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js">

<script type="text/javascript" src="">http://canvg.googlecode.com/svn/trunk/rgbcolor.js">
<script type="text/javascript" src="">http://canvg.googlecode.com/svn/trunk/StackBlur.js">
<script type="text/javascript" src="">http://canvg.googlecode.com/svn/trunk/canvg.js">
<script type="text/javascript" src="./js/canvas-toBlob.js"></script>
<script type="text/javascript" src="./js/FileSaver.js"></script>

<script>
var dataset = [
    {graphLegend:"001", graphValue:10, graphColor:"LightPink"},
    {graphLegend:"002", graphValue:20, graphColor:"LightCyan"},
    {graphLegend:"003", graphValue:30, graphColor:"LightGoldenrodYellow"},
    {graphLegend:"004", graphValue:25, graphColor:"Aquamarine"},
    {graphLegend:"005", graphValue:10, graphColor:"MistyRose"}
];

var width = 960,
    height = 500,
    radius = Math.min(width, height) / 2;

var arc = d3.svg.arc()
    .outerRadius(radius - 10)
    .innerRadius(0);

var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) { return d.graphValue; });

var svg = d3.select("#forSvg").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");


  var g = svg.selectAll(".arc")
      .data(pie(dataset))
      .enter().append("g");

  g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return d.data.graphColor; })
      // アニメーション効果
      .transition()
      .duration(1000) // 1秒間でアニメーションさせる
      .attrTween("d", function(d){
        var interpolate = d3.interpolate(
            { startAngle : 0, endAngle : 0 },
            { startAngle : d.startAngle, endAngle : d.endAngle }
        );
        return function(t){
            return arc(interpolate(t));
        }
      });
      
  g.append("text")
      .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
      .attr("dy", ".35em")
      .style("text-anchor", "middle")
      .text(function(d) { return d.data.graphLegend; });

// ★ここに注目★
function saveAsImage(id, fileName) {
  // SVGをテキスト形式で取得
  var svg = document.querySelector(id + " svg");
  var svgData = new XMLSerializer().serializeToString(svg);

  // SVGCanvas に変換するために、一時的にCanvas を作成する(jQuery使った)
  $("body").append("<div id='divIdToSave' style='display: none;'><canvas id='canvasIdToSave'></canvas></div>");

  // Canvas要素取得
  var canvas = document.getElementById('canvasIdToSave');
  
  // canvgでSVGからCanvasを描画
  canvg('canvasIdToSave', svgData);
  
  // Blob形式に変換し、保存する
  canvas.toBlob(function(blob) {
      saveAs(blob, fileName);
  }, "image/png");

  // 一時的に作成した div / canvas を削除しておく
  $("#divIdToSave").remove();
}
</script>
</body>
</html>


関連記事

D3.js ~ 入門編 ~

http://blogs.yahoo.co.jp/dk521123/35423681.html