{"spec_id":"dashboard-metrics-tiles","library":"highcharts","language":"javascript","code":"// anyplot.ai\n// dashboard-metrics-tiles: Real-Time Dashboard Tiles\n// Library: highcharts 12.6.0 | JavaScript 22.23.2\n// Quality: 91/100 | Created: 2026-09-02\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic LCG — no seeded RNG in the browser) ----\nfunction lcg(seed) {\n  let s = seed;\n  return () => {\n    s = (s * 1664525 + 1013904223) % 4294967296;\n    return s / 4294967296;\n  };\n}\n\nfunction history(seed, n, base, trend, noiseFrac) {\n  const rand = lcg(seed);\n  const values = [];\n  let v = base;\n  for (let i = 0; i < n; i++) {\n    v += trend + (rand() - 0.5) * base * noiseFrac;\n    values.push(Math.max(0, Math.round(v * 100) / 100));\n  }\n  return values;\n}\n\nconst STATUS_COLOR = { good: t.palette[0], warning: t.amber, critical: t.palette[4] };\nconst STATUS_GLYPH = { good: \"✓\", warning: \"!\", critical: \"✕\" };\n\nfunction mean(values) {\n  return values.reduce((sum, v) => sum + v, 0) / values.length;\n}\n\nconst tiles = [\n  {\n    label: \"CPU Usage\",\n    value: \"45%\",\n    changePercent: -5.2,\n    favorableDirection: \"down\",\n    status: \"good\",\n    history: history(1, 24, 50, -0.22, 0.05),\n  },\n  {\n    label: \"Memory Usage\",\n    value: \"72%\",\n    changePercent: 8.1,\n    favorableDirection: \"down\",\n    status: \"warning\",\n    history: history(2, 24, 63, 0.36, 0.04),\n  },\n  {\n    label: \"Response Time\",\n    value: \"120 ms\",\n    changePercent: -15.4,\n    favorableDirection: \"down\",\n    status: \"good\",\n    history: history(3, 24, 148, -1.1, 0.06),\n  },\n  {\n    label: \"Error Rate\",\n    value: \"2.3%\",\n    changePercent: 24.0,\n    favorableDirection: \"down\",\n    status: \"critical\",\n    history: history(4, 24, 1.6, 0.028, 0.18),\n  },\n  {\n    label: \"Active Users\",\n    value: \"8,412\",\n    changePercent: 12.3,\n    favorableDirection: \"up\",\n    status: \"good\",\n    history: history(5, 24, 7180, 55, 0.03),\n  },\n  {\n    label: \"Throughput\",\n    value: \"340 MB/s\",\n    changePercent: 6.7,\n    favorableDirection: \"up\",\n    status: \"good\",\n    history: history(6, 24, 305, 1.6, 0.05),\n  },\n];\n\n// --- Layout (dashboard grid built as DOM, sparklines rendered by Highcharts) --\nconst root = document.getElementById(\"container\");\n\nconst header = document.createElement(\"div\");\nheader.style.cssText = `padding:22px 28px 4px; font-size:22px; font-weight:600; color:${t.ink}; font-family:inherit;`;\nheader.textContent = \"dashboard-metrics-tiles · javascript · highcharts · anyplot.ai\";\nroot.appendChild(header);\n\nconst grid = document.createElement(\"div\");\ngrid.style.cssText =\n  \"display:grid; grid-template-columns:repeat(3, 1fr); grid-template-rows:repeat(2, 1fr); \" +\n  \"gap:22px; margin:14px 28px 28px; height:calc(100% - 90px);\";\nroot.appendChild(grid);\n\ntiles.forEach((tile, index) => {\n  const statusColor = STATUS_COLOR[tile.status];\n  const isFavorable =\n    (tile.favorableDirection === \"down\" && tile.changePercent < 0) ||\n    (tile.favorableDirection === \"up\" && tile.changePercent > 0);\n  const changeColor = isFavorable ? t.palette[0] : t.palette[4];\n  const arrow = tile.changePercent >= 0 ? \"▲\" : \"▼\";\n\n  const card = document.createElement(\"div\");\n  card.style.cssText = `background:${t.elevatedBg}; border-radius:14px; padding:22px 26px; display:flex; flex-direction:column; justify-content:flex-start;`;\n\n  const headerRow = document.createElement(\"div\");\n  headerRow.style.cssText = \"display:flex; align-items:center; justify-content:space-between;\";\n  const labelEl = document.createElement(\"span\");\n  labelEl.textContent = tile.label;\n  labelEl.style.cssText = `font-size:15px; font-weight:500; color:${t.inkSoft}; letter-spacing:0.02em;`;\n  const dotEl = document.createElement(\"span\");\n  dotEl.textContent = STATUS_GLYPH[tile.status];\n  dotEl.title = tile.status;\n  dotEl.style.cssText = `width:16px; height:16px; border-radius:50%; background:${statusColor}; display:inline-flex; align-items:center; justify-content:center; font-size:10px; font-weight:700; line-height:1; color:#FFFFFF;`;\n  headerRow.appendChild(labelEl);\n  headerRow.appendChild(dotEl);\n\n  const valueRow = document.createElement(\"div\");\n  valueRow.style.cssText = \"display:flex; align-items:baseline; gap:14px; margin-top:8px;\";\n  const valueEl = document.createElement(\"span\");\n  valueEl.textContent = tile.value;\n  valueEl.style.cssText = `font-size:46px; font-weight:700; color:${t.ink}; line-height:1;`;\n  const changeEl = document.createElement(\"span\");\n  changeEl.textContent = `${arrow} ${Math.abs(tile.changePercent).toFixed(1)}%`;\n  changeEl.style.cssText = `font-size:17px; font-weight:600; color:${changeColor};`;\n  valueRow.appendChild(valueEl);\n  valueRow.appendChild(changeEl);\n\n  const sparkEl = document.createElement(\"div\");\n  sparkEl.id = `spark-${index}`;\n  sparkEl.style.cssText = \"flex:1; min-height:64px; margin-top:8px;\";\n\n  card.appendChild(headerRow);\n  card.appendChild(valueRow);\n  card.appendChild(sparkEl);\n  grid.appendChild(card);\n});\n\n// --- Sparkline charts (one Highcharts instance per tile, mounted after the DOM\n//     nodes above are attached so Highcharts can measure each mount's size) ----\ntiles.forEach((tile, index) => {\n  const statusColor = STATUS_COLOR[tile.status];\n  const baseline = mean(tile.history);\n  Highcharts.chart(`spark-${index}`, {\n    chart: {\n      type: \"area\",\n      backgroundColor: \"transparent\",\n      animation: false,\n      margin: [4, 2, 4, 2],\n    },\n    credits: { enabled: false },\n    title: { text: null },\n    xAxis: { visible: false },\n    // Distinctive Highcharts touch: a dashed baseline plotLine (period mean)\n    // showing trend-vs-baseline context, not just the raw sparkline. `visible`\n    // must stay true (default) — Highcharts only wires up plotLines during\n    // Axis#render(), which the chart skips entirely for axes marked\n    // visible:false — so the chrome is stripped by hand instead.\n    yAxis: {\n      lineWidth: 0,\n      gridLineWidth: 0,\n      tickLength: 0,\n      labels: { enabled: false },\n      title: { text: null },\n      plotLines: [\n        {\n          value: baseline,\n          color: t.inkSoft,\n          width: 1,\n          dashStyle: \"Dash\",\n          zIndex: 3,\n        },\n      ],\n    },\n    legend: { enabled: false },\n    tooltip: { enabled: false },\n    plotOptions: {\n      series: {\n        animation: false,\n        enableMouseTracking: false,\n        marker: { enabled: false },\n        lineWidth: 2.5,\n      },\n      area: { fillOpacity: 0.16 },\n    },\n    series: [{ data: tile.history, color: statusColor }],\n  });\n});\n"}