2013-03-26 135 views
4

這是一個特定的問題,但我想如果我能找到解決方案,它可能在某些時候對別人有用。highcharts和canvg縮放問題

我需要將我的一些Highcharts圖轉換成瀏覽器端的PNG。這個想法是,當我們的作者創建一個圖形時,它會自動轉換爲PNG,並且該PNG將與給定圖形的JS代碼一起保存。然後,我們可以在JS無法選擇的情況下提供該PNG版本。我已經通過canvg庫完成了所有工作,而且非常完美。

好吧,差不多。由於所有高分辨率屏幕都存在,我們希望PNG的放大倍數可以像圖表正常顯示的一樣大。這樣,PNG版本可以在iPhone/iPad等上看起來不錯...

canvg有一些縮放選項,所以我試圖使用這些。但那就是它開始崩潰的地方。該圖形正確縮放,但Highcharts對象中有一個框不會與其他所有對象一起縮放,而生成的縮放圖只顯示精美縮放圖的左上角。

我看了一下canvg代碼,很快就意識到我的JS能力不足以說明發生了什麼,對於Highcharts來說同樣的事情。

如果任何人有想法或知道這個簡單的解決方案,我會非常感激。

複製的問題,您可以在此的jsfiddle例如我放在一起看看:

http://jsfiddle.net/UVNvh/3/

而這裏如果頁面的jsfiddle被搞砸或莫名其妙消失的代碼。

<script src="http://code.highcharts.com/highcharts.js">http://code.highcharts.com/highcharts.js</script> 
<script src="http://code.highcharts.com/modules/exporting.js"></script> 
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script> 
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script> 
<p>Highcharts</p> 
<div id="container" style="height: 400px; margin-top: 1em"></div> 
<p>Canvas</p> 
<canvas id="canvas"></canvas> 
<p>Image</p> 
<div id="image"><div> 

<script type="text/javascript"> 
$(function() { 
    var chart = new Highcharts.Chart({ 

     chart: { 
      renderTo: 'container' 
     }, 

     credits: { 
      enabled: false 
     }, 

     xAxis: { 
      categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] 
     }, 

     series: [{ 
      data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]   
     }], 

     navigation: { 
      buttonOptions: { 
       enabled: false 
      } 
     }, 
     exporting: { 
      type: 'image/jpeg' 
     } 

    }); 

    var chart_svg = chart.getSVG();      
    var chart_canvas = document.getElementById('canvas'); 

    canvg(chart_canvas, chart_svg, {scaleWidth: 1280, scaleHeight: 860}); 

    var chart_img = chart_canvas.toDataURL('image/png'); 

    jQuery('#image').append('<img src="' + chart_img + '" />'); 
}); 
</script> 

回答

5

聽起來好像您正在使用某種管理工具,因此更改圖表大小可能不是問題。在調用getSVG()之前,您應該使用chart.setSize(width,height)。

如果你不能走這條路,你也可以直接編輯SVG文本,但在我看來這不是最佳實踐。

Canvg的工作方式似乎是採用scaleWidth/scaleHeight,並根據您傳遞的選項和svg的現有高度/寬度向svg添加transform =「scale()」。問題是它不會改變svg和最終圖像的現有高度/寬度。我把一個jsfiddle放在一起,做我認爲你想要的,但它可能不是最好的解決方案。 http://jsfiddle.net/sgearhart2/EsPud/1/

var chart_svg = chart.getSVG();      
chart_svg = chart_svg.replace('width="600"', 'width="1280"'); 
chart_svg = chart_svg.replace('height="400"', 'height="860"'); 

// If i had to guess, canvg does the next part but not the prior part 
var dWidth = 1280/600, dHeight = 860/400; 
chart_svg = chart_svg.replace(
    '<svg ', 
    '<svg transform="scale(' + dWidth + ' ' + dHeight + ')" ' 
); 
+0

斯科特,這正是我想做的事。最好的解決方案或不,它的作品。 :)出於某種原因,我沒有想到在svg對象上引起問題的明確高度/寬度。 – 2013-03-26 20:51:03

+0

而且要清楚。謝謝! – 2013-03-26 20:52:42

7

我提高斯科特·吉爾哈特沒有黑客:) http://jsfiddle.net/marcalj/EsPud/7/

最重要的部分:

// Get chart aspect ratio 
var c_ar = chart.chartHeight/chart.chartWidth; 

// Set canvas size 
chart_canvas.width = 1280; 
chart_canvas.height = chart_canvas.width * c_ar; 

canvg(chart_canvas, chart_svg, { 
    ignoreDimensions: true, 
    scaleWidth: chart_canvas.width, 
    scaleHeight: chart_canvas.height 
}); 

確保您設置圖表元素上固定的寬度和高度。

1

與今天(2016年)一樣,通過將參數傳遞到getSVG()函數,我可以使畫布使用正確尺寸的圖表。

作爲例子:

var chartSVG = chart.highcharts().getSVG({ 
     exporting: { 
      sourceHeight: chart.highcharts().chartHeight, 
      sourceWidth: chart.highcharts().chartWidth, 
     } 
    });