"""f11_generalized_chart -- generalized compressibility chart: Z vs P_r for
T_r = 1.0, 1.05, 1.1, 1.2, 1.4, 1.6, 2.0, 3.0, computed with PR at
omega = 0 (simple-fluid reference), using the synthetic Tc=Pc=1 species.
"""
import sys
sys.path.insert(0, "/home/claude/eos_lecture/code")
from eosstyle import *

SPECIES["_simple"] = dict(Tc=1.0, Pc=1.0, w=0.0)

Trs = [1.0, 1.05, 1.1, 1.2, 1.4, 1.6, 2.0, 3.0]
Pr = np.linspace(0.02, 8.0, 300)

fig, ax = newfig(7.2, 4.8)

shades = [NAVY, "#2f6690", "#3d7fa8", SKYBLUE, "#6fa5c7", TEAL, "#0a5451", "#083a38"]

curves = {}
for Tr, col in zip(Trs, shades):
    Z = []
    for P in Pr:
        r = Zroots("pr", "_simple", Tr, P, Rg=1.0)
        Z.append(r[-1] if len(r) else np.nan)
    Z = np.array(Z)
    curves[Tr] = Z
    ax.plot(Pr, Z, color=col, lw=2.0)

# the Z = 1 guide line is drawn only across the data range so that it does
# not run through the label gutter on the right.
ax.plot([0.0, 8.0], [1.0, 1.0], color=GRAPHITE, lw=1.1, linestyle=":", zorder=2)

ax.set_xlabel(r"Reduced pressure, $P_r$")
ax.set_ylabel(r"Compressibility factor, $Z$")
# the region P_r > 8 is kept free of data and used as a label gutter, so the
# eight direct labels can be staggered without touching each other.
ax.set_xlim(0, 10.0)
ax.set_ylim(0.15, 1.25)
ax.set_xticks([0, 2, 4, 6, 8])

# all curves are close together at the right edge (Pr=8), so direct labels
# are staggered vertically with a minimum pitch and joined to the true
# curve endpoint with a leader line drawn entirely inside the empty gutter
# (same approach as f06/f09/f10).
LABEL_FS = 10.5
PITCH_PT = 15.0          # baseline-to-baseline pitch, comfortably > font size
fig.tight_layout()
fig.canvas.draw()
ax_h_pt = ax.get_window_extent().height * 72.0 / fig.dpi
y0, y1 = ax.get_ylim()
min_gap = PITCH_PT * (y1 - y0) / ax_h_pt

colmap = dict(zip(Trs, shades))
ends = sorted([(Tr, curves[Tr][-1]) for Tr in Trs], key=lambda t: -t[1])
ytexts = []
for i, (Tr, Z) in enumerate(ends):
    yt = Z if i == 0 else min(Z, ytexts[-1] - min_gap)
    ytexts.append(yt)
for (Tr, Z), yt in zip(ends, ytexts):
    col = colmap[Tr]
    if abs(yt - Z) > 1e-6:
        ax.plot([8.03, 8.62], [Z, yt], color=col, lw=0.9, alpha=0.85,
                solid_capstyle="round", zorder=3)
    else:
        ax.plot([8.03, 8.62], [Z, yt], color=col, lw=0.9, alpha=0.85, zorder=3)
    ax.text(8.75, yt, f"$T_r={Tr:g}$", color=col, fontsize=LABEL_FS,
            va="center", ha="left", zorder=6,
            bbox=dict(facecolor="white", edgecolor="none", alpha=0.9, pad=1.5))

save(fig, "f11_generalized_chart")
