{"spec_id":"line-timeseries","library":"echarts","language":"javascript","code":"// anyplot.ai\n// line-timeseries: Time Series Line Plot\n// Library: echarts 6.1.0 | JavaScript 22.23.2\n// Quality: 88/100 | Created: 2026-09-05\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Daily outdoor temperature readings over a full year — seasonal trend + noise,\n// generated with a fixed-seed LCG since the browser has no seeded RNG.\nlet seed = 42;\nfunction nextRandom() {\n  seed = (seed * 1664525 + 1013904223) % 4294967296;\n  return seed / 4294967296;\n}\n\nconst numDays = 365;\nconst startDate = new Date(\"2025-01-01T00:00:00Z\");\nconst data = [];\nlet peak = { date: null, value: -Infinity };\nlet trough = { date: null, value: Infinity };\nfor (let i = 0; i < numDays; i++) {\n  const date = new Date(startDate.getTime() + i * 86400000);\n  const isoDate = date.toISOString().slice(0, 10);\n  const seasonal = 12 + 10 * Math.sin((2 * Math.PI * i) / 365 - Math.PI / 2);\n  const noise = (nextRandom() - 0.5) * 4;\n  const value = Number((seasonal + noise).toFixed(1));\n  data.push([isoDate, value]);\n  if (value > peak.value) peak = { date: isoDate, value };\n  if (value < trough.value) trough = { date: isoDate, value };\n}\nconst average = Number(\n  (data.reduce((sum, [, v]) => sum + v, 0) / data.length).toFixed(1)\n);\n\n// --- Init ---------------------------------------------------------------------\nconst chart = echarts.init(document.getElementById(\"container\"));\n\n// --- Option ---------------------------------------------------------------------\nchart.setOption({\n  animation: false,\n  color: t.palette,\n  backgroundColor: \"transparent\",\n  title: {\n    text: \"Outdoor Temperature · line-timeseries · javascript · echarts · anyplot.ai\",\n    left: \"center\",\n    textStyle: { color: t.ink, fontSize: 20 },\n  },\n  grid: { left: 100, right: 70, top: 110, bottom: 90 },\n  dataZoom: [{ type: \"inside\" }],\n  xAxis: {\n    type: \"time\",\n    name: \"Date\",\n    nameLocation: \"middle\",\n    nameGap: 40,\n    nameTextStyle: { color: t.ink, fontSize: 16 },\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { lineStyle: { color: t.inkSoft } },\n    axisTick: { show: false },\n    splitLine: { show: true, lineStyle: { color: t.grid, opacity: 0.6 } },\n  },\n  yAxis: {\n    type: \"value\",\n    name: \"Temperature (°C)\",\n    nameTextStyle: { color: t.ink, fontSize: 16 },\n    nameGap: 55,\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { show: true, lineStyle: { color: t.inkSoft } },\n    axisTick: { show: false },\n    splitLine: { lineStyle: { color: t.grid, opacity: 0.6 } },\n  },\n  series: [\n    {\n      type: \"line\",\n      data,\n      showSymbol: false,\n      smooth: false,\n      lineStyle: { color: t.palette[0], width: 3 },\n      itemStyle: { color: t.palette[0] },\n      markPoint: {\n        symbol: \"circle\",\n        symbolSize: 10,\n        itemStyle: { color: t.palette[0] },\n        label: { color: t.ink, fontSize: 13, formatter: (p) => `${p.value}°C` },\n        data: [\n          { name: \"Peak\", coord: [peak.date, peak.value], value: peak.value },\n          {\n            name: \"Trough\",\n            coord: [trough.date, trough.value],\n            value: trough.value,\n            label: { position: \"right\", offset: [8, 0] },\n          },\n        ],\n      },\n      markLine: {\n        symbol: \"none\",\n        label: { color: t.inkSoft, fontSize: 13, formatter: `Avg ${average}°C` },\n        lineStyle: { color: t.inkSoft, type: \"dashed\" },\n        data: [{ yAxis: average }],\n      },\n    },\n  ],\n});\n"}