Line chart
Responsive line chart with a CSS-only renderer.
- Browsers
- Chrome 123+, Firefox 121+, Safari 17.5+
- Tier
- 0
- Forced layout budget
- 0 ms
- Axe budget
- 0
- SSR compatible
- Yes
- Published contract
- Test harness
Playground
Line chart
48 weekly values with CSS geometry, automatic axes, and an optional interactive client entry.
CSS-only chart
- Jan 25
- Feb 25
- Mar 25
- Apr 25
- May 25
- Jun 25
- Jul 25
- Aug 25
- Sep 25
- Oct 25
- Nov 25
- 159.9
- 145.72
- 131.54
- 117.36
- 103.18
- 89
| Time | Value |
|---|---|
| 2025-01-01 | 89 |
| 2025-01-08 | 92.3 |
| 2025-01-15 | 95.5 |
| 2025-01-22 | 98.3 |
| 2025-01-29 | 100.6 |
| 2025-02-05 | 102.4 |
| 2025-02-12 | 103.5 |
| 2025-02-19 | 104.1 |
| 2025-02-26 | 104.1 |
| 2025-03-05 | 103.7 |
| 2025-03-12 | 102.9 |
| 2025-03-19 | 102 |
| 2025-03-26 | 101 |
| 2025-04-02 | 100.2 |
| 2025-04-09 | 99.8 |
| 2025-04-16 | 99.7 |
| 2025-04-23 | 100.2 |
| 2025-04-30 | 101.3 |
| 2025-05-07 | 103 |
| 2025-05-14 | 105.2 |
| 2025-05-21 | 107.8 |
| 2025-05-28 | 110.8 |
| 2025-06-04 | 114 |
| 2025-06-11 | 117.3 |
| 2025-06-18 | 120.4 |
| 2025-06-25 | 123.3 |
| 2025-07-02 | 125.8 |
| 2025-07-09 | 127.8 |
| 2025-07-16 | 129.3 |
| 2025-07-23 | 130.3 |
| 2025-07-30 | 130.8 |
| 2025-08-06 | 130.9 |
| 2025-08-13 | 130.8 |
| 2025-08-20 | 130.5 |
| 2025-08-27 | 130.3 |
| 2025-09-03 | 130.2 |
| 2025-09-10 | 130.5 |
| 2025-09-17 | 131.2 |
| 2025-09-24 | 132.4 |
| 2025-10-01 | 134.2 |
| 2025-10-08 | 136.5 |
| 2025-10-15 | 139.3 |
| 2025-10-22 | 142.6 |
| 2025-10-29 | 146.1 |
| 2025-11-05 | 149.8 |
| 2025-11-12 | 153.4 |
| 2025-11-19 | 156.8 |
| 2025-11-26 | 159.9 |
Interactive chart
2025-11-26159.9
- Jan 25
- Feb 25
- Mar 25
- Apr 25
- May 25
- Jun 25
- Jul 25
- Aug 25
- Sep 25
- Oct 25
- Nov 25
- 159.9
- 145.72
- 131.54
- 117.36
- 103.18
- 89
| Time | Value |
|---|---|
| 2025-01-01 | 89 |
| 2025-01-08 | 92.3 |
| 2025-01-15 | 95.5 |
| 2025-01-22 | 98.3 |
| 2025-01-29 | 100.6 |
| 2025-02-05 | 102.4 |
| 2025-02-12 | 103.5 |
| 2025-02-19 | 104.1 |
| 2025-02-26 | 104.1 |
| 2025-03-05 | 103.7 |
| 2025-03-12 | 102.9 |
| 2025-03-19 | 102 |
| 2025-03-26 | 101 |
| 2025-04-02 | 100.2 |
| 2025-04-09 | 99.8 |
| 2025-04-16 | 99.7 |
| 2025-04-23 | 100.2 |
| 2025-04-30 | 101.3 |
| 2025-05-07 | 103 |
| 2025-05-14 | 105.2 |
| 2025-05-21 | 107.8 |
| 2025-05-28 | 110.8 |
| 2025-06-04 | 114 |
| 2025-06-11 | 117.3 |
| 2025-06-18 | 120.4 |
| 2025-06-25 | 123.3 |
| 2025-07-02 | 125.8 |
| 2025-07-09 | 127.8 |
| 2025-07-16 | 129.3 |
| 2025-07-23 | 130.3 |
| 2025-07-30 | 130.8 |
| 2025-08-06 | 130.9 |
| 2025-08-13 | 130.8 |
| 2025-08-20 | 130.5 |
| 2025-08-27 | 130.3 |
| 2025-09-03 | 130.2 |
| 2025-09-10 | 130.5 |
| 2025-09-17 | 131.2 |
| 2025-09-24 | 132.4 |
| 2025-10-01 | 134.2 |
| 2025-10-08 | 136.5 |
| 2025-10-15 | 139.3 |
| 2025-10-22 | 142.6 |
| 2025-10-29 | 146.1 |
| 2025-11-05 | 149.8 |
| 2025-11-12 | 153.4 |
| 2025-11-19 | 156.8 |
| 2025-11-26 | 159.9 |
Live stream
A simulated trade feed appends one finished one-minute close every second; existing points never move. Every point lives in a horizontal VirtualScroll sized to show 20 at a time: scroll back through the history, and the chart follows new points again once you return to the newest one.
10:293152.46
- 10:05
- 10:10
- 10:15
- 10:20
- 10:25
- 3,166.96
- 3,161.74
- 3,156.52
- 3,151.31
- 3,146.09
- 3,140.87
| Time | Value |
|---|---|
| 10:10 | 3166.96 |
| 10:11 | 3160.48 |
| 10:12 | 3154.88 |
| 10:13 | 3151.27 |
| 10:14 | 3156.95 |
| 10:15 | 3156.64 |
| 10:16 | 3153.31 |
| 10:17 | 3151.54 |
| 10:18 | 3148.18 |
| 10:19 | 3146.15 |
| 10:20 | 3144.78 |
| 10:21 | 3145.29 |
| 10:22 | 3143.28 |
| 10:23 | 3146.33 |
| 10:24 | 3142.35 |
| 10:25 | 3140.87 |
| 10:26 | 3149.75 |
| 10:27 | 3152.42 |
| 10:28 | 3154.24 |
| 10:29 | 3152.46 |
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
import { useEffect, useState } from "react";
import { LineChart } from "@gunkin/uiify";
import { LineChartClient } from "@gunkin/uiify/components/line-chart/client";
const data = Array.from({ length: 48 }, (_, index) => ({
time: new Date(Date.UTC(2025, 0, 1 + index * 7)).toISOString().slice(0, 10),
value: Math.round((86 + index * 1.4 + Math.sin(index / 3.5) * 7) * 10) / 10,
}));
export default function Example() {
return (
<>
<LineChart className="" data={data} aria-label="Weekly revenue" />
<LineChartClient className="" data={data} aria-label="Interactive weekly revenue" />
<LiveChart />
</>
);
}
function LiveChart() {
const [points, setPoints] = useState(data);
const [running, setRunning] = useState(false);
useEffect(() => {
if (!running) return;
const timer = setInterval(() => {
setPoints((current) => {
const last = current.at(-1);
if (!last) return current;
const value = Math.round(last.value * (1 + (Math.random() - 0.5) * 0.02) * 10) / 10;
return [...current, { time: String(current.length), value }];
});
}, 1000);
return () => clearInterval(timer);
}, [running]);
return (
<>
<button type="button" onClick={() => setRunning((value) => !value)}>
{running ? "Stop" : "Start"}
</button>
{/* All points, virtualized; 20 fit the viewport and new ones stay in view at the end. */}
<LineChartClient className="" data={points} visibleCount={20} aria-label="Live revenue" />
</>
);
}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
@property --line-y {
syntax: "<percentage>";
inherits: true;
initial-value: 50%;
}
@property --line-prev-y {
syntax: "<percentage>";
inherits: true;
initial-value: 50%;
}
@property --line-count {
syntax: "<integer>";
inherits: false;
initial-value: 1;
}
@property --line-scale {
syntax: "<number>";
inherits: true;
initial-value: 1;
}
@layer components {
[data-uiify-line-chart] {
--line-grid: color-mix(in srgb, currentcolor 10%, transparent);
--line-up: oklch(67% 0.14 166deg);
--line-down: oklch(64% 0.21 24deg);
--line-flat: light-dark(oklch(43% 0.05 165deg), oklch(72% 0.04 165deg));
--line-axis: light-dark(
color-mix(in oklch, var(--muted-foreground) 70%, var(--foreground)),
var(--muted-foreground)
);
--line-width: 0.12rem;
position: relative;
display: block;
inline-size: 100%;
min-block-size: 21rem;
padding: 1rem 0.75rem 0.5rem;
overflow: clip;
overscroll-behavior: none;
isolation: isolate;
/* No color-scheme declaration: it inherits, so light-dark() colors and the
live scrollbar follow the page theme. An explicit `inherit` is rewritten
to `normal` by Lightning CSS in consumer bundlers such as Next. */
background: transparent;
color: light-dark(oklch(28% 0.04 165deg), oklch(82% 0.04 165deg));
}
/* Interactive charts own touch and horizontal wheel gestures (crosshair,
zoom, native scroll); a static chart leaves page scrolling alone. */
[data-uiify-line-chart][data-interactive] {
touch-action: none;
}
[data-uiify-line-chart][data-interactive] [data-part="scroll-viewport"] {
overscroll-behavior-inline: none;
}
/* The time-axis row also reserves the horizontal scrollbar, measured by the
client entry (0 for overlay scrollbars and static charts), so the flexible
candle row does not absorb it and stays aligned with the value axis. */
[data-uiify-line-chart] > [data-part="plot"] {
position: relative;
display: grid;
grid-template-columns: minmax(0, 1fr) 4.5rem;
grid-template-rows: minmax(18rem, 1fr) calc(1.5rem + var(--line-scrollbar-size, 0px));
gap: 0 0.75rem;
min-inline-size: 0;
min-block-size: 18rem;
overscroll-behavior: none;
}
[data-uiify-line-chart] [data-part="scroll-viewport"] {
grid-column: 1;
grid-row: 1 / span 2;
min-inline-size: 0;
min-block-size: 18rem;
overflow: auto hidden;
container-type: inline-size;
direction: rtl;
}
[data-uiify-line-chart] [data-part="canvas"] {
display: grid;
grid-template-rows: minmax(18rem, 1fr) 1.5rem;
inline-size: calc(100% * var(--line-scale));
min-inline-size: 100%;
min-block-size: 100%;
direction: ltr;
}
/* Inline-size container: live-mode segments measure their run in cqw. */
[data-uiify-line-chart] [data-part="viewport"] {
container-type: inline-size;
position: relative;
grid-column: 1;
grid-row: 1;
min-inline-size: 0;
min-block-size: 18rem;
overflow: clip;
overscroll-behavior: none;
}
[data-uiify-line-chart] > figcaption {
position: absolute;
z-index: 1;
inset-block-start: 0.75rem;
inset-inline-start: 1rem;
color: var(--line-axis);
font-size: 0.75rem;
font-weight: 650;
letter-spacing: 0.04em;
text-transform: uppercase;
}
[data-uiify-line-chart] [data-part="readout"] {
position: absolute;
z-index: 1;
inset-block-start: 0.75rem;
inset-inline-end: 1rem;
display: flex;
gap: 0.625rem;
align-items: baseline;
color: var(--line-axis);
font-size: 0.7rem;
font-variant-numeric: tabular-nums;
line-height: 1;
white-space: nowrap;
}
[data-uiify-line-chart] [data-part="readout-time"] {
font-weight: 650;
}
/* Size container for segment slopes. Its height comes from insets, so it is
definite (a height from min-block-size alone reports 0cqh in Chromium).
One container for all points keeps every line below every dot. */
[data-uiify-line-chart] [data-part="points"] {
container-type: size;
position: absolute;
inset: 1rem 0;
display: block;
margin: 0;
padding: 0;
list-style: none;
background-image:
linear-gradient(to right, var(--line-grid) 1px, transparent 1px),
linear-gradient(to bottom, var(--line-grid) 1px, transparent 1px);
background-size:
var(--line-segment-slot) 100%,
100% 20%;
}
/* Live mode: a horizontal VirtualScroll replaces the static list. The grid sits
on the viewport, so it holds still while points scroll past and a classic
scrollbar cannot squeeze it. */
[data-uiify-line-chart] [data-part="viewport"] > [data-uiify-virtual-scroll] {
position: absolute;
inset: 0;
}
[data-uiify-line-chart] [data-part="viewport"]:has(> [data-uiify-virtual-scroll]) {
background-image:
linear-gradient(to right, var(--line-grid) 1px, transparent 1px),
linear-gradient(to bottom, var(--line-grid) 1px, transparent 1px);
background-position: 0 1rem;
background-size:
10% 100%,
100% calc((100% - 2rem) / 5);
}
[data-uiify-line-chart] [data-part="point"] {
position: absolute;
min-inline-size: 0;
color: var(--line-flat);
list-style: none;
}
[data-uiify-line-chart] [data-part="points"] > [data-part="point"] {
inset-block: 0;
inset-inline-start: var(--line-prev-x, var(--line-x));
inline-size: var(--line-slot);
min-block-size: 100%;
}
/* A virtual row is one point slot; the point element spans from the previous
slot's center to this one's, so the segment ends on the row center. Its
block size comes from the plot, since a classic scrollbar shortens rows. */
[data-uiify-line-chart] [data-uiify-virtual-scroll] [data-part="point"] {
--line-point-block-size: calc(var(--line-plot-height, 18rem) - 2rem);
inset-block: 1rem auto;
inset-inline-start: -50%;
inline-size: 100%;
block-size: var(--line-point-block-size);
}
/* Each segment is a bar of constant thickness rotated to its slope, so steep
jumps stay as thick as flat runs. The run is one slot (`--line-run`% of the
plot width); the rise is `--line-rise`% of the point box height — the points
list in the static chart, the explicit point size in live mode. */
[data-uiify-line-chart] [data-part="point"]::before {
--line-dx: calc(var(--line-run, 0) * 1cqw);
--line-dy: calc(var(--line-rise, 0) / 100 * var(--line-point-block-size, 100cqh));
position: absolute;
z-index: 1;
inset-block-start: calc(var(--line-prev-y) - var(--line-width));
inset-inline-start: 0;
display: block;
inline-size: hypot(var(--line-dx), var(--line-dy));
block-size: calc(var(--line-width) * 2);
border-radius: var(--line-width);
background: currentcolor;
content: "";
transform-origin: 0 50%;
rotate: atan2(var(--line-dy), var(--line-dx));
}
[data-uiify-line-chart] [data-part="point"][data-first]::before {
display: none;
}
[data-uiify-line-chart] [data-part="point"]::after {
position: absolute;
z-index: 2;
inset-block-start: var(--line-y);
inset-inline-start: 100%;
display: block;
inline-size: 0.55rem;
block-size: 0.55rem;
border: 0;
border-radius: 50%;
background: currentcolor;
content: "";
transform: translate(-50%, -50%);
}
[data-uiify-line-chart] [data-part="points"] > [data-part="point"][data-first]::after {
inset-inline-start: 0;
}
[data-uiify-line-chart] [data-part="point"][data-trend="up"] {
color: var(--line-up);
}
[data-uiify-line-chart] [data-part="point"][data-trend="down"] {
color: var(--line-down);
}
[data-uiify-line-chart] [data-part="point-hit"] {
position: absolute;
z-index: 3;
inset: 0;
inline-size: 100%;
block-size: 100%;
margin: 0;
padding: 0;
border: 0;
appearance: none;
background: transparent;
color: transparent;
cursor: crosshair;
font: inherit;
}
[data-uiify-line-chart][data-interactive] [data-part="point"][data-point-selected]::after {
box-shadow: 0 0 0 0.2rem color-mix(in srgb, currentcolor 24%, transparent);
}
[data-uiify-line-chart][data-interactive] [data-part="point-hit"]:focus-visible {
outline: 2px solid currentcolor;
outline-offset: -2px;
}
/* The crosshair and time axis span the scrolled content in live mode:
`--line-content-size` is its width, `--line-scroll-x` its scroll offset. */
[data-uiify-line-chart] [data-part="crosshair"] {
position: absolute;
z-index: 4;
inset: 0;
inline-size: var(--line-content-size, 100%);
translate: calc(-1 * var(--line-scroll-x, 0px)) 0;
block-size: 100%;
color: light-dark(oklch(52% 0.01 0deg), oklch(72% 0.01 0deg));
pointer-events: none;
}
[data-uiify-line-chart] [data-part="crosshair"]::before,
[data-uiify-line-chart] [data-part="crosshair"]::after {
position: absolute;
display: block;
background: currentcolor;
content: "";
}
[data-uiify-line-chart] [data-part="crosshair"]::before {
inset-block: 0;
inset-inline-start: var(--line-crosshair-x);
inline-size: 1px;
background-image: repeating-linear-gradient(
to bottom,
currentcolor 0 0.4rem,
transparent 0.4rem 0.8rem
);
background-color: transparent;
}
[data-uiify-line-chart] [data-part="crosshair"]::after {
inset-block-start: calc(var(--line-cursor-y, 50%) + 1rem);
inset-inline: 0;
block-size: 1px;
background-image: repeating-linear-gradient(
to right,
currentcolor 0 0.4rem,
transparent 0.4rem 0.8rem
);
background-color: transparent;
}
[data-uiify-line-chart] [data-part="crosshair-marker"] {
position: absolute;
inset-block-start: calc(var(--line-cursor-y, 50%) + 1rem);
inset-inline-start: var(--line-crosshair-x);
font-size: 1rem;
line-height: 1;
transform: translate(-50%, -50%);
}
[data-uiify-line-chart] [data-part="value-axis"],
[data-uiify-line-chart] [data-part="time-axis"] {
margin: 0;
padding: 0;
list-style: none;
}
[data-uiify-line-chart] [data-part="value-axis"] {
position: relative;
grid-column: 2;
grid-row: 1;
min-inline-size: 0;
}
[data-uiify-line-chart] [data-part="value-axis"] > li {
position: absolute;
inset-inline: 0;
inset-block-start: var(--line-axis-y);
overflow: hidden;
color: var(--line-axis);
font-size: 0.65rem;
font-variant-numeric: tabular-nums;
line-height: 1;
text-align: end;
text-overflow: ellipsis;
white-space: nowrap;
transform: translateY(-50%);
}
[data-uiify-line-chart] [data-part="value-axis"] > li:first-child {
transform: none;
}
[data-uiify-line-chart] [data-part="value-axis"] > li:last-child {
transform: translateY(-100%);
}
[data-uiify-line-chart] [data-part="time-viewport"] {
position: relative;
grid-column: 1;
grid-row: 2;
min-inline-size: 0;
overflow: clip;
overscroll-behavior: none;
}
[data-uiify-line-chart] [data-part="time-axis"] {
position: relative;
inset-block: 0;
inline-size: var(--line-content-size, 100%);
translate: calc(-1 * var(--line-scroll-x, 0px)) 0;
min-inline-size: 0;
}
[data-uiify-line-chart] [data-part="time-axis"] > li {
position: absolute;
inset-block-start: 0.375rem;
inset-inline-start: var(--line-axis-x);
color: var(--line-axis);
font-size: 0.7rem;
white-space: nowrap;
transform: translateX(-50%);
}
[data-uiify-line-chart] [data-part="time-axis"] > li:first-child {
transform: none;
}
[data-uiify-line-chart] [data-part="time-axis"] > li:last-child {
transform: translateX(-100%);
}
[data-uiify-line-chart] [data-part="time-axis"] > li:only-child {
transform: translateX(-50%);
}
[data-uiify-line-chart] [data-part="time-axis"] > li[data-part="crosshair-time"] {
inset-inline-start: var(--line-crosshair-x);
padding: 0.25rem 0.5rem;
background: var(--line-axis);
color: Canvas;
font-weight: 650;
transform: translateX(-50%);
}
[data-uiify-line-chart] [data-part="value-axis"] > li[data-part="crosshair-value"] {
inset-block-start: calc(var(--line-cursor-y, 50%) + 1rem);
inset-inline-end: 0;
padding: 0.25rem 0.5rem;
background: var(--line-axis);
color: Canvas;
font-weight: 650;
transform: translateY(-50%);
}
[data-uiify-line-chart] > table {
position: absolute;
inline-size: 1px;
block-size: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
@media (prefers-reduced-motion: no-preference) {
[data-uiify-line-chart] [data-part="point"]::after {
transition: scale 180ms ease;
}
[data-uiify-line-chart][data-interactive] [data-part="point"][data-point-selected]::after {
scale: 1.15;
}
}
}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
import { useEffect, useState } from "react";
import { LineChart } from "@gunkin/uiify";
import { LineChartClient } from "@gunkin/uiify/components/line-chart/client";
const data = Array.from({ length: 48 }, (_, index) => ({
time: new Date(Date.UTC(2025, 0, 1 + index * 7)).toISOString().slice(0, 10),
value: Math.round((86 + index * 1.4 + Math.sin(index / 3.5) * 7) * 10) / 10,
}));
export default function Example() {
return (
<>
<LineChart
className={
"[--line-grid:color-mix(in_srgb,_currentcolor_10%,_transparent)] [--line-up:oklch(67%_0.14_166deg)] [--lin" +
"e-down:oklch(64%_0.21_24deg)] [--line-flat:light-dark(oklch(43%_0.05_165deg),_oklch(72%_0.04_165deg))] [-" +
"-line-axis:light-dark(_color-mix(in_oklch,_var(--muted-foreground)_70%,_var(--foreground)),_var(--muted-f" +
"oreground)_)] [--line-width:0.12rem] relative block [inline-size:100%] [min-block-size:21rem] [padding:1r" +
"em_0.75rem_0.5rem] overflow-clip [overscroll-behavior:none] isolate bg-transparent [color:light-dark(oklc" +
"h(28%_0.04_165deg),_oklch(82%_0.04_165deg))] data-[interactive]:[touch-action:none] [&[data-interactive]_" +
"[data-part=scroll-viewport]]:[overscroll-behavior-inline:none] [&>[data-part=plot]]:relative [&>[data-par" +
"t=plot]]:grid [&>[data-part=plot]]:[grid-template-columns:minmax(0,_1fr)_4.5rem] [&>[data-part=plot]]:[gr" +
"id-template-rows:minmax(18rem,_1fr)_calc(1.5rem_+_var(--line-scrollbar-size,_0px))] [&>[data-part=plot]]:" +
"[gap:0_0.75rem] [&>[data-part=plot]]:[min-inline-size:0] [&>[data-part=plot]]:[min-block-size:18rem] [&>[" +
"data-part=plot]]:[overscroll-behavior:none] [&_[data-part=scroll-viewport]]:[grid-column:1] [&_[data-part" +
"=scroll-viewport]]:[grid-row:1_/_span_2] [&_[data-part=scroll-viewport]]:[min-inline-size:0] [&_[data-par" +
"t=scroll-viewport]]:[min-block-size:18rem] [&_[data-part=scroll-viewport]]:[overflow:auto_hidden] [&_[dat" +
"a-part=scroll-viewport]]:[container-type:inline-size] [&_[data-part=scroll-viewport]]:[direction:rtl] [&_" +
"[data-part=canvas]]:grid [&_[data-part=canvas]]:[grid-template-rows:minmax(18rem,_1fr)_1.5rem] [&_[data-p" +
"art=canvas]]:[inline-size:calc(100%_*_var(--line-scale))] [&_[data-part=canvas]]:[min-inline-size:100%] [" +
"&_[data-part=canvas]]:[min-block-size:100%] [&_[data-part=canvas]]:[direction:ltr] [&_[data-part=viewport" +
"]]:[container-type:inline-size] [&_[data-part=viewport]]:relative [&_[data-part=viewport]]:[grid-column:1" +
"] [&_[data-part=viewport]]:[grid-row:1] [&_[data-part=viewport]]:[min-inline-size:0] [&_[data-part=viewpo" +
"rt]]:[min-block-size:18rem] [&_[data-part=viewport]]:overflow-clip [&_[data-part=viewport]]:[overscroll-b" +
"ehavior:none] [&>figcaption]:absolute [&>figcaption]:z-[1] [&>figcaption]:[inset-block-start:0.75rem] [&>" +
"figcaption]:[inset-inline-start:1rem] [&>figcaption]:[color:var(--line-axis)] [&>figcaption]:[font-size:0" +
".75rem] [&>figcaption]:[font-weight:650] [&>figcaption]:[letter-spacing:0.04em] [&>figcaption]:[text-tran" +
"sform:uppercase] [&_[data-part=readout]]:absolute [&_[data-part=readout]]:z-[1] [&_[data-part=readout]]:[" +
"inset-block-start:0.75rem] [&_[data-part=readout]]:[inset-inline-end:1rem] [&_[data-part=readout]]:flex [" +
"&_[data-part=readout]]:[gap:0.625rem] [&_[data-part=readout]]:items-baseline [&_[data-part=readout]]:[col" +
"or:var(--line-axis)] [&_[data-part=readout]]:[font-size:0.7rem] [&_[data-part=readout]]:[font-variant-num" +
"eric:tabular-nums] [&_[data-part=readout]]:leading-none [&_[data-part=readout]]:whitespace-nowrap [&_[dat" +
"a-part=readout-time]]:[font-weight:650] [&_[data-part=points]]:[container-type:size] [&_[data-part=points" +
"]]:absolute [&_[data-part=points]]:[inset:1rem_0] [&_[data-part=points]]:block [&_[data-part=points]]:m-0" +
" [&_[data-part=points]]:p-0 [&_[data-part=points]]:list-none [&_[data-part=points]]:[background-image:lin" +
"ear-gradient(to_right,_var(--line-grid)_1px,_transparent_1px),_linear-gradient(to_bottom,_var(--line-grid" +
")_1px,_transparent_1px)] [&_[data-part=points]]:[background-size:var(--line-segment-slot)_100%,_100%_20%]" +
" [&_[data-part=viewport]>[data-uiify-virtual-scroll]]:absolute [&_[data-part=viewport]>[data-uiify-virtua" +
"l-scroll]]:inset-0 [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-image:linear-gr" +
"adient(to_right,_var(--line-grid)_1px,_transparent_1px),_linear-gradient(to_bottom,_var(--line-grid)_1px," +
"_transparent_1px)] [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-position:0_1rem" +
"] [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-size:10%_100%,_100%_calc((100%_-" +
"_2rem)_/_5)] [&_[data-part=point]]:absolute [&_[data-part=point]]:[min-inline-size:0] [&_[data-part=point" +
"]]:[color:var(--line-flat)] [&_[data-part=point]]:list-none [&_[data-part=points]>[data-part=point]]:[ins" +
"et-block:0] [&_[data-part=points]>[data-part=point]]:[inset-inline-start:var(--line-prev-x,_var(--line-x)" +
")] [&_[data-part=points]>[data-part=point]]:[inline-size:var(--line-slot)] [&_[data-part=points]>[data-pa" +
"rt=point]]:[min-block-size:100%] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[--line-point-block-si" +
"ze:calc(var(--line-plot-height,_18rem)_-_2rem)] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[inset-" +
"block:1rem_auto] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[inset-inline-start:-50%] [&_[data-uii" +
"fy-virtual-scroll]_[data-part=point]]:[inline-size:100%] [&_[data-uiify-virtual-scroll]_[data-part=point]" +
"]:[block-size:var(--line-point-block-size)] [&_[data-part=point]::before]:[--line-dx:calc(var(--line-run," +
"_0)_*_1cqw)] [&_[data-part=point]::before]:[--line-dy:calc(var(--line-rise,_0)_/_100_*_var(--line-point-b" +
"lock-size,_100cqh))] [&_[data-part=point]::before]:absolute [&_[data-part=point]::before]:z-[1] [&_[data-" +
"part=point]::before]:[inset-block-start:calc(var(--line-prev-y)_-_var(--line-width))] [&_[data-part=point" +
"]::before]:[inset-inline-start:0] [&_[data-part=point]::before]:block [&_[data-part=point]::before]:[inli" +
"ne-size:hypot(var(--line-dx),_var(--line-dy))] [&_[data-part=point]::before]:[block-size:calc(var(--line-" +
"width)_*_2)] [&_[data-part=point]::before]:[border-radius:var(--line-width)] [&_[data-part=point]::before" +
"]:[background:currentcolor] [&_[data-part=point]::before]:content-[''] [&_[data-part=point]::before]:[tra" +
"nsform-origin:0_50%] [&_[data-part=point]::before]:[rotate:atan2(var(--line-dy),_var(--line-dx))] [&_[dat" +
"a-part=point][data-first]::before]:hidden [&_[data-part=point]::after]:absolute [&_[data-part=point]::aft" +
"er]:z-[2] [&_[data-part=point]::after]:[inset-block-start:var(--line-y)] [&_[data-part=point]::after]:[in" +
"set-inline-start:100%] [&_[data-part=point]::after]:block [&_[data-part=point]::after]:[inline-size:0.55r" +
"em] [&_[data-part=point]::after]:[block-size:0.55rem] [&_[data-part=point]::after]:border-0 [&_[data-part" +
"=point]::after]:border-current [&_[data-part=point]::after]:border-none [&_[data-part=point]::after]:roun" +
"ded-[50%] [&_[data-part=point]::after]:[background:currentcolor] [&_[data-part=point]::after]:content-[''" +
"] [&_[data-part=point]::after]:[transform:translate(-50%,_-50%)] [&_[data-part=points]>[data-part=point][" +
"data-first]::after]:[inset-inline-start:0] [&_[data-part=point][data-trend=up]]:[color:var(--line-up)] [&" +
"_[data-part=point][data-trend=down]]:[color:var(--line-down)] [&_[data-part=point-hit]]:absolute [&_[data" +
"-part=point-hit]]:z-[3] [&_[data-part=point-hit]]:inset-0 [&_[data-part=point-hit]]:[inline-size:100%] [&" +
"_[data-part=point-hit]]:[block-size:100%] [&_[data-part=point-hit]]:m-0 [&_[data-part=point-hit]]:p-0 [&_" +
"[data-part=point-hit]]:border-0 [&_[data-part=point-hit]]:border-current [&_[data-part=point-hit]]:border" +
"-none [&_[data-part=point-hit]]:appearance-none [&_[data-part=point-hit]]:bg-transparent [&_[data-part=po" +
"int-hit]]:text-transparent [&_[data-part=point-hit]]:[cursor:crosshair] [&_[data-part=point-hit]]:[font-s" +
"tyle:inherit] [&_[data-part=point-hit]]:[font-variant:inherit] [&_[data-part=point-hit]]:[font-weight:inh" +
"erit] [&_[data-part=point-hit]]:[font-stretch:inherit] [&_[data-part=point-hit]]:text-[length:inherit] [&" +
"_[data-part=point-hit]]:leading-[inherit] [&_[data-part=point-hit]]:font-[family-name:inherit] [&[data-in" +
"teractive]_[data-part=point][data-point-selected]::after]:[box-shadow:0_0_0_0.2rem_color-mix(in_srgb,_cur" +
"rentcolor_24%,_transparent)] [&[data-interactive]_[data-part=point-hit]:focus-visible]:[outline:2px_solid" +
"_currentcolor] [&[data-interactive]_[data-part=point-hit]:focus-visible]:[outline-offset:-2px] [&_[data-p" +
"art=crosshair]]:absolute [&_[data-part=crosshair]]:z-[4] [&_[data-part=crosshair]]:inset-0 [&_[data-part=" +
"crosshair]]:[inline-size:var(--line-content-size,_100%)] [&_[data-part=crosshair]]:[translate:calc(-1_*_v" +
"ar(--line-scroll-x,_0px))_0] [&_[data-part=crosshair]]:[block-size:100%] [&_[data-part=crosshair]]:[color" +
":light-dark(oklch(52%_0.01_0deg),_oklch(72%_0.01_0deg))] [&_[data-part=crosshair]]:pointer-events-none [&" +
"_[data-part=crosshair]::before]:absolute [&_[data-part=crosshair]::before]:block [&_[data-part=crosshair]" +
"::before]:[background:currentcolor] [&_[data-part=crosshair]::before]:content-[''] [&_[data-part=crosshai" +
"r]::after]:absolute [&_[data-part=crosshair]::after]:block [&_[data-part=crosshair]::after]:[background:c" +
"urrentcolor] [&_[data-part=crosshair]::after]:content-[''] [&_[data-part=crosshair]::before]:[inset-block" +
":0] [&_[data-part=crosshair]::before]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=crosshai" +
"r]::before]:[inline-size:1px] [&_[data-part=crosshair]::before]:[background-image:repeating-linear-gradie" +
"nt(_to_bottom,_currentcolor_0_0.4rem,_transparent_0.4rem_0.8rem_)] [&_[data-part=crosshair]::before]:bg-t" +
"ransparent [&_[data-part=crosshair]::after]:[inset-block-start:calc(var(--line-cursor-y,_50%)_+_1rem)] [&" +
"_[data-part=crosshair]::after]:[inset-inline:0] [&_[data-part=crosshair]::after]:[block-size:1px] [&_[dat" +
"a-part=crosshair]::after]:[background-image:repeating-linear-gradient(_to_right,_currentcolor_0_0.4rem,_t" +
"ransparent_0.4rem_0.8rem_)] [&_[data-part=crosshair]::after]:bg-transparent [&_[data-part=crosshair-marke" +
"r]]:absolute [&_[data-part=crosshair-marker]]:[inset-block-start:calc(var(--line-cursor-y,_50%)_+_1rem)] " +
"[&_[data-part=crosshair-marker]]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=crosshair-mar" +
"ker]]:[font-size:1rem] [&_[data-part=crosshair-marker]]:leading-none [&_[data-part=crosshair-marker]]:[tr" +
"ansform:translate(-50%,_-50%)] [&_[data-part=value-axis]]:m-0 [&_[data-part=value-axis]]:p-0 [&_[data-par" +
"t=value-axis]]:list-none [&_[data-part=time-axis]]:m-0 [&_[data-part=time-axis]]:p-0 [&_[data-part=time-a" +
"xis]]:list-none [&_[data-part=value-axis]]:relative [&_[data-part=value-axis]]:[grid-column:2] [&_[data-p" +
"art=value-axis]]:[grid-row:1] [&_[data-part=value-axis]]:[min-inline-size:0] [&_[data-part=value-axis]>li" +
"]:absolute [&_[data-part=value-axis]>li]:[inset-inline:0] [&_[data-part=value-axis]>li]:[inset-block-star" +
"t:var(--line-axis-y)] [&_[data-part=value-axis]>li]:overflow-hidden [&_[data-part=value-axis]>li]:[color:" +
"var(--line-axis)] [&_[data-part=value-axis]>li]:[font-size:0.65rem] [&_[data-part=value-axis]>li]:[font-v" +
"ariant-numeric:tabular-nums] [&_[data-part=value-axis]>li]:leading-none [&_[data-part=value-axis]>li]:tex" +
"t-end [&_[data-part=value-axis]>li]:[text-overflow:ellipsis] [&_[data-part=value-axis]>li]:whitespace-now" +
"rap [&_[data-part=value-axis]>li]:[transform:translateY(-50%)] [&_[data-part=value-axis]>li:first-child]:" +
"[transform:none] [&_[data-part=value-axis]>li:last-child]:[transform:translateY(-100%)] [&_[data-part=tim" +
"e-viewport]]:relative [&_[data-part=time-viewport]]:[grid-column:1] [&_[data-part=time-viewport]]:[grid-r" +
"ow:2] [&_[data-part=time-viewport]]:[min-inline-size:0] [&_[data-part=time-viewport]]:overflow-clip [&_[d" +
"ata-part=time-viewport]]:[overscroll-behavior:none] [&_[data-part=time-axis]]:relative [&_[data-part=time" +
"-axis]]:[inset-block:0] [&_[data-part=time-axis]]:[inline-size:var(--line-content-size,_100%)] [&_[data-p" +
"art=time-axis]]:[translate:calc(-1_*_var(--line-scroll-x,_0px))_0] [&_[data-part=time-axis]]:[min-inline-" +
"size:0] [&_[data-part=time-axis]>li]:absolute [&_[data-part=time-axis]>li]:[inset-block-start:0.375rem] [" +
"&_[data-part=time-axis]>li]:[inset-inline-start:var(--line-axis-x)] [&_[data-part=time-axis]>li]:[color:v" +
"ar(--line-axis)] [&_[data-part=time-axis]>li]:[font-size:0.7rem] [&_[data-part=time-axis]>li]:whitespace-" +
"nowrap [&_[data-part=time-axis]>li]:[transform:translateX(-50%)] [&_[data-part=time-axis]>li:first-child]" +
":[transform:none] [&_[data-part=time-axis]>li:last-child]:[transform:translateX(-100%)] [&_[data-part=tim" +
"e-axis]>li:only-child]:[transform:translateX(-50%)] [&_[data-part=time-axis]>li[data-part=crosshair-time]" +
"]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[pa" +
"dding:0.25rem_0.5rem] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[background:var(--line-axis)" +
"] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[color:Canvas] [&_[data-part=time-axis]>li[data-" +
"part=crosshair-time]]:[font-weight:650] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[transform" +
":translateX(-50%)] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[inset-block-start:calc(var(-" +
"-line-cursor-y,_50%)_+_1rem)] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[inset-inline-end:" +
"0] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[padding:0.25rem_0.5rem] [&_[data-part=value-" +
"axis]>li[data-part=crosshair-value]]:[background:var(--line-axis)] [&_[data-part=value-axis]>li[data-part" +
"=crosshair-value]]:[color:Canvas] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[font-weight:6" +
"50] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[transform:translateY(-50%)] [&>table]:absol" +
"ute [&>table]:[inline-size:1px] [&>table]:[block-size:1px] [&>table]:overflow-hidden [&>table]:[clip-path" +
":inset(50%)] [&>table]:whitespace-nowrap motion-safe:[&_[data-part=point]::after]:[transition:scale_180ms" +
"_ease] motion-safe:[&[data-interactive]_[data-part=point][data-point-selected]::after]:[scale:1.15]"
}
data={data}
aria-label="Weekly revenue"
/>
<LineChartClient
className={
"[--line-grid:color-mix(in_srgb,_currentcolor_10%,_transparent)] [--line-up:oklch(67%_0.14_166deg)] [--lin" +
"e-down:oklch(64%_0.21_24deg)] [--line-flat:light-dark(oklch(43%_0.05_165deg),_oklch(72%_0.04_165deg))] [-" +
"-line-axis:light-dark(_color-mix(in_oklch,_var(--muted-foreground)_70%,_var(--foreground)),_var(--muted-f" +
"oreground)_)] [--line-width:0.12rem] relative block [inline-size:100%] [min-block-size:21rem] [padding:1r" +
"em_0.75rem_0.5rem] overflow-clip [overscroll-behavior:none] isolate bg-transparent [color:light-dark(oklc" +
"h(28%_0.04_165deg),_oklch(82%_0.04_165deg))] data-[interactive]:[touch-action:none] [&[data-interactive]_" +
"[data-part=scroll-viewport]]:[overscroll-behavior-inline:none] [&>[data-part=plot]]:relative [&>[data-par" +
"t=plot]]:grid [&>[data-part=plot]]:[grid-template-columns:minmax(0,_1fr)_4.5rem] [&>[data-part=plot]]:[gr" +
"id-template-rows:minmax(18rem,_1fr)_calc(1.5rem_+_var(--line-scrollbar-size,_0px))] [&>[data-part=plot]]:" +
"[gap:0_0.75rem] [&>[data-part=plot]]:[min-inline-size:0] [&>[data-part=plot]]:[min-block-size:18rem] [&>[" +
"data-part=plot]]:[overscroll-behavior:none] [&_[data-part=scroll-viewport]]:[grid-column:1] [&_[data-part" +
"=scroll-viewport]]:[grid-row:1_/_span_2] [&_[data-part=scroll-viewport]]:[min-inline-size:0] [&_[data-par" +
"t=scroll-viewport]]:[min-block-size:18rem] [&_[data-part=scroll-viewport]]:[overflow:auto_hidden] [&_[dat" +
"a-part=scroll-viewport]]:[container-type:inline-size] [&_[data-part=scroll-viewport]]:[direction:rtl] [&_" +
"[data-part=canvas]]:grid [&_[data-part=canvas]]:[grid-template-rows:minmax(18rem,_1fr)_1.5rem] [&_[data-p" +
"art=canvas]]:[inline-size:calc(100%_*_var(--line-scale))] [&_[data-part=canvas]]:[min-inline-size:100%] [" +
"&_[data-part=canvas]]:[min-block-size:100%] [&_[data-part=canvas]]:[direction:ltr] [&_[data-part=viewport" +
"]]:[container-type:inline-size] [&_[data-part=viewport]]:relative [&_[data-part=viewport]]:[grid-column:1" +
"] [&_[data-part=viewport]]:[grid-row:1] [&_[data-part=viewport]]:[min-inline-size:0] [&_[data-part=viewpo" +
"rt]]:[min-block-size:18rem] [&_[data-part=viewport]]:overflow-clip [&_[data-part=viewport]]:[overscroll-b" +
"ehavior:none] [&>figcaption]:absolute [&>figcaption]:z-[1] [&>figcaption]:[inset-block-start:0.75rem] [&>" +
"figcaption]:[inset-inline-start:1rem] [&>figcaption]:[color:var(--line-axis)] [&>figcaption]:[font-size:0" +
".75rem] [&>figcaption]:[font-weight:650] [&>figcaption]:[letter-spacing:0.04em] [&>figcaption]:[text-tran" +
"sform:uppercase] [&_[data-part=readout]]:absolute [&_[data-part=readout]]:z-[1] [&_[data-part=readout]]:[" +
"inset-block-start:0.75rem] [&_[data-part=readout]]:[inset-inline-end:1rem] [&_[data-part=readout]]:flex [" +
"&_[data-part=readout]]:[gap:0.625rem] [&_[data-part=readout]]:items-baseline [&_[data-part=readout]]:[col" +
"or:var(--line-axis)] [&_[data-part=readout]]:[font-size:0.7rem] [&_[data-part=readout]]:[font-variant-num" +
"eric:tabular-nums] [&_[data-part=readout]]:leading-none [&_[data-part=readout]]:whitespace-nowrap [&_[dat" +
"a-part=readout-time]]:[font-weight:650] [&_[data-part=points]]:[container-type:size] [&_[data-part=points" +
"]]:absolute [&_[data-part=points]]:[inset:1rem_0] [&_[data-part=points]]:block [&_[data-part=points]]:m-0" +
" [&_[data-part=points]]:p-0 [&_[data-part=points]]:list-none [&_[data-part=points]]:[background-image:lin" +
"ear-gradient(to_right,_var(--line-grid)_1px,_transparent_1px),_linear-gradient(to_bottom,_var(--line-grid" +
")_1px,_transparent_1px)] [&_[data-part=points]]:[background-size:var(--line-segment-slot)_100%,_100%_20%]" +
" [&_[data-part=viewport]>[data-uiify-virtual-scroll]]:absolute [&_[data-part=viewport]>[data-uiify-virtua" +
"l-scroll]]:inset-0 [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-image:linear-gr" +
"adient(to_right,_var(--line-grid)_1px,_transparent_1px),_linear-gradient(to_bottom,_var(--line-grid)_1px," +
"_transparent_1px)] [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-position:0_1rem" +
"] [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-size:10%_100%,_100%_calc((100%_-" +
"_2rem)_/_5)] [&_[data-part=point]]:absolute [&_[data-part=point]]:[min-inline-size:0] [&_[data-part=point" +
"]]:[color:var(--line-flat)] [&_[data-part=point]]:list-none [&_[data-part=points]>[data-part=point]]:[ins" +
"et-block:0] [&_[data-part=points]>[data-part=point]]:[inset-inline-start:var(--line-prev-x,_var(--line-x)" +
")] [&_[data-part=points]>[data-part=point]]:[inline-size:var(--line-slot)] [&_[data-part=points]>[data-pa" +
"rt=point]]:[min-block-size:100%] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[--line-point-block-si" +
"ze:calc(var(--line-plot-height,_18rem)_-_2rem)] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[inset-" +
"block:1rem_auto] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[inset-inline-start:-50%] [&_[data-uii" +
"fy-virtual-scroll]_[data-part=point]]:[inline-size:100%] [&_[data-uiify-virtual-scroll]_[data-part=point]" +
"]:[block-size:var(--line-point-block-size)] [&_[data-part=point]::before]:[--line-dx:calc(var(--line-run," +
"_0)_*_1cqw)] [&_[data-part=point]::before]:[--line-dy:calc(var(--line-rise,_0)_/_100_*_var(--line-point-b" +
"lock-size,_100cqh))] [&_[data-part=point]::before]:absolute [&_[data-part=point]::before]:z-[1] [&_[data-" +
"part=point]::before]:[inset-block-start:calc(var(--line-prev-y)_-_var(--line-width))] [&_[data-part=point" +
"]::before]:[inset-inline-start:0] [&_[data-part=point]::before]:block [&_[data-part=point]::before]:[inli" +
"ne-size:hypot(var(--line-dx),_var(--line-dy))] [&_[data-part=point]::before]:[block-size:calc(var(--line-" +
"width)_*_2)] [&_[data-part=point]::before]:[border-radius:var(--line-width)] [&_[data-part=point]::before" +
"]:[background:currentcolor] [&_[data-part=point]::before]:content-[''] [&_[data-part=point]::before]:[tra" +
"nsform-origin:0_50%] [&_[data-part=point]::before]:[rotate:atan2(var(--line-dy),_var(--line-dx))] [&_[dat" +
"a-part=point][data-first]::before]:hidden [&_[data-part=point]::after]:absolute [&_[data-part=point]::aft" +
"er]:z-[2] [&_[data-part=point]::after]:[inset-block-start:var(--line-y)] [&_[data-part=point]::after]:[in" +
"set-inline-start:100%] [&_[data-part=point]::after]:block [&_[data-part=point]::after]:[inline-size:0.55r" +
"em] [&_[data-part=point]::after]:[block-size:0.55rem] [&_[data-part=point]::after]:border-0 [&_[data-part" +
"=point]::after]:border-current [&_[data-part=point]::after]:border-none [&_[data-part=point]::after]:roun" +
"ded-[50%] [&_[data-part=point]::after]:[background:currentcolor] [&_[data-part=point]::after]:content-[''" +
"] [&_[data-part=point]::after]:[transform:translate(-50%,_-50%)] [&_[data-part=points]>[data-part=point][" +
"data-first]::after]:[inset-inline-start:0] [&_[data-part=point][data-trend=up]]:[color:var(--line-up)] [&" +
"_[data-part=point][data-trend=down]]:[color:var(--line-down)] [&_[data-part=point-hit]]:absolute [&_[data" +
"-part=point-hit]]:z-[3] [&_[data-part=point-hit]]:inset-0 [&_[data-part=point-hit]]:[inline-size:100%] [&" +
"_[data-part=point-hit]]:[block-size:100%] [&_[data-part=point-hit]]:m-0 [&_[data-part=point-hit]]:p-0 [&_" +
"[data-part=point-hit]]:border-0 [&_[data-part=point-hit]]:border-current [&_[data-part=point-hit]]:border" +
"-none [&_[data-part=point-hit]]:appearance-none [&_[data-part=point-hit]]:bg-transparent [&_[data-part=po" +
"int-hit]]:text-transparent [&_[data-part=point-hit]]:[cursor:crosshair] [&_[data-part=point-hit]]:[font-s" +
"tyle:inherit] [&_[data-part=point-hit]]:[font-variant:inherit] [&_[data-part=point-hit]]:[font-weight:inh" +
"erit] [&_[data-part=point-hit]]:[font-stretch:inherit] [&_[data-part=point-hit]]:text-[length:inherit] [&" +
"_[data-part=point-hit]]:leading-[inherit] [&_[data-part=point-hit]]:font-[family-name:inherit] [&[data-in" +
"teractive]_[data-part=point][data-point-selected]::after]:[box-shadow:0_0_0_0.2rem_color-mix(in_srgb,_cur" +
"rentcolor_24%,_transparent)] [&[data-interactive]_[data-part=point-hit]:focus-visible]:[outline:2px_solid" +
"_currentcolor] [&[data-interactive]_[data-part=point-hit]:focus-visible]:[outline-offset:-2px] [&_[data-p" +
"art=crosshair]]:absolute [&_[data-part=crosshair]]:z-[4] [&_[data-part=crosshair]]:inset-0 [&_[data-part=" +
"crosshair]]:[inline-size:var(--line-content-size,_100%)] [&_[data-part=crosshair]]:[translate:calc(-1_*_v" +
"ar(--line-scroll-x,_0px))_0] [&_[data-part=crosshair]]:[block-size:100%] [&_[data-part=crosshair]]:[color" +
":light-dark(oklch(52%_0.01_0deg),_oklch(72%_0.01_0deg))] [&_[data-part=crosshair]]:pointer-events-none [&" +
"_[data-part=crosshair]::before]:absolute [&_[data-part=crosshair]::before]:block [&_[data-part=crosshair]" +
"::before]:[background:currentcolor] [&_[data-part=crosshair]::before]:content-[''] [&_[data-part=crosshai" +
"r]::after]:absolute [&_[data-part=crosshair]::after]:block [&_[data-part=crosshair]::after]:[background:c" +
"urrentcolor] [&_[data-part=crosshair]::after]:content-[''] [&_[data-part=crosshair]::before]:[inset-block" +
":0] [&_[data-part=crosshair]::before]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=crosshai" +
"r]::before]:[inline-size:1px] [&_[data-part=crosshair]::before]:[background-image:repeating-linear-gradie" +
"nt(_to_bottom,_currentcolor_0_0.4rem,_transparent_0.4rem_0.8rem_)] [&_[data-part=crosshair]::before]:bg-t" +
"ransparent [&_[data-part=crosshair]::after]:[inset-block-start:calc(var(--line-cursor-y,_50%)_+_1rem)] [&" +
"_[data-part=crosshair]::after]:[inset-inline:0] [&_[data-part=crosshair]::after]:[block-size:1px] [&_[dat" +
"a-part=crosshair]::after]:[background-image:repeating-linear-gradient(_to_right,_currentcolor_0_0.4rem,_t" +
"ransparent_0.4rem_0.8rem_)] [&_[data-part=crosshair]::after]:bg-transparent [&_[data-part=crosshair-marke" +
"r]]:absolute [&_[data-part=crosshair-marker]]:[inset-block-start:calc(var(--line-cursor-y,_50%)_+_1rem)] " +
"[&_[data-part=crosshair-marker]]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=crosshair-mar" +
"ker]]:[font-size:1rem] [&_[data-part=crosshair-marker]]:leading-none [&_[data-part=crosshair-marker]]:[tr" +
"ansform:translate(-50%,_-50%)] [&_[data-part=value-axis]]:m-0 [&_[data-part=value-axis]]:p-0 [&_[data-par" +
"t=value-axis]]:list-none [&_[data-part=time-axis]]:m-0 [&_[data-part=time-axis]]:p-0 [&_[data-part=time-a" +
"xis]]:list-none [&_[data-part=value-axis]]:relative [&_[data-part=value-axis]]:[grid-column:2] [&_[data-p" +
"art=value-axis]]:[grid-row:1] [&_[data-part=value-axis]]:[min-inline-size:0] [&_[data-part=value-axis]>li" +
"]:absolute [&_[data-part=value-axis]>li]:[inset-inline:0] [&_[data-part=value-axis]>li]:[inset-block-star" +
"t:var(--line-axis-y)] [&_[data-part=value-axis]>li]:overflow-hidden [&_[data-part=value-axis]>li]:[color:" +
"var(--line-axis)] [&_[data-part=value-axis]>li]:[font-size:0.65rem] [&_[data-part=value-axis]>li]:[font-v" +
"ariant-numeric:tabular-nums] [&_[data-part=value-axis]>li]:leading-none [&_[data-part=value-axis]>li]:tex" +
"t-end [&_[data-part=value-axis]>li]:[text-overflow:ellipsis] [&_[data-part=value-axis]>li]:whitespace-now" +
"rap [&_[data-part=value-axis]>li]:[transform:translateY(-50%)] [&_[data-part=value-axis]>li:first-child]:" +
"[transform:none] [&_[data-part=value-axis]>li:last-child]:[transform:translateY(-100%)] [&_[data-part=tim" +
"e-viewport]]:relative [&_[data-part=time-viewport]]:[grid-column:1] [&_[data-part=time-viewport]]:[grid-r" +
"ow:2] [&_[data-part=time-viewport]]:[min-inline-size:0] [&_[data-part=time-viewport]]:overflow-clip [&_[d" +
"ata-part=time-viewport]]:[overscroll-behavior:none] [&_[data-part=time-axis]]:relative [&_[data-part=time" +
"-axis]]:[inset-block:0] [&_[data-part=time-axis]]:[inline-size:var(--line-content-size,_100%)] [&_[data-p" +
"art=time-axis]]:[translate:calc(-1_*_var(--line-scroll-x,_0px))_0] [&_[data-part=time-axis]]:[min-inline-" +
"size:0] [&_[data-part=time-axis]>li]:absolute [&_[data-part=time-axis]>li]:[inset-block-start:0.375rem] [" +
"&_[data-part=time-axis]>li]:[inset-inline-start:var(--line-axis-x)] [&_[data-part=time-axis]>li]:[color:v" +
"ar(--line-axis)] [&_[data-part=time-axis]>li]:[font-size:0.7rem] [&_[data-part=time-axis]>li]:whitespace-" +
"nowrap [&_[data-part=time-axis]>li]:[transform:translateX(-50%)] [&_[data-part=time-axis]>li:first-child]" +
":[transform:none] [&_[data-part=time-axis]>li:last-child]:[transform:translateX(-100%)] [&_[data-part=tim" +
"e-axis]>li:only-child]:[transform:translateX(-50%)] [&_[data-part=time-axis]>li[data-part=crosshair-time]" +
"]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[pa" +
"dding:0.25rem_0.5rem] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[background:var(--line-axis)" +
"] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[color:Canvas] [&_[data-part=time-axis]>li[data-" +
"part=crosshair-time]]:[font-weight:650] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[transform" +
":translateX(-50%)] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[inset-block-start:calc(var(-" +
"-line-cursor-y,_50%)_+_1rem)] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[inset-inline-end:" +
"0] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[padding:0.25rem_0.5rem] [&_[data-part=value-" +
"axis]>li[data-part=crosshair-value]]:[background:var(--line-axis)] [&_[data-part=value-axis]>li[data-part" +
"=crosshair-value]]:[color:Canvas] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[font-weight:6" +
"50] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[transform:translateY(-50%)] [&>table]:absol" +
"ute [&>table]:[inline-size:1px] [&>table]:[block-size:1px] [&>table]:overflow-hidden [&>table]:[clip-path" +
":inset(50%)] [&>table]:whitespace-nowrap motion-safe:[&_[data-part=point]::after]:[transition:scale_180ms" +
"_ease] motion-safe:[&[data-interactive]_[data-part=point][data-point-selected]::after]:[scale:1.15]"
}
data={data}
aria-label="Interactive weekly revenue"
/>
<LiveChart />
</>
);
}
function LiveChart() {
const [points, setPoints] = useState(data);
const [running, setRunning] = useState(false);
useEffect(() => {
if (!running) return;
const timer = setInterval(() => {
setPoints((current) => {
const last = current.at(-1);
if (!last) return current;
const value = Math.round(last.value * (1 + (Math.random() - 0.5) * 0.02) * 10) / 10;
return [...current, { time: String(current.length), value }];
});
}, 1000);
return () => clearInterval(timer);
}, [running]);
return (
<>
<button type="button" onClick={() => setRunning((value) => !value)}>
{running ? "Stop" : "Start"}
</button>
{/* All points, virtualized; 20 fit the viewport and new ones stay in view at the end. */}
<LineChartClient
className={
"[--line-grid:color-mix(in_srgb,_currentcolor_10%,_transparent)] [--line-up:oklch(67%_0.14_166deg)] [--lin" +
"e-down:oklch(64%_0.21_24deg)] [--line-flat:light-dark(oklch(43%_0.05_165deg),_oklch(72%_0.04_165deg))] [-" +
"-line-axis:light-dark(_color-mix(in_oklch,_var(--muted-foreground)_70%,_var(--foreground)),_var(--muted-f" +
"oreground)_)] [--line-width:0.12rem] relative block [inline-size:100%] [min-block-size:21rem] [padding:1r" +
"em_0.75rem_0.5rem] overflow-clip [overscroll-behavior:none] isolate bg-transparent [color:light-dark(oklc" +
"h(28%_0.04_165deg),_oklch(82%_0.04_165deg))] data-[interactive]:[touch-action:none] [&[data-interactive]_" +
"[data-part=scroll-viewport]]:[overscroll-behavior-inline:none] [&>[data-part=plot]]:relative [&>[data-par" +
"t=plot]]:grid [&>[data-part=plot]]:[grid-template-columns:minmax(0,_1fr)_4.5rem] [&>[data-part=plot]]:[gr" +
"id-template-rows:minmax(18rem,_1fr)_calc(1.5rem_+_var(--line-scrollbar-size,_0px))] [&>[data-part=plot]]:" +
"[gap:0_0.75rem] [&>[data-part=plot]]:[min-inline-size:0] [&>[data-part=plot]]:[min-block-size:18rem] [&>[" +
"data-part=plot]]:[overscroll-behavior:none] [&_[data-part=scroll-viewport]]:[grid-column:1] [&_[data-part" +
"=scroll-viewport]]:[grid-row:1_/_span_2] [&_[data-part=scroll-viewport]]:[min-inline-size:0] [&_[data-par" +
"t=scroll-viewport]]:[min-block-size:18rem] [&_[data-part=scroll-viewport]]:[overflow:auto_hidden] [&_[dat" +
"a-part=scroll-viewport]]:[container-type:inline-size] [&_[data-part=scroll-viewport]]:[direction:rtl] [&_" +
"[data-part=canvas]]:grid [&_[data-part=canvas]]:[grid-template-rows:minmax(18rem,_1fr)_1.5rem] [&_[data-p" +
"art=canvas]]:[inline-size:calc(100%_*_var(--line-scale))] [&_[data-part=canvas]]:[min-inline-size:100%] [" +
"&_[data-part=canvas]]:[min-block-size:100%] [&_[data-part=canvas]]:[direction:ltr] [&_[data-part=viewport" +
"]]:[container-type:inline-size] [&_[data-part=viewport]]:relative [&_[data-part=viewport]]:[grid-column:1" +
"] [&_[data-part=viewport]]:[grid-row:1] [&_[data-part=viewport]]:[min-inline-size:0] [&_[data-part=viewpo" +
"rt]]:[min-block-size:18rem] [&_[data-part=viewport]]:overflow-clip [&_[data-part=viewport]]:[overscroll-b" +
"ehavior:none] [&>figcaption]:absolute [&>figcaption]:z-[1] [&>figcaption]:[inset-block-start:0.75rem] [&>" +
"figcaption]:[inset-inline-start:1rem] [&>figcaption]:[color:var(--line-axis)] [&>figcaption]:[font-size:0" +
".75rem] [&>figcaption]:[font-weight:650] [&>figcaption]:[letter-spacing:0.04em] [&>figcaption]:[text-tran" +
"sform:uppercase] [&_[data-part=readout]]:absolute [&_[data-part=readout]]:z-[1] [&_[data-part=readout]]:[" +
"inset-block-start:0.75rem] [&_[data-part=readout]]:[inset-inline-end:1rem] [&_[data-part=readout]]:flex [" +
"&_[data-part=readout]]:[gap:0.625rem] [&_[data-part=readout]]:items-baseline [&_[data-part=readout]]:[col" +
"or:var(--line-axis)] [&_[data-part=readout]]:[font-size:0.7rem] [&_[data-part=readout]]:[font-variant-num" +
"eric:tabular-nums] [&_[data-part=readout]]:leading-none [&_[data-part=readout]]:whitespace-nowrap [&_[dat" +
"a-part=readout-time]]:[font-weight:650] [&_[data-part=points]]:[container-type:size] [&_[data-part=points" +
"]]:absolute [&_[data-part=points]]:[inset:1rem_0] [&_[data-part=points]]:block [&_[data-part=points]]:m-0" +
" [&_[data-part=points]]:p-0 [&_[data-part=points]]:list-none [&_[data-part=points]]:[background-image:lin" +
"ear-gradient(to_right,_var(--line-grid)_1px,_transparent_1px),_linear-gradient(to_bottom,_var(--line-grid" +
")_1px,_transparent_1px)] [&_[data-part=points]]:[background-size:var(--line-segment-slot)_100%,_100%_20%]" +
" [&_[data-part=viewport]>[data-uiify-virtual-scroll]]:absolute [&_[data-part=viewport]>[data-uiify-virtua" +
"l-scroll]]:inset-0 [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-image:linear-gr" +
"adient(to_right,_var(--line-grid)_1px,_transparent_1px),_linear-gradient(to_bottom,_var(--line-grid)_1px," +
"_transparent_1px)] [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-position:0_1rem" +
"] [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-size:10%_100%,_100%_calc((100%_-" +
"_2rem)_/_5)] [&_[data-part=point]]:absolute [&_[data-part=point]]:[min-inline-size:0] [&_[data-part=point" +
"]]:[color:var(--line-flat)] [&_[data-part=point]]:list-none [&_[data-part=points]>[data-part=point]]:[ins" +
"et-block:0] [&_[data-part=points]>[data-part=point]]:[inset-inline-start:var(--line-prev-x,_var(--line-x)" +
")] [&_[data-part=points]>[data-part=point]]:[inline-size:var(--line-slot)] [&_[data-part=points]>[data-pa" +
"rt=point]]:[min-block-size:100%] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[--line-point-block-si" +
"ze:calc(var(--line-plot-height,_18rem)_-_2rem)] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[inset-" +
"block:1rem_auto] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[inset-inline-start:-50%] [&_[data-uii" +
"fy-virtual-scroll]_[data-part=point]]:[inline-size:100%] [&_[data-uiify-virtual-scroll]_[data-part=point]" +
"]:[block-size:var(--line-point-block-size)] [&_[data-part=point]::before]:[--line-dx:calc(var(--line-run," +
"_0)_*_1cqw)] [&_[data-part=point]::before]:[--line-dy:calc(var(--line-rise,_0)_/_100_*_var(--line-point-b" +
"lock-size,_100cqh))] [&_[data-part=point]::before]:absolute [&_[data-part=point]::before]:z-[1] [&_[data-" +
"part=point]::before]:[inset-block-start:calc(var(--line-prev-y)_-_var(--line-width))] [&_[data-part=point" +
"]::before]:[inset-inline-start:0] [&_[data-part=point]::before]:block [&_[data-part=point]::before]:[inli" +
"ne-size:hypot(var(--line-dx),_var(--line-dy))] [&_[data-part=point]::before]:[block-size:calc(var(--line-" +
"width)_*_2)] [&_[data-part=point]::before]:[border-radius:var(--line-width)] [&_[data-part=point]::before" +
"]:[background:currentcolor] [&_[data-part=point]::before]:content-[''] [&_[data-part=point]::before]:[tra" +
"nsform-origin:0_50%] [&_[data-part=point]::before]:[rotate:atan2(var(--line-dy),_var(--line-dx))] [&_[dat" +
"a-part=point][data-first]::before]:hidden [&_[data-part=point]::after]:absolute [&_[data-part=point]::aft" +
"er]:z-[2] [&_[data-part=point]::after]:[inset-block-start:var(--line-y)] [&_[data-part=point]::after]:[in" +
"set-inline-start:100%] [&_[data-part=point]::after]:block [&_[data-part=point]::after]:[inline-size:0.55r" +
"em] [&_[data-part=point]::after]:[block-size:0.55rem] [&_[data-part=point]::after]:border-0 [&_[data-part" +
"=point]::after]:border-current [&_[data-part=point]::after]:border-none [&_[data-part=point]::after]:roun" +
"ded-[50%] [&_[data-part=point]::after]:[background:currentcolor] [&_[data-part=point]::after]:content-[''" +
"] [&_[data-part=point]::after]:[transform:translate(-50%,_-50%)] [&_[data-part=points]>[data-part=point][" +
"data-first]::after]:[inset-inline-start:0] [&_[data-part=point][data-trend=up]]:[color:var(--line-up)] [&" +
"_[data-part=point][data-trend=down]]:[color:var(--line-down)] [&_[data-part=point-hit]]:absolute [&_[data" +
"-part=point-hit]]:z-[3] [&_[data-part=point-hit]]:inset-0 [&_[data-part=point-hit]]:[inline-size:100%] [&" +
"_[data-part=point-hit]]:[block-size:100%] [&_[data-part=point-hit]]:m-0 [&_[data-part=point-hit]]:p-0 [&_" +
"[data-part=point-hit]]:border-0 [&_[data-part=point-hit]]:border-current [&_[data-part=point-hit]]:border" +
"-none [&_[data-part=point-hit]]:appearance-none [&_[data-part=point-hit]]:bg-transparent [&_[data-part=po" +
"int-hit]]:text-transparent [&_[data-part=point-hit]]:[cursor:crosshair] [&_[data-part=point-hit]]:[font-s" +
"tyle:inherit] [&_[data-part=point-hit]]:[font-variant:inherit] [&_[data-part=point-hit]]:[font-weight:inh" +
"erit] [&_[data-part=point-hit]]:[font-stretch:inherit] [&_[data-part=point-hit]]:text-[length:inherit] [&" +
"_[data-part=point-hit]]:leading-[inherit] [&_[data-part=point-hit]]:font-[family-name:inherit] [&[data-in" +
"teractive]_[data-part=point][data-point-selected]::after]:[box-shadow:0_0_0_0.2rem_color-mix(in_srgb,_cur" +
"rentcolor_24%,_transparent)] [&[data-interactive]_[data-part=point-hit]:focus-visible]:[outline:2px_solid" +
"_currentcolor] [&[data-interactive]_[data-part=point-hit]:focus-visible]:[outline-offset:-2px] [&_[data-p" +
"art=crosshair]]:absolute [&_[data-part=crosshair]]:z-[4] [&_[data-part=crosshair]]:inset-0 [&_[data-part=" +
"crosshair]]:[inline-size:var(--line-content-size,_100%)] [&_[data-part=crosshair]]:[translate:calc(-1_*_v" +
"ar(--line-scroll-x,_0px))_0] [&_[data-part=crosshair]]:[block-size:100%] [&_[data-part=crosshair]]:[color" +
":light-dark(oklch(52%_0.01_0deg),_oklch(72%_0.01_0deg))] [&_[data-part=crosshair]]:pointer-events-none [&" +
"_[data-part=crosshair]::before]:absolute [&_[data-part=crosshair]::before]:block [&_[data-part=crosshair]" +
"::before]:[background:currentcolor] [&_[data-part=crosshair]::before]:content-[''] [&_[data-part=crosshai" +
"r]::after]:absolute [&_[data-part=crosshair]::after]:block [&_[data-part=crosshair]::after]:[background:c" +
"urrentcolor] [&_[data-part=crosshair]::after]:content-[''] [&_[data-part=crosshair]::before]:[inset-block" +
":0] [&_[data-part=crosshair]::before]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=crosshai" +
"r]::before]:[inline-size:1px] [&_[data-part=crosshair]::before]:[background-image:repeating-linear-gradie" +
"nt(_to_bottom,_currentcolor_0_0.4rem,_transparent_0.4rem_0.8rem_)] [&_[data-part=crosshair]::before]:bg-t" +
"ransparent [&_[data-part=crosshair]::after]:[inset-block-start:calc(var(--line-cursor-y,_50%)_+_1rem)] [&" +
"_[data-part=crosshair]::after]:[inset-inline:0] [&_[data-part=crosshair]::after]:[block-size:1px] [&_[dat" +
"a-part=crosshair]::after]:[background-image:repeating-linear-gradient(_to_right,_currentcolor_0_0.4rem,_t" +
"ransparent_0.4rem_0.8rem_)] [&_[data-part=crosshair]::after]:bg-transparent [&_[data-part=crosshair-marke" +
"r]]:absolute [&_[data-part=crosshair-marker]]:[inset-block-start:calc(var(--line-cursor-y,_50%)_+_1rem)] " +
"[&_[data-part=crosshair-marker]]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=crosshair-mar" +
"ker]]:[font-size:1rem] [&_[data-part=crosshair-marker]]:leading-none [&_[data-part=crosshair-marker]]:[tr" +
"ansform:translate(-50%,_-50%)] [&_[data-part=value-axis]]:m-0 [&_[data-part=value-axis]]:p-0 [&_[data-par" +
"t=value-axis]]:list-none [&_[data-part=time-axis]]:m-0 [&_[data-part=time-axis]]:p-0 [&_[data-part=time-a" +
"xis]]:list-none [&_[data-part=value-axis]]:relative [&_[data-part=value-axis]]:[grid-column:2] [&_[data-p" +
"art=value-axis]]:[grid-row:1] [&_[data-part=value-axis]]:[min-inline-size:0] [&_[data-part=value-axis]>li" +
"]:absolute [&_[data-part=value-axis]>li]:[inset-inline:0] [&_[data-part=value-axis]>li]:[inset-block-star" +
"t:var(--line-axis-y)] [&_[data-part=value-axis]>li]:overflow-hidden [&_[data-part=value-axis]>li]:[color:" +
"var(--line-axis)] [&_[data-part=value-axis]>li]:[font-size:0.65rem] [&_[data-part=value-axis]>li]:[font-v" +
"ariant-numeric:tabular-nums] [&_[data-part=value-axis]>li]:leading-none [&_[data-part=value-axis]>li]:tex" +
"t-end [&_[data-part=value-axis]>li]:[text-overflow:ellipsis] [&_[data-part=value-axis]>li]:whitespace-now" +
"rap [&_[data-part=value-axis]>li]:[transform:translateY(-50%)] [&_[data-part=value-axis]>li:first-child]:" +
"[transform:none] [&_[data-part=value-axis]>li:last-child]:[transform:translateY(-100%)] [&_[data-part=tim" +
"e-viewport]]:relative [&_[data-part=time-viewport]]:[grid-column:1] [&_[data-part=time-viewport]]:[grid-r" +
"ow:2] [&_[data-part=time-viewport]]:[min-inline-size:0] [&_[data-part=time-viewport]]:overflow-clip [&_[d" +
"ata-part=time-viewport]]:[overscroll-behavior:none] [&_[data-part=time-axis]]:relative [&_[data-part=time" +
"-axis]]:[inset-block:0] [&_[data-part=time-axis]]:[inline-size:var(--line-content-size,_100%)] [&_[data-p" +
"art=time-axis]]:[translate:calc(-1_*_var(--line-scroll-x,_0px))_0] [&_[data-part=time-axis]]:[min-inline-" +
"size:0] [&_[data-part=time-axis]>li]:absolute [&_[data-part=time-axis]>li]:[inset-block-start:0.375rem] [" +
"&_[data-part=time-axis]>li]:[inset-inline-start:var(--line-axis-x)] [&_[data-part=time-axis]>li]:[color:v" +
"ar(--line-axis)] [&_[data-part=time-axis]>li]:[font-size:0.7rem] [&_[data-part=time-axis]>li]:whitespace-" +
"nowrap [&_[data-part=time-axis]>li]:[transform:translateX(-50%)] [&_[data-part=time-axis]>li:first-child]" +
":[transform:none] [&_[data-part=time-axis]>li:last-child]:[transform:translateX(-100%)] [&_[data-part=tim" +
"e-axis]>li:only-child]:[transform:translateX(-50%)] [&_[data-part=time-axis]>li[data-part=crosshair-time]" +
"]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[pa" +
"dding:0.25rem_0.5rem] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[background:var(--line-axis)" +
"] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[color:Canvas] [&_[data-part=time-axis]>li[data-" +
"part=crosshair-time]]:[font-weight:650] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[transform" +
":translateX(-50%)] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[inset-block-start:calc(var(-" +
"-line-cursor-y,_50%)_+_1rem)] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[inset-inline-end:" +
"0] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[padding:0.25rem_0.5rem] [&_[data-part=value-" +
"axis]>li[data-part=crosshair-value]]:[background:var(--line-axis)] [&_[data-part=value-axis]>li[data-part" +
"=crosshair-value]]:[color:Canvas] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[font-weight:6" +
"50] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[transform:translateY(-50%)] [&>table]:absol" +
"ute [&>table]:[inline-size:1px] [&>table]:[block-size:1px] [&>table]:overflow-hidden [&>table]:[clip-path" +
":inset(50%)] [&>table]:whitespace-nowrap motion-safe:[&_[data-part=point]::after]:[transition:scale_180ms" +
"_ease] motion-safe:[&[data-interactive]_[data-part=point][data-point-selected]::after]:[scale:1.15]"
}
data={points}
visibleCount={20}
aria-label="Live revenue"
/>
</>
);
}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
/* app.css */
@layer reset, ui, app, tokens, base, demo, components, utilities, theme;
@import "@gunkin/uiify/styles/reset";
@import "@gunkin/uiify/components/behavior.css";
@import "@gunkin/uiify/styles/tokens";
@import "@gunkin/uiify/styles/tailwind";
@import "tailwindcss/utilities.css";
@theme { --spacing: 0.25rem; --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 600; --font-weight-bold: 700; }
@source inline('[--line-grid:color-mix(in_srgb,_currentcolor_10%,_transparent)] [--line-up:oklch(67%_0.14_166deg)] [--line-down:oklch(64%_0.21_24deg)] [--line-flat:light-dark(oklch(43%_0.05_165deg),_oklch(72%_0.04_165deg))] [--line-axis:light-dark(_color-mix(in_oklch,_var(--muted-foreground)_70%,_var(--foreground)),_var(--muted-foreground)_)] [--line-width:0.12rem] relative block [inline-size:100%] [min-block-size:21rem] [padding:1rem_0.75rem_0.5rem] overflow-clip [overscroll-behavior:none] isolate bg-transparent [color:light-dark(oklch(28%_0.04_165deg),_oklch(82%_0.04_165deg))] data-[interactive]:[touch-action:none] [&[data-interactive]_[data-part=scroll-viewport]]:[overscroll-behavior-inline:none] [&>[data-part=plot]]:relative [&>[data-part=plot]]:grid [&>[data-part=plot]]:[grid-template-columns:minmax(0,_1fr)_4.5rem] [&>[data-part=plot]]:[grid-template-rows:minmax(18rem,_1fr)_calc(1.5rem_+_var(--line-scrollbar-size,_0px))] [&>[data-part=plot]]:[gap:0_0.75rem] [&>[data-part=plot]]:[min-inline-size:0] [&>[data-part=plot]]:[min-block-size:18rem] [&>[data-part=plot]]:[overscroll-behavior:none] [&_[data-part=scroll-viewport]]:[grid-column:1] [&_[data-part=scroll-viewport]]:[grid-row:1_/_span_2] [&_[data-part=scroll-viewport]]:[min-inline-size:0] [&_[data-part=scroll-viewport]]:[min-block-size:18rem] [&_[data-part=scroll-viewport]]:[overflow:auto_hidden] [&_[data-part=scroll-viewport]]:[container-type:inline-size] [&_[data-part=scroll-viewport]]:[direction:rtl] [&_[data-part=canvas]]:grid [&_[data-part=canvas]]:[grid-template-rows:minmax(18rem,_1fr)_1.5rem] [&_[data-part=canvas]]:[inline-size:calc(100%_*_var(--line-scale))] [&_[data-part=canvas]]:[min-inline-size:100%] [&_[data-part=canvas]]:[min-block-size:100%] [&_[data-part=canvas]]:[direction:ltr] [&_[data-part=viewport]]:[container-type:inline-size] [&_[data-part=viewport]]:relative [&_[data-part=viewport]]:[grid-column:1] [&_[data-part=viewport]]:[grid-row:1] [&_[data-part=viewport]]:[min-inline-size:0] [&_[data-part=viewport]]:[min-block-size:18rem] [&_[data-part=viewport]]:overflow-clip [&_[data-part=viewport]]:[overscroll-behavior:none] [&>figcaption]:absolute [&>figcaption]:z-[1] [&>figcaption]:[inset-block-start:0.75rem] [&>figcaption]:[inset-inline-start:1rem] [&>figcaption]:[color:var(--line-axis)] [&>figcaption]:[font-size:0.75rem] [&>figcaption]:[font-weight:650] [&>figcaption]:[letter-spacing:0.04em] [&>figcaption]:[text-transform:uppercase] [&_[data-part=readout]]:absolute [&_[data-part=readout]]:z-[1] [&_[data-part=readout]]:[inset-block-start:0.75rem] [&_[data-part=readout]]:[inset-inline-end:1rem] [&_[data-part=readout]]:flex [&_[data-part=readout]]:[gap:0.625rem] [&_[data-part=readout]]:items-baseline [&_[data-part=readout]]:[color:var(--line-axis)] [&_[data-part=readout]]:[font-size:0.7rem] [&_[data-part=readout]]:[font-variant-numeric:tabular-nums] [&_[data-part=readout]]:leading-none [&_[data-part=readout]]:whitespace-nowrap [&_[data-part=readout-time]]:[font-weight:650] [&_[data-part=points]]:[container-type:size] [&_[data-part=points]]:absolute [&_[data-part=points]]:[inset:1rem_0] [&_[data-part=points]]:block [&_[data-part=points]]:m-0 [&_[data-part=points]]:p-0 [&_[data-part=points]]:list-none [&_[data-part=points]]:[background-image:linear-gradient(to_right,_var(--line-grid)_1px,_transparent_1px),_linear-gradient(to_bottom,_var(--line-grid)_1px,_transparent_1px)] [&_[data-part=points]]:[background-size:var(--line-segment-slot)_100%,_100%_20%] [&_[data-part=viewport]>[data-uiify-virtual-scroll]]:absolute [&_[data-part=viewport]>[data-uiify-virtual-scroll]]:inset-0 [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-image:linear-gradient(to_right,_var(--line-grid)_1px,_transparent_1px),_linear-gradient(to_bottom,_var(--line-grid)_1px,_transparent_1px)] [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-position:0_1rem] [&_[data-part=viewport]:has(>[data-uiify-virtual-scroll])]:[background-size:10%_100%,_100%_calc((100%_-_2rem)_/_5)] [&_[data-part=point]]:absolute [&_[data-part=point]]:[min-inline-size:0] [&_[data-part=point]]:[color:var(--line-flat)] [&_[data-part=point]]:list-none [&_[data-part=points]>[data-part=point]]:[inset-block:0] [&_[data-part=points]>[data-part=point]]:[inset-inline-start:var(--line-prev-x,_var(--line-x))] [&_[data-part=points]>[data-part=point]]:[inline-size:var(--line-slot)] [&_[data-part=points]>[data-part=point]]:[min-block-size:100%] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[--line-point-block-size:calc(var(--line-plot-height,_18rem)_-_2rem)] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[inset-block:1rem_auto] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[inset-inline-start:-50%] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[inline-size:100%] [&_[data-uiify-virtual-scroll]_[data-part=point]]:[block-size:var(--line-point-block-size)] [&_[data-part=point]::before]:[--line-dx:calc(var(--line-run,_0)_*_1cqw)] [&_[data-part=point]::before]:[--line-dy:calc(var(--line-rise,_0)_/_100_*_var(--line-point-block-size,_100cqh))] [&_[data-part=point]::before]:absolute [&_[data-part=point]::before]:z-[1] [&_[data-part=point]::before]:[inset-block-start:calc(var(--line-prev-y)_-_var(--line-width))] [&_[data-part=point]::before]:[inset-inline-start:0] [&_[data-part=point]::before]:block [&_[data-part=point]::before]:[inline-size:hypot(var(--line-dx),_var(--line-dy))] [&_[data-part=point]::before]:[block-size:calc(var(--line-width)_*_2)] [&_[data-part=point]::before]:[border-radius:var(--line-width)] [&_[data-part=point]::before]:[background:currentcolor] [&_[data-part=point]::before]:[transform-origin:0_50%] [&_[data-part=point]::before]:[rotate:atan2(var(--line-dy),_var(--line-dx))] [&_[data-part=point][data-first]::before]:hidden [&_[data-part=point]::after]:absolute [&_[data-part=point]::after]:z-[2] [&_[data-part=point]::after]:[inset-block-start:var(--line-y)] [&_[data-part=point]::after]:[inset-inline-start:100%] [&_[data-part=point]::after]:block [&_[data-part=point]::after]:[inline-size:0.55rem] [&_[data-part=point]::after]:[block-size:0.55rem] [&_[data-part=point]::after]:border-0 [&_[data-part=point]::after]:border-current [&_[data-part=point]::after]:border-none [&_[data-part=point]::after]:rounded-[50%] [&_[data-part=point]::after]:[background:currentcolor] [&_[data-part=point]::after]:[transform:translate(-50%,_-50%)] [&_[data-part=points]>[data-part=point][data-first]::after]:[inset-inline-start:0] [&_[data-part=point][data-trend=up]]:[color:var(--line-up)] [&_[data-part=point][data-trend=down]]:[color:var(--line-down)] [&_[data-part=point-hit]]:absolute [&_[data-part=point-hit]]:z-[3] [&_[data-part=point-hit]]:inset-0 [&_[data-part=point-hit]]:[inline-size:100%] [&_[data-part=point-hit]]:[block-size:100%] [&_[data-part=point-hit]]:m-0 [&_[data-part=point-hit]]:p-0 [&_[data-part=point-hit]]:border-0 [&_[data-part=point-hit]]:border-current [&_[data-part=point-hit]]:border-none [&_[data-part=point-hit]]:appearance-none [&_[data-part=point-hit]]:bg-transparent [&_[data-part=point-hit]]:text-transparent [&_[data-part=point-hit]]:[cursor:crosshair] [&_[data-part=point-hit]]:[font-style:inherit] [&_[data-part=point-hit]]:[font-variant:inherit] [&_[data-part=point-hit]]:[font-weight:inherit] [&_[data-part=point-hit]]:[font-stretch:inherit] [&_[data-part=point-hit]]:text-[length:inherit] [&_[data-part=point-hit]]:leading-[inherit] [&_[data-part=point-hit]]:font-[family-name:inherit] [&[data-interactive]_[data-part=point][data-point-selected]::after]:[box-shadow:0_0_0_0.2rem_color-mix(in_srgb,_currentcolor_24%,_transparent)] [&[data-interactive]_[data-part=point-hit]:focus-visible]:[outline:2px_solid_currentcolor] [&[data-interactive]_[data-part=point-hit]:focus-visible]:[outline-offset:-2px] [&_[data-part=crosshair]]:absolute [&_[data-part=crosshair]]:z-[4] [&_[data-part=crosshair]]:inset-0 [&_[data-part=crosshair]]:[inline-size:var(--line-content-size,_100%)] [&_[data-part=crosshair]]:[translate:calc(-1_*_var(--line-scroll-x,_0px))_0] [&_[data-part=crosshair]]:[block-size:100%] [&_[data-part=crosshair]]:[color:light-dark(oklch(52%_0.01_0deg),_oklch(72%_0.01_0deg))] [&_[data-part=crosshair]]:pointer-events-none [&_[data-part=crosshair]::before]:absolute [&_[data-part=crosshair]::before]:block [&_[data-part=crosshair]::before]:[background:currentcolor] [&_[data-part=crosshair]::after]:absolute [&_[data-part=crosshair]::after]:block [&_[data-part=crosshair]::after]:[background:currentcolor] [&_[data-part=crosshair]::before]:[inset-block:0] [&_[data-part=crosshair]::before]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=crosshair]::before]:[inline-size:1px] [&_[data-part=crosshair]::before]:[background-image:repeating-linear-gradient(_to_bottom,_currentcolor_0_0.4rem,_transparent_0.4rem_0.8rem_)] [&_[data-part=crosshair]::before]:bg-transparent [&_[data-part=crosshair]::after]:[inset-block-start:calc(var(--line-cursor-y,_50%)_+_1rem)] [&_[data-part=crosshair]::after]:[inset-inline:0] [&_[data-part=crosshair]::after]:[block-size:1px] [&_[data-part=crosshair]::after]:[background-image:repeating-linear-gradient(_to_right,_currentcolor_0_0.4rem,_transparent_0.4rem_0.8rem_)] [&_[data-part=crosshair]::after]:bg-transparent [&_[data-part=crosshair-marker]]:absolute [&_[data-part=crosshair-marker]]:[inset-block-start:calc(var(--line-cursor-y,_50%)_+_1rem)] [&_[data-part=crosshair-marker]]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=crosshair-marker]]:[font-size:1rem] [&_[data-part=crosshair-marker]]:leading-none [&_[data-part=crosshair-marker]]:[transform:translate(-50%,_-50%)] [&_[data-part=value-axis]]:m-0 [&_[data-part=value-axis]]:p-0 [&_[data-part=value-axis]]:list-none [&_[data-part=time-axis]]:m-0 [&_[data-part=time-axis]]:p-0 [&_[data-part=time-axis]]:list-none [&_[data-part=value-axis]]:relative [&_[data-part=value-axis]]:[grid-column:2] [&_[data-part=value-axis]]:[grid-row:1] [&_[data-part=value-axis]]:[min-inline-size:0] [&_[data-part=value-axis]>li]:absolute [&_[data-part=value-axis]>li]:[inset-inline:0] [&_[data-part=value-axis]>li]:[inset-block-start:var(--line-axis-y)] [&_[data-part=value-axis]>li]:overflow-hidden [&_[data-part=value-axis]>li]:[color:var(--line-axis)] [&_[data-part=value-axis]>li]:[font-size:0.65rem] [&_[data-part=value-axis]>li]:[font-variant-numeric:tabular-nums] [&_[data-part=value-axis]>li]:leading-none [&_[data-part=value-axis]>li]:text-end [&_[data-part=value-axis]>li]:[text-overflow:ellipsis] [&_[data-part=value-axis]>li]:whitespace-nowrap [&_[data-part=value-axis]>li]:[transform:translateY(-50%)] [&_[data-part=value-axis]>li:first-child]:[transform:none] [&_[data-part=value-axis]>li:last-child]:[transform:translateY(-100%)] [&_[data-part=time-viewport]]:relative [&_[data-part=time-viewport]]:[grid-column:1] [&_[data-part=time-viewport]]:[grid-row:2] [&_[data-part=time-viewport]]:[min-inline-size:0] [&_[data-part=time-viewport]]:overflow-clip [&_[data-part=time-viewport]]:[overscroll-behavior:none] [&_[data-part=time-axis]]:relative [&_[data-part=time-axis]]:[inset-block:0] [&_[data-part=time-axis]]:[inline-size:var(--line-content-size,_100%)] [&_[data-part=time-axis]]:[translate:calc(-1_*_var(--line-scroll-x,_0px))_0] [&_[data-part=time-axis]]:[min-inline-size:0] [&_[data-part=time-axis]>li]:absolute [&_[data-part=time-axis]>li]:[inset-block-start:0.375rem] [&_[data-part=time-axis]>li]:[inset-inline-start:var(--line-axis-x)] [&_[data-part=time-axis]>li]:[color:var(--line-axis)] [&_[data-part=time-axis]>li]:[font-size:0.7rem] [&_[data-part=time-axis]>li]:whitespace-nowrap [&_[data-part=time-axis]>li]:[transform:translateX(-50%)] [&_[data-part=time-axis]>li:first-child]:[transform:none] [&_[data-part=time-axis]>li:last-child]:[transform:translateX(-100%)] [&_[data-part=time-axis]>li:only-child]:[transform:translateX(-50%)] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[inset-inline-start:var(--line-crosshair-x)] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[padding:0.25rem_0.5rem] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[background:var(--line-axis)] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[color:Canvas] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[font-weight:650] [&_[data-part=time-axis]>li[data-part=crosshair-time]]:[transform:translateX(-50%)] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[inset-block-start:calc(var(--line-cursor-y,_50%)_+_1rem)] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[inset-inline-end:0] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[padding:0.25rem_0.5rem] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[background:var(--line-axis)] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[color:Canvas] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[font-weight:650] [&_[data-part=value-axis]>li[data-part=crosshair-value]]:[transform:translateY(-50%)] [&>table]:absolute [&>table]:[inline-size:1px] [&>table]:[block-size:1px] [&>table]:overflow-hidden [&>table]:[clip-path:inset(50%)] [&>table]:whitespace-nowrap motion-safe:[&_[data-part=point]::after]:[transition:scale_180ms_ease] motion-safe:[&[data-interactive]_[data-part=point][data-point-selected]::after]:[scale:1.15]');
@source inline("[&_[data-part=point]::before]:content-[''] [&_[data-part=point]::after]:content-[''] [&_[data-part=crosshair]::before]:content-[''] [&_[data-part=crosshair]::after]:content-['']");
@layer base { :root { --uiify-control-text: var(--text-sm); } @media (pointer: coarse) { :root { --uiify-control-text: var(--text-base); } } }
/* Authored animation and registered properties used by the Tailwind skin.
* Visual rules belong in utility recipes; only at-rule definitions live here. */
@layer components {
@keyframes uiify-presence-in {
from {
opacity: 0;
scale: var(--presence-scale);
}
}
}
@layer components {
@keyframes uiify-presence-out {
to {
opacity: 0;
scale: var(--presence-scale);
}
}
}
@property --uiify-spinner-tail {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
@property --uiify-spinner-length {
syntax: "<angle>";
inherits: false;
initial-value: 36deg;
}
@layer components {
@keyframes uiify-spinner-rotate {
to {
transform: rotate(360deg);
}
}
}
@layer components {
@keyframes uiify-spinner-orbit {
0% {
--uiify-spinner-tail: 0deg;
--uiify-spinner-length: 36deg;
}
50% {
--uiify-spinner-tail: 90deg;
--uiify-spinner-length: 324deg;
}
100% {
--uiify-spinner-tail: 360deg;
--uiify-spinner-length: 36deg;
}
}
}
@layer components {
@keyframes uiify-skeleton-pulse {
50% {
opacity: 0.45;
}
}
}
@layer components {
@keyframes uiify-skeleton-shimmer {
to {
background-position: -200% 0;
}
}
}
@layer components {
@keyframes uiify-skeleton-reveal {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
}
@property --candle-body-height {
syntax: "<percentage>";
inherits: true;
initial-value: 0%;
}
@property --candle-body-top {
syntax: "<percentage>";
inherits: true;
initial-value: 50%;
}
@property --candle-slot {
syntax: "<percentage>";
inherits: true;
initial-value: 100%;
}
@property --candle-wick-height {
syntax: "<percentage>";
inherits: true;
initial-value: 0%;
}
@property --candle-wick-top {
syntax: "<percentage>";
inherits: true;
initial-value: 50%;
}
@property --candle-x {
syntax: "<percentage>";
inherits: true;
initial-value: 0%;
}
@property --candle-scale {
syntax: "<number>";
inherits: true;
initial-value: 1;
}
@property --line-y {
syntax: "<percentage>";
inherits: true;
initial-value: 50%;
}
@property --line-prev-y {
syntax: "<percentage>";
inherits: true;
initial-value: 50%;
}
@property --line-count {
syntax: "<integer>";
inherits: false;
initial-value: 1;
}
@property --line-scale {
syntax: "<number>";
inherits: true;
initial-value: 1;
}
@layer components {
@keyframes uiify-otp-input-caret-blink {
50% {
opacity: 0;
}
}
}API
LineChart
| Prop | Type | Default | Description |
|---|---|---|---|
data* | readonly LineChartData[] | — | Time/value records used to draw the line. |
aria-label | string | "Line chart" | Accessible name used for the chart and its data table. |
xAxis | readonly LineChartAxisLabel[] | — | Optional custom bottom-axis labels. Each item supplies arbitrary React content and a position from 0 to 100 percent. |
yAxis | readonly LineChartAxisLabel[] | — | Optional custom right-axis labels. Each item supplies arbitrary React content and a position from 0 to 100 percent. |
interactive | boolean | — | Enables point hit areas, crosshair state, keyboard activation, and the React-rendered value readout; LineChartClient sets this automatically. |
render | ReactElement | ((props, state) => ReactElement) | — | Replace the rendered element while keeping behavior and accessibility wiring. |
LineChartClient (@gunkin/uiify/components/line-chart/client)
| Prop | Type | Default | Description |
|---|---|---|---|
data* | readonly LineChartData[] | — | The same time/value data as LineChart; the client adds wheel zoom, horizontal scrolling, an endpoint-snapped crosshair, keyboard point selection and a value readout. |
visibleCount | number | — | Live mode: N points fill the viewport; history is virtualized. Axes, readout and table track visible points; the chart follows new ones unless scrolled back, with zoom and announcements off. |
Keyboard
| Key | Action |
|---|---|
| Tab | Focus an interactive point |
| Enter / Space | Select the focused point and update the readout |
Accessibility
The static line is decorative and the figure includes a visually hidden table with the original time and value pairs. The optional client entry makes points keyboard-focusable, adds wheel zoom, native horizontal scrolling, a snapped crosshair, and a live value readout while preserving that table.
Styling hooks
data-uiify-line-chartdata-interactivedata-trenddata-timedata-crosshair-activedata-axis--line-y--line-prev-y--line-slot--line-count--line-scale--line-axis-x--line-axis-y--line-crosshair-x--line-cursor-y