在PHP文件中执行Google Chart API(Javascript)

12

我正在使用WordPress插件编写PHP邮件,并且想要在邮件中包含由Google图表API创建的图片。我尝试了以下方法:

<?php
$message.= <<<HTML

      <script>
    google.charts.load('current', {
        'packages': ['corechart']
    });
    google.charts.setOnLoadCallback(drawChart);

    function drawChart() {
        var data = google.visualization.arrayToDataTable([
            ['Year', 'Sales', 'Expenses'],
            ['2013', 1000, 400],
            ['2014', 1170, 460],
            ['2015', 660, 1120],
            ['2016', 1030, 540]
        ]);

        var options = {
            title: 'Company Performance',
            hAxis: {
                title: 'Year',
                titleTextStyle: {
                    color: '#333'
                }
            },
            vAxis: {
                minValue: 0
            }
        };

        var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
        chart.draw(data, options);
    }
    </script>

    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

    HTML;   

        $message.=<<<HTML

<h1> test message </h1>
    HTML;   

    $to = "test@test.com";
    $subject = "test message";
    $headers = "test message";

    add_filter( 'wp_mail_content_type', 'set_html_content_type' );
    wp_mail( $to, $subject, $message,$headers );
    remove_filter( 'wp_mail_content_type', 'set_html_content_type' );
?>

我的问题是Javascript无法在邮件中执行。因此,我正在寻找一种在脚本内部执行Javascript的方法。

有没有建议如何在php文件中执行javascript以获取结果google-api链接的方法?

我需要一个工作示例!

PS:我的php版本是:

> php --version
PHP 5.5.9-1ubuntu4.17 (cli) (built: May 19 2016 19:05:57) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.3, Copyright (c) 1999-2014, by Zend Technologies
    with Xdebug v2.4.0, Copyright (c) 2002-2016, by Derick Rethans
4个回答

7

谷歌图表有一个本地方法(getImageURI
它创建了一个图表的base64字符串表示形式,
可以将其包含在img元素的src属性中
或保存为.png文件。

有关更多信息,请参见Printing PNG Charts

此外,在抓取图像之前,应等待图表的'ready'事件触发。
要发送电子邮件中的图表图像,建议先创建绘制图表的页面
然后当'ready'事件触发时,通过ajax将图像字符串发送到发送电子邮件的控制器...

请查看以下代码片段以获取示例图像:

google.charts.load('current', {
  callback: function () {
    var data = google.visualization.arrayToDataTable([
      ['Year', 'Sales', 'Expenses'],
      ['2013',  1000,      400],
      ['2014',  1170,      460],
      ['2015',  660,       1120],
      ['2016',  1030,      540]
    ]);

    var options = {
      title: 'Company Performance',
      hAxis: {title: 'Year',  titleTextStyle: {color: '#333'}},
      vAxis: {minValue: 0},
      legend: {
        position: 'top'
      }
    };

    var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
    google.visualization.events.addListener(chart, 'ready', function () {
      document.getElementById('image_div').innerHTML = '<img src="' + chart.getImageURI() + '" />';
    });
    chart.draw(data, options);
  },
  packages: ['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div>Chart</div>
<div id="chart_div"></div>
<div>Image</div>
<div id="image_div"></div>

编辑

从上面的例子中可以看出,当图表的 'ready' 事件触发时,
通过 ajax post 将图像字符串发送回同一页面。

然后在 php 中,检查是否接收到了图像。

如果接收到了图像,则发送电子邮件;否则绘制图表。

以下是工作流程的基本示例...

<?php
  if(isset($_POST['chartImage'])) {
    $to = "test@test.com";
    $subject = "test message";
    $headers = "test message";
    $message = $_POST['chartImage'];

    add_filter( 'wp_mail_content_type', 'set_html_content_type' );
    wp_mail( $to, $subject, $message, $headers );
    remove_filter( 'wp_mail_content_type', 'set_html_content_type' );
  } else {
?>
  <script>
    google.charts.load('current', {
      callback: function () {
        var data = google.visualization.arrayToDataTable([
          ['Year', 'Sales', 'Expenses'],
          ['2013',  1000,      400],
          ['2014',  1170,      460],
          ['2015',  660,       1120],
          ['2016',  1030,      540]
        ]);

        var options = {
          title: 'Company Performance',
          hAxis: {title: 'Year',  titleTextStyle: {color: '#333'}},
          vAxis: {minValue: 0},
          legend: {
            position: 'top'
          }
        };

        var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
        google.visualization.events.addListener(chart, 'ready', function () {
          // send chart image
          $.ajax({
            type: 'POST',
            url: 'mail.php',
            data: {
              'chartImage': chart.getImageURI(),
            },
            success: function(){
              console.log('email sent');
            }
          });
        });
        chart.draw(data, options);
      },
      packages: ['corechart']
    });
  </script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  <script src="https://www.gstatic.com/charts/loader.js"></script>
  <div id="chart_div"></div>
<?php
  }
?>

谢谢您的回答!您有什么建议可以告诉我如何在我的 PHP 文件中创建这个“隐形”页面吗? - Carol.Kar
1
你有邮件 PHP 的例子吗?建议创建一个绘制图表的页面,当图表的 'ready' 事件触发时,通过 ajax 将图像字符串发送回 PHP 继续发送电子邮件。 - WhiteHat
非常感谢您的回复!请查看我上面更新的答案。 - Carol.Kar
请参见__EDIT__,以更好地阐述工作流程... - WhiteHat

6

虽然不完全是使用Google图表API的用法,但这可能确实对您有所帮助。

Google还拥有他们的Image Charts(已经被弃用,但他们表示没有关闭它的计划)。您可以使用Image Charts生成所需的图形并获得返回的图像。

我使用数据生成了这张图片:

enter image description here

可以使用 this link 生成。

我知道这不完全是与图表API相同的图形(它们的图像图表缺少一些很棒的东西,比如透明度等),但它可能是您正在寻找的快速解决方案。

还有一个实时片段:

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script>
    google.charts.load('current', {
        'packages': ['corechart']
    });
    google.charts.setOnLoadCallback(drawChart);

    function drawChart() {
        var data = google.visualization.arrayToDataTable([
            ['Year', 'Sales', 'Expenses'],
            ['2013', 1000, 400],
            ['2014', 1170, 460],
            ['2015', 660, 1120],
            ['2016', 1030, 540]
        ]);

        var options = {
            title: 'Company Performance',
            hAxis: {
                title: 'Year',
                titleTextStyle: {
                    color: '#333'
                }
            },
            vAxis: {
                minValue: 0
            }
        };

        var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
        chart.draw(data, options);
    }
</script>
<div id="chart_div"></div> 
<img src="https://chart.googleapis.com/chart?cht=lc&chd=t:1000,1170,660,1030|400,460,1120,540&chds=a&chxr=1,0,1200,300&chxt=x,y&chxl=0:|2013|2014|2015|2016&chs=600x200&chm=B,c2d1f0,0,0,0|B,f5c4b8,1,1,0&chtt=Company%20Performance&chts=000000,20,l&chdl=Sales|Expenses&chco=0000FF,FF0000">


5

我真的很喜欢这个想法!您能否友好地展示一个工作的PHP示例?赏金将在近23小时后结束。 - Carol.Kar

5
你可以使用canvas2html.js来将图表导出为数据URI
<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <script src="canvas2html.js"></script>
  <div id="chart_div"></div>
  <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js">
  </script>
  <script type="text/javascript">
    google.charts.load('current', {
      'packages': ['corechart']
    });
    google.charts.setOnLoadCallback(drawChart);

    function drawChart() {
      var data = google.visualization.arrayToDataTable([
        ['Year', 'Sales', 'Expenses'],
        ['2013', 1000, 400],
        ['2014', 1170, 460],
        ['2015', 660, 1120],
        ['2016', 1030, 540]
      ]);

      var options = {
        title: 'Company Performance',
        hAxis: {
          title: 'Year',
          titleTextStyle: {
            color: '#333'
          }
        },
        vAxis: {
          minValue: 0
        }
      };

      var chart = new google.visualization
                 .AreaChart(document.getElementById('chart_div'));
      chart.draw(data, options);
      html2canvas(document.getElementById('chart_div'))
        .then(function(canvas) {
          var dataURL = canvas.toDataURL();
          // `dataURL` : `data URI` of chart drawn on `<canvas>` element
          console.log(dataURL);
        })
    }
  </script>
</body>

</html>

plnkr http://plnkr.co/edit/WPeiFuSdFIYP9297yHYN?p=preview

这句话的意思是:在这个段落中包含一个名为“plnkr”的链接,链接地址为http://plnkr.co/edit/WPeiFuSdFIYP9297yHYN?p=preview。

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Carol.Kar
1
需要等待'ready'事件,否则可能会出现空白画布。 - WhiteHat
@mrquad 你可以将 canvasdata URI 发送到 php - guest271314

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接