@ganttloom/gantt-core 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -0
- package/dist/index.cjs +52 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +52 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -140,7 +140,6 @@ function computeCriticalPath(tasks, dependencies) {
|
|
|
140
140
|
}
|
|
141
141
|
for (const e of edges) {
|
|
142
142
|
outgoing.get(e.fromId)?.push(e);
|
|
143
|
-
incoming.get(e.fromId) === void 0 ? void 0 : void 0;
|
|
144
143
|
incoming.get(e.toId)?.push(e);
|
|
145
144
|
}
|
|
146
145
|
const inDegree = /* @__PURE__ */ new Map();
|
|
@@ -225,11 +224,9 @@ function computeCriticalPath(tasks, dependencies) {
|
|
|
225
224
|
criticalLinks.add(linkKey(e.fromId, e.toId));
|
|
226
225
|
}
|
|
227
226
|
}
|
|
228
|
-
const taskMap = new Map(tasks.map((t) => [t.id, t]));
|
|
229
227
|
for (const task of tasks) {
|
|
230
228
|
if (!task.isGroup) continue;
|
|
231
229
|
let hasCriticalDescendant = false;
|
|
232
|
-
let cur = task;
|
|
233
230
|
const descendantStack = [task.id];
|
|
234
231
|
const visited = /* @__PURE__ */ new Set();
|
|
235
232
|
while (descendantStack.length > 0) {
|
|
@@ -244,8 +241,6 @@ function computeCriticalPath(tasks, dependencies) {
|
|
|
244
241
|
}
|
|
245
242
|
}
|
|
246
243
|
if (hasCriticalDescendant) criticalTasks.add(task.id);
|
|
247
|
-
void cur;
|
|
248
|
-
void taskMap;
|
|
249
244
|
}
|
|
250
245
|
return { criticalTasks, criticalLinks };
|
|
251
246
|
}
|
|
@@ -640,6 +635,9 @@ function flatten(roots) {
|
|
|
640
635
|
}
|
|
641
636
|
return out;
|
|
642
637
|
}
|
|
638
|
+
function estimateTextWidth(text, fontSize) {
|
|
639
|
+
return text.length * fontSize * 0.62;
|
|
640
|
+
}
|
|
643
641
|
function anchorPoint(bar, side) {
|
|
644
642
|
const y = bar.y + bar.height / 2;
|
|
645
643
|
return side === "start" ? { x: bar.x, y } : { x: bar.x + bar.width, y };
|
|
@@ -765,8 +763,9 @@ function computeLayout(input) {
|
|
|
765
763
|
const end = row.node.computedEnd;
|
|
766
764
|
if (!start || !end) return;
|
|
767
765
|
const x = dateToX(start, paddedStart, viewMode, columnWidth);
|
|
768
|
-
const
|
|
769
|
-
if (!Number.isFinite(x) || !Number.isFinite(
|
|
766
|
+
const rawWidth = Math.max(0, dateToX(end, paddedStart, viewMode, columnWidth) - x);
|
|
767
|
+
if (!Number.isFinite(x) || !Number.isFinite(rawWidth)) return;
|
|
768
|
+
const width2 = rawWidth > 0 ? Math.max(rawWidth, 3) : rawWidth;
|
|
770
769
|
const progress = task.progress !== void 0 ? Math.min(100, Math.max(0, task.progress)) : autoRollupProgress ? row.node.computedProgress : 0;
|
|
771
770
|
const barHeight = theme.barHeight;
|
|
772
771
|
const barY = y + (theme.rowHeight - barHeight) / 2;
|
|
@@ -874,7 +873,13 @@ function computeLayout(input) {
|
|
|
874
873
|
})).filter((m) => Number.isFinite(m.x));
|
|
875
874
|
let width = 0;
|
|
876
875
|
for (const tick of ticks) width = Math.max(width, tick.x);
|
|
877
|
-
for (const bar of bars)
|
|
876
|
+
for (const bar of bars) {
|
|
877
|
+
width = Math.max(width, bar.x + bar.width);
|
|
878
|
+
if (bar.label) {
|
|
879
|
+
const labelOffset = bar.isMilestone ? theme.barHeight * 0.4 + 8 : bar.width + 6;
|
|
880
|
+
width = Math.max(width, bar.x + labelOffset + estimateTextWidth(bar.label, theme.fontSize));
|
|
881
|
+
}
|
|
882
|
+
}
|
|
878
883
|
width += columnWidth;
|
|
879
884
|
const height = rows.length * theme.rowHeight;
|
|
880
885
|
return {
|
|
@@ -1373,7 +1378,9 @@ var GanttRenderer = class {
|
|
|
1373
1378
|
}
|
|
1374
1379
|
}
|
|
1375
1380
|
renderMarkers(group, model) {
|
|
1376
|
-
|
|
1381
|
+
const sorted = [...model.markers].sort((a, b) => a.x - b.x);
|
|
1382
|
+
let defs = null;
|
|
1383
|
+
sorted.forEach((marker, i) => {
|
|
1377
1384
|
const line = svgEl("line");
|
|
1378
1385
|
line.setAttribute("x1", String(marker.x));
|
|
1379
1386
|
line.setAttribute("x2", String(marker.x));
|
|
@@ -1385,16 +1392,33 @@ var GanttRenderer = class {
|
|
|
1385
1392
|
line.dataset.ganttMarker = marker.label;
|
|
1386
1393
|
group.appendChild(line);
|
|
1387
1394
|
if (marker.label) {
|
|
1395
|
+
const nextX = sorted[i + 1]?.x ?? model.width;
|
|
1396
|
+
const cellWidth = Math.max(0, nextX - marker.x);
|
|
1397
|
+
if (!defs) {
|
|
1398
|
+
defs = svgEl("defs");
|
|
1399
|
+
group.insertBefore(defs, group.firstChild);
|
|
1400
|
+
}
|
|
1401
|
+
const clipId = `${this.markerDefsId}-marker-${i}`;
|
|
1402
|
+
const clipPath = svgEl("clipPath");
|
|
1403
|
+
clipPath.setAttribute("id", clipId);
|
|
1404
|
+
const clipRect = svgEl("rect");
|
|
1405
|
+
clipRect.setAttribute("x", String(marker.x));
|
|
1406
|
+
clipRect.setAttribute("y", "0");
|
|
1407
|
+
clipRect.setAttribute("width", String(cellWidth));
|
|
1408
|
+
clipRect.setAttribute("height", String(model.height));
|
|
1409
|
+
clipPath.appendChild(clipRect);
|
|
1410
|
+
defs.appendChild(clipPath);
|
|
1388
1411
|
const label = svgEl("text");
|
|
1389
1412
|
label.setAttribute("x", String(marker.x + 4));
|
|
1390
1413
|
label.setAttribute("y", "12");
|
|
1414
|
+
label.setAttribute("clip-path", `url(#${clipId})`);
|
|
1391
1415
|
label.setAttribute("fill", marker.color);
|
|
1392
1416
|
label.setAttribute("font-size", String(model.theme.fontSize));
|
|
1393
1417
|
label.setAttribute("font-family", model.theme.fontFamily);
|
|
1394
1418
|
label.textContent = marker.label;
|
|
1395
1419
|
group.appendChild(label);
|
|
1396
1420
|
}
|
|
1397
|
-
}
|
|
1421
|
+
});
|
|
1398
1422
|
}
|
|
1399
1423
|
renderHeader(model) {
|
|
1400
1424
|
let headerGroup = this.svg.querySelector(".gantt-header-group");
|
|
@@ -1408,16 +1432,32 @@ var GanttRenderer = class {
|
|
|
1408
1432
|
bg.setAttribute("height", String(model.headerHeight));
|
|
1409
1433
|
bg.style.fill = themedFill("backgroundColor", model.theme.backgroundColor);
|
|
1410
1434
|
headerGroup.appendChild(bg);
|
|
1411
|
-
|
|
1435
|
+
const defs = svgEl("defs");
|
|
1436
|
+
const ticks = model.ticks;
|
|
1437
|
+
for (let i = 0; i < ticks.length; i++) {
|
|
1438
|
+
const tick = ticks[i];
|
|
1439
|
+
const cellWidth = (ticks[i + 1]?.x ?? model.width) - tick.x;
|
|
1440
|
+
const clipId = `${this.markerDefsId}-tick-${i}`;
|
|
1441
|
+
const clipPath = svgEl("clipPath");
|
|
1442
|
+
clipPath.setAttribute("id", clipId);
|
|
1443
|
+
const clipRect = svgEl("rect");
|
|
1444
|
+
clipRect.setAttribute("x", String(tick.x));
|
|
1445
|
+
clipRect.setAttribute("y", "0");
|
|
1446
|
+
clipRect.setAttribute("width", String(Math.max(0, cellWidth)));
|
|
1447
|
+
clipRect.setAttribute("height", String(model.headerHeight));
|
|
1448
|
+
clipPath.appendChild(clipRect);
|
|
1449
|
+
defs.appendChild(clipPath);
|
|
1412
1450
|
const text = svgEl("text");
|
|
1413
1451
|
text.setAttribute("x", String(tick.x + 4));
|
|
1414
1452
|
text.setAttribute("y", String(model.headerHeight - 8));
|
|
1453
|
+
text.setAttribute("clip-path", `url(#${clipId})`);
|
|
1415
1454
|
text.style.fill = themedFill("textColor", model.theme.textColor);
|
|
1416
1455
|
text.setAttribute("font-size", String(model.theme.fontSize));
|
|
1417
1456
|
text.setAttribute("font-family", model.theme.fontFamily);
|
|
1418
1457
|
text.textContent = tick.label;
|
|
1419
1458
|
headerGroup.appendChild(text);
|
|
1420
1459
|
}
|
|
1460
|
+
headerGroup.insertBefore(defs, headerGroup.firstChild);
|
|
1421
1461
|
this.svg.appendChild(headerGroup);
|
|
1422
1462
|
}
|
|
1423
1463
|
/**
|
|
@@ -2501,7 +2541,7 @@ var _GanttChart = class _GanttChart {
|
|
|
2501
2541
|
const newStart = edge === "left" ? new Date(task.start.getTime() + dxMs) : task.start;
|
|
2502
2542
|
const newEnd = edge === "right" ? new Date(task.end.getTime() + dxMs) : task.end;
|
|
2503
2543
|
if (newEnd.getTime() <= newStart.getTime()) return;
|
|
2504
|
-
|
|
2544
|
+
const newSegments = task.segments?.map((s) => ({ ...s }));
|
|
2505
2545
|
if (newSegments && newSegments.length > 0) {
|
|
2506
2546
|
if (edge === "left") newSegments[0] = { ...newSegments[0], start: newStart };
|
|
2507
2547
|
else newSegments[newSegments.length - 1] = { ...newSegments[newSegments.length - 1], end: newEnd };
|