{"spec_id":"point-basic","library":"echarts","language":"javascript","code":"// anyplot.ai\n// point-basic: Point Estimate Plot\n// Library: echarts 6.1.0 | JavaScript 22.23.2\n// Quality: 95/100 | Created: 2026-09-05\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Average test-score improvement (points) attributed to eight tutoring\n// programs, each with a 95% confidence interval from a randomized evaluation.\nconst rawPrograms = [\n  \"Test Prep Course\",\n  \"Group Workshops\",\n  \"Homework Support\",\n  \"Online Modules\",\n  \"Peer Tutoring\",\n  \"After-School Program\",\n  \"Summer Intensive\",\n  \"1-on-1 Coaching\",\n];\nconst rawEstimate = [6.0, 3.1, 2.4, 1.5, 4.2, 5.8, 7.2, 8.6];\nconst rawLowerBound = [4.8, 1.2, 0.6, -0.3, 2.8, 4.5, 5.9, 7.1];\nconst rawUpperBound = [7.2, 5.0, 4.2, 3.3, 5.6, 7.1, 8.5, 10.1];\n\n// Rank by estimate (descending) so the strongest program reads first from the top.\nconst order = rawPrograms.map((_, i) => i).sort((a, b) => rawEstimate[b] - rawEstimate[a]);\nconst programs = order.map((i) => rawPrograms[i]);\nconst estimate = order.map((i) => rawEstimate[i]);\nconst lowerBound = order.map((i) => rawLowerBound[i]);\nconst upperBound = order.map((i) => rawUpperBound[i]);\n\nconst rows = programs.map((_, i) => [i, lowerBound[i], upperBound[i]]);\nconst points = programs.map((_, i) => [estimate[i], i]);\n\n// --- Custom renderer: error bar with caps -----------------------------------\nfunction renderErrorBar(params, api) {\n  const categoryIndex = api.value(0);\n  const lowPt = api.coord([api.value(1), categoryIndex]);\n  const highPt = api.coord([api.value(2), categoryIndex]);\n  const capHalf = 10;\n  const style = { stroke: t.inkSoft, lineWidth: 2.5 };\n  return {\n    type: \"group\",\n    children: [\n      { type: \"line\", shape: { x1: lowPt[0], y1: lowPt[1], x2: highPt[0], y2: highPt[1] }, style },\n      { type: \"line\", shape: { x1: lowPt[0], y1: lowPt[1] - capHalf, x2: lowPt[0], y2: lowPt[1] + capHalf }, style },\n      { type: \"line\", shape: { x1: highPt[0], y1: highPt[1] - capHalf, x2: highPt[0], y2: highPt[1] + capHalf }, style },\n    ],\n  };\n}\n\n// --- Init --------------------------------------------------------------------\nconst chart = echarts.init(document.getElementById(\"container\"));\n\n// --- Option --------------------------------------------------------------------\nchart.setOption({\n  animation: false,\n  backgroundColor: \"transparent\",\n  title: {\n    text: \"point-basic · javascript · echarts · anyplot.ai\",\n    left: \"center\",\n    textStyle: { color: t.ink, fontSize: 22 },\n  },\n  grid: { left: 260, right: 80, top: 110, bottom: 90 },\n  xAxis: {\n    type: \"value\",\n    name: \"Score Improvement (points)\",\n    nameLocation: \"middle\",\n    nameGap: 40,\n    nameTextStyle: { color: t.inkSoft, fontSize: 14 },\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { lineStyle: { color: t.inkSoft } },\n    splitLine: { lineStyle: { color: t.grid } },\n  },\n  yAxis: {\n    type: \"category\",\n    data: programs,\n    inverse: true,\n    axisLabel: {\n      color: t.inkSoft,\n      fontSize: 14,\n      // Emphasize the top-ranked program to give the sorted list a clear focal point.\n      formatter: (value, index) => (index === 0 ? `{focal|${value}}` : value),\n      rich: { focal: { color: t.ink, fontWeight: 700 } },\n    },\n    axisLine: { show: false },\n    axisTick: { show: false },\n    splitLine: { show: false },\n  },\n  series: [\n    {\n      type: \"custom\",\n      renderItem: renderErrorBar,\n      encode: { x: [1, 2], y: 0 },\n      data: rows,\n      clip: true,\n      z: 2,\n    },\n    {\n      type: \"scatter\",\n      data: points,\n      symbolSize: 18,\n      itemStyle: { color: t.palette[0] },\n      z: 3,\n      markLine: {\n        silent: true,\n        symbol: \"none\",\n        lineStyle: { color: t.inkSoft, type: \"dashed\", width: 1.5 },\n        label: { show: false },\n        data: [{ xAxis: 0 }],\n      },\n    },\n  ],\n});\n"}