6.7 KiB
6.7 KiB
前后端分离的可视化数据返回方案(ECharts)
目标
- 后端不再生成/传输图片,仅返回图表数据;前端使用 ECharts 渲染。
- 统一的数据结构,减少前端适配代码;杜绝 NaN/Infinity/不可序列化对象导致的 API 崩溃。
- 与现有 API 保持兼容(
images可留空),逐步迁移到charts数据模式。
序列化与清洗规范(必须遵守)
- NaN / Infinity / pd.NA:递归清洗为
null(JSONnull)。不得返回字符串 "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,旧字段保持)
{
"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 名称、指标含义)。前端根据主题决定配色与风格。
实施步骤(建议)
- 增加
to_echarts_safe清洗函数,统一处理 NaN/Infinity/Timestamp/DataFrame -> JSON-safe。 - 在各分析函数里:保留计算逻辑,改为组装 chart data(dataset/records/flatten),不再生成 PNG;
generate_plots逻辑可留作开关,但默认 False。 run_analysis汇总时,将各 step 的数据填入charts,在steps内写入chartkey(引用图表)。- 路由层返回
charts字段,images留空,steps仍返回。 - 前端按
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。
- 将现有用于绘图的中间结果(DataFrame/ndarray/statsmodels 结果)转换为 ECharts 友好的 JSON 结构,统一经过
- 不需改动的部分:
- 预处理、标准化流程、算法的数学实现与参数选择(滞后阶、分解周期、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,保证对齐。