from __future__ import annotations import plotly.graph_objects as go from app.analysis.spc import SPCResult def histogram(result: SPCResult) -> dict: """Distribution histogram with spec limits overlay.""" fig = go.Figure() fig.add_trace(go.Histogram(x=result.values, name="Measurements", nbinsx=20)) fig.add_vline(x=result.usl, line_dash="dash", line_color="red", annotation_text="USL") fig.add_vline(x=result.lsl, line_dash="dash", line_color="red", annotation_text="LSL") fig.add_vline(x=result.nominal, line_dash="dot", line_color="green", annotation_text="Nominal") fig.update_layout( title=f"Distribution – {result.feature_name}", xaxis_title="Value", yaxis_title="Count", template="plotly_white", height=350, ) return fig.to_plotly_json() def control_chart(result: SPCResult) -> dict: """Individual values control chart (I-chart).""" x_axis = list(range(1, result.n + 1)) fig = go.Figure() fig.add_trace(go.Scatter( x=x_axis, y=result.values, mode="lines+markers", name="Value", )) fig.add_hline(y=result.mean, line_color="green", annotation_text="Mean") fig.add_hline(y=result.ucl, line_dash="dash", line_color="red", annotation_text="UCL") fig.add_hline(y=result.lcl, line_dash="dash", line_color="red", annotation_text="LCL") fig.add_hline(y=result.usl, line_dash="dot", line_color="orange", annotation_text="USL") fig.add_hline(y=result.lsl, line_dash="dot", line_color="orange", annotation_text="LSL") fig.update_layout( title=f"Control Chart – {result.feature_name}", xaxis_title="Sample #", yaxis_title="Value", template="plotly_white", height=350, ) return fig.to_plotly_json() def capability_bar(results: list[SPCResult]) -> dict: """Capability index bar chart comparing all features.""" names = [r.feature_name for r in results] cpk_vals = [r.cpk if r.cpk is not None else 0.0 for r in results] ppk_vals = [r.ppk if r.ppk is not None else 0.0 for r in results] colors = ["#2ecc71" if v >= 1.33 else "#f39c12" if v >= 1.0 else "#e74c3c" for v in cpk_vals] fig = go.Figure() fig.add_trace(go.Bar(x=names, y=cpk_vals, name="Cpk", marker_color=colors)) fig.add_trace(go.Bar(x=names, y=ppk_vals, name="Ppk", marker_color="rgba(52,152,219,0.6)")) fig.add_hline(y=1.33, line_dash="dash", line_color="green", annotation_text="Cpk=1.33") fig.add_hline(y=1.0, line_dash="dot", line_color="orange", annotation_text="Cpk=1.0") fig.update_layout( title="Process Capability Summary", xaxis_title="Feature", yaxis_title="Index", barmode="group", template="plotly_white", height=400, ) return fig.to_plotly_json() def generate_charts(results: list[SPCResult]) -> dict: """Generate all charts for a set of SPC results.""" charts: dict[str, list[dict] | dict] = { "histograms": [], "control_charts": [], } for r in results: if r.n >= 2: charts["histograms"].append(histogram(r)) charts["control_charts"].append(control_chart(r)) if results: charts["capability_bar"] = capability_bar(results) return charts