aw-spec-cli 0.1.4 → 0.1.5

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 (254) hide show
  1. package/assets/.agents/agent.json +28 -0
  2. package/assets/.agents/skills/aw-spec-orch/SKILL.md +56 -0
  3. package/assets/.agents/skills/aw-spec-orch-demo/SKILL.md +59 -0
  4. package/assets/.aw-spec/DESIGN-FORMAT.md +151 -0
  5. package/assets/.aw-spec/ORCH-DIALECT.md +156 -0
  6. package/assets/.aw-spec/RULE-PARTITION.md +126 -0
  7. package/assets/.aw-spec/extensions/agent-context/extension.yml +12 -9
  8. package/assets/.aw-spec/extensions.yml +12 -19
  9. package/assets/.aw-spec/integrations/aw-spec.manifest.json +1 -9
  10. package/assets/.aw-spec/interpreter/run-skill.py +1158 -0
  11. package/assets/.aw-spec/orchestrator/AGENT-PROFILE.md +94 -0
  12. package/assets/.aw-spec/orchestrator/README.md +300 -0
  13. package/assets/.aw-spec/orchestrator/adapters/claude_agent_sdk.py +74 -0
  14. package/assets/.aw-spec/orchestrator/adapters/google_antigravity.py +74 -0
  15. package/assets/.aw-spec/orchestrator/modules/delta-design.orch.yaml +105 -0
  16. package/assets/.aw-spec/orchestrator/modules/delta-spec.orch.yaml +79 -0
  17. package/assets/.aw-spec/orchestrator/modules/domain-select.orch.yaml +81 -0
  18. package/assets/.aw-spec/orchestrator/modules/tech-select.orch.yaml +75 -0
  19. package/assets/.aw-spec/orchestrator/orchestrator.py +1721 -0
  20. package/assets/.aw-spec/orchestrator/rev-templates/ai-rules.reference.md +40 -0
  21. package/assets/.aw-spec/orchestrator/rev-templates/comandrulemap.skeleton.md +59 -0
  22. package/assets/.aw-spec/orchestrator/rev-templates/commandtechrulemap.skeleton.md +97 -0
  23. package/assets/.aw-spec/orchestrator/rev-templates/domain-constitution.skeleton.md +61 -0
  24. package/assets/.aw-spec/orchestrator/rev-templates/domain-requirements.skeleton.md +48 -0
  25. package/assets/.aw-spec/orchestrator/rev-templates/domain-rule-file.skeleton.md +39 -0
  26. package/assets/.aw-spec/orchestrator/rev-templates/technical-constitution.skeleton.md +106 -0
  27. package/assets/.aw-spec/orchestrator/rev-templates/technical-rule-file.skeleton.md +54 -0
  28. package/assets/.aw-spec/orchestrator/workflows/_smoke.orch.yaml +160 -0
  29. package/assets/.aw-spec/orchestrator/workflows/aw-spec-add-component.orch.yaml +244 -0
  30. package/assets/.aw-spec/orchestrator/workflows/aw-spec-adopt.orch.yaml +775 -0
  31. package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-delta-design.orch.yaml +248 -0
  32. package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +261 -0
  33. package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +425 -0
  34. package/assets/.aw-spec/orchestrator/workflows/aw-spec-build.orch.yaml +188 -0
  35. package/assets/.aw-spec/orchestrator/workflows/aw-spec-characterize.orch.yaml +474 -0
  36. package/assets/.aw-spec/orchestrator/workflows/aw-spec-close-delta.orch.yaml +181 -0
  37. package/assets/.aw-spec/orchestrator/workflows/aw-spec-constitution.orch.yaml +284 -0
  38. package/assets/.aw-spec/orchestrator/workflows/aw-spec-demo.orch.yaml +103 -0
  39. package/assets/.aw-spec/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +69 -0
  40. package/assets/.aw-spec/orchestrator/workflows/aw-spec-deploy.orch.yaml +85 -0
  41. package/assets/.aw-spec/orchestrator/workflows/aw-spec-design.orch.yaml +382 -0
  42. package/assets/.aw-spec/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +382 -0
  43. package/assets/.aw-spec/orchestrator/workflows/aw-spec-foundation.orch.yaml +246 -0
  44. package/assets/.aw-spec/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +231 -0
  45. package/assets/.aw-spec/orchestrator/workflows/aw-spec-implement.orch.yaml +258 -0
  46. package/assets/.aw-spec/orchestrator/workflows/aw-spec-inventory.orch.yaml +236 -0
  47. package/assets/.aw-spec/orchestrator/workflows/aw-spec-onboard.orch.yaml +949 -0
  48. package/assets/.aw-spec/orchestrator/workflows/aw-spec-parity.orch.yaml +293 -0
  49. package/assets/.aw-spec/orchestrator/workflows/aw-spec-run.orch.yaml +177 -0
  50. package/assets/.aw-spec/orchestrator/workflows/aw-spec-select-domain.orch.yaml +79 -0
  51. package/assets/.aw-spec/orchestrator/workflows/aw-spec-select-feature.orch.yaml +128 -0
  52. package/assets/.aw-spec/orchestrator/workflows/aw-spec-specify.orch.yaml +412 -0
  53. package/assets/.aw-spec/scripts/bash/aw-inventory.sh +14 -0
  54. package/assets/.aw-spec/scripts/bash/aw-parity.sh +13 -0
  55. package/assets/.aw-spec/scripts/bash/aw-rev-constitution.sh +13 -0
  56. package/assets/.aw-spec/scripts/bash/aw-spec-actions.sh +1899 -0
  57. package/assets/.aw-spec/scripts/bash/aw-xref.sh +15 -0
  58. package/assets/.aw-spec/scripts/bash/common.sh +11 -60
  59. package/assets/.aw-spec/scripts/powershell/aw-inventory.ps1 +14 -0
  60. package/assets/.aw-spec/scripts/powershell/aw-parity.ps1 +13 -0
  61. package/assets/.aw-spec/scripts/powershell/aw-rev-constitution.ps1 +13 -0
  62. package/assets/.aw-spec/scripts/powershell/aw-spec-actions.ps1 +1563 -0
  63. package/assets/.aw-spec/scripts/powershell/aw-xref.ps1 +15 -0
  64. package/assets/.aw-spec/scripts/python/aw-inventory.py +683 -0
  65. package/assets/.aw-spec/scripts/python/aw-parity.py +380 -0
  66. package/assets/.aw-spec/scripts/python/aw-rev-constitution.py +312 -0
  67. package/assets/.aw-spec/scripts/python/aw-xref.py +1330 -0
  68. package/assets/.aw-spec/scripts/python/validate_okf.py +349 -0
  69. package/assets/.aw-spec/templates/constitution-domain-template.md +75 -0
  70. package/assets/.aw-spec/templates/constitution-technical-template.md +70 -0
  71. package/assets/.aw-spec/templates/delta-design-template.md +69 -0
  72. package/assets/.aw-spec/templates/delta-spec-template.md +60 -0
  73. package/assets/.aw-spec/templates/design-template.md +383 -0
  74. package/assets/.aw-spec/templates/okf-concept-template.md +103 -0
  75. package/assets/.aw-spec/templates/parity-manifest-template.json +49 -0
  76. package/assets/.aw-spec/templates/source-map-template.md +85 -0
  77. package/assets/.aw-spec/templates/spec-template.md +192 -71
  78. package/assets/.claude/agent.json +27 -0
  79. package/assets/.claude/skills/aw-spec-orch/SKILL.md +55 -0
  80. package/assets/.claude/skills/aw-spec-orch-demo/SKILL.md +59 -0
  81. package/assets/.kilocode/agent.json +28 -0
  82. package/assets/.kilocode/workflows/aw-spec-orch-demo.md +59 -0
  83. package/assets/.kilocode/workflows/aw-spec-orch.md +55 -0
  84. package/assets/docs/architecture/clean-architecture.md +1 -1
  85. package/assets/docs/architecture/cqrs.md +1 -1
  86. package/assets/docs/architecture/eventing.md +1 -1
  87. package/assets/docs/architecture/folder-structure.md +1 -1
  88. package/assets/docs/architecture/modular-monolith.md +1 -1
  89. package/assets/docs/architecture/persistence.md +1 -1
  90. package/assets/docs/architecture/testing.md +1 -1
  91. package/assets/docs/architecture/vertical-slices.md +1 -1
  92. package/assets/docs/components/Email/README.md +1 -1
  93. package/assets/docs/components/Jobs/README.md +1 -1
  94. package/assets/docs/components/QrGenerator/README.md +1 -1
  95. package/assets/docs/components/README.md +1 -1
  96. package/assets/docs/domain/domain-driven-design.md +1 -1
  97. package/assets/docs/domainspecs/healthcare/api-versioning.domain.md +1 -1
  98. package/assets/docs/domainspecs/healthcare/auditing.domain.md +86 -18
  99. package/assets/docs/domainspecs/healthcare/authorization.domain.md +1 -1
  100. package/assets/docs/domainspecs/healthcare/clinical-terms.md +1 -1
  101. package/assets/docs/domainspecs/healthcare/coding-standards.domain.md +1 -1
  102. package/assets/docs/domainspecs/healthcare/comandrulemap.md +58 -124
  103. package/assets/docs/domainspecs/healthcare/commandtechrulemap.md +119 -0
  104. package/assets/docs/domainspecs/healthcare/consent.md +1 -1
  105. package/assets/docs/domainspecs/healthcare/cqrs.domain.md +1 -1
  106. package/assets/docs/domainspecs/healthcare/data-classification.domain.md +1 -1
  107. package/assets/docs/domainspecs/healthcare/dependency-policy.domain.md +1 -1
  108. package/assets/docs/domainspecs/healthcare/dicom.md +1 -1
  109. package/assets/docs/domainspecs/healthcare/domain-driven-design.domain.md +1 -1
  110. package/assets/docs/domainspecs/healthcare/eventing.domain.md +1 -1
  111. package/assets/docs/domainspecs/healthcare/fhir.md +1 -1
  112. package/assets/docs/domainspecs/healthcare/folder-structure.domain.md +1 -1
  113. package/assets/docs/domainspecs/healthcare/hipaa.md +1 -1
  114. package/assets/docs/domainspecs/healthcare/hl7.md +1 -1
  115. package/assets/docs/domainspecs/healthcare/integration-terms.md +1 -1
  116. package/assets/docs/domainspecs/healthcare/persistence.domain.md +1 -1
  117. package/assets/docs/domainspecs/healthcare/terminology.md +1 -1
  118. package/assets/docs/domainspecs/healthcare/testing.domain.md +1 -1
  119. package/assets/docs/domainspecs/healthcare/vertical-slices.domain.md +1 -1
  120. package/assets/docs/domainspecs/healthcare/zero-trust.domain.md +1 -1
  121. package/assets/docs/domainspecs/pharma/api-versioning.domain.md +1 -1
  122. package/assets/docs/domainspecs/pharma/atc.md +1 -1
  123. package/assets/docs/domainspecs/pharma/auditing.domain.md +80 -16
  124. package/assets/docs/domainspecs/pharma/authorization.domain.md +1 -1
  125. package/assets/docs/domainspecs/pharma/coding-standards.domain.md +1 -1
  126. package/assets/docs/domainspecs/pharma/comandrulemap.md +64 -142
  127. package/assets/docs/domainspecs/pharma/commandtechrulemap.md +119 -0
  128. package/assets/docs/domainspecs/pharma/cqrs.domain.md +1 -1
  129. package/assets/docs/domainspecs/pharma/data-classification.domain.md +1 -1
  130. package/assets/docs/domainspecs/pharma/data-provenance.md +1 -1
  131. package/assets/docs/domainspecs/pharma/dependency-policy.domain.md +1 -1
  132. package/assets/docs/domainspecs/pharma/domain-driven-design.domain.md +1 -1
  133. package/assets/docs/domainspecs/pharma/eventing.domain.md +1 -1
  134. package/assets/docs/domainspecs/pharma/fhir.md +1 -1
  135. package/assets/docs/domainspecs/pharma/folder-structure.domain.md +1 -1
  136. package/assets/docs/domainspecs/pharma/hl7.md +1 -1
  137. package/assets/docs/domainspecs/pharma/idmp.md +1 -1
  138. package/assets/docs/domainspecs/pharma/integration-terms.md +1 -1
  139. package/assets/docs/domainspecs/pharma/ndc.md +1 -1
  140. package/assets/docs/domainspecs/pharma/persistence.domain.md +1 -1
  141. package/assets/docs/domainspecs/pharma/pharma-terms.md +1 -1
  142. package/assets/docs/domainspecs/pharma/product-lifecycle.domain.md +1 -1
  143. package/assets/docs/domainspecs/pharma/regulatory-compliance.md +1 -1
  144. package/assets/docs/domainspecs/pharma/terminology.md +1 -1
  145. package/assets/docs/domainspecs/pharma/testing.domain.md +1 -1
  146. package/assets/docs/domainspecs/pharma/vertical-slices.domain.md +1 -1
  147. package/assets/docs/domainspecs/pharma/zero-trust.domain.md +1 -1
  148. package/assets/docs/governance/api-versioning.md +1 -1
  149. package/assets/docs/governance/coding-standards.md +1 -1
  150. package/assets/docs/governance/dependency-policy.md +1 -1
  151. package/assets/docs/requirement-spec.txt +27 -0
  152. package/assets/docs/security/auditing.md +54 -11
  153. package/assets/docs/security/authorization.md +1 -1
  154. package/assets/docs/security/data-classification.md +1 -1
  155. package/assets/docs/security/zero-trust.md +1 -1
  156. package/dist/commands/init.d.ts.map +1 -1
  157. package/dist/commands/init.js +7 -54
  158. package/dist/commands/init.js.map +1 -1
  159. package/dist/index.js +0 -2
  160. package/dist/index.js.map +1 -1
  161. package/dist/utils/paths.js +2 -2
  162. package/dist/utils/paths.js.map +1 -1
  163. package/package.json +1 -1
  164. package/assets/.agents/skills/aw-spec-addcomponent/SKILL.md +0 -129
  165. package/assets/.agents/skills/aw-spec-agent-context-update/SKILL.md +0 -31
  166. package/assets/.agents/skills/aw-spec-analyze/SKILL.md +0 -296
  167. package/assets/.agents/skills/aw-spec-checklist/SKILL.md +0 -374
  168. package/assets/.agents/skills/aw-spec-clarify/SKILL.md +0 -320
  169. package/assets/.agents/skills/aw-spec-constitution/SKILL.md +0 -194
  170. package/assets/.agents/skills/aw-spec-fast-implement/SKILL.md +0 -268
  171. package/assets/.agents/skills/aw-spec-foundation/SKILL.md +0 -358
  172. package/assets/.agents/skills/aw-spec-implement/SKILL.md +0 -279
  173. package/assets/.agents/skills/aw-spec-minimal-implementation/SKILL.md +0 -209
  174. package/assets/.agents/skills/aw-spec-plan/SKILL.md +0 -221
  175. package/assets/.agents/skills/aw-spec-select-domain/SKILL.md +0 -73
  176. package/assets/.agents/skills/aw-spec-specify/SKILL.md +0 -382
  177. package/assets/.agents/skills/aw-spec-tasks/SKILL.md +0 -259
  178. package/assets/.agents/skills/aw-spec-taskstoissues/SKILL.md +0 -107
  179. package/assets/.aw-spec/integrations/claude.manifest.json +0 -17
  180. package/assets/.aw-spec/scripts/bash/check-prerequisites.sh +0 -189
  181. package/assets/.aw-spec/scripts/bash/create-new-feature.sh +0 -299
  182. package/assets/.aw-spec/scripts/bash/setup-plan.sh +0 -84
  183. package/assets/.aw-spec/scripts/bash/setup-tasks.sh +0 -91
  184. package/assets/.aw-spec/templates/checklist-template.md +0 -40
  185. package/assets/.aw-spec/templates/constitution-template.md +0 -57
  186. package/assets/.aw-spec/templates/plan-template.md +0 -113
  187. package/assets/.aw-spec/templates/tasks-template.md +0 -252
  188. package/assets/.aw-spec/workflows/aw-spec/workflow.yml +0 -77
  189. package/assets/.aw-spec/workflows/workflow-registry.json +0 -13
  190. package/assets/.claude/skills/aw-spec-addcomponent/SKILL.md +0 -129
  191. package/assets/.claude/skills/aw-spec-agent-context-update/SKILL.md +0 -31
  192. package/assets/.claude/skills/aw-spec-analyze/SKILL.md +0 -296
  193. package/assets/.claude/skills/aw-spec-checklist/SKILL.md +0 -374
  194. package/assets/.claude/skills/aw-spec-clarify/SKILL.md +0 -320
  195. package/assets/.claude/skills/aw-spec-constitution/SKILL.md +0 -194
  196. package/assets/.claude/skills/aw-spec-fast-implement/SKILL.md +0 -268
  197. package/assets/.claude/skills/aw-spec-foundation/SKILL.md +0 -358
  198. package/assets/.claude/skills/aw-spec-implement/SKILL.md +0 -279
  199. package/assets/.claude/skills/aw-spec-minimal-implementation/SKILL.md +0 -209
  200. package/assets/.claude/skills/aw-spec-plan/SKILL.md +0 -221
  201. package/assets/.claude/skills/aw-spec-select-domain/SKILL.md +0 -73
  202. package/assets/.claude/skills/aw-spec-specify/SKILL.md +0 -382
  203. package/assets/.claude/skills/aw-spec-tasks/SKILL.md +0 -259
  204. package/assets/.claude/skills/aw-spec-taskstoissues/SKILL.md +0 -107
  205. package/assets/.kilocode/rules/specify-rules.md +0 -4
  206. package/assets/.kilocode/workflows/aw-spec-addcomponent.md +0 -129
  207. package/assets/.kilocode/workflows/aw-spec-agent-context.update.md +0 -31
  208. package/assets/.kilocode/workflows/aw-spec-analyze.md +0 -296
  209. package/assets/.kilocode/workflows/aw-spec-checklist.md +0 -374
  210. package/assets/.kilocode/workflows/aw-spec-clarify.md +0 -320
  211. package/assets/.kilocode/workflows/aw-spec-constitution.md +0 -194
  212. package/assets/.kilocode/workflows/aw-spec-fast-implement.md +0 -263
  213. package/assets/.kilocode/workflows/aw-spec-foundation.md +0 -358
  214. package/assets/.kilocode/workflows/aw-spec-implement.md +0 -279
  215. package/assets/.kilocode/workflows/aw-spec-minimal-implementation.md +0 -204
  216. package/assets/.kilocode/workflows/aw-spec-plan.md +0 -221
  217. package/assets/.kilocode/workflows/aw-spec-select-domain.md +0 -73
  218. package/assets/.kilocode/workflows/aw-spec-specify.md +0 -382
  219. package/assets/.kilocode/workflows/aw-spec-tasks.md +0 -259
  220. package/assets/.kilocode/workflows/aw-spec-taskstoissues.md +0 -107
  221. package/assets/docs/UI.Visualization/PACKAGING.md +0 -191
  222. package/assets/docs/UI.Visualization/UI.Visualization.Reference.pack.txt +0 -11768
  223. package/assets/docs/UI.Visualization/UI.Visualization.pack.txt +0 -11214
  224. package/assets/docs/UI.Visualization/pack-foundation.ps1 +0 -165
  225. package/assets/docs/UI.Visualization/pack-foundation.sh +0 -206
  226. package/assets/docs/UI.Visualization/pack-reference-foundation.ps1 +0 -159
  227. package/assets/docs/UI.Visualization/pack-reference-foundation.sh +0 -205
  228. package/assets/docs/UI.Visualization/unpack-foundation.ps1 +0 -126
  229. package/assets/docs/UI.Visualization/unpack-foundation.sh +0 -217
  230. package/assets/docs/UI.Visualization/unpack-reference-foundation.ps1 +0 -129
  231. package/assets/docs/UI.Visualization/unpack-reference-foundation.sh +0 -218
  232. package/assets/docs/command.txt +0 -295
  233. package/assets/docs/domainspecs/UIVisualization/chart-bubble.md +0 -70
  234. package/assets/docs/domainspecs/UIVisualization/chart-dimred.md +0 -58
  235. package/assets/docs/domainspecs/UIVisualization/chart-heatmap.md +0 -62
  236. package/assets/docs/domainspecs/UIVisualization/chart-network.md +0 -69
  237. package/assets/docs/domainspecs/UIVisualization/chart-parallel.md +0 -75
  238. package/assets/docs/domainspecs/UIVisualization/chart-scurve.md +0 -66
  239. package/assets/docs/domainspecs/UIVisualization/chart-survival.md +0 -69
  240. package/assets/docs/domainspecs/UIVisualization/chart-trellis.md +0 -68
  241. package/assets/docs/domainspecs/UIVisualization/chart-violin.md +0 -61
  242. package/assets/docs/domainspecs/UIVisualization/chart-volcano.md +0 -63
  243. package/assets/docs/domainspecs/UIVisualization/charting-standards.domain.md +0 -80
  244. package/assets/docs/domainspecs/UIVisualization/clean-architecture.domain.md +0 -87
  245. package/assets/docs/domainspecs/UIVisualization/coding-standards.domain.md +0 -47
  246. package/assets/docs/domainspecs/UIVisualization/comandrulemap.md +0 -130
  247. package/assets/docs/domainspecs/UIVisualization/component-contracts.domain.md +0 -67
  248. package/assets/docs/domainspecs/UIVisualization/data-source.domain.md +0 -68
  249. package/assets/docs/domainspecs/UIVisualization/domain-requirements.md +0 -110
  250. package/assets/docs/domainspecs/UIVisualization/folder-structure.domain.md +0 -55
  251. package/assets/docs/domainspecs/UIVisualization/state-management.domain.md +0 -67
  252. package/assets/docs/domainspecs/UIVisualization/testing.domain.md +0 -52
  253. package/assets/docs/domainspecs/UIVisualization/ui-viz-terms.md +0 -39
  254. package/assets/docs/pharma-constitution.my-ref.md +0 -86
@@ -1,62 +0,0 @@
1
- # Heatmap — Chart Rule
2
-
3
- > Load **only when "Heatmap" (or "all plots") is in the selection** (see [[domain-requirements]]).
4
- > Component: `Heatmap` in `components/charts/generic/Heatmap.tsx`. Built on [[charting-standards.domain]].
5
-
6
- ## Purpose
7
- Colour-encoded grid for a 2-D value matrix. Use for correlation matrices, expression grids
8
- (log₂FC), confusion matrices, risk tables, cross-asset return grids.
9
-
10
- ## Props contract
11
- ```ts
12
- type ColourPreset = 'diverging-purple-red' | 'sequential-teal' | 'sequential-heat' | 'diverging-blue-red'
13
-
14
- interface HeatmapProps {
15
- matrix: number[][] // matrix[row][col] — REQUIRED
16
- rowLabels: string[] // y-axis — REQUIRED
17
- colLabels: string[] // x-axis — REQUIRED
18
- title?: string
19
- unit?: string // colour-bar title + tooltip unit (e.g. "log₂FC", "r")
20
- colorscale?: ColourPreset | [number, string][] // default 'diverging-purple-red'
21
- zMid?: number // centre of a diverging scale (use 0 for FC / correlation)
22
- zMin?: number; zMax?: number // override colour range (defaults to matrix min/max)
23
- showCellValues?: boolean // annotate each cell (default true)
24
- cellValuePrecision?: number // decimals in annotations (default 2)
25
- cellValueContrastThreshold?: number // |value| above → white text (default 1.0)
26
- height?: number // omit for responsive fill
27
- reverseRows?: boolean
28
- }
29
- ```
30
-
31
- ## Rules
32
- - `matrix.length === rowLabels.length`; every row length `=== colLabels.length`. Validate in the
33
- adapter, not the chart.
34
- - For **diverging** data (fold-change, correlation) set `zMid={0}` so zero maps to the neutral
35
- midpoint; for **sequential** data (counts, intensity) use a `sequential-*` preset and omit `zMid`.
36
- - Keep cell annotations on for ≤ ~12×12 grids; turn `showCellValues` off for dense matrices.
37
-
38
- ## Adapter example (agent reference)
39
- ```tsx
40
- 'use client'
41
- import { Heatmap } from '@/components/charts/generic'
42
- import type { BiomarkerData } from '@/lib/types/pharma'
43
-
44
- export default function BiomarkerHeatmap({ data, height }: { data: BiomarkerData; height?: number }) {
45
- return (
46
- <Heatmap
47
- matrix={data.matrix} rowLabels={data.treatments} colLabels={data.markers}
48
- unit="log₂FC" colorscale="diverging-purple-red" zMid={0}
49
- showCellValues cellValuePrecision={2} cellValueContrastThreshold={1.5}
50
- height={height}
51
- />
52
- )
53
- }
54
- ```
55
-
56
- ## Scaffolds when selected
57
- - `components/charts/generic/Heatmap.tsx` (from the generic library — always present)
58
- - `app/heatmap/page.tsx` (example route) + nav tab
59
- - optional adapter `components/charts/<Domain>Heatmap.tsx`
60
-
61
- ## Related
62
- - [[charting-standards.domain]] · [[component-contracts.domain]] · [[clean-architecture.domain]]
@@ -1,69 +0,0 @@
1
- # NetworkGraph — Chart Rule
2
-
3
- > Load **only when "Network / graph / node-edge" (or "all plots") is selected** (see [[domain-requirements]]).
4
- > Component: `NetworkGraph` in `components/charts/generic/NetworkGraph.tsx`. Built on [[charting-standards.domain]].
5
-
6
- ## Purpose
7
- Force-directed **node-edge** graph rendered with Plotly scatter+line traces; layout is computed
8
- in-component (Fruchterman-Reingold spring or circular) so **no extra graph library** is needed.
9
- Use for PPI/pathway networks, microservice/dependency maps, knowledge graphs, org/social graphs.
10
-
11
- ## Props contract
12
- ```ts
13
- interface NetworkNode {
14
- id: string // referenced by edges
15
- label: string
16
- group?: string // colour + legend
17
- size?: number // marker size (importance, default 10)
18
- meta?: Record<string, string|number>
19
- }
20
- interface NetworkEdge {
21
- source: string; target: string // node ids
22
- weight?: number // line thickness (default 1)
23
- label?: string // hover label
24
- }
25
- interface NetworkGraphProps {
26
- nodes: NetworkNode[]; edges: NetworkEdge[] // REQUIRED
27
- layout?: 'spring' | 'circular' // default 'spring'
28
- springIterations?: number // default 120 (higher = better layout, slower)
29
- showEdgeLabels?: boolean // default true
30
- directed?: boolean // arrowheads (default false)
31
- title?: string; height?: number
32
- }
33
- ```
34
-
35
- ## Rules
36
- - Every edge `source`/`target` MUST reference an existing node `id`. Validate in the adapter;
37
- dangling edges are dropped silently.
38
- - Layout is **deterministic per dataset** (warm-started from a circle) but recomputes when the
39
- node/edge set changes — memoise `nodes`/`edges` so it doesn't recompute each render.
40
- - Keep graphs modest (≲ ~150 nodes) for readable spring layout; above that, pre-cluster or paginate.
41
- - Set `directed` for DAGs / signalling cascades; leave off for undirected association graphs.
42
-
43
- ## Page/adapter example (agent reference)
44
- ```tsx
45
- 'use client'
46
- import { NetworkGraph } from '@/components/charts/generic'
47
- import type { NetworkNode, NetworkEdge } from '@/components/charts/generic'
48
-
49
- const NODES: NetworkNode[] = [
50
- { id: 'EGFR', label: 'EGFR', group: 'Receptor', size: 26 },
51
- { id: 'RAS', label: 'RAS', group: 'GTPase', size: 22 },
52
- { id: 'RAF', label: 'BRAF', group: 'Kinase', size: 20 },
53
- ]
54
- const EDGES: NetworkEdge[] = [
55
- { source: 'EGFR', target: 'RAS', weight: 2.5, label: 'activates' },
56
- { source: 'RAS', target: 'RAF', weight: 2, label: 'activates' },
57
- ]
58
-
59
- export default function PathwayNetwork() {
60
- return <NetworkGraph nodes={NODES} edges={EDGES} layout="spring" springIterations={150} directed showEdgeLabels />
61
- }
62
- ```
63
-
64
- ## Scaffolds when selected
65
- - generic `NetworkGraph` + `app/network/page.tsx` + nav tab + optional adapter; type the node/edge
66
- arrays with `NetworkNode[]` / `NetworkEdge[]` to avoid `meta` literal-type errors.
67
-
68
- ## Related
69
- - [[charting-standards.domain]] · [[component-contracts.domain]] · [[clean-architecture.domain]]
@@ -1,75 +0,0 @@
1
- # ParallelCoordinatesPlot — Chart Rule
2
-
3
- > Load **only when "Parallel Coords / parcoords" (or "all plots") is selected** (see [[domain-requirements]]).
4
- > Component: `ParallelCoordinatesPlot` in `components/charts/generic/ParallelCoordinatesPlot.tsx`.
5
- > Built on [[charting-standards.domain]]; uses Plotly's native `parcoords` (interactive axis brushing).
6
-
7
- ## Purpose
8
- Multi-dimensional data as **polylines crossing parallel vertical axes** — one line per observation.
9
- Use for multi-parameter optimisation (MPO), ADMET profiles, hyperparameter sweeps, KPI dashboards,
10
- portfolio metrics.
11
-
12
- ## Props contract
13
- ```ts
14
- interface PCDimension {
15
- key: string // matches a key in each trace's `values`
16
- label: string
17
- range?: [number, number] // axis range (auto if omitted)
18
- tickFormat?: string // d3 format, e.g. ".2f", ".0f"
19
- invertAxis?: boolean // for "lower is better" metrics (IC₅₀, p-value)
20
- }
21
- interface PCTrace {
22
- id: string; label: string
23
- colorValue: number // drives the line colour (continuous)
24
- values: Record<string, number> // one value per dimension key
25
- group?: string
26
- }
27
- type PCColorscale = 'teal-purple' | 'blue-red' | 'viridis' | 'plasma' | [number, string][]
28
-
29
- interface ParallelCoordinatesPlotProps {
30
- dimensions: PCDimension[] // REQUIRED — the axes
31
- traces: PCTrace[] // REQUIRED — one per observation
32
- colorLabel?: string // colour-bar title
33
- colorscale?: PCColorscale // default 'teal-purple'
34
- lineOpacity?: number; lineWidth?: number
35
- title?: string; height?: number
36
- }
37
- ```
38
-
39
- ## Rules
40
- - `dimensions[].key` must exist in **every** trace's `values`. Validate in the adapter.
41
- - Use `invertAxis` for metrics where **lower is better** so "good" lines trend the same way.
42
- - `colorValue` is a single continuous dimension (often the headline metric, e.g. IC₅₀ or score);
43
- it maps onto `colorscale`. Brushing on any axis filters interactively — no extra wiring.
44
-
45
- ## Page/adapter example (agent reference)
46
- ```tsx
47
- 'use client'
48
- import { ParallelCoordinatesPlot } from '@/components/charts/generic'
49
- import type { Compound } from '@/lib/types/pharma'
50
-
51
- const DIMS = [
52
- { key: 'mw', label: 'MW (Da)', range: [300, 560] as [number, number], tickFormat: '.0f' },
53
- { key: 'logP', label: 'LogP', range: [1.5, 5.5] as [number, number], tickFormat: '.1f' },
54
- { key: 'ic50', label: 'IC₅₀ (nM)', range: [0, 800] as [number, number], tickFormat: '.0f', invertAxis: true },
55
- ]
56
-
57
- export default function MpoParallel({ compounds }: { compounds: Compound[] }) {
58
- return (
59
- <ParallelCoordinatesPlot
60
- dimensions={DIMS}
61
- traces={compounds.filter(c => c.ic50_nM <= 800).map(c => ({
62
- id: c.id, label: c.name, group: c.status, colorValue: c.ic50_nM,
63
- values: { mw: c.molecularWeight, logP: c.logP, ic50: c.ic50_nM },
64
- }))}
65
- colorLabel="IC₅₀ (nM)" colorscale="teal-purple"
66
- />
67
- )
68
- }
69
- ```
70
-
71
- ## Scaffolds when selected
72
- - generic `ParallelCoordinatesPlot` + `app/parallel/page.tsx` + nav tab + optional adapter.
73
-
74
- ## Related
75
- - [[charting-standards.domain]] · [[component-contracts.domain]] · [[clean-architecture.domain]]
@@ -1,66 +0,0 @@
1
- # SCurveChart — Chart Rule
2
-
3
- > Load **only when "S-Curve / dose-response / sigmoid" (or "all plots") is selected** (see [[domain-requirements]]).
4
- > Component: `SCurveChart` in `components/charts/generic/SCurveChart.tsx`. Built on [[charting-standards.domain]].
5
-
6
- ## Purpose
7
- One or more **sigmoidal (S-shaped)** curves with optional inflection markers. Use for
8
- dose-response (4-PL / Hill), technology adoption, market penetration, enzyme kinetics, SaaS ramp.
9
-
10
- ## Props contract
11
- ```ts
12
- interface SCurvePoint { x: number; y: number }
13
- interface SCurve {
14
- id: string; label: string; color?: string
15
- points: SCurvePoint[] // PRE-COMPUTED by the caller (model runs outside the chart)
16
- inflectionX?: number // e.g. IC₅₀ / midpoint — draws a marker + dashed line
17
- inflectionLabel?: string // "IC₅₀", "EC₅₀", "Midpoint", "Tipping point"
18
- metadata?: Record<string, string> // tooltip enrichment
19
- }
20
- interface SCurveChartProps {
21
- curves: SCurve[] // REQUIRED
22
- xLabel: string; yLabel: string // REQUIRED
23
- xAxisType?: 'linear' | 'log'
24
- referenceY?: number // horizontal reference (default 50)
25
- referenceYLabel?: string
26
- yRange?: [number, number] // default [-5, 108]
27
- title?: string; height?: number
28
- }
29
- ```
30
-
31
- ## Rules
32
- - The chart **plots points, it does not fit models** — the caller generates curve points (4-PL,
33
- logistic, etc.) and passes them. Provide generators in `lib/utils.ts`
34
- (`generate4PLCurve`, `generateLogisticPoints`).
35
- - `inflectionX` is in the **same x-units** as the points (e.g. `log10(ic50_nM)` if x is log-conc).
36
- - Use `referenceY={50}` for "50% response/adoption"; set to `undefined` to hide.
37
-
38
- ## Adapter example (agent reference)
39
- ```tsx
40
- 'use client'
41
- import { SCurveChart } from '@/components/charts/generic'
42
- import { PHARMA_COLORS } from '@/components/charts/PlotlyChart'
43
- import type { DoseResponseCurve } from '@/lib/types/pharma'
44
-
45
- export default function DoseResponseChart({ curves, height }: { curves: DoseResponseCurve[]; height?: number }) {
46
- return (
47
- <SCurveChart
48
- curves={curves.map((c, i) => ({
49
- id: c.compoundId, label: c.compoundName, color: PHARMA_COLORS[i % PHARMA_COLORS.length],
50
- points: c.points.map(p => ({ x: p.logConc, y: p.response })),
51
- inflectionX: Math.log10(c.ic50_nM), inflectionLabel: 'IC₅₀',
52
- metadata: { Target: c.target, 'Hill slope': c.hillSlope.toFixed(2) },
53
- }))}
54
- xLabel="log₁₀[Concentration (nM)]" yLabel="% Inhibition"
55
- referenceY={50} referenceYLabel="50% Inhibition" height={height}
56
- />
57
- )
58
- }
59
- ```
60
-
61
- ## Scaffolds when selected
62
- - generic `SCurveChart` + curve generators in `lib/utils.ts` + `app/scurve/` (or `dose-response/`)
63
- route + nav tab + optional adapter.
64
-
65
- ## Related
66
- - [[charting-standards.domain]] · [[component-contracts.domain]] · [[clean-architecture.domain]]
@@ -1,69 +0,0 @@
1
- # SurvivalCurveChart — Chart Rule
2
-
3
- > Load **only when "Survival / Kaplan-Meier / retention" (or "all plots") is selected** (see [[domain-requirements]]).
4
- > Component: `SurvivalCurveChart` in `components/charts/generic/SurvivalCurveChart.tsx`. Built on [[charting-standards.domain]].
5
-
6
- ## Purpose
7
- Kaplan-Meier–style **step-function** curves with optional CI shading, median markers, and a
8
- significance annotation. Use for clinical OS/PFS, user-cohort retention, component MTTF, churn.
9
-
10
- ## Props contract
11
- ```ts
12
- interface SurvivalPoint {
13
- time: number
14
- survival: number // 0–1 (×100 applied) or 0–100
15
- ciLower?: number; ciUpper?: number // same scale as survival
16
- nAtRisk?: number
17
- }
18
- interface SurvivalArm {
19
- label: string; color: string // colour REQUIRED — distinguishes arms
20
- points: SurvivalPoint[]
21
- medianTime?: number | null // null = not reached
22
- }
23
- interface SurvivalCurveChartProps {
24
- arms: SurvivalArm[] // REQUIRED
25
- timeLabel?: string // default "Time"
26
- survivalLabel?: string // default "Survival Probability (%)"
27
- eventLabel?: string // "Death", "Churn", "Failure" …
28
- medianLabel?: string // "mOS", "mPFS", "Median retention"
29
- curveType?: string // corner badge: "OS", "KM", "Retention"
30
- pValue?: string // "< 0.001", "n.s."
31
- showCI?: boolean // default true (needs ciLower/ciUpper)
32
- xMax?: number; height?: number
33
- }
34
- ```
35
-
36
- ## Rules
37
- - Curve is a **step function** (`shape: 'hv'`) — survival is constant between events. Pass points
38
- at event/censor times; the chart draws the steps.
39
- - `survival` accepts either 0–1 or 0–100 — the chart normalises; be consistent within an arm.
40
- - CI shading requires `ciLower`/`ciUpper` on the points and `showCI` (default on).
41
- - `medianTime: null` renders "Not reached" — use it, don't fake a value.
42
-
43
- ## Adapter example (agent reference)
44
- ```tsx
45
- 'use client'
46
- import { SurvivalCurveChart } from '@/components/charts/generic'
47
- import type { TrialArm } from '@/lib/types/pharma'
48
-
49
- export default function KaplanMeierChart({ arms, height }: { arms: TrialArm[]; height?: number }) {
50
- return (
51
- <SurvivalCurveChart
52
- arms={arms.map(a => ({
53
- label: a.name, color: a.color, medianTime: a.medianSurvival,
54
- points: a.points.map(p => ({ time: p.time, survival: p.survival,
55
- ciLower: p.ciLower, ciUpper: p.ciUpper, nAtRisk: p.nAtRisk })),
56
- }))}
57
- timeLabel="Days" survivalLabel="Survival Probability (%)" medianLabel="mOS"
58
- curveType="OS" pValue="< 0.001" showCI height={height}
59
- />
60
- )
61
- }
62
- ```
63
-
64
- ## Scaffolds when selected
65
- - generic `SurvivalCurveChart` + `app/survival/` (or `trials/`) route + nav tab + optional adapter;
66
- an optional number-at-risk table consumes `nAtRisk`.
67
-
68
- ## Related
69
- - [[charting-standards.domain]] · [[component-contracts.domain]] · [[clean-architecture.domain]]
@@ -1,68 +0,0 @@
1
- # TrellisGrid — Chart Rule
2
-
3
- > Load **only when "Trellis / facet / small-multiples" (or "all plots") is selected** (see [[domain-requirements]]).
4
- > Component: `TrellisGrid` in `components/charts/generic/TrellisGrid.tsx`. Built on [[charting-standards.domain]];
5
- > uses Plotly subplot `grid`.
6
-
7
- ## Purpose
8
- An **N×M grid of the same chart type** — one panel per data subset (small multiples / facets).
9
- Use for KPI by region, IC₅₀ by target class, sensor readings by machine, feature distributions
10
- per class.
11
-
12
- ## Props contract
13
- ```ts
14
- interface TrellisTrace {
15
- type: 'bar' | 'scatter' | 'line' | 'box'
16
- x: (string|number)[]; y: number[]
17
- label: string; color?: string
18
- mode?: 'markers' | 'lines' | 'lines+markers' // scatter/line only
19
- }
20
- interface TrellisPanel { title: string; traces: TrellisTrace[] }
21
-
22
- interface TrellisGridProps {
23
- panels: TrellisPanel[] // REQUIRED — one per subset
24
- cols?: number // grid columns (default 3); rows auto
25
- xLabel?: string; yLabel?: string // shared axis labels
26
- sharedXAxis?: boolean // align x-range across panels
27
- sharedYAxis?: boolean // align y-range — ESSENTIAL for fair comparison
28
- panelHeight?: number // px per panel (total = rows × panelHeight)
29
- title?: string
30
- }
31
- ```
32
-
33
- ## Rules
34
- - All panels render the **same trace type** — that is the point of small multiples. Don't mix bar
35
- and line across panels.
36
- - Turn on **`sharedYAxis`** whenever comparing magnitudes across panels — otherwise each panel
37
- auto-scales and the comparison misleads.
38
- - `panels` is built by grouping the dataset on the facet dimension (target, region, class) in the
39
- adapter/page.
40
- - `TrellisGrid` sizes by `rows × panelHeight` (it does not fill-parent); pick `panelHeight` for the
41
- card and let the page scroll if needed.
42
-
43
- ## Page/adapter example (agent reference)
44
- ```tsx
45
- 'use client'
46
- import { TrellisGrid } from '@/components/charts/generic'
47
- import { PHARMA_COLORS } from '@/components/charts/PlotlyChart'
48
- import type { Compound } from '@/lib/types/pharma'
49
-
50
- export default function Ic50ByTarget({ compounds }: { compounds: Compound[] }) {
51
- const targets = [...new Set(compounds.map(c => c.target))]
52
- const panels = targets.map((t, i) => {
53
- const g = compounds.filter(c => c.target === t).sort((a, b) => a.ic50_nM - b.ic50_nM)
54
- return {
55
- title: t,
56
- traces: [{ type: 'bar' as const, label: t, color: PHARMA_COLORS[i % PHARMA_COLORS.length],
57
- x: g.map(c => c.name), y: g.map(c => Math.min(c.ic50_nM, 800)) }],
58
- }
59
- })
60
- return <TrellisGrid panels={panels} cols={4} xLabel="Compound" yLabel="IC₅₀ (nM)" sharedYAxis panelHeight={210} />
61
- }
62
- ```
63
-
64
- ## Scaffolds when selected
65
- - generic `TrellisGrid` + `app/trellis/page.tsx` + nav tab + optional adapter.
66
-
67
- ## Related
68
- - [[charting-standards.domain]] · [[component-contracts.domain]] · [[clean-architecture.domain]]
@@ -1,61 +0,0 @@
1
- # ViolinPlot — Chart Rule
2
-
3
- > Load **only when "Violin / distribution" (or "all plots") is selected** (see [[domain-requirements]]).
4
- > Component: `ViolinPlot` in `components/charts/generic/ViolinPlot.tsx`.
5
- > Built on [[charting-standards.domain]]; uses Plotly's native `violin` (KDE + box computed for you).
6
-
7
- ## Purpose
8
- Distribution **shape (KDE)** of a numeric variable across groups, with optional box plot and
9
- jittered points. Use for biomarker expression by cohort, API latency by endpoint, salary by band,
10
- any group-wise distribution comparison.
11
-
12
- ## Props contract
13
- ```ts
14
- interface ViolinGroup {
15
- label: string // x-axis category
16
- values: number[] // RAW observations — Plotly computes KDE/IQR/whiskers
17
- color?: string
18
- }
19
- type PointDisplayMode = 'none' | 'outliers' | 'all' | 'suspected'
20
-
21
- interface ViolinPlotProps {
22
- groups: ViolinGroup[] // REQUIRED
23
- yLabel?: string; xLabel?: string
24
- showBox?: boolean // overlay median/IQR box (default true)
25
- showMean?: boolean // mean line (default false)
26
- showPoints?: PointDisplayMode // default 'outliers'
27
- side?: 'both' | 'positive' | 'negative' // split violin for back-to-back compare
28
- bandwidth?: 'normal reference' | 'scott' | 'silverman'
29
- fillOpacity?: number
30
- title?: string; height?: number
31
- }
32
- ```
33
-
34
- ## Rules
35
- - Pass **raw values** — never pre-binned or pre-summarised; the chart computes KDE, quartiles and
36
- whiskers. Each group needs enough points (≥ ~10) for a meaningful KDE.
37
- - Use `showPoints="outliers"` for clinical/quality data; `"all"` only for small n.
38
- - `side="positive"`/`"negative"` enables split (back-to-back) violins for two-condition compares.
39
-
40
- ## Page/adapter example (agent reference)
41
- ```tsx
42
- 'use client'
43
- import { ViolinPlot } from '@/components/charts/generic'
44
-
45
- // readings: { group: string; value: number }[]
46
- export default function ExpressionViolin({ readings }: { readings: { group: string; value: number }[] }) {
47
- const groups = [...new Set(readings.map(r => r.group))].map(g => ({
48
- label: g, values: readings.filter(r => r.group === g).map(r => r.value),
49
- }))
50
- return (
51
- <ViolinPlot groups={groups} yLabel="Expression (log₂FC)" xLabel="Treatment"
52
- showBox showMean showPoints="outliers" />
53
- )
54
- }
55
- ```
56
-
57
- ## Scaffolds when selected
58
- - generic `ViolinPlot` + `app/violin/page.tsx` + nav tab + optional adapter.
59
-
60
- ## Related
61
- - [[charting-standards.domain]] · [[component-contracts.domain]] · [[clean-architecture.domain]]
@@ -1,63 +0,0 @@
1
- # VolcanoPlot — Chart Rule
2
-
3
- > Load **only when "Volcano" (or "all plots") is selected** (see [[domain-requirements]]).
4
- > Component: `VolcanoPlot` in `components/charts/generic/VolcanoPlot.tsx`. Built on [[charting-standards.domain]].
5
-
6
- ## Purpose
7
- **Magnitude vs. significance** scatter, partitioned into up / down / not-significant by two
8
- thresholds. Use for differential expression (RNA-seq/proteomics), A/B-test lift vs significance,
9
- GWAS hits, ML feature importance, adverse-event signals.
10
-
11
- ## Props contract
12
- ```ts
13
- interface VolcanoPoint {
14
- x: number // magnitude (e.g. log₂FC, effect size)
15
- y: number // significance (e.g. -log₁₀ p-value)
16
- label: string
17
- meta?: Record<string, string|number>
18
- }
19
- interface VolcanoPlotProps {
20
- points: VolcanoPoint[] // REQUIRED
21
- xLabel?: string // default "log₂(Fold Change)"
22
- yLabel?: string // default "-log₁₀(p-value)"
23
- foldChangeThreshold?: number // |x| above → "changed" (default 1.0)
24
- significanceThreshold?: number // y above → significant (default 1.301 ≈ p<0.05)
25
- upColor?: string; downColor?: string; nsColor?: string
26
- upLabel?: string; downLabel?: string; nsLabel?: string
27
- labelTopN?: number // annotate top-N by |x·y| (default 10; 0 disables)
28
- title?: string; height?: number
29
- }
30
- ```
31
-
32
- ## Rules
33
- - The caller supplies **already-computed** statistics: `x` = effect/log₂FC, `y` = `-log10(p)`.
34
- The chart does not run the test.
35
- - `significanceThreshold` is in **`-log10(p)`** units (1.301 = p 0.05; 2 = p 0.01). State the test
36
- basis in `yLabel`.
37
- - The chart partitions points by the two thresholds and labels the top-N hits — keep `labelTopN`
38
- small (≤ 15) to avoid clutter.
39
-
40
- ## Page/adapter example (agent reference)
41
- ```tsx
42
- 'use client'
43
- import { VolcanoPlot } from '@/components/charts/generic'
44
-
45
- // genes: { name, log2FC, pValue }[]
46
- export default function DiffExpressionVolcano({ genes }: { genes: { name: string; log2FC: number; pValue: number }[] }) {
47
- return (
48
- <VolcanoPlot
49
- points={genes.map(g => ({ x: g.log2FC, y: -Math.log10(g.pValue), label: g.name,
50
- meta: { 'p-value': g.pValue.toExponential(2) } }))}
51
- xLabel="log₂(Fold Change)" yLabel="-log₁₀(p-value)"
52
- foldChangeThreshold={1} significanceThreshold={1.301}
53
- upLabel="Up-regulated" downLabel="Down-regulated" labelTopN={10}
54
- />
55
- )
56
- }
57
- ```
58
-
59
- ## Scaffolds when selected
60
- - generic `VolcanoPlot` + `app/volcano/page.tsx` + nav tab + optional adapter.
61
-
62
- ## Related
63
- - [[charting-standards.domain]] · [[component-contracts.domain]] · [[clean-architecture.domain]]
@@ -1,80 +0,0 @@
1
- # Charting Standards — UI Visualization Domain
2
-
3
- > The base Plotly wrapper, theme, and rendering rules every chart depends on. NON-NEGOTIABLE.
4
- > Commands: `/aw-spec-plan`, `/aw-spec-tasks`, `/aw-spec-implement`.
5
-
6
- ## Single base wrapper
7
-
8
- - **All** charts render through one component: `components/charts/PlotlyChart.tsx`. No chart imports
9
- `plotly.js` directly.
10
- - Plotly is loaded via **dynamic import inside `useEffect`** (SSR-safe — Plotly touches `window`).
11
- Never import it at module top level; never render it in a Server Component.
12
- - The wrapper exposes a shared `BASE_LAYOUT`, `BASE_CONFIG`, and `PHARMA_COLORS` palette that every
13
- generic chart spreads over its own layout.
14
- - **Responsive fill:** when a chart is given no explicit `height`, it passes `fillHeight` and the
15
- wrapper sizes to the parent (`height: 100%`); when given a number, that wins. Charts therefore
16
- fill a flex card without manual measuring.
17
-
18
- ## Canonical base wrapper (agent reference)
19
-
20
- ```tsx
21
- // components/charts/PlotlyChart.tsx
22
- 'use client'
23
- import { useEffect, useRef } from 'react'
24
-
25
- export const PHARMA_COLORS = ['#00d4b4','#3b82f6','#8b5cf6','#f59e0b','#ef4444','#10b981','#f97316','#ec4899']
26
- export const BASE_LAYOUT = {
27
- paper_bgcolor: '#0a1628', plot_bgcolor: '#0a1628',
28
- font: { color: '#8ba3c7', family: 'Inter, system-ui, sans-serif', size: 11 },
29
- margin: { t: 30, r: 20, b: 50, l: 60 },
30
- xaxis: { gridcolor: 'rgba(59,130,246,0.10)', zerolinecolor: 'rgba(59,130,246,0.10)' },
31
- yaxis: { gridcolor: 'rgba(59,130,246,0.10)', zerolinecolor: 'rgba(59,130,246,0.10)' },
32
- hoverlabel: { bgcolor: '#0f1e38', bordercolor: 'rgba(0,212,180,0.3)', font: { color: '#e2ecff' } },
33
- }
34
- export const BASE_CONFIG = { displayModeBar: true, displaylogo: false, responsive: true }
35
-
36
- interface Props { data: unknown[]; layout?: Record<string, unknown>; config?: Record<string, unknown>; className?: string; fillHeight?: boolean }
37
-
38
- export default function PlotlyChart({ data, layout = {}, config = {}, className, fillHeight = false }: Props) {
39
- const ref = useRef<HTMLDivElement>(null)
40
- useEffect(() => {
41
- if (!ref.current) return
42
- const el = ref.current; let cancelled = false
43
- import('plotly.js-dist-min').then(Plotly => {
44
- if (cancelled || !el) return
45
- Plotly.react(el, data, { ...BASE_LAYOUT, ...layout }, { ...BASE_CONFIG, ...config })
46
- })
47
- return () => { cancelled = true; import('plotly.js-dist-min').then(P => { try { P.purge(el) } catch {} }) }
48
- // eslint-disable-next-line react-hooks/exhaustive-deps
49
- }, [JSON.stringify(data), JSON.stringify(layout)])
50
- return <div ref={ref} className={className} style={{ width: '100%', height: fillHeight ? '100%' : undefined }} />
51
- }
52
- ```
53
-
54
- ## Generic-chart contract (every chart in `generic/`)
55
-
56
- 1. `'use client'` at the top; renders only via `PlotlyChart`.
57
- 2. Accepts an **optional `height?: number`**; spreads `height` into layout only when defined,
58
- else passes `fillHeight={height === undefined}` and adds `h-full` to the className.
59
- 3. Builds `data` + `layout` from props, spreading `BASE_LAYOUT`.
60
- 4. **No domain vocabulary** — all labels/units/colours come from props
61
- (see [[component-contracts.domain]]).
62
- 5. Colours default from `PHARMA_COLORS` (rename palette per project; keep the export name stable).
63
-
64
- ## Theme tokens
65
-
66
- - Dark "glass" theme: `bg-mesh` background, `glass-card` + `gradient-border` chart cards,
67
- accent teal `#00d4b4` / purple `#7c3aed`. Tokens live in `globals.css` and `tailwind.config.ts`.
68
- - Chart text/grid colours come from `BASE_LAYOUT` so every chart matches the shell automatically.
69
-
70
- ## Rules
71
-
72
- - Purge the Plotly instance on unmount (the wrapper does this) to avoid leaks on route change.
73
- - Re-render keys off `JSON.stringify(data/layout)` — keep prop objects stable or memoised for
74
- large datasets.
75
- - Never set a fixed pixel height in a page card; let `fillHeight` size to the flex parent.
76
-
77
- ## Related
78
- - [[component-contracts.domain]] — the per-chart prop contract built on this base
79
- - [[clean-architecture.domain]] — the generic ring depends only on this wrapper
80
- - All `chart-*` rule files build on this base.