pcp-tgu интерфейс

This commit is contained in:
Дмитрий Соловьев
2026-05-29 15:18:21 +03:00
parent 4556592e63
commit 913b3d7c9b
@@ -6,6 +6,7 @@
const TIMELINE_ROW_HEIGHT = 54;
const TIMELINE_AXIS_HEIGHT = 52;
const TIMELINE_MIN_WIDTH = 760;
const TIMELINE_LANE_STEP = 12;
const STATUS_COLORS = {
ACCEPTED: '#198754',
@@ -260,16 +261,17 @@
const label = spacecraftLabel(group.spacecraftId);
const subLabel = label === String(group.spacecraftId) ? '' : String(group.spacecraftId);
const sortedPlans = group.items.sort((left, right) => left.start.getTime() - right.start.getTime());
const planLines = sortedPlans.map((item) => {
const planLines = sortedPlans.map((item, planIndex) => {
const x1 = Math.max(TIMELINE_LEFT_WIDTH, xForTime(item.start));
const x2 = Math.min(TIMELINE_LEFT_WIDTH + chartWidth, xForTime(item.end));
const widthAdjustedX2 = x2 - x1 < 4 ? Math.min(TIMELINE_LEFT_WIDTH + chartWidth, x1 + 4) : x2;
const status = String(item.plan.status || '');
const selected = String(item.plan.planId) === String(state.selectedPlanId);
const dashArray = status === 'START_AMBIGUOUS' ? '7 5' : '';
const planY = rowY + timelineLaneOffset(planIndex);
return `
<line class="tgu-timeline-plan${selected ? ' tgu-timeline-plan-selected' : ''}"
x1="${x1.toFixed(2)}" y1="${rowY}" x2="${widthAdjustedX2.toFixed(2)}" y2="${rowY}"
x1="${x1.toFixed(2)}" y1="${planY}" x2="${widthAdjustedX2.toFixed(2)}" y2="${planY}"
stroke="${escapeHtml(statusColor(status))}" stroke-width="${selected ? 15 : 11}"
${dashArray ? `stroke-dasharray="${dashArray}"` : ''}
data-plan-id="${escapeHtml(item.plan.planId)}">
@@ -280,11 +282,14 @@
const next = sortedPlans[planIndex + 1];
const startX = Math.min(TIMELINE_LEFT_WIDTH + chartWidth - 8, Math.max(TIMELINE_LEFT_WIDTH + 8, xForTime(item.end) + 7));
const endX = Math.min(TIMELINE_LEFT_WIDTH + chartWidth - 4, Math.max(TIMELINE_LEFT_WIDTH + 12, xForTime(next.start) - 7));
const startY = rowY + timelineLaneOffset(planIndex);
const endY = rowY + timelineLaneOffset(planIndex + 1);
if (endX - startX >= 16) {
return `<line class="tgu-sequence-arrow" x1="${startX.toFixed(2)}" y1="${rowY - 13}" x2="${endX.toFixed(2)}" y2="${rowY - 13}" marker-end="url(#tgu-arrowhead)" />`;
return `<line class="tgu-sequence-arrow" x1="${startX.toFixed(2)}" y1="${startY.toFixed(2)}" x2="${endX.toFixed(2)}" y2="${endY.toFixed(2)}" marker-end="url(#tgu-arrowhead)" />`;
}
const markerX = Math.min(TIMELINE_LEFT_WIDTH + chartWidth - 20, Math.max(TIMELINE_LEFT_WIDTH + 20, xForTime(next.start)));
return `<path class="tgu-sequence-arrow" d="M ${markerX - 12} ${rowY - 16} C ${markerX - 2} ${rowY - 26}, ${markerX + 16} ${rowY - 22}, ${markerX + 12} ${rowY - 8}" marker-end="url(#tgu-arrowhead)" />`;
const controlY = Math.min(startY, endY) - TIMELINE_LANE_STEP;
return `<path class="tgu-sequence-arrow" d="M ${(markerX - 12).toFixed(2)} ${startY.toFixed(2)} C ${(markerX - 2).toFixed(2)} ${controlY.toFixed(2)}, ${(markerX + 16).toFixed(2)} ${controlY.toFixed(2)}, ${(markerX + 12).toFixed(2)} ${endY.toFixed(2)}" marker-end="url(#tgu-arrowhead)" />`;
}).join('');
return `
<g>
@@ -500,6 +505,10 @@
return ticks;
}
function timelineLaneOffset(index) {
return [0, -1, 0, 1][index % 4] * TIMELINE_LANE_STEP;
}
function groupBySpacecraft(items) {
const groups = new Map();
items.forEach((item) => {