{"spec_id":"spc-xbar-r","library":"echarts","language":"javascript","code":"// anyplot.ai\n// spc-xbar-r: Statistical Process Control Chart (X-bar/R)\n// Library: echarts 5.5.1 | JavaScript 22.22.3\n// Quality: 91/100 | Created: 2026-06-20\n\nconst t = window.ANYPLOT_TOKENS;\n\n// SPC constants for subgroup size n=5: A2=0.577, D3=0, D4=2.115\nconst A2 = 0.577, D3 = 0, D4 = 2.115;\nconst xbarBar = 50.0;\nconst rBar = 1.20;\n\nconst UCL_x = +(xbarBar + A2 * rBar).toFixed(4);          // 50.6924\nconst LCL_x = +(xbarBar - A2 * rBar).toFixed(4);          // 49.3076\nconst UWL_x = +(xbarBar + (2 / 3) * A2 * rBar).toFixed(4); // +2σ warning\nconst LWL_x = +(xbarBar - (2 / 3) * A2 * rBar).toFixed(4); // -2σ warning\nconst UCL_r = +(D4 * rBar).toFixed(4);                    // 2.538 (LCL_r=0 for n=5)\n\n// Shaft diameter sample means and ranges — CNC machining process, 25 subgroups of n=5\n// Samples 12 and 22 breach X-bar control limits; sample 13 breaches R UCL\nconst xbarData = [\n  49.82, 50.15, 49.97, 50.31, 49.65,\n  50.08, 50.24, 49.78, 50.43, 50.12,\n  49.88, 50.76, 49.71, 50.19, 49.95,\n  50.38, 49.56, 50.11, 49.83, 50.22,\n  50.64, 49.25, 50.18, 49.91, 50.03,\n];\nconst rData = [\n  0.92, 1.15, 1.08, 1.32, 0.87,\n  1.21, 0.95, 1.44, 1.18, 0.76,\n  1.35, 1.09, 2.61, 0.88, 1.22,\n  1.47, 1.03, 0.91, 1.28, 1.16,\n  1.08, 1.39, 0.84, 1.25, 1.10,\n];\nconst sampleNums = Array.from({ length: 25 }, (_, i) => i + 1);\n\n// Isolate out-of-control points for red scatter overlay\nconst xbarOOC = sampleNums\n  .map((s, i) => (xbarData[i] > UCL_x || xbarData[i] < LCL_x ? [s, xbarData[i]] : null))\n  .filter(Boolean);\nconst rOOC = sampleNums\n  .map((s, i) => (rData[i] > UCL_r ? [s, rData[i]] : null))\n  .filter(Boolean);\n\n// --- Init\nconst chart = echarts.init(document.getElementById(\"container\"));\n\nchart.setOption({\n  animation: false,\n  color: t.palette,\n  backgroundColor: \"transparent\",\n\n  title: [\n    {\n      text: \"spc-xbar-r · javascript · echarts · anyplot.ai\",\n      left: \"center\",\n      top: 16,\n      textStyle: { color: t.ink, fontSize: 22, fontWeight: \"bold\" },\n    },\n    {\n      text: \"X-bar Chart  —  Shaft Diameter (CNC Machining, n = 5)\",\n      left: 90,\n      top: 60,\n      textStyle: { color: t.ink, fontSize: 15, fontWeight: \"normal\" },\n    },\n    {\n      text: \"R Chart  —  Sample Range\",\n      left: 90,\n      top: \"50%\",\n      textStyle: { color: t.ink, fontSize: 15, fontWeight: \"normal\" },\n    },\n  ],\n\n  grid: [\n    { left: 90, right: 130, top: 92, bottom: \"52%\" },\n    { left: 90, right: 130, top: \"54%\", bottom: 62 },\n  ],\n\n  xAxis: [\n    {\n      gridIndex: 0,\n      type: \"category\",\n      data: sampleNums,\n      axisLabel: { show: false },\n      axisLine: { lineStyle: { color: t.inkSoft } },\n      axisTick: { show: false },\n      splitLine: { show: false },\n    },\n    {\n      gridIndex: 1,\n      type: \"category\",\n      data: sampleNums,\n      name: \"Sample Number\",\n      nameLocation: \"middle\",\n      nameGap: 38,\n      nameTextStyle: { color: t.inkSoft, fontSize: 14 },\n      axisLabel: { color: t.inkSoft, fontSize: 12 },\n      axisLine: { lineStyle: { color: t.inkSoft } },\n      axisTick: { show: false },\n      splitLine: { show: false },\n    },\n  ],\n\n  yAxis: [\n    {\n      gridIndex: 0,\n      type: \"value\",\n      name: \"Mean (mm)\",\n      nameLocation: \"middle\",\n      nameGap: 58,\n      nameTextStyle: { color: t.inkSoft, fontSize: 14 },\n      min: 49.0,\n      max: 51.0,\n      axisLabel: { color: t.inkSoft, fontSize: 12, formatter: (v) => v.toFixed(1) },\n      axisLine: { show: false },\n      axisTick: { show: false },\n      splitLine: { lineStyle: { color: t.grid } },\n    },\n    {\n      gridIndex: 1,\n      type: \"value\",\n      name: \"Range (mm)\",\n      nameLocation: \"middle\",\n      nameGap: 58,\n      nameTextStyle: { color: t.inkSoft, fontSize: 14 },\n      min: 0,\n      max: 3.0,\n      axisLabel: { color: t.inkSoft, fontSize: 12, formatter: (v) => v.toFixed(1) },\n      axisLine: { show: false },\n      axisTick: { show: false },\n      splitLine: { lineStyle: { color: t.grid } },\n    },\n  ],\n\n  series: [\n    // X-bar line with control limit markLines\n    {\n      name: \"X-bar\",\n      type: \"line\",\n      xAxisIndex: 0,\n      yAxisIndex: 0,\n      data: xbarData,\n      symbol: \"circle\",\n      symbolSize: 9,\n      lineStyle: { color: t.palette[0], width: 2.5 },\n      itemStyle: { color: t.palette[0] },\n      markLine: {\n        silent: true,\n        symbol: \"none\",\n        label: { show: true, position: \"end\", fontSize: 11 },\n        data: [\n          {\n            yAxis: UCL_x,\n            label: { formatter: `UCL=${UCL_x.toFixed(3)}`, color: t.palette[4], fontSize: 11 },\n            lineStyle: { color: t.palette[4], type: \"dashed\", width: 2 },\n          },\n          {\n            yAxis: LCL_x,\n            label: { formatter: `LCL=${LCL_x.toFixed(3)}`, color: t.palette[4], fontSize: 11 },\n            lineStyle: { color: t.palette[4], type: \"dashed\", width: 2 },\n          },\n          {\n            yAxis: xbarBar,\n            label: { formatter: `CL=${xbarBar.toFixed(3)}`, color: t.ink, fontSize: 11 },\n            lineStyle: { color: t.ink, type: \"solid\", width: 2 },\n          },\n          {\n            yAxis: UWL_x,\n            label: { formatter: \"+2σ\", color: t.palette[2], fontSize: 11 },\n            lineStyle: { color: t.palette[2], type: \"dashed\", width: 1.5, opacity: 0.55 },\n          },\n          {\n            yAxis: LWL_x,\n            label: { formatter: \"−2σ\", color: t.palette[2], fontSize: 11 },\n            lineStyle: { color: t.palette[2], type: \"dashed\", width: 1.5, opacity: 0.55 },\n          },\n        ],\n      },\n    },\n    // X-bar out-of-control points (red scatter overlay)\n    {\n      type: \"scatter\",\n      xAxisIndex: 0,\n      yAxisIndex: 0,\n      data: xbarOOC,\n      symbolSize: 14,\n      symbol: \"circle\",\n      itemStyle: { color: t.palette[4] },\n      z: 10,\n    },\n    // R chart line with control limit markLines\n    {\n      name: \"Range\",\n      type: \"line\",\n      xAxisIndex: 1,\n      yAxisIndex: 1,\n      data: rData,\n      symbol: \"circle\",\n      symbolSize: 9,\n      lineStyle: { color: t.palette[0], width: 2.5 },\n      itemStyle: { color: t.palette[0] },\n      markLine: {\n        silent: true,\n        symbol: \"none\",\n        label: { show: true, position: \"end\", fontSize: 11 },\n        data: [\n          {\n            yAxis: UCL_r,\n            label: { formatter: `UCL=${UCL_r.toFixed(3)}`, color: t.palette[4], fontSize: 11 },\n            lineStyle: { color: t.palette[4], type: \"dashed\", width: 2 },\n          },\n          {\n            yAxis: rBar,\n            label: { formatter: `CL=${rBar.toFixed(3)}`, color: t.ink, fontSize: 11 },\n            lineStyle: { color: t.ink, type: \"solid\", width: 2 },\n          },\n        ],\n      },\n    },\n    // R chart out-of-control points (red scatter overlay)\n    {\n      type: \"scatter\",\n      xAxisIndex: 1,\n      yAxisIndex: 1,\n      data: rOOC,\n      symbolSize: 14,\n      symbol: \"circle\",\n      itemStyle: { color: t.palette[4] },\n      z: 10,\n    },\n  ],\n});\n"}