vue-ganttastic甘特图label标签横向滚动固定方法

发布于:2025-05-15 ⋅ 阅读:(12) ⋅ 点赞:(0)

这个甘特图之前插件里,没有找到能固定label标签在屏幕上的办法,用css各种办法都没有实现,所以我我直接手写定位,用js监听滚动条滚动的距离,然后同步移动甘特图label标签,造成一种定位的错觉,以下是代码:

我用的是介绍 | Pure Admin 保姆级文档(已更新至最新版v6.0.0)这个前端框架,感觉功能还是非常完善的,作者全职做开源,希望大家也多多支持。

这个是全部甘特图的示例代码

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
// https://zunnzunn.github.io/vue-ganttastic/introduction.html
import { GGanttChart, GGanttRow } from "@infectoone/vue-ganttastic";

// 添加滚动位置状态
const scrollLeft = ref(0);
// 添加容器引用
const containerRef = ref(null);

// 现有数据保持不变
const context = ref([
  [
    {
      week: "星期一",
      beginDate: "06:00",
      endDate: "22:00",
      label_column_title: "123",
      ganttBarConfig: {
        id: "0",
        hasHandles: true,
        label: "需求收集和分析  负责人:小张",
        style: {
          background: "#e96560"
        }
      }
    }
  ],
  [
    {
      week: "星期二",
      beginDate: "09:00",
      endDate: "18:00",
      ganttBarConfig: {
        id: "1",
        hasHandles: true,
        label: "系统设计  负责人:小强",
        style: {
          background: "#5ccfa3"
        }
      }
    }
  ],
  [
    {
      week: "星期三",
      beginDate: "07:00",
      endDate: "20:00",
      ganttBarConfig: {
        id: "2",
        hasHandles: true,
        label: "编码实现  负责人:老李",
        style: {
          background: "#77d6fa"
        }
      }
    }
  ],
  [
    {
      week: "星期四",
      beginDate: "06:00",
      endDate: "21:00",
      ganttBarConfig: {
        id: "3",
        hasHandles: true,
        label: "编码实现  负责人:小明",
        style: {
          color: "#fff",
          background: "#1b2a47"
        }
      }
    }
  ],
  [
    {
      week: "星期五",
      beginDate: "05:00",
      endDate: "19:00",
      ganttBarConfig: {
        id: "4",
        hasHandles: true,
        label: "内部测试  负责人:小雪",
        style: {
          background: "#5ccfa3"
        }
      }
    }
  ],
  [
    {
      week: "星期六",
      beginDate: "10:00",
      endDate: "22:00",
      ganttBarConfig: {
        id: "5",
        hasHandles: true,
        label: "系统优化和文档整理  负责人:小欣",
        style: {
          background: "#f8bc45"
        }
      }
    }
  ],
  [
    {
      week: "星期天",
      beginDate: "04:00",
      endDate: "23:59",
      ganttBarConfig: {
        id: "6",
        immobile: false,
        hasHandles: false,
        label: "部署和上线  负责人:老王",
        style: {
          background: "#f3953d"
        }
      }
    }
  ],
  [
    {
      week: "星期天",
      beginDate: "04:00",
      endDate: "23:59",
      ganttBarConfig: {
        id: "6",
        immobile: false,
        hasHandles: false,
        label: "部署和上线  负责人:老王",
        style: {
          background: "#f3953d"
        }
      }
    }
  ]
]);

// 滚动事件处理函数
function handleScroll(e) {
  scrollLeft.value = e.target.scrollLeft;
  console.log("滚动事件触发", scrollLeft.value);
  const labels = document.querySelectorAll(
    ".g-gantt-row-label, .g-gantt-row-label-container"
  );
  labels.forEach(label => {
    label.style.position = "absolute";
    label.style.left = scrollLeft.value + "px";
  });
}

// 添加和移除滚动事件监听
onMounted(() => {
  // 延迟添加事件监听,确保DOM已完全渲染
  setTimeout(() => {
    if (containerRef.value) {
      containerRef.value.addEventListener("scroll", handleScroll);
      console.log("滚动监听已添加", containerRef.value);
    }
  }, 500);
});

onUnmounted(() => {
  if (containerRef.value) {
    containerRef.value.removeEventListener("scroll", handleScroll);
    console.log("滚动监听已移除");
  }
});

function getWeekRange() {
  const today = new Date();
  const dayOfWeek = today.getDay();

  const startDate = new Date(today);
  startDate.setDate(today.getDate() - dayOfWeek + 1);

  const endDate = new Date(startDate);
  endDate.setDate(startDate.getDate() + 6);

  const formatDate = date => {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    return `${year}-${month}-${day}`;
  };

  const currentWeekStart = formatDate(startDate);
  const currentWeekEnd = formatDate(endDate);

  return {
    currentWeekStart,
    currentWeekEnd
  };
}

const weekRangeInChina = getWeekRange();
</script>

<template>
  <div ref="containerRef" class="gantt-container">
    <g-gantt-chart
      chart-start="00:00"
      chart-end="23:59"
      precision="hour"
      date-format="HH:mm"
      bar-start="beginDate"
      bar-end="endDate"
      grid
      class="full-width-gantt"
    >
      <template #upper-timeunit>
        <h1>
          {{
            `${weekRangeInChina.currentWeekStart} / ${weekRangeInChina.currentWeekEnd}`
          }}
        </h1>
      </template>
      <g-gantt-row
        v-for="(item, index) in context"
        :key="index"
        :bars="item"
        :label="item[0].week"
        highlight-on-hover
      />
    </g-gantt-chart>
  </div>
</template>

<style>
/* 全局样式,确保能覆盖组件内部样式 */
.g-gantt-row-label,
.g-gantt-row-label-container {
  position: relative !important;
  transition: none !important;
}

.gantt-container {
  width: 100%;
  overflow-x: auto;
  padding-bottom: 10px;
}

.full-width-gantt {
  min-width: 1500px;
  width: 200%;
}

/* 修改标签宽度样式 */
.g-gantt-row-label {
  width: 100px !important;
  min-width: 100px !important;
  max-width: 100px !important;
  box-sizing: border-box !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
</style>

重点处理方法是:

// 添加滚动位置状态
const scrollLeft = ref(0);
// 添加容器引用
const containerRef = ref(null);

// 添加和移除滚动事件监听
onMounted(() => {
  // 延迟添加事件监听,确保DOM已完全渲染
  setTimeout(() => {
    if (containerRef.value) {
      containerRef.value.addEventListener("scroll", handleScroll);
      console.log("滚动监听已添加", containerRef.value);
    }
  }, 500);
});


// 滚动事件处理函数
function handleScroll(e) {
  scrollLeft.value = e.target.scrollLeft;
  console.log("滚动事件触发", scrollLeft.value);
  const labels = document.querySelectorAll(
    ".g-gantt-row-label, .g-gantt-row-label-container"
  );
  labels.forEach(label => {
    label.style.position = "absolute";
    label.style.left = scrollLeft.value + "px";
  });
}
onUnmounted(() => {
  if (containerRef.value) {
    containerRef.value.removeEventListener("scroll", handleScroll);
    console.log("滚动监听已移除");
  }
});


网站公告

今日签到

点亮在社区的每一天
去签到