{"spec_id":"line-timeseries-rolling","library":"echarts","language":"javascript","code":"// anyplot.ai\n// line-timeseries-rolling: Time Series with Rolling Average Overlay\n// Library: echarts 6.1.0 | JavaScript 22.23.2\n// Quality: 92/100 | Created: 2026-09-05\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic fixed-seed LCG) -------------------------\n// Hourly outdoor temperature readings over 10 days with a 24-hour rolling mean.\nlet seed = 42;\nfunction lcgRandom() {\n  seed = (seed * 1103515245 + 12345) & 0x7fffffff;\n  return seed / 0x7fffffff;\n}\n\nconst HOURS = 240;\nconst WINDOW = 24;\nconst startDate = new Date(\"2024-06-01T00:00:00Z\");\n\nconst times = [];\nconst temperatures = [];\nfor (let i = 0; i < HOURS; i++) {\n  times.push(new Date(startDate.getTime() + i * 3600 * 1000));\n  const dailyCycle = 6 * Math.sin(((i % 24) / 24) * 2 * Math.PI - Math.PI / 2);\n  const seasonalDrift = 3 * Math.sin((i / HOURS) * Math.PI);\n  const noise = (lcgRandom() - 0.5) * 4;\n  temperatures.push(18 + dailyCycle + seasonalDrift + noise);\n}\n\nconst rawSeries = times.map((ts, i) => [ts, temperatures[i]]);\nconst rollingSeries = times.map((ts, i) => {\n  if (i < WINDOW - 1) return [ts, null];\n  let sum = 0;\n  for (let j = i - WINDOW + 1; j <= i; j++) sum += temperatures[j];\n  return [ts, sum / WINDOW];\n});\n\n// --- Init ---------------------------------------------------------------\nconst chart = echarts.init(document.getElementById(\"container\"));\n\n// --- Option ---------------------------------------------------------------\nchart.setOption({\n  animation: false,\n  color: [t.palette[0], t.palette[1]],\n  backgroundColor: \"transparent\",\n  title: {\n    text: \"line-timeseries-rolling · javascript · echarts · anyplot.ai\",\n    left: \"center\",\n    textStyle: { color: t.ink, fontSize: 22, fontWeight: 500 },\n  },\n  grid: { left: 90, right: 60, top: 100, bottom: 160 },\n  legend: {\n    data: [\"Raw Data\", \"24-Hour Rolling Average\"],\n    bottom: 15,\n    textStyle: { color: t.inkSoft, fontSize: 16 },\n    itemWidth: 24,\n    itemHeight: 3,\n  },\n  tooltip: { trigger: \"axis\" },\n  dataZoom: [\n    { type: \"inside\", xAxisIndex: 0 },\n    {\n      type: \"slider\",\n      xAxisIndex: 0,\n      bottom: 60,\n      height: 20,\n      borderColor: t.grid,\n      fillerColor: `${t.palette[0]}33`,\n      handleStyle: { color: t.palette[0] },\n      textStyle: { color: t.inkSoft, fontSize: 12 },\n      dataBackground: {\n        lineStyle: { color: t.inkSoft },\n        areaStyle: { color: t.grid },\n      },\n    },\n  ],\n  xAxis: {\n    type: \"time\",\n    name: \"Date / Hour (UTC)\",\n    nameLocation: \"middle\",\n    nameGap: 32,\n    nameTextStyle: { color: t.ink, fontSize: 16 },\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { lineStyle: { color: t.inkSoft } },\n    splitLine: { show: true, lineStyle: { color: t.grid } },\n  },\n  yAxis: {\n    type: \"value\",\n    scale: true,\n    name: \"Temperature (°C)\",\n    nameLocation: \"middle\",\n    nameGap: 60,\n    nameTextStyle: { color: t.ink, fontSize: 16 },\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { show: true, lineStyle: { color: t.inkSoft } },\n    splitLine: { lineStyle: { color: t.grid } },\n  },\n  series: [\n    {\n      name: \"Raw Data\",\n      type: \"line\",\n      data: rawSeries,\n      showSymbol: false,\n      lineStyle: { width: 1.5, color: t.palette[0], opacity: 0.35 },\n      z: 1,\n    },\n    {\n      name: \"24-Hour Rolling Average\",\n      type: \"line\",\n      data: rollingSeries,\n      showSymbol: false,\n      lineStyle: { width: 3.5, color: t.palette[1] },\n      z: 2,\n    },\n  ],\n});\n"}