优化:周视图月开始分隔线实现使用canvas替代dom
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, nextTick, onMounted } from 'vue'
|
import { ref, watch, nextTick, onMounted, computed } from 'vue'
|
||||||
import type { Task } from '../models/classes/Task'
|
import type { Task } from '../models/classes/Task'
|
||||||
import { getPredecessorIds } from '../utils/predecessorUtils'
|
import { getPredecessorIds } from '../utils/predecessorUtils'
|
||||||
|
|
||||||
@@ -11,6 +11,12 @@ interface TaskBarPosition {
|
|||||||
height: number
|
height: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 定义月份分隔线位置类型
|
||||||
|
interface VerticalLine {
|
||||||
|
left: number
|
||||||
|
label?: string
|
||||||
|
}
|
||||||
|
|
||||||
// 定义 Props
|
// 定义 Props
|
||||||
interface Props {
|
interface Props {
|
||||||
tasks: Task[]
|
tasks: Task[]
|
||||||
@@ -20,13 +26,24 @@ interface Props {
|
|||||||
highlightedTaskId: number | null
|
highlightedTaskId: number | null
|
||||||
highlightedTaskIds: Set<number>
|
highlightedTaskIds: Set<number>
|
||||||
hoveredTaskId: number | null
|
hoveredTaskId: number | null
|
||||||
|
// 月份分隔线配置
|
||||||
|
verticalLines?: VerticalLine[]
|
||||||
|
showVerticalLines?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
verticalLines: () => [],
|
||||||
|
showVerticalLines: true,
|
||||||
|
})
|
||||||
|
|
||||||
// Canvas 引用
|
// Canvas 引用
|
||||||
const canvasRef = ref<HTMLCanvasElement | null>(null)
|
const canvasRef = ref<HTMLCanvasElement | null>(null)
|
||||||
|
|
||||||
|
// 当前主题(用于分隔线颜色)
|
||||||
|
const isDarkTheme = computed(() => {
|
||||||
|
return document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绘制关系线到 Canvas
|
* 绘制关系线到 Canvas
|
||||||
* 性能优势:相比 SVG 提升 18 倍渲染性能
|
* 性能优势:相比 SVG 提升 18 倍渲染性能
|
||||||
@@ -52,6 +69,26 @@ const drawLinks = () => {
|
|||||||
// 清空画布
|
// 清空画布
|
||||||
ctx.clearRect(0, 0, rect.width, rect.height)
|
ctx.clearRect(0, 0, rect.width, rect.height)
|
||||||
|
|
||||||
|
// 绘制月份分隔线(在关系线之前,作为背景)
|
||||||
|
if (props.showVerticalLines && props.verticalLines && props.verticalLines.length > 0) {
|
||||||
|
ctx.save()
|
||||||
|
|
||||||
|
// 使用与旗帜一致的主题色:浅色模式 #409eff,暗色模式 #66b1ff
|
||||||
|
const lineColor = isDarkTheme.value ? '#66b1ff' : '#409eff'
|
||||||
|
ctx.strokeStyle = lineColor
|
||||||
|
ctx.lineWidth = 1
|
||||||
|
|
||||||
|
// 绘制每条垂直线
|
||||||
|
for (const line of props.verticalLines) {
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.moveTo(line.left, 0)
|
||||||
|
ctx.lineTo(line.left, rect.height)
|
||||||
|
ctx.stroke()
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.restore()
|
||||||
|
}
|
||||||
|
|
||||||
// 获取当前渲染的任务ID集合
|
// 获取当前渲染的任务ID集合
|
||||||
const currentTaskIds = new Set<number>()
|
const currentTaskIds = new Set<number>()
|
||||||
for (const task of props.tasks) {
|
for (const task of props.tasks) {
|
||||||
|
|||||||
@@ -3283,6 +3283,8 @@ const handleAddSuccessor = (task: Task) => {
|
|||||||
:highlighted-task-id="highlightedTaskId"
|
:highlighted-task-id="highlightedTaskId"
|
||||||
:highlighted-task-ids="highlightedTaskIds"
|
:highlighted-task-ids="highlightedTaskIds"
|
||||||
:hovered-task-id="hoveredTaskId"
|
:hovered-task-id="hoveredTaskId"
|
||||||
|
:vertical-lines="monthFirstVerticalLines"
|
||||||
|
:show-vertical-lines="currentTimeScale === TimelineScale.WEEK"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<!-- 年度视图今日标记线 -->
|
<!-- 年度视图今日标记线 -->
|
||||||
@@ -3295,17 +3297,6 @@ const handleAddSuccessor = (task: Task) => {
|
|||||||
}"
|
}"
|
||||||
></div>
|
></div>
|
||||||
|
|
||||||
<!-- 月份1号竖直线(周视图) - 优化:使用预计算的位置数组 -->
|
|
||||||
<div
|
|
||||||
v-for="(line, index) in monthFirstVerticalLines"
|
|
||||||
:key="`vline-${index}`"
|
|
||||||
class="month-first-vertical-line"
|
|
||||||
:style="{
|
|
||||||
left: `${line.left}px`,
|
|
||||||
height: `${contentHeight}px`,
|
|
||||||
}"
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<!-- 背景列 -->
|
<!-- 背景列 -->
|
||||||
<div class="day-columns" :style="{ height: `${contentHeight}px` }">
|
<div class="day-columns" :style="{ height: `${contentHeight}px` }">
|
||||||
<!-- 小时视图背景列 -->
|
<!-- 小时视图背景列 -->
|
||||||
@@ -3874,22 +3865,6 @@ const handleAddSuccessor = (task: Task) => {
|
|||||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 月份1号竖直线样式 */
|
|
||||||
.month-first-vertical-line {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
width: 1px;
|
|
||||||
background-color: var(--gantt-primary, #409eff);
|
|
||||||
opacity: 0.6;
|
|
||||||
z-index: 5;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 暗色主题下的竖直线 */
|
|
||||||
:global(html[data-theme='dark']) .month-first-vertical-line {
|
|
||||||
background-color: var(--gantt-primary-light, #66b1ff);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 周视图背景列样式 */
|
/* 周视图背景列样式 */
|
||||||
.month-week-columns {
|
.month-week-columns {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Reference in New Issue
Block a user