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").
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:
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
innerRadiusRatiolà 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ẽ.
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ỳ.
const ref = useRef<PieChartHandle>(null);
<PieChart ref={ref} {...props} timeline={{ speedMs: 1000, loop: true }} />;
// ref.current?.timeline() -> play() / pause() / seek(year) / stepForward()<PieChart :options="{ ...props, timeline: { speedMs: 1000, loop: true } }" /><div use:pieChart={{ ...props, timeline: { speedMs: 1000, loop: true } }}></div>applyPieChartProps(this.c.nativeElement, { ...props, timeline: { speedMs: 1000, loop: true } });<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>speedMschỉnh nhịp chạy,loopquay vòng,autoplay: truetự 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ằngtweenMsvàeasing, hoặc đặtinterpolate: 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()choplay() / pause() / toggle() / seek(period) / stepForward() / stepBack(), kèmonStepvàformatPeriodtrong 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ó
datehiển thị ở mọi giai đoạn.
Cách dùng
import { PieChart } from "@michi-vz/react";
export default () => <PieChart {...props} />; // props = the chart options<script setup>
import { PieChart } from "@michi-vz/vue";
</script>
<template>
<PieChart :options="props" />
</template><script>
import { pieChart } from "@michi-vz/svelte";
</script>
<div use:pieChart={props}></div>// 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);<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>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.
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.
