22

I'm using a plugin for Jquery called FLOT http://code.google.com/p/flot/

Once the graph is rendered I want the client to be able to save the graph to a file for later. Any idea on how this can be done without requiring the client to download some tool or image capture device?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en">
   <head>
      <!--[if IE]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <title>Graph</title>
      <link href="layout.css" rel="stylesheet" type="text/css"></link>
      <!--[if IE]><script language="javascript" type="text/javascript" src="lib/flot/excanvas.min.js"></script><![endif]-->
      <script language="javascript" type="text/javascript" src="lib/canvas2image/base64.js"></script>
      <script language="javascript" type="text/javascript" src="lib/canvas2image/canvas2image.js"></script>
      <script language="javascript" type="text/javascript" src="lib/flot/jquery.js"></script>
      <script language="javascript" type="text/javascript" src="lib/gChart/jquery.gchart.js"></script>
      <script language="javascript" type="text/javascript" src="lib/flot/jquery.flot.js"></script>
      <script language="javascript" type="text/javascript" src="lib/flot/jquery.flot.selection.js"></script>
      <script language="javascript" type="text/javascript" src="lib/flot/jquery.flot.crosshair.js"></script>
      <script language="javascript" type="text/javascript" src="lib/flot/jquery.flot.navigate.js"></script>
      <style>
      </style>
   </head>
   <body>

<div id="placeholder" style="width:1000px;height:400px;"></div>
<div id="test" style="display: none; background: #ff0; padding: 5px; border: 1px solid #ddd; position: absolute;"></div>

<script type="text/javascript">
   $(function () {
       var options0 = {
         xaxis: {mode: "time"}, 
         legend: {position: "nw"},
         lines: {show: true}, 
         grid: {hoverable: true}};
         var grid_data0 = [[new Date(1286172000 * 1000), 1219], [new Date(1286258400 * 1000), 1583], [new Date(1286344800 * 1000), 1566], [new Date(1286431200 * 1000), 2191], [new Date(1286517600 * 1000), 2471], [new Date(1286604000 * 1000), 3128], [new Date(1286690400 * 1000), 2713], [new Date(1286776800 * 1000), 2117], [new Date(1286863200 * 1000), 3174], [new Date(1286949600 * 1000), 3051], [new Date(1287036000 * 1000), 3582], [new Date(1287122400 * 1000), 3472], [new Date(1287208800 * 1000), 3928], [new Date(1287295200 * 1000), 3688], [new Date(1287381600 * 1000), 2547], [new Date(1287468000 * 1000), 1549], [new Date(1287554400 * 1000), 3008], [new Date(1287640800 * 1000), 2309], [new Date(1287727200 * 1000), 2973], [new Date(1287813600 * 1000), 3805], [new Date(1287900000 * 1000), 3643], [new Date(1287986400 * 1000), 2310], [new Date(1288072800 * 1000), 2323], [new Date(1288159200 * 1000), 2399], [new Date(1288245600 * 1000), 2305], [new Date(1288332000 * 1000), 2393], [new Date(1288418400 * 1000), 3212], [new Date(1288504800 * 1000), 3348], [new Date(1288591200 * 1000), 2391], [new Date(1288677600 * 1000), 2130], [new Date(1288764000 * 1000), 1896], [new Date(1288850400 * 1000), 1765], [new Date(1288936800 * 1000), 2191], [new Date(1289023200 * 1000), 3008], [new Date(1289109600 * 1000), 3085], [new Date(1289199600 * 1000), 2151], [new Date(1289286000 * 1000), 2011], [new Date(1289372400 * 1000), 2016], [new Date(1289458800 * 1000), 1914]];
         var plot = $.plot($("#placeholder"), [{data: grid_data0}, ], options0);
   });

$("#placeholder").mouseout(function(e){
$("#test").hide();
});

function test() {
//var oCanvas = $("#placeholder");//document.getElementById("placeholder");
//img=document.createElement("img");
//Save
//img.src=oCanvas.toDataUrl();
//Restore
//oCanvas.drawImage(img, 0, 0);
//var oCanvas = $("#placeholder");//document.getElementById("placeholder");
//document.write(document.getElementById('placeholder').toDataUrl());
   Canvas2Image.saveAsPNG(document.getElementById('placeholder'));
//Canvas2Image.saveAsPNG(oCanvas, true);
}
</script>
<a onClick="JavaScript:test();">Click</a>
   </body>
</html>
Cœur
  • 37,241
  • 25
  • 195
  • 267
Josh
  • 819
  • 1
  • 14
  • 30

3 Answers3

11

The basic way to do it is using canvas.toDataURL("image/png"); but I also found this link for you

http://nihilogic.dk/labs/canvas2image/

I've not tested it.

Hogan
  • 69,564
  • 10
  • 76
  • 117
  • I get some "oScaledCanvas.toDataURL is not a function" error when I try and run it. Also it appears it only works in none IE browsers. (I'm using FireFox, however, client might be using IE). – Josh Nov 16 '10 at 18:43
  • 3
    You are going to have much pain supporting canvas in IE. (remember, I warned you.) – Hogan Nov 16 '10 at 18:59
  • Is there anything I need to do to enable or use HTML5 on my web-server? If I go to http://nihilogic.dk/labs/canvas2image/ the demo works fine, but, when I place the code on my site, it gives me the error "oScaledCanvas.toDataURL is not a function". – Josh Nov 16 '10 at 19:23
  • hmmm... you are using both libs he has there? I guess I'd have to see the code. – Hogan Nov 16 '10 at 19:28
  • 8
    The problem with this answer is that flot combines the canvas (for drawing) HTML (for axis labels). Saving just the canvas image will not serialize the entire chart. You will need to use a [patch to flot](http://code.google.com/p/flot/issues/detail?id=142) that modifies it to draw everything on the canvas. – Phrogz Dec 05 '10 at 16:13
3

If you are willing to use Firefox, I wrote WWW::Mechanize::Firefox, which can save the whole page or elements on a page to PNG.

You can also automate Firefox completely, which I do with ffeedflotr, a small data plotting program that creates flot charts.

kapa
  • 77,694
  • 21
  • 158
  • 175
Corion
  • 31
  • 1
2

You might look into HighCharts which has an export and print feature. It works by generating all the graphics in SVG before rendering on the canvas. When a user wants an image, the javascript sends the SVG to the server for conversion into an image. See the Exporting Module for more details.

The data structures for highcharts are well documented and not too hard to port flot to highcharts. They also have lots of examples you can interactively play with using jsFiddle.

ericslaw
  • 851
  • 1
  • 8
  • 16