{"spec_id":"pp-basic","library":"highcharts","language":"javascript","code":"// anyplot.ai\n// pp-basic: Probability-Probability (P-P) Plot\n// Library: highcharts 12.6.0 | JavaScript 22.22.3\n// Quality: 84/100 | Created: 2026-06-09\n//# anyplot-orientation: square\n\nconst t = window.ANYPLOT_TOKENS;\n\n// Deterministic LCG for reproducible data (no seeded RNG in browser)\nlet lcgState = 42;\nfunction lcgRand() {\n    lcgState = (1664525 * lcgState + 1013904223) >>> 0;\n    return lcgState / 0x100000000;\n}\n\n// Box-Muller: standard normal samples\nfunction stdNormal() {\n    const u1 = Math.max(lcgRand(), 1e-10);\n    const u2 = lcgRand();\n    return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);\n}\n\n// Normal CDF via Abramowitz & Stegun rational approximation (max error ~7.5e-8)\nfunction normalCDF(x, mu, sigma) {\n    const z = (x - mu) / sigma;\n    const a = Math.abs(z);\n    const t0 = 1 / (1 + 0.2316419 * a);\n    const poly = t0 * (0.319381530 + t0 * (-0.356563782 + t0 * (1.781477937 + t0 * (-1.821255978 + t0 * 1.330274429))));\n    const phi = Math.exp(-0.5 * a * a) / Math.sqrt(2 * Math.PI);\n    const p = 1 - phi * poly;\n    return z >= 0 ? p : 1 - p;\n}\n\n// Generate 200 samples: right-skewed, simulating manufacturing process cycle times\n// (short cycles dominate; occasional long runs create a heavier upper tail)\nconst N = 200;\nconst samples = [];\nfor (let i = 0; i < N; i++) {\n    const base = stdNormal();\n    const skew = Math.abs(stdNormal()) * 0.4;\n    samples.push(base + skew);\n}\n\n// Fit normal parameters (MLE: sample mean and std)\nconst mean = samples.reduce((s, v) => s + v, 0) / N;\nconst std = Math.sqrt(samples.reduce((s, v) => s + (v - mean) ** 2, 0) / N);\n\n// Sort and compute P-P values using plotting position i/(n+1)\nconst sorted = [...samples].sort((a, b) => a - b);\nconst ppPoints = sorted.map((x, i) => {\n    const empirical = (i + 1) / (N + 1);\n    const theoretical = normalCDF(x, mean, std);\n    return [theoretical, empirical];\n});\n\n// 45-degree reference line (perfect distributional fit)\nconst refLine = [[0, 0], [1, 1]];\n\n// Deviation zone: where the S-shaped curve crosses the diagonal (~0.35–0.65)\nconst devBandColor = 'rgba(0, 158, 115, 0.08)';\n\nHighcharts.chart(\"container\", {\n    chart: {\n        backgroundColor: \"transparent\",\n        plotBorderWidth: 0,\n        animation: false,\n        style: { fontFamily: \"inherit\" },\n        margin: [80, 50, 95, 90]\n    },\n    credits: { enabled: false },\n    colors: t.palette,\n    title: {\n        text: \"pp-basic · javascript · highcharts · anyplot.ai\",\n        style: { color: t.ink, fontSize: \"22px\", fontWeight: \"600\" }\n    },\n    subtitle: {\n        text: \"Manufacturing process cycle times (n=200) vs Normal — S-curve signals heavier tails\",\n        style: { color: t.inkSoft, fontSize: \"13px\" }\n    },\n    xAxis: {\n        title: {\n            text: \"Theoretical Probability\",\n            style: { color: t.inkSoft, fontSize: \"16px\" }\n        },\n        min: 0,\n        max: 1,\n        tickInterval: 0.25,\n        lineColor: t.inkSoft,\n        lineWidth: 1,\n        tickColor: t.inkSoft,\n        tickLength: 5,\n        gridLineColor: t.grid,\n        gridLineWidth: 1,\n        labels: {\n            style: { color: t.inkSoft, fontSize: \"14px\" },\n            format: \"{value:.2f}\"\n        },\n        plotBands: [{\n            from: 0.35,\n            to: 0.65,\n            color: devBandColor,\n            zIndex: 0,\n            label: {\n                text: \"deviation zone\",\n                align: \"center\",\n                verticalAlign: \"top\",\n                y: 14,\n                style: { color: t.inkSoft, fontSize: \"11px\", fontStyle: \"italic\" }\n            }\n        }]\n    },\n    yAxis: {\n        title: {\n            text: \"Empirical Probability\",\n            style: { color: t.inkSoft, fontSize: \"16px\" }\n        },\n        min: 0,\n        max: 1,\n        tickInterval: 0.25,\n        lineColor: t.inkSoft,\n        lineWidth: 1,\n        tickColor: t.inkSoft,\n        tickLength: 5,\n        gridLineColor: t.grid,\n        gridLineWidth: 1,\n        labels: {\n            style: { color: t.inkSoft, fontSize: \"14px\" },\n            format: \"{value:.2f}\"\n        },\n        plotBands: [{\n            from: 0.35,\n            to: 0.65,\n            color: \"rgba(0, 158, 115, 0.04)\",\n            zIndex: 0\n        }]\n    },\n    legend: {\n        enabled: true,\n        align: \"right\",\n        verticalAlign: \"top\",\n        layout: \"vertical\",\n        itemStyle: { color: t.inkSoft, fontSize: \"14px\" },\n        itemHoverStyle: { color: t.ink }\n    },\n    tooltip: { enabled: false },\n    plotOptions: {\n        series: { animation: false },\n        scatter: {\n            marker: {\n                radius: 5,\n                symbol: \"circle\",\n                lineWidth: 1,\n                lineColor: t.pageBg\n            }\n        }\n    },\n    series: [\n        {\n            type: \"scatter\",\n            name: \"Manufacturing Cycle Times\",\n            data: ppPoints,\n            color: t.palette[0],\n            zIndex: 2\n        },\n        {\n            type: \"line\",\n            name: \"Perfect Fit\",\n            data: refLine,\n            color: t.inkSoft,\n            dashStyle: \"Dash\",\n            lineWidth: 2,\n            marker: { enabled: false },\n            enableMouseTracking: false,\n            zIndex: 1\n        }\n    ]\n});\n"}