我对D3很新(所以我的问题可能有点愚蠢)并且正在进行可视化,我想将其导出到png。我是这样做的:http://bl.ocks.org/Rokotyan/0556f8facbaf344507cdc45dc3622177
我在造型等方面遇到了一些问题,但是内嵌样式解决了这个问题。
我现在遇到的问题是我在SVG中使用的png图像没有出现在我导出到png的画布中。
我已经进行了相当多的实验,没有达到预期的效果。
下面的代码将png放在SVG上:
svg.selectAll("svg")
.data(inputdata)
.enter()
.append("svg:image")
.attr("xlink:href", "image_1.png")
.attr("x", function(d) {
return (d.X_Coordinate);})
.attr("y", function(d) {
return (d.Y_Coordinate);})
.attr("width", image_width)
.attr("height", image_height)
;
d3.selectAll("svg").attr({'xmlns': 'http://www.w3.org/2000/svg','xmlns:xmlns:xlink': 'http://www.w3.org/1999/xlink'});
答案 0 :(得分:0)
您需要对images as base64进行编码。因此,借用this excellent answer中的一些代码并将其与您链接的示例放在一起:
<!DOCTYPE html>
<html lang="en">
<head>
<title>How to properly export SVG D3 visualization to PNG or JPEG</title>
<meta charset="utf-8">
<script src="https://cdn.rawgit.com/eligrey/canvas-toBlob.js/f1a01896135ab378aa5c0118eadd81da55e698d8/canvas-toBlob.js"></script>
<script src="https://cdn.rawgit.com/eligrey/FileSaver.js/e9d941381475b5df8b7d7691013401e171014e89/FileSaver.min.js"></script>
<script src="https://d3js.org/d3.v3.min.js"></script>
<style type="text/css">
.blendCircle {
mix-blend-mode: multiply;
}
</style>
</head>
<body>
<div>
<button id='saveButton'>Export my D3 visualization to PNG</button>
</div>
<script type="text/javascript">
var width = 200,
height = 200;
var svg = d3.select('body').append('svg')
.attr('width', width)
.attr('height', height);
svg
.append("svg:image")
.each(function() {
toDataURL(
'https://i.imgur.com/1kqZEq2.jpg',
(dataUrl) => {
d3.select(this).attr("xlink:href", dataUrl);
}
)
})
.attr("width", width)
.attr("height", height);
function toDataURL(src, callback, outputFormat) {
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.naturalHeight;
canvas.width = this.naturalWidth;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(dataURL);
};
img.src = src;
if (img.complete || img.complete === undefined) {
img.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
img.src = src;
}
}
// Set-up the export button
d3.select('#saveButton').on('click', function() {
var svgString = getSVGString(svg.node());
svgString2Image(svgString, 2 * width, 2 * height, 'png', save); // passes Blob and filesize String to the callback
function save(dataBlob, filesize) {
saveAs(dataBlob, 'D3 vis exported to PNG.png'); // FileSaver.js function
}
});
// Below are the functions that handle actual exporting:
// getSVGString ( svgNode ) and svgString2Image( svgString, width, height, format, callback )
function getSVGString(svgNode) {
svgNode.setAttribute('xlink', 'http://www.w3.org/1999/xlink');
var cssStyleText = getCSSStyles(svgNode);
appendCSS(cssStyleText, svgNode);
var serializer = new XMLSerializer();
var svgString = serializer.serializeToString(svgNode);
svgString = svgString.replace(/(\w+)?:?xlink=/g, 'xmlns:xlink='); // Fix root xlink without namespace
svgString = svgString.replace(/NS\d+:href/g, 'xlink:href'); // Safari NS namespace fix
return svgString;
function getCSSStyles(parentElement) {
var selectorTextArr = [];
// Add Parent element Id and Classes to the list
selectorTextArr.push('#' + parentElement.id);
for (var c = 0; c < parentElement.classList.length; c++)
if (!contains('.' + parentElement.classList[c], selectorTextArr))
selectorTextArr.push('.' + parentElement.classList[c]);
// Add Children element Ids and Classes to the list
var nodes = parentElement.getElementsByTagName("*");
for (var i = 0; i < nodes.length; i++) {
var id = nodes[i].id;
if (!contains('#' + id, selectorTextArr))
selectorTextArr.push('#' + id);
var classes = nodes[i].classList;
for (var c = 0; c < classes.length; c++)
if (!contains('.' + classes[c], selectorTextArr))
selectorTextArr.push('.' + classes[c]);
}
// Extract CSS Rules
var extractedCSSText = "";
for (var i = 0; i < document.styleSheets.length; i++) {
var s = document.styleSheets[i];
try {
if (!s.cssRules) continue;
} catch (e) {
if (e.name !== 'SecurityError') throw e; // for Firefox
continue;
}
var cssRules = s.cssRules;
for (var r = 0; r < cssRules.length; r++) {
if (contains(cssRules[r].selectorText, selectorTextArr))
extractedCSSText += cssRules[r].cssText;
}
}
return extractedCSSText;
function contains(str, arr) {
return arr.indexOf(str) === -1 ? false : true;
}
}
function appendCSS(cssText, element) {
var styleElement = document.createElement("style");
styleElement.setAttribute("type", "text/css");
styleElement.innerHTML = cssText;
var refNode = element.hasChildNodes() ? element.children[0] : null;
element.insertBefore(styleElement, refNode);
}
}
function svgString2Image(svgString, width, height, format, callback) {
var format = format ? format : 'png';
var imgsrc = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgString))); // Convert SVG string to data URL
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
var image = new Image();
image.onload = function() {
context.clearRect(0, 0, width, height);
context.drawImage(image, 0, 0, width, height);
canvas.toBlob(function(blob) {
var filesize = Math.round(blob.length / 1024) + ' KB';
if (callback) callback(blob, filesize);
});
};
image.src = imgsrc;
}
</script>
</body>
</html>