I am using Morris.js to create graphs. I have requirement to export graphs as pdf. I can see that graphs are svg elements. What should i do to achieve this.

- 8,805
- 2
- 20
- 38

- 29,685
- 30
- 94
- 128
-
Css-to-pdf tag on here and github is a new project that supports native svg drawn into pdf not as image but vector. If you set up a fiddle with a sample, i can add for you to show you. – Kevin Brown Aug 11 '14 at 17:22
2 Answers
I took one of the Morris samples and made a fiddle for you:
http://jsfiddle.net/1roLdqte/48/
I added a simple call to format to PDF the existing div with just the morris chart:
$('#print').click(function () {
printMe();
});
function printMe() {
xepOnline.Formatter.Format('line-example',{render:'download', srctype:'svg'});
}
Run the fiddle and push the PDF button.
Note there are many more parameters available here, you can format much more content than just the morris.js chart, control page sizes, add header/footers and such. This only formats the chart alone (srctype:'svg') to PDF as a vector image (not raster).

- 8,805
- 2
- 20
- 38
-
Thanks this is great help, Just one more question. Is it supported across browsers and will it work locally i mean if i download the file to my system. – sushil bharwani Aug 12 '14 at 05:09
-
We have been working on all the various browsers, but that should work on all modern ones -- IE, Safari, Firefox. I also ran that Fiddle on on Android phone and tablet an it also works fine. The actually formatter is web based so requires a connection to the web, but you can certainly download the JS and run it locally. It sends a modified HTML to a remote server (at xep.cloudformatter.com), formats to PDF and returns the PDF. – Kevin Brown Aug 12 '14 at 05:27
-
Dear @KevinBrown I tested,work fine but when I use it with dynamic data then it generates an error like this, Uncaught TypeError: Cannot read property 'length' of null on xepOnline.jqPlugin.008.js:166.Kindly help. – Raham Jun 02 '16 at 10:49
-
It works. I tried with morris.js v0.5.0 and Raphael 2.1.2.
Add this to where you have your chart(for example your controller):
$scope.pdf = function(chartName){
printMorris(chartName);
};
function printMorris(chartName) {
xepOnline.Formatter.Format(chartName, {render:'download', srctype:'svg'});
}
xepOnline.jqPlugin.008.js is wrong. To resolve the error: "Uncaught TypeError: Cannot read property 'length' of null on xepOnline.jqPlugin.008.js:166", change the code in xepOnline.jqPlugin.008.js.
Add this in line 166. This will skip the length when "rules" is null.
if(rules === null)
continue;
Now, the code in function togglePrintMediaStyle in xepOnline.jqPlugin.008.js:
togglePrintMediaStyle: function() {
if($('head style[data-xeponline-formatting]').length > 0) {
$('head style[data-xeponline-formatting]').remove();
return;
}
var printrules = [];
for(var x=0;x<document.styleSheets.length;x++) {
var rules=document.styleSheets[x].cssRules;
var rule=[];
if(rules === null)
continue;
for(var x2=0;x2<rules.length;x2++) {
if(rules[x2].media && rules[x2].media && (rules[x2].media[0] === 'print' ||
rules[x2].media && rules[x2].media.mediaText === 'print')) {
for(var x3=0;x3<rules[x2].cssRules.length; x3++) {
rule.push(rules[x2].cssRules[x3]);
}
} else if (rules[x2].parentStyleSheet.media[0] &&
rules[x2].parentStyleSheet.media[0] === 'print' ||
(rules[x2].parentStyleSheet.media &&
rules[x2].parentStyleSheet.media.mediaText === 'print')) {
rule.push(rules[x2]);
}
}
for(var x2=0;x2<rule.length;x2++) {
printrules.push(rule[x2].cssText);
}
}
// write print media styles to head
var html = '\n<style type="text/css" data-xeponline-formatting="true">\n';
for(var x=0; x<printrules.length; x++) {
html+='.xeponline-container ' + printrules[x] + '\n';
}
html += '</style>\n';
$('head').append(html);
},