Show HN: ChartGPU – 基于 WebGPU 的图表库(60fps 下 100 万数据点)
Show HN: ChartGPU – WebGPU-powered charting library (1M points at 60fps)

原始链接: https://github.com/ChartGPU/ChartGPU

## ChartGPU:高性能 WebGPU 图表 ChartGPU 是一个利用 WebGPU 实现异常流畅和交互式渲染的 TypeScript 图表库,尤其适用于大型数据集。它支持各种图表类型,包括折线图、面积图、柱状图、散点图、饼图和 K 线图,并提供内置交互功能,如悬停高亮、工具提示和 X 轴缩放。 主要特性包括流式数据更新、可定制主题(亮色/暗色 & 自定义)以及管理 WebGPU 生命周期的强大架构。该库利用渲染协调器来处理布局、比例尺、数据上传和渲染通道。 ChartGPU 提供用于图表创建和操作的公共 API,以及用于用户交互的事件。它基于核心 WebGPU 实现构建,并为每种图表类型使用专用着色器。还提供 React 绑定 (`chartgpu-react`),以便轻松集成。 **浏览器支持:** Chrome/Edge 113+ & Safari 18+(已启用 WebGPU)。Firefox 支持目前正在开发中。示例和本地开发可通过 npm 获取。

## ChartGPU:一款快速的 WebGPU 图表库 一个名为 **ChartGPU** 的新型图表库正在 Hacker News 上受到关注,因为它具有令人印象深刻的性能。由 huntergemmer 创建,它解决了现有库在处理大型数据集(超过 10 万个点)时遇到的限制。 其关键创新在于利用 **WebGPU** —— 将所有计算转移到 GPU,而不是依赖于受 CPU 限制的 Canvas2D,甚至是由 CPU 驱动的 WebGL 实现。这使得 ChartGPU 能够以 60fps 的帧率渲染 **100 万个数据点**,并具有流畅的缩放和平移功能。 目前支持折线图、面积图、柱状图、散点图、饼图和 K 线图,它作为一个 MIT 许可的 npm 包提供 (`npm install chartgpu`)。作者乐于讨论 WebGPU 内部机制,并正在探索盈利模式,例如针对企业功能推出“专业版”,同时保持核心库的开源状态。像 macOS 上的滚动条问题这样的错误报告正在积极处理中。 **演示:** [https://chartgpu.github.io/ChartGPU/examples/million-points/](https://chartgpu.github.io/ChartGPU/examples/million-points/)
相关文章

原文

ChartGPU

High-performance charts powered by WebGPU

Documentation | Live Demo | Examples

npm license Live Demo

ChartGPU is a TypeScript charting library built on WebGPU for smooth, interactive rendering—especially when you have lots of data.

  • 🚀 WebGPU-accelerated rendering for high FPS with large datasets
  • 📈 Multiple series types: line, area, bar, scatter, pie, candlestick
  • 🧭 Built-in interaction: hover highlight, tooltip, crosshair
  • 🔁 Streaming updates via appendData(...) (cartesian series)
  • 🔍 X-axis zoom (inside gestures + optional slider UI)
  • 🎛️ Theme presets ('dark' | 'light') and custom theme support

At a high level, ChartGPU.create(...) owns the canvas + WebGPU lifecycle, and delegates render orchestration (layout/scales/data upload/render passes + internal overlays) to the render coordinator. For deeper internal notes, see docs/API.md (especially “Render coordinator”).

flowchart TB
  UserApp["Consumer app"] --> PublicAPI["src/index.ts (Public API exports)"]

  PublicAPI --> ChartCreate["ChartGPU.create(container, options)"]
  PublicAPI --> SyncAPI["connectCharts(charts)"]

  subgraph ChartInstance["Chart instance (src/ChartGPU.ts)"]
    ChartCreate --> SupportCheck["checkWebGPUSupport()"]
    ChartCreate --> Canvas["Create canvas + mount into container"]
    ChartCreate --> Options["resolveOptions(options)"]
    ChartCreate --> GPUInit["GPUContext.create(canvas)"]
    ChartCreate --> Coordinator["createRenderCoordinator(gpuContext, resolvedOptions)"]

    ChartCreate --> InstanceAPI["ChartGPUInstance APIs"]
    InstanceAPI --> RequestRender["requestAnimationFrame (coalesced)"]
    RequestRender --> Coordinator

    InstanceAPI --> SetOption["setOption(...)"]
    InstanceAPI --> AppendData["appendData(...)"]
    InstanceAPI --> Resize["resize()"]

    subgraph PublicEvents["Public events + hit-testing (ChartGPU.ts)"]
      Canvas --> PointerHandlers["Pointer listeners"]
      PointerHandlers --> PublicHitTest["findNearestPoint() / findPieSlice()"]
      PointerHandlers --> EmitEvents["emit('click'/'mouseover'/'mouseout')"]
    end

    DataZoomSlider["dataZoom slider UI (DOM)"] --> Coordinator
  end

  subgraph WebGPUCore["WebGPU core (src/core/GPUContext.ts)"]
    GPUInit --> AdapterDevice["navigator.gpu.requestAdapter/device"]
    GPUInit --> CanvasConfig["canvasContext.configure(format)"]
  end

  subgraph RenderCoordinatorLayer["Render coordinator (src/core/createRenderCoordinator.ts)"]
    Coordinator --> Layout["GridArea layout"]
    Coordinator --> Scales["xScale/yScale (clip space for render)"]
    Coordinator --> DataUpload["createDataStore(device) (GPU buffer upload/caching)"]
    Coordinator --> RenderPass["Encode + submit render pass"]

    subgraph InternalOverlays["Internal interaction overlays (coordinator)"]
      Coordinator --> Events["createEventManager(canvas, gridArea)"]
      Events --> OverlayHitTest["hover/tooltip hit-testing"]
      Events --> InteractionX["interaction-x state (crosshair)"]
      Coordinator --> OverlaysDOM["DOM overlays: legend / tooltip / text labels"]
    end
  end

  subgraph Renderers["GPU renderers (src/renderers/*)"]
    RenderPass --> GridR["Grid"]
    RenderPass --> AreaR["Area"]
    RenderPass --> BarR["Bar"]
    RenderPass --> ScatterR["Scatter"]
    RenderPass --> LineR["Line"]
    RenderPass --> PieR["Pie"]
    RenderPass --> CandlestickR["Candlestick"]
    RenderPass --> CrosshairR["Crosshair overlay"]
    RenderPass --> HighlightR["Hover highlight overlay"]
    RenderPass --> AxisR["Axes/ticks"]
  end

  subgraph Shaders["WGSL shaders (src/shaders/*)"]
    GridR --> gridWGSL["grid.wgsl"]
    AreaR --> areaWGSL["area.wgsl"]
    BarR --> barWGSL["bar.wgsl"]
    ScatterR --> scatterWGSL["scatter.wgsl"]
    LineR --> lineWGSL["line.wgsl"]
    PieR --> pieWGSL["pie.wgsl"]
    CandlestickR --> candlestickWGSL["candlestick.wgsl"]
    CrosshairR --> crosshairWGSL["crosshair.wgsl"]
    HighlightR --> highlightWGSL["highlight.wgsl"]
  end

  subgraph ChartSync["Chart sync (src/interaction/createChartSync.ts)"]
    SyncAPI --> ListenX["listen: 'crosshairMove'"]
    SyncAPI --> DriveX["setCrosshairX(...) on peers"]
  end

  InteractionX --> ListenX
  DriveX --> InstanceAPI
Loading

ChartGPU demo

Financial OHLC (open-high-low-close) candlestick rendering with classic/hollow style toggle and color customization.

Candlestick chart example

import { ChartGPU } from 'chartgpu';
const container = document.getElementById('chart')!;
await ChartGPU.create(container, {
  series: [{ type: 'line', data: [[0, 1], [1, 3], [2, 2]] }],
});

npm install chartgpu

React bindings are available via chartgpu-react:

npm install chartgpu-react
import { ChartGPUChart } from 'chartgpu-react';

function MyChart() {
  return (
    <ChartGPUChart
      options={{
        series: [{ type: 'line', data: [[0, 1], [1, 3], [2, 2]] }],
      }}
    />
  );
}

See the chartgpu-react repository for full documentation and examples.

Browser support (WebGPU required)

  • Chrome 113+ or Edge 113+ (WebGPU enabled by default)
  • Safari 18+ (WebGPU enabled by default)
  • Firefox: not supported (WebGPU support in development)
  • Browse examples: examples/
  • Run locally:
    • npm install
    • npm run dev (opens http://localhost:5176/examples/)

See CONTRIBUTING.md.

MIT — see LICENSE.

联系我们 contact @ memedata.com