This commit is contained in:
LINING-PC\lining
2026-02-27 22:18:51 +08:00
parent 544f6ec2d5
commit d387967944
6 changed files with 210 additions and 8 deletions

View File

@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.9.2] - 2026-02-26
### Added
- 🎉 新增Singleton Tooltip 架构重构TaskBar 不再独立维护 Teleport DOM改由 Timeline 统一管理单一 Tooltip 节点,大幅降低大数据量下的 DOM 开销
- 🎉 新增GanttChart 支持 `#taskbar-tooltip` 自定义 Scoped Slot可完全替换内置 Tooltip 内容,获得 `task``taskStatus``resourcePercent` 三个作用域参数
- 🎉 新增GanttChart 新增 Props `enableTaskListCollapsible`(默认 `true`),设为 `false` 时强制隐藏 TaskList 并让 Timeline 独占全宽
- 🎉 新增GanttChart 新增 Props `taskListVisible`(默认 `true`),支持响应式外部控制 TaskList 显隐
- 🎉 新增GanttChart Expose API 新增 `getTaskListVisible()``setTaskListVisible(visible)``toggleTaskList()` 三个方法,支持命令式控制 TaskList
- 🎉 新增ToolbarConfig 新增 `showViewMode` 字段,用于控制视图切换按钮组的可见性
- 🎉 新增Demo 新增 `data-100.json` 中等规模数据集100 条任务),默认数据源切换至此
- 🎉 Added: Singleton Tooltip architecture refactored — TaskBar no longer maintains independent Teleport DOM, Timeline now manages a single shared Tooltip node, significantly reducing DOM overhead for large datasets
- 🎉 Added: GanttChart supports `#taskbar-tooltip` custom Scoped Slot to fully replace built-in Tooltip content, exposing `task`, `taskStatus`, `resourcePercent` scope parameters
- 🎉 Added: GanttChart new prop `enableTaskListCollapsible` (default `true`); set to `false` to force-hide TaskList and let Timeline occupy full width
- 🎉 Added: GanttChart new prop `taskListVisible` (default `true`) for reactive external control of TaskList visibility
- 🎉 Added: GanttChart Expose API adds `getTaskListVisible()`, `setTaskListVisible(visible)`, `toggleTaskList()` for imperative TaskList control
- 🎉 Added: ToolbarConfig adds `showViewMode` field to control visibility of the view-mode toggle button group
- 🎉 Added: Demo adds `data-100.json` medium-scale dataset (100 tasks) as the new default data source
### Fixed
- 🔧 修复:异步加载数据时首次滚动以空任务列表计算范围,真实数据到来后今日定位失效
- 🔧 修复:从资源视图切换回任务视图后,`updateTimelineRange` 重算偏移导致今日标记偏离视口
- 🔧 修复GanttToolbar 中视图切换按钮组缺少 `v-if` 守卫,导致 `showViewMode: false` 设置不生效
- 🔧 Fixed: When data is loaded asynchronously, initial scroll used empty task list; today marker lost after real data arrived
- 🔧 Fixed: After switching from resource view back to task view, `updateTimelineRange` recalculation caused today marker to move out of viewport
- 🔧 Fixed: View-mode toggle button group in GanttToolbar was missing `v-if` guard, causing `showViewMode: false` to have no effect
## [1.9.1] - 2026-02-07
### Fixed

View File

@@ -224,6 +224,8 @@ npm run dev
| `enableTaskbarTooltip` ![v1.8.0](https://img.shields.io/badge/v1.8.0-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | Whether to enable TaskBar hover tooltip (shows task details on mouse hover) |
| `showConflicts` ![v1.9.0](https://img.shields.io/badge/v1.9.0-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | Whether to display resource conflict visualization layer (shows diagonal stripe background for overload zones in resource view) |
| `showTaskbarTab` ![v1.9.0](https://img.shields.io/badge/v1.9.0-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | Whether to display resource tab on TaskBar (shows resource allocation label on TaskBar in resource view) |
| `enableTaskListCollapsible` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | Whether to allow collapsing/expanding the TaskList panel. When `false`: forcibly hides TaskList, SplitterBar and collapse button; Timeline takes full width |
| `taskListVisible` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | Controls TaskList visibility (reactive). Only effective when `enableTaskListCollapsible=true` |
#### TaskListColumn Component Props
@@ -1798,6 +1800,7 @@ Customize the toolbar functional buttons and time scale options.
| `timeScaleDimensions` | `TimelineScale[]` | `['hour', 'day', 'week', 'month', 'quarter', 'year']` | Set time scale dimensions to display, options: `'hour'`, `'day'`, `'week'`, `'month'`, `'quarter'`, `'year'` |
| `defaultTimeScale` | `TimelineScale` | `'week'` | Default selected time scale |
| `showExpandCollapse` | `boolean` | `true` | Show "Expand All/Collapse All" button (for parent-child task tree structure) |
| `showViewMode` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | Show Task / Resource view mode toggle button group |
**TimelineScale Type Description:**
@@ -2349,6 +2352,9 @@ The GanttChart component exposes a series of methods through `defineExpose`, all
| `scrollToToday` ![v1.7.1](https://img.shields.io/badge/v1.7.1-409EFF?style=flat-square&labelColor=ECF5FF) | - | `void` | Scroll to today's position |
| `scrollToTask` ![v1.7.1](https://img.shields.io/badge/v1.7.1-409EFF?style=flat-square&labelColor=ECF5FF) | `taskId: number \| string` | `void` | Scroll to specified task (task will auto-expand to visible state) |
| `scrollToDate` ![v1.7.1](https://img.shields.io/badge/v1.7.1-409EFF?style=flat-square&labelColor=ECF5FF) | `date: string \| Date` | `void` | Scroll to specified date position (format: `'YYYY-MM-DD'` or Date object) |
| `getTaskListVisible` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | - | `boolean` | Get the current visibility state of TaskList |
| `setTaskListVisible` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | `visible: boolean` | `void` | Imperatively set TaskList visibility (only effective when `enableTaskListCollapsible=true`) |
| `toggleTaskList` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | - | `void` | Toggle TaskList expand/collapse state with animation |
#### Usage Example
@@ -2780,6 +2786,71 @@ const month = formatMonth(3) // '3月' (zh-CN) or '03' (en-US)
Component provides slots support, allowing custom task content rendering。
##### `taskbar-tooltip` Slot ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF)
Fully replaces the built-in TaskBar hover tooltip content. When used, the built-in tooltip is no longer rendered — the consumer has complete control.
> **Prerequisite**: Requires `:enable-taskbar-tooltip="true"` (enabled by default)
**Slot scope parameters (`TaskbarTooltipSlotScope`):**
> The component provides data via `<slot :task="..." :task-status="..." />`. The consumer can receive the whole `scope` object or destructure only what's needed — all parameters are **optional**. `task` is the raw task object from your `:tasks` / `:resources` data, including any custom fields.
| Param | Type | Description |
| --- | --- | --- |
| `task` | `Task` | The currently hovered task object with complete task data |
| `taskStatus` | `{ color: string; label: string }` | Pre-computed task status (color + label) for quick display |
| `resourcePercent` | `number \| null` | Resource usage percentage (valid in resource view; `null` in task view) |
**All three patterns are equivalent:**
```vue
<!-- Pattern 1: whole scope object -->
<template #taskbar-tooltip="scope">
{{ scope.task.name }}
</template>
<!-- Pattern 2: destructure only what you need -->
<template #taskbar-tooltip="{ task }">
{{ task.name }}
</template>
<!-- Pattern 3: destructure all fields -->
<template #taskbar-tooltip="{ task, taskStatus, resourcePercent }">
...
</template>
```
**Example — minimal usage (task name only):**
```vue
<GanttChart :tasks="tasks">
<template #taskbar-tooltip="{ task }">
<div class="my-simple-tooltip">{{ task.name }}</div>
</template>
</GanttChart>
```
**Example — using full scope:**
```vue
<GanttChart :tasks="tasks">
<template #taskbar-tooltip="{ task, taskStatus, resourcePercent }">
<div class="my-tooltip">
<div class="tooltip-title" :style="{ borderColor: taskStatus.color }">
{{ task.name }}
</div>
<div>Status: {{ taskStatus.label }}</div>
<div>Start: {{ task.startDate }}</div>
<div>End: {{ task.endDate }}</div>
<div v-if="resourcePercent !== null">Resource: {{ resourcePercent }}%</div>
</div>
</template>
</GanttChart>
```
---
##### `custom-task-content` Slots
Used to customize task display content in task list (TaskRow) and timeline (TaskBar).

View File

@@ -222,6 +222,8 @@ npm run dev
| `enableTaskbarTooltip` ![v1.8.0](https://img.shields.io/badge/v1.8.0-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | 是否启用TaskBar悬停提示框鼠标悬停显示任务详情 |
| `showConflicts` ![v1.9.0](https://img.shields.io/badge/v1.9.0-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | 是否显示资源冲突可视化层(资源视图下显示斜纹背景标识超载区域) |
| `showTaskbarTab` ![v1.9.0](https://img.shields.io/badge/v1.9.0-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | 是否显示TaskBar上的资源Tab标签资源视图下TaskBar的资源分配标签 |
| `enableTaskListCollapsible` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | 是否允许折叠/展开 TaskList 面板。`false` 时强制隐藏 TaskList、SplitterBar 及折叠按钮Timeline 独占全宽 |
| `taskListVisible` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | 控制 TaskList 的显隐状态(响应式)。仅在 `enableTaskListCollapsible=true` 时有效 |
#### TaskListColumn 属性
@@ -1791,6 +1793,7 @@ const tasks = ref([
| `timeScaleDimensions` | `TimelineScale[]` | `['hour', 'day', 'week', 'month', 'quarter', 'year']` | 设置时间刻度按钮组要显示的维度,可选值:`'hour'``'day'``'week'``'month'``'quarter'``'year'` |
| `defaultTimeScale` | `TimelineScale` | `'week'` | 默认选中的时间刻度 |
| `showExpandCollapse` | `boolean` | `true` | 显示"全部展开/折叠"按钮(用于父子任务树形结构) |
| `showViewMode` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | `boolean` | `true` | 显示 Task / Resource 视图切换按钮组 |
**TimelineScale 类型说明:**
@@ -2342,6 +2345,9 @@ GanttChart 组件通过 `defineExpose` 暴露了一系列方法,允许父组
| `scrollToToday` ![v1.7.1](https://img.shields.io/badge/v1.7.1-409EFF?style=flat-square&labelColor=ECF5FF) | - | `void` | 滚动到今天的位置 |
| `scrollToTask` ![v1.7.1](https://img.shields.io/badge/v1.7.1-409EFF?style=flat-square&labelColor=ECF5FF) | `taskId: number \| string` | `void` | 滚动到指定任务(任务会自动展开到可见状态) |
| `scrollToDate` ![v1.7.1](https://img.shields.io/badge/v1.7.1-409EFF?style=flat-square&labelColor=ECF5FF) | `date: string \| Date` | `void` | 滚动到指定日期位置(格式:`'YYYY-MM-DD'` 或 Date 对象) |
| `getTaskListVisible` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | - | `boolean` | 获取 TaskList 当前可见状态 |
| `setTaskListVisible` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | `visible: boolean` | `void` | 命令式设置 TaskList 显隐(仅 `enableTaskListCollapsible=true` 时生效) |
| `toggleTaskList` ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF) | - | `void` | 带动画切换 TaskList 展开/收起状态 |
#### 使用示例
@@ -2773,6 +2779,71 @@ const month = formatMonth(3) // '3月' (zh-CN) 或 '03' (en-US)
组件提供了插槽支持,允许自定义任务内容的渲染。
##### `taskbar-tooltip` 插槽 ![v1.9.2](https://img.shields.io/badge/v1.9.2-409EFF?style=flat-square&labelColor=ECF5FF)
用于完全替换 TaskBar 的内置悬停 Tooltip 内容。启用后内置样式不再渲染,由消费方完全控制。
> **前提条件**:需设置 `:enable-taskbar-tooltip="true"`(默认已开启)
**插槽作用域参数(`TaskbarTooltipSlotScope`**
> 组件通过 `<slot :task="..." :task-status="..." />` 提供数据,消费者可用整体对象 `scope` 接收,也可按需解构——所有参数均为**可选**。`task` 是完整的任务对象,自定义字段(如 `task.myField`)均可直接访问。
| 参数名 | 类型 | 说明 |
| --- | --- | --- |
| `task` | `Task` | 当前悬停的任务对象,包含完整的任务数据 |
| `taskStatus` | `{ color: string; label: string }` | 由组件计算好的任务状态(颜色 + 文本),辅助快速显示状态 |
| `resourcePercent` | `number \| null` | 资源占比百分比(资源视图有效,任务视图为 `null` |
**三种写法完全等价:**
```vue
<!-- 写法一整体 scope 对象接收 -->
<template #taskbar-tooltip="scope">
{{ scope.task.name }}
</template>
<!-- 写法二只解构需要的字段 -->
<template #taskbar-tooltip="{ task }">
{{ task.name }}
</template>
<!-- 写法三解构全部字段 -->
<template #taskbar-tooltip="{ task, taskStatus, resourcePercent }">
...
</template>
```
**示例——仅展示任务名称(最简用法):**
```vue
<GanttChart :tasks="tasks">
<template #taskbar-tooltip="{ task }">
<div class="my-simple-tooltip">{{ task.name }}</div>
</template>
</GanttChart>
```
**示例——利用全部作用域参数:**
```vue
<GanttChart :tasks="tasks">
<template #taskbar-tooltip="{ task, taskStatus, resourcePercent }">
<div class="my-tooltip">
<div class="tooltip-title" :style="{ borderColor: taskStatus.color }">
{{ task.name }}
</div>
<div>状态{{ taskStatus.label }}</div>
<div>开始{{ task.startDate }}</div>
<div>结束{{ task.endDate }}</div>
<div v-if="resourcePercent !== null">资源占比{{ resourcePercent }}%</div>
</div>
</template>
</GanttChart>
```
---
##### `custom-task-content` 插槽
用于自定义任务在任务列表TaskRow和时间轴TaskBar中的显示内容。

View File

@@ -552,5 +552,29 @@
"🔧 修复: GanttChart管理ThemeChange的问题",
"🔧 Fixed: Issue with ThemeChange management in GanttChart"
]
},
{
"version": "1.9.2",
"date": "2026-02-26",
"notes": [
"🎉 新增Singleton Tooltip 架构重构,整个 Timeline 共享单一 Tooltip 节点,大幅降低大数据量下的 DOM 开销",
"🎉 新增GanttChart 支持 #taskbar-tooltip 自定义插槽,可完全替换内置 Tooltip 内容",
"🎉 新增GanttChart 新增 enableTaskListCollapsible / taskListVisible Props支持响应式外部控制 TaskList 显隐",
"🎉 新增GanttChart Expose API 新增 getTaskListVisible()、setTaskListVisible()、toggleTaskList() 方法",
"🎉 新增ToolbarConfig 新增 showViewMode 字段,控制视图切换按钮组可见性",
"🔧 修复:异步数据加载后今日定位失效",
"🔧 修复:资源视图切换回任务视图后今日定位偏移",
"🔧 修复GanttToolbar 视图切换按钮组 showViewMode:false 设置不生效",
"<span style=\"font-weight: bold; color: #f00;\">特别感谢来自德国柏林的 Andrés Jorge 使用与反馈</span>",
"🎉 Added: Singleton Tooltip architecture refactored — Timeline shares a single Tooltip node, greatly reducing DOM overhead for large datasets",
"🎉 Added: GanttChart supports #taskbar-tooltip custom scoped slot to fully replace built-in Tooltip content",
"🎉 Added: GanttChart new props enableTaskListCollapsible / taskListVisible for reactive external TaskList visibility control",
"🎉 Added: GanttChart Expose API adds getTaskListVisible(), setTaskListVisible(), toggleTaskList() methods",
"🎉 Added: ToolbarConfig adds showViewMode field to control view-mode toggle button group visibility",
"🔧 Fixed: Today marker lost after async data load",
"🔧 Fixed: Today marker offset after switching from resource view back to task view",
"🔧 Fixed: GanttToolbar showViewMode:false had no effect due to missing v-if guard",
"<span style=\"font-weight: bold; color: #f00;\">Special thanks to Andrés Jorge from Berlin, Germany for their use and feedback</span>"
]
}
]

View File

@@ -1,6 +1,6 @@
{
"name": "jordium-gantt-vue3",
"version": "1.9.2-rc.1",
"version": "1.9.2",
"type": "module",
"main": "npm-package/dist/jordium-gantt-vue3.cjs.js",
"module": "npm-package/dist/jordium-gantt-vue3.es.js",

View File

@@ -4661,15 +4661,25 @@ watch([timelineData, timelineContainerWidth], () => {
// 监听viewMode和dataSource变化刷新缓存和时间线
watch(
[viewMode, dataSource],
([newViewMode]) => {
([newViewMode], [oldViewMode]) => {
invalidateTaskDateRangeCache()
// bugfix: 切换回任务视图时重置 hasInitialAutoScroll确保 updateTimelineRange 完成后能重新定位今日
// 场景资源视图切换回任务视图时updateTimelineRange 重新计算任务范围导致像素偏移,
// 若不重置则 scrollToTodayCenter 不会被触发,今日标记将出现在视口之外
const viewModeChanged = newViewMode !== oldViewMode
if (newViewMode === 'task') {
// bugfix: 切换回任务视图时重置 hasInitialAutoScroll确保 updateTimelineRange 完成后能重新定位今日
// 场景资源视图切换回任务视图时updateTimelineRange 重新计算任务范围导致像素偏移,
// 若不重置则 scrollToTodayCenter 不会被触发,今日标记将出现在视口之外
hasInitialAutoScroll = false
debouncedUpdateTimelineRange()
} else if (newViewMode === 'resource') {
if (viewModeChanged) {
// bugfix: 切换到资源视图时直接调用 scrollToTodayCenter
// 原因updateTimelineRange() 在 resource 视图下直接返回(不更新 timelineData/timelineConfig
// 导致内层 watch 无法触发timeline 保留任务视图中拖拽后的偏移位置
// 注意:切换视图不重新挂载 DOMtimelineContainerElement 始终可用,
// nextTick 后直接调用即可scrollToTodayCenter 内部有重试机制无需额外 setTimeout
nextTick(() => scrollToTodayCenter())
}
}
debouncedUpdateTimelineRange()
},
)