繁体   English   中英

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

[英]generate server-side google charts as images

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

但是,我有吞吐量挑战。 在我的应用程序中,我根据从 NOAA 提取的实时数据生成三个图表。 获取数据,将其整理成图表形式,然后在客户端绘制图表所花费的时间是令人无法忍受的缓慢用户体验。

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

我看着phantomjs(在推荐这个帖子),但它看起来像它的.exe文件使用,我不能上传到我的共享主机。

还有这个线程用于专有解决方案 (Highcharts),但我想在沿着 Highcharts 路径之前先探索开源替代方案。

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

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

总而言之,这是我试图拼凑起来的三个部分:

1)从第三方(在这种情况下为 NOAA)提取数据并将数据呈现为谷歌图表(完成,这里没有问题)2)将每个呈现的图表自动转换为图像,服务器端并创建图像网址 3)粘贴图像图表的 URL(会经常刷新)在呈现之前(通过 php)到网页的 html 中

PS 可以为每个图表图像设置一个静态 url ......我不是在创建图像存档......

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

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

  1. 创建一个呈现图表的网页。 它不会供公众使用,仅用于生成图表图像。
  2. 添加为每个图表调用 getImageURI() 以获取 PNG 数据的 Javascript。
  3. 使用 Ajax 在服务器上调用 PHP 脚本。 传入 PNG 数据并将其保存到文件中。
  4. 在 Watir 中编写一个脚本,只需打开浏览器并加载您的网页。
  5. 安排 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(一个无头 Chromium 浏览器)中呈现图表图像。

它既可以用作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 的完整源代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM