forked from balisujohn/localwriter
-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathviz_auto_plot.py
More file actions
122 lines (108 loc) · 3.84 KB
/
Copy pathviz_auto_plot.py
File metadata and controls
122 lines (108 loc) · 3.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# WriterAgent - AI Writing Assistant for LibreOffice
# Copyright (c) 2026 KeithCu (modifications and relicensing)
#
# SPDX-License-Identifier: GPL-3.0-or-later
"""Analysis → viz auto-plot mapping for analyze_data."""
from __future__ import annotations
import re
from typing import Any
from plugin.scripting.viz import HELPER_NAMES
AUTO_PLOT_ANALYSIS_HELPERS = frozenset(
{
"run_regression",
"cluster_numeric",
"monte_carlo",
"correlation_matrix",
}
)
_VIZ_HINT_RE = re.compile(r"\b(chart|plot|visual|graph|distribution|histogram|heatmap)\b", re.I)
def task_hint_implies_plot(task_hint: str | None) -> bool:
if not task_hint or not str(task_hint).strip():
return False
return _VIZ_HINT_RE.search(str(task_hint)) is not None
def should_auto_plot(*, helper: str, auto_plot: bool, task_hint: str | None) -> bool:
if helper not in AUTO_PLOT_ANALYSIS_HELPERS:
return False
return bool(auto_plot) or task_hint_implies_plot(task_hint)
def build_viz_request(
analysis_helper: str,
*,
analysis_result: dict[str, Any],
analysis_params: dict[str, Any] | None,
) -> tuple[str, dict[str, Any]] | None:
"""Return (viz_helper, viz_params) for a completed analysis result."""
params = dict(analysis_params or {})
if analysis_helper == "correlation_matrix":
return "correlation_heatmap", {"method": params.get("method", "pearson")}
if analysis_helper == "monte_carlo":
return "plot_data", {"spec": {"chart_type": "histogram", "title": "Monte Carlo distribution"}}
if analysis_helper == "run_regression":
target = params.get("target")
features = params.get("features") or []
x_col = features[0] if isinstance(features, list) and features else None
if not target or not x_col:
return None
return "plot_data", {
"spec": {
"chart_type": "scatter",
"x": x_col,
"y": target,
"title": f"Regression: {target} vs {x_col}",
}
}
if analysis_helper == "cluster_numeric":
columns = params.get("columns")
if isinstance(columns, list) and len(columns) >= 2:
x_col, y_col = columns[0], columns[1]
else:
metadata = analysis_result.get("metadata")
if not isinstance(metadata, dict):
return None
numeric_raw = metadata.get("numeric_cols")
if not isinstance(numeric_raw, list) or len(numeric_raw) < 2:
return None
x_col, y_col = numeric_raw[0], numeric_raw[1]
return "plot_data", {
"spec": {
"chart_type": "scatter",
"x": x_col,
"y": y_col,
"title": "Cluster view",
}
}
return None
def run_auto_plot_after_analysis(
uno_ctx: Any,
doc: Any,
*,
analysis_helper: str,
analysis_result: dict[str, Any],
analysis_params: dict[str, Any] | None,
data_range: str | None,
auto_plot: bool,
task_hint: str | None,
) -> dict[str, Any] | None:
"""Run a viz helper when auto-plot triggers; return viz result or None."""
if analysis_result.get("status") != "ok":
return None
if not should_auto_plot(helper=analysis_helper, auto_plot=auto_plot, task_hint=task_hint):
return None
request = build_viz_request(
analysis_helper,
analysis_result=analysis_result,
analysis_params=analysis_params,
)
if request is None:
return None
viz_helper, viz_params = request
if viz_helper not in HELPER_NAMES:
return None
from plugin.scripting.viz import run_trusted_viz
return run_trusted_viz(
uno_ctx,
doc,
helper=viz_helper,
params=viz_params,
data_range=data_range,
task_hint=task_hint,
)