去除调试日志相关代码,优化demo调试可视区
This commit is contained in:
@@ -910,7 +910,7 @@ function taskDebug(item: any) {
|
|||||||
.app-container {
|
.app-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 20px;
|
padding: 10px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background: var(--gantt-bg-secondary, #f0f2f5);
|
background: var(--gantt-bg-secondary, #f0f2f5);
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -922,7 +922,7 @@ function taskDebug(item: any) {
|
|||||||
background: var(--gantt-bg-primary, #ffffff);
|
background: var(--gantt-bg-primary, #ffffff);
|
||||||
border: 1px solid var(--gantt-border-color, #e4e7ed);
|
border: 1px solid var(--gantt-border-color, #e4e7ed);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 10px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -1453,7 +1453,6 @@ function taskDebug(item: any) {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
margin-bottom: 24px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.license-info {
|
.license-info {
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
min-width: 320px;
|
min-width: 320px;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
padding: 30px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, nextTick, onMounted, onUnmounted, computed } from 'vue'
|
import { ref, watch, nextTick, onMounted, onUnmounted } 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'
|
||||||
|
|
||||||
@@ -44,11 +44,16 @@ const canvasRef = ref<HTMLCanvasElement | null>(null)
|
|||||||
// requestAnimationFrame 防抖控制
|
// requestAnimationFrame 防抖控制
|
||||||
let rafId: number | null = null
|
let rafId: number | null = null
|
||||||
let pendingRedraw = false
|
let pendingRedraw = false
|
||||||
|
let themeObserver: MutationObserver | null = null
|
||||||
|
|
||||||
// 当前主题(用于分隔线颜色)
|
// 当前主题(用于分隔线颜色)
|
||||||
const isDarkTheme = computed(() => {
|
const isDarkTheme = ref(document.documentElement.getAttribute('data-theme') === 'dark')
|
||||||
return document.documentElement.getAttribute('data-theme') === 'dark'
|
|
||||||
})
|
// 监听主题变化
|
||||||
|
const updateTheme = () => {
|
||||||
|
isDarkTheme.value = document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
scheduleRedraw()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绘制关系线到 Canvas
|
* 绘制关系线到 Canvas
|
||||||
@@ -58,25 +63,29 @@ const drawLinks = () => {
|
|||||||
const canvas = canvasRef.value
|
const canvas = canvasRef.value
|
||||||
if (!canvas) return
|
if (!canvas) return
|
||||||
|
|
||||||
// 适配高清屏(Retina)
|
const ctx = canvas.getContext('2d', { alpha: true })
|
||||||
const dpr = window.devicePixelRatio || 1
|
|
||||||
const rect = canvas.getBoundingClientRect()
|
|
||||||
|
|
||||||
// 设置实际像素尺寸
|
|
||||||
canvas.width = rect.width * dpr
|
|
||||||
canvas.height = rect.height * dpr
|
|
||||||
const ctx = canvas.getContext('2d', { alpha: true }) // 启用透明背景
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error('❌ Canvas context 获取失败,可能是尺寸超限')
|
console.error('❌ Canvas context 获取失败,可能是尺寸超限')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缩放上下文以适配高清屏
|
// 适配高清屏(Retina)
|
||||||
ctx.scale(dpr, dpr)
|
const dpr = window.devicePixelRatio || 1
|
||||||
|
const displayWidth = props.width
|
||||||
|
const displayHeight = props.height
|
||||||
|
|
||||||
|
// 只在尺寸变化时更新 canvas 尺寸
|
||||||
|
const pixelWidth = displayWidth * dpr
|
||||||
|
const pixelHeight = displayHeight * dpr
|
||||||
|
if (canvas.width !== pixelWidth || canvas.height !== pixelHeight) {
|
||||||
|
canvas.width = pixelWidth
|
||||||
|
canvas.height = pixelHeight
|
||||||
|
ctx.scale(dpr, dpr)
|
||||||
|
}
|
||||||
|
|
||||||
// 清空画布(透明)
|
// 清空画布(透明)
|
||||||
ctx.clearRect(0, 0, rect.width, rect.height)
|
ctx.clearRect(0, 0, displayWidth, displayHeight)
|
||||||
|
|
||||||
// 绘制月份分隔线(在关系线之前,作为背景)
|
// 绘制月份分隔线(在关系线之前,作为背景)
|
||||||
if (props.showVerticalLines && props.verticalLines && props.verticalLines.length > 0) {
|
if (props.showVerticalLines && props.verticalLines && props.verticalLines.length > 0) {
|
||||||
@@ -93,9 +102,9 @@ const drawLinks = () => {
|
|||||||
for (const line of props.verticalLines) {
|
for (const line of props.verticalLines) {
|
||||||
const localX = line.left - props.offsetLeft
|
const localX = line.left - props.offsetLeft
|
||||||
// 只绘制在 Canvas 可见范围内的线
|
// 只绘制在 Canvas 可见范围内的线
|
||||||
if (localX >= 0 && localX <= rect.width) {
|
if (localX >= 0 && localX <= displayWidth) {
|
||||||
ctx.moveTo(localX, 0)
|
ctx.moveTo(localX, 0)
|
||||||
ctx.lineTo(localX, rect.height)
|
ctx.lineTo(localX, displayHeight)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.stroke()
|
ctx.stroke()
|
||||||
@@ -114,7 +123,7 @@ const drawLinks = () => {
|
|||||||
|
|
||||||
// 虚拟渲染:计算 Canvas 覆盖的范围
|
// 虚拟渲染:计算 Canvas 覆盖的范围
|
||||||
const canvasStartX = props.offsetLeft
|
const canvasStartX = props.offsetLeft
|
||||||
const canvasEndX = props.offsetLeft + rect.width
|
const canvasEndX = props.offsetLeft + displayWidth
|
||||||
|
|
||||||
// 定义线条数据类型
|
// 定义线条数据类型
|
||||||
interface LineData {
|
interface LineData {
|
||||||
@@ -135,24 +144,16 @@ const drawLinks = () => {
|
|||||||
const normalLines: LineData[] = []
|
const normalLines: LineData[] = []
|
||||||
const fadedLines: LineData[] = [] // 高亮模式下的普通线条(半透明)
|
const fadedLines: LineData[] = [] // 高亮模式下的普通线条(半透明)
|
||||||
|
|
||||||
// 收集所有关系线数据并分组
|
|
||||||
let totalRelations = 0 // 总关系数
|
|
||||||
let culledRelations = 0 // 被裁剪的关系数
|
|
||||||
let drawnRelations = 0 // 实际绘制的关系数
|
|
||||||
|
|
||||||
for (const task of props.tasks) {
|
for (const task of props.tasks) {
|
||||||
if (!task.predecessor || !props.taskBarPositions[task.id]) continue
|
if (!task.predecessor || !props.taskBarPositions[task.id]) continue
|
||||||
|
|
||||||
const predecessorIds = getPredecessorIds(task.predecessor)
|
const predecessorIds = getPredecessorIds(task.predecessor)
|
||||||
|
|
||||||
for (const predecessorId of predecessorIds) {
|
for (const predecessorId of predecessorIds) {
|
||||||
totalRelations++
|
|
||||||
|
|
||||||
const fromBar = props.taskBarPositions[predecessorId]
|
const fromBar = props.taskBarPositions[predecessorId]
|
||||||
const toBar = props.taskBarPositions[task.id]
|
const toBar = props.taskBarPositions[task.id]
|
||||||
|
|
||||||
if (!fromBar || !toBar || !currentTaskIds.has(predecessorId)) {
|
if (!fromBar || !toBar || !currentTaskIds.has(predecessorId)) {
|
||||||
culledRelations++
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,12 +164,9 @@ const drawLinks = () => {
|
|||||||
const lineMinX = Math.min(fromX, toX)
|
const lineMinX = Math.min(fromX, toX)
|
||||||
const lineMaxX = Math.max(fromX, toX)
|
const lineMaxX = Math.max(fromX, toX)
|
||||||
if (lineMaxX < canvasStartX || lineMinX > canvasEndX) {
|
if (lineMaxX < canvasStartX || lineMinX > canvasEndX) {
|
||||||
culledRelations++
|
|
||||||
continue // 完全在 Canvas 外,跳过
|
continue // 完全在 Canvas 外,跳过
|
||||||
}
|
}
|
||||||
|
|
||||||
drawnRelations++
|
|
||||||
|
|
||||||
// 判断高亮状态
|
// 判断高亮状态
|
||||||
const fromIsPrimary = props.highlightedTaskId === predecessorId
|
const fromIsPrimary = props.highlightedTaskId === predecessorId
|
||||||
const toIsPrimary = props.highlightedTaskId === task.id
|
const toIsPrimary = props.highlightedTaskId === task.id
|
||||||
@@ -204,7 +202,6 @@ const drawLinks = () => {
|
|||||||
|
|
||||||
// 预计算箭头角度
|
// 预计算箭头角度
|
||||||
const arrowAngle = Math.atan2(y2 - c2y, x2 - c2x)
|
const arrowAngle = Math.atan2(y2 - c2y, x2 - c2x)
|
||||||
|
|
||||||
const lineData: LineData = { x1, y1, x2, y2, c1x, c1y, c2x, c2y, arrowAngle }
|
const lineData: LineData = { x1, y1, x2, y2, c1x, c1y, c2x, c2y, arrowAngle }
|
||||||
|
|
||||||
// 根据状态分组
|
// 根据状态分组
|
||||||
@@ -363,7 +360,7 @@ const scheduleRedraw = () => {
|
|||||||
watch(
|
watch(
|
||||||
[
|
[
|
||||||
() => props.taskBarPositions,
|
() => props.taskBarPositions,
|
||||||
() => props.tasks.length,
|
() => props.tasks,
|
||||||
() => props.highlightedTaskId,
|
() => props.highlightedTaskId,
|
||||||
() => props.highlightedTaskIds,
|
() => props.highlightedTaskIds,
|
||||||
() => props.hoveredTaskId,
|
() => props.hoveredTaskId,
|
||||||
@@ -382,6 +379,21 @@ watch(
|
|||||||
|
|
||||||
// 组件挂载后初始化绘制
|
// 组件挂载后初始化绘制
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 监听主题变化
|
||||||
|
themeObserver = new MutationObserver((mutations) => {
|
||||||
|
for (const mutation of mutations) {
|
||||||
|
if (mutation.attributeName === 'data-theme') {
|
||||||
|
updateTheme()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
themeObserver.observe(document.documentElement, {
|
||||||
|
attributes: true,
|
||||||
|
attributeFilter: ['data-theme'],
|
||||||
|
})
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
drawLinks()
|
drawLinks()
|
||||||
})
|
})
|
||||||
@@ -389,6 +401,12 @@ onMounted(() => {
|
|||||||
|
|
||||||
// 组件卸载时清理
|
// 组件卸载时清理
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
// 清理主题观察器
|
||||||
|
if (themeObserver) {
|
||||||
|
themeObserver.disconnect()
|
||||||
|
themeObserver = null
|
||||||
|
}
|
||||||
|
|
||||||
// 取消待处理的 RAF
|
// 取消待处理的 RAF
|
||||||
if (rafId !== null) {
|
if (rafId !== null) {
|
||||||
cancelAnimationFrame(rafId)
|
cancelAnimationFrame(rafId)
|
||||||
|
|||||||
Reference in New Issue
Block a user