@operato/gantt 8.0.0-beta.0 β 8.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/package.json +5 -5
- package/.editorconfig +0 -29
- package/.storybook/main.js +0 -3
- package/.storybook/preview.js +0 -52
- package/.storybook/server.mjs +0 -8
- package/demo/index.html +0 -22
- package/src/draw-time-scale-header.ts +0 -142
- package/src/gantt-chart-controller.ts +0 -402
- package/src/index.ts +0 -0
- package/src/locales.ts +0 -78
- package/src/ox-gantt-chart.ts +0 -418
- package/src/ox-gantt-resize-splitter.ts +0 -159
- package/src/ox-gantt.ts +0 -535
- package/src/ox-resource-chart.ts +0 -147
- package/src/ox-task-tooltip.ts +0 -142
- package/src/resource-chart-controller.ts +0 -284
- package/src/types.ts +0 -33
- package/src/utils.ts +0 -13
- package/stories/ox-gantt-chart.stories.ts +0 -125
- package/stories/ox-gantt.stories.ts +0 -453
- package/tsconfig.json +0 -25
- package/web-dev-server.config.mjs +0 -27
- package/web-test-runner.config.mjs +0 -41
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,24 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [8.0.0-beta.2](https://github.com/hatiolab/operato/compare/v8.0.0-beta.1...v8.0.0-beta.2) (2025-01-08)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### :bug: Bug Fix
|
|
10
|
+
|
|
11
|
+
* typo .npmignore ([d9c0c8c](https://github.com/hatiolab/operato/commit/d9c0c8c79abc688c3c2cfb6c37fcb689483a5977))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## [8.0.0-beta.1](https://github.com/hatiolab/operato/compare/v8.0.0-beta.0...v8.0.0-beta.1) (2025-01-08)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### :bug: Bug Fix
|
|
19
|
+
|
|
20
|
+
* missing .npmignore ([be05985](https://github.com/hatiolab/operato/commit/be05985abfae4af53501f718dd52932099f7fbcb))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
6
24
|
## [8.0.0-beta.0](https://github.com/hatiolab/operato/compare/v8.0.0-alpha.56...v8.0.0-beta.0) (2025-01-07)
|
|
7
25
|
|
|
8
26
|
**Note:** Version bump only for package @operato/gantt
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@operato/gantt",
|
|
3
3
|
"description": "Webcomponents for gantt chart following open-wc recommendations",
|
|
4
4
|
"author": "heartyoh@hatiolab.com",
|
|
5
|
-
"version": "8.0.0-beta.
|
|
5
|
+
"version": "8.0.0-beta.2",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
7
7
|
"module": "dist/src/index.js",
|
|
8
8
|
"license": "MIT",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@operato/i18n": "^8.0.0-beta.
|
|
46
|
-
"@operato/styles": "^8.0.0-beta.
|
|
47
|
-
"@operato/utils": "^8.0.0-beta.
|
|
45
|
+
"@operato/i18n": "^8.0.0-beta.2",
|
|
46
|
+
"@operato/styles": "^8.0.0-beta.2",
|
|
47
|
+
"@operato/utils": "^8.0.0-beta.2",
|
|
48
48
|
"d3": "^7.8.5",
|
|
49
49
|
"d3-time-format": "^4.1.0",
|
|
50
50
|
"i18next": "^23.11.5",
|
|
@@ -85,5 +85,5 @@
|
|
|
85
85
|
"prettier --write"
|
|
86
86
|
]
|
|
87
87
|
},
|
|
88
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "ee1b5124995accb99272d3b5854f3df1d8746dda"
|
|
89
89
|
}
|
package/.editorconfig
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# EditorConfig helps developers define and maintain consistent
|
|
2
|
-
# coding styles between different editors and IDEs
|
|
3
|
-
# editorconfig.org
|
|
4
|
-
|
|
5
|
-
root = true
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
[*]
|
|
9
|
-
|
|
10
|
-
# Change these settings to your own preference
|
|
11
|
-
indent_style = space
|
|
12
|
-
indent_size = 2
|
|
13
|
-
|
|
14
|
-
# We recommend you to keep these unchanged
|
|
15
|
-
end_of_line = lf
|
|
16
|
-
charset = utf-8
|
|
17
|
-
trim_trailing_whitespace = true
|
|
18
|
-
insert_final_newline = true
|
|
19
|
-
|
|
20
|
-
[*.md]
|
|
21
|
-
trim_trailing_whitespace = false
|
|
22
|
-
|
|
23
|
-
[*.json]
|
|
24
|
-
indent_size = 2
|
|
25
|
-
|
|
26
|
-
[*.{html,js,md}]
|
|
27
|
-
block_comment_start = /**
|
|
28
|
-
block_comment = *
|
|
29
|
-
block_comment_end = */
|
package/.storybook/main.js
DELETED
package/.storybook/preview.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { i18next } from '@operato/i18n'
|
|
2
|
-
|
|
3
|
-
export const globalTypes = {
|
|
4
|
-
locale: {
|
|
5
|
-
name: 'Locale',
|
|
6
|
-
description: 'Internationalization locale',
|
|
7
|
-
toolbar: {
|
|
8
|
-
icon: 'globe',
|
|
9
|
-
items: [
|
|
10
|
-
{ value: 'en', right: 'πΊπΈ', title: 'English' },
|
|
11
|
-
{ value: 'ko', right: 'π°π·', title: 'νκ΅μ΄' },
|
|
12
|
-
{ value: 'zh', right: 'π¨π³', title: 'δΈζ' },
|
|
13
|
-
{ value: 'ja', right: 'π―π΅', title: 'ζ₯ζ¬θͺ' },
|
|
14
|
-
{ value: 'ms', right: 'π²πΎ', title: 'Bahasa Melayu' }
|
|
15
|
-
],
|
|
16
|
-
showName: true
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
theme: {
|
|
20
|
-
name: 'Theme',
|
|
21
|
-
description: 'Global theme for components',
|
|
22
|
-
toolbar: {
|
|
23
|
-
icon: 'paintbrush',
|
|
24
|
-
items: [
|
|
25
|
-
{ value: 'light', title: 'Light' },
|
|
26
|
-
{ value: 'dark', title: 'Dark' }
|
|
27
|
-
],
|
|
28
|
-
showName: true
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export const decorators = [
|
|
34
|
-
(Story, context) => {
|
|
35
|
-
const { locale, theme } = context.globals
|
|
36
|
-
|
|
37
|
-
if (locale) {
|
|
38
|
-
i18next.changeLanguage(locale)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Set the theme class for the document
|
|
42
|
-
if (theme === 'dark') {
|
|
43
|
-
document.documentElement.classList.add('dark')
|
|
44
|
-
document.documentElement.classList.remove('light')
|
|
45
|
-
} else {
|
|
46
|
-
document.documentElement.classList.add('light')
|
|
47
|
-
document.documentElement.classList.remove('dark')
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return Story()
|
|
51
|
-
}
|
|
52
|
-
]
|
package/.storybook/server.mjs
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { storybookPlugin } from '@web/dev-server-storybook'
|
|
2
|
-
import baseConfig from '../web-dev-server.config.mjs'
|
|
3
|
-
|
|
4
|
-
export default /** @type {import('@web/dev-server').DevServerConfig} */ ({
|
|
5
|
-
...baseConfig,
|
|
6
|
-
open: '/',
|
|
7
|
-
plugins: [storybookPlugin({ type: 'web-components' }), ...baseConfig.plugins]
|
|
8
|
-
})
|
package/demo/index.html
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en-GB">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1" />
|
|
6
|
-
<style>
|
|
7
|
-
body {
|
|
8
|
-
background: #fafafa;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
a {
|
|
12
|
-
display: block;
|
|
13
|
-
}
|
|
14
|
-
</style>
|
|
15
|
-
<link href="/themes/app-theme.css" rel="stylesheet" />
|
|
16
|
-
<link href="/themes/input-theme.css" rel="stylesheet" />
|
|
17
|
-
<link href="https://fonts.googleapis.com/css?family=Material+Icons&display=block" rel="stylesheet" />
|
|
18
|
-
</head>
|
|
19
|
-
<body>
|
|
20
|
-
<a href="./index-select.html">select</a>
|
|
21
|
-
</body>
|
|
22
|
-
</html>
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import * as d3 from 'd3'
|
|
2
|
-
import { TimeScale } from './types'
|
|
3
|
-
|
|
4
|
-
export function drawTimeScaleHeader(
|
|
5
|
-
svgHeader: SVGElement,
|
|
6
|
-
timeScale: d3.ScaleTime<number, number, never>,
|
|
7
|
-
fromTime: Date,
|
|
8
|
-
toTime: Date,
|
|
9
|
-
baseWidth: number,
|
|
10
|
-
level: TimeScale,
|
|
11
|
-
isTwoLevelHeader: boolean = true
|
|
12
|
-
) {
|
|
13
|
-
const header = d3.select(svgHeader)
|
|
14
|
-
|
|
15
|
-
header.selectAll('*').remove()
|
|
16
|
-
header.attr('width', getChartWidth(fromTime, toTime, baseWidth, level))
|
|
17
|
-
|
|
18
|
-
if (!isTwoLevelHeader) {
|
|
19
|
-
header.attr('height', '30px')
|
|
20
|
-
} else {
|
|
21
|
-
header.attr('height', '40px')
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const addGridLines = (ticks: Date[], yStart: number, yEnd: number) => {
|
|
25
|
-
ticks.forEach(tick => {
|
|
26
|
-
const startX = timeScale(tick)
|
|
27
|
-
header
|
|
28
|
-
.append('line')
|
|
29
|
-
.attr('x1', startX)
|
|
30
|
-
.attr('x2', startX)
|
|
31
|
-
.attr('y1', yStart)
|
|
32
|
-
.attr('y2', yEnd)
|
|
33
|
-
.attr('stroke', 'var(--ox-gantt-color-gridlines, var(--md-sys-color-outline))')
|
|
34
|
-
.attr('stroke-width', 1)
|
|
35
|
-
})
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const centerLabel = (
|
|
39
|
-
selection: d3.Selection<SVGGElement, unknown, null, undefined>,
|
|
40
|
-
tickInterval: d3.CountableTimeInterval
|
|
41
|
-
) => {
|
|
42
|
-
selection.selectAll('text').attr('transform', (d: any) => {
|
|
43
|
-
const tickIntervalWidth = timeScale(tickInterval.offset(d, 1)) - timeScale(d)
|
|
44
|
-
return `translate(${tickIntervalWidth / 2}, ${isTwoLevelHeader ? -2 : -8})`
|
|
45
|
-
})
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const drawLevel = (
|
|
49
|
-
mainTicks: Date[],
|
|
50
|
-
mainFormat: (d: Date) => string,
|
|
51
|
-
mainInterval: d3.CountableTimeInterval,
|
|
52
|
-
detailTicks: Date[],
|
|
53
|
-
detailFormat: (d: Date) => string,
|
|
54
|
-
detailInterval: d3.CountableTimeInterval
|
|
55
|
-
) => {
|
|
56
|
-
if (isTwoLevelHeader) {
|
|
57
|
-
const mainAxis = d3
|
|
58
|
-
.axisTop(timeScale)
|
|
59
|
-
.ticks(mainInterval)
|
|
60
|
-
.tickFormat(mainFormat as any)
|
|
61
|
-
.tickSize(0)
|
|
62
|
-
addGridLines(mainTicks, 0, 20)
|
|
63
|
-
|
|
64
|
-
const mainAxisG = header
|
|
65
|
-
.append('g')
|
|
66
|
-
.classed('main-axis no-select md-typescale-label-small', true)
|
|
67
|
-
.attr('transform', 'translate(0, 20)')
|
|
68
|
-
.call(mainAxis)
|
|
69
|
-
|
|
70
|
-
centerLabel(mainAxisG, mainInterval)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const detailAxis = d3
|
|
74
|
-
.axisTop(timeScale)
|
|
75
|
-
.ticks(detailInterval)
|
|
76
|
-
.tickFormat(detailFormat as any)
|
|
77
|
-
.tickSize(0)
|
|
78
|
-
addGridLines(detailTicks, isTwoLevelHeader ? 20 : 0, isTwoLevelHeader ? 40 : 30)
|
|
79
|
-
|
|
80
|
-
const detailAxisG = header
|
|
81
|
-
.append('g')
|
|
82
|
-
.classed('detail-axis no-select md-typescale-label-small', true)
|
|
83
|
-
.attr('transform', `translate(0, ${isTwoLevelHeader ? 40 : 30})`)
|
|
84
|
-
.call(detailAxis)
|
|
85
|
-
|
|
86
|
-
centerLabel(detailAxisG, detailInterval)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (level === 'week-day') {
|
|
90
|
-
drawLevel(
|
|
91
|
-
d3.timeWeek.every(1)!.range(d3.timeWeek.floor(fromTime), d3.timeWeek.offset(toTime, 1)),
|
|
92
|
-
d3.timeFormat('%B %d'),
|
|
93
|
-
d3.timeWeek,
|
|
94
|
-
d3.timeDay.every(1)!.range(d3.timeDay.floor(fromTime), d3.timeDay.offset(toTime, 1)),
|
|
95
|
-
d3.timeFormat('%d'),
|
|
96
|
-
d3.timeDay
|
|
97
|
-
)
|
|
98
|
-
} else if (level === 'quarter-week') {
|
|
99
|
-
drawLevel(
|
|
100
|
-
d3.timeMonth.every(3)!.range(d3.timeMonth.floor(fromTime), d3.timeMonth.offset(toTime, 3)),
|
|
101
|
-
d3.timeFormat('%Y %b'),
|
|
102
|
-
d3.timeMonth.every(3)! as any,
|
|
103
|
-
d3.timeWeek.every(1)!.range(d3.timeWeek.floor(fromTime), d3.timeWeek.offset(toTime, 1)),
|
|
104
|
-
d3.timeFormat('%b %d'),
|
|
105
|
-
d3.timeWeek
|
|
106
|
-
)
|
|
107
|
-
} else if (level === 'year-month') {
|
|
108
|
-
drawLevel(
|
|
109
|
-
d3.timeYear.every(1)!.range(d3.timeYear.floor(fromTime), d3.timeYear.offset(toTime, 1)),
|
|
110
|
-
d3.timeFormat('%Y'),
|
|
111
|
-
d3.timeYear,
|
|
112
|
-
d3.timeMonth.every(1)!.range(d3.timeMonth.floor(fromTime), d3.timeMonth.offset(toTime, 1)),
|
|
113
|
-
d3.timeFormat('%b'),
|
|
114
|
-
d3.timeMonth
|
|
115
|
-
)
|
|
116
|
-
} else if (level === 'year-quarter') {
|
|
117
|
-
drawLevel(
|
|
118
|
-
d3.timeYear.every(1)!.range(d3.timeYear.floor(fromTime), d3.timeYear.offset(toTime, 1)),
|
|
119
|
-
d3.timeFormat('%Y'),
|
|
120
|
-
d3.timeYear,
|
|
121
|
-
d3.timeMonth.every(3)!.range(d3.timeMonth.floor(fromTime), d3.timeMonth.offset(toTime, 3)),
|
|
122
|
-
d3.timeFormat('%Y %b'),
|
|
123
|
-
d3.timeMonth.every(3)! as any
|
|
124
|
-
)
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export function getChartWidth(fromTime: Date, toTime: Date, baseWidth: number, level: TimeScale): number {
|
|
129
|
-
const totalDays = d3.timeDay.count(fromTime, d3.timeDay.offset(toTime, 1))
|
|
130
|
-
return (totalDays * baseWidth) / getScale(level)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export function getScale(level: TimeScale): number {
|
|
134
|
-
if (level === 'quarter-week') {
|
|
135
|
-
return 7 / 2
|
|
136
|
-
} else if (level === 'year-month') {
|
|
137
|
-
return 30 / 2
|
|
138
|
-
} else if (level === 'year-quarter') {
|
|
139
|
-
return 90 / 2
|
|
140
|
-
}
|
|
141
|
-
return 1
|
|
142
|
-
}
|