File size: 4,702 Bytes
fdcec08
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import plotly.graph_objects as go
from plotly.subplots import make_subplots

def create_dcrm_plot(df, zones):
    # Create figure with secondary y-axis
    fig = make_subplots(specs=[[{"secondary_y": True}]])

    # Add Traces
    # Ensure column names match what is in the DF (dcrm_llm_app.py uses 'Time (ms)', 'Current', 'Resistance', 'Travel')
    # The user's code uses 'Time_ms'. I need to be careful here.
    # process_uploaded_image returns DF with 'Time (ms)', 'Current', 'Resistance', 'Travel'.
    # I should adapt the plotting code to use the existing column names OR rename columns in the DF.
    # The user's code expects 'Time_ms'.
    # I will handle this mapping inside the function to be safe.
    
    time_col = 'Time (ms)' if 'Time (ms)' in df.columns else 'Time_ms'
    
    fig.add_trace(go.Scatter(x=df[time_col], y=df['Current'], name="Current (A)", line=dict(color='#2980b9', width=2)), secondary_y=False)
    fig.add_trace(go.Scatter(x=df[time_col], y=df['Resistance'], name="Resistance (uOhm)", line=dict(color='#27ae60', width=2)), secondary_y=False)
    fig.add_trace(go.Scatter(x=df[time_col], y=df['Travel'], name="Travel (mm)", line=dict(color='#c0392b', width=2)), secondary_y=True)

    # Zone Colors
    zone_colors = {
        "zone_1_pre_contact": "rgba(52, 152, 219, 0.1)",
        "zone_2_arcing_engagement": "rgba(231, 76, 60, 0.1)",
        "zone_3_main_conduction": "rgba(46, 204, 113, 0.1)",
        "zone_4_parting": "rgba(155, 89, 182, 0.1)",
        "zone_5_final_open": "rgba(149, 165, 166, 0.1)"
    }

    # Add Zone Rectangles
    # The user's code expects 'zones' to be a dict of zone details.
    # The result_json has "zones" key.
    zones_dict = zones.get("zones", {}) if "zones" in zones else zones

    for zone_name, details in zones_dict.items():
        start = details.get("start_ms")
        end = details.get("end_ms")
        color = zone_colors.get(zone_name, "rgba(0,0,0,0)")
        
        if start is not None and end is not None:
            fig.add_vrect(
                x0=start, x1=end,
                fillcolor=color, opacity=1,
                layer="below", line_width=0,
                annotation_text=zone_name.split('_')[1].upper(),
                annotation_position="top left",
                annotation_font_color="#7f8c8d"
            )

    fig.update_layout(
        title_text="<b>Main Signals & Zones</b>",
        height=500,
        hovermode="x unified",
        plot_bgcolor="white",
        paper_bgcolor="white",
        font=dict(family="Segoe UI, sans-serif"),
        legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),
        margin=dict(l=20, r=20, t=60, b=20)
    )
    fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='#f0f0f0')
    fig.update_yaxes(title_text="Current / Resistance", secondary_y=False, showgrid=True, gridwidth=1, gridcolor='#f0f0f0')
    fig.update_yaxes(title_text="Travel", secondary_y=True, showgrid=False)

    return fig

def create_velocity_plot(df):
    time_col = 'Time (ms)' if 'Time (ms)' in df.columns else 'Time_ms'
    
    # Calculate Velocity (Derivative of Travel)
    # V = d(Travel) / d(Time)
    # Units: mm/ms = m/s
    df['Velocity'] = df['Travel'].diff() / df[time_col].diff()
    
    fig = go.Figure()
    fig.add_trace(go.Scatter(x=df[time_col], y=df['Velocity'], name="Velocity (m/s)", line=dict(color='#e67e22', width=2), fill='tozeroy'))
    
    fig.update_layout(
        title_text="<b>Contact Velocity Profile</b>",
        height=300,
        hovermode="x unified",
        plot_bgcolor="white",
        paper_bgcolor="white",
        font=dict(family="Segoe UI, sans-serif"),
        margin=dict(l=20, r=20, t=40, b=20)
    )
    fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='#f0f0f0')
    fig.update_yaxes(title_text="Velocity (m/s)", showgrid=True, gridwidth=1, gridcolor='#f0f0f0')
    return fig

def create_resistance_zoom_plot(df):
    time_col = 'Time (ms)' if 'Time (ms)' in df.columns else 'Time_ms'
    
    fig = go.Figure()
    fig.add_trace(go.Scatter(x=df[time_col], y=df['Resistance'], name="Resistance", line=dict(color='#27ae60', width=2)))
    
    fig.update_layout(
        title_text="<b>Detailed Resistance (Log Scale)</b>",
        height=300,
        hovermode="x unified",
        plot_bgcolor="white",
        paper_bgcolor="white",
        font=dict(family="Segoe UI, sans-serif"),
        yaxis_type="log", # Log scale to see details
        margin=dict(l=20, r=20, t=40, b=20)
    )
    fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='#f0f0f0')
    fig.update_yaxes(title_text="Resistance (uOhm)", showgrid=True, gridwidth=1, gridcolor='#f0f0f0')
    return fig