2015-10-17 185 views
5

我有以下問題:我正在轉換由d3.js創建的svg plot,但是png與svg完全不同。前 SVG轉換後轉換SVG before converting將svg轉換爲png時添加css樣式

PNG:PNG after converting

如何申請相同的CSS代碼的皈依?反正有沒有像創建svg的時候鏈接到.css文件?

svgtopng.js代碼:

d3.select("#save").on("click", function(){ 
var html = d3.select('#h3 svg') 
    .attr("version", 1.1) 
    .attr("xmlns", "http://www.w3.org/2000/svg") 
    //HERE I WAS TRYING WITH .style but I want to link all the css classes from .css file below// 
    .node().parentNode.innerHTML; 

var imgsrc = 'data:image/svg+xml;base64,'+ btoa(html); 
var img = '<img src="'+imgsrc+'">'; 
d3.select("#svgdataurl").html(img); 

CSS代碼:

body { 
font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif; 
padding-left: 10px; 
color: #222; 
} 
/* Histogram line areas */ 
.Histogram .line { 
    shape-rendering: crispEdges; 
} 
.LineChart .line { 
    stroke-width: 2px; 
} 
/* 2D Histogram bins */ 
.Histogram2D .tile { 
    shape-rendering: crispEdges; 
} 
/* Error bars */ 
.uncertainty { 
    stroke-width: 1px; 
    shape-rendering: crispEdges; 
} 
/* Axes */ 
.axis path { 
    fill: none; 
    stroke: #000; 
    stroke-width: 1px; 
    shape-rendering: crispEdges; 
} 
.axis .tick line { 
    stroke: #000; 
    stroke-width: 1px; 
    shape-rendering: crispEdges; 
} 
.grid { 
    fill: none; 
    stroke: #e0e0e0; 
    shape-rendering: crispEdges; 
} 
.axis-label { 
    font-size: 0.9em; 
} 
/* TextBox */ 
.TextBox rect { 
    shape-rendering: crispEdges; 
} 
/* Brush, i.e. zoom box */ 
.brush .extent { 
    fill: #000; 
    fill-opacity: 0.125; 
    stroke: #000; 
    stroke-opacity: 0.2; 
    stroke-width: 1px; 
    shape-rendering: crispEdges; 
} 
/* 'Clear zoom' text */ 
.clear-button { 
    cursor: pointer; 
} 
.clear-button rect { 
    fill: #eee; 
    stroke: #000; 
    stroke-width: 1px; 
    stroke-opacity: 0.125; 
    border-radius: 2px; 
} 
.clear-button:hover rect { 
    fill: #e4e4e4; 
} 
.clear-button:active rect { 
    fill: #ddd; 
} 

.zscale-box { 
    stroke: #000; 
    stroke-width: 1px; 
    shape-rendering: crispEdges; 
} 

HTML代碼:

<button id="save">Save as Image</button></h1> 
<div id="svgdataurl"></div> 
    <span id="h3"> 
    </span> 
+0

我不是專家,但也許你可以嘗試像不同的庫https://github.com/exupero/saveSvgAsPng – makshh

+0

我正在嘗試這個,但不幸的是不工作;/ –

回答

3

本質上講,你需要移動樣式 「內聯」 上的元素。例如你g軸道路是從:

<g class="x axis" transform="translate(0,450)"> 
    <path class="domain" d="M0,6V0H440V6"></path> 
</g> 

要:

<g class="x axis" transform="translate(0,450)"> 
    <path class="domain" d="M0,6V0H440V6" 
    style="fill: none; stroke: #000; stroke-width: 1px; shape-rendering: crispEdges;"> 
    </path> 
</g> 

有一些遞歸tricks了那裏所有的元素做到這一點,但完全遞歸可能是有點矯枉過正的(和會緩慢)。

我會手動移動樣式或做一些事情來定位您關心的元素。舉例來說,這裏是如何您可以修復軸線:

d3.selectAll('.axis path, .axis line, .axis').each(function() { 
    var element = this; 
    var computedStyle = getComputedStyle(element, null); 
    for (var i = 0; i < computedStyle.length; i++) { 
     var property = computedStyle.item(i); 
     var value = computedStyle.getPropertyValue(property); 
     element.style[property] = value; 
    } 
    }); 

全部工作示例:

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 
<style> 
 

 
    .axis { 
 
    font: 10px sans-serif; 
 
    } 
 
    
 
    .axis path, 
 
    .axis line { 
 
    fill: none; 
 
    stroke: #000; 
 
    shape-rendering: crispEdges; 
 
    } 
 
    
 
    .x.axis path { 
 
    display: none; 
 
    } 
 
</style> 
 

 
<body> 
 

 
    <button id="save">Save as Image</button> 
 

 
    <div id="svgdataurl"></div> 
 

 
    <span id="h3"> 
 
    </span> 
 

 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> 
 
    <script> 
 
    var margin = { 
 
     top: 20, 
 
     right: 20, 
 
     bottom: 30, 
 
     left: 40 
 
     }, 
 
     width = 500 - margin.left - margin.right, 
 
     height = 500 - margin.top - margin.bottom; 
 

 
    var x = d3.scale.linear() 
 
     .range([0, width]); 
 

 
    var y = d3.scale.linear() 
 
     .range([height, 0]); 
 

 
    var xAxis = d3.svg.axis() 
 
     .scale(x) 
 
     .orient("bottom"); 
 

 
    var yAxis = d3.svg.axis() 
 
     .scale(y) 
 
     .orient("left"); 
 

 
    var svg = d3.select("#h3").append("svg") 
 
     .attr("width", width + margin.left + margin.right) 
 
     .attr("height", height + margin.top + margin.bottom) 
 
     .append("g") 
 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
    x.domain([0, 100]); 
 
    y.domain([0, 100]); 
 

 
    svg.append("g") 
 
     .attr("class", "x axis") 
 
     .attr("transform", "translate(0," + height + ")") 
 
     .call(xAxis); 
 

 
    svg.append("g") 
 
     .attr("class", "y axis") 
 
     .call(yAxis) 
 
     .append("text") 
 
     .attr("transform", "rotate(-90)") 
 
     .attr("y", 6) 
 
     .attr("dy", ".71em") 
 
     .style("text-anchor", "end"); 
 

 
    d3.select("#save").on("click", function() { 
 

 
     d3.selectAll('.axis path, .axis line, .axis').each(function() { 
 
     var element = this; 
 
     var computedStyle = getComputedStyle(element, null); 
 
     for (var i = 0; i < computedStyle.length; i++) { 
 
      var property = computedStyle.item(i); 
 
      var value = computedStyle.getPropertyValue(property); 
 
      element.style[property] = value; 
 
     } 
 
     }); 
 

 
     var html = d3.select('#h3 svg') 
 
     .attr("version", 1.1) 
 
     .attr("xmlns", "http://www.w3.org/2000/svg") 
 
     //HERE I WAS TRYING WITH .style but I want to link all the css classes from .css file below// 
 
     .node().parentNode.innerHTML; 
 

 
     var imgsrc = 'data:image/svg+xml;base64,' + btoa(html); 
 
     var img = '<img src="' + imgsrc + '">'; 
 
     d3.select("#svgdataurl").html(img); 
 
    }); 
 
    </script>

+0

非常感謝。我手動傳輸樣式,它的工作原理,但它真的不起作用; /很遺憾,在d3.js沒有選項鍊接到外部的CSS文件 –