{"spec_id":"arc-basic","library":"highcharts","language":"javascript","code":"// anyplot.ai\n// arc-basic: Basic Arc Diagram\n// Library: highcharts 12.6.0 | JavaScript 22.23.2\n// Quality: 89/100 | Created: 2026-08-24\n//# anyplot-orientation: landscape\n// anyplot.ai\n// arc-basic: Basic Arc Diagram\n// Library: Highcharts 12.6.0 | Node 22\n// License: Highcharts — commercial license, free for non-commercial use (highcharts.com/license)\n// Quality: pending | Created: 2026-08-24\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\nconst stages = [\n  \"Checkout\", \"Lint\", \"UnitTest\", \"Build\", \"IntegrationTest\", \"SecurityScan\",\n  \"PackageArtifact\", \"PublishRegistry\", \"DeployStaging\", \"SmokeTest\",\n  \"LoadTest\", \"ApproveGate\", \"DeployProd\", \"Monitor\",\n];\n\n// [fromIndex, toIndex, couplingStrength]\nconst dependencies = [\n  [0, 1, 4], [0, 2, 5], [0, 3, 7], [0, 13, 2],\n  [1, 3, 3], [2, 3, 6], [2, 4, 5],\n  [3, 4, 8], [3, 6, 6], [3, 13, 2],\n  [4, 5, 4], [4, 9, 3],\n  [5, 6, 3], [5, 8, 2],\n  [6, 7, 9], [6, 8, 5],\n  [7, 8, 7],\n  [8, 9, 8], [8, 10, 4],\n  [9, 11, 6], [10, 11, 5],\n  [11, 12, 9],\n  [12, 13, 7],\n];\n\nconst nodeCount = stages.length;\nconst maxDistance = nodeCount - 1;\nconst maxWeight = Math.max(...dependencies.map((d) => d[2]));\n\n// --- Chart -------------------------------------------------------------------\nHighcharts.chart(\"container\", {\n  chart: {\n    type: \"scatter\",\n    backgroundColor: \"transparent\",\n    animation: false,\n    style: { fontFamily: \"inherit\" },\n    marginTop: 70,\n    marginBottom: 150,\n    marginLeft: 40,\n    marginRight: 40,\n    events: {\n      render() {\n        const chart = this;\n        if (chart.arcGroup) chart.arcGroup.destroy();\n        const arcGroup = chart.renderer.g(\"arc-diagram\").add();\n        chart.arcGroup = arcGroup;\n\n        const xAxis = chart.xAxis[0];\n        const baseY = chart.plotTop + chart.plotHeight;\n        const maxHeight = chart.plotHeight * 0.96;\n\n        dependencies.forEach(([from, to, weight]) => {\n          const x1 = xAxis.toPixels(from);\n          const x2 = xAxis.toPixels(to);\n          const distance = Math.abs(from - to);\n          const arcHeight = Math.sqrt(distance / maxDistance) * maxHeight;\n          const midX = (x1 + x2) / 2;\n          const controlY = baseY - arcHeight;\n          const strokeWidth = 1.5 + (weight / maxWeight) * 4.5;\n          const opacity = 0.38 + (weight / maxWeight) * 0.32;\n\n          chart.renderer\n            .path([\"M\", x1, baseY, \"Q\", midX, controlY, x2, baseY])\n            .attr({\n              stroke: t.palette[0],\n              \"stroke-width\": strokeWidth,\n              fill: \"none\",\n              opacity,\n            })\n            .add(arcGroup);\n        });\n      },\n    },\n  },\n  credits: { enabled: false },\n  title: {\n    text: \"arc-basic · javascript · highcharts · anyplot.ai\",\n    style: { color: t.ink, fontSize: \"22px\", fontWeight: \"600\" },\n    margin: 40,\n  },\n  subtitle: {\n    text: \"CI/CD pipeline dependencies — arc height = stage distance, thickness/opacity = coupling strength\",\n    style: { color: t.inkSoft, fontSize: \"14px\" },\n  },\n  xAxis: {\n    min: -0.5,\n    max: nodeCount - 0.5,\n    lineWidth: 0,\n    tickLength: 0,\n    gridLineWidth: 0,\n    labels: { enabled: false },\n    title: { text: null },\n  },\n  yAxis: {\n    min: 0,\n    max: 1,\n    gridLineWidth: 0,\n    lineWidth: 0,\n    tickLength: 0,\n    labels: { enabled: false },\n    title: { text: null },\n  },\n  legend: { enabled: false },\n  tooltip: { enabled: false },\n  plotOptions: {\n    series: { animation: false },\n    scatter: {\n      dataLabels: {\n        enabled: true,\n        format: \"{point.name}\",\n        rotation: -55,\n        align: \"right\",\n        verticalAlign: \"top\",\n        crop: false,\n        overflow: \"allow\",\n        y: 14,\n        x: -2,\n        style: {\n          color: t.inkSoft,\n          fontSize: \"14px\",\n          fontWeight: \"400\",\n          textOutline: \"none\",\n        },\n      },\n    },\n  },\n  series: [\n    {\n      name: \"Pipeline stages\",\n      data: stages.map((name, i) => ({ x: i, y: 0, name })),\n      marker: {\n        radius: 7,\n        fillColor: t.ink,\n        lineColor: t.pageBg,\n        lineWidth: 1.5,\n      },\n    },\n  ],\n});\n"}