Skip to content

Biểu đồ tròn / Vành khuyên

Cơ cấu

"Mỗi phần chiếm bao nhiêu tỷ trọng trong tổng thể?" Câu hỏi lâu đời nhất trong ngành biểu đồ, và một biểu đồ tròn vẫn trả lời tốt nhất khi chỉ có một số ít múi. Mỗi múi được vẽ theo kích thước giá trị và gắn nhãn phần trăm; các múi được sắp xếp theo giá trị để múi lớn nhất đọc trước tiên. Muốn dùng vành khuyên thay vào đó? Đó là cùng một biểu đồ - chỉ cần đặt innerRadiusRatio lớn hơn 0 để khoét lỗ giữa (khi đó context sẽ báo mode: "donut").

Example
canvas · responsive
Tìm hiểu thêm: Hướng dẫn Insights·Hướng dẫn DevTools

Biến thể vành khuyên chỉ cách một prop - đây là cùng các tỷ trọng đó với innerRadiusRatio: 0.6, một padAngle nhỏ, và các góc bo tròn:

Example
canvas · responsive
Tìm hiểu thêm: Hướng dẫn Insights·Hướng dẫn DevTools

Giữ số lượng múi ở mức thấp (khoảng 6 hoặc ít hơn). Với nhiều danh mục hơn, biểu đồ cột hoặc treemap đọc chính xác hơn một biểu đồ tròn.

Khi nào nên dùng

  • Tỷ trọng cho slide báo cáo. Vài lát cắt, mỗi lát gắn nhãn phần trăm: vẫn là cách nhanh nhất để một slide trả lời "ai chiếm bao nhiêu phần của tổng thể".
  • Vành khuyên cho dashboard. Đặt innerRadiusRatio là có ngay lỗ tròn ở giữa: vị trí đắc địa cho con số tiêu đề mà biểu đồ đang chứng minh.

Dữ liệu lớn trên WebGPU Thử nghiệm

PieChart có renderer="webgpu" tùy chọn, vẽ các múi thành các cung do GPU dựng trong khi nhãn, chú giải và tooltip vẫn nằm trên lớp SVG. Tính năng này được kiểm soát theo khả năng phần cứng: trên trình duyệt không có WebGPU, nó tự động hạ cấp về canvas, và getContext().renderer báo cáo bộ dựng thực sự đã vẽ.

⚗️ Experimental - not yet stable. WebGPU rendering is an opt-in preview. It needs a WebGPU-capable browser (Chrome / Edge, or Safari 26+); everywhere else it falls back to canvas automatically. Axes, labels and tooltips stay on the SVG layer - only the data marks are painted on the GPU.
Heavy-data demo · 40 múi… detecting

Xem dữ liệu chạy theo năm

Gắn date cho từng múi rồi bật timeline: biểu đồ tròn thành câu chuyện theo từng năm với nút play và thanh tua riêng, mỗi lần hiển thị tỷ trọng của một giai đoạn. Mặc định tắt - không bật thì biểu đồ giữ nguyên.

Bấm nút play dưới biểu đồ: dữ liệu chạy qua từng năm, mỗi lần một snapshot. Kéo thanh tua để nhảy đến năm bất kỳ.

tsx
const ref = useRef<PieChartHandle>(null);

<PieChart ref={ref} {...props} timeline={{ speedMs: 1000, loop: true }} />;
// ref.current?.timeline() -> play() / pause() / seek(year) / stepForward()
vue
<PieChart :options="{ ...props, timeline: { speedMs: 1000, loop: true } }" />
svelte
<div use:pieChart={{ ...props, timeline: { speedMs: 1000, loop: true } }}></div>
ts
applyPieChartProps(this.c.nativeElement, { ...props, timeline: { speedMs: 1000, loop: true } });
html
<michi-vz-pie-chart id="c"></michi-vz-pie-chart>
<script>
  const el = document.getElementById("c");
  el.timeline = { speedMs: 1000, loop: true };
  // el.getTimeline() -> play() / pause() / seek(year)
</script>
  • speedMs chỉnh nhịp chạy, loop quay vòng, autoplay: true tự chạy khi mount, showControl: false ẩn thanh điều khiển có sẵn.
  • Giá trị trượt mượt giữa các giai đoạn theo mặc định (interpolate); chỉnh chuyển động bằng tweenMseasing, hoặc đặt interpolate: false để cắt thẳng. Khi bật reduced motion, biểu đồ luôn cắt thẳng.
  • Controller headless luôn sẵn sàng: chart.timeline() cho play() / pause() / toggle() / seek(period) / stepForward() / stepBack(), kèm onStepformatPeriod trong config khi cần tự dựng UI.
  • filter (top-N, sắp xếp) vẫn áp dụng bên trong từng giai đoạn, nên mỗi năm chỉ giữ lại top 5 múi.
  • Múi không có date hiển thị ở mọi giai đoạn.

Cách dùng

tsx
import { PieChart } from "@michi-vz/react";

export default () => <PieChart {...props} />; // props = the chart options
vue
<script setup>
import { PieChart } from "@michi-vz/vue";
</script>

<template>
  <PieChart :options="props" />
</template>
svelte
<script>
  import { pieChart } from "@michi-vz/svelte";
</script>

<div use:pieChart={props}></div>
ts
// main.ts - register the elements once
import "@michi-vz/angular";
import { applyPieChartProps } from "@michi-vz/angular";

// component (uses CUSTOM_ELEMENTS_SCHEMA)
// template: <michi-vz-pie-chart #c></michi-vz-pie-chart>
applyPieChartProps(this.c.nativeElement, props);
html
<script type="module" src="https://cdn.jsdelivr.net/npm/@michi-vz/wc/dist/michi-vz-wc.bundle.js"></script>

<michi-vz-pie-chart id="c"></michi-vz-pie-chart>
<script>
  Object.assign(document.getElementById("c"), props); // dataSet, innerRadiusRatio, …
</script>
ts
import { mountPieChart } from "@michi-vz/core";

const chart = mountPieChart(el, props);
chart.update(next);
chart.getContext(); // renderer-agnostic, LLM-ready
chart.destroy();

Cấu trúc dữ liệu

Mỗi mục dataSet là một múi: một label, một value, và một color tùy chọn.

ts
const props = {
  innerRadiusRatio: 0, // 0 = pie; e.g. 0.6 = donut
  showLabels: true,    // % labels inside large-enough slices
  showLegend: true,
  dataSet: [
    { label: "Industry", value: 281, color: "#005aba" },
    { label: "Agri-food", value: 381, color: "#f0a500" },
    { label: "Materials", value: 132, color: "#2aa39a" },
  ],
};

Biểu đồ tròn so với vành khuyên

Một engine duy nhất vẽ cả hai. innerRadiusRatio là lỗ giữa tính theo tỷ lệ bán kính ngoài: 0 là biểu đồ tròn đặc, 0.6 là vành khuyên. padAngle (radian) thêm khoảng cách giữa các múi và cornerRadius bo tròn các góc cung. Các múi, tooltip, getContext() và sự tương đồng SVG/canvas đều giống nhau ở cả hai trường hợp.

API

Các prop được định kiểu là PieChartProps trong @michi-vz/core. Dùng chung cho mọi biểu đồ: width, height, margin, colors / colorsMapping, renderer ("svg", "canvas", hoặc "webgpu" thử nghiệm), highlightItems, disabledItems, và các callback on*. onChartDataProcessed / getContext() trả về ChartContext không phụ thuộc bộ dựng. Tham chiếu đầy đủ: API Biểu đồ tròn / Vành khuyên.