[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 736
  • Last Modified:

save Google Visualization chart as image

I am building an application that needs to capture Google Visualization Charts and save them as images to a server so they can be used in a report. I was able to find a solution at http://www.battlehorse.net/page/topics/charts/save_google_charts_as_image.html which uses javascript and canvas to extract image data. This solution worked fine on localhost but as soon as I put the page on the Web Server it comes up with an error "canvg is undefined". I have searched quite a bit and have not been able to find any resolutions to this error. I would prefer to do something server side if possible to capture the chart as an image but I have not seen any samples where this is possible. Can anyone recommend a solution to the "canvg" error I am receiving or offer a .Net solution to capturing the Visualization Charts?

javascript catch error
<%@ Page Language="VB" ContentType="text/html" ResponseEncoding="iso-8859-1" %>

<script runat="server">           
Sub Page_Load(Src As Object, E As EventArgs)
	Dim loggedIn As Integer=0	
	IF NOT IsPostBack THEN						
            If loggedIn = 1 Then
                                
                Try
                   
                Catch exc As Exception
                    lblError.Text = exc.ToString() & "<br />"				                
                   
                End Try
            Else
                lblError.Text = ""
            End If
        End If
	
    End Sub                                         
    
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Test</title>
<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>
    <script type="text/javascript">
        function getImgData(chartContainer) {
            var chartArea = chartContainer.getElementsByTagName('svg')[0].parentNode;
            var svg = chartArea.innerHTML;
            var doc = chartContainer.ownerDocument;
            var canvas = doc.createElement('canvas');
            canvas.setAttribute('width', chartArea.offsetWidth);
            canvas.setAttribute('height', chartArea.offsetHeight);


            canvas.setAttribute(
            'style',
            'position: absolute; ' +
            'top: ' + (-chartArea.offsetHeight * 2) + 'px;' +
            'left: ' + (-chartArea.offsetWidth * 2) + 'px;');
            doc.body.appendChild(canvas);
            canvg(canvas, svg);
            var imgData = canvas.toDataURL("image/png");
            canvas.parentNode.removeChild(canvas);
            return imgData;
        }                               

        function alert10() {
            try {
                textbox1 = document.getElementById('textbox1');
                textbox1.innerHTML = getImgData(document.getElementById('chart1_div'));
            }
            catch (err) {
                alert(err.message);
            }            
        }                        
    </script>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
        google.load("visualization", "1", { packages: ["corechart", "treemap", "geochart"] });
        google.setOnLoadCallback(drawChart);
        function drawChart() {

            var data;
            var chart;


            document.getElementById('chart1_div').scrollIntoView();

            chartTitle = 'Regular & REO Average Sold Price';

            xColumn = 'Quarter';
            yColumn = 'Avg Sold Price';
            zColumn = 'Smoothed';
            yTitle = 'Price in Thousands';
            chart = new google.visualization.LineChart(document.getElementById('chart1_div'));
            legendType = 'none';

            data = new google.visualization.DataTable();

            data.addColumn('string', xColumn);
            data.addColumn('number', yColumn);
            data.addColumn('number', zColumn);

            data.addRows(35);

            data.setValue(0, 0, '2005-Q1');
            data.setValue(0, 1, 288 + 0);

            data.setValue(1, 0, '2005-Q2');
            data.setValue(1, 1, 285 + 0);

            data.setValue(2, 0, '2005-Q3');
            data.setValue(2, 1, 315 + 0);

            data.setValue(3, 0, '2005-Q4');
            data.setValue(3, 1, 318 + 0);

            data.setValue(4, 0, '2006-Q1');
            data.setValue(4, 1, 310 + 0);

            data.setValue(5, 0, '2006-Q2');
            data.setValue(5, 1, 286 + 0);

            data.setValue(6, 0, '2006-Q3');
            data.setValue(6, 1, 299 + 0);

            data.setValue(7, 0, '2006-Q4');
            data.setValue(7, 1, 278 + 0);

            data.setValue(8, 0, '2007-Q1');
            data.setValue(8, 1, 283 + 0);

            data.setValue(9, 0, '2007-Q2');
            data.setValue(9, 1, 278 + 0);

            data.setValue(10, 0, '2007-Q3');
            data.setValue(10, 1, 287 + 0);

            data.setValue(11, 0, '2007-Q4');
            data.setValue(11, 1, 260 + 0);

            data.setValue(12, 0, '2008-Q1');
            data.setValue(12, 1, 299 + 0);

            data.setValue(13, 0, '2008-Q2');
            data.setValue(13, 1, 273 + 0);

            data.setValue(14, 0, '2008-Q3');
            data.setValue(14, 1, 259 + 0);

            data.setValue(15, 0, '2008-Q4');
            data.setValue(15, 1, 231 + 0);

            data.setValue(16, 0, '2009-Q1');
            data.setValue(16, 1, 233 + 0);

            data.setValue(17, 0, '2009-Q2');
            data.setValue(17, 1, 244 + 0);

            data.setValue(18, 0, '2009-Q3');
            data.setValue(18, 1, 234 + 0);

            data.setValue(19, 0, '2009-Q4');
            data.setValue(19, 1, 219 + 0);

            data.setValue(20, 0, '2010-Q1');
            data.setValue(20, 1, 235 + 0);

            data.setValue(21, 0, '2010-Q2');
            data.setValue(21, 1, 236 + 0);

            data.setValue(22, 0, '2010-Q3');
            data.setValue(22, 1, 207 + 0);

            data.setValue(23, 0, '2010-Q4');
            data.setValue(23, 1, 210 + 0);

            data.setValue(24, 0, '2011-Q1');
            data.setValue(24, 1, 184 + 0);

            data.setValue(25, 0, '2011-Q2');
            data.setValue(25, 1, 188 + 0);

            data.setValue(26, 0, '2011-Q3');
            data.setValue(26, 1, 202 + 0);

            data.setValue(27, 0, '2011-Q4');
            data.setValue(27, 1, 186 + 0);

            data.setValue(28, 0, '2012-Q1');
            data.setValue(28, 1, 204 + 0);

            data.setValue(29, 0, '2012-Q2');
            data.setValue(29, 1, 237 + 0);

            data.setValue(30, 0, '2012-Q3');
            data.setValue(30, 1, 185 + 0);

            data.setValue(31, 0, '2012-Q4');
            data.setValue(31, 1, 195 + 0);

            data.setValue(32, 0, '2013-Q1');
            data.setValue(32, 1, 196 + 0);

            data.setValue(33, 0, '2013-Q2');
            data.setValue(33, 1, 225 + 0);

            data.setValue(34, 0, '2013-Q3');
            data.setValue(34, 1, 218 + 0);

            data.setValue(0, 2, 302 + 0);

            data.setValue(1, 2, 301 + 0);

            data.setValue(2, 2, 301 + 0);

            data.setValue(3, 2, 300 + 0);

            data.setValue(4, 2, 298 + 0);

            data.setValue(5, 2, 296 + 0);

            data.setValue(6, 2, 293 + 0);

            data.setValue(7, 2, 290 + 0);

            data.setValue(8, 2, 286 + 0);

            data.setValue(9, 2, 282 + 0);

            data.setValue(10, 2, 278 + 0);

            data.setValue(11, 2, 274 + 0);

            data.setValue(12, 2, 269 + 0);

            data.setValue(13, 2, 263 + 0);

            data.setValue(14, 2, 257 + 0);

            data.setValue(15, 2, 251 + 0);

            data.setValue(16, 2, 245 + 0);

            data.setValue(17, 2, 239 + 0);

            data.setValue(18, 2, 233 + 0);

            data.setValue(19, 2, 227 + 0);

            data.setValue(20, 2, 222 + 0);

            data.setValue(21, 2, 217 + 0);

            data.setValue(22, 2, 212 + 0);

            data.setValue(23, 2, 208 + 0);

            data.setValue(24, 2, 205 + 0);

            data.setValue(25, 2, 202 + 0);

            data.setValue(26, 2, 201 + 0);

            data.setValue(27, 2, 200 + 0);

            data.setValue(28, 2, 201 + 0);

            data.setValue(29, 2, 201 + 0);

            data.setValue(30, 2, 203 + 0);

            data.setValue(31, 2, 204 + 0);

            data.setValue(32, 2, 206 + 0);

            data.setValue(33, 2, 209 + 0);

            data.setValue(34, 2, 211 + 0);


            chart.draw(data,
                     { title: chartTitle
                     , vAxis: { title: yTitle }
                     , width: 300, height: 300
                     , hAxis: { slantedText: true, slantedTextAngle: 90, textStyle: { fontSize: 10} }
                     , curveType: 'function', lineWidth: 1, pointSize: 1, legend: 'none'
                     , legend: legendType

                     });                        
        }
    </script>
</head>
<body text="black" alink="blue" vlink="purple" link="blue" topmargin="0" leftmargin="0" MARGINWIDTH="0" MARGINHEIGHT="0">
<form runat="server" style="width:100%;" id="form1" name="form1" >
<div id="header" style="display:none;"><MenuDisplay:Menu id="menuDisplay01" runat="server" /></div>
<asp:Label ID="lblWelcome" runat="server" />
<br />
<asp:Label ID="lblError" runat="server" />
    <div id="chart1_div"></div>              
    <br />
    <textarea  id="textbox1" name="textbox1" rows="4" cols="50"></textarea>
    <br />    
    <button onclick="alert10();">Test</button>
    
	
</form>
</body>
</html>

Open in new window

0
cwarr
Asked:
cwarr
  • 3
  • 2
1 Solution
 
Rainer JeschorCommented:
Hi,
is your site running with SSL enabled?
Meaning you open your website with https ...
0
 
cwarrAuthor Commented:
Yes, our website is running with SSL enabled.
0
 
Rainer JeschorCommented:
Hi,
then you might try to adjust your external script file references to either use also https OR the better way to use it protocol relative like this:
<%@ Page Language="VB" ContentType="text/html" ResponseEncoding="iso-8859-1" %>

<script runat="server">           
Sub Page_Load(Src As Object, E As EventArgs)
	Dim loggedIn As Integer=0	
	IF NOT IsPostBack THEN						
            If loggedIn = 1 Then
                                
                Try
                   
                Catch exc As Exception
                    lblError.Text = exc.ToString() & "<br />"				                
                   
                End Try
            Else
                lblError.Text = ""
            End If
        End If
	
    End Sub                                         
    
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="//canvg.googlecode.com/svn/trunk/rgbcolor.js"></script> 
    <script type="text/javascript" src="//canvg.googlecode.com/svn/trunk/canvg.js"></script>
    <script type="text/javascript">
        function getImgData(chartContainer) {
            var chartArea = chartContainer.getElementsByTagName('svg')[0].parentNode;
            var svg = chartArea.innerHTML;
            var doc = chartContainer.ownerDocument;
            var canvas = doc.createElement('canvas');
            canvas.setAttribute('width', chartArea.offsetWidth);
            canvas.setAttribute('height', chartArea.offsetHeight);


            canvas.setAttribute(
            'style',
            'position: absolute; ' +
            'top: ' + (-chartArea.offsetHeight * 2) + 'px;' +
            'left: ' + (-chartArea.offsetWidth * 2) + 'px;');
            doc.body.appendChild(canvas);
            canvg(canvas, svg);
            var imgData = canvas.toDataURL("image/png");
            canvas.parentNode.removeChild(canvas);
            return imgData;
        }                               

        function alert10() {
            try {
                textbox1 = document.getElementById('textbox1');
                textbox1.innerHTML = getImgData(document.getElementById('chart1_div'));
            }
            catch (err) {
                alert(err.message);
            }            
        }                        
    </script>
    <script type="text/javascript" src="//www.google.com/jsapi"></script>
    <script type="text/javascript">
        google.load("visualization", "1", { packages: ["corechart", "treemap", "geochart"] });
        google.setOnLoadCallback(drawChart);
        function drawChart() {

            var data;
            var chart;


            document.getElementById('chart1_div').scrollIntoView();

            chartTitle = 'Regular & REO Average Sold Price';

            xColumn = 'Quarter';
            yColumn = 'Avg Sold Price';
            zColumn = 'Smoothed';
            yTitle = 'Price in Thousands';
            chart = new google.visualization.LineChart(document.getElementById('chart1_div'));
            legendType = 'none';

            data = new google.visualization.DataTable();

            data.addColumn('string', xColumn);
            data.addColumn('number', yColumn);
            data.addColumn('number', zColumn);

            data.addRows(35);

            data.setValue(0, 0, '2005-Q1');
            data.setValue(0, 1, 288 + 0);

            data.setValue(1, 0, '2005-Q2');
            data.setValue(1, 1, 285 + 0);

            data.setValue(2, 0, '2005-Q3');
            data.setValue(2, 1, 315 + 0);

            data.setValue(3, 0, '2005-Q4');
            data.setValue(3, 1, 318 + 0);

            data.setValue(4, 0, '2006-Q1');
            data.setValue(4, 1, 310 + 0);

            data.setValue(5, 0, '2006-Q2');
            data.setValue(5, 1, 286 + 0);

            data.setValue(6, 0, '2006-Q3');
            data.setValue(6, 1, 299 + 0);

            data.setValue(7, 0, '2006-Q4');
            data.setValue(7, 1, 278 + 0);

            data.setValue(8, 0, '2007-Q1');
            data.setValue(8, 1, 283 + 0);

            data.setValue(9, 0, '2007-Q2');
            data.setValue(9, 1, 278 + 0);

            data.setValue(10, 0, '2007-Q3');
            data.setValue(10, 1, 287 + 0);

            data.setValue(11, 0, '2007-Q4');
            data.setValue(11, 1, 260 + 0);

            data.setValue(12, 0, '2008-Q1');
            data.setValue(12, 1, 299 + 0);

            data.setValue(13, 0, '2008-Q2');
            data.setValue(13, 1, 273 + 0);

            data.setValue(14, 0, '2008-Q3');
            data.setValue(14, 1, 259 + 0);

            data.setValue(15, 0, '2008-Q4');
            data.setValue(15, 1, 231 + 0);

            data.setValue(16, 0, '2009-Q1');
            data.setValue(16, 1, 233 + 0);

            data.setValue(17, 0, '2009-Q2');
            data.setValue(17, 1, 244 + 0);

            data.setValue(18, 0, '2009-Q3');
            data.setValue(18, 1, 234 + 0);

            data.setValue(19, 0, '2009-Q4');
            data.setValue(19, 1, 219 + 0);

            data.setValue(20, 0, '2010-Q1');
            data.setValue(20, 1, 235 + 0);

            data.setValue(21, 0, '2010-Q2');
            data.setValue(21, 1, 236 + 0);

            data.setValue(22, 0, '2010-Q3');
            data.setValue(22, 1, 207 + 0);

            data.setValue(23, 0, '2010-Q4');
            data.setValue(23, 1, 210 + 0);

            data.setValue(24, 0, '2011-Q1');
            data.setValue(24, 1, 184 + 0);

            data.setValue(25, 0, '2011-Q2');
            data.setValue(25, 1, 188 + 0);

            data.setValue(26, 0, '2011-Q3');
            data.setValue(26, 1, 202 + 0);

            data.setValue(27, 0, '2011-Q4');
            data.setValue(27, 1, 186 + 0);

            data.setValue(28, 0, '2012-Q1');
            data.setValue(28, 1, 204 + 0);

            data.setValue(29, 0, '2012-Q2');
            data.setValue(29, 1, 237 + 0);

            data.setValue(30, 0, '2012-Q3');
            data.setValue(30, 1, 185 + 0);

            data.setValue(31, 0, '2012-Q4');
            data.setValue(31, 1, 195 + 0);

            data.setValue(32, 0, '2013-Q1');
            data.setValue(32, 1, 196 + 0);

            data.setValue(33, 0, '2013-Q2');
            data.setValue(33, 1, 225 + 0);

            data.setValue(34, 0, '2013-Q3');
            data.setValue(34, 1, 218 + 0);

            data.setValue(0, 2, 302 + 0);

            data.setValue(1, 2, 301 + 0);

            data.setValue(2, 2, 301 + 0);

            data.setValue(3, 2, 300 + 0);

            data.setValue(4, 2, 298 + 0);

            data.setValue(5, 2, 296 + 0);

            data.setValue(6, 2, 293 + 0);

            data.setValue(7, 2, 290 + 0);

            data.setValue(8, 2, 286 + 0);

            data.setValue(9, 2, 282 + 0);

            data.setValue(10, 2, 278 + 0);

            data.setValue(11, 2, 274 + 0);

            data.setValue(12, 2, 269 + 0);

            data.setValue(13, 2, 263 + 0);

            data.setValue(14, 2, 257 + 0);

            data.setValue(15, 2, 251 + 0);

            data.setValue(16, 2, 245 + 0);

            data.setValue(17, 2, 239 + 0);

            data.setValue(18, 2, 233 + 0);

            data.setValue(19, 2, 227 + 0);

            data.setValue(20, 2, 222 + 0);

            data.setValue(21, 2, 217 + 0);

            data.setValue(22, 2, 212 + 0);

            data.setValue(23, 2, 208 + 0);

            data.setValue(24, 2, 205 + 0);

            data.setValue(25, 2, 202 + 0);

            data.setValue(26, 2, 201 + 0);

            data.setValue(27, 2, 200 + 0);

            data.setValue(28, 2, 201 + 0);

            data.setValue(29, 2, 201 + 0);

            data.setValue(30, 2, 203 + 0);

            data.setValue(31, 2, 204 + 0);

            data.setValue(32, 2, 206 + 0);

            data.setValue(33, 2, 209 + 0);

            data.setValue(34, 2, 211 + 0);


            chart.draw(data,
                     { title: chartTitle
                     , vAxis: { title: yTitle }
                     , width: 300, height: 300
                     , hAxis: { slantedText: true, slantedTextAngle: 90, textStyle: { fontSize: 10} }
                     , curveType: 'function', lineWidth: 1, pointSize: 1, legend: 'none'
                     , legend: legendType

                     });                        
        }
    </script>
</head>
<body text="black" alink="blue" vlink="purple" link="blue" topmargin="0" leftmargin="0" MARGINWIDTH="0" MARGINHEIGHT="0">
<form runat="server" style="width:100%;" id="form1" name="form1" >
<div id="header" style="display:none;"><MenuDisplay:Menu id="menuDisplay01" runat="server" /></div>
<asp:Label ID="lblWelcome" runat="server" />
<br />
<asp:Label ID="lblError" runat="server" />
    <div id="chart1_div"></div>              
    <br />
    <textarea  id="textbox1" name="textbox1" rows="4" cols="50"></textarea>
    <br />    
    <button onclick="alert10();">Test</button>
    
	
</form>
</body>
</html>

Open in new window


HTH
Rainer
0
 
Rainer JeschorCommented:
Additional info:
your chart worked as you referenced the script library using https - but not for the canvas stuff. This results in a mixed security context (both https and http resources) which could cause issues in the browsers.

Using the protocol relative path like "//..." would work then both in HTTP and HTTPS

HTH
Rainer
0
 
cwarrAuthor Commented:
This worked like a charm. I can't believe it was something so simple. Thank you for all of your help.
0

Featured Post

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now