diff --git a/web/app.js b/web/app.js index d7d49aa..b8174e3 100644 --- a/web/app.js +++ b/web/app.js @@ -35,6 +35,8 @@ function drawProfile(f){ export function selectFacility(f){ if(!f)return;app.selected=f;app.renderer.set({selected:f.pickId});$('#view-name').textContent=f.id; let html=`${labels[f.type]}
${f.xy===null?'좌표가 없어 위치를 배치하지 않았습니다.':f.id==='UHR1-01411'?'양 끝의 평면 좌표가 같아 관로 형상을 생략했습니다.':'연결 노드 좌표 또는 단면이 없어 형상을 배치하지 않았습니다.'}
`; @@ -85,7 +87,15 @@ function updateScales(){ const height=Number($('#height-scale').value),size=Number($('#size-scale').value);app.renderer.set({height,size,section:$('#section-mode').checked}); $('#height-output').value=`×${height}`;$('#size-output').value=`×${size}`;$('#height-badge').textContent=`높이 ×${height}`;$('#size-badge').textContent=`단면·맨홀 폭 ×${size}`;$('#section-badge').hidden=!$('#section-mode').checked; } +function syncAuditHighlight(){ + const enabled=$('#audit-highlight').checked,reduced=matchMedia('(prefers-reduced-motion: reduce)').matches; + const steady=$('#audit-steady').checked||reduced; + $('#audit-steady').disabled=!enabled||reduced; + $('#audit-highlight-note').textContent=reduced?'동작 줄이기 설정에 따라 고정 강조합니다. 오류 확정이 아닌 점검 필요 표시입니다.':steady?'고정 빨간색으로 강조합니다. 오류 확정이 아닌 점검 필요 표시입니다.':'빨간색 1초 · 원래 색 1초 반복. 오류 확정이 아닌 점검 필요 표시입니다.'; + app.renderer.setAuditHighlight(enabled,steady); +} function reset(){ + $('#audit-highlight').checked=false;$('#audit-steady').checked=false;syncAuditHighlight(); $('#height-scale').value=3;$('#size-scale').value=3;$('#section-mode').checked=false;$$('[data-layer]').forEach(b=>{b.checked=true;app.renderer.setLayer(b.dataset.layer,true);});updateScales();app.renderer.set({selected:0});app.selected=null;$('#search').value='';updateSearch();clearDetails();$('#view-name').textContent='전체 관망';app.renderer.setView('iso');app.renderer.fit();toast('표시·배율·시점을 초기화했습니다.'); } function frame(renderer,error){ @@ -109,6 +119,12 @@ async function main(){ app.network=await response.json();const n=app.network,s=n.summary; app.facilities=[...n.nodes,...n.links].map((f,i)=>({...f,pickId:i+1})); app.renderer=new NetworkRenderer($('#scene'),n,app.facilities,selectFacility,frame); + const unplaced=app.facilities.filter(f=>!isPlaced(f)); + $('#audit-highlight-count').textContent=`표시 가능한 점검 관로 ${app.renderer.auditPickIds.size}개`; + $('#audit-unplaced').textContent=`위치 표시 불가 ${unplaced.length}개 · 사유 보기 ↗`; + $('#audit-unplaced').onclick=()=>openAudit('placement'); + $('#audit-highlight').onchange=syncAuditHighlight;$('#audit-steady').onchange=syncAuditHighlight; + matchMedia('(prefers-reduced-motion: reduce)').addEventListener('change',syncAuditHighlight);syncAuditHighlight(); $('#node-count').textContent=s.counts.junction;$('#pipe-count').textContent=s.counts.conduit; for(const [layer,count] of Object.entries({junction:s.counts.junction,conduit:s.counts.conduit,outfall:s.counts.outfall,other:s.counts.storage+s.counts.pump+s.counts.weir}))$(`#layer-${layer}-count`).textContent=count; $('#circle-count').textContent=s.shapes.CIRCULAR;$('#rect-count').textContent=s.shapes.RECT_CLOSED;$('#source-name').textContent=n.meta.sourceName;