Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

To capture a JavaScript-rendered canvas chart reliably, wait for the chart itself to be ready, then take a page or element screenshot. Navigation completion and network idleness can help, but neither proves that chart drawing has finished. For Chart.js, also check the canvas’s CSS display size separately from its bitmap dimensions; increase devicePixelRatio when you need a sharper image.

Use chart readiness—not just navigation completion

Puppeteer’s screenshot guide shows navigating with waitUntil: 'networkidle2' before calling page.screenshot(). That is a useful starting point, but a chart may still be waiting on application code, data processing, or an animation after network activity settles. Network idleness is not a guarantee that the canvas has been painted.

Prefer an application-specific signal: for example, a global state your page sets after rendering, or a selector that appears only once the chart is initialized. Puppeteer provides page.waitForFunction() to wait for a page predicate and page.waitForSelector() to wait for an element. If you control the page, expose an explicit ready state after chart drawing completes rather than relying on a fixed delay. There is no universal chart-ready event that applies to every library or page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Runnable example with an application-ready signal

The example assumes the page sets window.chartReady = true only after the chart is drawn. Replace the URL and readiness predicate with the ones your application actually provides. It uses Chart.js selectors as an example; your page may use another chart library.

#1 Best Overall
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
  • Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM)
  • Includes 128GB Micro SD Card pre-loaded with 64-bit Raspberry Pi OS, USB MicroSD Card Reader
  • CanaKit Turbine Black Case for the Raspberry Pi 5
  • CanaKit Low Noise Bearing System Fan
  • Mega Heat Sink - Black Anodized
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com/dashboard', {
      waitUntil: 'networkidle2',
    });

    await page.waitForFunction(() => window.chartReady === true, {
      timeout: 30000,
    });

    await page.screenshot({ path: 'page.png', fullPage: true });
  } finally {
    await browser.close();
  }
})();

If the page does not expose a global state, wait for a meaningful selector or another observable state change that your application guarantees occurs after chart initialization. A canvas element merely existing may not be enough: it can exist before data arrives or before drawing finishes.

Choose between a page screenshot and a chart screenshot

Use page.screenshot() when the surrounding page context matters, or an element screenshot when you want only the chart. Puppeteer documents both methods. An element screenshot attempts to scroll a hidden element into view before capturing it.

Rank #2
CanaKit Raspberry Pi 4 4GB Starter PRO Kit - 4GB RAM
  • Includes Raspberry Pi 4 4GB Model B with 1.5GHz 64-bit quad-core CPU (4GB RAM)
  • Includes Pre-Loaded 32GB EVO+ Micro SD Card (Class 10), USB MicroSD Card Reader
  • CanaKit Premium High-Gloss Raspberry Pi 4 Case with Integrated Fan Mount, CanaKit Low Noise Bearing System Fan
  • CanaKit 3.5A USB-C Raspberry Pi 4 Power Supply (US Plug) with Noise Filter, Set of Heat Sinks, Display Cable - 6 foot (Supports up to 4K60p)
  • CanaKit USB-C PiSwitch (On/Off Power Switch for Raspberry Pi 4)
// Capture the whole page
await page.screenshot({ path: 'page.png', fullPage: true });

// Capture one chart element
const chart = await page.waitForSelector('#chart-container');
await chart.screenshot({ path: 'chart.png' });

Change #chart-container to a selector that identifies the element you want in the output. If the canvas is clipped by its parent, capturing the canvas alone will not correct the page’s layout or sizing; diagnose those dimensions separately.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Diagnose Chart.js sizing and blurry output

For Chart.js, distinguish the canvas’s CSS display dimensions from its bitmap dimensions. The CSS size controls how large the chart appears in the layout; the canvas width and height attributes control its backing bitmap. These are independent. A chart can look correctly sized but be blurry if its bitmap resolution is too low.

Rank #3
ELECROW CrowPi Case Kit for Raspberry Pi 5, 9-Inch Display
  • Not including the Raspberry Pi 5 (8GB), the Crowpi advanced version comes with the Raspberry Pi 5
  • ELECROW Black Case for the Raspberry Pi 5, CrowPi is equipped with a 9-inch HD touchscreen along with a camera; All the regular components used in DIY electronics are packed into the CrowPi development board, such as LCD, LED matrix, buzzer, light sensor, PIR sensor, ultrasonic sensor, IR sensor, etc
  • Raspberry Pi Sensors: The Crowpi raspberry pi 5 programming kit is jam-packed with lots of buttons such as 19 different sensors in a tidy easy to use package; You don't have to wait and wire things
  • Build Quality: Solid ABS shell and well made components in one place make it strong and convenient to travel
  • Programming Lessons: This raspberry pi 5 learning kit ships with step by step instructions and provides 21 lessons to take you through identifying components reading code and running it in the terminal

Chart.js recommends responsive sizing through a dedicated, relatively positioned parent container. Styling only the canvas can lead to inaccurate or blurry rendering. Inspect both the canvas attributes and its computed display size, along with the dimensions of its parent.

const dimensions = await page.$eval('#myChart', canvas => {
  const style = getComputedStyle(canvas);
  const rect = canvas.getBoundingClientRect();
  return {
    bitmapWidth: canvas.width,
    bitmapHeight: canvas.height,
    cssWidth: style.width,
    cssHeight: style.height,
    displayedWidth: rect.width,
    displayedHeight: rect.height,
  };
});
console.log(dimensions);

When you need a higher-resolution Chart.js bitmap, configure options.devicePixelRatio. It scales the canvas relative to its container and is documented as useful when converting the chart to a bitmap or printing at higher DPI. It changes output resolution; it does not indicate that rendering is complete.

Rank #4
CanaKit Raspberry Pi 5 Desktop PC with SSD (Fully Assembled) (256 GB SSD)
  • Fully assembled for plug-and-play operation
  • Includes Raspberry Pi 5 with 8GB RAM
  • 256 GB PCIe Pi NVMe SSD (Pre-loaded with Pi 64-Bit OS)
  • M.2 HAT+
  • CanaKit Turbine Black Case for the Pi 5
const chart = new Chart(ctx, {
  type: 'bar',
  data,
  options: {
    devicePixelRatio: 2,
  },
});

Use a ratio that suits your output requirements and check the resulting bitmap size. Increasing it can make the image larger in pixel dimensions, but it will not fix a chart that has not rendered, has the wrong CSS size, or is clipped by its container.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshoot blank, clipped, or blurry captures

Blank chart

  • Check whether the page’s data request and chart initialization completed; inspect browser console errors and runtime state.
  • Wait for a chart-specific ready signal or a state change that occurs after drawing. Do not treat the presence of a canvas as proof that it contains the final chart.
  • Check whether the canvas or a parent is hidden, has zero display dimensions, or is covered by page state that has not cleared.
  • If the chart animates, wait for an application-level completion signal where available rather than guessing with a delay.

Clipped or incorrectly sized chart

  • Inspect the computed CSS display size of the canvas and the size and positioning of its parent container.
  • For Chart.js, use a dedicated, relatively positioned parent for responsive sizing; do not rely on styling only the canvas.
  • Decide whether you need a full-page capture or only the chart element. An element screenshot scrolls the target into view, but does not repair layout clipping.

Blurry chart

  • Compare the canvas bitmap width and height with its CSS display dimensions.
  • For Chart.js, adjust options.devicePixelRatio when a higher-resolution bitmap is needed; this is separate from waiting for readiness.
  • Verify the chart’s responsive parent sizing before increasing bitmap resolution, since a larger bitmap cannot correct an inaccurate display layout.

Waits time out or remain unreliable

  • Confirm that the predicate or selector you wait for actually changes on successful chart initialization.
  • Use network-idle waiting as a navigation aid, not as the sole chart-ready condition. Pages with continuing requests may not become idle, while pages with no active requests may still be drawing.
  • Check console errors, page state, and dimensions to distinguish loading failures from a selector mismatch or sizing problem.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Accessibility note for canvas charts

Canvas pixels are not inherently available to screen readers. The Chart.js accessibility guide states: “The canvas element has support in all browsers and will render on screen but the canvas content will not be accessible to screen readers.” Provide an accessible name or fallback content for the chart in the page itself; a screenshot does not supply that semantic information.

Best Value
RasTech Raspberry Pi 5 8GB Kit with Active Cooler and Pi5 Case
  • 【What you Get】You will get 1*Pi 5 8GB Single Board,1*RasTech Case,1*Active Cooler,1*Screwdriver,1*Installation instructions,12-month free warranty, lifetime service, 24-hour prompt and friendly response.
  • 【More Connectors】There are two USB 3.0 ports(5Gbps simultaneously) and two USB 2.0 ports, which triple total bandwidth ,support any combination of up to two cameras or displays. Peak SD card performance is doubled through support for the SDR104 high-speed mode. It provides a smooth desktop experience for you. Offer Gigabit Ethernet and a PCIe interface, along with dual-band Wi-Fi and Bluetooth 5.0/BLE wireless capability. The RasTech Pi 5 Kit use the new 27W 5.1V 5A USB-C power connector.
  • 【 Support Dual 4Kp60 Display 】Each of the two microHDMI sockets can control a 4K display at 60 Hertz, now support HDR, offering super HD video for media streaming projects. RPi 5 is the first RPi model that comes with a PCI Express port (PCIe 2.0 x1 with 500 MB/s) to attach SSDs (requires separate M.2 HAT).
  • 【 Excellent Chips And Applications】Pi 5 is a full-size Pi computer using silicon built in-house at Pi. The RP1 “southbridge” provides the bulk of the I/O capabilities for Pi 5. Pi 5 is more friendly and convenient in the development of Internet of Things, Web development, machine identification, automatic control and other electronic equipment applications and network.
  • 【 Faster CPU, Better GPU 】 Pi 5 features a Broadcom BCM2712 64-bit quad-core Arm Cortex-A76 processor running at 2.4GHz, it delivers a 2–3× increase in CPU performance relative to RaspberryPi 4. The 800MHz VideoCore VII GPU is compatible to OpenGL ES 3.1 and Vulkan 1.2, substantial uplift in graphics performance. Pi 5 Offers lightning-fast CPU speed, a PCI Express interface, a Real Time Clock (RTC) and a power button and runs significantly cooler than Pi 4.

Or skip the browser setup

ScreenshotNeo can capture a page with one GET request and return an image or PDF. Cookie banners are accepted and removed before the shot, along with known newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers identify the page verdict and billing status. An MCP server provides screenshot tools for AI agents, and the free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots.

For API parameters and options, see the ScreenshotNeo documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/dashboard -o shot.webp

Sign up free for 1,000 screenshots a month with no card.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quick Recap

Bestseller No. 1
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
CanaKit Raspberry Pi 5 Starter Kit PRO - Turbine Black (128GB Edition) (8GB RAM)
Includes Raspberry Pi 5 with 2.4Ghz 64-bit quad-core CPU (8GB RAM); CanaKit Turbine Black Case for the Raspberry Pi 5
$259.95
Bestseller No. 2
CanaKit Raspberry Pi 4 4GB Starter PRO Kit - 4GB RAM
CanaKit Raspberry Pi 4 4GB Starter PRO Kit - 4GB RAM
Includes Raspberry Pi 4 4GB Model B with 1.5GHz 64-bit quad-core CPU (4GB RAM); Includes Pre-Loaded 32GB EVO+ Micro SD Card (Class 10), USB MicroSD Card Reader
$159.99
Bestseller No. 4
CanaKit Raspberry Pi 5 Desktop PC with SSD (Fully Assembled) (256 GB SSD)
CanaKit Raspberry Pi 5 Desktop PC with SSD (Fully Assembled) (256 GB SSD)
Fully assembled for plug-and-play operation; Includes Raspberry Pi 5 with 8GB RAM; 256 GB PCIe Pi NVMe SSD (Pre-loaded with Pi 64-Bit OS)
$339.97

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.