繁体   English   中英

当页面中有多个SVG时,如何将SVG转换为canvas到PNG

[英]How to convert SVG to canvas to PNG when there are multiple SVGs in a page

 var formatAsPercentage = d3.format("%"), formatAsPercentage1Dec = d3.format(".1%"), formatAsInteger = d3.format(","), fsec = d3.time.format("%S s"), fmin = d3.time.format("%M m"), fhou = d3.time.format("%H h"), fwee = d3.time.format("%a"), fdat = d3.time.format("%dd"), fmon = d3.time.format("%b") ; // Let's create a mock visualization function dsPieChart(){ var dataset = [ {category: "apple", measure: 0.30}, {category: "mango", measure: 0.25}, {category: "pineapple", measure: 0.18}, {category: "orange", measure: 0.0}, {category: "peach", measure: 0.18} ] ; var width = 400, height = 400, outerRadius = Math.min(width, height) / 2, innerRadius = outerRadius * .999, // for animation innerRadiusFinal = outerRadius * .5, innerRadiusFinal3 = outerRadius* .45, color = d3.scale.category20() //builtin range of colors ; var svg = d3.select("#pie") .append("svg:svg") //create the SVG element inside the <body> .data([dataset]) //associate our data with the document .attr("width", width) //set the width and height of our visualization (these will be attributes of the <svg> tag .attr("height", height) .append("svg:g") //make a group to hold our pie chart .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")") //move the center of the pie chart from 0, 0 to radius, radius ; var arc = d3.svg.arc() //this will create <path> elements for us using arc data .outerRadius(outerRadius).innerRadius(innerRadius); // for animation var arcFinal = d3.svg.arc().innerRadius(innerRadiusFinal).outerRadius(outerRadius); var arcFinal3 = d3.svg.arc().innerRadius(innerRadiusFinal3).outerRadius(outerRadius); var pie = d3.layout.pie() //this will create arc data for us given a list of values .value(function(d) { return d.measure; }); //we must tell it out to access the value of each element in our data array var arcs = svg.selectAll("g.slice") //this selects all <g> elements with class slice (there aren't any yet) .data(pie) //associate the generated pie data (an array of arcs, each having startAngle, endAngle and value properties) .enter() //this will create <g> elements for every "extra" data element that should be associated with a selection. The result is creating a <g> for every object in the data array .append("svg:g") //create a group to hold each slice (we will have a <path> and a <text> element associated with each slice) .attr("class", "slice") //allow us to style things in the slices (like text) .on("mouseover", mouseover) .on("mouseout", mouseout) .on("click", up) ; arcs.append("svg:path") .attr("fill", function(d, i) { return color(i); } ) //set the color for each slice to be chosen from the color function defined above .attr("d", arc) //this creates the actual SVG path using the associated data (pie) with the arc drawing function .append("svg:title") //mouseover title showing the figures .text(function(d) { return d.data.category + ": " + formatAsPercentage(d.data.measure); }); d3.selectAll("g.slice").selectAll("path").transition() .duration(750) .delay(10) .attr("d", arcFinal ) ; // Add a label to the larger arcs, translated to the arc centroid and rotated. // source: http://bl.ocks.org/1305337#index.html arcs.filter(function(d) { return d.endAngle - d.startAngle > .2; }) .append("svg:text") .attr("dy", ".35em") .attr("text-anchor", "middle") .attr("transform", function(d) { return "translate(" + arcFinal.centroid(d) + ")rotate(" + angle(d) + ")"; }) //.text(function(d) { return formatAsPercentage(d.value); }) .text(function(d) { return d.data.category; }) ; // Computes the label angle of an arc, converting from radians to degrees. function angle(d) { var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90; return a > 90 ? a - 180 : a; } // Pie chart title svg.append("svg:text") .attr("dy", ".35em") .attr("text-anchor", "middle") .text("Usage Domainwise") .attr("class","title") ; function mouseover() { d3.select(this).select("path").transition() .duration(750) //.attr("stroke","red") //.attr("stroke-width", 1.5) .attr("d", arcFinal3) ; } function mouseout() { d3.select(this).select("path").transition() .duration(750) //.attr("stroke","blue") //.attr("stroke-width", 1.5) .attr("d", arcFinal) ; } function up(d, i) { /* update bar chart when user selects piece of the pie chart */ //updateBarChart(dataset[i].category); updateBarChart(d.data.category, color(i)); updateBarStatusChart(d.data.category, color(i)); } // Create an export button d3.select("#pie") .append("button") .html("Export") .on("click",svgToCanvas); var w = 100, // or whatever your svg width is h = 100; // Create the export function - this will just export // the first svg element it finds function svgToCanvas(){ debugger; var svg = d3.select("svg")[0][0], img = new Image(), serializer = new XMLSerializer(), svgStr = serializer.serializeToString(svg); data = 'data:image/svg+xml;base64,'+window.btoa(svgStr); var canvas = document.createElement("canvas"); canvas.width = 400; canvas.height = 400; context = canvas.getContext("2d"); img.src = data; img.onload = function() { context.drawImage(img, 0, 0, w, h); var canvasdata = canvas.toDataURL("image/png"); var pngimg = '<img src="'+canvasdata+'">'; var a = document.createElement("a"); a.download = "sample.png"; a.href = canvasdata; a.click(); }; }; } dsPieChart(); var datasetBarChart = [ { "group": "All","category": "seasonal", "measure": 63850.4963 }, { "group": "All", "category": "allYear", "measure": 78258.0845 }, { group: "apple", category: "seasonal", measure: 19441.5648 }, { group: "apple", category: "allYear", measure: 25922.0864 }, { group: "mango", category: "seasonal", measure: 9720.7824 }, { group: "mango", category: "allYear", measure: 6480.5216 }, ] ; // set initial group value var group = "All"; function datasetBarChosen(group) { var ds = []; for (x in datasetBarChart) { if(datasetBarChart[x].group==group){ ds.push(datasetBarChart[x]); } } return ds; } function dsBarChartBasics() { var margin = {top: 30, right: 5, bottom: 20, left: 50}, width = 500 - margin.left - margin.right, height = 250 - margin.top - margin.bottom, colorBar = d3.scale.category20(), barPadding = 1 ; return { margin : margin, width : width, height : height, colorBar : colorBar, barPadding : barPadding } ; } function dsBarChart() { var firstDatasetBarChart = datasetBarChosen(group); var basics = dsBarChartBasics(); var margin = basics.margin, width = basics.width, height = basics.height, colorBar = basics.colorBar, barPadding = basics.barPadding ; var xScale = d3.scale.linear() .domain([0, firstDatasetBarChart.length]) .range([0, width]) ; // Create linear y scale // Purpose: No matter what the data is, the bar should fit into the svg area; bars should not // get higher than the svg height. Hence incoming data needs to be scaled to fit into the svg area. var yScale = d3.scale.linear() // use the max funtion to derive end point of the domain (max value of the dataset) // do not use the min value of the dataset as min of the domain as otherwise you will not see the first bar .domain([0, d3.max(firstDatasetBarChart, function(d) { return d.measure; })]) // As coordinates are always defined from the top left corner, the y position of the bar // is the svg height minus the data value. So you basically draw the bar starting from the top. // To have the y position calculated by the range function .range([height, 0]) ; //Create SVG element var svg = d3.select("#bar") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .attr("id","barChartPlot") ; var svg = svg .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") ; svg.selectAll("rect") .data(firstDatasetBarChart) .enter() .append("rect") .attr("x", function(d, i) { return xScale(i); }) .attr("width", width / firstDatasetBarChart.length - barPadding) .attr("y", function(d) { return yScale(d.measure); }) .attr("height", function(d) { return height-yScale(d.measure); }) .attr("fill", "BLUE") ; // Add y labels to plot svg.selectAll("text") .data(firstDatasetBarChart) .enter() .append("text") .text(function(d) { return formatAsInteger(d3.round(d.measure)); }) .attr("text-anchor", "middle") // Set x position to the left edge of each bar plus half the bar width .attr("x", function(d, i) { return (i * (width / firstDatasetBarChart.length)) + ((width / firstDatasetBarChart.length - barPadding) / 2); }) .attr("y", function(d) { return yScale(d.measure) + 14; }) .attr("class", "yAxis") /* moved to CSS .attr("font-family", "sans-serif") .attr("font-size", "11px") .attr("fill", "white") */ ; // Add x labels to chart var xLabels = svg .append("g") .attr("transform", "translate(" + margin.left + "," + (margin.top + height) + ")") ; xLabels.selectAll("text.xAxis") .data(firstDatasetBarChart) .enter() .append("text") .text(function(d) { return d.category;}) .attr("text-anchor", "middle") // Set x position to the left edge of each bar plus half the bar width .attr("x", function(d, i) { return (i * (width / firstDatasetBarChart.length)) + ((width / firstDatasetBarChart.length - barPadding) / 2); }) .attr("y", 15) .attr("class", "xAxis") //.attr("style", "font-size: 12; font-family: Helvetica, sans-serif") ; // Title svg.append("text") .attr("x", (width + margin.left + margin.right)/2) .attr("y", 15) .attr("class","title") .attr("text-anchor", "middle") .text("Overall") ; // Create an export button d3.select("#bar") .append("button") .html("Export") .on("click",svgToCan); } dsBarChart(); var w = 100, // or whatever your svg width is h = 100; function svgToCan(){ // Select the first svg element debugger; var svg = d3.select("svg")[0][0], img = new Image(), serializer = new XMLSerializer(), svgStr = serializer.serializeToString(svg); data = 'data:image/svg+xml;base64,'+window.btoa(svgStr); var canvas = document.createElement("canvas"); canvas.width = 400; canvas.height = 400; context = canvas.getContext("2d"); img.src = data; img.onload = function() { context.drawImage(img, 0, 0, w, h); var canvasdata = canvas.toDataURL("image/png"); var pngimg = '<img src="'+canvasdata+'">'; var a = document.createElement("a"); a.download = "sample.png"; a.href = canvasdata; a.click(); }; }; 
 <head> <script src="https://d3js.org/d3.v3.min.js"></script> </head> <body> <div> <div id="pie"></div> <div id="bar"></div> </div> </body> 

无论我选择哪个选择器,它总是下载第一个SVG元素。 我知道这是因为我以这种方式选择var svg = d3.select("svg")[0][0]第一个元素。 但是我在调​​用函数的两个实例来避免这种情况,有人可以建议我在将其转换为PNG时如何选择所需的SVG元素。

使用selectAll()方法,而不是select()svgToCan()函数在那里你会得到svgs的全部名单。

用这些行替换函数svgToCan(){}

var arr=[];
    for(var i=0;i<d3.selectAll("svg").length;i++){
        arr=d3.selectAll("svg")[i];
        console.log(d3.selectAll("svg")[i]);
    }
     for(var j=0;j<arr.length;j++)
        var svg = arr[j],
        img = new Image(),
        serializer = new XMLSerializer(),
        svgStr = serializer.serializeToString(svg);

供您参考,我附上了我的jsfiddle示例

https://jsfiddle.net/achuakshuu/L92ngrrd/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM