@coinbase/cds-mcp-server 8.17.2 → 8.17.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/mcp-docs/mobile/components/Accordion.txt +189 -0
  3. package/mcp-docs/mobile/components/AccordionItem.txt +30 -0
  4. package/mcp-docs/mobile/components/Alert.txt +156 -0
  5. package/mcp-docs/mobile/components/AreaChart.txt +266 -0
  6. package/mcp-docs/mobile/components/Avatar.txt +196 -0
  7. package/mcp-docs/mobile/components/AvatarButton.txt +226 -0
  8. package/mcp-docs/mobile/components/Banner.txt +222 -0
  9. package/mcp-docs/mobile/components/BarChart.txt +816 -0
  10. package/mcp-docs/mobile/components/Box.txt +174 -0
  11. package/mcp-docs/mobile/components/BrowserBar.txt +147 -0
  12. package/mcp-docs/mobile/components/Button.txt +199 -0
  13. package/mcp-docs/mobile/components/ButtonGroup.txt +80 -0
  14. package/mcp-docs/mobile/components/Carousel.txt +1084 -0
  15. package/mcp-docs/mobile/components/CartesianChart.txt +826 -0
  16. package/mcp-docs/mobile/components/CellMedia.txt +71 -0
  17. package/mcp-docs/mobile/components/Checkbox.txt +246 -0
  18. package/mcp-docs/mobile/components/CheckboxCell.txt +202 -0
  19. package/mcp-docs/mobile/components/CheckboxGroup.txt +285 -0
  20. package/mcp-docs/mobile/components/Chip.txt +195 -0
  21. package/mcp-docs/mobile/components/Coachmark.txt +158 -0
  22. package/mcp-docs/mobile/components/Collapsible.txt +105 -0
  23. package/mcp-docs/mobile/components/ContainedAssetCard.txt +135 -0
  24. package/mcp-docs/mobile/components/ContentCard.txt +366 -0
  25. package/mcp-docs/mobile/components/ContentCardBody.txt +136 -0
  26. package/mcp-docs/mobile/components/ContentCardFooter.txt +128 -0
  27. package/mcp-docs/mobile/components/ContentCardHeader.txt +146 -0
  28. package/mcp-docs/mobile/components/ContentCell.txt +227 -0
  29. package/mcp-docs/mobile/components/ControlGroup.txt +444 -0
  30. package/mcp-docs/mobile/components/DatePicker.txt +497 -0
  31. package/mcp-docs/mobile/components/Divider.txt +139 -0
  32. package/mcp-docs/mobile/components/DotCount.txt +146 -0
  33. package/mcp-docs/mobile/components/DotStatusColor.txt +59 -0
  34. package/mcp-docs/mobile/components/DotSymbol.txt +135 -0
  35. package/mcp-docs/mobile/components/Fallback.txt +158 -0
  36. package/mcp-docs/mobile/components/FloatingAssetCard.txt +156 -0
  37. package/mcp-docs/mobile/components/HStack.txt +235 -0
  38. package/mcp-docs/mobile/components/HeroSquare.txt +48 -0
  39. package/mcp-docs/mobile/components/Icon.txt +52 -0
  40. package/mcp-docs/mobile/components/IconButton.txt +269 -0
  41. package/mcp-docs/mobile/components/InputChip.txt +188 -0
  42. package/mcp-docs/mobile/components/Interactable.txt +187 -0
  43. package/mcp-docs/mobile/components/LineChart.txt +1325 -0
  44. package/mcp-docs/mobile/components/Link.txt +292 -0
  45. package/mcp-docs/mobile/components/ListCell.txt +391 -0
  46. package/mcp-docs/mobile/components/LogoMark.txt +85 -0
  47. package/mcp-docs/mobile/components/LogoWordMark.txt +94 -0
  48. package/mcp-docs/mobile/components/Lottie.txt +139 -0
  49. package/mcp-docs/mobile/components/LottieStatusAnimation.txt +47 -0
  50. package/mcp-docs/mobile/components/Modal.txt +84 -0
  51. package/mcp-docs/mobile/components/ModalBody.txt +34 -0
  52. package/mcp-docs/mobile/components/ModalFooter.txt +25 -0
  53. package/mcp-docs/mobile/components/ModalHeader.txt +28 -0
  54. package/mcp-docs/mobile/components/MultiContentModule.txt +380 -0
  55. package/mcp-docs/mobile/components/NavigationTitle.txt +132 -0
  56. package/mcp-docs/mobile/components/NavigationTitleSelect.txt +142 -0
  57. package/mcp-docs/mobile/components/NudgeCard.txt +90 -0
  58. package/mcp-docs/mobile/components/Numpad.txt +341 -0
  59. package/mcp-docs/mobile/components/Overlay.txt +152 -0
  60. package/mcp-docs/mobile/components/PageFooter.txt +161 -0
  61. package/mcp-docs/mobile/components/PageHeader.txt +186 -0
  62. package/mcp-docs/mobile/components/PeriodSelector.txt +408 -0
  63. package/mcp-docs/mobile/components/Pictogram.txt +48 -0
  64. package/mcp-docs/mobile/components/Point.txt +205 -0
  65. package/mcp-docs/mobile/components/PortalProvider.txt +79 -0
  66. package/mcp-docs/mobile/components/Pressable.txt +211 -0
  67. package/mcp-docs/mobile/components/ProgressBar.txt +130 -0
  68. package/mcp-docs/mobile/components/ProgressBarWithFixedLabels.txt +161 -0
  69. package/mcp-docs/mobile/components/ProgressBarWithFloatLabel.txt +138 -0
  70. package/mcp-docs/mobile/components/ProgressCircle.txt +237 -0
  71. package/mcp-docs/mobile/components/Radio.txt +242 -0
  72. package/mcp-docs/mobile/components/RadioCell.txt +202 -0
  73. package/mcp-docs/mobile/components/RadioGroup.txt +282 -0
  74. package/mcp-docs/mobile/components/ReferenceLine.txt +153 -0
  75. package/mcp-docs/mobile/components/RemoteImage.txt +106 -0
  76. package/mcp-docs/mobile/components/RemoteImageGroup.txt +61 -0
  77. package/mcp-docs/mobile/components/RollingNumber.txt +789 -0
  78. package/mcp-docs/mobile/components/Scrubber.txt +204 -0
  79. package/mcp-docs/mobile/components/SearchInput.txt +192 -0
  80. package/mcp-docs/mobile/components/SectionHeader.txt +205 -0
  81. package/mcp-docs/mobile/components/SegmentedTabs.txt +316 -0
  82. package/mcp-docs/mobile/components/Select.txt +212 -0
  83. package/mcp-docs/mobile/components/SelectChip.txt +324 -0
  84. package/mcp-docs/mobile/components/SelectOption.txt +85 -0
  85. package/mcp-docs/mobile/components/SlideButton.txt +331 -0
  86. package/mcp-docs/mobile/components/Spacer.txt +84 -0
  87. package/mcp-docs/mobile/components/Sparkline.txt +123 -0
  88. package/mcp-docs/mobile/components/SparklineGradient.txt +107 -0
  89. package/mcp-docs/mobile/components/SparklineInteractive.txt +157 -0
  90. package/mcp-docs/mobile/components/SparklineInteractiveHeader.txt +73 -0
  91. package/mcp-docs/mobile/components/Spinner.txt +49 -0
  92. package/mcp-docs/mobile/components/SpotIcon.txt +48 -0
  93. package/mcp-docs/mobile/components/SpotRectangle.txt +48 -0
  94. package/mcp-docs/mobile/components/SpotSquare.txt +48 -0
  95. package/mcp-docs/mobile/components/Stepper.txt +528 -0
  96. package/mcp-docs/mobile/components/SubBrandLogoMark.txt +126 -0
  97. package/mcp-docs/mobile/components/SubBrandLogoWordMark.txt +126 -0
  98. package/mcp-docs/mobile/components/Switch.txt +98 -0
  99. package/mcp-docs/mobile/components/TabIndicator.txt +49 -0
  100. package/mcp-docs/mobile/components/TabLabel.txt +154 -0
  101. package/mcp-docs/mobile/components/TabNavigation.txt +147 -0
  102. package/mcp-docs/mobile/components/TabbedChips.txt +143 -0
  103. package/mcp-docs/mobile/components/Tabs.txt +191 -0
  104. package/mcp-docs/mobile/components/Tag.txt +301 -0
  105. package/mcp-docs/mobile/components/Text.txt +212 -0
  106. package/mcp-docs/mobile/components/TextInput.txt +718 -0
  107. package/mcp-docs/mobile/components/ThemeProvider.txt +133 -0
  108. package/mcp-docs/mobile/components/Toast.txt +197 -0
  109. package/mcp-docs/mobile/components/Tooltip.txt +60 -0
  110. package/mcp-docs/mobile/components/TopNavBar.txt +162 -0
  111. package/mcp-docs/mobile/components/Tour.txt +159 -0
  112. package/mcp-docs/mobile/components/Tray.txt +253 -0
  113. package/mcp-docs/mobile/components/UpsellCard.txt +322 -0
  114. package/mcp-docs/mobile/components/VStack.txt +223 -0
  115. package/mcp-docs/mobile/components/XAxis.txt +622 -0
  116. package/mcp-docs/mobile/components/YAxis.txt +568 -0
  117. package/mcp-docs/mobile/getting-started/introduction.txt +99 -0
  118. package/mcp-docs/mobile/getting-started/mcp-server.txt +94 -0
  119. package/mcp-docs/mobile/getting-started/playground.txt +25 -0
  120. package/mcp-docs/mobile/hooks/useDimensions.txt +47 -0
  121. package/mcp-docs/mobile/hooks/useOverlayContentContext.txt +215 -0
  122. package/mcp-docs/mobile/hooks/useTheme.txt +110 -0
  123. package/mcp-docs/mobile/routes.txt +132 -0
  124. package/mcp-docs/web/components/Accordion.txt +190 -0
  125. package/mcp-docs/web/components/AccordionItem.txt +32 -0
  126. package/mcp-docs/web/components/Alert.txt +165 -0
  127. package/mcp-docs/web/components/AreaChart.txt +511 -0
  128. package/mcp-docs/web/components/Avatar.txt +212 -0
  129. package/mcp-docs/web/components/AvatarButton.txt +241 -0
  130. package/mcp-docs/web/components/Banner.txt +227 -0
  131. package/mcp-docs/web/components/BarChart.txt +1268 -0
  132. package/mcp-docs/web/components/Box.txt +176 -0
  133. package/mcp-docs/web/components/Button.txt +213 -0
  134. package/mcp-docs/web/components/ButtonGroup.txt +80 -0
  135. package/mcp-docs/web/components/Calendar.txt +182 -0
  136. package/mcp-docs/web/components/Carousel.txt +1576 -0
  137. package/mcp-docs/web/components/CartesianChart.txt +1045 -0
  138. package/mcp-docs/web/components/CellMedia.txt +57 -0
  139. package/mcp-docs/web/components/Checkbox.txt +189 -0
  140. package/mcp-docs/web/components/CheckboxCell.txt +203 -0
  141. package/mcp-docs/web/components/CheckboxGroup.txt +220 -0
  142. package/mcp-docs/web/components/Chip.txt +197 -0
  143. package/mcp-docs/web/components/Coachmark.txt +189 -0
  144. package/mcp-docs/web/components/Collapsible.txt +120 -0
  145. package/mcp-docs/web/components/ContainedAssetCard.txt +233 -0
  146. package/mcp-docs/web/components/ContentCard.txt +368 -0
  147. package/mcp-docs/web/components/ContentCardBody.txt +138 -0
  148. package/mcp-docs/web/components/ContentCardFooter.txt +130 -0
  149. package/mcp-docs/web/components/ContentCardHeader.txt +148 -0
  150. package/mcp-docs/web/components/ContentCell.txt +220 -0
  151. package/mcp-docs/web/components/ControlGroup.txt +437 -0
  152. package/mcp-docs/web/components/DatePicker.txt +506 -0
  153. package/mcp-docs/web/components/Divider.txt +144 -0
  154. package/mcp-docs/web/components/DotCount.txt +150 -0
  155. package/mcp-docs/web/components/DotStatusColor.txt +59 -0
  156. package/mcp-docs/web/components/DotSymbol.txt +138 -0
  157. package/mcp-docs/web/components/Dropdown.txt +120 -0
  158. package/mcp-docs/web/components/Fallback.txt +164 -0
  159. package/mcp-docs/web/components/FloatingAssetCard.txt +251 -0
  160. package/mcp-docs/web/components/FullscreenAlert.txt +70 -0
  161. package/mcp-docs/web/components/FullscreenModal.txt +146 -0
  162. package/mcp-docs/web/components/FullscreenModalLayout.txt +188 -0
  163. package/mcp-docs/web/components/Grid.txt +237 -0
  164. package/mcp-docs/web/components/GridColumn.txt +210 -0
  165. package/mcp-docs/web/components/HStack.txt +237 -0
  166. package/mcp-docs/web/components/HeroSquare.txt +49 -0
  167. package/mcp-docs/web/components/Icon.txt +146 -0
  168. package/mcp-docs/web/components/IconButton.txt +391 -0
  169. package/mcp-docs/web/components/InputChip.txt +188 -0
  170. package/mcp-docs/web/components/Interactable.txt +194 -0
  171. package/mcp-docs/web/components/LineChart.txt +1577 -0
  172. package/mcp-docs/web/components/Link.txt +244 -0
  173. package/mcp-docs/web/components/ListCell.txt +397 -0
  174. package/mcp-docs/web/components/LogoMark.txt +85 -0
  175. package/mcp-docs/web/components/LogoWordMark.txt +94 -0
  176. package/mcp-docs/web/components/Lottie.txt +158 -0
  177. package/mcp-docs/web/components/LottieStatusAnimation.txt +58 -0
  178. package/mcp-docs/web/components/MediaQueryProvider.txt +109 -0
  179. package/mcp-docs/web/components/Modal.txt +193 -0
  180. package/mcp-docs/web/components/ModalBody.txt +118 -0
  181. package/mcp-docs/web/components/ModalFooter.txt +120 -0
  182. package/mcp-docs/web/components/ModalHeader.txt +124 -0
  183. package/mcp-docs/web/components/MultiContentModule.txt +382 -0
  184. package/mcp-docs/web/components/NavigationBar.txt +103 -0
  185. package/mcp-docs/web/components/NavigationTitle.txt +26 -0
  186. package/mcp-docs/web/components/NavigationTitleSelect.txt +46 -0
  187. package/mcp-docs/web/components/NudgeCard.txt +182 -0
  188. package/mcp-docs/web/components/Overlay.txt +172 -0
  189. package/mcp-docs/web/components/PageFooter.txt +185 -0
  190. package/mcp-docs/web/components/PageHeader.txt +244 -0
  191. package/mcp-docs/web/components/Pagination.txt +500 -0
  192. package/mcp-docs/web/components/PeriodSelector.txt +704 -0
  193. package/mcp-docs/web/components/Pictogram.txt +49 -0
  194. package/mcp-docs/web/components/Point.txt +461 -0
  195. package/mcp-docs/web/components/PortalProvider.txt +77 -0
  196. package/mcp-docs/web/components/Pressable.txt +194 -0
  197. package/mcp-docs/web/components/ProgressBar.txt +164 -0
  198. package/mcp-docs/web/components/ProgressBarWithFixedLabels.txt +213 -0
  199. package/mcp-docs/web/components/ProgressBarWithFloatLabel.txt +182 -0
  200. package/mcp-docs/web/components/ProgressCircle.txt +444 -0
  201. package/mcp-docs/web/components/Radio.txt +220 -0
  202. package/mcp-docs/web/components/RadioCell.txt +216 -0
  203. package/mcp-docs/web/components/RadioGroup.txt +289 -0
  204. package/mcp-docs/web/components/ReferenceLine.txt +452 -0
  205. package/mcp-docs/web/components/RemoteImage.txt +166 -0
  206. package/mcp-docs/web/components/RemoteImageGroup.txt +87 -0
  207. package/mcp-docs/web/components/RollingNumber.txt +1022 -0
  208. package/mcp-docs/web/components/Scrubber.txt +232 -0
  209. package/mcp-docs/web/components/SearchInput.txt +118 -0
  210. package/mcp-docs/web/components/SectionHeader.txt +218 -0
  211. package/mcp-docs/web/components/SegmentedTabs.txt +325 -0
  212. package/mcp-docs/web/components/Select.txt +225 -0
  213. package/mcp-docs/web/components/SelectChip.txt +315 -0
  214. package/mcp-docs/web/components/SelectOption.txt +166 -0
  215. package/mcp-docs/web/components/Sidebar.txt +350 -0
  216. package/mcp-docs/web/components/SidebarItem.txt +132 -0
  217. package/mcp-docs/web/components/SidebarMoreMenu.txt +31 -0
  218. package/mcp-docs/web/components/Spacer.txt +174 -0
  219. package/mcp-docs/web/components/Sparkline.txt +123 -0
  220. package/mcp-docs/web/components/SparklineGradient.txt +107 -0
  221. package/mcp-docs/web/components/SparklineInteractive.txt +154 -0
  222. package/mcp-docs/web/components/SparklineInteractiveHeader.txt +77 -0
  223. package/mcp-docs/web/components/Spinner.txt +129 -0
  224. package/mcp-docs/web/components/SpotIcon.txt +49 -0
  225. package/mcp-docs/web/components/SpotRectangle.txt +49 -0
  226. package/mcp-docs/web/components/SpotSquare.txt +49 -0
  227. package/mcp-docs/web/components/Stepper.txt +683 -0
  228. package/mcp-docs/web/components/SubBrandLogoMark.txt +126 -0
  229. package/mcp-docs/web/components/SubBrandLogoWordMark.txt +126 -0
  230. package/mcp-docs/web/components/Switch.txt +86 -0
  231. package/mcp-docs/web/components/TabIndicator.txt +49 -0
  232. package/mcp-docs/web/components/TabLabel.txt +159 -0
  233. package/mcp-docs/web/components/TabNavigation.txt +160 -0
  234. package/mcp-docs/web/components/TabbedChips.txt +156 -0
  235. package/mcp-docs/web/components/Table.txt +368 -0
  236. package/mcp-docs/web/components/TableBody.txt +84 -0
  237. package/mcp-docs/web/components/TableCaption.txt +103 -0
  238. package/mcp-docs/web/components/TableCell.txt +166 -0
  239. package/mcp-docs/web/components/TableCellFallback.txt +98 -0
  240. package/mcp-docs/web/components/TableFooter.txt +84 -0
  241. package/mcp-docs/web/components/TableHeader.txt +101 -0
  242. package/mcp-docs/web/components/TableRow.txt +141 -0
  243. package/mcp-docs/web/components/Tabs.txt +213 -0
  244. package/mcp-docs/web/components/Tag.txt +305 -0
  245. package/mcp-docs/web/components/Text.txt +233 -0
  246. package/mcp-docs/web/components/TextInput.txt +653 -0
  247. package/mcp-docs/web/components/ThemeProvider.txt +200 -0
  248. package/mcp-docs/web/components/TileButton.txt +159 -0
  249. package/mcp-docs/web/components/Toast.txt +204 -0
  250. package/mcp-docs/web/components/Tooltip.txt +90 -0
  251. package/mcp-docs/web/components/Tour.txt +180 -0
  252. package/mcp-docs/web/components/Tray.txt +289 -0
  253. package/mcp-docs/web/components/UpsellCard.txt +320 -0
  254. package/mcp-docs/web/components/VStack.txt +225 -0
  255. package/mcp-docs/web/components/XAxis.txt +620 -0
  256. package/mcp-docs/web/components/YAxis.txt +549 -0
  257. package/mcp-docs/web/getting-started/introduction.txt +99 -0
  258. package/mcp-docs/web/getting-started/mcp-server.txt +94 -0
  259. package/mcp-docs/web/getting-started/playground.txt +25 -0
  260. package/mcp-docs/web/hooks/useBreakpoints.txt +33 -0
  261. package/mcp-docs/web/hooks/useDimensions.txt +55 -0
  262. package/mcp-docs/web/hooks/useHasMounted.txt +55 -0
  263. package/mcp-docs/web/hooks/useIsoEffect.txt +42 -0
  264. package/mcp-docs/web/hooks/useMediaQuery.txt +94 -0
  265. package/mcp-docs/web/hooks/useOverlayContentContext.txt +217 -0
  266. package/mcp-docs/web/hooks/useScrollBlocker.txt +63 -0
  267. package/mcp-docs/web/hooks/useTheme.txt +105 -0
  268. package/mcp-docs/web/routes.txt +155 -0
  269. package/package.json +1 -1
@@ -0,0 +1,1577 @@
1
+ # LineChart
2
+
3
+ A flexible line chart component for displaying data trends over time. Supports multiple series, custom curves, areas, scrubbing, and interactive data exploration.
4
+
5
+ ## Import
6
+
7
+ ```jsx
8
+ import { LineChart } from '@coinbase/cds-web-visualization'
9
+ ```
10
+
11
+ ## Props
12
+
13
+ | Prop | Type | Required | Default | Description |
14
+ | --- | --- | --- | --- | --- |
15
+ | `AreaComponent` | `AreaComponent` | No | `-` | Custom component to render line area fill. |
16
+ | `LineComponent` | `LineComponent` | No | `-` | Component to render the line. Takes precedence over the type prop if provided. |
17
+ | `accentHeight` | `string \| number` | No | `-` | - |
18
+ | `accumulate` | `none \| sum` | No | `-` | - |
19
+ | `additive` | `sum \| replace` | No | `-` | - |
20
+ | `alignContent` | `ResponsiveProp<center \| end \| normal \| start \| flex-start \| flex-end \| space-between \| space-around \| space-evenly \| stretch \| baseline \| first baseline \| last baseline>` | No | `-` | - |
21
+ | `alignItems` | `ResponsiveProp<center \| end \| normal \| start \| flex-start \| flex-end \| stretch \| baseline \| first baseline \| last baseline \| self-start \| self-end>` | No | `-` | - |
22
+ | `alignSelf` | `ResponsiveProp<center \| end \| normal \| auto \| start \| flex-start \| flex-end \| stretch \| baseline \| first baseline \| last baseline \| self-start \| self-end>` | No | `-` | - |
23
+ | `alignmentBaseline` | `alphabetic \| hanging \| ideographic \| mathematical \| inherit \| auto \| baseline \| before-edge \| text-before-edge \| middle \| central \| after-edge \| text-after-edge` | No | `-` | - |
24
+ | `allowReorder` | `no \| yes` | No | `-` | - |
25
+ | `alphabetic` | `string \| number` | No | `-` | - |
26
+ | `amplitude` | `string \| number` | No | `-` | - |
27
+ | `animate` | `boolean` | No | `true` | Whether to animate the chart. |
28
+ | `arabicForm` | `initial \| medial \| terminal \| isolated` | No | `-` | - |
29
+ | `areaType` | `dotted \| solid \| gradient` | No | `'gradient'` | The type of area fill to add to the line. |
30
+ | `as` | `svg` | No | `-` | - |
31
+ | `ascent` | `string \| number` | No | `-` | - |
32
+ | `aspectRatio` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - |
33
+ | `attributeName` | `string` | No | `-` | - |
34
+ | `attributeType` | `string` | No | `-` | - |
35
+ | `autoReverse` | `false \| true \| true \| false` | No | `-` | - |
36
+ | `azimuth` | `string \| number` | No | `-` | - |
37
+ | `background` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | - |
38
+ | `baseFrequency` | `string \| number` | No | `-` | - |
39
+ | `baseProfile` | `string \| number` | No | `-` | - |
40
+ | `baselineShift` | `string \| number` | No | `-` | - |
41
+ | `bbox` | `string \| number` | No | `-` | - |
42
+ | `begin` | `string \| number` | No | `-` | - |
43
+ | `bias` | `string \| number` | No | `-` | - |
44
+ | `borderBottomLeftRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
45
+ | `borderBottomRightRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
46
+ | `borderBottomWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
47
+ | `borderColor` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | - |
48
+ | `borderEndWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
49
+ | `borderRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
50
+ | `borderStartWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
51
+ | `borderTopLeftRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
52
+ | `borderTopRightRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000` | No | `-` | - |
53
+ | `borderTopWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
54
+ | `borderWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | - |
55
+ | `bordered` | `boolean` | No | `-` | Add a border around all sides of the box. |
56
+ | `borderedBottom` | `boolean` | No | `-` | Add a border to the bottom side of the box. |
57
+ | `borderedEnd` | `boolean` | No | `-` | Add a border to the trailing side of the box. |
58
+ | `borderedHorizontal` | `boolean` | No | `-` | Add a border to the leading and trailing sides of the box. |
59
+ | `borderedStart` | `boolean` | No | `-` | Add a border to the leading side of the box. |
60
+ | `borderedTop` | `boolean` | No | `-` | Add a border to the top side of the box. |
61
+ | `borderedVertical` | `boolean` | No | `-` | Add a border to the top and bottom sides of the box. |
62
+ | `bottom` | `ResponsiveProp<Bottom<string \| number>>` | No | `-` | - |
63
+ | `by` | `string \| number` | No | `-` | - |
64
+ | `calcMode` | `string \| number` | No | `-` | - |
65
+ | `capHeight` | `string \| number` | No | `-` | - |
66
+ | `className` | `string` | No | `-` | - |
67
+ | `clip` | `string \| number` | No | `-` | - |
68
+ | `clipPath` | `string` | No | `-` | - |
69
+ | `clipPathUnits` | `string \| number` | No | `-` | - |
70
+ | `clipRule` | `string \| number` | No | `-` | - |
71
+ | `color` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | - |
72
+ | `colorInterpolation` | `string \| number` | No | `-` | - |
73
+ | `colorInterpolationFilters` | `inherit \| auto \| sRGB \| linearRGB` | No | `-` | - |
74
+ | `colorProfile` | `string \| number` | No | `-` | - |
75
+ | `colorRendering` | `string \| number` | No | `-` | - |
76
+ | `columnGap` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - |
77
+ | `contentScriptType` | `string \| number` | No | `-` | - |
78
+ | `contentStyleType` | `string \| number` | No | `-` | - |
79
+ | `crossOrigin` | ` \| anonymous \| use-credentials` | No | `-` | - |
80
+ | `cursor` | `string \| number` | No | `-` | - |
81
+ | `curve` | `bump \| catmullRom \| linear \| linearClosed \| monotone \| natural \| step \| stepBefore \| stepAfter` | No | `'linear'` | The curve interpolation method to use for the line. |
82
+ | `cx` | `string \| number` | No | `-` | - |
83
+ | `cy` | `string \| number` | No | `-` | - |
84
+ | `d` | `string` | No | `-` | - |
85
+ | `dangerouslySetBackground` | `string` | No | `-` | - |
86
+ | `decelerate` | `string \| number` | No | `-` | - |
87
+ | `descent` | `string \| number` | No | `-` | - |
88
+ | `diffuseConstant` | `string \| number` | No | `-` | - |
89
+ | `direction` | `string \| number` | No | `-` | - |
90
+ | `display` | `ResponsiveProp<grid \| revert \| none \| block \| inline \| inline-block \| flex \| inline-flex \| inline-grid \| contents \| flow-root \| list-item>` | No | `-` | - |
91
+ | `divisor` | `string \| number` | No | `-` | - |
92
+ | `dominantBaseline` | `string \| number` | No | `-` | - |
93
+ | `dur` | `string \| number` | No | `-` | - |
94
+ | `dx` | `string \| number` | No | `-` | - |
95
+ | `dy` | `string \| number` | No | `-` | - |
96
+ | `edgeMode` | `string \| number` | No | `-` | - |
97
+ | `elevation` | `0 \| 1 \| 2` | No | `-` | - |
98
+ | `enableBackground` | `string \| number` | No | `-` | - |
99
+ | `enableScrubbing` | `boolean` | No | `-` | Enables scrubbing interactions. When true, allows scrubbing and makes scrubber components interactive. |
100
+ | `end` | `string \| number` | No | `-` | - |
101
+ | `exponent` | `string \| number` | No | `-` | - |
102
+ | `externalResourcesRequired` | `false \| true \| true \| false` | No | `-` | - |
103
+ | `fill` | `string` | No | `-` | - |
104
+ | `fillOpacity` | `string \| number` | No | `-` | - |
105
+ | `fillRule` | `inherit \| nonzero \| evenodd` | No | `-` | - |
106
+ | `filter` | `string` | No | `-` | - |
107
+ | `filterRes` | `string \| number` | No | `-` | - |
108
+ | `filterUnits` | `string \| number` | No | `-` | - |
109
+ | `flexBasis` | `ResponsiveProp<FlexBasis<string \| number>>` | No | `-` | - |
110
+ | `flexDirection` | `ResponsiveProp<row \| row-reverse \| column \| column-reverse>` | No | `-` | - |
111
+ | `flexGrow` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset` | No | `-` | - |
112
+ | `flexShrink` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset` | No | `-` | - |
113
+ | `flexWrap` | `ResponsiveProp<nowrap \| wrap \| wrap-reverse>` | No | `-` | - |
114
+ | `floodColor` | `string \| number` | No | `-` | - |
115
+ | `floodOpacity` | `string \| number` | No | `-` | - |
116
+ | `focusable` | `auto \| Booleanish` | No | `-` | - |
117
+ | `font` | `ResponsiveProp<FontFamily \| inherit>` | No | `-` | - |
118
+ | `fontFamily` | `ResponsiveProp<FontFamily \| inherit>` | No | `-` | - |
119
+ | `fontSize` | `ResponsiveProp<FontSize \| inherit>` | No | `-` | - |
120
+ | `fontSizeAdjust` | `string \| number` | No | `-` | - |
121
+ | `fontStretch` | `string \| number` | No | `-` | - |
122
+ | `fontStyle` | `string \| number` | No | `-` | - |
123
+ | `fontVariant` | `string \| number` | No | `-` | - |
124
+ | `fontWeight` | `ResponsiveProp<FontWeight \| inherit>` | No | `-` | - |
125
+ | `format` | `string \| number` | No | `-` | - |
126
+ | `fr` | `string \| number` | No | `-` | - |
127
+ | `from` | `string \| number` | No | `-` | - |
128
+ | `fx` | `string \| number` | No | `-` | - |
129
+ | `fy` | `string \| number` | No | `-` | - |
130
+ | `g1` | `string \| number` | No | `-` | - |
131
+ | `g2` | `string \| number` | No | `-` | - |
132
+ | `gap` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - |
133
+ | `glyphName` | `string \| number` | No | `-` | - |
134
+ | `glyphOrientationHorizontal` | `string \| number` | No | `-` | - |
135
+ | `glyphOrientationVertical` | `string \| number` | No | `-` | - |
136
+ | `glyphRef` | `string \| number` | No | `-` | - |
137
+ | `gradientTransform` | `string` | No | `-` | - |
138
+ | `gradientUnits` | `string` | No | `-` | - |
139
+ | `grid` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none` | No | `-` | - |
140
+ | `gridArea` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - |
141
+ | `gridAutoColumns` | `ResponsiveProp<GridAutoColumns<string \| number>>` | No | `-` | - |
142
+ | `gridAutoFlow` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| row \| column \| dense` | No | `-` | - |
143
+ | `gridAutoRows` | `ResponsiveProp<GridAutoRows<string \| number>>` | No | `-` | - |
144
+ | `gridColumn` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - |
145
+ | `gridColumnEnd` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - |
146
+ | `gridColumnStart` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - |
147
+ | `gridRow` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - |
148
+ | `gridRowEnd` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - |
149
+ | `gridRowStart` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - |
150
+ | `gridTemplate` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none` | No | `-` | - |
151
+ | `gridTemplateAreas` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none` | No | `-` | - |
152
+ | `gridTemplateColumns` | `ResponsiveProp<GridTemplateColumns<string \| number>>` | No | `-` | - |
153
+ | `gridTemplateRows` | `ResponsiveProp<GridTemplateRows<string \| number>>` | No | `-` | - |
154
+ | `hanging` | `string \| number` | No | `-` | - |
155
+ | `height` | `ResponsiveProp<Height<string \| number>>` | No | `-` | - |
156
+ | `horizAdvX` | `string \| number` | No | `-` | - |
157
+ | `horizOriginX` | `string \| number` | No | `-` | - |
158
+ | `href` | `string` | No | `-` | - |
159
+ | `id` | `string` | No | `-` | - |
160
+ | `ideographic` | `string \| number` | No | `-` | - |
161
+ | `imageRendering` | `string \| number` | No | `-` | - |
162
+ | `in` | `string` | No | `-` | - |
163
+ | `in2` | `string \| number` | No | `-` | - |
164
+ | `inset` | `number \| Partial<ChartInset>` | No | `-` | Inset around the entire chart (outside the axes). |
165
+ | `intercept` | `string \| number` | No | `-` | - |
166
+ | `justifyContent` | `ResponsiveProp<left \| right \| center \| end \| normal \| start \| flex-start \| flex-end \| space-between \| space-around \| space-evenly \| stretch>` | No | `-` | - |
167
+ | `k` | `string \| number` | No | `-` | - |
168
+ | `k1` | `string \| number` | No | `-` | - |
169
+ | `k2` | `string \| number` | No | `-` | - |
170
+ | `k3` | `string \| number` | No | `-` | - |
171
+ | `k4` | `string \| number` | No | `-` | - |
172
+ | `kernelMatrix` | `string \| number` | No | `-` | - |
173
+ | `kernelUnitLength` | `string \| number` | No | `-` | - |
174
+ | `kerning` | `string \| number` | No | `-` | - |
175
+ | `key` | `Key \| null` | No | `-` | - |
176
+ | `keyPoints` | `string \| number` | No | `-` | - |
177
+ | `keySplines` | `string \| number` | No | `-` | - |
178
+ | `keyTimes` | `string \| number` | No | `-` | - |
179
+ | `lang` | `string` | No | `-` | - |
180
+ | `left` | `ResponsiveProp<Left<string \| number>>` | No | `-` | - |
181
+ | `lengthAdjust` | `string \| number` | No | `-` | - |
182
+ | `letterSpacing` | `string \| number` | No | `-` | - |
183
+ | `lightingColor` | `string \| number` | No | `-` | - |
184
+ | `limitingConeAngle` | `string \| number` | No | `-` | - |
185
+ | `lineHeight` | `ResponsiveProp<LineHeight \| inherit>` | No | `-` | - |
186
+ | `local` | `string \| number` | No | `-` | - |
187
+ | `margin` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
188
+ | `marginBottom` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
189
+ | `marginEnd` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
190
+ | `marginStart` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
191
+ | `marginTop` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
192
+ | `marginX` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
193
+ | `marginY` | `ResponsiveProp<0 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
194
+ | `markerEnd` | `string` | No | `-` | - |
195
+ | `markerHeight` | `string \| number` | No | `-` | - |
196
+ | `markerMid` | `string` | No | `-` | - |
197
+ | `markerStart` | `string` | No | `-` | - |
198
+ | `markerUnits` | `string \| number` | No | `-` | - |
199
+ | `markerWidth` | `string \| number` | No | `-` | - |
200
+ | `mask` | `string` | No | `-` | - |
201
+ | `maskContentUnits` | `string \| number` | No | `-` | - |
202
+ | `maskUnits` | `string \| number` | No | `-` | - |
203
+ | `mathematical` | `string \| number` | No | `-` | - |
204
+ | `max` | `string \| number` | No | `-` | - |
205
+ | `maxHeight` | `ResponsiveProp<MaxHeight<string \| number>>` | No | `-` | - |
206
+ | `maxWidth` | `ResponsiveProp<MaxWidth<string \| number>>` | No | `-` | - |
207
+ | `media` | `string` | No | `-` | - |
208
+ | `method` | `string` | No | `-` | - |
209
+ | `min` | `string \| number` | No | `-` | - |
210
+ | `minHeight` | `ResponsiveProp<MinHeight<string \| number>>` | No | `-` | - |
211
+ | `minWidth` | `ResponsiveProp<MinWidth<string \| number>>` | No | `-` | - |
212
+ | `mode` | `string \| number` | No | `-` | - |
213
+ | `name` | `string` | No | `-` | - |
214
+ | `numOctaves` | `string \| number` | No | `-` | - |
215
+ | `offset` | `string \| number` | No | `-` | - |
216
+ | `onChange` | `FormEventHandler<SVGSVGElement>` | No | `-` | - |
217
+ | `onPointClick` | `((event: MouseEvent<Element, MouseEvent>, point: { x: number; y: number; dataX: number; dataY: number; }) => void)` | No | `-` | Handler for when a dot is clicked. Automatically makes dots appear pressable when provided. |
218
+ | `onScrubberPositionChange` | `((index: number) => void) \| undefined` | No | `-` | Callback fired when the scrubber position changes. Receives the dataIndex of the scrubber or undefined when not scrubbing. |
219
+ | `opacity` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset` | No | `-` | - |
220
+ | `operator` | `string \| number` | No | `-` | - |
221
+ | `order` | `string \| number` | No | `-` | - |
222
+ | `orient` | `string \| number` | No | `-` | - |
223
+ | `orientation` | `string \| number` | No | `-` | - |
224
+ | `origin` | `string \| number` | No | `-` | - |
225
+ | `overflow` | `ResponsiveProp<clip \| auto \| visible \| hidden \| scroll>` | No | `-` | - |
226
+ | `overlinePosition` | `string \| number` | No | `-` | - |
227
+ | `overlineThickness` | `string \| number` | No | `-` | - |
228
+ | `padding` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - |
229
+ | `paddingBottom` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - |
230
+ | `paddingEnd` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - |
231
+ | `paddingStart` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - |
232
+ | `paddingTop` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - |
233
+ | `paddingX` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - |
234
+ | `paddingY` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - |
235
+ | `paintOrder` | `string \| number` | No | `-` | - |
236
+ | `panose1` | `string \| number` | No | `-` | - |
237
+ | `path` | `string` | No | `-` | - |
238
+ | `pathLength` | `string \| number` | No | `-` | - |
239
+ | `patternContentUnits` | `string` | No | `-` | - |
240
+ | `patternTransform` | `string \| number` | No | `-` | - |
241
+ | `patternUnits` | `string` | No | `-` | - |
242
+ | `pin` | `top \| bottom \| left \| right \| all` | No | `-` | Direction in which to absolutely pin the box. |
243
+ | `pointerEvents` | `string \| number` | No | `-` | - |
244
+ | `points` | `string` | No | `-` | - |
245
+ | `pointsAtX` | `string \| number` | No | `-` | - |
246
+ | `pointsAtY` | `string \| number` | No | `-` | - |
247
+ | `pointsAtZ` | `string \| number` | No | `-` | - |
248
+ | `position` | `ResponsiveProp<static \| relative \| absolute \| fixed \| sticky>` | No | `-` | - |
249
+ | `preserveAlpha` | `false \| true \| true \| false` | No | `-` | - |
250
+ | `preserveAspectRatio` | `string` | No | `-` | - |
251
+ | `primitiveUnits` | `string \| number` | No | `-` | - |
252
+ | `r` | `string \| number` | No | `-` | - |
253
+ | `radius` | `string \| number` | No | `-` | - |
254
+ | `ref` | `((instance: SVGSVGElement \| null) => void) \| RefObject<SVGSVGElement> \| null` | No | `-` | - |
255
+ | `refX` | `string \| number` | No | `-` | - |
256
+ | `refY` | `string \| number` | No | `-` | - |
257
+ | `renderPoints` | `((params: RenderPointsParams) => boolean \| PointConfig \| null) \| undefined` | No | `-` | Callback function to determine how to render points at each data point in the series. Called for every entry in the data array. |
258
+ | `renderingIntent` | `string \| number` | No | `-` | - |
259
+ | `repeatCount` | `string \| number` | No | `-` | - |
260
+ | `repeatDur` | `string \| number` | No | `-` | - |
261
+ | `requiredExtensions` | `string \| number` | No | `-` | - |
262
+ | `requiredFeatures` | `string \| number` | No | `-` | - |
263
+ | `restart` | `string \| number` | No | `-` | - |
264
+ | `result` | `string` | No | `-` | - |
265
+ | `right` | `ResponsiveProp<Right<string \| number>>` | No | `-` | - |
266
+ | `role` | `grid \| article \| button \| dialog \| figure \| form \| img \| link \| main \| menu \| menuitem \| option \| search \| table \| switch \| string & {} \| none \| row \| alert \| alertdialog \| application \| banner \| cell \| checkbox \| columnheader \| combobox \| complementary \| contentinfo \| definition \| directory \| document \| feed \| gridcell \| group \| heading \| list \| listbox \| listitem \| log \| marquee \| math \| menubar \| menuitemcheckbox \| menuitemradio \| navigation \| note \| presentation \| progressbar \| radio \| radiogroup \| region \| rowgroup \| rowheader \| scrollbar \| searchbox \| separator \| slider \| spinbutton \| status \| tab \| tablist \| tabpanel \| term \| textbox \| timer \| toolbar \| tooltip \| tree \| treegrid \| treeitem` | No | `-` | - |
267
+ | `rotate` | `string \| number` | No | `-` | - |
268
+ | `rowGap` | `0 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9` | No | `-` | - |
269
+ | `rx` | `string \| number` | No | `-` | - |
270
+ | `ry` | `string \| number` | No | `-` | - |
271
+ | `scale` | `string \| number` | No | `-` | - |
272
+ | `seed` | `string \| number` | No | `-` | - |
273
+ | `series` | `LineSeries[]` | No | `-` | Configuration objects that define how to visualize the data. Each series supports Line component props for individual customization. |
274
+ | `shapeRendering` | `string \| number` | No | `-` | - |
275
+ | `showArea` | `boolean` | No | `-` | Show area fill under the line. |
276
+ | `showXAxis` | `boolean` | No | `-` | Whether to show the X axis. |
277
+ | `showYAxis` | `boolean` | No | `-` | Whether to show the Y axis. |
278
+ | `slope` | `string \| number` | No | `-` | - |
279
+ | `spacing` | `string \| number` | No | `-` | - |
280
+ | `specularConstant` | `string \| number` | No | `-` | - |
281
+ | `specularExponent` | `string \| number` | No | `-` | - |
282
+ | `speed` | `string \| number` | No | `-` | - |
283
+ | `spreadMethod` | `string` | No | `-` | - |
284
+ | `startOffset` | `string \| number` | No | `-` | - |
285
+ | `stdDeviation` | `string \| number` | No | `-` | - |
286
+ | `stemh` | `string \| number` | No | `-` | - |
287
+ | `stemv` | `string \| number` | No | `-` | - |
288
+ | `stitchTiles` | `string \| number` | No | `-` | - |
289
+ | `stopColor` | `string` | No | `-` | - |
290
+ | `stopOpacity` | `string \| number` | No | `-` | - |
291
+ | `strikethroughPosition` | `string \| number` | No | `-` | - |
292
+ | `strikethroughThickness` | `string \| number` | No | `-` | - |
293
+ | `string` | `string \| number` | No | `-` | - |
294
+ | `stroke` | `string` | No | `-` | - |
295
+ | `strokeDasharray` | `string \| number` | No | `-` | - |
296
+ | `strokeDashoffset` | `string \| number` | No | `-` | - |
297
+ | `strokeLinecap` | `inherit \| butt \| round \| square` | No | `-` | - |
298
+ | `strokeLinejoin` | `inherit \| round \| miter \| bevel` | No | `-` | - |
299
+ | `strokeMiterlimit` | `string \| number` | No | `-` | - |
300
+ | `strokeOpacity` | `string \| number` | No | `-` | - |
301
+ | `strokeWidth` | `number` | No | `-` | - |
302
+ | `style` | `CSSProperties` | No | `-` | - |
303
+ | `suppressHydrationWarning` | `boolean` | No | `-` | - |
304
+ | `surfaceScale` | `string \| number` | No | `-` | - |
305
+ | `systemLanguage` | `string \| number` | No | `-` | - |
306
+ | `tabIndex` | `number` | No | `-` | - |
307
+ | `tableValues` | `string \| number` | No | `-` | - |
308
+ | `target` | `string` | No | `-` | - |
309
+ | `targetX` | `string \| number` | No | `-` | - |
310
+ | `targetY` | `string \| number` | No | `-` | - |
311
+ | `testID` | `string` | No | `-` | Used to locate this element in unit and end-to-end tests. Under the hood, testID translates to data-testid on Web. On Mobile, testID stays the same - testID |
312
+ | `textAlign` | `ResponsiveProp<center \| end \| start \| justify>` | No | `-` | - |
313
+ | `textAnchor` | `string` | No | `-` | - |
314
+ | `textDecoration` | `ResponsiveProp<none \| underline \| overline \| line-through \| underline overline \| underline double>` | No | `-` | - |
315
+ | `textLength` | `string \| number` | No | `-` | - |
316
+ | `textRendering` | `string \| number` | No | `-` | - |
317
+ | `textTransform` | `ResponsiveProp<capitalize \| lowercase \| none \| uppercase>` | No | `-` | - |
318
+ | `to` | `string \| number` | No | `-` | - |
319
+ | `top` | `ResponsiveProp<Top<string \| number>>` | No | `-` | - |
320
+ | `transform` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none` | No | `-` | - |
321
+ | `type` | `dotted \| solid \| gradient` | No | `'solid'` | The type of line to render. |
322
+ | `u1` | `string \| number` | No | `-` | - |
323
+ | `u2` | `string \| number` | No | `-` | - |
324
+ | `underlinePosition` | `string \| number` | No | `-` | - |
325
+ | `underlineThickness` | `string \| number` | No | `-` | - |
326
+ | `unicode` | `string \| number` | No | `-` | - |
327
+ | `unicodeBidi` | `string \| number` | No | `-` | - |
328
+ | `unicodeRange` | `string \| number` | No | `-` | - |
329
+ | `unitsPerEm` | `string \| number` | No | `-` | - |
330
+ | `userSelect` | `ResponsiveProp<text \| none \| auto \| all>` | No | `-` | - |
331
+ | `vAlphabetic` | `string \| number` | No | `-` | - |
332
+ | `vHanging` | `string \| number` | No | `-` | - |
333
+ | `vIdeographic` | `string \| number` | No | `-` | - |
334
+ | `vMathematical` | `string \| number` | No | `-` | - |
335
+ | `values` | `string` | No | `-` | - |
336
+ | `vectorEffect` | `string \| number` | No | `-` | - |
337
+ | `version` | `string` | No | `-` | - |
338
+ | `vertAdvY` | `string \| number` | No | `-` | - |
339
+ | `vertOriginX` | `string \| number` | No | `-` | - |
340
+ | `vertOriginY` | `string \| number` | No | `-` | - |
341
+ | `viewBox` | `string` | No | `-` | - |
342
+ | `viewTarget` | `string \| number` | No | `-` | - |
343
+ | `visibility` | `ResponsiveProp<visible \| hidden>` | No | `-` | - |
344
+ | `width` | `ResponsiveProp<Width<string \| number>>` | No | `-` | - |
345
+ | `widths` | `string \| number` | No | `-` | - |
346
+ | `wordSpacing` | `string \| number` | No | `-` | - |
347
+ | `writingMode` | `string \| number` | No | `-` | - |
348
+ | `x` | `string \| number` | No | `-` | - |
349
+ | `x1` | `string \| number` | No | `-` | - |
350
+ | `x2` | `string \| number` | No | `-` | - |
351
+ | `xAxis` | `(Partial<AxisConfigProps> & AxisBaseProps & { className?: string; classNames?: { root?: string \| undefined; tickLabel?: string \| undefined; gridLine?: string \| undefined; line?: string \| undefined; tickMark?: string \| undefined; } \| undefined; style?: CSSProperties \| undefined; styles?: { root?: CSSProperties \| undefined; tickLabel?: CSSProperties \| undefined; gridLine?: CSSProperties \| undefined; line?: CSSProperties \| undefined; tickMark?: CSSProperties \| undefined; } \| undefined; } & { position?: top \| bottom \| undefined; height?: number \| undefined; }) \| undefined` | No | `-` | - |
352
+ | `xChannelSelector` | `string` | No | `-` | - |
353
+ | `xHeight` | `string \| number` | No | `-` | - |
354
+ | `xlinkActuate` | `string` | No | `-` | - |
355
+ | `xlinkArcrole` | `string` | No | `-` | - |
356
+ | `xlinkHref` | `string` | No | `-` | - |
357
+ | `xlinkRole` | `string` | No | `-` | - |
358
+ | `xlinkShow` | `string` | No | `-` | - |
359
+ | `xlinkTitle` | `string` | No | `-` | - |
360
+ | `xlinkType` | `string` | No | `-` | - |
361
+ | `xmlBase` | `string` | No | `-` | - |
362
+ | `xmlLang` | `string` | No | `-` | - |
363
+ | `xmlSpace` | `string` | No | `-` | - |
364
+ | `xmlns` | `string` | No | `-` | - |
365
+ | `xmlnsXlink` | `string` | No | `-` | - |
366
+ | `y` | `string \| number` | No | `-` | - |
367
+ | `y1` | `string \| number` | No | `-` | - |
368
+ | `y2` | `string \| number` | No | `-` | - |
369
+ | `yAxis` | `(Partial<AxisConfigProps> & AxisBaseProps & { className?: string; classNames?: { root?: string \| undefined; tickLabel?: string \| undefined; gridLine?: string \| undefined; line?: string \| undefined; tickMark?: string \| undefined; } \| undefined; style?: CSSProperties \| undefined; styles?: { root?: CSSProperties \| undefined; tickLabel?: CSSProperties \| undefined; gridLine?: CSSProperties \| undefined; line?: CSSProperties \| undefined; tickMark?: CSSProperties \| undefined; } \| undefined; } & { axisId?: string \| undefined; position?: left \| right \| undefined; width?: number \| undefined; }) \| undefined` | No | `-` | - |
370
+ | `yChannelSelector` | `string` | No | `-` | - |
371
+ | `z` | `string \| number` | No | `-` | - |
372
+ | `zIndex` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto` | No | `-` | - |
373
+ | `zoomAndPan` | `string` | No | `-` | - |
374
+
375
+
376
+ ## Examples
377
+
378
+ ### Basic Example
379
+
380
+ ```jsx live
381
+ function BasicExample() {
382
+ const [scrubIndex, setScrubIndex] = useState(undefined);
383
+ const data = [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58];
384
+
385
+ const accessibilityLabel = useMemo(() => {
386
+ if (scrubIndex === undefined) return undefined;
387
+ return `Value: ${data[scrubIndex]} at index ${scrubIndex}`;
388
+ }, [scrubIndex, data]);
389
+
390
+ return (
391
+ <LineChart
392
+ enableScrubbing
393
+ onScrubberPositionChange={setScrubIndex}
394
+ height={{ base: 150, tablet: 200, desktop: 250 }}
395
+ series={[
396
+ {
397
+ id: 'prices',
398
+ data: data,
399
+ },
400
+ ]}
401
+ curve="monotone"
402
+ showYAxis
403
+ showArea
404
+ yAxis={{
405
+ showGrid: true,
406
+ }}
407
+ accessibilityLabel={accessibilityLabel}
408
+ >
409
+ <Scrubber />
410
+ </LineChart>
411
+ );
412
+ }
413
+ ```
414
+
415
+ ### Simple
416
+
417
+ ```jsx live
418
+ <LineChart
419
+ height={{ base: 150, tablet: 200, desktop: 250 }}
420
+ series={[
421
+ {
422
+ id: 'prices',
423
+ data: [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58],
424
+ },
425
+ ]}
426
+ curve="monotone"
427
+ />
428
+ ```
429
+
430
+ ### Compact
431
+
432
+ You can specify the dimensions of the chart to make it more compact.
433
+
434
+ ```jsx live
435
+ function CompactLineChart() {
436
+ const dimensions = { width: 62, height: 18 };
437
+
438
+ const sparklineData = prices
439
+ .map((price) => parseFloat(price))
440
+ .filter((price, index) => index % 10 === 0);
441
+ const positiveFloor = Math.min(...sparklineData) - 10;
442
+
443
+ const negativeData = sparklineData.map((price) => -1 * price).reverse();
444
+ const negativeCeiling = Math.max(...negativeData) + 10;
445
+
446
+ const formatPrice = useCallback((price: number) => {
447
+ return `$${price.toLocaleString('en-US', {
448
+ minimumFractionDigits: 2,
449
+ maximumFractionDigits: 2,
450
+ })}`;
451
+ }, []);
452
+
453
+ const CompactChart = memo(({ data, showArea, color, referenceY }) => (
454
+ <Box style={{ padding: 1 }}>
455
+ <LineChart
456
+ {...dimensions}
457
+ enableScrubbing={false}
458
+ overflow="visible"
459
+ inset={0}
460
+ showArea={showArea}
461
+ series={[
462
+ {
463
+ id: 'btc',
464
+ data,
465
+ color,
466
+ },
467
+ ]}
468
+ >
469
+ <ReferenceLine dataY={referenceY} />
470
+ </LineChart>
471
+ </Box>
472
+ ));
473
+
474
+ const ChartCell = memo(({ data, showArea, color, referenceY, subdetail, variant }) => {
475
+ const { isPhone } = useBreakpoints();
476
+
477
+ return (
478
+ <ListCell
479
+ spacingVariant="condensed"
480
+ description={isPhone ? undefined : assets.btc.symbol}
481
+ detail={formatPrice(parseFloat(prices[0]))}
482
+ intermediary={
483
+ <CompactChart data={data} showArea={showArea} color={color} referenceY={referenceY} />
484
+ }
485
+ media={<Avatar src={assets.btc.imageUrl} />}
486
+ onClick={() => console.log('clicked')}
487
+ subdetail={subdetail}
488
+ title={isPhone ? undefined : assets.btc.name}
489
+ variant={variant}
490
+ style={{ padding: 0 }}
491
+ />
492
+ );
493
+ });
494
+
495
+ return (
496
+ <VStack>
497
+ <ChartCell
498
+ data={sparklineData}
499
+ color={assets.btc.color}
500
+ referenceY={parseFloat(prices[Math.floor(prices.length / 4)])}
501
+ subdetail="-4.55%"
502
+ variant="negative"
503
+ />
504
+ <ChartCell
505
+ data={sparklineData}
506
+ showArea
507
+ color={assets.btc.color}
508
+ referenceY={parseFloat(prices[Math.floor(prices.length / 4)])}
509
+ subdetail="-4.55%"
510
+ variant="negative"
511
+ />
512
+ <ChartCell
513
+ data={sparklineData}
514
+ showArea
515
+ color="var(--color-fgPositive)"
516
+ referenceY={positiveFloor}
517
+ subdetail="+0.25%"
518
+ variant="positive"
519
+ />
520
+ <ChartCell
521
+ data={negativeData}
522
+ showArea
523
+ color="var(--color-fgNegative)"
524
+ referenceY={negativeCeiling}
525
+ subdetail="-4.55%"
526
+ variant="negative"
527
+ />
528
+ </VStack>
529
+ );
530
+ };
531
+ ```
532
+
533
+ ### Gain/Loss
534
+
535
+ You can use the y-axis scale and a [linearGradient](https://developer.mozilla.org/en-US/docs/Web/SVG/Reference/Element/linearGradient) to create a gain/loss chart.
536
+
537
+ ```jsx live
538
+ function GainLossChart() {
539
+ const gradientId = useId();
540
+
541
+ const data = [-40, -28, -21, -5, 48, -5, -28, 2, -29, -46, 16, -30, -29, 8];
542
+
543
+ const priceFormatter = useCallback(
544
+ (value) =>
545
+ new Intl.NumberFormat('en-US', {
546
+ style: 'currency',
547
+ currency: 'USD',
548
+ maximumFractionDigits: 0,
549
+ }).format(value),
550
+ [],
551
+ );
552
+
553
+ const ChartDefs = ({ threshold = 0 }) => {
554
+ const { getYScale } = useCartesianChartContext();
555
+ // get the default y-axis scale
556
+ const yScale = getYScale();
557
+
558
+ if (yScale) {
559
+ const domain = yScale.domain();
560
+ const range = yScale.range();
561
+
562
+ const baselinePercentage = ((threshold - domain[0]) / (domain[1] - domain[0])) * 100;
563
+
564
+ const negativeColor = 'rgb(var(--gray15))';
565
+ const positiveColor = 'var(--color-fgPositive)';
566
+
567
+ return (
568
+ <defs>
569
+ <linearGradient
570
+ gradientUnits="userSpaceOnUse"
571
+ id={`${gradientId}-solid`}
572
+ x1="0%"
573
+ x2="0%"
574
+ y1={range[0]}
575
+ y2={range[1]}
576
+ >
577
+ <stop offset="0%" stopColor={negativeColor} />
578
+ <stop offset={`${baselinePercentage}%`} stopColor={negativeColor} />
579
+ <stop offset={`${baselinePercentage}%`} stopColor={positiveColor} />
580
+ <stop offset="100%" stopColor={positiveColor} />
581
+ </linearGradient>
582
+ <linearGradient
583
+ gradientUnits="userSpaceOnUse"
584
+ id={`${gradientId}-gradient`}
585
+ x1="0%"
586
+ x2="0%"
587
+ y1={range[0]}
588
+ y2={range[1]}
589
+ >
590
+ <stop offset="0%" stopColor={negativeColor} stopOpacity={0.3} />
591
+ <stop offset={`${baselinePercentage}%`} stopColor={negativeColor} stopOpacity={0} />
592
+ <stop offset={`${baselinePercentage}%`} stopColor={positiveColor} stopOpacity={0} />
593
+ <stop offset="100%" stopColor={positiveColor} stopOpacity={0.3} />
594
+ </linearGradient>
595
+ </defs>
596
+ );
597
+ }
598
+
599
+ return null;
600
+ };
601
+
602
+ const solidColor = `url(#${gradientId}-solid)`;
603
+
604
+ return (
605
+ <CartesianChart
606
+ enableScrubbing
607
+ height={{ base: 150, tablet: 200, desktop: 250 }}
608
+ series={[
609
+ {
610
+ id: 'prices',
611
+ data: data,
612
+ color: solidColor,
613
+ },
614
+ ]}
615
+ padding={{ top: 1.5, bottom: 1.5, left: 2, right: 0 }}
616
+ >
617
+ <ChartDefs />
618
+ <YAxis requestedTickCount={2} showGrid tickLabelFormatter={priceFormatter} />
619
+ <Area seriesId="prices" curve="monotone" fill={`url(#${gradientId}-gradient)`} />
620
+ <Line strokeWidth={3} curve="monotone" seriesId="prices" stroke={solidColor} />
621
+ <Scrubber hideOverlay />
622
+ </CartesianChart>
623
+ );
624
+ }
625
+ ```
626
+
627
+ ### Multiple Series
628
+
629
+ You can add multiple series to a line chart.
630
+
631
+ ```jsx live
632
+ function MultipleSeriesChart() {
633
+ const [scrubIndex, setScrubIndex] = useState(undefined);
634
+
635
+ const prices = [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58];
636
+ const volume = [4, 8, 11, 15, 16, 14, 16, 10, 12, 14, 16, 14, 16, 10];
637
+
638
+ return (
639
+ <LineChart
640
+ enableScrubbing
641
+ height={{ base: 150, tablet: 200, desktop: 250 }}
642
+ series={[
643
+ {
644
+ id: 'prices',
645
+ data: [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58],
646
+ label: 'Prices',
647
+ color: 'var(--color-accentBoldBlue)',
648
+ },
649
+ {
650
+ id: 'volume',
651
+ data: [4, 8, 11, 15, 16, 14, 16, 10, 12, 14, 16, 14, 16, 10],
652
+ label: 'Volume',
653
+ color: 'var(--color-accentBoldGreen)',
654
+ },
655
+ ]}
656
+ showYAxis
657
+ yAxis={{
658
+ domain: {
659
+ min: 0,
660
+ },
661
+ showGrid: true,
662
+ }}
663
+ curve="monotone"
664
+ >
665
+ <Scrubber />
666
+ </LineChart>
667
+ );
668
+ }
669
+ ```
670
+
671
+ ### Points
672
+
673
+ You can use the `renderPoints` prop to dynamically show points on a line.
674
+
675
+ ```jsx live
676
+ function PointsChart() {
677
+ const keyMarketShiftIndices = [4, 6, 7, 9, 10];
678
+ const data = [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58];
679
+
680
+ return (
681
+ <CartesianChart
682
+ height={{ base: 150, tablet: 200, desktop: 250 }}
683
+ series={[
684
+ {
685
+ id: 'prices',
686
+ data: data,
687
+ },
688
+ ]}
689
+ >
690
+ <Area seriesId="prices" curve="monotone" fill="rgb(var(--blue5))" />
691
+ <Line
692
+ seriesId="prices"
693
+ renderPoints={({ dataX, dataY, ...props }) =>
694
+ keyMarketShiftIndices.includes(dataX)
695
+ ? {
696
+ ...props,
697
+ strokeWidth: 2,
698
+ stroke: 'var(--color-bg)',
699
+ radius: 5,
700
+ onClick: () =>
701
+ alert(
702
+ `You have clicked a key market shift at position ${dataX + 1} with value ${dataY}!`,
703
+ ),
704
+ accessibilityLabel: `Key market shift point at position ${dataX + 1}, value ${dataY}. Click to view details.`,
705
+ }
706
+ : false
707
+ }
708
+ curve="monotone"
709
+ />
710
+ </CartesianChart>
711
+ );
712
+ }
713
+ ```
714
+
715
+ ### Empty State
716
+
717
+ This example shows how to use an empty state for a line chart.
718
+
719
+ ```jsx live
720
+ <LineChart
721
+ series={[
722
+ {
723
+ id: 'line',
724
+ color: 'rgb(var(--gray50))',
725
+ data: [1, 1],
726
+ showArea: true,
727
+ },
728
+ ]}
729
+ yAxis={{ domain: { min: -1, max: 3 } }}
730
+ height={{ base: 150, tablet: 200, desktop: 250 }}
731
+ />
732
+ ```
733
+
734
+ ### Line Styles
735
+
736
+ ```jsx live
737
+ <LineChart
738
+ height={{ base: 150, tablet: 200, desktop: 250 }}
739
+ series={[
740
+ {
741
+ id: 'top',
742
+ data: [15, 28, 32, 44, 46, 36, 40, 45, 48, 38],
743
+ },
744
+ {
745
+ id: 'upperMiddle',
746
+ data: [12, 23, 21, 29, 34, 28, 31, 38, 42, 35],
747
+ color: '#ef4444',
748
+ type: 'dotted',
749
+ },
750
+ {
751
+ id: 'lowerMiddle',
752
+ data: [8, 15, 14, 25, 20, 18, 22, 28, 24, 30],
753
+ color: '#f59e0b',
754
+ curve: 'natural',
755
+ LineComponent: (props) => (
756
+ <GradientLine {...props} endColor="#F7931A" startColor="#E3D74D" strokeWidth={4} />
757
+ ),
758
+ },
759
+ {
760
+ id: 'bottom',
761
+ data: [4, 8, 11, 15, 16, 14, 16, 10, 12, 14],
762
+ color: '#800080',
763
+ curve: 'step',
764
+ AreaComponent: DottedArea,
765
+ showArea: true,
766
+ },
767
+ ]}
768
+ />
769
+ ```
770
+
771
+ ### Live Data
772
+
773
+ ```jsx live
774
+ function LiveAssetPrice() {
775
+ const scrubberRef = useRef(null);
776
+ const [scrubIndex, setScrubIndex] = useState(undefined);
777
+
778
+ const initialData = useMemo(() => {
779
+ return sparklineInteractiveData.hour.map((d) => d.value);
780
+ }, []);
781
+
782
+ const [priceData, setPriceData] = useState(initialData);
783
+
784
+ const lastDataPointTimeRef = useRef(Date.now());
785
+ const updateCountRef = useRef(0);
786
+
787
+ const intervalSeconds = 3600 / initialData.length;
788
+
789
+ const maxPercentChange = Math.abs(initialData[initialData.length - 1] - initialData[0]) * 0.05;
790
+
791
+ useEffect(() => {
792
+ const priceUpdateInterval = setInterval(
793
+ () => {
794
+ setPriceData((currentData) => {
795
+ const newData = [...currentData];
796
+ const lastPrice = newData[newData.length - 1];
797
+
798
+ const priceChange = (Math.random() - 0.5) * maxPercentChange;
799
+ const newPrice = Math.round((lastPrice + priceChange) * 100) / 100;
800
+
801
+ // Check if we should roll over to a new data point
802
+ const currentTime = Date.now();
803
+ const timeSinceLastPoint = (currentTime - lastDataPointTimeRef.current) / 1000;
804
+
805
+ if (timeSinceLastPoint >= intervalSeconds) {
806
+ // Time for a new data point - remove first, add new at end
807
+ lastDataPointTimeRef.current = currentTime;
808
+ newData.shift(); // Remove oldest data point
809
+ newData.push(newPrice); // Add new data point
810
+ updateCountRef.current = 0;
811
+ } else {
812
+ // Just update the last data point
813
+ newData[newData.length - 1] = newPrice;
814
+ updateCountRef.current++;
815
+ }
816
+
817
+ return newData;
818
+ });
819
+
820
+ // Pulse the scrubber on each update
821
+ scrubberRef.current?.pulse();
822
+ },
823
+ 2000 + Math.random() * 1000,
824
+ );
825
+
826
+ return () => clearInterval(priceUpdateInterval);
827
+ }, [intervalSeconds, maxPercentChange]);
828
+
829
+ const accessibilityLabel = useMemo(() => {
830
+ if (scrubIndex === undefined)
831
+ return `Bitcoin Price: $${priceData[priceData.length - 1].toFixed(2)}`;
832
+ const price = priceData[scrubIndex];
833
+ return `Bitcoin Price: $${price.toFixed(2)} at position ${scrubIndex + 1}`;
834
+ }, [scrubIndex, priceData]);
835
+
836
+ return (
837
+ <LineChart
838
+ enableScrubbing
839
+ onScrubberPositionChange={setScrubIndex}
840
+ showArea
841
+ height={{ base: 150, tablet: 200, desktop: 250 }}
842
+ series={[
843
+ {
844
+ id: 'btc',
845
+ data: priceData,
846
+ color: assets.btc.color,
847
+ },
848
+ ]}
849
+ inset={{ right: 64 }}
850
+ accessibilityLabel={accessibilityLabel}
851
+ >
852
+ <Scrubber ref={scrubberRef} labelProps={{ elevation: 1 }} />
853
+ </LineChart>
854
+ );
855
+ }
856
+ ```
857
+
858
+ ### Data Format
859
+
860
+ You can adjust the y values for a series of data by setting the `data` prop on the xAxis.
861
+
862
+ ```jsx live
863
+ function DataFormatChart() {
864
+ const [scrubIndex, setScrubIndex] = useState(undefined);
865
+
866
+ const yData = [2, 5.5, 2, 8.5, 1.5, 5];
867
+ const xData = [1, 2, 3, 5, 8, 10];
868
+
869
+ const accessibilityLabel = useMemo(() => {
870
+ if (scrubIndex === undefined) return undefined;
871
+ return `X: ${xData[scrubIndex]}, Y: ${yData[scrubIndex]} at point ${scrubIndex + 1}`;
872
+ }, [scrubIndex, xData, yData]);
873
+
874
+ return (
875
+ <LineChart
876
+ enableScrubbing
877
+ onScrubberPositionChange={setScrubIndex}
878
+ series={[
879
+ {
880
+ id: 'line',
881
+ data: yData,
882
+ },
883
+ ]}
884
+ height={{ base: 150, tablet: 200, desktop: 250 }}
885
+ showArea
886
+ renderPoints={() => true}
887
+ curve="natural"
888
+ showXAxis
889
+ xAxis={{ data: xData, showLine: true, showTickMarks: true, showGrid: true }}
890
+ showYAxis
891
+ yAxis={{
892
+ domain: { min: 0 },
893
+ position: 'left',
894
+ showLine: true,
895
+ showTickMarks: true,
896
+ showGrid: true,
897
+ }}
898
+ inset={{ top: 16, right: 16, bottom: 0, left: 0 }}
899
+ accessibilityLabel={accessibilityLabel}
900
+ >
901
+ <Scrubber hideOverlay />
902
+ </LineChart>
903
+ );
904
+ }
905
+ ```
906
+
907
+ ### Accessibility
908
+
909
+ You can use `accessibilityLabel` to provide a descriptive label for the chart. This is especially important for charts with scrubbing enabled, where the label should update dynamically to reflect the current data point.
910
+
911
+ ```jsx live
912
+ function AccessibleBasicChart() {
913
+ const [scrubIndex, setScrubIndex] = useState(undefined);
914
+ const data = [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58];
915
+
916
+ const accessibilityLabel = useMemo(() => {
917
+ if (scrubIndex === undefined) {
918
+ return `Current price: ${data[data.length - 1]}`;
919
+ }
920
+ return `Price at position ${scrubIndex + 1}: ${data[scrubIndex]}`;
921
+ }, [scrubIndex, data]);
922
+
923
+ return (
924
+ <LineChart
925
+ enableScrubbing
926
+ onScrubberPositionChange={setScrubIndex}
927
+ height={{ base: 150, tablet: 200, desktop: 250 }}
928
+ series={[
929
+ {
930
+ id: 'prices',
931
+ data: data,
932
+ },
933
+ ]}
934
+ curve="monotone"
935
+ showYAxis
936
+ showArea
937
+ yAxis={{
938
+ showGrid: true,
939
+ }}
940
+ accessibilityLabel={accessibilityLabel}
941
+ >
942
+ <Scrubber />
943
+ </LineChart>
944
+ );
945
+ }
946
+ ```
947
+
948
+ When a chart has a visible header or title, you can use `aria-labelledby` to reference it.
949
+
950
+ ```jsx live
951
+ function AccessibleChartWithHeader() {
952
+ const headerId = useId();
953
+ const [scrubIndex, setScrubIndex] = useState(undefined);
954
+ const data = [10, 22, 29, 45, 98, 45, 22, 52, 21, 4, 68, 20, 21, 58];
955
+
956
+ const accessibilityLabel = useMemo(() => {
957
+ if (scrubIndex === undefined) {
958
+ return `Line chart showing price trend. Current value: ${data[data.length - 1]}`;
959
+ }
960
+ return `Value: ${data[scrubIndex]} at position ${scrubIndex + 1}`;
961
+ }, [scrubIndex, data]);
962
+
963
+ return (
964
+ <VStack gap={2}>
965
+ <Text id={headerId} font="label1">
966
+ {accessibilityLabel}
967
+ </Text>
968
+ <LineChart
969
+ enableScrubbing
970
+ onScrubberPositionChange={setScrubIndex}
971
+ height={{ base: 150, tablet: 200, desktop: 250 }}
972
+ series={[
973
+ {
974
+ id: 'revenue',
975
+ data: data,
976
+ },
977
+ ]}
978
+ curve="monotone"
979
+ showYAxis
980
+ showArea
981
+ yAxis={{
982
+ showGrid: true,
983
+ }}
984
+ aria-labelledby={headerId}
985
+ >
986
+ <Scrubber />
987
+ </LineChart>
988
+ </VStack>
989
+ );
990
+ }
991
+ ```
992
+
993
+ ### Customization
994
+
995
+ #### Asset Price with Dotted Area
996
+
997
+ ```jsx live
998
+ function AssetPriceWithDottedArea() {
999
+ const BTCTab: TabComponent = memo(
1000
+ forwardRef(
1001
+ ({ label, ...props }: SegmentedTabProps, ref: React.ForwardedRef<HTMLButtonElement>) => {
1002
+ const { activeTab } = useTabsContext();
1003
+ const isActive = activeTab?.id === props.id;
1004
+
1005
+ return (
1006
+ <SegmentedTab
1007
+ ref={ref}
1008
+ label={
1009
+ <TextLabel1
1010
+ style={{
1011
+ transition: 'color 0.2s ease',
1012
+ color: isActive ? assets.btc.color : undefined,
1013
+ }}
1014
+ >
1015
+ {label}
1016
+ </TextLabel1>
1017
+ }
1018
+ {...props}
1019
+ />
1020
+ );
1021
+ },
1022
+ ),
1023
+ );
1024
+
1025
+ const BTCActiveIndicator = memo(({ style, ...props }: TabsActiveIndicatorProps) => (
1026
+ <PeriodSelectorActiveIndicator
1027
+ {...props}
1028
+ style={{ ...style, backgroundColor: `${assets.btc.color}1A` }}
1029
+ />
1030
+ ));
1031
+
1032
+ const AssetPriceDotted = memo(() => {
1033
+ const [scrubIndex, setScrubIndex] = useState<number | undefined>(undefined);
1034
+ const currentPrice =
1035
+ sparklineInteractiveData.hour[sparklineInteractiveData.hour.length - 1].value;
1036
+ const tabs = [
1037
+ { id: 'hour', label: '1H' },
1038
+ { id: 'day', label: '1D' },
1039
+ { id: 'week', label: '1W' },
1040
+ { id: 'month', label: '1M' },
1041
+ { id: 'year', label: '1Y' },
1042
+ { id: 'all', label: 'All' },
1043
+ ];
1044
+ const [timePeriod, setTimePeriod] = useState<TabValue>(tabs[0]);
1045
+
1046
+ const sparklineTimePeriodData = useMemo(() => {
1047
+ return sparklineInteractiveData[timePeriod.id as keyof typeof sparklineInteractiveData];
1048
+ }, [timePeriod]);
1049
+
1050
+ const sparklineTimePeriodDataValues = useMemo(() => {
1051
+ return sparklineTimePeriodData.map((d) => d.value);
1052
+ }, [sparklineTimePeriodData]);
1053
+
1054
+ const sparklineTimePeriodDataTimestamps = useMemo(() => {
1055
+ return sparklineTimePeriodData.map((d) => d.date);
1056
+ }, [sparklineTimePeriodData]);
1057
+
1058
+ const onPeriodChange = useCallback(
1059
+ (period: TabValue | null) => {
1060
+ setTimePeriod(period || tabs[0]);
1061
+ },
1062
+ [tabs, setTimePeriod],
1063
+ );
1064
+
1065
+ const priceFormatter = useMemo(
1066
+ () =>
1067
+ new Intl.NumberFormat('en-US', {
1068
+ style: 'currency',
1069
+ currency: 'USD',
1070
+ }),
1071
+ [],
1072
+ );
1073
+
1074
+ const scrubberPriceFormatter = useMemo(
1075
+ () =>
1076
+ new Intl.NumberFormat('en-US', {
1077
+ minimumFractionDigits: 2,
1078
+ maximumFractionDigits: 2,
1079
+ }),
1080
+ [],
1081
+ );
1082
+
1083
+ const formatPrice = useCallback((price: number) => {
1084
+ return priceFormatter.format(price);
1085
+ }, [priceFormatter]);
1086
+
1087
+ const formatDate = useCallback((date: Date) => {
1088
+ const dayOfWeek = date.toLocaleDateString('en-US', { weekday: 'short' });
1089
+
1090
+ const monthDay = date.toLocaleDateString('en-US', {
1091
+ month: 'short',
1092
+ day: 'numeric',
1093
+ });
1094
+
1095
+ const time = date.toLocaleTimeString('en-US', {
1096
+ hour: 'numeric',
1097
+ minute: '2-digit',
1098
+ hour12: true,
1099
+ });
1100
+
1101
+ return `${dayOfWeek}, ${monthDay}, ${time}`;
1102
+ }, []);
1103
+
1104
+ const scrubberLabel = useCallback(
1105
+ (index: number) => {
1106
+ const price = scrubberPriceFormatter.format(sparklineTimePeriodDataValues[index]);
1107
+ const date = formatDate(sparklineTimePeriodDataTimestamps[index]);
1108
+ return (
1109
+ <>
1110
+ <tspan style={{ fontWeight: 'bold' }}>{price} USD</tspan> {date}
1111
+ </>
1112
+ );
1113
+ },
1114
+ [scrubberPriceFormatter, sparklineTimePeriodDataValues, sparklineTimePeriodDataTimestamps, formatDate],
1115
+ );
1116
+
1117
+ const accessibilityLabel = useCallback(
1118
+ (index: number) => {
1119
+ const price = scrubberPriceFormatter.format(sparklineTimePeriodDataValues[index]);
1120
+ const date = formatDate(sparklineTimePeriodDataTimestamps[index]);
1121
+ return `${price} USD ${date}`;
1122
+ },
1123
+ [scrubberPriceFormatter, sparklineTimePeriodDataValues, sparklineTimePeriodDataTimestamps, formatDate],
1124
+ );
1125
+
1126
+ return (
1127
+ <VStack gap={2}>
1128
+ <SectionHeader
1129
+ style={{ padding: 0 }}
1130
+ title={<Text font="title1">Bitcoin</Text>}
1131
+ balance={<Text font="title2">{formatPrice(currentPrice)}</Text>}
1132
+ end={
1133
+ <VStack justifyContent="center">
1134
+ <RemoteImage source={assets.btc.imageUrl} size="xl" shape="circle" />
1135
+ </VStack>
1136
+ }
1137
+ />
1138
+ <LineChart
1139
+ overflow="visible"
1140
+ enableScrubbing
1141
+ onScrubberPositionChange={setScrubIndex}
1142
+ series={[
1143
+ {
1144
+ id: 'btc',
1145
+ data: sparklineTimePeriodDataValues,
1146
+ color: assets.btc.color,
1147
+ },
1148
+ ]}
1149
+ showArea
1150
+ areaType="dotted"
1151
+ height={{ base: 150, tablet: 200, desktop: 250 }}
1152
+ style={{ outlineColor: assets.btc.color }}
1153
+ accessibilityLabel={scrubberLabel}
1154
+ padding={{ left: 2, right: 2 }}
1155
+ >
1156
+ <Scrubber label={scrubberLabel} labelProps={{ elevation: 1 }} idlePulse />
1157
+ </LineChart>
1158
+ <PeriodSelector
1159
+ TabComponent={BTCTab}
1160
+ TabsActiveIndicatorComponent={BTCActiveIndicator}
1161
+ tabs={tabs}
1162
+ activeTab={timePeriod}
1163
+ onChange={onPeriodChange}
1164
+ />
1165
+ </VStack>
1166
+ )});
1167
+
1168
+ return <AssetPriceDotted />;
1169
+ };
1170
+ ```
1171
+
1172
+ #### Forecast Asset Price
1173
+
1174
+ ```jsx live
1175
+ function ForecastAssetPrice() {
1176
+ const ForecastAreaComponent = memo(
1177
+ (props: AreaComponentProps) => (
1178
+ <DottedArea {...props} peakOpacity={0.4} baselineOpacity={0.4} />
1179
+ ),
1180
+ );
1181
+
1182
+ const ForecastChart = memo(() => {
1183
+ const [scrubIndex, setScrubIndex] = useState<number | undefined>(undefined);
1184
+
1185
+ const getDataFromSparkline = useCallback((startDate: Date) => {
1186
+ const allData = sparklineInteractiveData.all;
1187
+ if (!allData || allData.length === 0) return [];
1188
+
1189
+ const timelineData = allData.filter((point) => point.date >= startDate);
1190
+
1191
+ return timelineData.map((point) => ({
1192
+ date: point.date,
1193
+ value: point.value,
1194
+ }));
1195
+ }, []);
1196
+
1197
+ const historicalData = useMemo(() => getDataFromSparkline(new Date('2019-01-01')), [getDataFromSparkline]);
1198
+
1199
+ const annualGrowthRate = 10;
1200
+
1201
+ const generateForecastData = useCallback(
1202
+ (lastDate: Date, lastPrice: number, growthRate: number) => {
1203
+ const dailyGrowthRate = Math.pow(1 + growthRate / 100, 1 / 365) - 1;
1204
+ const forecastData = [];
1205
+ const fiveYearsFromNow = new Date(lastDate);
1206
+ fiveYearsFromNow.setFullYear(fiveYearsFromNow.getFullYear() + 5);
1207
+
1208
+ // Generate daily forecast points for 5 years
1209
+ const currentDate = new Date(lastDate);
1210
+ let currentPrice = lastPrice;
1211
+
1212
+ while (currentDate <= fiveYearsFromNow) {
1213
+ currentPrice = currentPrice * (1 + dailyGrowthRate * 10);
1214
+ forecastData.push({
1215
+ date: new Date(currentDate),
1216
+ value: Math.round(currentPrice),
1217
+ });
1218
+ currentDate.setDate(currentDate.getDate() + 10);
1219
+ }
1220
+
1221
+ return forecastData;
1222
+ },
1223
+ [],
1224
+ );
1225
+
1226
+ const priceFormatter = useMemo(
1227
+ () =>
1228
+ new Intl.NumberFormat('en-US', {
1229
+ minimumFractionDigits: 2,
1230
+ maximumFractionDigits: 2,
1231
+ }),
1232
+ [],
1233
+ );
1234
+
1235
+ const formatDate = useCallback((date: Date) => {
1236
+ const dayOfWeek = date.toLocaleDateString('en-US', { weekday: 'short' });
1237
+
1238
+ const monthDay = date.toLocaleDateString('en-US', {
1239
+ month: 'short',
1240
+ day: 'numeric',
1241
+ });
1242
+
1243
+ const time = date.toLocaleTimeString('en-US', {
1244
+ hour: 'numeric',
1245
+ minute: '2-digit',
1246
+ hour12: true,
1247
+ });
1248
+
1249
+ return `${dayOfWeek}, ${monthDay}, ${time}`;
1250
+ }, []);
1251
+
1252
+ const forecastData = useMemo(() => {
1253
+ if (historicalData.length === 0) return [];
1254
+ const lastPoint = historicalData[historicalData.length - 1];
1255
+ return generateForecastData(lastPoint.date, lastPoint.value, annualGrowthRate);
1256
+ }, [generateForecastData, historicalData, annualGrowthRate]);
1257
+
1258
+ // Combine all data points with dates converted to timestamps for x-axis
1259
+ const allDataPoints = useMemo(
1260
+ () => [...historicalData, ...forecastData],
1261
+ [historicalData, forecastData],
1262
+ );
1263
+
1264
+ const historicalDataValues = useMemo(
1265
+ () => historicalData.map((d) => d.value),
1266
+ [historicalData],
1267
+ );
1268
+
1269
+ const forecastDataValues = useMemo(
1270
+ () => [...historicalData.map((d) => null), ...forecastData.map((d) => d.value)],
1271
+ [historicalData, forecastData],
1272
+ );
1273
+
1274
+ const xAxisData = useMemo(
1275
+ () => allDataPoints.map((d) => d.date.getTime()),
1276
+ [allDataPoints],
1277
+ );
1278
+
1279
+ const scrubberLabel = useCallback(
1280
+ (index: number) => {
1281
+ const price = priceFormatter.format(allDataPoints[index].value);
1282
+ const date = formatDate(allDataPoints[index].date);
1283
+ return (
1284
+ <>
1285
+ <tspan style={{ fontWeight: 'bold' }}>{price} USD</tspan> {date}
1286
+ </>
1287
+ );
1288
+ },
1289
+ [priceFormatter, allDataPoints, formatDate],
1290
+ );
1291
+
1292
+ const accessibilityLabel = useCallback(
1293
+ (index: number) => {
1294
+ const price = priceFormatter.format(allDataPoints[index].value);
1295
+ const date = formatDate(allDataPoints[index].date);
1296
+ return `${price} USD ${date}`;
1297
+ },
1298
+ [priceFormatter, allDataPoints, formatDate],
1299
+ );
1300
+
1301
+ return (
1302
+ <LineChart
1303
+ overflow="visible"
1304
+ animate={false}
1305
+ enableScrubbing
1306
+ showArea
1307
+ showXAxis
1308
+ AreaComponent={ForecastAreaComponent}
1309
+ height={{ base: 150, tablet: 200, desktop: 250 }}
1310
+ padding={{
1311
+ top: 4,
1312
+ left: 2,
1313
+ right: 2,
1314
+ bottom: 0,
1315
+ }}
1316
+ series={[
1317
+ {
1318
+ id: 'historical',
1319
+ data: historicalDataValues,
1320
+ color: assets.btc.color,
1321
+ },
1322
+ {
1323
+ id: 'forecast',
1324
+ data: forecastDataValues,
1325
+ color: assets.btc.color,
1326
+ type: 'dotted',
1327
+ },
1328
+ ]}
1329
+ xAxis={{
1330
+ data: xAxisData,
1331
+ tickLabelFormatter: (value: number) => {
1332
+ return new Date(value).toLocaleDateString('en-US', {
1333
+ month: 'numeric',
1334
+ year: 'numeric',
1335
+ });
1336
+ },
1337
+ tickInterval: 2,
1338
+ }}
1339
+ accessibilityLabel={accessibilityLabel}
1340
+ style={{ outlineColor: assets.btc.color }}
1341
+ >
1342
+ <Scrubber label={scrubberLabel} labelProps={{ elevation: 1 }} />
1343
+ </LineChart>
1344
+ );
1345
+ });
1346
+
1347
+ return <ForecastChart />;
1348
+ };
1349
+ ```
1350
+
1351
+ #### Availability
1352
+
1353
+ ```jsx live
1354
+ function AvailabilityChart() {
1355
+ const [scrubIndex, setScrubIndex] = useState(undefined);
1356
+
1357
+ const availabilityEvents = [
1358
+ {
1359
+ date: new Date('2022-01-01'),
1360
+ availability: 79,
1361
+ },
1362
+ {
1363
+ date: new Date('2022-01-03'),
1364
+ availability: 81,
1365
+ },
1366
+ {
1367
+ date: new Date('2022-01-04'),
1368
+ availability: 82,
1369
+ },
1370
+ {
1371
+ date: new Date('2022-01-06'),
1372
+ availability: 91,
1373
+ },
1374
+ {
1375
+ date: new Date('2022-01-07'),
1376
+ availability: 92,
1377
+ },
1378
+ {
1379
+ date: new Date('2022-01-10'),
1380
+ availability: 86,
1381
+ },
1382
+ ];
1383
+
1384
+ const accessibilityLabel = useMemo(() => {
1385
+ if (scrubIndex === undefined) return undefined;
1386
+ const event = availabilityEvents[scrubIndex];
1387
+ const formattedDate = event.date.toLocaleDateString('en-US', {
1388
+ weekday: 'short',
1389
+ month: 'short',
1390
+ day: 'numeric',
1391
+ year: 'numeric',
1392
+ });
1393
+ const status =
1394
+ event.availability >= 90 ? 'Good' : event.availability >= 85 ? 'Warning' : 'Critical';
1395
+ return `${formattedDate}: Availability ${event.availability}% - Status: ${status}`;
1396
+ }, [scrubIndex, availabilityEvents]);
1397
+
1398
+ const ChartDefs = memo(({ yellowThresholdPercentage = 85, greenThresholdPercentage = 90 }) => {
1399
+ const { drawingArea, height, series, getYScale, getYAxis } = useCartesianChartContext();
1400
+ const yScale = getYScale();
1401
+ const yAxis = getYAxis();
1402
+
1403
+ if (!series || !drawingArea || !yScale) return null;
1404
+
1405
+ const rangeBounds = yAxis?.domain;
1406
+ const rangeMin = rangeBounds?.min ?? 0;
1407
+ const rangeMax = rangeBounds?.max ?? 100;
1408
+
1409
+ // Calculate the Y positions in the chart coordinate system
1410
+ const yellowThresholdY = yScale(yellowThresholdPercentage) ?? 0;
1411
+ const greenThresholdY = yScale(greenThresholdPercentage) ?? 0;
1412
+ const minY = yScale(rangeMax) ?? 0; // Top of chart (max value)
1413
+ const maxY = yScale(rangeMin) ?? drawingArea.height; // Bottom of chart (min value)
1414
+
1415
+ // Calculate percentages based on actual chart positions
1416
+ const yellowThreshold = ((yellowThresholdY - minY) / (maxY - minY)) * 100;
1417
+ const greenThreshold = ((greenThresholdY - minY) / (maxY - minY)) * 100;
1418
+
1419
+ return (
1420
+ <defs>
1421
+ <linearGradient
1422
+ gradientUnits="userSpaceOnUse"
1423
+ id="availabilityGradient"
1424
+ x1="0%"
1425
+ x2="0%"
1426
+ y1={minY}
1427
+ y2={maxY}
1428
+ >
1429
+ <stop offset="0%" stopColor="var(--color-fgPositive)" />
1430
+ <stop offset={`${greenThreshold}%`} stopColor="var(--color-fgPositive)" />
1431
+ <stop offset={`${greenThreshold}%`} stopColor="var(--color-fgWarning)" />
1432
+ <stop offset={`${yellowThreshold}%`} stopColor="var(--color-fgWarning)" />
1433
+ <stop offset={`${yellowThreshold}%`} stopColor="var(--color-fgNegative)" />
1434
+ <stop offset="100%" stopColor="var(--color-fgNegative)" />
1435
+ </linearGradient>
1436
+ </defs>
1437
+ );
1438
+ });
1439
+
1440
+ return (
1441
+ <CartesianChart
1442
+ enableScrubbing
1443
+ onScrubberPositionChange={setScrubIndex}
1444
+ height={{ base: 150, tablet: 200, desktop: 250 }}
1445
+ series={[
1446
+ {
1447
+ id: 'availability',
1448
+ data: availabilityEvents.map((event) => event.availability),
1449
+ color: 'url(#availabilityGradient)',
1450
+ },
1451
+ ]}
1452
+ xAxis={{
1453
+ data: availabilityEvents.map((event) => event.date.getTime()),
1454
+ }}
1455
+ yAxis={{
1456
+ domain: ({ min, max }) => ({ min: Math.max(min - 2, 0), max: Math.min(max + 2, 100) }),
1457
+ }}
1458
+ padding={{ left: 2, right: 2 }}
1459
+ accessibilityLabel={accessibilityLabel}
1460
+ >
1461
+ <ChartDefs />
1462
+ <XAxis
1463
+ showGrid
1464
+ showLine
1465
+ showTickMarks
1466
+ tickLabelFormatter={(value) => new Date(value).toLocaleDateString()}
1467
+ />
1468
+ <YAxis
1469
+ showGrid
1470
+ showLine
1471
+ showTickMarks
1472
+ position="left"
1473
+ tickLabelFormatter={(value) => `${value}%`}
1474
+ />
1475
+ <Line
1476
+ curve="stepAfter"
1477
+ renderPoints={() => ({
1478
+ fill: 'var(--color-bg)',
1479
+ stroke: 'url(#availabilityGradient)',
1480
+ strokeWidth: 2,
1481
+ })}
1482
+ seriesId="availability"
1483
+ />
1484
+ <Scrubber hideOverlay />
1485
+ </CartesianChart>
1486
+ );
1487
+ }
1488
+ ```
1489
+
1490
+ #### Asset Price Widget
1491
+
1492
+ You can coordinate LineChart with custom styles to create a custom card that shows the latest price and percent change.
1493
+
1494
+ ```jsx live
1495
+ function BitcoinChartWithScrubberBeacon() {
1496
+ const { isPhone } = useBreakpoints();
1497
+ const prices = [...btcCandles].reverse().map((candle) => parseFloat(candle.close));
1498
+ const latestPrice = prices[prices.length - 1];
1499
+
1500
+ const formatPrice = (price: number) => {
1501
+ return new Intl.NumberFormat('en-US', {
1502
+ style: 'currency',
1503
+ currency: 'USD',
1504
+ }).format(price);
1505
+ };
1506
+
1507
+ const formatPercentChange = (price: number) => {
1508
+ return new Intl.NumberFormat('en-US', {
1509
+ style: 'percent',
1510
+ minimumFractionDigits: 2,
1511
+ maximumFractionDigits: 2,
1512
+ }).format(price);
1513
+ };
1514
+
1515
+ const percentChange = (latestPrice - prices[0]) / prices[0];
1516
+
1517
+ return (
1518
+ <VStack
1519
+ style={{
1520
+ background:
1521
+ 'linear-gradient(0deg, rgba(0, 0, 0, 0.80) 0%, rgba(0, 0, 0, 0.80) 100%), #ED702F',
1522
+ }}
1523
+ borderRadius={300}
1524
+ gap={2}
1525
+ padding={2}
1526
+ paddingBottom={0}
1527
+ overflow="hidden"
1528
+ >
1529
+ <HStack gap={2} alignItems="center">
1530
+ <RemoteImage source={assets.btc.imageUrl} size="xxl" shape="circle" aria-hidden />
1531
+ {!isPhone && (
1532
+ <VStack gap={0.25} flexGrow={1}>
1533
+ <Text font="title1" style={{ color: 'white' }} aria-hidden>
1534
+ BTC
1535
+ </Text>
1536
+ <Text font="label1" color="fgMuted">
1537
+ Bitcoin
1538
+ </Text>
1539
+ </VStack>
1540
+ )}
1541
+ <VStack gap={0.25} alignItems="flex-end" flexGrow={isPhone ? 1 : undefined}>
1542
+ <Text font="title1" style={{ color: 'white' }}>
1543
+ {formatPrice(latestPrice)}
1544
+ </Text>
1545
+ <Text font="label1" color="fgPositive" accessibilityLabel={`Up ${formatPercentChange(percentChange)}`}>
1546
+ +{formatPercentChange(percentChange)}
1547
+ </Text>
1548
+ </VStack>
1549
+ </HStack>
1550
+ <div
1551
+ style={{
1552
+ marginLeft: 'calc(-1 * var(--space-2))',
1553
+ marginRight: 'calc(-1 * var(--space-2))',
1554
+ }}
1555
+ >
1556
+ <LineChart
1557
+ inset={{ left: 0, right: 18, bottom: 0, top: 0 }}
1558
+ series={[
1559
+ {
1560
+ id: 'btcPrice',
1561
+ data: prices,
1562
+ color: assets.btc.color,
1563
+ },
1564
+ ]}
1565
+ showArea
1566
+ width="100%"
1567
+ height={92}
1568
+ >
1569
+ <Scrubber idlePulse styles={{ beacon: { stroke: 'white' } }} />
1570
+ </LineChart>
1571
+ </div>
1572
+ </VStack>
1573
+ );
1574
+ };
1575
+ ```
1576
+
1577
+