File size: 2,593 Bytes
60034d4
 
010071f
b8b8eab
010071f
60034d4
 
 
 
 
 
 
 
 
 
b8b8eab
60034d4
 
 
 
 
b8b8eab
60034d4
 
 
 
 
 
 
 
 
b8b8eab
60034d4
 
 
 
b04cfbb
60034d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b8b8eab
60034d4
b8b8eab
60034d4
 
 
 
 
 
 
 
 
 
b8b8eab
60034d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os
import tempfile
import pandas as pd
import plotly.graph_objects as go


def plot_metric_tool(
    file_path: str,
    date_col: str,
    value_col: str,
    output_dir: str = "/tmp",
    title: str = None,
    line_width: int = 2,
    marker_size: int = 6
):
    """
    Load CSV or Excel file, parse a time series metric, and return an interactive Plotly Figure.
    Also saves a high-resolution PNG to a temp directory for static embedding.

    Returns:
      fig (go.Figure) or error string starting with '❌'.
    """
    # 0) Load data
    ext = os.path.splitext(file_path)[1].lower()
    try:
        if ext in ('.xls', '.xlsx'):
            df = pd.read_excel(file_path)
        else:
            df = pd.read_csv(file_path)
    except Exception as exc:
        return f"❌ Failed to load file: {exc}"

    # 1) Validate columns
    missing = [c for c in (date_col, value_col) if c not in df.columns]
    if missing:
        return f"❌ Missing column(s): {', '.join(missing)}"

    # 2) Parse date and ensure numeric values
    try:
        df[date_col] = pd.to_datetime(df[date_col], errors='coerce')
    except Exception:
        return f"❌ Could not parse '{date_col}' as dates."
    df[value_col] = pd.to_numeric(df[value_col], errors='coerce')
    df = df.dropna(subset=[date_col, value_col])
    if df.empty:
        return f"❌ No valid data after cleaning '{date_col}'/'{value_col}'"

    # 3) Sort and aggregate duplicates
    df = (
        df[[date_col, value_col]]
        .groupby(date_col, as_index=True)
        .mean()
        .sort_index()
    )

    # 4) Create Plotly figure
    fig = go.Figure(
        data=[
            go.Scatter(
                x=df.index,
                y=df[value_col],
                mode='lines+markers',
                line=dict(width=line_width),
                marker=dict(size=marker_size),
                name=value_col
            )
        ]
    )
    plot_title = title or f"{value_col} Trend"
    fig.update_layout(
        title=plot_title,
        xaxis_title=date_col,
        yaxis_title=value_col,
        template='plotly_dark',
        hovermode='x unified'
    )

    # 5) Save static PNG
    os.makedirs(output_dir, exist_ok=True)
    tmpfile = tempfile.NamedTemporaryFile(
        suffix='.png', prefix='trend_', dir=output_dir, delete=False
    )
    img_path = tmpfile.name
    tmpfile.close()
    try:
        fig.write_image(img_path, scale=2)
    except Exception as exc:
        return f"❌ Failed saving image: {exc}"

    # 6) Return figure and path for embedding
    return fig, img_path