fix(web): 自动刷新保留 K 线视窗;威科夫与图表增量更新
自动刷新改用 tail update 与 scrollToPosition 恢复视窗,避免 setData 后跳到最右;拆分 chart_tv 模块并扩展 analyze/recent API。同步威科夫分析、pipeline 增量构建及相关策略与配置。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -70,36 +70,43 @@ def build_timeframe_labels(timeframes):
|
||||
return labels
|
||||
|
||||
|
||||
def _adjacent_smaller(timeframe_keys, ceiling_tf):
|
||||
"""取排序列表中严格小于 ceiling 的相邻周期。"""
|
||||
if not timeframe_keys:
|
||||
return ceiling_tf
|
||||
try:
|
||||
idx = timeframe_keys.index(ceiling_tf)
|
||||
return timeframe_keys[idx - 1] if idx > 0 else timeframe_keys[0]
|
||||
except ValueError:
|
||||
return timeframe_keys[0]
|
||||
|
||||
|
||||
def _prefer_smaller(candidates, labels_ordered, ceiling_tf, timeframe_keys):
|
||||
"""从候选中选第一个存在且严格小于 ceiling 的周期,否则回退相邻更小。"""
|
||||
ceil_m = timeframe_to_minutes(ceiling_tf)
|
||||
for tf in candidates:
|
||||
m = timeframe_to_minutes(tf)
|
||||
if tf in labels_ordered and m is not None and ceil_m is not None and m < ceil_m:
|
||||
return tf
|
||||
return _adjacent_smaller(timeframe_keys, ceiling_tf)
|
||||
|
||||
|
||||
def compute_timeframe_defaults(labels_ordered):
|
||||
"""
|
||||
根据已排序的「周期 → 中文标签」映射,计算主 / 次 / 次次周期默认值。
|
||||
默认偏好:主 4h、次 1h、次次 15m。
|
||||
labels_ordered: OrderedDict 或按插入顺序排列的 dict。
|
||||
"""
|
||||
if not labels_ordered:
|
||||
labels_ordered = DEFAULT_TIMEFRAME_LABELS.copy()
|
||||
timeframe_keys = list(labels_ordered.keys())
|
||||
preferred_main = next((tf for tf in ['5m', '15m', '1h'] if tf in labels_ordered), None)
|
||||
preferred_main = next((tf for tf in ['4h', '1h', '15m'] if tf in labels_ordered), None)
|
||||
default_main = preferred_main or (timeframe_keys[0] if timeframe_keys else '1m')
|
||||
if default_main not in labels_ordered and timeframe_keys:
|
||||
default_main = timeframe_keys[0]
|
||||
|
||||
if timeframe_keys:
|
||||
try:
|
||||
idx = timeframe_keys.index(default_main)
|
||||
default_element = timeframe_keys[idx - 1] if idx > 0 else timeframe_keys[0]
|
||||
except ValueError:
|
||||
default_element = timeframe_keys[0]
|
||||
else:
|
||||
default_element = default_main
|
||||
|
||||
if timeframe_keys:
|
||||
try:
|
||||
idx_el = timeframe_keys.index(default_element)
|
||||
default_sub_sub = timeframe_keys[idx_el - 1] if idx_el > 0 else timeframe_keys[0]
|
||||
except ValueError:
|
||||
default_sub_sub = timeframe_keys[0]
|
||||
else:
|
||||
default_sub_sub = default_element
|
||||
default_element = _prefer_smaller(['1h', '15m'], labels_ordered, default_main, timeframe_keys)
|
||||
default_sub_sub = _prefer_smaller(['15m', '5m'], labels_ordered, default_element, timeframe_keys)
|
||||
|
||||
return default_main, default_element, default_sub_sub, timeframe_keys
|
||||
|
||||
|
||||
Reference in New Issue
Block a user