<div class="container">
<div class="header">
<h1>Project Timeline</h1>
<p>Gantt Chart Overview</p>
</div>
<div class="gantt-container">
<div class="gantt-chart" id="ganttChart"></div>
</div>
<div class="legend">
<div class="legend-item">
<div class="legend-color"></div>
<span>Project Tasks</span>
</div>
</div>
</div>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
background: linear-gradient(135deg, #f5f5f5 0%, #e8e8e8 100%);
padding: 40px 20px;
min-height: 100vh;
}
.container {
max-width: 1400px;
margin: 0 auto;
background: white;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #CD5700 0%, #FF7B1C 100%);
color: white;
padding: 30px;
}
.header h1 {
font-size: 28px;
font-weight: 600;
margin-bottom: 8px;
}
.header p {
opacity: 0.95;
font-size: 14px;
}
.gantt-container {
padding: 30px;
overflow-x: auto;
}
.gantt-chart {
display: flex;
min-width: 900px;
}
.task-list {
width: 200px;
border-right: 2px solid #e0e0e0;
padding-right: 20px;
}
.task-item {
height: 50px;
display: flex;
align-items: center;
padding: 0 10px;
font-size: 14px;
font-weight: 500;
color: #333;
border-bottom: 1px solid #f0f0f0;
}
.timeline {
flex: 1;
padding-left: 20px;
}
.timeline-header {
display: flex;
height: 40px;
border-bottom: 2px solid #e0e0e0;
margin-bottom: 10px;
}
.month {
flex: 1;
text-align: center;
font-size: 12px;
font-weight: 600;
color: #666;
display: flex;
align-items: center;
justify-content: center;
border-left: 1px solid #f0f0f0;
}
.bars-container {
position: relative;
}
.bar-row {
height: 50px;
display: flex;
align-items: center;
position: relative;
border-bottom: 1px solid #f0f0f0;
}
.timeline-grid {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
}
.grid-line {
flex: 1;
border-left: 1px solid #f5f5f5;
}
.bar {
position: absolute;
height: 28px;
background: linear-gradient(135deg, #CD5700 0%, #FF8C3A 100%);
border-radius: 6px;
display: flex;
align-items: center;
padding: 0 12px;
color: white;
font-size: 12px;
font-weight: 500;
box-shadow: 0 2px 8px rgba(205, 87, 0, 0.3);
cursor: pointer;
transition: all 0.3s ease;
}
.bar:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(205, 87, 0, 0.4);
}
.bar-label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.legend {
display: flex;
gap: 20px;
padding: 20px 30px;
background: #fafafa;
border-top: 1px solid #e0e0e0;
font-size: 13px;
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
}
.legend-color {
width: 20px;
height: 12px;
border-radius: 3px;
background: linear-gradient(135deg, #CD5700 0%, #FF8C3A 100%);
}
@media (max-width: 768px) {
.gantt-container {
padding: 20px;
}
.task-list {
width: 150px;
}
}
const tasks = [
{ name: 'Planning', start: 0, duration: 2 },
{ name: 'Design', start: 1.5, duration: 3 },
{ name: 'Development', start: 4, duration: 4 },
{ name: 'Testing', start: 7, duration: 2 },
{ name: 'Deployment', start: 8.5, duration: 1.5 },
{ name: 'Documentation', start: 6, duration: 4 }
];
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
function createGanttChart() {
const chartContainer = document.getElementById('ganttChart');
// Create task list
const taskList = document.createElement('div');
taskList.className = 'task-list';
tasks.forEach(task => {
const taskItem = document.createElement('div');
taskItem.className = 'task-item';
taskItem.textContent = task.name;
taskList.appendChild(taskItem);
});
// Create timeline
const timeline = document.createElement('div');
timeline.className = 'timeline';
// Create timeline header
const timelineHeader = document.createElement('div');
timelineHeader.className = 'timeline-header';
for (let i = 0; i < 12; i++) {
const month = document.createElement('div');
month.className = 'month';
month.textContent = months[i];
timelineHeader.appendChild(month);
}
// Create bars container
const barsContainer = document.createElement('div');
barsContainer.className = 'bars-container';
// Create grid
const grid = document.createElement('div');
grid.className = 'timeline-grid';
for (let i = 0; i < 12; i++) {
const gridLine = document.createElement('div');
gridLine.className = 'grid-line';
grid.appendChild(gridLine);
}
barsContainer.appendChild(grid);
// Create bars
tasks.forEach((task, index) => {
const barRow = document.createElement('div');
barRow.className = 'bar-row';
const bar = document.createElement('div');
bar.className = 'bar';
const leftPercent = (task.start / 12) * 100;
const widthPercent = (task.duration / 12) * 100;
bar.style.left = leftPercent + '%';
bar.style.width = widthPercent + '%';
const label = document.createElement('span');
label.className = 'bar-label';
label.textContent = task.name;
bar.appendChild(label);
bar.addEventListener('click', () => {
alert(`${task.name}\nDuration: ${task.duration} months`);
});
barRow.appendChild(bar);
barsContainer.appendChild(barRow);
});
timeline.appendChild(timelineHeader);
timeline.appendChild(barsContainer);
chartContainer.appendChild(taskList);
chartContainer.appendChild(timeline);
}
createGanttChart();
No comments yet. Be the first!