|
|
@@ -1,54 +1,269 @@
|
|
|
<template>
|
|
|
- <div>
|
|
|
- <gantt-chart-vue
|
|
|
- :rows="ganttRows"
|
|
|
- :legend="ganttLegend"
|
|
|
- :readOnly="false"
|
|
|
- @tagDragEnd="handleDragEnd"
|
|
|
- />
|
|
|
+ <div class="gantt-wrapper">
|
|
|
+ <!-- 甘特图容器 -->
|
|
|
+ <div ref="ganttContainer" class="gantt-container"></div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import ganttChartVue from 'gantt-chart-vue';
|
|
|
+import gantt from 'dhtmlx-gantt';
|
|
|
+import 'dhtmlx-gantt/codebase/dhtmlxgantt.css'; // 引入样式
|
|
|
+// 立即启用插件,在任何配置之前
|
|
|
+
|
|
|
export default {
|
|
|
name: "ganttChart",
|
|
|
- components: { ganttChartVue },
|
|
|
+ props:['data','clickCan'],
|
|
|
data() {
|
|
|
return {
|
|
|
- // 1. 定义图例 (tag的类型和颜色)
|
|
|
- ganttLegend: [
|
|
|
- { label: '设计', color: '#5470c6', type: 1, dragable: true },
|
|
|
- { label: '开发', color: '#91cc75', type: 2, dragable: true },
|
|
|
- { label: '测试', color: '#fac858', type: 3, dragable: false },
|
|
|
- ],
|
|
|
- // 2. 定义行数据
|
|
|
- ganttRows: [
|
|
|
- {
|
|
|
- label: '项目A',
|
|
|
- tags: [
|
|
|
- { startTime: '2024-03-01 09:00', endTime: '2024-03-05 18:00', label: '原型设计', type: 1 },
|
|
|
- { startTime: '2024-03-06 09:00', endTime: '2024-03-20 18:00', label: '前端开发', type: 2 },
|
|
|
- ]
|
|
|
- },
|
|
|
- {
|
|
|
- label: '项目B',
|
|
|
- tags: [
|
|
|
- { startTime: '2024-03-10 09:00', endTime: '2024-03-25 18:00', label: '功能测试', type: 3 },
|
|
|
- ]
|
|
|
- }
|
|
|
- ]
|
|
|
+ clickedTaskInfo: null,
|
|
|
+ // 模拟数据
|
|
|
+ tasks: {
|
|
|
+ data: [],
|
|
|
+ links: []
|
|
|
+ },
|
|
|
+ showType:'日'
|
|
|
};
|
|
|
},
|
|
|
+ mounted() {
|
|
|
+ // this.setList()
|
|
|
+ this.initGantt();
|
|
|
+ // 监听窗口大小变化以重绘甘特图
|
|
|
+ window.addEventListener('resize', () => {
|
|
|
+ if (gantt) gantt.render();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ // 清理事件监听,防止内存泄漏
|
|
|
+ window.removeEventListener('resize', () => {
|
|
|
+ if (gantt) gantt.render();
|
|
|
+ });
|
|
|
+ },
|
|
|
methods: {
|
|
|
- handleDragEnd(data) {
|
|
|
- console.log('任务拖拽结束,新数据:', data);
|
|
|
- // 在这里更新后端数据
|
|
|
- }
|
|
|
- }
|
|
|
+ setList(data){
|
|
|
+ console.log(data,'输出data的数据输出')
|
|
|
+ const oneDay = 24 * 60 * 60 * 1000; // 毫秒数
|
|
|
+ const firstDate = new Date(data[0].begdate);
|
|
|
+ const secondDate = new Date(data[0].enddate);
|
|
|
+ const diffDays = Math.round(Math.abs((firstDate - secondDate) / oneDay));
|
|
|
+ console.log(diffDays,'相差的天数')
|
|
|
+ if (diffDays > 30){
|
|
|
+ this.showType = '月'
|
|
|
+ }else {
|
|
|
+ this.showType = '日'
|
|
|
+ }
|
|
|
+ this.tasks.data = data.map(item => {
|
|
|
+ return {
|
|
|
+ id:item.sa_service_improvement_planid,
|
|
|
+ text:item.title + ',' + item.begdate + '~' + item.enddate,
|
|
|
+ start_date:item.begdate,
|
|
|
+ end_date:item.enddate,
|
|
|
+ progress:1
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.$nextTick(()=>{
|
|
|
+ this.initGantt()
|
|
|
+ })
|
|
|
+
|
|
|
+ },
|
|
|
+ initGantt() {
|
|
|
+
|
|
|
+ gantt.i18n.setLocale('cn'); // 设置为中文 [citation:1]
|
|
|
+ gantt.config.xml_date = "%Y-%m-%d"; // 设置日期格式 [citation:5]
|
|
|
+
|
|
|
+ // 关键配置:隐藏左侧表格
|
|
|
+ gantt.config.grid_width = 0; // 将左侧表格宽度设为0
|
|
|
+ gantt.config.show_grid = false; // 不显示表格网格
|
|
|
+
|
|
|
+ // === 只读配置:禁止所有拖动编辑 ===
|
|
|
+ gantt.config.readonly = true; // 整体只读模式
|
|
|
+
|
|
|
+ // 6. 工具提示配置
|
|
|
+ gantt.config.tooltip_timeout = 100; // 设置短延迟方便测试
|
|
|
+ gantt.config.tooltip_hide_timeout = 100;
|
|
|
+ gantt.config.tooltip_offset_x = 15;
|
|
|
+ gantt.config.tooltip_offset_y = 20;
|
|
|
+
|
|
|
+
|
|
|
+ // 7. 自定义工具提示(简化版本测试)
|
|
|
+ gantt.templates.tooltip_text = function(start, end, task) {
|
|
|
+ // 简单测试内容
|
|
|
+ return `
|
|
|
+ <div style="padding: 10px; background: white; border: 1px solid #ccc; border-radius: 4px;">
|
|
|
+ <div><strong>${task.text}</strong></div>
|
|
|
+ <div>开始: ${gantt.templates.tooltip_date_format(start)}</div>
|
|
|
+ <div>结束: ${gantt.templates.tooltip_date_format(end)}</div>
|
|
|
+ </div>
|
|
|
+ `;
|
|
|
+ };
|
|
|
+
|
|
|
+ if (this.showType == '日'){
|
|
|
+ gantt.config.scales = [
|
|
|
+ { unit: "month", step: 1, format: "%Y年%m月" },
|
|
|
+ { unit: "day", step: 1, format: "%d日" }
|
|
|
+ ];
|
|
|
+ }else {
|
|
|
+ gantt.config.scales = [
|
|
|
+ { unit: "year", step: 1, format: "%Y年" },
|
|
|
+ { unit: "month", step: 1, format: "%Y年%m月" }
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 9. 调试:检查tooltip是否被正确注册
|
|
|
+ console.log('Tooltip plugin enabled:', !!gantt.plugins.tooltip);
|
|
|
+
|
|
|
+ // === 添加点击事件 ===
|
|
|
+ this.setupClickEvents();
|
|
|
+
|
|
|
+
|
|
|
+ // 4. 清空并初始化
|
|
|
+ gantt.clearAll();
|
|
|
+ gantt.init(this.$refs.ganttContainer);
|
|
|
+ gantt.parse(this.tasks);
|
|
|
+ },
|
|
|
+ formatDate(dateStr) {
|
|
|
+ if (!dateStr) return '';
|
|
|
+ const d = new Date(dateStr);
|
|
|
+ const y = d.getFullYear();
|
|
|
+ const m = String(d.getMonth() + 1).padStart(2, '0');
|
|
|
+ const day = String(d.getDate()).padStart(2, '0');
|
|
|
+ return `${y}年${m}月${day}日`;
|
|
|
+ },
|
|
|
+ setupClickEvents(){
|
|
|
+ // 先解绑已存在的事件
|
|
|
+ gantt.detachEvent("onTaskClick");
|
|
|
+
|
|
|
+ // 再重新绑定
|
|
|
+ gantt.attachEvent("onTaskClick", (id, e) => {
|
|
|
+ const task = gantt.getTask(id);
|
|
|
+ console.log('点击了任务:', task);
|
|
|
+
|
|
|
+ // 显示任务详情
|
|
|
+ this.showTaskDetail(task);
|
|
|
+
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 显示任务详情
|
|
|
+ showTaskDetail(task) {
|
|
|
+ this.$emit('taskDetail',task)
|
|
|
+ },
|
|
|
+ },
|
|
|
};
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
+/* 容器样式 */
|
|
|
+.gantt-wrapper {
|
|
|
+ width: 100%;
|
|
|
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
|
+}
|
|
|
+
|
|
|
+.gantt-container {
|
|
|
+ height: 200px;
|
|
|
+ width: 100%;
|
|
|
+ border: 1px solid #e0e0e0; /* 淡灰色边框 */
|
|
|
+}
|
|
|
+
|
|
|
+.click-info-box {
|
|
|
+ margin-top: 15px;
|
|
|
+ padding: 10px;
|
|
|
+ background: #f0f7ff;
|
|
|
+ color: #1890ff;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.date-range {
|
|
|
+ color: #666;
|
|
|
+ margin-left: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+/* =========================================
|
|
|
+ 核心:深度定制 dhtmlxGantt 样式以匹配图片
|
|
|
+ 注意:这里使用了 /deep/ 或 ::v-deep (Vue 2/3 兼容写法)
|
|
|
+ ========================================= */
|
|
|
+
|
|
|
+/* 1. 整体背景与字体 */
|
|
|
+::v-deep .gantt_container {
|
|
|
+ background-color: #fff;
|
|
|
+ color: #333;
|
|
|
+ font-size: 13px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 2. 顶部时间轴 (Header) */
|
|
|
+::v-deep .gantt_scale_cell {
|
|
|
+ background-color: #fafafa; /* 极淡的灰色背景 */
|
|
|
+ border-right: 1px solid #eee; /* 极细的分隔线 */
|
|
|
+ border-bottom: 1px solid #eee;
|
|
|
+ color: #666;
|
|
|
+ font-weight: normal;
|
|
|
+}
|
|
|
+
|
|
|
+/* 3. 网格线 (Grid Lines) - 让它变淡或消失 */
|
|
|
+::v-deep .gantt_task_cell {
|
|
|
+ border-right: 1px solid #f5f5f5; /* 非常淡的竖线 */
|
|
|
+}
|
|
|
+::v-deep .gantt_task_row:nth-child(even) {
|
|
|
+ background-color: #fff; /* 去除斑马纹,保持纯白 */
|
|
|
+}
|
|
|
+::v-deep .gantt_task_row:nth-child(odd) {
|
|
|
+ background-color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+/* 4. 任务条形图 (The Blue Bars) - 关键样式 */
|
|
|
+::v-deep .gantt_task_line {
|
|
|
+ background-color: #1890ff; /* 阿里蓝/标准蓝 */
|
|
|
+ border-radius: 4px; /* 圆角 */
|
|
|
+ border: none; /* 去除默认边框 */
|
|
|
+ box-shadow: 0 2px 4px rgba(24, 144, 255, 0.2); /* 轻微阴影增加立体感 */
|
|
|
+ opacity: 0.9;
|
|
|
+}
|
|
|
+
|
|
|
+/* 鼠标悬停在条形图上时的效果 */
|
|
|
+::v-deep .gantt_task_line:hover {
|
|
|
+ opacity: 1;
|
|
|
+ box-shadow: 0 4px 8px rgba(24, 144, 255, 0.4);
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+/* 进度条内部白色部分 (如果 progress < 1) */
|
|
|
+::v-deep .gantt_task_progress {
|
|
|
+ background-color: rgba(255, 255, 255, 0.3); /* 半透明白色表示未完成部分 */
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+::v-deep .gantt_task_progress_wrapper {
|
|
|
+ background-color: transparent;
|
|
|
+ border-radius: 4px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 5. 左侧表格区域优化 */
|
|
|
+::v-deep .gantt_grid_head_cell {
|
|
|
+ background-color: #fafafa;
|
|
|
+ border-right: 1px solid #eee;
|
|
|
+ border-bottom: 1px solid #eee;
|
|
|
+ color: #666;
|
|
|
+ font-weight: normal;
|
|
|
+}
|
|
|
+::v-deep .gantt_grid_cell {
|
|
|
+ border-right: 1px solid #f5f5f5;
|
|
|
+ border-bottom: 1px solid #f5f5f5;
|
|
|
+}
|
|
|
+
|
|
|
+/* 6. 自定义 Tooltip 样式 (悬浮提示框) */
|
|
|
+::v-deep .gantt_tooltip {
|
|
|
+ background-color: rgba(0, 0, 0, 0.75); /* 深色半透明背景 */
|
|
|
+ color: #fff;
|
|
|
+ border: none;
|
|
|
+ border-radius: 4px;
|
|
|
+ padding: 8px 12px;
|
|
|
+ font-size: 12px;
|
|
|
+ box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
|
+ white-space: nowrap; /* 防止换行 */
|
|
|
+ z-index: 9999;
|
|
|
+}
|
|
|
|
|
|
+/* 隐藏默认的箭头三角形,如果想要更现代的风格可以去掉箭头 */
|
|
|
+::v-deep .gantt_tooltip_arrow {
|
|
|
+ display: none;
|
|
|
+}
|
|
|
</style>
|