Commit 8eb9bace authored by Sascha Herzinger's avatar Sascha Herzinger
Browse files

offer toSVG and toPNG for heatmap and scatterplot

parent 2f7daaf6
......@@ -10,6 +10,7 @@
<span>API examples:</span>
<button onclick="update()">update()</button>
<button onclick="toPNG()">toPNG()</button>
<button onclick="toSVG()">toSVG()</button>
<button onclick="highlight()">highlight()</button>
</div>
<div id="heatmap-container"></div>
......@@ -69,6 +70,10 @@
heatmap.toPNG();
}
function toSVG() {
heatmap.toSVG();
}
function update() {
generateRandomMatrix(-1, 1, true);
heatmap.update({
......
......@@ -10,6 +10,7 @@
<span>API examples:</span>
<button onclick="update()">update()</button>
<button onclick="toPNG()">toPNG()</button>
<button onclick="toSVG()">toSVG()</button>
</div>
<div id="scatterplot-container"></div>
</body>
......@@ -40,7 +41,7 @@
function update() {
scatterplot.update({
values: generateRandomData(2000, -10000, 10000),
values: generateRandomData(500, -10000, 10000),
categories: { name: 'Gender', 0: 'male', 1: 'female', 2: 'N/A'},
title: 'Scatterplot',
xAxisLabel: 'X Axis Values',
......@@ -53,6 +54,10 @@
scatterplot.toPNG();
}
function toSVG() {
scatterplot.toSVG();
}
document.addEventListener('DOMContentLoaded', update, false);
</script>
......
......@@ -49,25 +49,49 @@ export default class {
return this.container.getBoundingClientRect().height || this.containerWidth;
}
async toPNG() {
offerDownload(href, type) {
const a = document.createElement('a');
a.href = href;
a.download = `capture.${type}`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}
toPNG() {
this.captureSetup();
const element = this.prepareCaptureElement();
html2canvas(element.parentNode).then((canvas) => {
const img = canvas.toDataURL('image/png');
this.offerDownload(img, 'png');
this.captureTeardown();
});
}
toSVG() {
this.captureSetup();
const element = this.prepareCaptureElement();
const svgBlob = new Blob([element.outerHTML], { type: 'image/svg+xml;charset=utf-8' });
const svgUrl = URL.createObjectURL(svgBlob);
this.offerDownload(svgUrl, 'svg');
this.captureTeardown();
}
prepareCaptureElement() {
const svgElement = this.container.querySelector('svg');
svgElement.setAttribute('version', '1.1');
svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
const cssRules = this.collectCSSRules();
const defs = `<defs><style type="text/css"><![CDATA[${cssRules.join('')}]]></style></defs>`;
svgElement.innerHTML += defs;
html2canvas(this.container).then((canvas) => {
const img = canvas.toDataURL('image/png');
const a = document.createElement('a');
a.href = img;
a.download = 'capture.png';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
this.captureTeardown();
});
const defs = svgElement.querySelector('defs');
if (defs != null) { defs.remove(); }
const newDefs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
const style = document.createElement('style');
style.type = 'text/css';
const cdata = document.createTextNode(cssRules.join(''));
style.appendChild(cdata);
newDefs.appendChild(style);
svgElement.appendChild(newDefs);
return svgElement;
}
}
......@@ -48,6 +48,20 @@ export default class extends Chart {
return 'heatmap';
}
captureSetup() {
this.canvas.style('display', 'hidden');
this.captureImage = this.svg.insert('image', ':first-child')
.attr('width', this.width)
.attr('height', this.height)
.attr('xlink:href', this.canvas.node().toDataURL('image/png'));
}
captureTeardown() {
this.canvas.style('display', 'visible');
this.captureImage.node().parentNode.removeChild(this.captureImage.node());
this.render({});
}
prepareValues({ values, rows, cols }) {
this.data = [];
rows.forEach((row, i) => {
......
......@@ -92,14 +92,17 @@ export default class extends Chart {
}
captureSetup() {
this.tmpImage = this.svg.insert('image', ':first-child')
this.canvas.style('display', 'hidden');
this.captureImage = this.svg.insert('image', ':first-child')
.attr('width', this.width)
.attr('height', this.height)
.attr('xlink:href', this.canvas.node().toDataURL('image/png'));
}
captureTeardown() {
this.tmpImage.remove();
this.canvas.style('display', 'visible');
this.captureImage.node().parentNode.removeChild(this.captureImage.node());
this.render({});
}
render({
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment