refactor: 차트 기간 '연도별/월별' → '지정기간' + 유형 하위 드롭다운
기간 드롭다운의 연도별·월별 2옵션을 '지정기간' 1옵션으로 통합. 지정기간 선택 시 보조 드롭다운 노출: 유형(연도별/월별) → 연도 → 월(월별일 때만). - _render_chart_controls: custom 옵션 + data-nw-ymtype 유형 select 추가, 가시성 재구성 - JS: range='custom' 진입·data-nw-ymtype 핸들러(ymSet/curYear/curType 헬퍼) chart_ym 인코딩·서버 로직은 그대로(YYYY/YYYY-MM). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5141,8 +5141,8 @@ def _owner_full_title(owner: str) -> str:
|
||||
|
||||
def _render_chart_controls(selected_days: int, selected_unit: str, selected_mode: str = NET_WORTH_CHART_MODE, chart_ym: str = '', avail: dict | None = None) -> str:
|
||||
"""차트용 공통 컨트롤 — 기간 / 단위 / 모드(순자산·손익누적·기간손익) select.
|
||||
기간에 '연도별'(연도 선택→월별집계)·'월별'(연도+월 선택→일별) 추가. period(chart_ym) 활성 시 단위는 강제·비활성.
|
||||
의미없는 단위(이번주+월별 등)는 disabled."""
|
||||
기간에 '지정기간' 추가 → 유형(연도별/월별) + 연도 + 월(월별일 때) 보조 드롭다운.
|
||||
period(chart_ym) 활성 시 단위는 강제·비활성. 의미없는 단위(이번주+월별 등)는 disabled."""
|
||||
avail = avail or {'years': [], 'months': {}}
|
||||
period = (chart_ym or '').strip()
|
||||
is_year = len(period) == 4
|
||||
@@ -5158,8 +5158,13 @@ def _render_chart_controls(selected_days: int, selected_unit: str, selected_mode
|
||||
f'<option value="{d}"{" selected" if (not period_active and d == selected_days) else ""}>{html.escape(lbl)}</option>'
|
||||
for lbl, d in NET_WORTH_CHART_PRESETS
|
||||
)
|
||||
range_opts += f'<option value="year"{" selected" if is_year else ""}>연도별</option>'
|
||||
range_opts += f'<option value="month"{" selected" if is_month else ""}>월별</option>'
|
||||
range_opts += f'<option value="custom"{" selected" if period_active else ""}>지정기간</option>'
|
||||
|
||||
# 유형: 연도별(year) / 월별(month) — period_active 일 때만 노출.
|
||||
type_opts = (
|
||||
f'<option value="year"{" selected" if not is_month else ""}>연도별</option>'
|
||||
f'<option value="month"{" selected" if is_month else ""}>월별</option>'
|
||||
)
|
||||
|
||||
cur_year = period[:4] if period_active else (years[0] if years else '')
|
||||
cur_month = period[5:7] if is_month else ''
|
||||
@@ -5171,7 +5176,7 @@ def _render_chart_controls(selected_days: int, selected_unit: str, selected_mode
|
||||
f'<option value="{m}"{" selected" if m == cur_month else ""}>{int(m)}월</option>'
|
||||
for m in months_map.get(cur_year, [])
|
||||
)
|
||||
_yhide = '' if period_active else ' hidden'
|
||||
_customhide = '' if period_active else ' hidden'
|
||||
_mhide = '' if is_month else ' hidden'
|
||||
months_json = html.escape(json.dumps(months_map, ensure_ascii=False), quote=True)
|
||||
|
||||
@@ -5191,8 +5196,10 @@ def _render_chart_controls(selected_days: int, selected_unit: str, selected_mode
|
||||
f'<div class="chart-controls" data-ym-months="{months_json}">'
|
||||
f'<label class="cc-field"><span class="cc-label">기간</span>'
|
||||
f'<select class="nw-select" data-nw-range>{range_opts}</select></label>'
|
||||
# 연도별/월별 선택 시 노출되는 연·월 드롭다운 (데이터 있는 기간만).
|
||||
f'<label class="cc-field cc-ym" data-ym-year-field{_yhide}><span class="cc-label">연도</span>'
|
||||
# 지정기간 선택 시 노출: 유형(연도별/월별) → 연도 → 월(월별일 때만). 데이터 있는 기간만.
|
||||
f'<label class="cc-field cc-ym" data-ym-type-field{_customhide}><span class="cc-label">유형</span>'
|
||||
f'<select class="nw-select" data-nw-ymtype>{type_opts}</select></label>'
|
||||
f'<label class="cc-field cc-ym" data-ym-year-field{_customhide}><span class="cc-label">연도</span>'
|
||||
f'<select class="nw-select" data-nw-year>{year_opts}</select></label>'
|
||||
f'<label class="cc-field cc-ym" data-ym-month-field{_mhide}><span class="cc-label">월</span>'
|
||||
f'<select class="nw-select" data-nw-month>{month_opts}</select></label>'
|
||||
@@ -6931,15 +6938,15 @@ def render_html() -> str:
|
||||
'var sel=e.target;'
|
||||
'if(!sel||sel.tagName!=="SELECT"||!sel.classList||!sel.classList.contains("nw-select"))return;'
|
||||
'function ymFirstMonth(y){var cc=document.querySelector(".chart-controls");try{var mp=JSON.parse(cc.getAttribute("data-ym-months")||"{}");var a=mp[y]||[];return a.length?a[0]:"";}catch(_){return "";}}'
|
||||
'function ymSet(tp,y){if(!y)return;if(tp==="month"){var mm=ymFirstMonth(y);window.__behive_set_ym(mm?(y+"-"+mm):y);}else{window.__behive_set_ym(y);}}'
|
||||
'function curYear(){var e=document.querySelector(\'select.nw-select[data-nw-year]\');return e&&e.value?e.value:"";}'
|
||||
'function curType(){var e=document.querySelector(\'select.nw-select[data-nw-ymtype]\');return e&&e.value?e.value:"year";}'
|
||||
'if(sel.hasAttribute("data-nw-range")){'
|
||||
'var rv=sel.value;'
|
||||
'if(rv==="year"||rv==="month"){'
|
||||
# 연도별/월별 진입 — 현재 연도 드롭다운 값(기본=최신연도)으로 chartYM 세팅.
|
||||
'var yEl=document.querySelector(\'select.nw-select[data-nw-year]\');'
|
||||
'var y=yEl&&yEl.value?yEl.value:"";'
|
||||
'if(!y)return;' # 데이터 없음
|
||||
'if(rv==="year"){window.__behive_set_ym(y);}'
|
||||
'else{var mm=ymFirstMonth(y);window.__behive_set_ym(mm?(y+"-"+mm):y);}'
|
||||
'if(rv==="custom"){'
|
||||
# 지정기간 진입 — 유형(기본 연도별)·연도(기본 최신)로 chartYM 세팅.
|
||||
'var y=curYear();if(!y)return;' # 데이터 없음
|
||||
'ymSet(curType(),y);'
|
||||
'}else{'
|
||||
'window.__behive_set_ym("");' # 프리셋 → 절대선택 해제
|
||||
'try{localStorage.setItem("behive.chartDaysV2",rv);}catch(_){}'
|
||||
@@ -6950,11 +6957,10 @@ def render_html() -> str:
|
||||
'var curU=unitSel?unitSel.value:"day";'
|
||||
'if(allowed.indexOf(curU)<0){try{localStorage.setItem("behive.chartUnit",allowed[0]);}catch(_){}}'
|
||||
'}'
|
||||
'}else if(sel.hasAttribute("data-nw-ymtype")){'
|
||||
'ymSet(sel.value,curYear());'
|
||||
'}else if(sel.hasAttribute("data-nw-year")){'
|
||||
'var rEl=document.querySelector(\'select.nw-select[data-nw-range]\');'
|
||||
'var mode=rEl?rEl.value:"year";var yy=sel.value;'
|
||||
'if(mode==="month"){var m2=ymFirstMonth(yy);window.__behive_set_ym(m2?(yy+"-"+m2):yy);}'
|
||||
'else{window.__behive_set_ym(yy);}'
|
||||
'ymSet(curType(),sel.value);'
|
||||
'}else if(sel.hasAttribute("data-nw-month")){'
|
||||
'var ry=document.querySelector(\'select.nw-select[data-nw-year]\');'
|
||||
'window.__behive_set_ym((ry?ry.value:"")+"-"+sel.value);'
|
||||
|
||||
Reference in New Issue
Block a user