为了账号安全,请及时绑定邮箱和手机立即绑定

使用 Puppeteer 渲染谷歌图表

使用 Puppeteer 渲染谷歌图表

慕娘9325324 2021-12-02 10:20:37
我正在尝试找出将 Puppeteer 和 GoogleCharts 库结合起来以呈现条形图并导出图表的 PNG 图像的正确方法。主要受 Puppeteer 文档启发的基本布局似乎是这样的,用于创建一个带有画布元素的新页面。(async () => {    const browser = await puppeteer.launch();    const page = await browser.newPage();    await page.setContent(`            <!DOCTYPE html>                <html>                    <body>                        <canvas id="chart" width="580" height="400"></canvas>                    </body>                </html>            `);    await browser.close();})();我发现这个 npm 包可以与 Google Charts 一起使用:https : //www.npmjs.com/package/google-charts。该chart.draw方法似乎接受一个 DOM 元素,它将在其中呈现图表。根据这个包的文档,用法看起来很简单。const pie_1_chart = new GoogleCharts.api.visualization.PieChart(document.getElementById('chart1'));pie_1_chart.draw(data);如何执行 draw 方法,以便它#canvas在 Puppeteer 页面的DOM 元素内呈现图表?另外,如果您能给我一个将页面/画布导出为 PNG 图像的正确方法的示例,我将不胜感激。注意:我浏览了很多东西以找到一个现有的库/包,它可以完成我想要实现的目标,但我能找到的最接近的是 Chart.JS 的 TypeScript 包:https : //github.com/SeanSobey/ChartjsNodePuppeteer。我不熟悉 TypeScript/ES6,所以我不知道如何调整这个库以使其与 Google Charts 库而不是 Chart.JS 一起使用。
查看完整描述

3 回答

?
慕雪6442864

TA贡献1812条经验 获得超5个赞

我遇到了同样的问题,并将其放入一个名为Google Charts Node的开源库中。


这是一个示例用法:


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


// Define your chart drawing function

function drawChart() {

  const data = google.visualization.arrayToDataTable([

    ['City', '2010 Population',],

    ['New York City, NY', 8175000],

    ['Los Angeles, CA', 3792000],

    ['Chicago, IL', 2695000],

    ['Houston, TX', 2099000],

    ['Philadelphia, PA', 1526000]

  ]);


  const options = {

    title: 'Population of Largest U.S. Cities',

    chartArea: {width: '50%'},

    hAxis: {

      title: 'Total Population',

      minValue: 0

    },

    vAxis: {

      title: 'City'

    }

  };


  const chart = new google.visualization.BarChart(container);

  chart.draw(data, options);

}


// Render the chart to image

const image = await GoogleChartsNode.render(drawChart, {

  width: 400,

  height: 300,

});

该render方法返回一个包含此图像的缓冲区:

//img1.sycdn.imooc.com//61a82d930001afa303980297.jpg

它在 NPM 上以google-charts-node 的形式提供。


关于使用 Puppeteer 渲染的一般问题,我发现它相当简单。我尽量使用图表提供的方法getImageURI,但并非所有图表都支持它。在这种情况下,我使用 Puppeteer 截取屏幕截图。


这是基本逻辑(另请查看完整的源代码):


async function render() {

  // Puppeteer setup

  const browser = await puppeteer.launch();

  const page = await browser.newPage();


  // Add the chart

  await page.setContent(`...Insert your Google Charts code here...`);


  // Use getImageURI if available (not all charts support)

  const imageBase64 = await page.evaluate(() => {

    if (!window.chart || typeof window.chart.getImageURI === 'undefined') {

      return null;

    }

    return window.chart.getImageURI();

  });


  let buf;

  if (imageBase64) {

    buf = Buffer.from(imageBase64.slice('data:image/png;base64,'.length), 'base64');

  } else {

    // getImageURI was not available - take a screenshot using puppeteer

    const elt = await page.$('#chart_div');

    buf = await elt.screenshot();

  }


  await browser.close();

  return buf;

}


查看完整回答
反对 回复 2021-12-02
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

我使用以下代码行在 node.js 应用程序中设置了 puppeteer。在 pdf 文件中显示图表工作正常。


对我来说, defaultViewport: null 和 args: ['--window-size=1920,1080'] 的组合给了我全屏显示,视图适合屏幕大小,图表显示宽度适当,如应用程序所示:


const browser = await puppeteer.launch({

      headless: true,

      defaultViewport: null,

      args: [

        '--window-size=1366,768',

        '--no-sandbox',

        '--disable-setuid-sandbox',

      ],

});

const page = await browser.newPage();

await page.setDefaultNavigationTimeout(0);

await page.goto(reportUrl, {

    waitUntil: ['load', 'domcontentloaded', 'networkidle0'],

});


查看完整回答
反对 回复 2021-12-02
?
烙印99

TA贡献1829条经验 获得超13个赞

我已经设置了一个 puppeteer 代码,用于加载 Google Chart 示例页面的 Iframe,然后将elementHandle #chart_div. 这比加载另一个库要快得多和简单得多。


接下来,您可以使用 div 元素创建 HTML DOM,并使用它设置 Google Chart 并截取 div 元素的屏幕截图。


    const page = await browser.newPage()

    page.setDefaultNavigationTimeout(0);


    const goto = await page.goto('https://developers-dot-devsite-v2-prod.appspot.com/chart/interactive/docs/gallery/barchart_9a8ce4c79b8da3fa2e73bee14869e01b6f7fb5150dc7540172d60b5680259b48.frame')

    const wait = await page.waitForSelector('#chart_div > div', {'visible' : true, 'timeout' : 0})

    const elem = await page.$('#chart_div')

    const save = await elem.screenshot({path : 'googlechart.png' })


查看完整回答
反对 回复 2021-12-02
  • 3 回答
  • 0 关注
  • 206 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信