Open uniquejava opened 7 years ago
http://stackoverflow.com/questions/11567668/svg-to-canvas-with-d3-js
http://blog.csdn.net/wyaspnet/article/details/52095157
https://yq.aliyun.com/wenzhang/show_38978
https://github.com/niklasvh/html2canvas/issues/95
v1
$scope.exportAsPDF = function () {
var svgs = document.querySelectorAll('svg');
for (var i = 0; i < svgs.length; i++) {
var $svg = $(svgs[i]);
var $svgp = $svg.parent();
var serializer = new XMLSerializer();
var svgString = serializer.serializeToString($svg.get(0));
var myCanvas = document.createElement('canvas');
myCanvas.width = $svgp.width();
myCanvas.height = $svgp.height();
$svgp.append(myCanvas);
canvg(myCanvas, svgString);
$svg.hide();
}
html2canvas(document.getElementById('analytics-content'), {
onrendered: function (canvas) {
var data = canvas.toDataURL();
var docDefinition = {
content: [{
image: data,
width: 500,
}]
};
pdfMake.createPdf(docDefinition).download("canvs.pdf");
$("canvas").remove();
$("svg").show();
}
});
};
http://codepen.io/wadeharrell/pen/iebdw
var svgs = document.getElementsByTagName('svg');
for (var i = 0; i < svgs.length; i++) {
var $svg = $(svgs[i]);
var $svgp = $svg.parent();
var serializer = new XMLSerializer();
var svgString = serializer.serializeToString($svg.get(0));
/*
var myCanvas = document.createElement('canvas');
myCanvas.width = $svgp.width();
myCanvas.height = $svgp.height();
$svgp.append(myCanvas);
canvg(myCanvas, svgString);
$svg.hide();
*/
var canvasId = "c" + i;
var myCanvas = document.createElement('canvas');
myCanvas.width = $svgp.width();
myCanvas.height = $svgp.height();
myCanvas.id = canvasId;
$svgp.append(myCanvas);
var f = new fabric.Canvas(canvasId);
var path = fabric.loadSVGFromString(svgString,function(objects, options) {
var obj = fabric.util.groupSVGElements(objects, options);
f.add(obj).renderAll();
});
$svg.hide();
}
$scope.generatePDF = function () {
// get styles from all required stylesheets
// http://www.coffeegnome.net/converting-svg-to-png-with-canvg/
var style = "\n";
var requiredSheets = ['chart.css', 'lineChart.css', 'donutChart.css', 'application.css', 'material-icons.css']; // list of required CSS
for (var i = 0; i < document.styleSheets.length; i++) {
var sheet = document.styleSheets[i];
if (sheet.href) {
var sheetName = sheet.href.split('/').pop();
if (requiredSheets.indexOf(sheetName) != -1) {
var rules = sheet.rules || sheet.cssRules;
if (rules) {
console.log("append new rules:", rules.length, sheetName);
for (var j = 0; j < rules.length; j++) {
var css = rules[j].cssText;
if (css.startsWith('@font-face')) {
if (css.indexOf("url(\"MaterialIcons") != -1) {
var url = sheet.href;
console.log(url);
url = url.substring(0, url.lastIndexOf('/') + 1);
css = css.replace(/url\("/gi, "url(\"" + url);
console.log(css);
}
}
style += (css + '\n');
}
}
}
}
}
d3.selectAll('svg').each(function () {
var node = this,
svg = d3.select(node),
serializer = new XMLSerializer(),
width = node.getBBox().width,
height = node.getBBox().height;
// prepend style to svg
svg.insert('defs', ":first-child");
svg.select("defs")
.append('style')
.attr('type', 'text/css')
.html(style);
var svgStr = serializer.serializeToString(node);
var myCanvas = document.createElement('canvas');
myCanvas.width = width;
myCanvas.height = height;
$(node).parent().append(myCanvas);
canvg(myCanvas, svgStr);
$(node).hide();
});
html2canvas(document.getElementById('analytics-content'), {
onrendered: function (canvas) {
var data = canvas.toDataURL();
var docDefinition = {
content: [{
image: data,
width: 500,
}]
};
pdfMake.createPdf(docDefinition).download("output.pdf");
$("canvas").remove();
$("svg").show();
}
});
};
$scope.generatePDF = function () {
// get required stylesheets for svg and embed the style into svg itself.
// see http://www.coffeegnome.net/converting-svg-to-png-with-canvg/
var style = "\n";
var requiredSheets = ['application.css', 'chart.css', 'lineChart.css', 'donutChart.css', 'material-icons.css']; // list of required CSS
for (var i = 0; i < document.styleSheets.length; i++) {
var sheet = document.styleSheets[i];
if (sheet.href) {
var sheetName = sheet.href.split('/').pop();
if (requiredSheets.indexOf(sheetName) != -1) {
var rules = sheet.rules || sheet.cssRules;
if (rules) {
for (var j = 0; j < rules.length; j++) {
var css = rules[j].cssText;
if (css.startsWith('@font-face')) {
if (css.indexOf("url(\"MaterialIcons") != -1) {
var url = sheet.href;
console.log(url);
url = url.substring(0, url.lastIndexOf('/') + 1);
css = css.replace(/url\("/gi, "url(\"" + url);
console.log(css);
}
}
style += (css + '\n');
}
}
}
}
}
// style += '.tick line{stroke: lightgray !important}\n';
d3.selectAll('svg').each(function () {
var node = this,
svg = d3.select(node),
serializer = new XMLSerializer(),
width = node.getBBox().width,
height = node.getBBox().height;
var pClasses = $(node).parent().attr('class').split(' ');
_.each(pClasses, function (clz) {
if (clz !== 'chart') {
$(node).toggleClass(clz, true);
}
});
// prepend style to svg
svg.insert('defs', ":first-child");
svg.select("defs")
.append('style')
.attr('type', 'text/css')
.html(style);
var myCanvas = document.createElement('canvas');
myCanvas.width = width;
myCanvas.height = height;
$(node).parent().append(myCanvas);
canvg(myCanvas, serializer.serializeToString(node));
var pClasses = $(node).parent().attr('class').split(' ');
_.each(pClasses, function (clz) {
$(node).toggleClass(clz, false);
});
$(node).hide();
});
Html5Page2Canvas();
};
function Html5Page2Canvas() {
html2canvas(document.getElementById('analytics-content'), {
onrendered: function (canvas) {
var data = canvas.toDataURL();
var docDefinition = {
content: [{
image: data,
width: 500
}]
};
pdfMake.createPdf(docDefinition).download("output.pdf");
$("canvas").remove();
$("svg").show();
}
});
}
function getRequiredStyles4Svg() {
// get required stylesheets for svg and embed the style into svg itself.
// see http://www.coffeegnome.net/converting-svg-to-png-with-canvg/
var style = "\n";
// list of required CSS
var requiredSheets = ['application.css', 'chart.css', 'lineChart.css', 'donutChart.css'];
for (var i = 0; i < document.styleSheets.length; i++) {
var sheet = document.styleSheets[i];
if (sheet.href) {
var sheetName = sheet.href.split('/').pop();
if (requiredSheets.indexOf(sheetName) != -1) {
var rules = sheet.rules || sheet.cssRules;
if (rules) {
for (var j = 0; j < rules.length; j++) {
var css = rules[j].cssText;
style += (css + '\n');
}
}
}
}
}
//fix grid line styles
style += '.axis .tick line, .x .tick line, .y .tick line{strike: lightgray !important; stroke-width: 1px !important}\n';
return style;
}
$scope.generatePDF = function () {
var style = getRequiredStyles4Svg();
d3.selectAll('svg').each(function () {
var node = this,
svg = d3.select(node),
serializer = new XMLSerializer(),
width = node.getBBox().width,
height = node.getBBox().height;
// fix stylesheet context issue: copy svg parent's classes onto svg itself
var pClasses = $(node).parent().attr('class').split(' ');
_.each(pClasses, function (clz) {
if (clz !== 'chart') { // grid line will be disappeared if `chart` is added
$(node).toggleClass(clz, true);
}
});
// add required styles to svg
svg.insert('defs', ":first-child");
svg.select("defs")
.append('style')
.attr('type', 'text/css')
.html(style);
// convert svg to canvas
var myCanvas = document.createElement('canvas');
myCanvas.width = width;
myCanvas.height = height;
$(node).parent().append(myCanvas);
canvg(myCanvas, serializer.serializeToString(node));
// hide svg temporarily
$(node).hide();
});
// convert whole html5 page to canvas and export canvas as pdf.
Html5Page2Canvas('analytics-content', document.title + '.pdf');
};
function Html5Page2Canvas(root, fileName) {
html2canvas(document.getElementById(root), {
onrendered: function (canvas) {
var data = canvas.toDataURL();
var docDefinition = {
content: [{
image: data,
width: 500
}]
};
pdfMake.createPdf(docDefinition).download(fileName);
// clean up
$("canvas").remove();
$("svg defs").remove();
$("svg").attr('class', '');
$("svg").show();
}
});
}
How to implement D3 for Vue.js
Composing D3 Visualizations With Vue.js
https://www.safaribooksonline.com/library/view/d3js-4x-data/9781787120358/
You can write SVG markup and embed it directly in a web page (provided you use <!DOCTYPE html>
). You can inspect SVG elements in your browser’s developer tools. And SVG elements can be styled with CSS, albeit using different property names like fill
instead of background-color
. However, unlike HTML, SVG elements must be positioned relative to the top-left corner of the container; SVG does not support flow layout or even text wrapping.
<!DOCTYPE html>
<style>
.chart rect {
fill: steelblue;
}
.chart text {
fill: white;
font: 10px sans-serif;
text-anchor: end;
}
</style>
<svg class="chart" width="420" height="120">
<g transform="translate(0,0)">
<rect width="40" height="19"></rect>
<text x="37" y="9.5" dy=".35em">4</text>
</g>
<g transform="translate(0,20)">
<rect width="80" height="19"></rect>
<text x="77" y="9.5" dy=".35em">8</text>
</g>
SVG requires text to be placed explicitly in text
elements. Since text
elements do not support padding or margins, the text position must be offset by three pixels from the end of the bar, while the dy
offset is used to center the text vertically.
select/selectAll/attr/style/property
data(..)返回的是需要update的selection enter(..)是没有element的data(OR 需要新建的element) exit(..)是没有data的element(OR 需要移除的element)
套路: selectAll + data + enter + append
, 示例:
var circle = svg.selectAll("circle")
.data([32, 57, 293], function(d) { return d; });
circle.enter().append("circle")
.attr("cy", 60)
.attr("cx", function(d, i) { return i * 100 + 30; })
.attr("r", function(d) { return Math.sqrt(d); });
circle.exit().remove();
需要注意的是append比较特殊返回的是新selection.
d3.selectAll("section")
.attr("class", "special")
.append("div")
.html("Hello, world!");
var section = d3.selectAll("section");
section.append("div")
.html("First!");
section.append("div")
.html("Second.");
var x = d3.scale.linear()
.domain([0, d3.max(data)])
.range([0, 420]);
d3.select(".chart")
.selectAll("div")
.data(data)
.enter().append("div")
.style("width", function(d) { return x(d) + "px"; })
.text(function(d) { return d; });
book: D3.js in Action
Three Little Circles Let’s Make a Bar Chart Thinking with Joins Setting Scales Domains and Ranges in d3.js
Fun with Circles in D3
https://leanpub.com/D3-Tips-and-Tricks/read#leanpub-auto-d3-javascript
http://www.ourd3js.com/wordpress/865
(1)官方 API
https://github.com/mbostock/d3/wiki/API-Reference
阅读 API 学习是一个不坏的方法。虽然有不少人说 D3 的 API 写得太学术性了,不好懂,但是真要想得心应手地使用 D3,此 API 是避不开的。
(2)Mike Bostock 的博客和作品展示板
http://bost.ocks.org/mike/
http://bl.ocks.org/mbostock/
这是由 D3 的作者制作的,Mike Bostock 是纽约时报的工程师,纽约时报目前的可视化技术是使用 D3 的。但是,这个博客和作品展示板里,文字说明不多,大多数只有代码,理解起来挺困难。
(3)Dashing D3.js
https://www.dashingd3js.com/table-of-contents
非常简单易懂的教程,文字解释、图片都十分清晰。此站开设的目的就是为了让人迅速而高效地掌握 D3。
(4)Custom Visualizations with D3.js
http://jsdatav.is/chap07.html
一本书的其中一章,但是内容很丰富,图形也很简洁精美。另外,该站都是关于数据可视化的文章,绝对值得一看。
(5)INTRO TO D3.JS
http://square.github.io/intro-to-d3/
排版很有意思,简单易懂的一个学习站。
(6)D3.js Gallery
http://christopheviau.com/d3list/gallery.html
汇集了网络上 2490 个 D3.js 的例子,是一个巨大的可视化宝库。
中文资料
(1)很早的一个站
http://www.pkuwwt.tk/d3-tutorial-cn/about.html
更新时间显示的是2012年,可以说非常非常早,要知道 D3 是2011年诞生,2012年12月版本才升级到3.0(现在常用的)。
(2)张天旭的博客
http://blog.csdn.net/tianxuzhang?viewmode=contents
张天旭的 CSDN 博客,其 D3 的系列教程有超过 10 万的访问量,人气相当高。
(3)阮一峰的博客
http://javascript.ruanyifeng.com/library/d3.html
阮一峰的写作风格是简单易懂。但是可惜,关于 D3 的只有一篇。
(4)楚狂人的博客
http://www.cnblogs.com/winleisure/tag/D3.js/
楚狂人的博客,翻译的 Dashing D3.js,翻译的质量很好。
https://schoolofdata.org/2013/10/01/pie-and-donut-charts-in-d3-js/ http://ddgreat.com/d3-svg-line-function-problem/
d3-tip demo: http://bl.ocks.org/Caged/6476579
http://nesterko.com/blog/2012/01/30/measuring-homophily-in-network-data-and-how-to-export-from-d3-js-to-pdf/