生成服务器端谷歌图表作为图像

时间:2014-06-03 20:45:51

标签: javascript php image charts google-visualization

我刚刚开始使用(新)Google Charts api,而且很酷。我使用这个api成功创建了图表。

然而,我遇到了吞吐量挑战。在我的应用程序中,我从NOAA中提取的实时数据生成三个图表。获取数据所需的时间,将其按到图表形式然后在客户端绘制图表是一种无法忍受的缓慢用户体验。

所以我的想法是在(托管)服务器上定期生成图表(每15-30分钟),然后只为访问者提供最新图像。

我查看了phantomjs(正如this post中所推荐的那样),但它看起来像是一个.exe文件,我无法将其上传到我的共享主机。

专有解决方案(Highcharts)也有this thread,但我想在沿着Highcharts路径前先探索开源替代方案。

其他解决方案专注于允许用户将渲染图表保存为图像,但我的目标是永远不会在浏览器中渲染图表,或者除了在页面请求时包含图像之外还有任何服务器负载。

我还没有看到任何处理动态生成的图表的内容,这些图表会“自动”转换为在呈现页面时“自动”提供的图像。

总之,以下是我想要拼凑的三件作品:

1)从第三方(本例中为NOAA)提取数据并将数据呈现为Google Chart(已完成,此处没有问题) 2)自动将每个渲染图表转换为图像,服务器端和创建图像URL 3)在渲染之前(通过php)将图表的图像URL(将经常刷新)粘贴到网页的html中

P.S。可以为每个图表图像设置一个静态URL ...我不是在创建图像存档...

有什么建议吗?我错过了什么吗?

2 个答案:

答案 0 :(得分:0)

使用Watir加载网页并保存图像。 Watir是一个基于Ruby的测试平台,旨在测试网页。我会做以下几点。

  1. 创建一个呈现图表的网页。它不适合 公共使用,仅用于生成图表图像。
  2. 为每个图表添加调用getImageURI()的Javascript以获取 PNG数据。
  3. 使用Ajax在服务器上调用PHP脚本。传入PNG数据 并将其保存到文件中。
  4. 在Watir中编写一个脚本,只需打开一个浏览器并加载你的 网页。
  5. 安排Watir脚本按照您的意愿运行。
  6. Watir脚本可以在任何本地计算机(PC或Mac)上运行,甚至可以在服务器上运行。

    这是通过Ajax将PNG数据发送到PHP脚本的Javascript。它只是获取图像数据并发送它的片段,而不是完整的解决方案。

    // Instantiate and draw our chart, passing in some options.
    var chart = new google.visualization.PieChart(chartDiv);
    // Wait for the chart to finish drawing before calling the getImageURI() method.
    google.visualization.events.addListener(chart, 'ready', function () {
        pieDone=1;
        piePNG=chart.getImageURI();
        saveChartPNGs(piePNG); 
    });
    chart.draw(data, options);
    
    function saveChartPNGs(png)
    {
      var jsonSavePNG = $.ajax({
        type: "POST",
        url: pngSaveUrl,
        dataType:"json",
        data: 'png=' + png
      }).done();
    }
    

    此PHP代码处理Ajax调用并保存文件。

    if (isset($_REQUEST['png']))
    {
        // Remove header string
        $data=str_replace('data:image/png;base64,','',$_REQUEST['png']);
        // Restore data to original format; convert space to '+'
        $data=str_replace(' ','+',$data);
        // Save PNG file
        $outFile=DOC_ROOT.'/atest.png';
        // Decode base 64 before saving
        $fres=file_put_contents($outFile, base64_decode($data));
    }
    

    在本地计算机上,Watir脚本(实际用Ruby编写)很简单。

    # Load watir
    require 'watir-webdriver'
    require "watir-webdriver/extensions/alerts"
    
    # Launch the browser; common choices: chrome, firefox, ie.
    # Headless browsers are available.
    browser = Watir::Browser.new :chrome # chrome browser window
    
    # Load the web page
    browser.goto 'http://domain.net/page/'
    

    为了完全自动化Watir方面,我会编写图表渲染网页,以便在完成保存文件后加载新页面。您可以在浏览器中检查该页面的Watir,然后退出,直到它再次执行。

    如果您可以安排在服务器上安装Ruby,Watir和浏览器,那么您可以使用cron作业自动执行整个场景。

答案 1 :(得分:0)

我刚刚发布了一个相关的开源项目Google Charts Node,该项目可以在无头的Chromium浏览器Puppeteer中渲染图表图像。

它可以用作NPM library或Web服务。这是使用NPM库的示例:

const GoogleChartsNode = require('google-charts-node');

function drawChart() {
  // Set up your chart here, just like in the browser
  // ...

  const chart = new google.visualization.BarChart(container);
  chart.draw(data, options);
}

// Render the chart to image
const image = await GoogleChartsNode.render(drawChart);

您的问题被标记为PHP,因此我将注意,它也可以作为托管Web服务提供,可以以任何语言使用。您可以阅读更多here

例如:

// Generate the image
$url = 'https://quickchart.io/google-charts/render';
$data = array(
  'width' => 600,
  'height' => 300,
  'packages' => array('gannt'),
  'code' => 'function drawChart() {...}'
);

$postdata = json_encode($data);

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$result = curl_exec($ch);
curl_close($ch);

// Write it to file
$fp = fopen('/tmp/image.png','x');
fwrite($fp, $raw);
fclose($fp);

现在,您可以将此image缓冲区另存为文件或作为HTTP响应返回,等等。

主要警告:

  1. 并非所有图表都支持getImageURI,因此该库使puppeteer可以在发生这种情况时对其进行截图。
  2. 很慢!但是,如果必须使用Google Charts作为必需项,那么您实际上没有其他选择。如果您能够切换图表库,建议您通过QuickChart使用Chart.js这样的开放格式。

您可以在Github project上查看用于生成服务器端Google图表的完整源。