{"spec_id":"timeline-basic","library":"highcharts","language":"javascript","code":"// anyplot.ai\n// timeline-basic: Event Timeline\n// Library: highcharts 12.6.0 | JavaScript 22.23.2\n// Quality: 92/100 | Created: 2026-09-09\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ---------------------------------------\n// Software product roadmap for 2024, grouped by phase category.\nconst events = [\n  { date: Date.UTC(2024, 0, 15), name: \"Kickoff\", category: \"Planning\" },\n  { date: Date.UTC(2024, 1, 10), name: \"Requirements Finalized\", category: \"Planning\" },\n  { date: Date.UTC(2024, 2, 5), name: \"Design Review\", category: \"Planning\" },\n  { date: Date.UTC(2024, 2, 25), name: \"Alpha Build\", category: \"Development\" },\n  { date: Date.UTC(2024, 3, 20), name: \"Core Features Complete\", category: \"Development\" },\n  { date: Date.UTC(2024, 4, 15), name: \"Beta Release\", category: \"Development\" },\n  { date: Date.UTC(2024, 5, 10), name: \"User Testing Begins\", category: \"Development\" },\n  { date: Date.UTC(2024, 6, 8), name: \"Performance Optimization\", category: \"Development\" },\n  { date: Date.UTC(2024, 7, 1), name: \"Feature Freeze\", category: \"Development\" },\n  { date: Date.UTC(2024, 7, 25), name: \"Release Candidate\", category: \"Release\" },\n  { date: Date.UTC(2024, 8, 15), name: \"Marketing Launch\", category: \"Release\" },\n  { date: Date.UTC(2024, 9, 1), name: \"General Availability\", category: \"Release\" },\n  { date: Date.UTC(2024, 10, 5), name: \"Post-Launch Review\", category: \"Release\" },\n  { date: Date.UTC(2024, 11, 1), name: \"Version 1.1 Planning\", category: \"Planning\" },\n];\n\n// The two pivotal milestones get a larger, ink-outlined marker and a bolder\n// label so the timeline has a focal point instead of reading as 14 uniform dots.\nconst EMPHASIZED = new Set([\"Beta Release\", \"General Availability\"]);\n\n// Alternate marker/label sides in chronological order so neighboring events\n// never compete for the same vertical space, regardless of category. Markers\n// sit off the axis line (not on it) and a thin connector stem bridges the gap\n// so the timeline band uses the full canvas height instead of a thin strip.\nconst ABOVE = { markerY: 1.1, labelY: -16, verticalAlign: \"bottom\" };\nconst BELOW = { markerY: -1.1, labelY: 16, verticalAlign: \"top\" };\nevents.forEach((event, index) => {\n  event.side = index % 2 === 0 ? ABOVE : BELOW;\n});\n\n// Quarterly plot bands give the timeline a Highcharts-distinctive backdrop\n// (instead of a generic scatter+line) and fill the vertical whitespace with\n// intentional structure rather than empty margins.\nconst quarterBg = Highcharts.color(t.ink).setOpacity(0.05).get();\nconst plotBands = [\n  { from: Date.UTC(2024, 0, 1), to: Date.UTC(2024, 3, 1), label: \"Q1\" },\n  { from: Date.UTC(2024, 3, 1), to: Date.UTC(2024, 6, 1), label: \"Q2\" },\n  { from: Date.UTC(2024, 6, 1), to: Date.UTC(2024, 9, 1), label: \"Q3\" },\n  { from: Date.UTC(2024, 9, 1), to: Date.UTC(2024, 11, 31), label: \"Q4\" },\n].map((quarter, index) => ({\n  from: quarter.from,\n  to: quarter.to,\n  color: index % 2 === 0 ? quarterBg : \"transparent\",\n  label: {\n    text: quarter.label,\n    verticalAlign: \"top\",\n    align: \"left\",\n    x: 6,\n    y: 6,\n    style: { color: t.inkSoft, fontSize: \"12px\", fontWeight: \"600\" },\n  },\n}));\n\n// Thin stems connecting the axis to each marker — the visual weight that\n// fills the band instead of leaving markers floating in blank space.\nconst stems = events.map((event) => ({\n  type: \"line\",\n  data: [\n    [event.date, 0],\n    [event.date, event.side.markerY],\n  ],\n  color: t.inkSoft,\n  opacity: 0.5,\n  lineWidth: 1,\n  marker: { enabled: false },\n  enableMouseTracking: false,\n  showInLegend: false,\n  dataLabels: { enabled: false },\n}));\n\nconst categories = [\"Planning\", \"Development\", \"Release\"];\nconst categoryColors = { Planning: t.palette[0], Development: t.palette[1], Release: t.palette[2] };\nconst series = categories.map((category) => ({\n  name: category,\n  type: \"scatter\",\n  color: categoryColors[category],\n  marker: { radius: 8, lineColor: t.pageBg, lineWidth: 2 },\n  data: events\n    .filter((event) => event.category === category)\n    .map((event) => ({\n      x: event.date,\n      y: event.side.markerY,\n      name: event.name,\n      marker: EMPHASIZED.has(event.name)\n        ? { radius: 15, lineColor: t.ink, lineWidth: 3 }\n        : undefined,\n      dataLabels: {\n        y: event.side.labelY,\n        verticalAlign: event.side.verticalAlign,\n        style: EMPHASIZED.has(event.name) ? { fontSize: \"16px\", fontWeight: \"700\" } : undefined,\n      },\n    })),\n  dataLabels: {\n    enabled: true,\n    format: \"{point.name}\",\n    align: \"center\",\n    style: { color: t.ink, fontSize: \"14px\", fontWeight: \"600\", textOutline: \"none\" },\n  },\n}));\n\n// --- Chart -----------------------------------------------------------------\nHighcharts.chart(\"container\", {\n  chart: { type: \"scatter\", backgroundColor: \"transparent\", animation: false,\n           style: { fontFamily: \"inherit\" } },\n  credits: { enabled: false },\n  colors: t.palette,\n  title: { text: \"timeline-basic · javascript · highcharts · anyplot.ai\",\n           style: { color: t.ink, fontSize: \"22px\", fontWeight: \"600\" } },\n  subtitle: { text: \"Software Product Roadmap 2024\",\n              style: { color: t.inkSoft, fontSize: \"14px\" } },\n  xAxis: {\n    type: \"datetime\",\n    min: Date.UTC(2024, 0, 1),\n    max: Date.UTC(2024, 11, 31),\n    lineColor: t.inkSoft,\n    tickColor: t.inkSoft,\n    gridLineWidth: 0,\n    dateTimeLabelFormats: { month: \"%b\" },\n    labels: { style: { color: t.inkSoft, fontSize: \"14px\" } },\n    plotBands,\n  },\n  yAxis: {\n    visible: false,\n    min: -1.75,\n    max: 1.75,\n  },\n  legend: {\n    align: \"center\",\n    verticalAlign: \"bottom\",\n    itemStyle: { color: t.inkSoft, fontSize: \"14px\" },\n    itemHoverStyle: { color: t.ink },\n  },\n  tooltip: {\n    formatter() {\n      return `<b>${this.point.name}</b><br>${Highcharts.dateFormat(\"%b %e, %Y\", this.point.x)}`;\n    },\n  },\n  plotOptions: { series: { animation: false } },\n  series: [\n    {\n      name: \"Timeline\",\n      type: \"line\",\n      data: [\n        [Date.UTC(2024, 0, 1), 0],\n        [Date.UTC(2024, 11, 31), 0],\n      ],\n      color: t.inkSoft,\n      lineWidth: 2,\n      marker: { enabled: false },\n      enableMouseTracking: false,\n      showInLegend: false,\n      dataLabels: { enabled: false },\n    },\n    ...stems,\n    ...series,\n  ],\n});\n"}