이 페이지는 영어에서 번역되었습니다. 영어 페이지 읽기
트리
Tree::of(action)은 필요할 때 불러오는 계층 구조를 보여 줍니다. action은 TreeQuery를 받아 q.parent의 자식을 반환합니다(최상위 수준은 None). 가지는 처음 열릴 때 자식을 불러오므로, 큰 계층 구조 위의 트리는 열린 가지마다 작은 요청 하나만 듭니다.
#[action(permission = "stock.product.read")]
pub async fn sample_tree(q: TreeQuery, store: SampleStore) -> Result<Vec<TreeItem>> {
Ok(match q.parent.as_deref() {
None => vec![TreeItem::branch("piece", "Piece"), TreeItem::branch("kg", "Kilogram")],
Some(unit) => store.by_unit(unit)?.into_iter().map(|s| TreeItem::leaf(s.id.0.to_string(), s.name).hint(s.code)).collect(),
})
}
Tree::of(sample_tree).label("Products by unit")- 불러오는 중…
트리는 ARIA 트리 패턴을 따릅니다. 화살표 키로 항목 사이를 이동하고 가지를 열거나 닫습니다. 서버는 가지당 자식 수에 상한을 둡니다(MAX_TREE_CHILDREN).
차트
Chart::bar, stacked_bar, line, area, combo, scatter, donut, gauge, funnel은 서버에서 SVG를 그립니다. 브라우저에는 차트 라이브러리가 없으며, 차트는 페이지 HTML의 일부입니다.
Row::new()
.col(Chart::bar("Sales").labels(["Jan", "Feb", "Mar", "Apr", "May", "Jun"])
.series("2025", [120.0, 98.0, 143.0, 160.0, 151.0, 189.0])
.series("2026", [131.0, 122.0, 150.0, 171.0, 166.0, 204.0]))
.col(Chart::donut("Units").labels(["Piece", "Kg", "Liter"]).series("Products", [40.0, 40.0, 40.0]))
Chart::stacked_bar("Channels").labels(months).series("Shop", shop).series("Web", web)
Chart::combo("Sales and margin").labels(months).series("Sales", sales).line_series("Margin %", margin).right_axis()
Chart::area("Visits").labels(months).series("Visits", visits)
Chart::scatter("Price and units").points("Tea", [(1.5, 40.0), (2.5, 22.0)])
Chart::gauge("Capacity").value(72.0).range(0.0, 100.0).target(85.0)
Chart::funnel("Checkout").labels(["Visited", "Cart", "Paid"]).series("People", [1000.0, 420.0, 150.0])Revenue
184,250
이전 기간 대비 12.4% 증가
목표 200,000, 92% 달성
Average wait
6.5 min
이전 기간 대비 9.0% 감소
- 2025
- 2026
데이터 표시
| 2025 | 2026 | |
|---|---|---|
| Jan | 120 | 131 |
| Feb | 98 | 122 |
| Mar | 143 | 150 |
| Apr | 160 | 171 |
| May | 151 | 166 |
| Jun | 189 | 204 |
- Piece
- Kg
- Liter
데이터 표시
| Products | |
|---|---|
| Piece | 40 |
| Kg | 40 |
| Liter | 40 |
- Sales
- Margin %
데이터 표시
| Sales | Margin % | |
|---|---|---|
| Jan | 120 | 18 |
| Feb | 98 | 14 |
| Mar | 143 | 21 |
| Apr | 160 | 22 |
| May | 151 | 19 |
| Jun | 189 | 24 |
데이터 표시
| 값 | 최소 | 최대 | 목표 |
|---|---|---|---|
| 72 | 0 | 100 | 85 |
각 차트에는 제목, 스크린 리더를 위한 텍스트 요약, 범례가 있으며, 수치는 Show data 아래의 표로 제공됩니다. 계열 색상은 --z-chart-1부터 --z-chart-6까지의 토큰입니다. 테스트(chart_colors_reach_three_to_one_in_both_themes)가 라이트 테마와 두 다크 테마에서 --z-surface 및 --z-surface-2에 대한 3:1 대비를 검사합니다(테마 참고).
모든 막대, 점, 조각, 단계, 게이지 값은 레이블과 값을 이름으로 가진 마크입니다. SVG는 제목과 요약으로 이름이 붙은 그룹이며, 차트는 탭 정지 지점 하나입니다.
| 키 | 동작 |
|---|---|
| Tab | 차트 안으로, 마지막으로 포커스된 마크로 이동합니다(처음에는 첫 번째 마크) |
| 왼쪽, 오른쪽 | 같은 계열의 이전 또는 다음 마크 (dir="rtl"에서는 서로 바뀝니다) |
| 위쪽, 아래쪽 | 이전 또는 다음 계열의 같은 지점 |
| Home, End | 계열의 첫 번째 또는 마지막 마크 |
| Escape | 툴팁을 숨깁니다 |
마우스 오버, 포커스, 탭은 같은 텍스트를 툴팁으로 보여 주며, 툴팁은 중복해서 읽히지 않도록 스크린 리더에서 숨겨집니다. 스크립트가 없어도 마크에는 이름이 있고 표가 남습니다. 작은 마크(8 px 점)는 24 px 대상 크기에 못 미칩니다. Show data 아래의 표가 동등한 대체 경로입니다(WCAG 2.5.8).
핵심 수치, 스파크라인, 불릿
Kpi는 값, 이전 기간 대비 변화(화살표와 방향을 나타내는 단어, 변화가 좋으면 녹색, 나쁘면 빨간색이며 비용과 대기 시간에는 .lower_is_better()), 달성 비율이 있는 목표, 최근 값의 스파크라인을 보여 줍니다.
Kpi::new("Revenue this month", 184_250.0).delta(12.4).target(200_000.0).trend([140.0, 152.0, 160.0, 184.0])
Kpi::new("Average wait", 6.5).decimals(1).unit("min").delta(-9.0).lower_is_better()DataGrid에서 Vec<f64> 열은 스파크라인으로, 숫자 또는 금액 열은 목표에 대한 불릿으로 그려집니다.
DataGrid::of(search_reps)
.column(Rep::sales).cell(BulletCell::new(80_000.0, 120_000.0))
.column(Rep::weeks).cell(SparklineCell::new())둘 다 셀당 작은 SVG 하나이며 "Trend of 12 values from 40 to 61, lowest 12, highest 99" 같은 이름을 가집니다. 예산: 두 셀을 합쳐 행당 HTML 약 0.65 KB입니다. 둘 다 있는 10,000행은 디버그 빌드에서 약 0.4초에 렌더링되며(sparkline_and_bullet_cells_render_ten_thousand_rows_quickly), 그리드는 보이는 행만 렌더링합니다. charts.js는 원본 3.7 KB(gzip 1.4 KB), charts.css는 3.3 KB(gzip 1.1 KB)를 추가합니다.