Files

9.7 KiB
Raw Permalink Blame History

Timeline 时间轴

概述

时间轴(Timeline)用于垂直展示一系列按时间排列的信息。常用于展示版本更新记录、操作日志、事件追踪等按时间顺序组织的数据。每个节点由指示器(圆点或自定义图标)和内容组成,通过尾线连接形成视觉上的时间流。

AtomUI 的 Timeline 控件复刻了 Ant Design 5.0 Timeline 的设计规范,在 .NET / Avalonia 平台上提供与 Ant Design React 版一致的视觉体验。


设计原理

Ant Design 的时间轴设计哲学

Ant Design 对时间轴的定位是:「垂直展示的时间流信息」。时间轴通常出现在以下场景:

  • 事件记录:按时间顺序展示一系列操作或事件
  • 版本日志:展示产品版本更新历史
  • 审批流程:展示多步骤流程的执行状态
  • 进度追踪:展示任务进展和未来计划

三种布局模式:

模式 设计意图 典型用途
📍 左对齐(Left) 指示器在左侧,内容在右侧。最常见的布局方式 基本时间轴、操作日志
📍 右对齐(Right) 指示器在右侧,内容在左侧 从右向左阅读场景
📍 交替(Alternate) 内容交替出现在指示器的左右两侧 双栏时间轴、里程碑展示

关键特性:

  • 指示器颜色:支持自定义颜色,用于区分不同状态(绿色=成功、红色=错误、蓝色=进行中、灰色=未完成)
  • 自定义图标:可用 Ant Design 图标替代默认圆点
  • 待办节点(Pending):在时间轴末尾添加一个"进行中"的幽灵节点,表示事件尚未完成
  • 反转显示:可倒序排列时间节点
  • 标签(Label):可为每个节点附加标签文本(如日期),在双栏布局中显示

AtomUI 的扩展设计

AtomUI Timeline 在 Ant Design 规范基础上做了以下实现:

扩展能力 实现方式 设计动机
三种布局模式 TimeLineMode 枚举(Left/Right/Alternate) 对齐 Ant Design 的 mode 属性
指示器颜色 IndicatorColor(IBrush?)属性 支持任意画刷,比 Ant Design 的字符串颜色更灵活
自定义图标 IndicatorIcon(PathIcon?)属性 替代默认圆点,与 AtomUI 图标系统集成
待办节点 Pending + PendingIcon 属性 自动在末尾生成带旋转 Loading 图标的幽灵节点
反转排列 IsReverse 属性 倒序展示时间节点
标签系统 Label 属性 + 自动检测标签布局 任一节点设置 Label 后自动切换为双栏标签布局
Design Token TimelineToken + RegisterTokenResourceScope 所有视觉值从 Token 派生

功能详解

布局模式(Mode)

Timeline 通过 Mode 属性控制内容和指示器的相对位置:

模式 无 Label 时 有 Label 时
Left 指示器靠左、内容在右 标签在左、指示器居中、内容在右
Right 指示器靠右、内容在左 内容在左、指示器居中、标签在右
Alternate 内容在指示器左右交替 标签和内容在指示器左右交替

当任一 TimelineItem 设置了 Label 属性时,所有节点自动切换为标签布局(双栏),指示器居中,标签和内容分列两侧。

待办节点(Pending)

当 Pending 属性不为 null 时:

  1. 自动在时间轴末尾添加一个幽灵节点
  2. 默认使用 LoadingOutlined 旋转图标作为指示器
  3. 可通过 PendingIcon 自定义幽灵节点的图标
  4. 幽灵节点前一个节点的下方间距自动加大(ItemPaddingBottomLG)

反转排列(IsReverse)

当 IsReverse = true 时:

  • 所有节点在视觉上倒序排列
  • 待办节点仍然出现在尾部(逻辑上的最后位置)
  • 节点位置信息(IsFirst/IsLast/IsOdd)会重新计算

指示器(TimelineIndicator)

每个 TimelineItem 包含一个内部的 TimelineIndicator 控件,负责渲染:

  1. 指示器圆点:默认空心圆,通过 IndicatorDotSize 和 IndicatorDotBorderWidth 控制
  2. 自定义图标:当 IndicatorIcon 不为 null 时,图标替代圆点
  3. 尾线:连接相邻节点的竖线,通过 IndicatorTailColor 和 IndicatorTailWidth 控制
  4. 首节点不绘制上方尾线,末节点不绘制下方尾线

与 Ant Design 规范的对齐程度

特性 Ant Design (React) AtomUI (Avalonia) 对齐情况
布局模式 mode ✅ left/right/alternate ✅ TimeLineMode 枚举 ✅ 完全对齐
指示器颜色 color ✅ 字符串颜色 ✅ IndicatorColor(IBrush) ✅ 对齐(类型更灵活)
自定义圆点 dot ✅ ReactNode ✅ IndicatorIcon(PathIcon) ✅ 对齐(类型不同,语义一致)
待办节点 pending ✅ boolean/ReactNode ✅ Pending(object) ✅ 完全对齐
待办图标 pendingDot ✅ ReactNode ✅ PendingIcon(PathIcon) ✅ 完全对齐
反转 reverse ✅ boolean ✅ IsReverse ✅ 完全对齐
标签 label ✅ ReactNode ✅ Label(string) ⚠️ 仅支持字符串,不支持任意内容
子项 children ✅ ReactNode ✅ Content(object) ✅ 完全对齐

继承关系

Timeline

Avalonia.Controls.ItemsControl
  └── AtomUI.Controls.Commons.AbstractTimeline    ← 设备无关基类
        └── AtomUI.Desktop.Controls.Timeline       ← 桌面实现

TimelineItem

Avalonia.Controls.ContentControl
  └── AtomUI.Controls.Commons.AbstractTimelineItem  ← 设备无关基类
        └── AtomUI.Desktop.Controls.TimelineItem     ← 桌面实现

各层级职责划分(Timeline):

层级 提供的能力
ItemsControl 子项容器基础设施、Items / ItemTemplate、容器生成与回收
AbstractTimeline(基类层) Mode 布局模式、Pending/PendingIcon 待办节点、IsReverse 反转、子项位置信息计算(IsOdd/IsFirst/IsLast)、标签布局自动检测
Timeline(桌面层) 注册 TimelineToken.ScopeProvider、创建桌面端 TimelineItem 容器、创建待办节点(默认 LoadingOutlined 图标)

各层级职责划分(TimelineItem):

层级 提供的能力
ContentControl 任意内容容纳、Content / ContentTemplate
AbstractTimelineItem(基类层) Label 标签、IndicatorIcon 自定义图标、IndicatorColor 指示器颜色、位置伪类管理(order-odd/order-even/order-first/order-last/pending-item)
TimelineItem(桌面层) 注册 TimelineToken.ScopeProvider

内部辅助控件

控件 位置 作用
TimelineIndicator AtomUI.Controls (internal) 渲染指示器圆点/图标和尾线
TimelineItemPanel AtomUI.Controls (internal) 自定义 Panel,根据 Mode 和 IsLabelLayout 安排标签、指示器、内容的布局
TimelineStackPanel AtomUI.Controls (internal) 支持 IsReverse 的 StackPanel,实现子项反转排列

源码位置

层级 文件路径 说明
基类 src/AtomUI.Controls/Timeline/AbstractTimeline.cs Timeline 设备无关基类
基类 src/AtomUI.Controls/Timeline/AbstractTimelineItem.cs TimelineItem 设备无关基类
枚举 src/AtomUI.Controls/Timeline/TimeLineEnums.cs TimeLineMode 枚举
内部控件 src/AtomUI.Controls/Timeline/TimelineIndicator.cs 指示器渲染控件
内部控件 src/AtomUI.Controls/Timeline/TimelineItemPanel.cs 节点布局面板
内部控件 src/AtomUI.Controls/Timeline/TimelineStackPanel.cs 支持反转的 StackPanel
控件类 src/AtomUI.Desktop.Controls/Timeline/Timeline.cs 桌面端 Timeline
控件类 src/AtomUI.Desktop.Controls/Timeline/TimelineItem.cs 桌面端 TimelineItem
Token 定义 src/AtomUI.Desktop.Controls/Timeline/TimelineToken.cs 组件级 Design Token
主题模板 src/AtomUI.Desktop.Controls/Timeline/Themes/TimelineTheme.axaml Timeline ControlTheme
主题模板 src/AtomUI.Desktop.Controls/Timeline/Themes/TimelineItemTheme.axaml TimelineItem ControlTheme
主题模板 src/AtomUI.Desktop.Controls/Timeline/Themes/TimelineIndicatorTheme.axaml TimelineIndicator ControlTheme
Gallery 示例 controlgallery/AtomUIGallery/ShowCases/Views/DataDisplay/TimelineShowCase.axaml 使用范例

模板结构

Timeline 模板

Border#Frame                                      ← 外框(背景、边框、圆角)
└── ScrollViewer#ScrollViewer (Lite Mode)          ← 滚动容器
    └── ItemsPresenter#ItemsPresenter             ← 子项呈现
        └── TimelineStackPanel (IsReverse)         ← 支持反转的 StackPanel 布局

TimelineItem 模板

TimelineItemPanel#RootLayout                      ← 自定义布局面板
├── TextBlock#Label                                ← 标签文本(标签布局时可见)
├── TimelineIndicator#Indicator                    ← 指示器(圆点/图标 + 尾线)
│   └── IconPresenter#PART_IconPresenter           ← 自定义图标呈现
└── ContentPresenter#ContentPresenter              ← 内容呈现

布局逻辑说明:

  • TimelineItemPanel 根据 Mode 和 IsLabelLayout 计算三个子元素(Label/Indicator/Content)的位置
  • 在标签布局或 Alternate 模式下,Label 和 Content 各占 (总宽度 - 指示器宽度) / 2
  • 在纯 Left/Right 模式下,Content 占 总宽度 - 指示器宽度
  • Alternate 模式下,奇偶节点的 Label 和 Content 位置互换