生成服务器端Google图表作为图像

generate server-side google charts as images

本文关键字:图像 服务器端 Google      更新时间:2023-09-26

我刚刚开始使用(新的)Google Charts api,它非常酷。我成功地使用这个api创建了图表。

然而,我有一个吞吐量挑战。在我的应用程序中,我从NOAA获取的实时数据生成了三个图表。获取数据,将其转换成图表形式,然后在客户端绘制图表所花费的时间是一种难以忍受的缓慢的用户体验。

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

我看了看phantomjs(在这篇文章中推荐),但它看起来像一个。exe文件被使用,我不能把它上传到我的共享主机。

也有一个关于专有解决方案(Highcharts)的帖子,但我想在沿着Highcharts的道路前进之前先探索一下开源的替代方案。

其他解决方案侧重于允许用户将已呈现的图表保存为图像,但我的目标是永远不要在浏览器中呈现图表,或者在页面请求时除了包含图像之外没有任何服务器加载。

我只是没有看到任何东西可以处理动态生成的图表"自动"转换成图像,在页面呈现时"自动"提供。

总之,以下是我试图拼凑起来的三个部分:

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

注:它可以有一个静态的url为每个图表图像…我不是在创建图像存档…

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

使用Watir加载网页并保存图像。Watir是一个基于ruby的测试平台,旨在测试网页。我会这样做。

  1. 创建一个呈现图表的网页。它不会是公共使用,仅用于生成图表图像。
  2. 添加Javascript,为每个图表调用getImageURI()来获取PNG数据。
  3. 使用Ajax在服务器上调用PHP脚本。传入PNG数据并保存到一个文件。在Watir中编写一个脚本,简单地打开浏览器并加载网页。
  4. 安排Watir脚本按你想要的频率运行

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作业自动化整个场景。

我刚刚发布了一个相关的开源项目Google Charts Node,它可以在Puppeteer(一个无头的chrome浏览器)中呈现图表图像。

它既可以作为NPM库使用,也可以作为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服务,可以在任何语言中使用。你可以在这里阅读更多。

例如:

// 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项目中查看生成服务器端Google Charts的完整源代码。