Reputation: 651
Here I have multiple charts from highcharts,These charts can be multiple which is coming dynamically,here for reference I have shown only 2.I need to download the content of some div as well as all highcharts in the page.I can able to do it with jspdf plugin,but when it comes multiple charts I am not able to get how to download it.I have updated the working code in the plunker http://plnkr.co/edit/Z3hJcC8pgzZxXPLWpfBw?p=preview ,here is my code below. Other libraries can be found on above url.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="jspdf.debug.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/series-label.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<script src="https://github.com/devongovett/pdfkit/releases/download/v0.6.2/pdfkit.js"></script>
<script src="rgbcolor.js"></script>
<script src="canvg.js"></script>
<script src="script.js"></script>
</head>
<body>
<input type="button" onclick="chartWithContentDownload()" value="download" /> Please click on this button to get chart with html content on pdf
<div class="white-back row" style="padding: 1.5rem;" id="tvgMainCnt">
<div id="top-content">
<div>
<div>
logo
</div>
</div>
<div style="margin-top: 1rem;">
<p>
Dear members,
</p>
</div>
<div>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book
</div>
<br />
<div style="margin-top: 1rem;">
<p>
Download of chart with html content should work with multiple chart.
</p>
</div>
</div>
<div id="middle-content">
<div id="testchart"></div>
<div id="testchart2"></div>
</div>
<div id="bottom-content">
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. </p>
</div>
</div>
$(document).ready(function(){
Highcharts.chart('testchart', {
title: {
text: 'Solar Employment Growth by Sector, 2010-2016'
},
subtitle: {
text: 'Source: thesolarfoundation.com'
},
yAxis: {
title: {
text: 'Number of Employees'
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
plotOptions: {
series: {
label: {
connectorAllowed: false
},
pointStart: 2010
}
},
series: [{
name: 'Installation',
data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
}, {
name: 'Manufacturing',
data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]
}, {
name: 'Sales & Distribution',
data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]
}, {
name: 'Project Development',
data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227]
}, {
name: 'Other',
data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
});
Highcharts.chart('testchart2', {
title: {
text: 'Solar Employment Growth by Sector, 2010-2016'
},
subtitle: {
text: 'Source: thesolarfoundation.com'
},
yAxis: {
title: {
text: 'Number of Employees'
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle'
},
plotOptions: {
series: {
label: {
connectorAllowed: false
},
pointStart: 2010
}
},
series: [{
name: 'Installation',
data: [43934, 52503, 57177, 69658, 97031, 119931, 137133, 154175]
}, {
name: 'Manufacturing',
data: [24916, 24064, 29742, 29851, 32490, 30282, 38121, 40434]
}, {
name: 'Sales & Distribution',
data: [11744, 17722, 16005, 19771, 20185, 24377, 32147, 39387]
}, {
name: 'Project Development',
data: [null, null, 7988, 12169, 15112, 22452, 34400, 34227]
}, {
name: 'Other',
data: [12908, 5948, 8105, 11248, 8989, 11816, 18274, 18111]
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
legend: {
layout: 'horizontal',
align: 'center',
verticalAlign: 'bottom'
}
}
}]
}
});
});
function chartWithContentDownload() {
var doc = new jsPDF('portrait', 'pt', 'a4', true);
var elementHandler = {
'#ignorePDF': function(element, renderer) {
return true;
}
};
var source = document.getElementById("top-content");
doc.fromHTML(source, 15, 15, {
'width': 560,
'elementHandlers': elementHandler
});
var svg = document.querySelector('svg');
var canvas = document.createElement('canvas');
var canvasIE = document.createElement('canvas');
var context = canvas.getContext('2d');
var DOMURL = window.URL || window.webkitURL || window;
var data1 = (new XMLSerializer()).serializeToString(svg);
canvg(canvas, data1);
var svgBlob = new Blob([data1], {
type: 'image/svg+xml;charset=utf-8'
});
var url = DOMURL.createObjectURL(svgBlob);
var img = new Image();
img.onload = function() {
context.canvas.width = $('#testchart').find('svg').width();
console.log(context.canvas.width)
context.canvas.height = $('#testchart').find('svg').height();
context.drawImage(img, 0, 0);
// freeing up the memory as image is drawn to canvas
DOMURL.revokeObjectURL(url);
var dataUrl;
if (isIEBrowser()) { // Check of IE browser
var svg = $('#testchart').highcharts().container.innerHTML;
canvg(canvasIE, svg);
dataUrl = canvasIE.toDataURL('image/JPEG');
}
else{
dataUrl = canvas.toDataURL('image/jpeg');
}
doc.addImage(dataUrl, 'JPEG', 20, 300, 560, 350);
var bottomContent = document.getElementById("bottom-content");
doc.fromHTML(bottomContent, 15, 650, {
'width': 560,
'elementHandlers': elementHandler
});
setTimeout(function() {
doc.save('TestChart.pdf');
}, 2000);
};
img.src = url;
};
function isIEBrowser(){
var ieBrowser;
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) // Internet Explorer
{
ieBrowser = true;
}
else //Other browser
{
console.log('Other Browser');
ieBrowser = false;
}
return ieBrowser;
};
Upvotes: 1
Views: 1638
Reputation: 526
The first issue here is that the code is just handling one chart / image. The approach should include a loop or multi-processing of various elements.
I've managed to edit your code and this is my result: http://plnkr.co/edit/qRT4dqJDMU8mTSocL3tb?p=preview
var elements = [$('#testchart'), $('#testchart2')];
for (let i in elements) {
var svg = document.querySelector('svg');
var canvas = document.createElement('canvas');
var canvasIE = document.createElement('canvas');
var context = canvas.getContext('2d');
var data1 = (new XMLSerializer()).serializeToString(svg);
canvg(canvas, data1);
var svgBlob = new Blob([data1], {
type: 'image/svg+xml;charset=utf-8'
});
var url = DOMURL.createObjectURL(svgBlob);
var img = new Image();
img.onload = function() {
context.canvas.width = elements[i].find('svg').width();
context.canvas.height = elements[i].find('svg').height();
context.drawImage(img, 0, 0);
// freeing up the memory as image is drawn to canvas
DOMURL.revokeObjectURL(url);
var dataUrl;
if (isIEBrowser()) { // Check of IE browser
var svg = $(elements[i]).highcharts().container.innerHTML;
canvg(canvasIE, svg);
dataUrl = canvasIE.toDataURL('image/JPEG');
} else {
dataUrl = canvas.toDataURL('image/jpeg');
}
doc.addPage();
doc.addImage(dataUrl, 'JPEG', 20, 20, 560, 350);
};
img.src = url;
}
var bottomContent = document.getElementById("bottom-content");
doc.fromHTML(bottomContent, 15, 650, {
'width': 560,
'elementHandlers': elementHandler
});
setTimeout(function() {
doc.save('TestChart.pdf');
}, 2000);
A PDF with 3 pages including both charts plus the additional contents. Give format, clean ups and edit as you may need. Hope it helps.
Upvotes: 1