From 34f00d52907e13954a0a32c284a9d0cec2cba24c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E9=A2=96=E6=96=8C?= Date: Wed, 13 Oct 2021 10:21:58 +0800 Subject: [PATCH 1/7] feat: init gantt --- devui/gantt/__tests__/gantt.spec.ts | 8 +++++ devui/gantt/index.ts | 17 +++++++++ devui/gantt/src/gantt-types.ts | 9 +++++ devui/gantt/src/gantt.scss | 3 ++ devui/gantt/src/gantt.tsx | 14 ++++++++ docs/components/gantt/index.md | 55 +++++++++++++++++++++++++++++ package.json | 2 +- 7 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 devui/gantt/__tests__/gantt.spec.ts create mode 100644 devui/gantt/index.ts create mode 100644 devui/gantt/src/gantt-types.ts create mode 100644 devui/gantt/src/gantt.scss create mode 100644 devui/gantt/src/gantt.tsx create mode 100644 docs/components/gantt/index.md diff --git a/devui/gantt/__tests__/gantt.spec.ts b/devui/gantt/__tests__/gantt.spec.ts new file mode 100644 index 00000000..321977ee --- /dev/null +++ b/devui/gantt/__tests__/gantt.spec.ts @@ -0,0 +1,8 @@ +import { mount } from '@vue/test-utils'; +import { Gantt } from '../index'; + +describe('gantt test', () => { + it('gantt init render', async () => { + // todo + }) +}) diff --git a/devui/gantt/index.ts b/devui/gantt/index.ts new file mode 100644 index 00000000..5b94ee46 --- /dev/null +++ b/devui/gantt/index.ts @@ -0,0 +1,17 @@ +import type { App } from 'vue' +import Gantt from './src/gantt' + +Gantt.install = function(app: App): void { + app.component(Gantt.name, Gantt) +} + +export { Gantt } + +export default { + title: 'Gantt 甘特图', + category: '数据展示', + status: undefined, // TODO: 组件若开发完成则填入"已完成",并删除该注释 + install(app: App): void { + app.use(Gantt as any) + } +} diff --git a/devui/gantt/src/gantt-types.ts b/devui/gantt/src/gantt-types.ts new file mode 100644 index 00000000..d075835d --- /dev/null +++ b/devui/gantt/src/gantt-types.ts @@ -0,0 +1,9 @@ +import type { PropType, ExtractPropTypes } from 'vue' + +export const ganttProps = { + /* test: { + type: Object as PropType<{ xxx: xxx }> + } */ +} as const + +export type GanttProps = ExtractPropTypes diff --git a/devui/gantt/src/gantt.scss b/devui/gantt/src/gantt.scss new file mode 100644 index 00000000..3633bdfe --- /dev/null +++ b/devui/gantt/src/gantt.scss @@ -0,0 +1,3 @@ +.devui-gantt { + // +} diff --git a/devui/gantt/src/gantt.tsx b/devui/gantt/src/gantt.tsx new file mode 100644 index 00000000..a142b80a --- /dev/null +++ b/devui/gantt/src/gantt.tsx @@ -0,0 +1,14 @@ +import { defineComponent } from 'vue' +import { ganttProps, GanttProps } from './gantt-types' +import './gantt.scss' + +export default defineComponent({ + name: 'DGantt', + props: ganttProps, + emits: [], + setup(props: GanttProps, ctx) { + return ( +
+ ) + } +}) diff --git a/docs/components/gantt/index.md b/docs/components/gantt/index.md new file mode 100644 index 00000000..6e4a8a65 --- /dev/null +++ b/docs/components/gantt/index.md @@ -0,0 +1,55 @@ +# Gantt 甘特图 + +// todo 组件描述 + +### 何时使用 + +// todo 使用时机描述 + + +### 基本用法 +// todo 用法描述 +:::demo // todo 展开代码的内部描述 + +```vue + + + + + +``` + +::: + +### d-gantt + +d-gantt 参数 + +| 参数 | 类型 | 默认 | 说明 | 跳转 Demo | 全局配置项 | +| ---- | ---- | ---- | ---- | --------- | --------- | +| | | | | | | +| | | | | | | +| | | | | | | + +d-gantt 事件 + +| 事件 | 类型 | 说明 | 跳转 Demo | +| ---- | ---- | ---- | --------- | +| | | | | +| | | | | +| | | | | + diff --git a/package.json b/package.json index e66cd27e..61a7c332 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "commander": "^8.1.0", "esbuild-register": "^2.6.0", "eslint": "^7.28.0", - "eslint-plugin-import": "^2.24.2", + "eslint-plugin-import": "^2.25.2", "eslint-plugin-vue": "^7.11.1", "husky": "^4.3.7", "inquirer": "^8.1.2", -- Gitee From 2bdacc031ad2f5dfa0f19ec96a57af706ecd965d Mon Sep 17 00:00:00 2001 From: ElsaOOo Date: Thu, 14 Oct 2021 10:24:03 +0800 Subject: [PATCH 2/7] =?UTF-8?q?feat(gantt):=20gantt-milestone=20gantt-scal?= =?UTF-8?q?e=20gantt-tools=E5=88=9D=E5=A7=8B=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/gantt-milestone/gantt-milestone.scss | 17 ++ devui/gantt/src/gantt-milestone/index.tsx | 32 +++ .../src/gantt-milestone/milestone-icon.tsx | 212 ++++++++++++++++++ devui/gantt/src/gantt-model.ts | 61 +++++ devui/gantt/src/gantt-scale/gantt-scale.scss | 175 +++++++++++++++ devui/gantt/src/gantt-scale/index.tsx | 157 +++++++++++++ devui/gantt/src/gantt-scale/use-scale-data.ts | 92 ++++++++ devui/gantt/src/gantt-tools/gantt-tools.scss | 63 ++++++ devui/gantt/src/gantt-tools/index.tsx | 96 ++++++++ devui/gantt/src/i18n-gantt.ts | 54 +++++ devui/gantt/src/utils.ts | 8 + 11 files changed, 967 insertions(+) create mode 100644 devui/gantt/src/gantt-milestone/gantt-milestone.scss create mode 100644 devui/gantt/src/gantt-milestone/index.tsx create mode 100644 devui/gantt/src/gantt-milestone/milestone-icon.tsx create mode 100644 devui/gantt/src/gantt-model.ts create mode 100644 devui/gantt/src/gantt-scale/gantt-scale.scss create mode 100644 devui/gantt/src/gantt-scale/index.tsx create mode 100644 devui/gantt/src/gantt-scale/use-scale-data.ts create mode 100644 devui/gantt/src/gantt-tools/gantt-tools.scss create mode 100644 devui/gantt/src/gantt-tools/index.tsx create mode 100644 devui/gantt/src/i18n-gantt.ts create mode 100644 devui/gantt/src/utils.ts diff --git a/devui/gantt/src/gantt-milestone/gantt-milestone.scss b/devui/gantt/src/gantt-milestone/gantt-milestone.scss new file mode 100644 index 00000000..0abd57b6 --- /dev/null +++ b/devui/gantt/src/gantt-milestone/gantt-milestone.scss @@ -0,0 +1,17 @@ +.devui-gantt-milestone { + position: relative; + height: 24px; + line-height: 24px; + display: inline-block; + + & span { + display: inline-block; + vertical-align: middle; + } + + & .icon { + width: 20px; + height: 24px; + margin-right: 4px; + } +} diff --git a/devui/gantt/src/gantt-milestone/index.tsx b/devui/gantt/src/gantt-milestone/index.tsx new file mode 100644 index 00000000..38aae3c7 --- /dev/null +++ b/devui/gantt/src/gantt-milestone/index.tsx @@ -0,0 +1,32 @@ +import { defineComponent, ref } from 'vue' +import { MilestoneIcon } from './milestone-icon' +import './gantt-milestone.scss' + +export default defineComponent({ + name: 'DGanttMilestone', + props: { + startDate: { + type: Date, + }, + title: { + type: String, + }, + id: { + type: String, + }, + }, + setup(props) { + // todo + }, + render() { + const { title } = this + return ( +
+ + + + {title} +
+ ) + }, +}) diff --git a/devui/gantt/src/gantt-milestone/milestone-icon.tsx b/devui/gantt/src/gantt-milestone/milestone-icon.tsx new file mode 100644 index 00000000..b0c2b586 --- /dev/null +++ b/devui/gantt/src/gantt-milestone/milestone-icon.tsx @@ -0,0 +1,212 @@ +export const MilestoneIcon = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +) diff --git a/devui/gantt/src/gantt-model.ts b/devui/gantt/src/gantt-model.ts new file mode 100644 index 00000000..91b5456b --- /dev/null +++ b/devui/gantt/src/gantt-model.ts @@ -0,0 +1,61 @@ +export interface GanttScaleDateInfo { + dayOfMonthLabel: string + dayOfWeekLabel: string + monthLabel: string + yearLabel: string + date: Date + monthStart?: boolean + weekend?: boolean + today?: boolean + highlight?: boolean + highlightStart?: boolean + milestone?: string + scaleStartVisable?: boolean + index?: number +} + +export enum GanttScaleUnit { + day = 'day', + week = 'week', + month = 'month', +} +export interface GanttBarStatus { + focused: boolean + startDate: Date + endDate: Date +} + +export interface GanttScaleConfig { + startDate?: Date + endDate?: Date + unit?: GanttScaleUnit +} + +export enum GanttMarkerType { + milestone = 'milestone', + month = 'month', + week = 'week', +} + +export interface GanttMilestone { + date: Date + lable: string +} + +export interface GanttTaskInfo { + id: string + startDate: Date + endDate: Date + title?: string + progress: string + duration: string + moveOffset?: number + left?: number + width?: number +} + +export enum UnitRole { + day = 10, + week = 20, + month = 30, +} diff --git a/devui/gantt/src/gantt-scale/gantt-scale.scss b/devui/gantt/src/gantt-scale/gantt-scale.scss new file mode 100644 index 00000000..c3720afd --- /dev/null +++ b/devui/gantt/src/gantt-scale/gantt-scale.scss @@ -0,0 +1,175 @@ +@import '../../../style/theme/color'; +@import '../../../style/theme/corner'; +@import '../../../style/core/_font'; + +:host { + display: block; + height: 36px; + line-height: 18px; +} + +.devui-gantt-scale { + display: inline-block; + color: $devui-placeholder; // TODO: Color-Question + text-align: center; + position: absolute; + height: 36px; + font-weight: normal; + + &.day { + &:not(.milestone) { + &:hover .devui-scale-start { + display: none; + } + } + + &.milestone { + background-image: + linear-gradient( + 180deg, + rgba(254, 204, 85, 0) 0%, + rgba(62, 204, 166, 0.1) 100% + ); + } + } + + & .devui-scale-start { + width: 100%; + height: 18px; + position: absolute; + left: 1px; + white-space: nowrap; + + &.milestone { + color: $devui-success; + } + } + + & .devui-scale-unit { + height: 18px; + position: absolute; + top: 18px; + width: 100%; + + & .border-left { + height: 18px; + border-left: 1px solid $devui-list-item-selected-bg; + } + + & .scale-highlight { + position: absolute; + height: 18px; + border-radius: $devui-border-radius; + background-color: $devui-brand; + padding: 0 4px 0 4px; + + & div { + color: $devui-base-bg; + font-size: $devui-font-size; + font-weight: normal; + } + } + + .today { + background: rgba(255, 121, 14, 0.2); + border-radius: $devui-border-radius; + height: 16px; + } + } + + & .milestone-new { + display: none; + position: absolute; + width: 18px; + height: 18px; + margin-left: 16px; + border: 1px solid $devui-list-item-selected-bg; // TODO: Color-Question + cursor: pointer; + + & div { + line-height: 16px; + } + } + + &:not(.milestone) { + &:hover .milestone-new.day { + display: block; + } + } +} + +.devui-mark-line { + position: absolute; + top: 0; + bottom: 0; + width: 2px; + z-index: 1; + background: $devui-line; + opacity: 0.5; + + &.today { + opacity: 0.2; + background: #ff790e; + + &.day { + margin-left: 24px; + } + + &.week { + margin-left: 9px; + } + + &.month { + margin-left: 4px; + } + } + + &.milestone { + opacity: 0.2; + background: $devui-success; + + &.day { + margin-left: 24px; + } + + &.week { + margin-left: 9px; + } + + &.month { + margin-left: 4px; + } + } +} + +.devui-mark-stripe { + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + background: + linear-gradient( + 45deg, + rgba(202, 207, 216, 0.2) 0, + rgba(202, 207, 216, 0.2) 10%, + transparent 10%, + transparent 50%, + rgba(202, 207, 216, 0.2) 50%, + rgba(202, 207, 216, 0.2) 60%, + transparent 60%, + transparent + ); + background-size: 6px 6px; + + &.day { + width: 100px; + } + + &.week { + width: 40px; + } + + &.month { + width: 20px; + } +} diff --git a/devui/gantt/src/gantt-scale/index.tsx b/devui/gantt/src/gantt-scale/index.tsx new file mode 100644 index 00000000..0890be0c --- /dev/null +++ b/devui/gantt/src/gantt-scale/index.tsx @@ -0,0 +1,157 @@ +import { defineComponent, ref, PropType, onMounted, toRefs } from 'vue' +import './gantt-scale.scss' +import { + GanttScaleUnit, + GanttMilestone, + GanttScaleDateInfo, +} from '../gantt-model' +import { useScaleData } from './use-scale-data' +import { i18nText } from '../i18n-gantt' +export default defineComponent({ + name: 'DGanttScale', + props: { + /** 视图单位 */ + unit: { + type: String, + default: GanttScaleUnit.day, + }, + height: { + type: Number, + }, + /** 开始时间 */ + startDate: { + type: Date, + }, + /** 结束时间 */ + endDate: { + type: Date, + }, + /** 甘特图时间轴容器左偏移像素 */ + ganttScaleContainerOffsetLeft: { + type: Number, + }, + /** 版本里程碑列表 */ + milestoneList: { + type: Array as PropType, + }, + scrollElement: { + type: Object, + }, + }, + emits: ['addMilestone'], + setup(props, ctx) { + const { startDate, endDate, milestoneList, scrollElement, unit } = + toRefs(props) + const scaleData = ref([]) + const viewSCaleData = ref([]) + const scaleWidth = ref({ + day: 40, + week: 30, + month: 20, + }) + const highlight = ref(false) + const highlightStartText = ref('') + const highlightEndText = ref('') + const { generateScaleData } = useScaleData(milestoneList) + let viewScaleRange = [0, 0] + const addMilestone = (info: GanttScaleDateInfo) => { + ctx.emit('addMilestone', info) + } + const getViewScaleData = () => { + if (scrollElement.value) { + const containerWidth = scrollElement.value.clientWidth + const scrollLeft = scrollElement.value.scrollLeft + const start = Math.floor(scrollLeft / scaleWidth.value[unit.value]) + const offset = Math.ceil(containerWidth / scaleWidth.value[unit.value]) + viewScaleRange = [start - 2, start + offset + 2] + viewSCaleData.value = scaleData.value.filter( + (i: GanttScaleDateInfo) => { + return i.index >= viewScaleRange[0] && i.index <= viewScaleRange[1] + } + ) + } + } + onMounted(() => { + if (startDate && endDate) { + scaleData.value = generateScaleData(startDate.value, endDate.value) + getViewScaleData() + } + }) + + return { + viewSCaleData, + scaleWidth, + addMilestone, + highlight, + highlightStartText, + highlightEndText, + } + }, + render() { + const { + unit, + viewSCaleData, + scaleWidth, + addMilestone, + highlight, + highlightStartText, + highlightEndText, + } = this + return viewSCaleData.map((data, index) => ( +
+
+ {data.milestone && unit === 'day' &&
{data.milestone}
} + {!data.milestone && + unit !== 'day' && + data.scaleStartVisable && + (index === 0 || data.monthStart) + ? unit === 'month' + ? i18nText.zh.yearDisplay(data.yearLabel) + : i18nText.zh.yearAndMonthDisplay(data.yearLabel, data.monthLabel) + : ''} +
+
+ {highlight && data.highlightStart && ( +
+
{highlightStartText}
+
{highlightEndText}
+
+
+ )} + {(!highlight || !data.highlightStart) && unit === 'day' && ( +
+ {data.today ? i18nText.zh.today : data.dayOfMonthLabel} +
+ )} + {(!highlight || !data.highlightStart) && unit === 'week' && ( +
+ {index === 0 || data.weekend ? data.dayOfMonthLabel : ''} +
+ )} + {(!highlight || !data.highlightStart) && unit === 'month' && ( +
+ {index === 0 || data.monthStart + ? i18nText.zh.monthDisplay(data.monthLabel) + : ''} +
+ )} +
+
addMilestone(data)} + > + +
+
+ )) + }, +}) diff --git a/devui/gantt/src/gantt-scale/use-scale-data.ts b/devui/gantt/src/gantt-scale/use-scale-data.ts new file mode 100644 index 00000000..37baaf29 --- /dev/null +++ b/devui/gantt/src/gantt-scale/use-scale-data.ts @@ -0,0 +1,92 @@ +import { Ref } from 'vue' +import { GanttMilestone, GanttScaleDateInfo } from '../gantt-model' +import { isSameDate } from '../utils' + +export const useScaleData = ( + milestoneList: Ref +): { + generateScaleData: (startDate: Date, endDate: Date) => GanttScaleDateInfo[] +} => { + const SCALE_START_LABLE_OFFSET = 7 + + const generateDateInfo = (date: Date, index: number): GanttScaleDateInfo => { + const dateInfo: GanttScaleDateInfo = { + dayOfMonthLabel: '', + dayOfWeekLabel: '', + monthLabel: '', + yearLabel: '', + date: date, + monthStart: false, + weekend: false, + today: false, + milestone: '', + highlightStart: false, + scaleStartVisable: true, + index, + } + const dayOfMonth = date.getDate() + dateInfo.dayOfMonthLabel = dayOfMonth + '' + if (dayOfMonth === 1) { + dateInfo.monthStart = true + } + + const dayOfWeek = date.getDay() + dateInfo.dayOfWeekLabel = dayOfWeek + '' + if (dayOfWeek === 6) { + dateInfo.weekend = true + } + const month = date.getMonth() + 1 + dateInfo.monthLabel = month + '' + const year = date.getFullYear() + dateInfo.yearLabel = year + '' + if (isSameDate(date, new Date())) { + dateInfo.today = true + } + + if ( + new Date( + year, + month - 1, + dayOfMonth + SCALE_START_LABLE_OFFSET + ).getMonth() > + month - 1 + ) { + dateInfo.scaleStartVisable = false + } + if (milestoneList.value) { + milestoneList.value.forEach((milestone) => { + if (milestone.date) { + if (isSameDate(milestone.date, dateInfo.date)) { + dateInfo.milestone = milestone.lable + } + } + }) + } + + return dateInfo + } + + const getNextDay = (date: Date) => { + const nextDayDate = date.setDate(date.getDate() + 1) + return new Date(nextDayDate) + } + const generateScaleData = ( + startDate: Date, + endDate: Date + ): GanttScaleDateInfo[] => { + const scaleData = [] + let handleDate = startDate + let index = 0 + while (!isSameDate(handleDate, endDate)) { + const dateInfo = generateDateInfo(handleDate, index) + scaleData.push(dateInfo) + handleDate = getNextDay(new Date(handleDate)) + index++ + } + return scaleData + } + + return { + generateScaleData, + } +} diff --git a/devui/gantt/src/gantt-tools/gantt-tools.scss b/devui/gantt/src/gantt-tools/gantt-tools.scss new file mode 100644 index 00000000..f021de6a --- /dev/null +++ b/devui/gantt/src/gantt-tools/gantt-tools.scss @@ -0,0 +1,63 @@ +@import '../../../style/theme/color'; +@import '../../../style/theme/corner'; +@import '../../../style/core/_font'; +@import '../../../style/theme/shadow'; + +.tools-container { + position: absolute; + top: 70px; + right: 20px; + z-index: 10; +} + +.tool { + display: inline-flex; + align-items: center; + justify-content: center; + height: 32px; + margin-left: 12px; + background-color: $devui-base-bg; + box-shadow: $devui-shadow-length-base rgba(81, 112, 255, 0.4); + cursor: pointer; + + &.disabled { + opacity: 0.5; + } + + span { + border: 0 !important; + } + + .switch-view { + padding: 0 8px; + + &:hover { + color: $devui-link !important; + } + } +} + +.devui-dropdown-menu { + top: 10px !important; + left: -6px !important; +} + +:host ::ng-deep { + .devui-dropdown-origin { + border: 0; + + &:hover { + color: $devui-link !important; + } + } + + .devui-btn { + height: 32px !important; + color: $devui-text !important; + padding: 0 8px !important; + + &:hover { + color: $devui-link !important; + } + } +} diff --git a/devui/gantt/src/gantt-tools/index.tsx b/devui/gantt/src/gantt-tools/index.tsx new file mode 100644 index 00000000..942ae2ef --- /dev/null +++ b/devui/gantt/src/gantt-tools/index.tsx @@ -0,0 +1,96 @@ +import { defineComponent, ref } from 'vue' +import './gantt-tools.scss' +import { UnitRole } from '../gantt-model' + +export default defineComponent({ + name: 'DGanttTools', + props: { + // currentUnit: { + // type: String, + // default: null, + // }, + isFullScreen: { + type: Boolean, + default: false, + }, + }, + emits: ['goToday', 'reduceUnit', 'increaseUnit', 'switchView'], + setup(props, ctx) { + const currentUnitLabel = ref('') + const views = ref([ + { + name: 'Day', + value: 'day', + }, + { + name: 'Week', + value: 'week', + }, + { + name: 'Month', + value: 'month', + }, + ]) + const actionHandle = (type: string) => { + switch (type) { + case 'today': + ctx.emit('goToday') + break + case 'reduce': + ctx.emit('reduceUnit') + break + case 'increase': + ctx.emit('increaseUnit') + break + } + } + const selectView = (value: string) => { + ctx.emit('switchView', value) + } + return { + actionHandle, + currentUnitLabel, + views, + selectView, + } + }, + render() { + const { isFullScreen, actionHandle, currentUnitLabel, views, selectView } = + this + return ( +
+ actionHandle('today')} + class="tool" + > + Today + +
+ +
+ + + + + + +
+ ) + }, +}) diff --git a/devui/gantt/src/i18n-gantt.ts b/devui/gantt/src/i18n-gantt.ts new file mode 100644 index 00000000..82d0363b --- /dev/null +++ b/devui/gantt/src/i18n-gantt.ts @@ -0,0 +1,54 @@ +export const i18nText = { + en: { + today: 'today', + monthsOfYear: [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + ], + yearDisplay(year: string): string { + return `${year}` + }, + monthDisplay(strMonthIndex: string): string { + return this.monthsOfYear[Number(strMonthIndex) - 1] + }, + yearAndMonthDisplay(year: string, strMonthIndex: string): string { + return this.yearDisplay(year) + this.monthDisplay(strMonthIndex) + }, + }, + zh: { + today: '今天', + monthsOfYear: [ + '1月', + '2月', + '3月', + '4月', + '5月', + '6月', + '7月', + '8月', + '9月', + '10月', + '11月', + '12月', + ], + yearDisplay(year: string): string { + return `${year}年` + }, + monthDisplay(strMonthIndex: string): string { + return this.monthsOfYear[Number(strMonthIndex) - 1] + }, + yearAndMonthDisplay(year: string, strMonthIndex: string): string { + return this.yearDisplay(year) + this.monthDisplay(strMonthIndex) + }, + }, +} diff --git a/devui/gantt/src/utils.ts b/devui/gantt/src/utils.ts new file mode 100644 index 00000000..a232b179 --- /dev/null +++ b/devui/gantt/src/utils.ts @@ -0,0 +1,8 @@ +/** 判断是否是同一天 */ +export const isSameDate = (date: Date, compareDate: Date): boolean => { + return ( + date.getFullYear() === compareDate.getFullYear() && + date.getMonth() === compareDate.getMonth() && + date.getDate() === compareDate.getDate() + ) +} -- Gitee From 7c0c3cc8412431eb94c790d619300c97aa7be80d Mon Sep 17 00:00:00 2001 From: ElsaOOo Date: Thu, 14 Oct 2021 14:27:10 +0800 Subject: [PATCH 3/7] =?UTF-8?q?feat(gantt):=20=E6=B7=BB=E5=8A=A0=E5=8C=85?= =?UTF-8?q?=E8=A3=B9=E7=BB=84=E4=BB=B6,=E6=9B=B4=E6=96=B0gantt-scale?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/gantt/index.ts | 9 +- devui/gantt/src/gantt-scale/gantt-scale.scss | 2 +- devui/gantt/src/gantt-scale/index.tsx | 135 +++++++++++------- devui/gantt/src/gantt-scale/use-scale-data.ts | 1 + devui/gantt/src/gantt-types.ts | 15 +- devui/gantt/src/gantt.scss | 37 ++++- devui/gantt/src/gantt.tsx | 41 +++++- devui/gantt/src/use-gantt.ts | 36 +++++ docs/components/gantt/index.md | 44 +++--- 9 files changed, 235 insertions(+), 85 deletions(-) create mode 100644 devui/gantt/src/use-gantt.ts diff --git a/devui/gantt/index.ts b/devui/gantt/index.ts index 5b94ee46..5c7c937d 100644 --- a/devui/gantt/index.ts +++ b/devui/gantt/index.ts @@ -1,8 +1,9 @@ import type { App } from 'vue' import Gantt from './src/gantt' - -Gantt.install = function(app: App): void { +import GanttTools from './src/gantt-tools' +Gantt.install = function (app: App): void { app.component(Gantt.name, Gantt) + app.component(GanttTools.name, GanttTools) } export { Gantt } @@ -12,6 +13,6 @@ export default { category: '数据展示', status: undefined, // TODO: 组件若开发完成则填入"已完成",并删除该注释 install(app: App): void { - app.use(Gantt as any) - } + app.use(Gantt as any) + }, } diff --git a/devui/gantt/src/gantt-scale/gantt-scale.scss b/devui/gantt/src/gantt-scale/gantt-scale.scss index c3720afd..bbb3cc42 100644 --- a/devui/gantt/src/gantt-scale/gantt-scale.scss +++ b/devui/gantt/src/gantt-scale/gantt-scale.scss @@ -2,7 +2,7 @@ @import '../../../style/theme/corner'; @import '../../../style/core/_font'; -:host { +.devui-gantt-scale-wrapper { display: block; height: 36px; line-height: 18px; diff --git a/devui/gantt/src/gantt-scale/index.tsx b/devui/gantt/src/gantt-scale/index.tsx index 0890be0c..54873917 100644 --- a/devui/gantt/src/gantt-scale/index.tsx +++ b/devui/gantt/src/gantt-scale/index.tsx @@ -1,4 +1,4 @@ -import { defineComponent, ref, PropType, onMounted, toRefs } from 'vue' +import { defineComponent, ref, PropType, onMounted, toRefs, watch } from 'vue' import './gantt-scale.scss' import { GanttScaleUnit, @@ -61,23 +61,43 @@ export default defineComponent({ if (scrollElement.value) { const containerWidth = scrollElement.value.clientWidth const scrollLeft = scrollElement.value.scrollLeft + console.log({ + containerWidth, + scrollLeft, + }) + const start = Math.floor(scrollLeft / scaleWidth.value[unit.value]) const offset = Math.ceil(containerWidth / scaleWidth.value[unit.value]) viewScaleRange = [start - 2, start + offset + 2] + console.log('viewScaleRange ==>', viewScaleRange) viewSCaleData.value = scaleData.value.filter( (i: GanttScaleDateInfo) => { return i.index >= viewScaleRange[0] && i.index <= viewScaleRange[1] } ) + console.log(viewSCaleData.value) } } onMounted(() => { - if (startDate && endDate) { + if (startDate.value && endDate.value) { scaleData.value = generateScaleData(startDate.value, endDate.value) getViewScaleData() } }) + watch( + () => props.scrollElement, + () => { + getViewScaleData() + ;(props.scrollElement as HTMLDivElement).addEventListener( + 'scroll', + () => { + getViewScaleData() + } + ) + } + ) + return { viewSCaleData, scaleWidth, @@ -97,61 +117,72 @@ export default defineComponent({ highlightStartText, highlightEndText, } = this - return viewSCaleData.map((data, index) => ( -
-
- {data.milestone && unit === 'day' &&
{data.milestone}
} - {!data.milestone && - unit !== 'day' && - data.scaleStartVisable && - (index === 0 || data.monthStart) - ? unit === 'month' - ? i18nText.zh.yearDisplay(data.yearLabel) - : i18nText.zh.yearAndMonthDisplay(data.yearLabel, data.monthLabel) - : ''} -
-
- {highlight && data.highlightStart && ( -
-
{highlightStartText}
-
{highlightEndText}
-
-
- )} - {(!highlight || !data.highlightStart) && unit === 'day' && ( -
- {data.today ? i18nText.zh.today : data.dayOfMonthLabel} + return ( +
+ {viewSCaleData.map((data, index) => ( +
+
+ {data.milestone && unit === 'day' &&
{data.milestone}
} + {!data.milestone && + unit !== 'day' && + data.scaleStartVisable && + (index === 0 || data.monthStart) + ? unit === 'month' + ? i18nText.zh.yearDisplay(data.yearLabel) + : i18nText.zh.yearAndMonthDisplay( + data.yearLabel, + data.monthLabel + ) + : ''}
- )} - {(!highlight || !data.highlightStart) && unit === 'week' && ( -
- {index === 0 || data.weekend ? data.dayOfMonthLabel : ''} +
+ {highlight && data.highlightStart && ( +
+
{highlightStartText}
+
{highlightEndText}
+
+
+ )} + {(!highlight || !data.highlightStart) && unit === 'day' && ( +
+ {data.today ? i18nText.zh.today : data.dayOfMonthLabel} +
+ )} + {(!highlight || !data.highlightStart) && unit === 'week' && ( +
+ {index === 0 || data.weekend ? data.dayOfMonthLabel : ''} +
+ )} + {(!highlight || !data.highlightStart) && unit === 'month' && ( +
+ {index === 0 || data.monthStart + ? i18nText.zh.monthDisplay(data.monthLabel) + : ''} +
+ )}
- )} - {(!highlight || !data.highlightStart) && unit === 'month' && (
addMilestone(data)} > - {index === 0 || data.monthStart - ? i18nText.zh.monthDisplay(data.monthLabel) - : ''} +
- )} -
-
addMilestone(data)} - > - -
+
+ ))}
- )) + ) }, }) diff --git a/devui/gantt/src/gantt-scale/use-scale-data.ts b/devui/gantt/src/gantt-scale/use-scale-data.ts index 37baaf29..72f2f14c 100644 --- a/devui/gantt/src/gantt-scale/use-scale-data.ts +++ b/devui/gantt/src/gantt-scale/use-scale-data.ts @@ -83,6 +83,7 @@ export const useScaleData = ( handleDate = getNextDay(new Date(handleDate)) index++ } + console.log({ scaleData }) return scaleData } diff --git a/devui/gantt/src/gantt-types.ts b/devui/gantt/src/gantt-types.ts index d075835d..82dc9ba9 100644 --- a/devui/gantt/src/gantt-types.ts +++ b/devui/gantt/src/gantt-types.ts @@ -1,9 +1,16 @@ import type { PropType, ExtractPropTypes } from 'vue' - +import { GanttScaleUnit } from './gantt-model' export const ganttProps = { - /* test: { - type: Object as PropType<{ xxx: xxx }> - } */ + startDate: { + type: Date, + }, + endDate: { + type: Date, + }, + unit: { + type: String as PropType, + default: GanttScaleUnit.day, + }, } as const export type GanttProps = ExtractPropTypes diff --git a/devui/gantt/src/gantt.scss b/devui/gantt/src/gantt.scss index 3633bdfe..6f2c3957 100644 --- a/devui/gantt/src/gantt.scss +++ b/devui/gantt/src/gantt.scss @@ -1,3 +1,36 @@ -.devui-gantt { - // +@import '../../styles-var/devui-var.scss'; + +.gantt-container { + overflow: scroll; + + .header { + position: relative; + border-bottom: 1px solid $devui-dividing-line; + } + + .body { + position: relative; + min-height: 400px; + height: 100%; + + .item { + height: 40px; + padding-top: 8px; + } + } +} + +.tool { + display: inline-flex; + align-items: center; + justify-content: center; + height: 32px; + margin-left: 12px; + background-color: $devui-base-bg; + box-shadow: $devui-shadow-length-base rgba(81, 112, 255, 0.4); + cursor: pointer; + + span { + border: 0 !important; + } } diff --git a/devui/gantt/src/gantt.tsx b/devui/gantt/src/gantt.tsx index a142b80a..7415cecc 100644 --- a/devui/gantt/src/gantt.tsx +++ b/devui/gantt/src/gantt.tsx @@ -1,14 +1,45 @@ -import { defineComponent } from 'vue' +import { defineComponent, onMounted, ref, toRefs } from 'vue' +import DGanttScale from './gantt-scale/index' import { ganttProps, GanttProps } from './gantt-types' import './gantt.scss' - +import { useGantt } from './use-gantt' export default defineComponent({ name: 'DGantt', + components: { DGanttScale }, props: ganttProps, - emits: [], setup(props: GanttProps, ctx) { + const { startDate, endDate } = toRefs(props) + const ganttContainer = ref() + const ganttScaleWidth = ref() + const { getDurationWidth } = useGantt() + onMounted(() => { + ganttScaleWidth.value = getDurationWidth(startDate.value, endDate.value) + }) + return { + ganttContainer, + ganttScaleWidth, + } + }, + render() { + const { + $slots, + startDate, + endDate, + unit, + ganttContainer, + ganttScaleWidth, + } = this return ( -
+
+
+ +
+
) - } + }, }) diff --git a/devui/gantt/src/use-gantt.ts b/devui/gantt/src/use-gantt.ts new file mode 100644 index 00000000..3a59908c --- /dev/null +++ b/devui/gantt/src/use-gantt.ts @@ -0,0 +1,36 @@ +import { GanttScaleUnit } from './gantt-model' +export const useGantt = (scaleUnit = GanttScaleUnit.day) => { + const DAY_DURATION = 24 * 60 * 60 * 1000 + + const getScaleUnitPixel = () => { + switch (scaleUnit) { + case GanttScaleUnit.day: + return 40 + case GanttScaleUnit.week: + return 30 + case GanttScaleUnit.month: + return 20 + default: + break + } + } + + const getDuration = (startDate: Date, endDate: Date): number => { + if (startDate && endDate) { + const timeOffset = endDate.getTime() - startDate.getTime() + const duration = timeOffset / DAY_DURATION + 1 + console.log('duration => ', duration) + + return Math.round(duration) + } + } + const getDurationWidth = (startDate: Date, endDate: Date): number => { + if (startDate && endDate) { + const duration = getDuration(startDate, endDate) + return duration * getScaleUnitPixel() + } + } + return { + getDurationWidth, + } +} diff --git a/docs/components/gantt/index.md b/docs/components/gantt/index.md index 6e4a8a65..919457f8 100644 --- a/docs/components/gantt/index.md +++ b/docs/components/gantt/index.md @@ -1,36 +1,47 @@ # Gantt 甘特图 -// todo 组件描述 +甘特图。 ### 何时使用 -// todo 使用时机描述 - +当用户需要通过条状图来显示项目,进度和其他时间相关的系统进展的内在关系随着时间进展的情况时。 ### 基本用法 -// todo 用法描述 -:::demo // todo 展开代码的内部描述 + +- d-gantt-scale(时间轴)容器作为时间轴标线的定位父级元素,须设置 position 或者是 table、td、th、body 元素。 +- d-gantt-scale(时间轴)容器和 d-gantt-bar(时间条)容器宽度须通过 GanttService 提供的方法根据起止时间计算后设置,初始化之后还须订阅 ganttScaleConfigChange 动态设置。 +- 时间条 move、resize 事件会改变该时间条起止时间和时间轴的起止时间,订阅时间条 resize、move 事件和 ganttScaleConfigChange 来记录变化。 +- 响应时间条 move、resize 事件调整最外层容器的滚动以获得更好的体验。 + +:::demo ```vue - + ``` ::: @@ -40,10 +51,10 @@ export default defineComponent({ d-gantt 参数 | 参数 | 类型 | 默认 | 说明 | 跳转 Demo | 全局配置项 | -| ---- | ---- | ---- | ---- | --------- | --------- | -| | | | | | | -| | | | | | | -| | | | | | | +| ---- | ---- | ---- | ---- | --------- | ---------- | +| | | | | | | +| | | | | | | +| | | | | | | d-gantt 事件 @@ -52,4 +63,3 @@ d-gantt 事件 | | | | | | | | | | | | | | | - -- Gitee From 1005ffa494d72b0bf35d7d01dc1596cde1c2ee13 Mon Sep 17 00:00:00 2001 From: ElsaOOo Date: Thu, 14 Oct 2021 16:04:12 +0800 Subject: [PATCH 4/7] =?UTF-8?q?feat(gantt):=20=E6=9B=B4=E6=96=B0gantt-scal?= =?UTF-8?q?e=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/gantt/index.ts | 3 + .../src/gantt-scale/gantt-marker-directive.ts | 47 +++++++++++ devui/gantt/src/gantt-scale/index.tsx | 20 +++-- devui/gantt/src/gantt-tools/gantt-tools.scss | 47 ++++++----- devui/gantt/src/gantt-tools/index.tsx | 78 ++++++++++--------- devui/gantt/src/gantt.scss | 1 + devui/gantt/src/gantt.tsx | 5 +- 7 files changed, 139 insertions(+), 62 deletions(-) create mode 100644 devui/gantt/src/gantt-scale/gantt-marker-directive.ts diff --git a/devui/gantt/index.ts b/devui/gantt/index.ts index 5c7c937d..071685e5 100644 --- a/devui/gantt/index.ts +++ b/devui/gantt/index.ts @@ -1,9 +1,12 @@ import type { App } from 'vue' import Gantt from './src/gantt' import GanttTools from './src/gantt-tools' +import ganttMarkerDirective from './src/gantt-scale/gantt-marker-directive' + Gantt.install = function (app: App): void { app.component(Gantt.name, Gantt) app.component(GanttTools.name, GanttTools) + app.directive('gantt-marker', ganttMarkerDirective) } export { Gantt } diff --git a/devui/gantt/src/gantt-scale/gantt-marker-directive.ts b/devui/gantt/src/gantt-scale/gantt-marker-directive.ts new file mode 100644 index 00000000..9156a42a --- /dev/null +++ b/devui/gantt/src/gantt-scale/gantt-marker-directive.ts @@ -0,0 +1,47 @@ +import { GanttScaleUnit } from '../gantt-model' +interface BindingType { + value: { + ganttBarContainerElement: HTMLElement + ganttScaleContainerOffsetLeft: number + monthMark: boolean + weekend: boolean + today: boolean + milestone: string + unit: GanttScaleUnit + date: Date + last: boolean + } +} +const ganttMarkerDirective = { + ganttBarContainerElement: null, + monthMarkElement: null, + weekendElement: null, + todayElement: null, + milestoneElement: null, + monthMark: '', + mounted(el: HTMLElement, binding: BindingType): void { + const { ganttBarContainerElement, monthMark } = binding.value + if (ganttBarContainerElement) { + this.ganttBarContainerElement = ganttBarContainerElement + } + if (monthMark) { + this.monthMark = this.monthMark + } + }, + updated(el: HTMLElement, binding: BindingType): void { + // todo + const { monthMark, weekend, today, milestone, unit } = binding.value + if (monthMark) { + this.initMarkElement() + } + }, + initMarkElement(): void { + if (this.ganttBarContainerElement) { + if (this.monthMark && !this.monthMarkElement) { + // todo + } + } + }, +} + +export default ganttMarkerDirective diff --git a/devui/gantt/src/gantt-scale/index.tsx b/devui/gantt/src/gantt-scale/index.tsx index 54873917..caa03ac7 100644 --- a/devui/gantt/src/gantt-scale/index.tsx +++ b/devui/gantt/src/gantt-scale/index.tsx @@ -37,6 +37,9 @@ export default defineComponent({ scrollElement: { type: Object, }, + ganttBarContainerElement: { + type: Object, + }, }, emits: ['addMilestone'], setup(props, ctx) { @@ -61,21 +64,15 @@ export default defineComponent({ if (scrollElement.value) { const containerWidth = scrollElement.value.clientWidth const scrollLeft = scrollElement.value.scrollLeft - console.log({ - containerWidth, - scrollLeft, - }) const start = Math.floor(scrollLeft / scaleWidth.value[unit.value]) const offset = Math.ceil(containerWidth / scaleWidth.value[unit.value]) viewScaleRange = [start - 2, start + offset + 2] - console.log('viewScaleRange ==>', viewScaleRange) viewSCaleData.value = scaleData.value.filter( (i: GanttScaleDateInfo) => { return i.index >= viewScaleRange[0] && i.index <= viewScaleRange[1] } ) - console.log(viewSCaleData.value) } } onMounted(() => { @@ -116,6 +113,7 @@ export default defineComponent({ highlight, highlightStartText, highlightEndText, + ganttBarContainerElement, } = this return (
@@ -126,6 +124,16 @@ export default defineComponent({ left: `${scaleWidth[unit] * data.index}px`, width: `${scaleWidth[unit]}px`, }} + v-gantt-marker={{ + ganttBarContainerElement, + monthMark: data.monthMark, + weekend: data.weekend, + milestone: data.milestone, + today: data.today, + date: data.date, + unit: unit, + last: index === viewSCaleData.length - 1, + }} >
{data.milestone && unit === 'day' &&
{data.milestone}
} diff --git a/devui/gantt/src/gantt-tools/gantt-tools.scss b/devui/gantt/src/gantt-tools/gantt-tools.scss index f021de6a..1cabaeb2 100644 --- a/devui/gantt/src/gantt-tools/gantt-tools.scss +++ b/devui/gantt/src/gantt-tools/gantt-tools.scss @@ -8,6 +8,33 @@ top: 70px; right: 20px; z-index: 10; + + .devui-dropdown-origin { + border: 0; + + &:hover { + color: $devui-link !important; + } + } + + .devui-btn { + height: 32px !important; + color: $devui-text !important; + padding: 0 8px !important; + min-width: 50px; + + &:hover { + color: $devui-link !important; + } + } + + .devui-select-selection { + width: 120px; + + .devui-select-input { + height: 32px; + } + } } .tool { @@ -41,23 +68,3 @@ top: 10px !important; left: -6px !important; } - -:host ::ng-deep { - .devui-dropdown-origin { - border: 0; - - &:hover { - color: $devui-link !important; - } - } - - .devui-btn { - height: 32px !important; - color: $devui-text !important; - padding: 0 8px !important; - - &:hover { - color: $devui-link !important; - } - } -} diff --git a/devui/gantt/src/gantt-tools/index.tsx b/devui/gantt/src/gantt-tools/index.tsx index 942ae2ef..f29a55e0 100644 --- a/devui/gantt/src/gantt-tools/index.tsx +++ b/devui/gantt/src/gantt-tools/index.tsx @@ -5,10 +5,10 @@ import { UnitRole } from '../gantt-model' export default defineComponent({ name: 'DGanttTools', props: { - // currentUnit: { - // type: String, - // default: null, - // }, + unit: { + type: String, + default: null, + }, isFullScreen: { type: Boolean, default: false, @@ -16,7 +16,7 @@ export default defineComponent({ }, emits: ['goToday', 'reduceUnit', 'increaseUnit', 'switchView'], setup(props, ctx) { - const currentUnitLabel = ref('') + const currentUnitLabel = ref(props.unit) const views = ref([ { name: 'Day', @@ -58,38 +58,46 @@ export default defineComponent({ const { isFullScreen, actionHandle, currentUnitLabel, views, selectView } = this return ( -
- actionHandle('today')} - class="tool" +
+
- Today - -
- + actionHandle('today')} + class="tool" + > + Today + +
+ +
+ + + + + +
- - - - - -
) }, diff --git a/devui/gantt/src/gantt.scss b/devui/gantt/src/gantt.scss index 6f2c3957..4b1dfdf1 100644 --- a/devui/gantt/src/gantt.scss +++ b/devui/gantt/src/gantt.scss @@ -2,6 +2,7 @@ .gantt-container { overflow: scroll; + position: relative; .header { position: relative; diff --git a/devui/gantt/src/gantt.tsx b/devui/gantt/src/gantt.tsx index 7415cecc..d2a3587d 100644 --- a/devui/gantt/src/gantt.tsx +++ b/devui/gantt/src/gantt.tsx @@ -1,11 +1,12 @@ import { defineComponent, onMounted, ref, toRefs } from 'vue' import DGanttScale from './gantt-scale/index' +import DGanttTools from './gantt-tools/index' import { ganttProps, GanttProps } from './gantt-types' import './gantt.scss' import { useGantt } from './use-gantt' export default defineComponent({ name: 'DGantt', - components: { DGanttScale }, + components: { DGanttScale, DGanttTools }, props: ganttProps, setup(props: GanttProps, ctx) { const { startDate, endDate } = toRefs(props) @@ -39,6 +40,8 @@ export default defineComponent({ scrollElement={ganttContainer} >
+ +
) }, -- Gitee From 3a6665575589ae90e899ab7341ae523c3bc096cc Mon Sep 17 00:00:00 2001 From: ElsaOOo Date: Mon, 18 Oct 2021 09:57:55 +0800 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84gantt-tools?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devui/gantt/src/gantt-scale/index.tsx | 5 +- devui/gantt/src/gantt-tools/gantt-tools.scss | 11 ++- devui/gantt/src/gantt-tools/index.tsx | 89 ++++++++++---------- devui/gantt/src/gantt.scss | 1 - devui/gantt/src/gantt.tsx | 22 ++--- 5 files changed, 70 insertions(+), 58 deletions(-) diff --git a/devui/gantt/src/gantt-scale/index.tsx b/devui/gantt/src/gantt-scale/index.tsx index caa03ac7..00cb52de 100644 --- a/devui/gantt/src/gantt-scale/index.tsx +++ b/devui/gantt/src/gantt-scale/index.tsx @@ -137,8 +137,7 @@ export default defineComponent({ >
{data.milestone && unit === 'day' &&
{data.milestone}
} - {!data.milestone && - unit !== 'day' && + {(!data.milestone || unit !== 'day') && data.scaleStartVisable && (index === 0 || data.monthStart) ? unit === 'month' @@ -158,7 +157,7 @@ export default defineComponent({
)} {(!highlight || !data.highlightStart) && unit === 'day' && ( -
+
{data.today ? i18nText.zh.today : data.dayOfMonthLabel}
)} diff --git a/devui/gantt/src/gantt-tools/gantt-tools.scss b/devui/gantt/src/gantt-tools/gantt-tools.scss index 1cabaeb2..45137d77 100644 --- a/devui/gantt/src/gantt-tools/gantt-tools.scss +++ b/devui/gantt/src/gantt-tools/gantt-tools.scss @@ -28,8 +28,17 @@ } } + .tool { + &.minus, + &.add { + .devui-btn { + min-width: 30px; + } + } + } + .devui-select-selection { - width: 120px; + width: 90px; .devui-select-input { height: 32px; diff --git a/devui/gantt/src/gantt-tools/index.tsx b/devui/gantt/src/gantt-tools/index.tsx index f29a55e0..070283dc 100644 --- a/devui/gantt/src/gantt-tools/index.tsx +++ b/devui/gantt/src/gantt-tools/index.tsx @@ -1,6 +1,6 @@ import { defineComponent, ref } from 'vue' import './gantt-tools.scss' -import { UnitRole } from '../gantt-model' +import { GanttScaleUnit } from '../gantt-model' export default defineComponent({ name: 'DGanttTools', @@ -44,8 +44,8 @@ export default defineComponent({ break } } - const selectView = (value: string) => { - ctx.emit('switchView', value) + const selectView = (selectItem: { name: string; value: string; }) => { + ctx.emit('switchView', selectItem.value) } return { actionHandle, @@ -55,49 +55,52 @@ export default defineComponent({ } }, render() { - const { isFullScreen, actionHandle, currentUnitLabel, views, selectView } = - this + const { isFullScreen, actionHandle, views, selectView, $slots } = this + return ( -
-
+ actionHandle('today')} + class="tool" > - actionHandle('today')} - class="tool" - > - Today - -
- -
- - - - - - + Today +
+
+
+ actionHandle('reduce')} + > + + + actionHandle('increase')} + > + + + {$slots.default && $slots.default()}
) }, diff --git a/devui/gantt/src/gantt.scss b/devui/gantt/src/gantt.scss index 4b1dfdf1..6f2c3957 100644 --- a/devui/gantt/src/gantt.scss +++ b/devui/gantt/src/gantt.scss @@ -2,7 +2,6 @@ .gantt-container { overflow: scroll; - position: relative; .header { position: relative; diff --git a/devui/gantt/src/gantt.tsx b/devui/gantt/src/gantt.tsx index d2a3587d..e2ddae9b 100644 --- a/devui/gantt/src/gantt.tsx +++ b/devui/gantt/src/gantt.tsx @@ -31,17 +31,19 @@ export default defineComponent({ ganttScaleWidth, } = this return ( -
-
- +
+
+
+ +
+ +
- -
) }, -- Gitee From c299a6f5acf54e73d01c4ec213501d5427d59f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E9=A2=96=E6=96=8C?= Date: Sun, 24 Oct 2021 19:04:10 +0800 Subject: [PATCH 6/7] feat: add gantt-service && gant-bar todo --- .../gantt-bar-parent/gantt-bar-parent.scss | 73 ++++++++ devui/gantt/src/gantt-bar-parent/index.tsx | 162 ++++++++++++++++++ devui/gantt/src/gantt-bar/gantt-bar.scss | 3 + devui/gantt/src/gantt-bar/index.tsx | 14 ++ devui/gantt/src/gantt-service.ts | 110 ++++++++++++ devui/gantt/src/gantt-types.ts | 1 + 6 files changed, 363 insertions(+) create mode 100644 devui/gantt/src/gantt-bar-parent/gantt-bar-parent.scss create mode 100644 devui/gantt/src/gantt-bar-parent/index.tsx create mode 100644 devui/gantt/src/gantt-bar/gantt-bar.scss create mode 100644 devui/gantt/src/gantt-bar/index.tsx create mode 100644 devui/gantt/src/gantt-service.ts diff --git a/devui/gantt/src/gantt-bar-parent/gantt-bar-parent.scss b/devui/gantt/src/gantt-bar-parent/gantt-bar-parent.scss new file mode 100644 index 00000000..6aaae086 --- /dev/null +++ b/devui/gantt/src/gantt-bar-parent/gantt-bar-parent.scss @@ -0,0 +1,73 @@ +@import '../../style/theme/color'; + +.devui-gantt-bar-parent { + width: 100%; + box-sizing: border-box; + height: 24px; + z-index: 3; + position: relative; + + .devui-gantt-bar-rail { + position: absolute; + background: #eaecf0; + height: 12px; + width: 100%; + margin-top: 4px; + } + + .devui-gantt-bar-rail::before { + width: 0; + height: 0; + border: 3px transparent solid; + border-top-color: #eaecf0; + border-left-color: #eaecf0; + position: absolute; + left: 0; + bottom: -6px; + content: ''; + } + + .devui-gantt-bar-rail::after { + width: 0; + height: 0; + border: 3px transparent solid; + border-top-color: #eaecf0; + border-right-color: #eaecf0; + position: absolute; + right: 0; + bottom: -6px; + content: ''; + } + + .devui-gantt-bar-track { + position: absolute; + background-color: #cacfd8; + height: 12px; + margin-top: 4px; + width: 0; + } + + .devui-gantt-bar-track.head::before { + width: 0; + height: 0; + border: 3px transparent solid; + border-top-color: #cacfd8; + border-left-color: #cacfd8; + position: absolute; + left: 0; + bottom: -6px; + content: ''; + } + + .devui-gantt-bar-track.tail::after { + width: 0; + height: 0; + border: 3px transparent solid; + border-top-color: #cacfd8; + border-right-color: #cacfd8; + position: absolute; + right: 0; + bottom: -6px; + content: ''; + } +} diff --git a/devui/gantt/src/gantt-bar-parent/index.tsx b/devui/gantt/src/gantt-bar-parent/index.tsx new file mode 100644 index 00000000..d331fd08 --- /dev/null +++ b/devui/gantt/src/gantt-bar-parent/index.tsx @@ -0,0 +1,162 @@ +import {defineComponent , ref , toRefs } from 'vue'; +import {GanttService} from '../gantt-service' +import { Subscription } from 'rxjs'; +import './gantt-bar-parent.scss'; +const ganttService = new GanttService() +export default defineComponent({ + name:'DGanttBarParent', + props:{ + // 开始时间 + startDate:{ + type:Date, + }, + // 结束时间 + endDate:{ + type:Date + }, + // 进度 + progressRate:{ + type:Number, + default:0 + }, + data:{}, + id:{ + type:String, + }, + tip:{ + type:String, + } + }, + setup(props){ + const {startDate,endDate,data,id,tip} = toRefs(props) + let { progressRate } = toRefs(props) + let ganttScaleStatusHandler:Subscription = ref() + const tipHovered = ref(false) + const percentage = ref(0) + let left = ref(0) + let width = ref(0) + const max = ref(100) + const min = ref(0) + let duration = ref('') + + const setValue = (value: number | null): void => { + if (progressRate !== value) { + progressRate = value; + updateTrackAndHandle(); + } + } + const ensureValueInRange = (value: number | null): number => { + let safeValue; + if (!valueMustBeValid(value)) { + safeValue = min; + } else { + safeValue = clamp(min, value as number, max); + } + return safeValue; + } + const valueMustBeValid = (value: number): boolean => { + return !isNaN(typeof value !== 'number' ? parseFloat(value) : value); + } + const clamp = (min: number, n: number, max: number) => { + return Math.max(min, Math.min(n, max)); + } + const updateTrackAndHandle = (): void => { + const value = progressRate; + const offset = valueToOffset(value); + updateStyle(offset / 100); + this.cdr.markForCheck(); + } + const valueToOffset = (value: number): number => { + return ((value - min.value) / (max.value - min.value)) * 100; + } + const updateStyle = (percentage) => { + percentage = Math.min(1, Math.max(0, percentage)); + if (this.ganttBarTrack && this.ganttBarTrack.nativeElement) { + this.ganttBarTrack.nativeElement.style.width = `${percentage * 100}%`; + } + + if (this.ganttBarProgress && this.ganttBarProgress.nativeElement) { + this.ganttBarProgress.nativeElement.style.left = `${percentage * 100}%`; + } + } + const onInit = () => { + if (progressRate === null) { + this.setValue(this.ensureValueInRange(null)); + } + + duration = ganttService.getDuration(startDate, endDate) + 'd'; + + this.ganttScaleStatusHandler = ganttService.ganttScaleConfigChange.subscribe((config) => { + if (config.startDate) { + left = ganttService.getDatePostionOffset(startDate); + } + if (config.unit) { + left = ganttService.getDatePostionOffset(startDate); + width = ganttService.getDurationWidth(startDate, endDate); + } + }); + } + + const ngOnChanges = (changes) => { + if (changes['progressRate'] && progressRate > 0) { + updateTrackAndHandle(); + } + + if (changes['startDate']) { + left = ganttService.getDatePostionOffset(startDate); + width = ganttService.getDurationWidth(startDate, endDate); + } + + if (changes['endDate']) { + width = ganttService.getDurationWidth(startDate, endDate); + } + } + + const AfterViewInit = () => { + if (progressRate && progressRate > 0) { + updateTrackAndHandle(); + } + } + + const OnDestroy= (): void => { + if (ganttScaleStatusHandler.value) { + ganttScaleStatusHandler.value.unsubscribe(); + ganttScaleStatusHandler = null; + } + } + + return { + // startDate, + // endDate, + // progressRate, + // data, + // id, + // tip, + left, + width + } + }, + render() { + const { + // startDate, + // endDate, + // progressRate, + // data, + // id, + // tip, + left, + width + } = this + const style = { + position:'', + left:left, + width:width + } + return ( +
+
+
+
+ ) + }, +}) \ No newline at end of file diff --git a/devui/gantt/src/gantt-bar/gantt-bar.scss b/devui/gantt/src/gantt-bar/gantt-bar.scss new file mode 100644 index 00000000..2e593ef9 --- /dev/null +++ b/devui/gantt/src/gantt-bar/gantt-bar.scss @@ -0,0 +1,3 @@ +.gantt-bar { + position: relative; +} diff --git a/devui/gantt/src/gantt-bar/index.tsx b/devui/gantt/src/gantt-bar/index.tsx new file mode 100644 index 00000000..8370cf80 --- /dev/null +++ b/devui/gantt/src/gantt-bar/index.tsx @@ -0,0 +1,14 @@ +import {defineComponent} from 'vue' + +import './gantt-bar.scss' + + +export default defineComponent({ + name:'GantBar', + props:{}, + render(){ + return ( +
+ ) + } +}) \ No newline at end of file diff --git a/devui/gantt/src/gantt-service.ts b/devui/gantt/src/gantt-service.ts new file mode 100644 index 00000000..22e88813 --- /dev/null +++ b/devui/gantt/src/gantt-service.ts @@ -0,0 +1,110 @@ +import { fromEvent, merge, Observable, ReplaySubject, Subject } from 'rxjs'; +import { pluck } from 'rxjs/operators'; +import { GanttBarStatus, GanttScaleConfig, GanttScaleUnit } from './gantt-model'; +export class GanttService { + static DAY_DURATION = 24 * 60 * 60 * 1000; + scaleUnit = GanttScaleUnit.day; + scaleStartDate: Date; + scaleEndDate: Date; + ganttBarStatusChange = new Subject(); + ganttScaleConfigChange = new ReplaySubject(1); + + mouseDownListener: Observable; + mouseMoveListener = new Observable(); + mouseEndListener = new Observable(); + + changeGanttBarStatus(status: GanttBarStatus):void { + this.ganttBarStatusChange.next(status); + } + + registContainerEvents(scrollContainer: HTMLElement):void { + // 背景拖拽 + this.mouseDownListener = fromEvent(scrollContainer, 'mousedown').pipe(pluck('pageX')); + + this.mouseMoveListener = fromEvent(scrollContainer, 'mousemove').pipe(pluck('pageX')); + + this.mouseEndListener = merge(fromEvent(scrollContainer, 'mouseup'), fromEvent(scrollContainer, 'mouseout')).pipe( + pluck('pageX') + ); + } + + changeGanttScaleConfig(status: GanttScaleConfig):void { + this.ganttScaleConfigChange.next(status); + } + + setScaleConfig(config: GanttScaleConfig):void { + if (config.startDate) { + this.scaleStartDate = config.startDate; + } + if (config.endDate) { + this.scaleEndDate = config.endDate; + } + if (config.unit) { + this.scaleUnit = config.unit; + } + this.changeGanttScaleConfig(config); + } + + getScaleUnitPixel():number { + switch (this.scaleUnit) { + case GanttScaleUnit.day: + return 40; + break; + case GanttScaleUnit.week: + return 30; + break; + case GanttScaleUnit.month: + return 20; + break; + default: + break; + } + } + + getDatePostionOffset(date: Date): number { + if (date && this.scaleStartDate) { + const timeOffset = date.getTime() - this.scaleStartDate.getTime(); + const units = timeOffset / GanttService.DAY_DURATION; + return units * this.getScaleUnitPixel(); + } + } + + getDuration(startDate: Date, endDate: Date): number { + if (startDate && endDate) { + const timeOffset = endDate.getTime() - startDate.getTime(); + const duration = timeOffset / GanttService.DAY_DURATION + 1; + return Math.round(duration); + } + } + + getDurationWidth(startDate: Date, endDate: Date): number { + if (startDate && endDate) { + const duration = this.getDuration(startDate, endDate); + return duration * this.getScaleUnitPixel(); + } + } + + isSomeDate(date: Date, compareDate: Date):boolean { + if (date.getFullYear() !== compareDate.getFullYear()) { + return false; + } + + if (date.getMonth() !== compareDate.getMonth()) { + return false; + } + + if (date.getDate() !== compareDate.getDate()) { + return false; + } + return true; + } + + roundDate(date: Date):void { + if (date.getHours() >= 12) { + date.setDate(date.getDate() + 1); + date.setHours(0, 0, 0); + } else if (date.getHours() < 12) { + date.setHours(0, 0, 0); + } + } +} \ No newline at end of file diff --git a/devui/gantt/src/gantt-types.ts b/devui/gantt/src/gantt-types.ts index 82dc9ba9..fde961d1 100644 --- a/devui/gantt/src/gantt-types.ts +++ b/devui/gantt/src/gantt-types.ts @@ -13,4 +13,5 @@ export const ganttProps = { }, } as const + export type GanttProps = ExtractPropTypes -- Gitee From d5d22abf935b9e180cee4b4becfc72c9636a5d9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E9=A2=96=E6=96=8C?= Date: Tue, 9 Nov 2021 09:39:05 +0800 Subject: [PATCH 7/7] fix: delete unuse codes --- devui/vue-devui.ts | 175 ----------- docs/.vitepress/config/sidebar.ts | 277 ------------------ packages/devui-vue/devui/gantt/index.ts | 2 +- .../gantt/src/gantt-bar-parent/index.tsx | 30 +- .../devui-vue/devui/gantt/src/gantt-types.ts | 3 + 5 files changed, 15 insertions(+), 472 deletions(-) delete mode 100644 devui/vue-devui.ts delete mode 100644 docs/.vitepress/config/sidebar.ts diff --git a/devui/vue-devui.ts b/devui/vue-devui.ts deleted file mode 100644 index 917096dd..00000000 --- a/devui/vue-devui.ts +++ /dev/null @@ -1,175 +0,0 @@ -import type { App } from 'vue' - -import AccordionInstall, { Accordion } from './accordion' -import AlertInstall, { Alert } from './alert' -import AnchorInstall, { Anchor } from './anchor' -import AvatarInstall, { Avatar } from './avatar' -import BadgeInstall, { Badge } from './badge' -import BreadcrumbInstall, { Breadcrumb } from './breadcrumb' -import ButtonInstall, { Button } from './button' -import CardInstall, { Card } from './card' -import CarouselInstall, { Carousel } from './carousel' -import CascaderInstall, { Cascader } from './cascader' -import CheckboxInstall, { Checkbox } from './checkbox' -import DatePickerInstall, { DatePicker, StickSlider } from './date-picker' -import EditableSelectInstall, { EditableSelect, EditableSelectOption } from './editable-select' -import FullscreenInstall, { Fullscreen } from './fullscreen' -import GanttInstall, { Gantt } from './gantt' -import IconInstall, { Icon } from './icon' -import ImagePreviewInstall, { ImagePreviewDirective, ImagePreviewService } from './image-preview' -import InputInstall, { Input } from './input' -import InputNumberInstall, { InputNumber } from './input-number' -import LayoutInstall, { Layout, Content, Header, Footer, Aside } from './layout' -import LoadingInstall, { LoadingService, Loading } from './loading' -import ModalInstall, { Modal } from './modal' -import OverlayInstall, { FlexibleOverlay, FixedOverlay } from './overlay' -import PaginationInstall, { Pagination } from './pagination' -import PanelInstall, { Panel } from './panel' -import PopoverInstall, { Popover } from './popover' -import ProgressInstall, { Progress } from './progress' -import QuadrantDiagramInstall, { QuadrantDiagram } from './quadrant-diagram' -import RadioInstall, { Radio, RadioGroup } from './radio' -import RateInstall, { Rate } from './rate' -import RippleInstall, { RippleDirective } from './ripple' -import SearchInstall, { Search } from './search' -import SelectInstall, { Select } from './select' -import SkeletonInstall, { Skeleton } from './skeleton' -import SliderInstall, { Slider } from './slider' -import SplitterInstall, { Splitter } from './splitter' -import StatusInstall, { Status } from './status' -import StepsGuideInstall, { StepsGuide } from './steps-guide' -import StickyInstall, { Sticky } from './sticky' -import SwitchInstall, { Switch } from './switch' -import TableInstall, { Table, Column } from './table' -import TabsInstall, { Tabs } from './tabs' -import TagInputInstall, { TagInput } from './tag-input' -import TimePickerInstall, { TimePicker } from './time-picker' -import ToastInstall, { Toast, ToastService } from './toast' -import TooltipInstall, { Tooltip } from './tooltip' -import TransferInstall, { Transfer } from './transfer' -import TreeInstall, { Tree } from './tree' -import UploadInstall, { Upload, MultiUpload } from './upload' - -const installs = [ - AccordionInstall, - AlertInstall, - AnchorInstall, - AvatarInstall, - BadgeInstall, - BreadcrumbInstall, - ButtonInstall, - CardInstall, - CarouselInstall, - CascaderInstall, - CheckboxInstall, - DatePickerInstall, - EditableSelectInstall, - FullscreenInstall, - GanttInstall, - IconInstall, - ImagePreviewInstall, - InputInstall, - InputNumberInstall, - LayoutInstall, - LoadingInstall, - ModalInstall, - OverlayInstall, - PaginationInstall, - PanelInstall, - PopoverInstall, - ProgressInstall, - QuadrantDiagramInstall, - RadioInstall, - RateInstall, - RippleInstall, - SearchInstall, - SelectInstall, - SkeletonInstall, - SliderInstall, - SplitterInstall, - StatusInstall, - StepsGuideInstall, - StickyInstall, - SwitchInstall, - TableInstall, - TabsInstall, - TagInputInstall, - TimePickerInstall, - ToastInstall, - TooltipInstall, - TransferInstall, - TreeInstall, - UploadInstall -] - -export { - Accordion, - Alert, - Anchor, - Avatar, - Badge, - Breadcrumb, - Button, - Card, - Carousel, - Cascader, - Checkbox, - DatePicker, - StickSlider, - EditableSelect, - EditableSelectOption, - Fullscreen, - Gantt, - Icon, - ImagePreviewDirective, - ImagePreviewService, - Input, - InputNumber, - Layout, - Content, - Header, - Footer, - Aside, - LoadingService, - Loading, - Modal, - FlexibleOverlay, - FixedOverlay, - Pagination, - Panel, - Popover, - Progress, - QuadrantDiagram, - Radio, - RadioGroup, - Rate, - RippleDirective, - Search, - Select, - Skeleton, - Slider, - Splitter, - Status, - StepsGuide, - Sticky, - Switch, - Table, - Column, - Tabs, - TagInput, - TimePicker, - Toast, - ToastService, - Tooltip, - Transfer, - Tree, - Upload, - MultiUpload -} - -export default { - version: '0.0.1', - install(app: App): void { - installs.forEach((p) => app.use(p as any)) - } -} diff --git a/docs/.vitepress/config/sidebar.ts b/docs/.vitepress/config/sidebar.ts deleted file mode 100644 index c1dfde12..00000000 --- a/docs/.vitepress/config/sidebar.ts +++ /dev/null @@ -1,277 +0,0 @@ -export default { - '/': [ - { - "text": "快速开始", - "link": "/" - }, - { - "text": "通用", - "children": [ - { - "text": "Button 按钮", - "link": "/components/button/", - "status": "已完成" - }, - { - "text": "Fullscreen 全屏", - "link": "/components/fullscreen/", - "status": "已完成" - }, - { - "text": "Icon 图标", - "link": "/components/icon/", - "status": "已完成" - }, - { - "text": "Overlay 遮罩层", - "link": "/components/overlay/", - "status": "已完成" - }, - { - "text": "Panel 面板", - "link": "/components/panel/", - "status": "50%" - }, - { - "text": "Ripple 水波纹", - "link": "/components/ripple/", - "status": "已完成" - }, - { - "text": "Search 搜索框", - "link": "/components/search/", - "status": "已完成" - }, - { - "text": "Status 状态", - "link": "/components/status/", - "status": "已完成" - }, - { - "text": "Sticky 便贴", - "link": "/components/sticky/", - "status": "50%" - } - ] - }, - { - "text": "导航", - "children": [ - { - "text": "Accordion 手风琴", - "link": "/components/accordion/", - "status": "10%" - }, - { - "text": "Anchor 锚点", - "link": "/components/anchor/", - "status": "50%" - }, - { - "text": "Breadcrumb 面包屑", - "link": "/components/breadcrumb/", - "status": "50%" - }, - { - "text": "Pagination 分页", - "link": "/components/pagination/", - "status": "已完成" - }, - { - "text": "StepsGuide 操作指引", - "link": "/components/steps-guide/", - "status": "50%" - }, - { - "text": "Tabs 选项卡", - "link": "/components/tabs/", - "status": "60%" - } - ] - }, - { - "text": "反馈", - "children": [ - { - "text": "Alert 警告", - "link": "/components/alert/", - "status": "已完成" - }, - { - "text": "Loading 加载提示", - "link": "/components/loading/", - "status": "已完成" - }, - { - "text": "Modal 弹窗", - "link": "/components/modal/", - "status": "已完成" - }, - { - "text": "Popover 悬浮提示", - "link": "/components/popover/", - "status": "已完成" - }, - { - "text": "Toast 全局提示", - "link": "/components/toast/", - "status": "已完成" - }, - { - "text": "Tooltip提示", - "link": "/components/tooltip/", - "status": "50%" - } - ] - }, - { - "text": "数据录入", - "children": [ - { - "text": "Cascader 级联菜单", - "link": "/components/cascader/", - "status": "10%" - }, - { - "text": "Checkbox 复选框", - "link": "/components/checkbox/", - "status": "已完成" - }, - { - "text": "DatePicker 日期选择器", - "link": "/components/date-picker/", - "status": "50%" - }, - { - "text": "EditableSelect 可输入下拉选择框", - "link": "/components/editable-select/", - "status": "10%" - }, - { - "text": "Input 输入框", - "link": "/components/input/", - "status": "已完成" - }, - { - "text": "Radio 单选框", - "link": "/components/radio/", - "status": "已完成" - }, - { - "text": "Select 下拉框", - "link": "/components/select/", - "status": "10%" - }, - { - "text": "Slider 滑块", - "link": "/components/slider/", - "status": "已完成" - }, - { - "text": "Switch 开关", - "link": "/components/switch/", - "status": "已完成" - }, - { - "text": "TagInput 标签输入框", - "link": "/components/tag-input/", - "status": "已完成" - }, - { - "text": "TimePicker 时间选择器", - "link": "/components/time-picker/", - "status": "20%" - }, - { - "text": "Transfer 穿梭框", - "link": "/components/transfer/", - "status": "10%" - }, - { - "text": "Upload 上传", - "link": "/components/upload/", - "status": "80%" - } - ] - }, - { - "text": "数据展示", - "children": [ - { - "text": "Avatar 头像", - "link": "/components/avatar/", - "status": "已完成" - }, - { - "text": "Badge 徽标", - "link": "/components/badge/", - "status": "已完成" - }, - { - "text": "Card 卡片", - "link": "/components/card/", - "status": "已完成" - }, - { - "text": "Carousel 走马灯", - "link": "/components/carousel/", - "status": "80%" - }, - { - "text": "Gantt 甘特图", - "link": "/components/gantt/" - }, - { - "text": "ImagePreview 图片预览", - "link": "/components/image-preview/", - "status": "已完成" - }, - { - "text": "Progress 进度条", - "link": "/components/progress/", - "status": "已完成" - }, - { - "text": "QuadrantDiagram 象限图", - "link": "/components/quadrant-diagram/", - "status": "10%" - }, - { - "text": "Rate 评分", - "link": "/components/rate/", - "status": "已完成" - }, - { - "text": "Skeleton 骨架屏", - "link": "/components/skeleton/", - "status": "已完成" - }, - { - "text": "Table 表格", - "link": "/components/table/", - "status": "10%" - }, - { - "text": "Tree 树", - "link": "/components/tree/", - "status": "20%" - } - ] - }, - { - "text": "布局", - "children": [ - { - "text": "Layout 布局", - "link": "/components/layout/", - "status": "已完成" - }, - { - "text": "Splitter 分割器", - "link": "/components/splitter/", - "status": "已完成" - } - ] - } - ] -} diff --git a/packages/devui-vue/devui/gantt/index.ts b/packages/devui-vue/devui/gantt/index.ts index 071685e5..4f79701c 100644 --- a/packages/devui-vue/devui/gantt/index.ts +++ b/packages/devui-vue/devui/gantt/index.ts @@ -14,7 +14,7 @@ export { Gantt } export default { title: 'Gantt 甘特图', category: '数据展示', - status: undefined, // TODO: 组件若开发完成则填入"已完成",并删除该注释 + status: '10%', // TODO: 组件若开发完成则填入"已完成",并删除该注释 install(app: App): void { app.use(Gantt as any) }, diff --git a/packages/devui-vue/devui/gantt/src/gantt-bar-parent/index.tsx b/packages/devui-vue/devui/gantt/src/gantt-bar-parent/index.tsx index d331fd08..c20a7cad 100644 --- a/packages/devui-vue/devui/gantt/src/gantt-bar-parent/index.tsx +++ b/packages/devui-vue/devui/gantt/src/gantt-bar-parent/index.tsx @@ -1,6 +1,7 @@ import {defineComponent , ref , toRefs } from 'vue'; import {GanttService} from '../gantt-service' import { Subscription } from 'rxjs'; +// import { GanttProps } from '../gantt-types' import './gantt-bar-parent.scss'; const ganttService = new GanttService() export default defineComponent({ @@ -25,18 +26,21 @@ export default defineComponent({ }, tip:{ type:String, + }, + ganttScaleStatusHandler:{ + type:Subscription } }, setup(props){ - const {startDate,endDate,data,id,tip} = toRefs(props) - let { progressRate } = toRefs(props) - let ganttScaleStatusHandler:Subscription = ref() + const {startDate,endDate,data,id,tip } = toRefs(props) + let { progressRate, ganttScaleStatusHandler } = toRefs(props) + // const ganttScaleStatusHandler:Subscription = ref() const tipHovered = ref(false) const percentage = ref(0) let left = ref(0) let width = ref(0) - const max = ref(100) - const min = ref(0) + let max = 100 + let min = 0 let duration = ref('') const setValue = (value: number | null): void => { @@ -86,7 +90,7 @@ export default defineComponent({ duration = ganttService.getDuration(startDate, endDate) + 'd'; - this.ganttScaleStatusHandler = ganttService.ganttScaleConfigChange.subscribe((config) => { + ganttScaleStatusHandler = ganttService.ganttScaleConfigChange.subscribe((config) => { if (config.startDate) { left = ganttService.getDatePostionOffset(startDate); } @@ -94,7 +98,7 @@ export default defineComponent({ left = ganttService.getDatePostionOffset(startDate); width = ganttService.getDurationWidth(startDate, endDate); } - }); + }) as Subscription; } const ngOnChanges = (changes) => { @@ -126,24 +130,12 @@ export default defineComponent({ } return { - // startDate, - // endDate, - // progressRate, - // data, - // id, - // tip, left, width } }, render() { const { - // startDate, - // endDate, - // progressRate, - // data, - // id, - // tip, left, width } = this diff --git a/packages/devui-vue/devui/gantt/src/gantt-types.ts b/packages/devui-vue/devui/gantt/src/gantt-types.ts index fde961d1..02cf168d 100644 --- a/packages/devui-vue/devui/gantt/src/gantt-types.ts +++ b/packages/devui-vue/devui/gantt/src/gantt-types.ts @@ -11,6 +11,9 @@ export const ganttProps = { type: String as PropType, default: GanttScaleUnit.day, }, + progressRate:{ + type:Number + }, } as const -- Gitee