脚本管理
ScriptManagement<T> trait 定义了 ChartView 完整的脚本生命周期 API,涵盖脚本的添加、移除、查询与配置。
T 是用户自定义的标签类型——可以是 String(脚本名称)、UUID,或任何实现了 Clone + PartialEq + Display 的类型。
同一圖表上各脚本的 tag 必須唯一。 set_scripts 通過 tag 對比新舊列表:兩側都存在的 tag 對應的脚本保持不變(不重算);僅出現在新列表的 tag 對應脚本被添加;僅出現在舊列表的 tag 對應脚本被移除。若兩個脚本共用相同 tag,diff 結果不可預期。請使用脚本名稱、UUID 或其他每個脚本都唯一的值作為 tag。
导入
use navi_chart::{ChartView, ScriptManagement};添加脚本
add_script 是 ScriptManagement<T> 的一部分,接收 Script 类型的值(即 provider 的关联类型 P::Script):
// LocalChartProvider — Script = String(源码字符串)
let id = cv.add_script(source.to_string(), "RSI".to_string());
// 自定义 ChartProvider — Script 取决于 P::Script 的具体类型
let id = cv.add_script(script_handle, "RSI".to_string());使用 add_script_with_complete 可在初次历史回放完成时收到通知:
let id = cv.add_script_with_complete(source, "RSI".to_string(), |result| {
match result {
Ok(()) => println!("RSI 加载成功"),
Err(e) => eprintln!("RSI 错误: {e}"),
}
});添加脚本会触发 session 重启——所有脚本(含已有脚本)从第 0 根 bar 重新回放。
批量替換
要一次性替換所有脚本,使用 set_scripts。在 stream 已運行時,它通過 tag 對比新舊列表進行增量操作——保留未變化的脚本、添加新脚本、移除已刪除的脚本,無需重啟 stream,且只有新增脚本會被重新計算。若 stream 尚未啟動,則以一次 stream 啟動覆蓋所有脚本。
let ids = cv.set_scripts(vec![
(source1, "RSI".to_string()),
(source2, "MACD".to_string()),
]);使用 set_scripts_with_complete 可在初次歷史回放完成時收到通知:
let ids = cv.set_scripts_with_complete(
vec![(source1, "RSI".to_string()), (source2, "MACD".to_string())],
|result| match result {
Ok(()) => println!("全部加載完成"),
Err(e) => eprintln!("錯誤: {e}"),
},
);回調只觸發一次——若任意脚本出錯則攜帶該錯誤,全部成功時攜帶 Ok(())。
傳入空 Vec 等價於 remove_all_scripts。
泛型代码
由于 add_script 在 trait 中,可以编写适用于任意图表视图的泛型函数:
use navi_chart::{ScriptManagement, ScriptId};
fn add_and_track<C>(cv: &C, source: C::Script, tag: String) -> ScriptId
where
C: ScriptManagement<String>,
{
cv.add_script(source, tag)
}方法参考
| 方法 | 说明 |
|---|---|
add_script(script, tag) | 添加脚本,返回 ScriptId。觸發 session 重啟。 |
add_script_with_complete(script, tag, cb) | 同上,但初次回放完成後調用 cb。 |
set_scripts(scripts) | 一次性替換所有脚本,只觸發一次重啟。返回 Vec<ScriptId>,順序與輸入一致。 |
set_scripts_with_complete(scripts, cb) | 同上,但全部完成或首次出錯時調用一次 cb。 |
remove_script(id) | 按 ScriptId 移除脚本,釋放所有資源並重新渲染。 |
remove_all_scripts() | 移除圖表上的所有脚本。 |
set_script_config(id, config) | 套用 ScriptConfig(輸入覆蓋 + 策略配置覆蓋 + 視覺覆蓋)。輸入或策略配置變更觸發重啟;僅視覺變更則立即重新渲染。 |
strategy_report(id) | 返回策略报告;若非策略脚本或尚无输出则返回 None。 |
scripts() | 按插入顺序返回所有脚本的 (tag, id) 对。 |
has_script_tag(tag) | 若存在指定标签的脚本则返回 true。 |
script_id_for_tag(tag) | 按标签查找 ScriptId。 |
script_config(id) | 返回脚本当前的 ScriptConfig。 |
graph_configs(id) | 返回各系列图形的原始(未覆盖)视觉配置。 |
script_overrides(id) | 返回各系列图形当前的视觉覆盖。 |
script_inputs(id) | 返回脚本的输入定义及其默认值。 |
script_error(id) | 返回最近一次编译或运行时错误(如有)。 |
tag_for(id) | 反查:根据 ScriptId 返回对应标签。 |
注意
ScriptId是不透明且非零的。若需配置或移除脚本,请保存它;可通过tag_for从事件中恢复标签。
持久化
内置的 save / load API 返回泛型 ChartSnapshot<T, P::Script>:
let snapshot = cv.save(); // ChartSnapshot<String, P::Script>
let json = serde_json::to_string(&snapshot).unwrap();
// ...
cv.load(serde_json::from_str(&json).unwrap());完整的保存/恢复流程请参阅 ChartView — 持久化。ScriptConfig 数据模型和配置 UI 教程请参阅 脚本配置界面。