Skip to content

Commit 66635b2

Browse files
authored
Merge pull request #5072 from VisActor/feat/gantt-autoLocationIcon
Feat/gantt auto location icon
2 parents 513360a + 85c8ebd commit 66635b2

15 files changed

Lines changed: 517 additions & 5 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"changes": [
3+
{
4+
"comment": "feat: gantt add locateIcon for taskbar\n\n",
5+
"type": "none",
6+
"packageName": "@visactor/vtable"
7+
}
8+
],
9+
"packageName": "@visactor/vtable",
10+
"email": "892739385@qq.com"
11+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
category: examples
3+
group: gantt
4+
title: Task Bar Locate (Offscreen Indicator)
5+
cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/gantt/gantt-locate-taskbar.gif
6+
link: gantt/Getting_Started
7+
option: Gantt#taskBar
8+
---
9+
10+
# Task Bar Locate (Offscreen Indicator)
11+
12+
When the timeline is long, task bars may be outside the current viewport. This demo shows how to enable the locate icon feature: when a task bar is horizontally outside the viewport, an icon is displayed at the left/right edge of the gantt view; hover highlights it, and click scrolls the task bar into view.
13+
14+
## Key Option
15+
16+
- `taskBar.locateIcon: true`
17+
18+
## Live Demo
19+
20+
```javascript livedemo template=vtable
21+
// import * as VTableGantt from '@visactor/vtable-gantt';
22+
let ganttInstance;
23+
24+
const records = [
25+
{ id: 1, title: 'Offscreen on the left', start: '2024-02-05', end: '2024-02-20', progress: 20 },
26+
{ id: 2, title: 'Offscreen on the left', start: '2024-03-10', end: '2024-03-18', progress: 60 },
27+
{ id: 5, title: 'Visible in viewport', start: '2024-05-28', end: '2024-06-05', progress: 50 },
28+
{ id: 3, title: 'Offscreen on the right', start: '2024-10-05', end: '2024-10-20', progress: 40 },
29+
{ id: 4, title: 'Offscreen on the right', start: '2024-11-10', end: '2024-11-25', progress: 80 }
30+
];
31+
32+
const columns = [
33+
{ field: 'title', title: 'title', width: 160, sort: true },
34+
{ field: 'start', title: 'start', width: 120, sort: true },
35+
{ field: 'end', title: 'end', width: 120, sort: true },
36+
{ field: 'progress', title: 'progress', width: 100, sort: true }
37+
];
38+
39+
const option = {
40+
records,
41+
taskKeyField: 'id',
42+
taskListTable: {
43+
columns,
44+
tableWidth: 280,
45+
minTableWidth: 240,
46+
maxTableWidth: 600
47+
},
48+
taskBar: {
49+
startDateField: 'start',
50+
endDateField: 'end',
51+
progressField: 'progress',
52+
locateIcon: true
53+
},
54+
minDate: '2024-01-01',
55+
maxDate: '2024-12-31',
56+
timelineHeader: {
57+
colWidth: 30,
58+
scales: [{ unit: 'day', step: 1 }]
59+
},
60+
scrollStyle: {
61+
visible: 'scrolling'
62+
},
63+
grid: {
64+
verticalLine: { lineWidth: 1, lineColor: '#e1e4e8' },
65+
horizontalLine: { lineWidth: 1, lineColor: '#e1e4e8' }
66+
}
67+
};
68+
69+
ganttInstance = new VTableGantt.Gantt(document.getElementById(CONTAINER_ID), option);
70+
window['ganttInstance'] = ganttInstance;
71+
72+
setTimeout(() => {
73+
const x = ganttInstance.getXByTime(new Date('2024-06-01 00:00:00').getTime());
74+
ganttInstance.scrollLeft = x;
75+
}, 0);
76+
```
77+

docs/assets/demo/menu.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,13 @@
314314
"en": "Gantt Basic"
315315
}
316316
},
317+
{
318+
"path": "gantt-locate-taskbar",
319+
"title": {
320+
"zh": "任务条定位(超出可视区)",
321+
"en": "Task Bar Locate"
322+
}
323+
},
317324
{
318325
"path": "gantt-customLayout",
319326
"title": {
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
category: examples
3+
group: gantt
4+
title: 甘特图任务条定位(超出可视区提示)
5+
cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/VTable/gantt/gantt-locate-taskbar.gif
6+
link: gantt/Getting_Started
7+
option: Gantt#taskBar
8+
---
9+
10+
# 甘特图任务条定位(超出可视区提示)
11+
12+
当时间轴很长时,任务条可能不在当前可视区域内。本示例展示如何开启定位图标能力:当任务条横向超出可视区域时,在甘特图左右边缘显示定位图标;鼠标 hover 会高亮,点击后会自动滚动将任务条带入可视区域。
13+
14+
## 关键配置
15+
16+
- `taskBar.locateIcon: true`
17+
18+
## 代码演示
19+
20+
```javascript livedemo template=vtable
21+
// import * as VTableGantt from '@visactor/vtable-gantt';
22+
let ganttInstance;
23+
24+
const records = [
25+
{ id: 1, title: '任务条在左侧不可见', start: '2024-02-05', end: '2024-02-20', progress: 20 },
26+
{ id: 2, title: '任务条在左侧不可见', start: '2024-03-10', end: '2024-03-18', progress: 60 },
27+
{ id: 5, title: '任务条在可见区', start: '2024-05-28', end: '2024-06-05', progress: 50 },
28+
{ id: 3, title: '任务条在右侧不可见', start: '2024-10-05', end: '2024-10-20', progress: 40 },
29+
{ id: 4, title: '任务条在右侧不可见', start: '2024-11-10', end: '2024-11-25', progress: 80 }
30+
];
31+
32+
const columns = [
33+
{ field: 'title', title: 'title', width: 160, sort: true },
34+
{ field: 'start', title: 'start', width: 120, sort: true },
35+
{ field: 'end', title: 'end', width: 120, sort: true },
36+
{ field: 'progress', title: 'progress', width: 100, sort: true }
37+
];
38+
39+
const option = {
40+
records,
41+
taskKeyField: 'id',
42+
taskListTable: {
43+
columns,
44+
tableWidth: 280,
45+
minTableWidth: 240,
46+
maxTableWidth: 600
47+
},
48+
taskBar: {
49+
startDateField: 'start',
50+
endDateField: 'end',
51+
progressField: 'progress',
52+
locateIcon: true
53+
},
54+
minDate: '2024-01-01',
55+
maxDate: '2024-12-31',
56+
timelineHeader: {
57+
colWidth: 30,
58+
scales: [{ unit: 'day', step: 1 }]
59+
},
60+
scrollStyle: {
61+
visible: 'scrolling'
62+
},
63+
grid: {
64+
verticalLine: { lineWidth: 1, lineColor: '#e1e4e8' },
65+
horizontalLine: { lineWidth: 1, lineColor: '#e1e4e8' }
66+
}
67+
};
68+
69+
ganttInstance = new VTableGantt.Gantt(document.getElementById(CONTAINER_ID), option);
70+
window['ganttInstance'] = ganttInstance;
71+
72+
setTimeout(() => {
73+
const x = ganttInstance.getXByTime(new Date('2024-06-01 00:00:00').getTime());
74+
ganttInstance.scrollLeft = x;
75+
}, 0);
76+
```
77+

docs/assets/guide/en/gantt/introduction.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ You can set whether task bars are resizable through the `taskBar.resizable` conf
133133

134134
You can set whether task bars are adjustable through the `taskBar.progressAdjustable` configuration item.
135135

136+
#### Task Bar Locate
137+
138+
When the timeline is long and the task bar is outside the current viewport, you can enable the “locate icon” feature: an icon is shown on the left/right edge of the gantt view, and clicking it scrolls the task bar into the viewport.
139+
140+
Key option:
141+
142+
```javascript
143+
const option = {
144+
taskBar: {
145+
locateIcon: true
146+
}
147+
};
148+
```
149+
136150
#### Adjusting the Width of the Left Table
137151

138152
You can set the divider line to be draggable by configuring `frame.verticalSplitLineMoveable` to true.

docs/assets/guide/zh/gantt/introduction.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ links:[
133133

134134
通过 `taskBar.progressAdjustable` 配置项,可以设置任务条是否可调整进度。
135135

136+
#### 任务条定位
137+
138+
当时间轴较长、任务条不在当前可视区域内时,可以开启“定位图标”能力:在甘特图左右边缘显示图标,点击后自动滚动到该任务条的可视区域。
139+
140+
关键配置:
141+
142+
```javascript
143+
const option = {
144+
taskBar: {
145+
locateIcon: true
146+
}
147+
};
148+
```
149+
136150
#### 调整左侧表格宽度
137151

138152
通过 `frame.verticalSplitLineMoveable` 配置为 true,可以设置分割线可拖拽。

docs/assets/option/en/common/gantt/task-bar.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ Whether the service clause is optional, the default is true
171171

172172
Not required
173173

174+
${prefix} locateIcon(boolean) = false
175+
176+
When the task bar is horizontally outside the current viewport, show a “locate icon” at the left/right edge of the gantt view. Hover highlights the icon, and click scrolls the task bar into the viewport.
177+
178+
Optional
179+
174180
${prefix} scheduleCreatable(boolean | Function) = true
175181

176182
When there is no scheduling data, scheduling can be done by creating a task bar. When `tasksShowMode` is `TasksShowMode.Tasks_Separate` or `TasksShowMode.Sub_Tasks_Separate`, `scheduleCreatable` defaults to `true`, otherwise, when `tasksShowMode` is `TasksShowMode.Sub_Tasks_Inline`, `TasksShowMode.Sub_Tasks_Arrange`, or `TasksShowMode.Sub_Tasks_Compact`, `scheduleCreatable` defaults to `false`.
@@ -267,4 +273,3 @@ Vertical position of the baseline bar relative to the main task bar:
267273
- `overlap`: baseline overlaps and is centered with the task bar.
268274

269275
Optional
270-

docs/assets/option/zh/common/gantt/task-bar.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,12 @@ ${prefix} selectable(boolean)
176176

177177
非必填
178178

179+
${prefix} locateIcon(boolean) = false
180+
181+
当任务条在横向上不在当前可视区域内时,在甘特图左右边缘展示“定位图标”;鼠标 hover 会高亮,点击后会一键滚动到任务条可视区域内。
182+
183+
非必填
184+
179185
${prefix} scheduleCreatable(boolean | Function) = true
180186

181187
数据没有排期时,可通过创建任务条排期。当 tasksShowMode 为 TasksShowMode.Tasks_Separate 或 TasksShowMode.Sub_Tasks_Separate 时 `scheduleCreatable` 默认为 true,其他情况即当 tasksShowMode 为 TasksShowMode.Sub_Tasks_Inline 或 TasksShowMode.Sub_Tasks_Arrange 或 TasksShowMode.Sub_Tasks_Compact 时 `scheduleCreatable` 默认为 false
@@ -273,4 +279,3 @@ ${prefix} baselinePosition('top' | 'bottom' | 'overlap') = 'bottom'
273279
- `overlap`:基线与主任务条重叠居中。
274280

275281
非必填
276-
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import type { ColumnsDefine } from '@visactor/vtable';
2+
import type { GanttConstructorOptions } from '../../src/index';
3+
import { Gantt } from '../../src/index';
4+
5+
const CONTAINER_ID = 'vTable';
6+
7+
export function createTable() {
8+
const records = [
9+
{ id: 1, title: '任务条在左侧不可见', start: '2024-02-05', end: '2024-02-20', progress: 20 },
10+
{ id: 2, title: '任务条在左侧不可见', start: '2024-03-10', end: '2024-03-18', progress: 60 },
11+
{ id: 5, title: '任务条在可见区', start: '2024-05-28', end: '2024-06-05', progress: 50 },
12+
{ id: 3, title: '任务条在右侧不可见', start: '2024-10-05', end: '2024-10-20', progress: 40 },
13+
{ id: 4, title: '任务条在右侧不可见', start: '2024-11-10', end: '2024-11-25', progress: 80 }
14+
];
15+
16+
const columns: ColumnsDefine = [
17+
{ field: 'title', title: 'title', width: 160, sort: true },
18+
{ field: 'start', title: 'start', width: 120, sort: true },
19+
{ field: 'end', title: 'end', width: 120, sort: true },
20+
{ field: 'progress', title: 'progress', width: 100, sort: true }
21+
];
22+
23+
const option: GanttConstructorOptions = {
24+
records,
25+
taskListTable: {
26+
columns,
27+
tableWidth: 280,
28+
minTableWidth: 240,
29+
maxTableWidth: 600
30+
},
31+
taskKeyField: 'id',
32+
taskBar: {
33+
startDateField: 'start',
34+
endDateField: 'end',
35+
progressField: 'progress',
36+
locateIcon: true
37+
},
38+
minDate: '2024-01-01',
39+
maxDate: '2024-12-31',
40+
timelineHeader: {
41+
colWidth: 30,
42+
scales: [{ unit: 'day', step: 1 }]
43+
},
44+
scrollStyle: {
45+
visible: 'scrolling'
46+
},
47+
grid: {
48+
// backgroundColor: 'gray',
49+
verticalLine: {
50+
lineWidth: 1,
51+
lineColor: '#e1e4e8'
52+
},
53+
horizontalLine: {
54+
lineWidth: 1,
55+
lineColor: '#e1e4e8'
56+
}
57+
}
58+
};
59+
60+
const ganttInstance = new Gantt(document.getElementById(CONTAINER_ID)!, option);
61+
(window as any).ganttInstance = ganttInstance;
62+
63+
setTimeout(() => {
64+
const x = ganttInstance.getXByTime(new Date('2024-06-01 00:00:00').getTime());
65+
ganttInstance.scrollLeft = x;
66+
}, 0);
67+
}

packages/vtable-gantt/examples/menu.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ export const menus = [
170170
{
171171
path: 'gantt',
172172
name: 'project-sub-tasks-inline'
173+
},
174+
{
175+
path: 'gantt',
176+
name: 'gantt-locate-taskbar'
173177
}
174178
// ]
175179
// }

0 commit comments

Comments
 (0)