2016-11-15 17 views
14

Chúng tôi có ứng dụng js góc sử dụng thư viện highchart js và nó hiển thị biểu đồ dưới dạng SVG. Chúng tôi đã tạo ra một số tiện ích hiển thị kết hợp dữ liệu, giả sử trong một số tiện ích, chúng tôi chỉ có biểu đồ SVG, trong một số dữ liệu chỉ hiển thị với chỉ thị góc, trong khi trong một số tiện ích, chúng tôi có kết hợp cả hai biểu đồ + một số HTML nó có thể là danh sách bullet đơn giản hoặc để nói dữ liệu dạng bảng được hiển thị với góc). Bây giờ chúng tôi muốn cung cấp chức năng để mỗi tiện ích có thể được xuất dưới dạng hình ảnh.JavaScript - Xuất Div với biểu đồ SVG + HTML dưới dạng và Hình ảnh

Chúng tôi đã xem qua ví dụ này jsfiddle.net/8ypxW/3/ sử dụng thư viện html2canvas và hoạt động tốt với dữ liệu HTML, nhưng biểu đồ SVG không được xuất với điều này.

Chúng tôi nghĩ tạo ảnh từ phía máy chủ thông qua C#, nhưng mỗi tiện ích được tạo bằng thư viện js (highchart & góc), vì vậy trong trường hợp này, chúng tôi không có hỗ trợ trực tiếp nào về phía máy chủ.

Giải pháp cho kịch bản trên là gì? hoặc những gì có thể là cách tiếp cận khác để đạt được tương tự.

+0

Bạn đã thử chuyển đổi svg thành hình ảnh đầu tiên bằng cách sử dụng các công cụ như https://github.com/exupero/saveSvgAsPng sau đó chuyển đổi html bằng hình ảnh thành hình ảnh –

Trả lời

3

Tôi nghĩ dom-to-image.js là một chút chính xác hơn html để vải, sau đây là một số thủ thuật:

dom-to-hình ảnh cho phép bạn tạo ra từ định dạng url dữ liệu html svg, vâng tôi biết Tại sao bạn sẽ làm điều đó, nó chính xác hơn, với svg đó một bức ảnh được vẽ bên trong một khung hình (bạn cần gì trong trường hợp của bạn, hoặc một cái gì đó phức tạp hơn nếu bạn cần toàn bộ trang được in trong một hình ảnh như trong ví dụ của tôi). Từ canvas đó, bạn có thể kéo hình ảnh, thay đổi kích thước, tải xuống.

Bản quyền: http://jsfiddle.net/gregfedorov/Qh9X5/9/http://jsfiddle.net/christopheviau/v6VMf/

///dom to svg module 
 
document.getElementById('downloadbody').onclick= function(){ 
 
    var wrapper = document.getElementsByTagName("BODY")[0]; 
 
    //dom to image 
 
    domtoimage.toSvg(wrapper).then(function (svgDataUrl) { 
 
    //download function  
 
    downloadPNGFromAnyImageSrc(svgDataUrl); 
 
    }); 
 
} 
 

 
document.getElementById('downloadcircle').onclick= function(){ 
 
    var wrapper = document.getElementById('circle'); 
 
    //dom to image 
 
    domtoimage.toSvg(wrapper).then(function (svgDataUrl) { 
 
    //download function  
 
    downloadPNGFromAnyImageSrc(svgDataUrl); 
 
    }); 
 
} 
 

 
document.getElementById('downloadtable').onclick= function(){ 
 
    var wrapper = document.getElementById('table'); 
 
    //dom to image 
 
    domtoimage.toSvg(wrapper).then(function (svgDataUrl) { 
 
    //download function  
 
    downloadPNGFromAnyImageSrc(svgDataUrl); 
 
    }); 
 
} 
 

 
function downloadPNGFromAnyImageSrc(src) 
 
{ 
 
    //recreate the image with src recieved 
 
    var img = new Image; 
 
    //when image loaded (to know width and height) 
 
    img.onload = function(){ 
 
    //drow image inside a canvas 
 
    var canvas = convertImageToCanvas(img); 
 
    //get image/png from convas 
 
    var pngImage = convertCanvasToImage(canvas); 
 
    //download 
 
    var anchor = document.createElement('a'); 
 
    anchor.setAttribute('href', pngImage.src); 
 
    anchor.setAttribute('download', 'image.png'); 
 
    anchor.click(); 
 
    }; 
 
    
 
    img.src = src; 
 

 

 
\t // Converts image to canvas; returns new canvas element 
 
    function convertImageToCanvas(image) { 
 
     var canvas = document.createElement("canvas"); 
 
     canvas.width = image.width; 
 
     canvas.height = image.height; 
 
     canvas.getContext("2d").drawImage(image, 0, 0); 
 
     return canvas; 
 
    } 
 
    
 
    
 
    // Converts canvas to an image 
 
    function convertCanvasToImage(canvas) { 
 
     var image = new Image(); 
 
     image.src = canvas.toDataURL("image/png"); 
 
     return image; 
 
    } 
 
} 
 

 

 

 
////// svg's generations 
 

 
////CIrcle Modeule/////// 
 
var dataset = { 
 
    apples: [53245, 28479, 19697, 24037, 40245], 
 
}; 
 

 
var width = 460, 
 
    height = 300, 
 
    radius = Math.min(width, height)/2; 
 

 
var color = d3.scale.category20(); 
 

 
var pie = d3.layout.pie() 
 
    .sort(null); 
 

 
var arc = d3.svg.arc() 
 
    .innerRadius(radius - 100) 
 
    .outerRadius(radius - 50); 
 

 
var svg = d3.select("#circle").append("svg") 
 
    .attr("width", width) 
 
    .attr("height", height) 
 
    .append("g") 
 
    .attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 
 

 
var path = svg.selectAll("path") 
 
    .data(pie(dataset.apples)) 
 
    .enter().append("path") 
 
    .attr("fill", function(d, i) { return color(i); }) 
 
    .attr("d", arc); 
 

 

 
// Table module //////////////////////////////////// 
 
var Table = function module() { 
 
    var opts = { 
 
     width: 200, 
 
     height: 200, 
 
     margins: {top: 20, right: 20, bottom: 20, left: 20} 
 
    }; 
 

 
    function exports(selection) { 
 
     selection.each(function (dataset) { 
 

 
      //________________________________________________ 
 
      // Data 
 
      //________________________________________________ 
 
      var columnLabel = dataset.columnLabel; 
 
      var rowLabel = dataset.rowLabel; 
 
      var value = dataset.value; 
 

 
      //________________________________________________ 
 
      // DOM preparation 
 
      //________________________________________________ 
 
      // Size 
 
      var chartW = Math.max(opts.width - opts.margins.left - opts.margins.right, 0.1); 
 
      var chartH = Math.max(opts.height - opts.margins.top - opts.margins.bottom, 0.1); 
 

 
      // SVG 
 
      var parentDiv = d3.select(this).html(''); 
 
      var svg = parentDiv.append('svg').attr('width', opts.width).attr('height', opts.height); 
 
      var visSvg = svg.append('g').attr('class', 'vis-group').attr('transform', 'translate(' + opts.margins.left + ',' + opts.margins.top + ')'); 
 
      var tableBodySvg = visSvg.append('g').attr('class', 'chart-group'); 
 
      var tableHeaderSvg = visSvg.append('g').attr('class', 'chart-group'); 
 
      var rowHeaderSvg = tableHeaderSvg.append('g').attr('class', 'row-header'); 
 
      var colHeaderSvg = tableHeaderSvg.append('g').attr('class', 'col-header'); 
 

 
      //________________________________________________ 
 
      // Table 
 
      //________________________________________________ 
 
      var rowHeaderLevelNum = 1; 
 
      var colHeaderLevelNum = 1; 
 
      var cellH = chartH/(value.length + rowHeaderLevelNum); 
 
      var cellW = chartW/(value[0].length + colHeaderLevelNum); 
 

 
      // Row header 
 
      var rowHeaderCell = rowHeaderSvg.selectAll('rect.row-header-cell') 
 
       .data(rowLabel); 
 
      rowHeaderCell.enter().append('rect') 
 
       .attr({ 
 
        class:'row-header-cell', 
 
        width:cellW, height:cellH, 
 
        x: 0, 
 
        y: function(d, i){return i * cellH + (cellH * colHeaderLevelNum)} 
 
       }) 
 
       .style({fill:'#eee', stroke:'silver'}); 
 

 
      // Row header text 
 
      rowHeaderCell.enter().append('text') 
 
       .attr({ 
 
        class:'row-header-content', 
 
        x: 0, 
 
        y: function(d, i){return i * cellH + (cellH * colHeaderLevelNum)}, 
 
        dx: cellW/2, 
 
        dy: cellH/2 
 
       }) 
 
       .style({fill:'black', 'text-anchor':'middle'}) 
 
       .text(function(d, i){return d;}); 
 

 
      // Col header 
 
      var colHeaderCell = colHeaderSvg.selectAll('rect.col-header-cell') 
 
       .data(columnLabel); 
 
      colHeaderCell.enter().append('rect') 
 
       .attr({ 
 
        class:'col-header-cell', 
 
        width:cellW, height:cellH, 
 
        x: function(d, i){return i * cellW + (cellW * rowHeaderLevelNum)}, 
 
        y: 0 
 
       }) 
 
       .style({fill:'#eee', stroke:'silver'}); 
 

 
      // Col header text 
 
      colHeaderCell.enter().append('text') 
 
       .attr({ 
 
        class:'col-header-content', 
 
        x: function(d, i){return i * cellW + (cellW * rowHeaderLevelNum)}, 
 
        y: 0, 
 
        dx: cellW/2, 
 
        dy: cellH/2 
 
       }) 
 
       .style({fill:'black', 'text-anchor':'middle'}) 
 
       .text(function(d, i){return d;}); 
 

 
      // Body 
 
      var row = tableBodySvg.selectAll('g.row') 
 
       .data(value); 
 
      row.enter().append('g') 
 
       .attr('class', 'cell row') 
 
       .each(function(pD, pI){ 
 
        // Cells 
 
        var cell = d3.select(this) 
 
         .selectAll('rect.cell') 
 
         .data(pD); 
 
        cell.enter().append('rect') 
 
         .attr({ 
 
          class:'cell', width:cellW, height:cellH, 
 
          x: function(d, i){return i * cellW + (cellW * rowHeaderLevelNum)}, 
 
          y: function(d, i){return pI * cellH + cellH} 
 
         }) 
 
         .style({fill:'white', stroke:'silver'}); 
 
        // Text 
 
        cell.enter().append('text') 
 
         .attr({ 
 
          class:'cell-content', width:cellW, height:cellH, 
 
          x: function(d, i){return i * cellW + (cellW * rowHeaderLevelNum)}, 
 
          y: function(d, i){return pI * cellH + cellH}, 
 
          dx: cellW/2, 
 
          dy: cellH/2 
 
         }) 
 
         .style({fill:'black', 'text-anchor':'middle'}) 
 
         .text(function(d, i){return d;}); 
 
       }); 
 
     }); 
 
    } 
 

 
    exports.opts = opts; 
 
    createAccessors(exports, opts); 
 
    return exports; 
 
}; 
 
    
 
// Helper function ////////////////////////////////////      
 
var createAccessors = function(visExport) { 
 
    for (var n in visExport.opts) { 
 
     if (!visExport.opts.hasOwnProperty(n)) continue; 
 
     visExport[n] = (function(n) { 
 
      return function(v) { 
 
       return arguments.length ? (visExport.opts[n] = v, this) : visExport.opts[n]; 
 
      } 
 
     })(n); 
 
    } 
 
};       
 
    
 
// Usage ////////////////////////////////////       
 
var dataset = { 
 
    rowLabel: ['A', 'B', 'C', 'D', 'E'], 
 
    columnLabel: ['P', 'Q', 'R', 'S'], 
 
    value: [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16], [17, 18, 19, 20]] 
 
}; 
 
         
 
var width = 400; 
 
var height = 300; 
 

 
var table = Table().width(width).height(height); 
 

 
d3.select('#table') 
 
    .datum(dataset) 
 
    .call(table);
body { 
 
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 
 
    margin: auto; 
 
    position: relative; 
 
    width: 960px; 
 
    background-color:blue; 
 
} 
 

 
text { 
 
    font: 10px sans-serif; 
 
} 
 

 
form { 
 
    position: absolute; 
 
    right: 10px; 
 
    top: 10px; 
 
}
<script src="https://mbostock.github.io/d3/d3.js"></script> 
 
<script src="https://rawgit.com/tsayen/dom-to-image/master/src/dom-to-image.js"></script> 
 
<div> 
 
Using dom-to-image.js transform anny given html to a image (svg - no quality loss)<br> 
 
    1. tansform html into svg<br> 
 
    2. drow svg inside hidden canvas<br> 
 
    3. export canvas jpg or png<br> 
 
    4. I you like donwload the thing<br> 
 
</div> 
 
<button id='downloadbody'>Download body</button> 
 
<button id='downloadcircle'>Download Circle</button> 
 
<button id='downloadtable'>Download Table</button> 
 
<div id="circle"> 
 
</div> 
 
<div id="table"> 
 
</div>

+0

Vì điều này làm cho việc sử dụng hack 'externalObject', điều này sẽ không hoạt động IE 9. Ngoài ra, điều này có rất nhiều hạn chế ngay cả trong FF và chrome. – Kaiido

0

phantomjs sẽ chuyển đổi html + svg để một hình ảnh. Nó sẽ cần phải chạy phía máy chủ như là một quá trình riêng biệt, nhưng có thể được gọi từ C#.

0

Có thể bạn có thể thử SVG2Bitmap để chuyển đổi SVG thành hình ảnh đầu tiên, sau đó sử dụng html2canvas. Đây là phương pháp được sử dụng trong số này tương tự question.

Các vấn đề liên quan