# 前后端分离的可视化数据返回方案(ECharts) ## 目标 - 后端不再生成/传输图片,仅返回图表数据;前端使用 ECharts 渲染。 - 统一的数据结构,减少前端适配代码;杜绝 NaN/Infinity/不可序列化对象导致的 API 崩溃。 - 与现有 API 保持兼容(`images` 可留空),逐步迁移到 `charts` 数据模式。 ## 序列化与清洗规范(必须遵守) - **NaN / Infinity / pd.NA**:递归清洗为 `null`(JSON `null`)。不得返回字符串 "NaN"。 - **时间戳**:统一 ISO8601 字符串(例 `2023-01-01T12:00:00`)。 - **数组/矩阵**:全部转为原生 Python list,再 JSON 序列化。 - **DataFrame**:优先 `to_dict(orient="records")` 或组装 dataset 形式(见下)。 - **数值类型**:numpy 标量转原生 `int/float/bool`;遇到 `nan/inf` 先清洗。 > 建议实现一个通用函数 `to_echarts_safe(obj)`,递归处理上述清洗与类型转换,所有响应数据出站前统一走这一层。 ## 响应骨架(新增 `charts`,旧字段保持) ```json { "success": true, "meta": { ... }, "analysis": { "zh": { "data_description": "...", "preprocessing_steps": [ ... ], "api_analysis": { ... }, "steps": [ {"key": "ts", "title": "Time Series", "summary": "...", "chart": "ts"}, ... ] } }, "charts": { "ts": { "type": "line", "dataset": [...], "meta": {...} }, "acf_pacf": { "type": "bar", "series": [...], "meta": {...} }, "heatmap": { "type": "heatmap", "data": [...], "xLabels": [...], "yLabels": [...], "meta": {...} }, ... }, "images": {}, "log": [...] } ``` - `steps[].chart` 指向 `charts` 的 key,前端可按步骤顺序渲染。 - `images` 保留但为空,兼容旧前端。 ## 各图表建议的数据格式(贴合 ECharts) - **时间序列(ts)**:`dataset` 形式 - 二维数组:首行表头,例如 `[ ["timestamp","sales","ad_cost"], ["2023-01-01T00:00:00", 10, 5], ... ]` - 前端:`dataset.source = dataset`,`series: [{type:'line', encode:{x:'timestamp', y:'sales'}}, ...]` - **ACF / PACF(acf_pacf)**: - `{ series: [{name:'acf', data:[{lag:0, value:1.0}, ...]}, {name:'pacf', data:[...] }], meta:{column:'sales'} }` - **平稳性检验(stationarity)**: - `{ adf: {statistic:..., p_value:..., critical_values:{...}}, kpss:{...}, meta:{column:'sales'} }` - 前端可渲染 bar/表格。 - **正态性检验(normality)**: - `{ columns: [{name:'col', shapiro_p:..., jb_p:..., shapiro_stat:..., jb_stat:...}], meta:{} }` - **季节性分解(seasonal)**: - `dataset` 形式:`[["timestamp","observed","trend","seasonal","resid"], [...]]` - **频谱分析(spectral)**: - `periodogram`: `{ f: [...], psd: [...] }`(可截断前 N 点) - `spectrogram`: `{ f: [...], t: [...], values: [[i,j,val], ...] }`(可只返回 log10 后再压缩) - **相关性热力图(heatmap)**: - `{ data: [[i,j,value], ...], xLabels:[...], yLabels:[...], meta:{} }`(后端提前 flatten N×N 矩阵) - **PCA 碎石图(pca_scree)**: - `dataset`: `[["component","explained","cumulative"], [1,0.4,0.4], ...]` - **PCA 散点(pca_scatter)**: - `records`: `[{pc1:..., pc2:..., timestamp:"..."}, ...]` - **特征重要性(feature_importance)**: - `records`: `[{feature:"...", importance:0.12}, ...]` - **聚类(cluster)**: - `records`: `[{timestamp:"...", cluster:0, x:<可选>, y:<可选>}...]` - **因子分析(factor)**: - 类似聚类:`[{timestamp:"...", factor1:..., factor2:...}]` - **协整检验(cointegration)**: - `{ trace_stat:[...], crit_95:[...], eigen_vals:[...], meta:{} }` - **VAR 预测(var_forecast)**: - `dataset`: `[["step","var1_forecast","var2_forecast"], [1, ...], ...]` > 原则:能用 `dataset` 就用 `dataset`,多条线在前端通过 `encode` 指定;需要矩阵的提前 flatten;其余用 records。 ## 样式与主题 - 后端不返回颜色、线型等视觉样式;仅返回语义字段(series 名称、指标含义)。前端根据主题决定配色与风格。 ## 实施步骤(建议) 1) 增加 `to_echarts_safe` 清洗函数,统一处理 NaN/Infinity/Timestamp/DataFrame -> JSON-safe。 2) 在各分析函数里:保留计算逻辑,改为组装 chart data(dataset/records/flatten),不再生成 PNG;`generate_plots` 逻辑可留作开关,但默认 False。 3) `run_analysis` 汇总时,将各 step 的数据填入 `charts`,在 `steps` 内写入 `chart` key(引用图表)。 4) 路由层返回 `charts` 字段,`images` 留空,`steps` 仍返回。 5) 前端按 `charts` 协议接入 ECharts,去掉对 `images` 的依赖。 ## 兼容与回退 - 旧前端:仍可拿到 `analysis.steps` 及 `images`(为空)。 - 新前端:使用 `charts`。如果某一步失败,返回 `{error:"..."}` 和简短 summary,避免 500。 ## 性能注意 - 后端不画图,CPU/IO 显著下降;如需进一步优化,可让前端传 `methods` 列表决定执行哪些步骤。 ## 算法是否需要改动? - 核心统计/时序算法(ADF/KPSS、ACF/PACF、PCA、VAR、季节分解、相关矩阵、聚类等)保持不变,改动集中在“结果封装”层。 - 需要调整的只是输出包装: - 将现有用于绘图的中间结果(DataFrame/ndarray/statsmodels 结果)转换为 ECharts 友好的 JSON 结构,统一经过 `to_echarts_safe` 清洗(NaN/Inf/Timestamp)。 - 矩阵类结果(如相关性)在后端提前 flatten 成 `[i,j,value]` 列表;dataset 形式优先用于多系列折线/柱状。 - 可按需做截断/摘要以控体积(如 periodogram 取前 N 点,spectrogram 取均值或下采样)。 - 补充元信息(列名/单位/变量名),方便前端生成 legend/tooltip。 - 不需改动的部分: - 预处理、标准化流程、算法的数学实现与参数选择(滞后阶、分解周期、PCA 组件数等)保持现状。 - 如后续发现数据量过大或性能瓶颈,可再对个别步骤做抽样/截断,但不影响算法正确性。 ## 追加约定(仍然不改算法,只改结果包装) - **直方图分箱**:正态性/分布分析中,后端负责 binning(`np.histogram`),返回 `[["range_start","range_end","count"], ...]`。前端不做分箱。 - **to_echarts_safe 扩展**:除 NaN/Inf/Timestamp 外,显式处理 numpy 各数值类型、Decimal,必要时加“已访问集合”防循环引用。统一输出 JSON-safe、ECharts-friendly 结构。 - **矩阵/多系列格式**:矩阵类(相关性等)继续 flatten `[i,j,value]`;多系列/多列数据优先用 dataset+encode,保证对齐。