Edge AI工程师晨间作战地图:每日硬核技术动态与实操指南
2026/6/18 15:46:03
.html文件粘贴保存<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>项目管理甘特图 - Highcharts Gantt 可预览修复版</title> <!-- 稳定CDN,严格加载顺序:基础内核→甘特模块 --> <script src="https://cdn.jsdelivr.net/npm/highcharts@11.4.3/highcharts.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/highcharts@11.4.3/modules/gantt.min.js"></script> <style> * {margin: 0; padding: 0; box-sizing: border-box;} body {background: #fff; padding: 10px;} #container { width: 100%; height: 90vh; border: 1px solid #eee; } </style> </head> <body> <div id="container"></div> <script> const day = 24 * 36e5, today = Math.floor(Date.now() / day) * day; const options = { chart: { plotBorderColor: 'rgba(128,128,128,0.1)', plotBorderWidth: 1, plotBorderRadius: 5 }, plotOptions: { series: { borderRadius: '50%', connectors: { lineWidth: 1, lineColor: '#666', radius: 10, endMarker: { verticalAlign: 'bottom', align: 'center', yOffset: 5 }, startMarker: { symbol: 'arrow-half', lineWidth: 1, lineColor: '#666', xOffset: -5 } }, groupPadding: 0, dataLabels: [{ enabled: true, align: 'left', format: '{point.name}', padding: 10, style: { fontWeight: 'normal', textOutline: 'none' } }, { enabled: true, align: 'right', format: '{#if point.completed}{(multiply point.completed.amount 100):.0f}% {/if}', padding: 10, style: { fontWeight: 'normal', textOutline: 'none', opacity: 0.6 } }] } }, series: [{ name: '办公场地项目', data: [{ name: '新办公室筹备', id: 'new_offices', owner: 'Peter', pointWidth: 3, color: '#666', dataLabels: { align: 'right', style: { color: '#666' }, x: 72 } }, { name: '办公楼装修施工', id: 'prepare_building', parent: 'new_offices', start: today - (8 * day), end: today + (6 * day), completed: { amount: 0.5 }, owner: 'Linda' }, { name: '建筑竣工验收', id: 'inspect_building', dependency: 'prepare_building', parent: 'new_offices', start: today + 6 * day, end: today + 8 * day, owner: 'Ivy' }, { name: '验收通过里程碑', id: 'passed_inspection', dependency: 'inspect_building', parent: 'new_offices', start: today + 9.5 * day, milestone: true, owner: 'Peter' }, { name: '搬迁工作', id: 'relocate', owner: 'Josh', pointWidth: 3, color: '#666', dataLabels: { align: 'right', style: { color: '#666' }, x: 57 } }, { name: '员工搬迁', id: 'relocate_staff', parent: 'relocate', start: today + 10 * day, end: today + 11 * day, owner: 'Mark' }, { name: '实验室设备迁移', dependency: 'relocate_staff', parent: 'relocate', start: today + 11 * day, end: today + 13 * day, owner: 'Anne' }, { name: '食堂搬迁', dependency: 'relocate_staff', parent: 'relocate', start: today + 11 * day, end: today + 14 * day }] }, { name: '产品项目', data: [{ name: '新品上线计划', id: 'new_product', owner: 'Peter', pointWidth: 3, color: '#666', dataLabels: { align: 'right', style: { color: '#666' }, format: '上线', x: 50 } }, { name: '产品研发', id: 'development', parent: 'new_product', start: today - day, end: today + (11 * day), completed: { amount: 0.6 }, owner: 'Susan' }, { name: 'Beta测试里程碑', id: 'beta', dependency: 'development', parent: 'new_product', start: today + 12.5 * day, milestone: true, owner: 'Peter' }, { name: '最终版本完善开发', id: 'finalize', dependency: 'beta', parent: 'new_product', start: today + 13 * day, end: today + 17 * day }, { name: '正式上线里程碑', dependency: 'finalize', parent: 'new_product', start: today + 17.5 * day, milestone: true, owner: 'Peter' }] }], tooltip: { pointFormat: '<span style="font-weight: bold">{point.name}</span><br>' + '{point.start:%m月%d日}' + '{#unless point.milestone} → {point.end:%m月%d日}{/unless}' + '<br>' + '{#if point.completed}完成进度: {multiply point.completed.amount 100}%<br>{/if}' + '负责人: {#if point.owner}{point.owner}{else}未分配{/if}' }, title: { text: '项目管理甘特图', align: 'left' }, xAxis: [{ currentDateIndicator: { color: '#ef4444', dashStyle: 'ShortDot', width: 2, label: { format: '' } }, dateTimeLabelFormats: { day: '%d<br><span style="opacity: 0.5; font-size: 0.7em">%a</span>' }, grid: { borderWidth: 0, cellHeight: 46 }, gridLineWidth: 1, min: today - 3 * day, max: today + 19 * day, custom: { weekendPlotBands: { color: '#f2f2f2' } } }, { dateTimeLabelFormats: { month: '%m月%Y年' }, labels: { align: 'left', x: 5, style: { fontSize: '0.7em', fontWeight: 'bold' } }, grid: { borderWidth: 0, cellHeight: 24 }, tickInterval: 30 * 24 * 36e5 }], yAxis: { grid: { borderWidth: 0, enabled: true, columns: [{ title: { text: '任务名称', textAlign: 'left', x: 18 }, labels: { format: '{value}', indentation: 0 } }, { title: { text: '工期', textAlign: 'left', x: 8 }, labels: { format: '{#if point.x2}{(divide (subtract point.x2 point.x) 86400000)} 天{else} - {/if}', style: { opacity: 0.7 } } }] }, gridLineWidth: 0, staticScale: 30 } }; // 周末底色渲染插件 Highcharts.addEvent(Highcharts.Axis, 'foundExtremes', e => { const weekendColor = e.target.options.custom?.weekendPlotBands?.color; if (!weekendColor) return; const axis = e.target, chart = axis.chart, day = 24 * 36e5; const isWeekend = t => /[06]/.test(chart.time.dateFormat('%w', t)); const plotBands = []; let inWeekend = false; for (let x = Math.floor(axis.min / day) * day; x <= Math.ceil(axis.max / day) * day; x += day) { const last = plotBands.at(-1); if (isWeekend(x) && !inWeekend) { plotBands.push({ from: x, color: weekendColor }); inWeekend = true; } if (!isWeekend(x) && inWeekend && last) { last.to = x; inWeekend = false; } } axis.options.plotBands = plotBands; }); // 延迟初始化,保证模块全部加载完成 window.addEventListener('load', function(){ Highcharts.ganttChart('container', options); }) </script> </body> </html>Highcharts Gantt 甘特图(项目排期图),支持树形分层任务、任务依赖箭头、里程碑标记、进度百分比、多列侧边栏、双层时间轴。
dependency绑定任务 ID,自动生成带箭头连接线,直观展示任务先后顺序,前序任务完成后方可执行后续工作。milestone: true生成菱形标记,仅占单个时间点,用于验收、上线、测试等关键节点。completed.amount配置完成比例,任务条内部填充进度,右侧标签直接展示百分比数值。在这套全功能项目甘特图案例中,Highcharts Gantt 提供开箱即用的专业排期可视化能力,解决传统表格、简易图表无法直观展示任务时序、依赖关系、分层结构的痛点。