fix(종단): 도구 고름 화면 흠 셋 — 고른 즉시 붉은 강조 · 스크롤 따라감 · 측점선 누름 전파 막음 (PLAN 456-3 · 요구 421 · 423~425)
- design_profile: 도구 고름 뒤 종단도 한 번 다시 그림 - RunHighlight · Render: 붉은 선을 계획선 세로 창 겹 안에 그림 - Render: 도구가 먹은 누름은 전파 막음 — 측점 고름 안 돎 - Panel_Tools: 도구 바꿀 때 겹 안 붉은 선도 같이 뗌 - test_271: 지킴 시험 더함 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -267,7 +267,8 @@ export function createDesignProfile(ctx: DesignProfileContext) {
|
||||
restore: () => void (store.resync() ? rebuild() : draw()),
|
||||
restoreSaved: () => store.restoreSaved(),
|
||||
canRestoreSaved: () => store.canRestoreSaved(),
|
||||
refresh: () => renderBalance(),
|
||||
// 고름 직후 종단도도 한 번 — 붉은 강조가 다음 그림을 기다리지 않게(423).
|
||||
refresh: () => (renderBalance(), drawSoon()),
|
||||
});
|
||||
|
||||
/** 편집을 적용한다. 법정 위반 정책이 block이면 새 위반이 생기는 편집을 막는다. false = 막힘. */
|
||||
|
||||
@@ -131,7 +131,10 @@ export function createPanelTools(ctx: PanelToolsContext): PanelTools {
|
||||
});
|
||||
const mountViews = (mode: string): void => {
|
||||
// [쉬프트] 붉은 강조는 그래프를 다시 그릴 때만 지워짐 — 다른 도구로 넘어가면 바로 뗌(271-1)
|
||||
if (mode !== "shift") lastGeom?.chart.querySelector(".b05-profile-runmark")?.remove();
|
||||
if (mode !== "shift")
|
||||
lastGeom?.chart
|
||||
.querySelectorAll(".b05-profile-runmark, .b05-profile-runmark__line")
|
||||
.forEach((node) => node.remove());
|
||||
freeView.mount(lastGeom, mode === "free");
|
||||
bandView.mount(lastGeom, mode === "straighten");
|
||||
};
|
||||
|
||||
@@ -322,8 +322,9 @@ export function renderProfile(ctx: ProfileRenderContext): void {
|
||||
if (ctx.toolActive()) {
|
||||
const marker = (event.target as HTMLElement).closest(".b06-chart__station");
|
||||
const raw = marker?.getAttribute("data-chainage");
|
||||
let picked: boolean;
|
||||
if (raw !== null && raw !== undefined) {
|
||||
if (ctx.handleToolPick(Number(raw))) return;
|
||||
picked = ctx.handleToolPick(Number(raw));
|
||||
} else {
|
||||
const rect = chartWrap.getBoundingClientRect();
|
||||
const chainage = chainageInverter(
|
||||
@@ -331,8 +332,10 @@ export function renderProfile(ctx: ProfileRenderContext): void {
|
||||
width,
|
||||
layout.originOffset,
|
||||
)(event.clientX - rect.left + chartWrap.scrollLeft);
|
||||
if (ctx.handleToolPick(Number.isFinite(chainage) ? chainage : null)) return;
|
||||
picked = ctx.handleToolPick(Number.isFinite(chainage) ? chainage : null);
|
||||
}
|
||||
// 도구가 먹은 누름은 측점선 자기 클릭(측점 고름)으로 새지 않게 막음(425).
|
||||
if (picked) event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
// 원지반선 근처 · 추가 측점 선 누름 = 그 자리 임시 횡단 작은 창(368-3)
|
||||
@@ -478,6 +481,8 @@ export function renderProfile(ctx: ProfileRenderContext): void {
|
||||
axis: yAxis,
|
||||
widthPx: width,
|
||||
heightPx: chartHeight,
|
||||
// 붉은 선은 계획선 겹 안에 — 스크롤 때 세로 맞춤 변환을 계획선과 같이 받음(424).
|
||||
windowLayer: chartWrap.querySelector(".b06-chart__profile")?.parentElement,
|
||||
});
|
||||
if (highlight) chartWrap.append(highlight);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@ export interface RunHighlightOptions {
|
||||
axis: { ticks: Array<{ y: number; label: string }> } | null;
|
||||
widthPx: number;
|
||||
heightPx: number;
|
||||
/**
|
||||
* 계획선이 든 세로 창 겹 — 붉은 선을 여기 넣으면 스크롤 때 계획선과 같은 변환을 받는다.
|
||||
* 없으면 덮개 안에 그대로 둔다(세로 맞춤을 못 따라감).
|
||||
*/
|
||||
windowLayer?: Element | null;
|
||||
}
|
||||
|
||||
/** 눈금 라벨(`880m`)에서 표고를 읽는다. 숫자가 아니면 null. */
|
||||
@@ -84,6 +89,7 @@ export function createRunHighlight(options: RunHighlightOptions): SVGElement | n
|
||||
svg.setAttribute("viewBox", `0 0 ${widthPx} ${heightPx}`);
|
||||
|
||||
const samples = alignment.samples;
|
||||
let drawn = 0;
|
||||
for (const run of runs) {
|
||||
const [fromM, toM] = runSpanWithCurves(alignment, run);
|
||||
// 계획선 샘플에는 변화점·BVC·EVC가 모두 들어 있어 라운드 곡률까지 그대로 따라온다.
|
||||
@@ -95,7 +101,8 @@ export function createRunHighlight(options: RunHighlightOptions): SVGElement | n
|
||||
const line = document.createElementNS(SVG_NS, "polyline");
|
||||
line.setAttribute("class", "b05-profile-runmark__line");
|
||||
line.setAttribute("points", points.join(" "));
|
||||
svg.append(line);
|
||||
(options.windowLayer ?? svg).append(line);
|
||||
drawn += 1;
|
||||
// 양 끝 표시 — 어디까지가 이 구간인지(라운드 포함) 한눈에 보이게 세로 표식을 둔다.
|
||||
for (const edge of [fromM, toM]) {
|
||||
const tick = document.createElementNS(SVG_NS, "line");
|
||||
@@ -107,5 +114,5 @@ export function createRunHighlight(options: RunHighlightOptions): SVGElement | n
|
||||
svg.append(tick);
|
||||
}
|
||||
}
|
||||
return svg.childElementCount ? svg : null;
|
||||
return drawn ? svg : null;
|
||||
}
|
||||
|
||||
@@ -199,3 +199,18 @@ def test_줄_수():
|
||||
"A00_Common/design/design_profile_range_band.ts",
|
||||
):
|
||||
assert len(_read(relative).splitlines()) <= 700
|
||||
|
||||
|
||||
def test_456_3_고름_즉시_강조_계획선_겹_전파_막음():
|
||||
# 도구 고름 뒤 종단도 한 번 다시 그림(423)
|
||||
profile = _read("A00_Common/design/design_profile.ts")
|
||||
assert "refresh: () => (renderBalance(), drawSoon())" in profile
|
||||
# 붉은 선 = 계획선 겹 안(424) · 도구가 먹은 누름은 측점선 자기 클릭으로 안 샘(425)
|
||||
render = _read("B05_Profile/B05_Profile_UI_Profile_Render.ts")
|
||||
assert 'windowLayer: chartWrap.querySelector(".b06-chart__profile")?.parentElement' in render
|
||||
assert "if (picked) event.stopPropagation();" in render
|
||||
mark = _read("B05_Profile/B05_Profile_UI_Profile_RunHighlight.ts")
|
||||
assert "(options.windowLayer ?? svg).append(line)" in mark
|
||||
# 도구를 바꾸면 겹 안 붉은 선도 같이 뗌
|
||||
panel = _read("B05_Profile/B05_Profile_UI_Profile_Panel_Tools.ts")
|
||||
assert ".b05-profile-runmark, .b05-profile-runmark__line" in panel
|
||||
|
||||
Reference in New Issue
Block a user