@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.0

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 (264) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +266 -267
  5. package/package.json +2 -2
  6. package/pipeline/scripts/_notices.mjs +1 -1
  7. package/pipeline/skills/.skill-manifest.json +68 -68
  8. package/pipeline/skills/shared/README.md +70 -70
  9. package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
  10. package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
  11. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
  12. package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
  13. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  14. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  15. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  16. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  17. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  18. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  19. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  20. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
  21. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  22. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
  23. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
  24. package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
  25. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  26. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  27. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  28. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
  29. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  30. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  31. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  32. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  33. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  34. package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
  35. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  36. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
  37. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  38. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  39. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  40. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  41. package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
  42. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  43. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
  44. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  45. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  46. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  47. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  48. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  49. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  50. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  51. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  52. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  53. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
  54. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  55. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  56. package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
  57. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  58. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  59. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  60. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  61. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  62. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  63. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  64. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  65. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  66. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  67. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  68. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  69. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  70. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  71. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  72. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  73. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  74. package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
  75. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  76. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  77. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  78. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  79. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  80. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  81. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  82. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  83. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  84. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  85. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  86. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  87. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  88. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  89. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  90. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  91. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  92. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  93. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  94. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  95. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  96. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  97. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  98. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  99. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  100. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  101. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  102. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  103. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  104. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  105. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  106. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  107. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  108. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  109. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  110. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  111. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
  112. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  113. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  114. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  115. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  116. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  117. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  118. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  119. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  120. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  121. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  122. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  123. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  124. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  125. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  126. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  127. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  128. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  129. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  130. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  131. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  132. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  133. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  134. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  135. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  136. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  137. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  138. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  139. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  140. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  141. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  142. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  143. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  144. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  145. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  146. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  147. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  148. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  149. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  150. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  151. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  152. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  153. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  154. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  155. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  156. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  157. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
  158. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  159. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  160. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  161. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  162. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  163. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  164. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  165. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  166. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  167. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  168. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  169. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  170. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  171. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  172. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
  173. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  174. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  175. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  176. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  177. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  178. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  179. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  180. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  181. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  182. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  183. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  184. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  185. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  186. package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
  187. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  188. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  189. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
  190. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  191. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  192. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  193. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  194. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  195. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  196. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
  197. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  198. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  199. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  200. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
  201. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  202. package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
  203. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  204. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
  205. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  206. package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
  207. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  208. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  209. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  210. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  211. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  212. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  213. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  214. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  215. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  216. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  217. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  218. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  219. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  220. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  221. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  222. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  223. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  224. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  225. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  226. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  227. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  228. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  229. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  230. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  231. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
  232. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  233. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
  234. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  235. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
  236. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  237. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  238. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  239. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  240. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  241. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  242. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  243. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  244. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  245. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  246. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  247. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  248. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  249. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  250. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  251. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  252. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  253. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  254. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  255. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  256. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  257. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  258. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  259. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  260. package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
  261. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  262. package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
  263. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
  264. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
@@ -1,262 +1,161 @@
1
- # Swift Charts Patterns Reference
1
+ # Swift Charts Patterns
2
2
 
3
- Extended patterns, accessibility guidance, and theming for Swift Charts on
4
- iOS 26+. Import `Charts` in every file that uses these APIs.
5
-
6
- ```swift
7
- import SwiftUI
8
- import Charts
9
- ```
10
-
11
- ---
3
+ Companion to the `swift-charts` skill. Any source file touching these types
4
+ imports `Charts` next to `SwiftUI`.
12
5
 
13
6
  ## Contents
14
7
 
15
- - [Data Modeling](#data-modeling)
16
- - [Bar Chart Patterns](#bar-chart-patterns)
17
- - [Line Chart Patterns](#line-chart-patterns)
18
- - [Pie and Donut Chart Patterns (SectorMark, iOS 17+)](#pie-and-donut-chart-patterns-sectormark-ios-17)
19
- - [Combined Chart Patterns](#combined-chart-patterns)
20
- - [Chart Selection with Overlay Annotation](#chart-selection-with-overlay-annotation)
21
- - [Scrollable Chart with Visible Domain](#scrollable-chart-with-visible-domain)
22
- - [Function Plotting (LinePlot, iOS 18+)](#function-plotting-lineplot-ios-18)
23
- - [3D Charts and Surfaces (Chart3D, iOS 26+)](#3d-charts-and-surfaces-chart3d-ios-26)
8
+ - [Modelling the Data](#modelling-the-data)
9
+ - [Bars](#bars)
10
+ - [Lines](#lines)
11
+ - [Pies and Donuts](#pies-and-donuts)
12
+ - [Combining Marks](#combining-marks)
13
+ - [A Tooltip on Selection](#a-tooltip-on-selection)
14
+ - [Scrolling with a Bound Position](#scrolling-with-a-bound-position)
15
+ - [Function Plots (iOS 18)](#function-plots-ios-18)
16
+ - [3D Charts and Surfaces (iOS 26)](#3d-charts-and-surfaces-ios-26)
24
17
  - [Accessibility](#accessibility)
25
- - [Dynamic Type and Color Considerations](#dynamic-type-and-color-considerations)
26
- - [Performance: Vectorized Plots for Large Datasets](#performance-vectorized-plots-for-large-datasets)
18
+ - [Dynamic Type and Colour](#dynamic-type-and-colour)
19
+ - [Performance: When to Vectorize](#performance-when-to-vectorize)
27
20
  - [Dark Mode and Theming](#dark-mode-and-theming)
28
- - [Heat Map Pattern](#heat-map-pattern)
29
- - [Stacking Methods](#stacking-methods)
30
- - [MarkDimension Options](#markdimension-options)
31
- - [Symbol Configuration](#symbol-configuration)
32
- - [ChartProxy and Coordinate Conversion](#chartproxy-and-coordinate-conversion)
33
- - [Quick Reference: Chart View Modifiers](#quick-reference-chart-view-modifiers)
34
- - [Apple Documentation Links](#apple-documentation-links)
21
+ - [Heat Map](#heat-map)
22
+ - [Stacking](#stacking)
23
+ - [`MarkDimension`](#markdimension)
24
+ - [Symbols](#symbols)
25
+ - [`ChartProxy` and Coordinates](#chartproxy-and-coordinates)
26
+ - [Modifier Quick Reference](#modifier-quick-reference)
27
+ - [Apple Documentation](#apple-documentation)
35
28
 
36
- ## Data Modeling
37
-
38
- Use `@Observable` for chart data models. Pair with `@State` in views.
29
+ ## Modelling the Data
39
30
 
40
31
  ```swift
32
+ import Charts
33
+ import SwiftUI
34
+
35
+ struct MonthlyUsage: Identifiable, Sendable {
36
+ let id = UUID()
37
+ let month: Date
38
+ let kilowattHours: Double
39
+ }
40
+
41
+ @MainActor
41
42
  @Observable
42
- class SalesModel {
43
- var monthlySales: [MonthlySale] = []
43
+ final class UsageModel {
44
+ private(set) var months: [MonthlyUsage] = []
44
45
 
45
46
  func load() async {
46
- monthlySales = await SalesService.fetchMonthlySales()
47
+ months = await UsageService.shared.lastTwelveMonths()
47
48
  }
48
49
  }
49
50
 
50
- struct MonthlySale: Identifiable {
51
- let id = UUID()
52
- let month: Date
53
- let revenue: Double
54
- let category: String
55
- }
56
- ```
57
-
58
- ```swift
59
- struct SalesDashboard: View {
60
- @State private var model = SalesModel()
51
+ struct UsageChart: View {
52
+ @State private var model = UsageModel()
61
53
 
62
54
  var body: some View {
63
- Chart(model.monthlySales) { item in
64
- BarMark(
65
- x: .value("Month", item.month, unit: .month),
66
- y: .value("Revenue", item.revenue)
67
- )
68
- .foregroundStyle(by: .value("Category", item.category))
55
+ Chart(model.months) { entry in
56
+ BarMark(x: .value("Month", entry.month, unit: .month),
57
+ y: .value("kWh", entry.kilowattHours))
69
58
  }
70
59
  .task { await model.load() }
71
60
  }
72
61
  }
73
62
  ```
74
63
 
75
- ---
64
+ The view owns the model with `@State` and starts loading from `.task`.
76
65
 
77
- ## Bar Chart Patterns
66
+ ## Bars
78
67
 
79
- ### Simple vertical bars
68
+ Side by side instead of stacked: combine `.position(by:)` with
69
+ `.foregroundStyle(by:)`.
80
70
 
81
71
  ```swift
82
- Chart(data) { item in
83
- BarMark(
84
- x: .value("Department", item.department),
85
- y: .value("Revenue", item.revenue)
86
- )
72
+ Chart(results) { row in
73
+ BarMark(x: .value("Quarter", row.quarter), y: .value("Units", row.units))
74
+ .foregroundStyle(by: .value("Model", row.model))
75
+ .position(by: .value("Model", row.model))
87
76
  }
88
77
  ```
89
78
 
90
- ### Stacked bars (automatic)
91
-
92
- When multiple bars share the same x value, they stack automatically:
79
+ Horizontal bars with only value labels on the category axis:
93
80
 
94
81
  ```swift
95
- Chart(data) { item in
96
- BarMark(
97
- x: .value("Quarter", item.quarter),
98
- y: .value("Sales", item.sales)
99
- )
100
- .foregroundStyle(by: .value("Product", item.product))
101
- }
102
- ```
103
-
104
- ### Grouped bars
105
-
106
- Use `.position(by:)` to place bars side by side instead of stacking:
107
-
108
- ```swift
109
- Chart(data) { item in
110
- BarMark(
111
- x: .value("Quarter", item.quarter),
112
- y: .value("Sales", item.sales)
113
- )
114
- .foregroundStyle(by: .value("Product", item.product))
115
- .position(by: .value("Product", item.product))
116
- }
117
- ```
118
-
119
- ### Horizontal bars
120
-
121
- Swap the x and y axes:
122
-
123
- ```swift
124
- Chart(data) { item in
125
- BarMark(
126
- x: .value("Sales", item.sales),
127
- y: .value("Region", item.region)
128
- )
82
+ Chart(languages) { item in
83
+ BarMark(x: .value("Speakers", item.speakers), y: .value("Language", item.name))
129
84
  }
130
85
  .chartYAxis {
131
- AxisMarks { _ in
132
- AxisValueLabel()
133
- }
86
+ AxisMarks { _ in AxisValueLabel() }
134
87
  }
135
88
  ```
136
89
 
137
- ### Normalized stacked bars (100%)
90
+ Shares of 100 percent per bar: `BarMark(x:y:stacking: .normalized)`.
138
91
 
139
- ```swift
140
- Chart(data) { item in
141
- BarMark(
142
- x: .value("Quarter", item.quarter),
143
- y: .value("Sales", item.sales),
144
- stacking: .normalized
145
- )
146
- .foregroundStyle(by: .value("Product", item.product))
147
- }
148
- ```
149
-
150
- ### Bar with annotation
92
+ A value on top of each bar:
151
93
 
152
94
  ```swift
153
- Chart(data) { item in
154
- BarMark(
155
- x: .value("Month", item.month),
156
- y: .value("Revenue", item.revenue)
157
- )
158
- .annotation(position: .top, alignment: .center, spacing: 4) {
159
- Text(item.revenue, format: .currency(code: "USD").precision(.fractionLength(0)))
95
+ BarMark(x: .value("Store", row.store), y: .value("Sales", row.sales))
96
+ .annotation(position: .top) {
97
+ Text(row.sales, format: .currency(code: "EUR").precision(.fractionLength(0)))
160
98
  .font(.caption2)
161
99
  }
162
- }
163
100
  ```
164
101
 
165
- ### Gantt chart (interval bars)
102
+ A Gantt chart colours interval bars by status:
166
103
 
167
104
  ```swift
168
105
  Chart(tasks) { task in
169
- BarMark(
170
- xStart: .value("Start", task.startDate),
171
- xEnd: .value("End", task.endDate),
172
- y: .value("Task", task.name)
173
- )
174
- .foregroundStyle(by: .value("Status", task.status))
106
+ BarMark(xStart: .value("Start", task.start),
107
+ xEnd: .value("End", task.end),
108
+ y: .value("Task", task.title))
109
+ .foregroundStyle(by: .value("Phase", task.phase.rawValue))
175
110
  }
176
111
  ```
177
112
 
178
- ---
179
-
180
- ## Line Chart Patterns
113
+ ## Lines
181
114
 
182
- ### Single line with points
115
+ Points on the line: put a `LineMark` and a `PointMark` in the same closure.
183
116
 
184
117
  ```swift
185
- Chart(data) { item in
186
- LineMark(
187
- x: .value("Date", item.date),
188
- y: .value("Price", item.price)
189
- )
190
- PointMark(
191
- x: .value("Date", item.date),
192
- y: .value("Price", item.price)
193
- )
194
- .symbolSize(30)
118
+ Chart(temperatures) { sample in
119
+ LineMark(x: .value("Hour", sample.hour), y: .value("Celsius", sample.value))
120
+ .foregroundStyle(by: .value("City", sample.city))
121
+ .symbol(by: .value("City", sample.city))
122
+ PointMark(x: .value("Hour", sample.hour), y: .value("Celsius", sample.value))
123
+ .symbolSize(30)
195
124
  }
196
125
  ```
197
126
 
198
- ### Multi-series lines
127
+ Pairing `.foregroundStyle(by:)` with `.symbol(by:)` keeps series apart for
128
+ people who cannot tell the colours apart.
199
129
 
200
- ```swift
201
- Chart(temperatures) { item in
202
- LineMark(
203
- x: .value("Date", item.date),
204
- y: .value("Temp", item.temperature)
205
- )
206
- .foregroundStyle(by: .value("City", item.city))
207
- .symbol(by: .value("City", item.city))
208
- }
209
- ```
210
-
211
- ### Line with area fill
130
+ A line over a fading area:
212
131
 
213
132
  ```swift
214
- Chart(data) { item in
215
- AreaMark(
216
- x: .value("Date", item.date),
217
- y: .value("Value", item.value)
218
- )
219
- .foregroundStyle(
220
- .linearGradient(
221
- colors: [.blue.opacity(0.3), .blue.opacity(0.05)],
222
- startPoint: .top,
223
- endPoint: .bottom
224
- )
225
- )
226
- LineMark(
227
- x: .value("Date", item.date),
228
- y: .value("Value", item.value)
229
- )
230
- .foregroundStyle(.blue)
133
+ Chart(prices) { point in
134
+ AreaMark(x: .value("Day", point.day), y: .value("Price", point.close))
135
+ .foregroundStyle(.linearGradient(
136
+ colors: [.indigo.opacity(0.35), .indigo.opacity(0.02)],
137
+ startPoint: .top, endPoint: .bottom))
138
+ LineMark(x: .value("Day", point.day), y: .value("Price", point.close))
139
+ .foregroundStyle(.indigo)
231
140
  }
232
141
  ```
233
142
 
234
- ### Interpolation methods
143
+ Interpolation methods:
235
144
 
236
- | Method | Use Case |
237
- |---|---|
238
- | `.linear` | Default; straight segments between points |
239
- | `.monotone` | Smooth curve that preserves monotonicity |
240
- | `.catmullRom` | Smooth general-purpose curve |
241
- | `.cardinal` | Smooth with adjustable tension |
242
- | `.stepStart` | Step function starting at data point |
243
- | `.stepCenter` | Step function centered on data point |
244
- | `.stepEnd` | Step function ending at data point |
145
+ | Method | Result |
146
+ |--------|--------|
147
+ | `.linear` | Straight segments (the default) |
148
+ | `.monotone` | Smooth without overshooting; keeps monotonic data monotonic |
149
+ | `.catmullRom` | Smooth curve for general data |
150
+ | `.cardinal` | Smooth curve with adjustable tension |
151
+ | `.stepStart`, `.stepCenter`, `.stepEnd` | Steps placed at the start, middle or end of each interval |
245
152
 
246
- ```swift
247
- LineMark(x: .value("X", item.x), y: .value("Y", item.y))
248
- .interpolationMethod(.monotone)
249
- ```
250
-
251
- ### Sparkline (minimal inline chart)
153
+ A sparkline:
252
154
 
253
155
  ```swift
254
- Chart(recentData) { item in
255
- LineMark(
256
- x: .value("Time", item.time),
257
- y: .value("Value", item.value)
258
- )
259
- .interpolationMethod(.catmullRom)
156
+ Chart(recent) { point in
157
+ LineMark(x: .value("t", point.index), y: .value("v", point.value))
158
+ .interpolationMethod(.catmullRom)
260
159
  }
261
160
  .chartXAxis(.hidden)
262
161
  .chartYAxis(.hidden)
@@ -264,625 +163,360 @@ Chart(recentData) { item in
264
163
  .frame(width: 80, height: 30)
265
164
  ```
266
165
 
267
- ---
268
-
269
- ## Pie and Donut Chart Patterns (SectorMark, iOS 17+)
270
-
271
- Use strictly positive values for sectors. Filter, aggregate, or show zero and
272
- negative values outside the pie or donut so angular sizes remain meaningful.
273
-
274
- ### Basic pie chart
275
-
276
- ```swift
277
- Chart(products, id: \.name) { item in
278
- SectorMark(angle: .value("Sales", item.sales))
279
- .foregroundStyle(by: .value("Product", item.name))
280
- }
281
- ```
166
+ ## Pies and Donuts
282
167
 
283
- ### Donut chart with golden ratio inner radius
168
+ An inner radius of 0.618 (the golden ratio) gives a balanced donut. Put a label
169
+ in the hole with `.chartBackground`:
284
170
 
285
171
  ```swift
286
- Chart(products, id: \.name) { item in
287
- SectorMark(
288
- angle: .value("Sales", item.sales),
289
- innerRadius: .ratio(0.618),
290
- outerRadius: .inset(10),
291
- angularInset: 1
292
- )
293
- .cornerRadius(4)
294
- .foregroundStyle(by: .value("Product", item.name))
295
- }
296
- ```
297
-
298
- ### Donut chart with center label
299
-
300
- ```swift
301
- Chart(products, id: \.name) { item in
302
- SectorMark(
303
- angle: .value("Sales", item.sales),
304
- innerRadius: .ratio(0.618),
305
- angularInset: 1
306
- )
307
- .cornerRadius(4)
308
- .foregroundStyle(by: .value("Product", item.name))
172
+ Chart(portfolio) { holding in
173
+ SectorMark(angle: .value("Value", holding.value), innerRadius: .ratio(0.618))
174
+ .foregroundStyle(by: .value("Asset", holding.asset))
309
175
  }
310
176
  .chartBackground { _ in
311
177
  VStack {
312
- Text("Total")
313
- .font(.caption)
314
- .foregroundStyle(.secondary)
315
- Text("\(totalSales, format: .number)")
316
- .font(.title2.bold())
178
+ Text("Total").font(.caption)
179
+ Text(portfolioTotal, format: .currency(code: "EUR")).font(.headline)
317
180
  }
318
181
  }
319
182
  ```
320
183
 
321
- ### Angular selection on donut
184
+ Selecting a slice. The binding holds a position along the summed values, so
185
+ map it back to a slice:
322
186
 
323
187
  ```swift
324
- struct ProductSales: Identifiable {
325
- let id = UUID()
326
- let name: String
327
- let sales: Double
328
- }
188
+ struct PortfolioDonut: View {
189
+ let holdings: [Holding]
190
+ @State private var selectedAngle: Double?
329
191
 
330
- @State private var selectedAngle: Double?
331
-
332
- var selectedProduct: ProductSales? {
333
- guard let selectedAngle else { return nil }
334
- var runningTotal = 0.0
335
-
336
- return products.first { product in
337
- let range = runningTotal..<(runningTotal + product.sales)
338
- runningTotal += product.sales
339
- return range.contains(selectedAngle)
192
+ private var selectedHolding: Holding? {
193
+ guard let angle = selectedAngle else { return nil }
194
+ var start = 0.0
195
+ for holding in holdings {
196
+ let end = start + holding.value
197
+ if (start..<end).contains(angle) { return holding }
198
+ start = end
199
+ }
200
+ return nil
340
201
  }
341
- }
342
202
 
343
- Chart(products, id: \.name) { item in
344
- SectorMark(
345
- angle: .value("Sales", item.sales),
346
- innerRadius: .ratio(0.618),
347
- angularInset: 1
348
- )
349
- .cornerRadius(4)
350
- .foregroundStyle(by: .value("Product", item.name))
351
- .opacity(selectedProduct == nil || selectedProduct?.name == item.name ? 1.0 : 0.4)
203
+ var body: some View {
204
+ Chart(holdings) { holding in
205
+ SectorMark(angle: .value("Value", holding.value), innerRadius: .ratio(0.6))
206
+ .foregroundStyle(by: .value("Asset", holding.asset))
207
+ .opacity(selectedHolding == nil || selectedHolding?.id == holding.id ? 1 : 0.4)
208
+ }
209
+ .chartAngleSelection(value: $selectedAngle)
210
+ }
352
211
  }
353
- .chartAngleSelection(value: $selectedAngle)
354
212
  ```
355
213
 
356
- `chartAngleSelection(value:)` binds the selected plottable angle value, not the
357
- sector label. Convert that value through cumulative sector ranges before using
358
- it to highlight or annotate a category.
359
-
360
- ### Grouping small slices
361
-
362
- Limit pie/donut charts to 5-7 positive-value sectors. Group the rest into "Other":
214
+ Keep five to seven positive slices:
363
215
 
364
216
  ```swift
365
- func groupSmallSlices(_ data: [CategorySales], topN: Int = 5) -> [CategorySales] {
366
- let sorted = data.sorted { $0.sales > $1.sales }
367
- let top = Array(sorted.prefix(topN))
368
- let otherTotal = sorted.dropFirst(topN).reduce(0) { $0 + $1.sales }
369
- guard otherTotal > 0 else { return top }
370
- return top + [CategorySales(name: "Other", sales: otherTotal)]
217
+ func topSlices(_ items: [Holding], keep limit: Int = 5) -> [Holding] {
218
+ let ordered = items.filter { $0.value > 0 }.sorted { $0.value > $1.value }
219
+ let head = Array(ordered.prefix(limit))
220
+ let remainder = ordered.dropFirst(limit).reduce(0) { $0 + $1.value }
221
+ guard remainder > 0 else { return head }
222
+ return head + [Holding(asset: "Other", value: remainder)]
371
223
  }
372
224
  ```
373
225
 
374
- ---
375
-
376
- ## Combined Chart Patterns
226
+ ## Combining Marks
377
227
 
378
- ### Line + area (trend with fill)
228
+ A range band with an average line:
379
229
 
380
230
  ```swift
381
- Chart(data) { item in
382
- AreaMark(
383
- x: .value("Date", item.date),
384
- yStart: .value("Min", item.low),
385
- yEnd: .value("Max", item.high)
386
- )
387
- .foregroundStyle(.blue.opacity(0.15))
388
-
389
- LineMark(
390
- x: .value("Date", item.date),
391
- y: .value("Average", item.average)
392
- )
393
- .foregroundStyle(.blue)
394
- .lineStyle(StrokeStyle(lineWidth: 2))
231
+ Chart(week) { day in
232
+ AreaMark(x: .value("Day", day.date),
233
+ yStart: .value("Low", day.low),
234
+ yEnd: .value("High", day.high))
235
+ .opacity(0.15)
236
+ LineMark(x: .value("Day", day.date), y: .value("Mean", day.mean))
237
+ .lineStyle(StrokeStyle(lineWidth: 2))
395
238
  }
396
239
  ```
397
240
 
398
- ### Bar + threshold rule
241
+ Bars with a target line:
399
242
 
400
243
  ```swift
401
244
  Chart {
402
- ForEach(data) { item in
403
- BarMark(
404
- x: .value("Month", item.month),
405
- y: .value("Revenue", item.revenue)
406
- )
245
+ ForEach(weeks) { week in
246
+ BarMark(x: .value("Week", week.label), y: .value("Hours", week.hours))
407
247
  }
408
- RuleMark(y: .value("Target", targetRevenue))
409
- .foregroundStyle(.red)
410
- .lineStyle(StrokeStyle(lineWidth: 1, dash: [5, 3]))
411
- .annotation(position: .top, alignment: .leading) {
412
- Text("Target: \(targetRevenue, format: .number)")
413
- .font(.caption)
414
- .foregroundStyle(.red)
415
- }
248
+ RuleMark(y: .value("Target", 38))
249
+ .lineStyle(StrokeStyle(lineWidth: 1, dash: [4, 4]))
250
+ .annotation(position: .top, alignment: .leading) { Text("38 h") }
416
251
  }
417
252
  ```
418
253
 
419
- ### Scatter + trend line
254
+ Observations with a fitted curve; marks and plots can share a chart:
420
255
 
421
256
  ```swift
422
257
  Chart {
423
- ForEach(data) { item in
424
- PointMark(
425
- x: .value("Experience", item.yearsExperience),
426
- y: .value("Salary", item.salary)
427
- )
428
- .opacity(0.6)
258
+ ForEach(samples) { sample in
259
+ PointMark(x: .value("Dose", sample.dose), y: .value("Response", sample.response))
429
260
  }
430
- LinePlot(x: "Experience", y: "Salary", domain: 0...20) { x in
431
- baseSalary + x * salaryPerYear // linear trend
261
+ LinePlot(x: "Dose", y: "Response", domain: 0...10) { dose in
262
+ fit.slope * dose + fit.intercept
432
263
  }
433
264
  .foregroundStyle(.red)
434
- .lineStyle(StrokeStyle(lineWidth: 1.5, dash: [4, 2]))
265
+ .lineStyle(StrokeStyle(lineWidth: 1, dash: [3, 3]))
435
266
  }
436
267
  ```
437
268
 
438
- ---
269
+ ## A Tooltip on Selection
439
270
 
440
- ## Chart Selection with Overlay Annotation
271
+ ```swift
272
+ struct ActivityChart: View {
273
+ let days: [ActivityDay]
274
+ @State private var focusedDate: Date?
441
275
 
442
- Show a tooltip at the selected position using `chartOverlay`:
276
+ private var focusedDay: ActivityDay? {
277
+ guard let focusedDate else { return nil }
278
+ let calendar = Calendar.current
279
+ return days.first { calendar.isDate($0.date, inSameDayAs: focusedDate) }
280
+ }
443
281
 
444
- ```swift
445
- @State private var selectedDate: Date?
446
-
447
- var body: some View {
448
- Chart(data) { item in
449
- LineMark(
450
- x: .value("Date", item.date),
451
- y: .value("Value", item.value)
452
- )
453
- if let selectedDate,
454
- let match = data.first(where: { Calendar.current.isDate($0.date, inSameDayAs: selectedDate) }) {
455
- RuleMark(x: .value("Selected", match.date))
456
- .foregroundStyle(.secondary)
457
- PointMark(
458
- x: .value("Date", match.date),
459
- y: .value("Value", match.value)
460
- )
461
- .symbolSize(60)
462
- .annotation(position: .top) {
463
- Text("\(match.value, format: .number)")
464
- .font(.caption)
465
- .padding(4)
466
- .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 4))
282
+ var body: some View {
283
+ Chart {
284
+ ForEach(days) { day in
285
+ LineMark(x: .value("Date", day.date, unit: .day),
286
+ y: .value("Minutes", day.minutes))
287
+ }
288
+ if let focusedDay {
289
+ RuleMark(x: .value("Date", focusedDay.date, unit: .day))
290
+ .foregroundStyle(.secondary)
291
+ PointMark(x: .value("Date", focusedDay.date, unit: .day),
292
+ y: .value("Minutes", focusedDay.minutes))
293
+ .symbolSize(80)
294
+ .annotation(position: .top) {
295
+ Text("\(focusedDay.minutes) min")
296
+ .padding(6)
297
+ .background(.regularMaterial, in: .rect(cornerRadius: 6))
298
+ }
467
299
  }
468
300
  }
301
+ .chartXSelection(value: $focusedDate)
469
302
  }
470
- .chartXSelection(value: $selectedDate)
471
303
  }
472
304
  ```
473
305
 
474
- ---
306
+ ## Scrolling with a Bound Position
475
307
 
476
- ## Scrollable Chart with Visible Domain
308
+ `chartScrollPosition(x:)` takes a binding to a non-optional `Plottable` value,
309
+ so bind a `Date`, not a `Date?`:
477
310
 
478
311
  ```swift
479
- @State private var scrollPosition: Date?
480
-
481
- var body: some View {
482
- Chart(dailySteps) { item in
483
- BarMark(
484
- x: .value("Date", item.date, unit: .day),
485
- y: .value("Steps", item.steps)
486
- )
487
- }
488
- .chartScrollableAxes(.horizontal)
489
- .chartXVisibleDomain(length: 3600 * 24 * 7) // 7 days
490
- .chartScrollPosition(x: $scrollPosition)
491
- .chartScrollTargetBehavior(
492
- .valueAligned(matching: DateComponents(hour: 0), majorAlignment: .page)
493
- )
494
- .chartXAxis {
495
- AxisMarks(values: .stride(by: .day)) { value in
496
- AxisGridLine()
497
- AxisValueLabel(format: .dateTime.weekday(.abbreviated))
498
- }
312
+ @State private var windowStart = Date.now.addingTimeInterval(-7 * 86_400)
313
+
314
+ Chart(readings) { reading in
315
+ BarMark(x: .value("Day", reading.date, unit: .day),
316
+ y: .value("Litres", reading.litres))
317
+ }
318
+ .chartScrollableAxes(.horizontal)
319
+ .chartXVisibleDomain(length: 3600 * 24 * 7)
320
+ .chartScrollPosition(x: $windowStart)
321
+ .chartXAxis {
322
+ AxisMarks(values: .stride(by: .day)) { value in
323
+ AxisGridLine()
324
+ AxisValueLabel(format: .dateTime.weekday(.abbreviated))
499
325
  }
500
326
  }
501
327
  ```
502
328
 
503
- ---
504
-
505
- ## Function Plotting (LinePlot, iOS 18+)
506
-
507
- ### Standard function y = f(x)
329
+ ## Function Plots (iOS 18)
508
330
 
509
331
  ```swift
510
332
  Chart {
511
- LinePlot(x: "x", y: "y", domain: -2 * .pi ... 2 * .pi) { x in
512
- sin(x)
513
- }
514
- .foregroundStyle(.blue)
333
+ LinePlot(x: "Angle", y: "Amplitude", domain: -2 * .pi ... 2 * .pi) { cos($0) }
515
334
  }
516
- .chartYScale(domain: -1.5...1.5)
517
- ```
335
+ .chartYScale(domain: -1.2...1.2)
518
336
 
519
- ### Parametric function (x, y) = f(t)
520
-
521
- ```swift
522
337
  Chart {
523
- LinePlot(x: "x", y: "y", t: "t", domain: 0 ... 2 * .pi) { t in
524
- (x: cos(t), y: sin(t))
338
+ LinePlot(x: "Across", y: "Up", t: "Turn", domain: 0...(2 * .pi)) { turn in
339
+ (x: 2 * cos(turn), y: 2 * sin(turn))
525
340
  }
526
341
  }
527
- .chartXScale(domain: -1.5...1.5)
528
- .chartYScale(domain: -1.5...1.5)
529
- ```
342
+ .chartXScale(domain: -2.5...2.5)
343
+ .chartYScale(domain: -2.5...2.5)
530
344
 
531
- ### Range area function
532
-
533
- ```swift
534
345
  Chart {
535
- AreaPlot(x: "x", yStart: "min", yEnd: "max", domain: 0...10) { x in
536
- (yStart: sin(x) - 0.5, yEnd: sin(x) + 0.5)
346
+ AreaPlot(x: "x", yStart: "lower", yEnd: "upper", domain: 0...4) { x in
347
+ (yStart: x - 0.5, yEnd: x * x / 2 + 0.5)
537
348
  }
538
- .foregroundStyle(.blue.opacity(0.2))
539
349
  }
540
350
  ```
541
351
 
542
- ---
352
+ The last chart fills the band between two functions of x.
543
353
 
544
- ## 3D Charts and Surfaces (Chart3D, iOS 26+)
354
+ ## 3D Charts and Surfaces (iOS 26)
545
355
 
546
- Use `Chart3D` when the data has a real third dimension, such as `(x, y, z)`
547
- points, 3D regions, or a bivariate surface. Keep ordinary category comparison,
548
- time series, and proportions in 2D charts because they are easier to label,
549
- compare, and make accessible.
550
-
551
- ### SurfacePlot for bivariate functions
356
+ `Chart3D` is for data with a real third dimension: points in (x, y, z), 3D
357
+ regions, or a surface of two variables. Categories, time series and shares stay
358
+ in 2D: labels, comparisons and VoiceOver all work better there.
552
359
 
553
360
  ```swift
554
- @State private var pose: Chart3DPose = .default
361
+ struct SensorCloud: View {
362
+ let readings: [SensorReading]
555
363
 
556
- Chart3D {
557
- SurfacePlot(x: "x", y: "y", z: "z") { x, z in
558
- sin(2 * x) * cos(2 * z)
364
+ var body: some View {
365
+ Chart3D(readings) { reading in
366
+ PointMark(x: .value("X", reading.x),
367
+ y: .value("Y", reading.y),
368
+ z: .value("Z", reading.z))
369
+ .foregroundStyle(by: .value("Sensor", reading.sensor))
370
+ }
371
+ .chart3DCameraProjection(.perspective)
559
372
  }
560
- .foregroundStyle(.heightBased)
561
- }
562
- .chartXScale(domain: -2...2)
563
- .chartYScale(domain: -1...1)
564
- .chartZScale(domain: -2...2)
565
- .chart3DPose($pose)
566
- ```
567
-
568
- ### 3D point cloud
569
-
570
- ```swift
571
- Chart3D(points) { point in
572
- PointMark(
573
- x: .value("Width", point.x),
574
- y: .value("Height", point.y),
575
- z: .value("Depth", point.z)
576
- )
577
- .foregroundStyle(by: .value("Cluster", point.cluster))
578
373
  }
579
- .chart3DCameraProjection(.perspective)
580
374
  ```
581
375
 
582
- ### 3D review notes
583
-
584
- - Confirm the z dimension is meaningful and labeled; do not use depth only for decoration.
585
- - Set explicit x/y/z domains when users need stable comparisons across states.
586
- - Bind `Chart3DPose` when users need to inspect the scene interactively.
587
- - Use `SurfacePlot` for `y = f(x, z)` surfaces; use 3D mark initializers for observed data points or regions.
588
-
589
- ---
376
+ Review notes:
377
+ - The z axis must mean something and carry a label.
378
+ - Set explicit x, y and z domains so charts can be compared.
379
+ - Bind a `Chart3DPose` when users should rotate the chart.
380
+ - `SurfacePlot` draws y as a function of x and z; the 3D mark initialisers
381
+ draw observed points and regions.
590
382
 
591
383
  ## Accessibility
592
384
 
593
- ### Automatic VoiceOver support
594
-
595
- Swift Charts provides automatic VoiceOver descriptions for chart elements. The
596
- framework reads axis labels and values to visually impaired users without
597
- additional code. Ensure `.value("Label", ...)` strings are descriptive.
598
-
599
- ### Custom accessibility labels
600
-
601
- ```swift
602
- Chart(data) { item in
603
- BarMark(
604
- x: .value("Month", item.month),
605
- y: .value("Sales", item.sales)
606
- )
607
- .accessibilityLabel("Sales for \(item.month)")
608
- .accessibilityValue("\(item.sales) units sold")
609
- }
610
- ```
611
-
612
- ### Accessibility on vectorized plots (KeyPath-based)
613
-
614
- ```swift
615
- BarPlot(data, x: .value("Month", \.month), y: .value("Sales", \.sales))
616
- .accessibilityLabel(\.accessibilityDescription)
617
- .accessibilityValue(\.formattedSales)
618
- ```
619
-
620
- ### Audio graphs
621
-
622
- The system automatically generates audio representations of chart data for
623
- VoiceOver users. Use clear, consistent data labels to ensure audio graphs
624
- convey meaningful patterns.
625
-
626
- ### Best practices
627
-
628
- - Use descriptive strings in `.value("Label", ...)` -- these become VoiceOver labels.
629
- - Add `.accessibilityLabel` and `.accessibilityValue` for context beyond raw numbers.
630
- - Test with VoiceOver enabled: navigate the chart and verify each element is announced.
631
- - Avoid `.accessibilityHidden(true)` on data-bearing marks.
632
-
633
- ---
634
-
635
- ## Dynamic Type and Color Considerations
636
-
637
- ### Dynamic Type
638
-
639
- Charts automatically adjust axis label sizes with Dynamic Type. Avoid fixed
640
- frame heights that clip labels at larger text sizes.
641
-
642
- ```swift
643
- // WRONG -- clips at large text sizes
644
- Chart(data) { ... }
645
- .frame(height: 200)
646
-
647
- // CORRECT -- adaptive height
648
- Chart(data) { ... }
649
- .frame(minHeight: 200)
650
- .frame(maxHeight: 400)
651
- ```
652
-
653
- Test charts at the "Accessibility Extra Extra Extra Large" text size to verify
654
- axis labels, annotations, and legends remain readable.
655
-
656
- ### Color
657
-
658
- - Avoid encoding meaning solely in color. Pair `.foregroundStyle(by:)` with
659
- `.symbol(by:)` or `.lineStyle(by:)` for distinguishability.
660
- - Use system colors that adapt to both light and dark modes.
661
- - Test with color blindness simulations in the Accessibility Inspector.
662
-
663
- ```swift
664
- LineMark(x: .value("Date", item.date), y: .value("Value", item.value))
665
- .foregroundStyle(by: .value("Category", item.category))
666
- .symbol(by: .value("Category", item.category))
667
- .lineStyle(by: .value("Category", item.category))
668
- ```
669
-
670
- ---
671
-
672
- ## Performance: Vectorized Plots for Large Datasets
673
-
674
- For datasets exceeding 1000 data points, use vectorized plot types instead of
675
- individual marks. Vectorized plots accept entire collections and render
676
- efficiently.
677
-
678
- ### When to use vectorized plots
679
-
680
- | Data Points | Recommended Approach |
681
- |---|---|
682
- | < 100 | Individual marks (`BarMark`, `LineMark`, etc.) |
683
- | 100 - 1000 | Either approach; profile if performance matters |
684
- | > 1000 | Vectorized plots (`BarPlot`, `LinePlot`, etc.) |
685
-
686
- ### Data-driven vectorized plot
687
-
688
- ```swift
689
- struct SensorReading: Identifiable {
385
+ - Swift Charts builds VoiceOver descriptions from axis labels and values, so
386
+ the strings in `.value("Label", ...)` are what VoiceOver says. Make them
387
+ descriptive.
388
+ - Add `.accessibilityLabel` and `.accessibilityValue` to marks when the
389
+ default is not clear enough.
390
+ - Vectorized plots take key paths:
391
+ `.accessibilityLabel(\.spokenName)` and `.accessibilityValue(\.spokenValue)`.
392
+ - The system creates an audio graph for VoiceOver users automatically; clear,
393
+ consistent labels make it useful.
394
+ - Move through every element with VoiceOver. Never mark data-bearing marks
395
+ `.accessibilityHidden(true)`.
396
+
397
+ ## Dynamic Type and Colour
398
+
399
+ - Axis labels follow Dynamic Type. Avoid fixed heights; give a range such as
400
+ `.frame(minHeight: 200)` with `.frame(maxHeight: 400)`.
401
+ - Check axes, annotations and legends at the largest accessibility size
402
+ (Accessibility Extra Extra Extra Large).
403
+ - Colour must not be the only carrier of meaning. Pair
404
+ `.foregroundStyle(by:)` with `.symbol(by:)`, `.lineStyle(by:)` or both.
405
+ - Prefer system colours, which adapt, and check colour-blindness filters in
406
+ Accessibility Inspector.
407
+
408
+ ## Performance: When to Vectorize
409
+
410
+ | Points | Use |
411
+ |--------|-----|
412
+ | Fewer than 100 | Individual marks |
413
+ | 100 to 1,000 | Either; profile if it feels slow |
414
+ | More than 1,000 | Vectorized plots |
415
+
416
+ ```swift
417
+ struct TemperatureSample: Identifiable {
690
418
  let id: Int
691
- let timestamp: Date
692
- let temperature: Double
693
- var color: Color { temperature > 30 ? .red : .blue }
694
- var accessibilityDescription: Text {
695
- Text("\(timestamp.formatted(.dateTime.hour().minute())): \(temperature, specifier: "%.1f") degrees")
696
- }
419
+ let time: Date
420
+ let celsius: Double
421
+ var tint: Color { celsius > 30 ? .red : .blue }
422
+ var spokenValue: Text { Text("\(celsius, specifier: "%.1f") degrees") }
697
423
  }
698
424
 
699
425
  Chart {
700
- LinePlot(
701
- readings,
702
- x: .value("Time", \.timestamp),
703
- y: .value("Temperature", \.temperature)
704
- )
705
- .foregroundStyle(.blue)
426
+ LinePlot(samples, x: .value("Time", \.time), y: .value("Celsius", \.celsius))
427
+ .foregroundStyle(\.tint)
428
+ .accessibilityValue(\.spokenValue)
706
429
  }
707
430
  ```
708
431
 
709
- ### KeyPath modifier ordering
710
-
711
- Apply KeyPath-based modifiers before simple-value modifiers:
712
-
713
- ```swift
714
- // WRONG
715
- BarPlot(data, x: .value("X", \.x), y: .value("Y", \.y))
716
- .opacity(0.8) // value modifier
717
- .foregroundStyle(\.color) // KeyPath -- compiler error
718
-
719
- // CORRECT
720
- BarPlot(data, x: .value("X", \.x), y: .value("Y", \.y))
721
- .foregroundStyle(\.color) // KeyPath first
722
- .opacity(0.8) // value modifier second
723
- ```
724
-
725
- ### Available vectorized plot types
726
-
727
- | Plot Type | Mark Equivalent | Available From |
728
- |---|---|---|
729
- | `BarPlot` | `BarMark` | iOS 18+ |
730
- | `LinePlot` | `LineMark` | iOS 18+ |
731
- | `PointPlot` | `PointMark` | iOS 18+ |
732
- | `AreaPlot` | `AreaMark` | iOS 18+ |
733
- | `RulePlot` | `RuleMark` | iOS 18+ |
734
- | `RectanglePlot` | `RectangleMark` | iOS 18+ |
735
- | `SectorPlot` | `SectorMark` | iOS 18+ |
736
-
737
- ---
432
+ | Vectorized (iOS 18) | Mark equivalent |
433
+ |---------------------|-----------------|
434
+ | `BarPlot` | `BarMark` |
435
+ | `LinePlot` | `LineMark` |
436
+ | `PointPlot` | `PointMark` |
437
+ | `AreaPlot` | `AreaMark` |
438
+ | `RulePlot` | `RuleMark` |
439
+ | `RectanglePlot` | `RectangleMark` |
440
+ | `SectorPlot` | `SectorMark` |
738
441
 
739
442
  ## Dark Mode and Theming
740
443
 
741
- ### Automatic adaptation
742
-
743
- Swift Charts inherits the current color scheme automatically. System colors
744
- (`.blue`, `.orange`, `.green`) adapt to light and dark modes without extra code.
745
-
746
- ### Custom color palettes
747
-
748
- Use `.chartForegroundStyleScale` to define a consistent palette:
444
+ Charts follow the colour scheme, and system colours adapt on their own.
749
445
 
750
446
  ```swift
751
- Chart(data) { item in
752
- BarMark(
753
- x: .value("Category", item.category),
754
- y: .value("Value", item.value)
755
- )
756
- .foregroundStyle(by: .value("Category", item.category))
447
+ Chart(spending) { entry in
448
+ BarMark(x: .value("Period", entry.period), y: .value("Spent", entry.amount))
449
+ .foregroundStyle(by: .value("Kind", entry.kind))
757
450
  }
758
451
  .chartForegroundStyleScale([
759
- "Electronics": .blue,
760
- "Clothing": .purple,
761
- "Food": .orange,
762
- "Books": .green,
763
- "Other": .gray
452
+ "Food": Color.orange,
453
+ "Travel": Color.teal,
454
+ "Home": Color.purple,
764
455
  ])
765
- ```
766
-
767
- ### Background and plot area styling
768
-
769
- ```swift
770
- Chart(data) { ... }
771
- .chartPlotStyle { plotArea in
772
- plotArea
773
- .background(.quaternary.opacity(0.3))
774
- .border(.quaternary, width: 0.5)
456
+ .chartPlotStyle { plot in
457
+ plot.background(.quaternary.opacity(0.3))
458
+ .border(.separator, width: 0.5)
775
459
  }
776
- ```
777
-
778
- ### Axis styling
779
-
780
- ```swift
781
460
  .chartXAxisStyle { axis in
782
- axis.background(.blue.opacity(0.05))
783
- }
784
- ```
785
-
786
- ### Testing dark mode
787
-
788
- Always preview charts in both light and dark color schemes. In Xcode previews:
789
-
790
- ```swift
791
- #Preview {
792
- ChartView()
793
- .preferredColorScheme(.dark)
461
+ axis.background(.thinMaterial)
794
462
  }
795
463
  ```
796
464
 
797
- Verify:
798
- - Axis labels and grid lines are readable.
799
- - Data colors maintain sufficient contrast.
800
- - Annotations and legend text adapt properly.
801
-
802
- ---
465
+ `chartForegroundStyleScale` fixes one colour per category across the app.
466
+ Preview both schemes (`.preferredColorScheme(.dark)` in a `#Preview`) and check
467
+ that labels and grid lines stay readable, data keeps its contrast, and
468
+ annotations and legends adapt.
803
469
 
804
- ## Heat Map Pattern
470
+ ## Heat Map
805
471
 
806
472
  ```swift
807
- Chart(heatMapData) { item in
808
- RectangleMark(
809
- x: .value("Hour", item.hour),
810
- y: .value("Day", item.day)
811
- )
812
- .foregroundStyle(by: .value("Count", item.count))
473
+ Chart(bookings) { cell in
474
+ RectangleMark(x: .value("Hour", cell.hour), y: .value("Weekday", cell.weekday))
475
+ .foregroundStyle(by: .value("Bookings", cell.count))
813
476
  }
814
- .chartForegroundStyleScale(range: Gradient(colors: [.blue, .yellow, .red]))
815
- ```
816
-
817
- ---
818
-
819
- ## Stacking Methods
820
-
821
- | Method | Behavior |
822
- |---|---|
823
- | `.standard` | Default. Regions stack on top showing absolute values. |
824
- | `.normalized` | Scales to 0-100% proportional view. |
825
- | `.center` | Baseline centered (streamgraph). |
826
- | `.unstacked` | Overlapping; no stacking. |
827
-
828
- ```swift
829
- AreaMark(
830
- x: .value("Date", item.date),
831
- y: .value("Revenue", item.revenue),
832
- stacking: .normalized
833
- )
834
- .foregroundStyle(by: .value("Category", item.category))
477
+ .chartForegroundStyleScale(range: Gradient(colors: [.mint, .yellow, .orange]))
835
478
  ```
836
479
 
837
- ---
838
-
839
- ## MarkDimension Options
480
+ ## Stacking
840
481
 
841
- | Dimension | Description |
842
- |---|---|
843
- | `.automatic` | Framework decides |
844
- | `.fixed(CGFloat)` | Exact pixel size |
845
- | `.inset(CGFloat)` | Inset from available space |
846
- | `.ratio(CGFloat)` | Proportion of available space (0...1) |
482
+ Pass `stacking:` to `BarMark` or `AreaMark`:
847
483
 
848
- Use for `width`, `height` on `BarMark` and `innerRadius`, `outerRadius` on `SectorMark`.
484
+ | Value | Effect |
485
+ |-------|--------|
486
+ | `.standard` | Absolute values stacked on each other (default) |
487
+ | `.normalized` | Each stack fills 0 to 100 percent |
488
+ | `.center` | Stacks centred on a baseline, as in a streamgraph |
489
+ | `.unstacked` | Series overlap instead of stacking |
849
490
 
850
- ---
491
+ ## `MarkDimension`
851
492
 
852
- ## Symbol Configuration
493
+ `.automatic`, `.fixed(CGFloat)`, `.inset(CGFloat)` and `.ratio(CGFloat)` with a
494
+ ratio between 0 and 1. Used for `width` and `height` on `BarMark` and for
495
+ `innerRadius` and `outerRadius` on `SectorMark`.
853
496
 
854
- ### Built-in shapes
497
+ ## Symbols
855
498
 
856
- `circle`, `square`, `triangle`, `diamond`, `pentagon`, `plus`, `cross`, `asterisk`
499
+ The built-in shapes are `asterisk`, `circle`, `cross`, `diamond`, `pentagon`,
500
+ `plus`, `square` and `triangle`.
857
501
 
858
502
  ```swift
859
- PointMark(x: .value("X", item.x), y: .value("Y", item.y))
503
+ PointMark(x: .value("Speed", run.speed), y: .value("Heart rate", run.bpm))
860
504
  .symbol(.diamond)
861
505
  .symbolSize(80)
862
- ```
863
506
 
864
- ### Data-driven symbol encoding
507
+ PointMark(x: .value("Speed", run.speed), y: .value("Heart rate", run.bpm))
508
+ .symbol(by: .value("Surface", run.surface))
865
509
 
866
- ```swift
867
- PointMark(x: .value("X", item.x), y: .value("Y", item.y))
868
- .symbol(by: .value("Category", item.category))
510
+ PointMark(x: .value("Speed", run.speed), y: .value("Heart rate", run.bpm))
511
+ .symbol { Image(systemName: "figure.run").font(.caption2) }
869
512
  ```
870
513
 
871
- ### Custom symbol view
514
+ ## `ChartProxy` and Coordinates
872
515
 
873
- ```swift
874
- PointMark(x: .value("X", item.x), y: .value("Y", item.y))
875
- .symbol {
876
- Image(systemName: "star.fill")
877
- .font(.caption2)
878
- }
879
- ```
880
-
881
- ---
882
-
883
- ## ChartProxy and Coordinate Conversion
884
-
885
- Use `chartOverlay` or `chartBackground` to access `ChartProxy`:
516
+ `chartOverlay` and `chartBackground` pass a `ChartProxy` that converts between
517
+ screen positions and data values. Since iOS 17, `plotFrame` (an optional
518
+ anchor) and `plotSize` replace the deprecated `plotAreaFrame` and
519
+ `plotAreaSize`.
886
520
 
887
521
  ```swift
888
522
  .chartOverlay { proxy in
@@ -891,86 +525,41 @@ Use `chartOverlay` or `chartBackground` to access `ChartProxy`:
891
525
  .fill(.clear)
892
526
  .contentShape(Rectangle())
893
527
  .gesture(
894
- DragGesture()
895
- .onChanged { value in
896
- let origin = geometry[proxy.plotAreaFrame].origin
897
- let location = CGPoint(
898
- x: value.location.x - origin.x,
899
- y: value.location.y - origin.y
900
- )
901
- if let date: Date = proxy.value(atX: location.x) {
902
- selectedDate = date
903
- }
904
- }
528
+ DragGesture(minimumDistance: 0).onChanged { drag in
529
+ guard let plotFrame = proxy.plotFrame else { return }
530
+ let origin = geometry[plotFrame].origin
531
+ let x = drag.location.x - origin.x
532
+ scrubbedDate = proxy.value(atX: x, as: Date.self)
533
+ }
905
534
  )
906
535
  }
907
536
  }
908
537
  ```
909
538
 
910
- ### Key ChartProxy methods
911
-
912
- | Method | Purpose |
913
- |---|---|
914
- | `position(forX:)` | Data value to screen x-coordinate |
915
- | `position(forY:)` | Data value to screen y-coordinate |
916
- | `value(atX:as:)` | Screen x-coordinate to data value |
917
- | `value(atY:as:)` | Screen y-coordinate to data value |
918
- | `plotAreaSize` | Size of the plot area |
919
- | `plotAreaFrame` | Anchor for the plot area frame |
920
-
921
- ---
922
-
923
- ## Quick Reference: Chart View Modifiers
924
-
925
- ### Axes
926
- - `chartXAxis(_:)` / `chartXAxis(content:)`
927
- - `chartYAxis(_:)` / `chartYAxis(content:)`
928
- - `chartXAxisLabel(...)` / `chartYAxisLabel(...)`
929
- - `chartXAxisStyle(content:)` / `chartYAxisStyle(content:)`
930
-
931
- ### Scales
932
- - `chartXScale(domain:range:type:)` and variants
933
- - `chartYScale(domain:range:type:)` and variants
934
- - `chartZScale(domain:range:type:)` for `Chart3D`
935
- - `chartForegroundStyleScale(_:)` -- custom color mapping
936
-
937
- ### 3D charts (iOS 26+)
938
- - `Chart3D` with `SurfacePlot` or 3D mark initializers
939
- - `chart3DPose(_:)` for interactive pose binding
940
- - `chart3DCameraProjection(_:)` for orthographic/perspective projection
941
-
942
- ### Legend
943
- - `chartLegend(_:)` -- visibility
944
- - `chartLegend(position:alignment:spacing:)` -- positioning
945
- - `chartLegend(position:alignment:spacing:content:)` -- custom content
946
-
947
- ### Selection (iOS 17+)
948
- - `chartXSelection(value:)` / `chartXSelection(range:)`
949
- - `chartYSelection(value:)` / `chartYSelection(range:)`
950
- - `chartAngleSelection(value:)` -- for `SectorMark`
951
-
952
- ### Scrolling (iOS 17+)
953
- - `chartScrollableAxes(_:)`
954
- - `chartXVisibleDomain(length:)` / `chartYVisibleDomain(length:)`
955
- - `chartScrollPosition(initialX:)` / `chartScrollPosition(x:)`
956
- - `chartScrollTargetBehavior(_:)`
957
-
958
- ### Overlay and Background
959
- - `chartOverlay(alignment:content:)` -- with `ChartProxy`
960
- - `chartBackground(alignment:content:)` -- with `ChartProxy`
961
- - `chartPlotStyle(content:)` -- plot area styling
962
-
963
- ---
964
-
965
- ## Apple Documentation Links
966
-
967
- - [Swift Charts](https://sosumi.ai/documentation/charts)
968
- - [Creating a chart using Swift Charts](https://sosumi.ai/documentation/charts/Creating-a-chart-using-Swift-Charts)
969
- - [BarMark](https://sosumi.ai/documentation/charts/BarMark)
970
- - [LineMark](https://sosumi.ai/documentation/charts/LineMark)
971
- - [SectorMark](https://sosumi.ai/documentation/charts/SectorMark)
972
- - [Chart3D](https://sosumi.ai/documentation/charts/Chart3D)
973
- - [SurfacePlot](https://sosumi.ai/documentation/charts/SurfacePlot)
974
- - [LinePlot](https://sosumi.ai/documentation/charts/LinePlot)
975
- - [AxisMarks](https://sosumi.ai/documentation/charts/AxisMarks)
976
- - [Swift Charts updates](https://sosumi.ai/documentation/updates/swiftcharts)
539
+ Proxy methods: `position(forX:)`, `position(forY:)`, `value(atX:as:)`,
540
+ `value(atY:as:)`, plus `plotSize` and `plotFrame`.
541
+
542
+ ## Modifier Quick Reference
543
+
544
+ | Area | Modifiers |
545
+ |------|-----------|
546
+ | Axes | hide or replace: `chartYAxis(_:)`, `chartXAxis(_:)`, and the builder forms `chartYAxis(content:)`, `chartXAxis(content:)`; titles: `chartYAxisLabel`, `chartXAxisLabel`; axis area styling: `chartYAxisStyle(content:)`, `chartXAxisStyle(content:)` |
547
+ | Scales | `chartYScale(domain:range:type:)`, `chartXScale(domain:range:type:)`; for `Chart3D` also `chartZScale(domain:range:type:)`; categorical colours with `chartForegroundStyleScale(_:)` |
548
+ | 3D | `chart3DCameraProjection(_:)` (perspective or orthographic), `chart3DPose(_:)` |
549
+ | Legend | `chartLegend(_:)` for visibility; `chartLegend(position:alignment:spacing:)` for placement; add `content:` for a custom legend view |
550
+ | Selection (iOS 17) | a single value: `chartXSelection(value:)`, `chartYSelection(value:)`; a span: `chartXSelection(range:)`, `chartYSelection(range:)`; pie slices: `chartAngleSelection(value:)` |
551
+ | Scrolling (iOS 17) | turn on with `chartScrollableAxes(_:)`; window size with `chartXVisibleDomain(length:)` or `chartYVisibleDomain(length:)`; position with `chartScrollPosition(initialX:)` or a bound `chartScrollPosition(x:)`; snapping with `chartScrollTargetBehavior(_:)` |
552
+ | Plot area and layers | `chartPlotStyle(content:)`, `chartBackground(alignment:content:)`, `chartOverlay(alignment:content:)` |
553
+
554
+ ## Apple Documentation
555
+
556
+ - [Swift Charts](https://developer.apple.com/documentation/charts)
557
+ - [Building a first chart](https://developer.apple.com/documentation/charts/creating-a-chart-using-swift-charts)
558
+ - [BarMark](https://developer.apple.com/documentation/charts/barmark)
559
+ - [LineMark](https://developer.apple.com/documentation/charts/linemark)
560
+ - [SectorMark](https://developer.apple.com/documentation/charts/sectormark)
561
+ - [Chart3D](https://developer.apple.com/documentation/charts/chart3d)
562
+ - [SurfacePlot](https://developer.apple.com/documentation/charts/surfaceplot)
563
+ - [LinePlot](https://developer.apple.com/documentation/charts/lineplot)
564
+ - [AxisMarks](https://developer.apple.com/documentation/charts/axismarks)
565
+ - [Swift Charts updates](https://developer.apple.com/documentation/updates/swiftcharts)