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.
- package/assets/.agents/agent.json +28 -0
- package/assets/.agents/skills/aw-spec-orch/SKILL.md +56 -0
- package/assets/.agents/skills/aw-spec-orch-demo/SKILL.md +59 -0
- package/assets/.aw-spec/DESIGN-FORMAT.md +151 -0
- package/assets/.aw-spec/ORCH-DIALECT.md +156 -0
- package/assets/.aw-spec/RULE-PARTITION.md +126 -0
- package/assets/.aw-spec/extensions/agent-context/extension.yml +12 -9
- package/assets/.aw-spec/extensions.yml +12 -19
- package/assets/.aw-spec/integrations/aw-spec.manifest.json +1 -9
- package/assets/.aw-spec/interpreter/run-skill.py +1158 -0
- package/assets/.aw-spec/orchestrator/AGENT-PROFILE.md +94 -0
- package/assets/.aw-spec/orchestrator/README.md +300 -0
- package/assets/.aw-spec/orchestrator/adapters/claude_agent_sdk.py +74 -0
- package/assets/.aw-spec/orchestrator/adapters/google_antigravity.py +74 -0
- package/assets/.aw-spec/orchestrator/modules/delta-design.orch.yaml +105 -0
- package/assets/.aw-spec/orchestrator/modules/delta-spec.orch.yaml +79 -0
- package/assets/.aw-spec/orchestrator/modules/domain-select.orch.yaml +81 -0
- package/assets/.aw-spec/orchestrator/modules/tech-select.orch.yaml +75 -0
- package/assets/.aw-spec/orchestrator/orchestrator.py +1721 -0
- package/assets/.aw-spec/orchestrator/rev-templates/ai-rules.reference.md +40 -0
- package/assets/.aw-spec/orchestrator/rev-templates/comandrulemap.skeleton.md +59 -0
- package/assets/.aw-spec/orchestrator/rev-templates/commandtechrulemap.skeleton.md +97 -0
- package/assets/.aw-spec/orchestrator/rev-templates/domain-constitution.skeleton.md +61 -0
- package/assets/.aw-spec/orchestrator/rev-templates/domain-requirements.skeleton.md +48 -0
- package/assets/.aw-spec/orchestrator/rev-templates/domain-rule-file.skeleton.md +39 -0
- package/assets/.aw-spec/orchestrator/rev-templates/technical-constitution.skeleton.md +106 -0
- package/assets/.aw-spec/orchestrator/rev-templates/technical-rule-file.skeleton.md +54 -0
- package/assets/.aw-spec/orchestrator/workflows/_smoke.orch.yaml +160 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-add-component.orch.yaml +244 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-adopt.orch.yaml +775 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-delta-design.orch.yaml +248 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-design.orch.yaml +261 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-analyze-slice.orch.yaml +425 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-build.orch.yaml +188 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-characterize.orch.yaml +474 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-close-delta.orch.yaml +181 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-constitution.orch.yaml +284 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-demo.orch.yaml +103 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-dependency-tree.orch.yaml +69 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-deploy.orch.yaml +85 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-design.orch.yaml +382 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-finalize-delta.orch.yaml +382 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-foundation.orch.yaml +246 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-implement-delta.orch.yaml +231 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-implement.orch.yaml +258 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-inventory.orch.yaml +236 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-onboard.orch.yaml +949 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-parity.orch.yaml +293 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-run.orch.yaml +177 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-select-domain.orch.yaml +79 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-select-feature.orch.yaml +128 -0
- package/assets/.aw-spec/orchestrator/workflows/aw-spec-specify.orch.yaml +412 -0
- package/assets/.aw-spec/scripts/bash/aw-inventory.sh +14 -0
- package/assets/.aw-spec/scripts/bash/aw-parity.sh +13 -0
- package/assets/.aw-spec/scripts/bash/aw-rev-constitution.sh +13 -0
- package/assets/.aw-spec/scripts/bash/aw-spec-actions.sh +1899 -0
- package/assets/.aw-spec/scripts/bash/aw-xref.sh +15 -0
- package/assets/.aw-spec/scripts/bash/common.sh +11 -60
- package/assets/.aw-spec/scripts/powershell/aw-inventory.ps1 +14 -0
- package/assets/.aw-spec/scripts/powershell/aw-parity.ps1 +13 -0
- package/assets/.aw-spec/scripts/powershell/aw-rev-constitution.ps1 +13 -0
- package/assets/.aw-spec/scripts/powershell/aw-spec-actions.ps1 +1563 -0
- package/assets/.aw-spec/scripts/powershell/aw-xref.ps1 +15 -0
- package/assets/.aw-spec/scripts/python/aw-inventory.py +683 -0
- package/assets/.aw-spec/scripts/python/aw-parity.py +380 -0
- package/assets/.aw-spec/scripts/python/aw-rev-constitution.py +312 -0
- package/assets/.aw-spec/scripts/python/aw-xref.py +1330 -0
- package/assets/.aw-spec/scripts/python/validate_okf.py +349 -0
- package/assets/.aw-spec/templates/constitution-domain-template.md +75 -0
- package/assets/.aw-spec/templates/constitution-technical-template.md +70 -0
- package/assets/.aw-spec/templates/delta-design-template.md +69 -0
- package/assets/.aw-spec/templates/delta-spec-template.md +60 -0
- package/assets/.aw-spec/templates/design-template.md +383 -0
- package/assets/.aw-spec/templates/okf-concept-template.md +103 -0
- package/assets/.aw-spec/templates/parity-manifest-template.json +49 -0
- package/assets/.aw-spec/templates/source-map-template.md +85 -0
- package/assets/.aw-spec/templates/spec-template.md +192 -71
- package/assets/.claude/agent.json +27 -0
- package/assets/.claude/skills/aw-spec-orch/SKILL.md +55 -0
- package/assets/.claude/skills/aw-spec-orch-demo/SKILL.md +59 -0
- package/assets/.kilocode/agent.json +28 -0
- package/assets/.kilocode/workflows/aw-spec-orch-demo.md +59 -0
- package/assets/.kilocode/workflows/aw-spec-orch.md +55 -0
- package/assets/docs/architecture/clean-architecture.md +1 -1
- package/assets/docs/architecture/cqrs.md +1 -1
- package/assets/docs/architecture/eventing.md +1 -1
- package/assets/docs/architecture/folder-structure.md +1 -1
- package/assets/docs/architecture/modular-monolith.md +1 -1
- package/assets/docs/architecture/persistence.md +1 -1
- package/assets/docs/architecture/testing.md +1 -1
- package/assets/docs/architecture/vertical-slices.md +1 -1
- package/assets/docs/components/Email/README.md +1 -1
- package/assets/docs/components/Jobs/README.md +1 -1
- package/assets/docs/components/QrGenerator/README.md +1 -1
- package/assets/docs/components/README.md +1 -1
- package/assets/docs/domain/domain-driven-design.md +1 -1
- package/assets/docs/domainspecs/healthcare/api-versioning.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/auditing.domain.md +86 -18
- package/assets/docs/domainspecs/healthcare/authorization.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/clinical-terms.md +1 -1
- package/assets/docs/domainspecs/healthcare/coding-standards.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/comandrulemap.md +58 -124
- package/assets/docs/domainspecs/healthcare/commandtechrulemap.md +119 -0
- package/assets/docs/domainspecs/healthcare/consent.md +1 -1
- package/assets/docs/domainspecs/healthcare/cqrs.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/data-classification.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/dependency-policy.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/dicom.md +1 -1
- package/assets/docs/domainspecs/healthcare/domain-driven-design.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/eventing.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/fhir.md +1 -1
- package/assets/docs/domainspecs/healthcare/folder-structure.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/hipaa.md +1 -1
- package/assets/docs/domainspecs/healthcare/hl7.md +1 -1
- package/assets/docs/domainspecs/healthcare/integration-terms.md +1 -1
- package/assets/docs/domainspecs/healthcare/persistence.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/terminology.md +1 -1
- package/assets/docs/domainspecs/healthcare/testing.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/vertical-slices.domain.md +1 -1
- package/assets/docs/domainspecs/healthcare/zero-trust.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/api-versioning.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/atc.md +1 -1
- package/assets/docs/domainspecs/pharma/auditing.domain.md +80 -16
- package/assets/docs/domainspecs/pharma/authorization.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/coding-standards.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/comandrulemap.md +64 -142
- package/assets/docs/domainspecs/pharma/commandtechrulemap.md +119 -0
- package/assets/docs/domainspecs/pharma/cqrs.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/data-classification.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/data-provenance.md +1 -1
- package/assets/docs/domainspecs/pharma/dependency-policy.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/domain-driven-design.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/eventing.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/fhir.md +1 -1
- package/assets/docs/domainspecs/pharma/folder-structure.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/hl7.md +1 -1
- package/assets/docs/domainspecs/pharma/idmp.md +1 -1
- package/assets/docs/domainspecs/pharma/integration-terms.md +1 -1
- package/assets/docs/domainspecs/pharma/ndc.md +1 -1
- package/assets/docs/domainspecs/pharma/persistence.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/pharma-terms.md +1 -1
- package/assets/docs/domainspecs/pharma/product-lifecycle.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/regulatory-compliance.md +1 -1
- package/assets/docs/domainspecs/pharma/terminology.md +1 -1
- package/assets/docs/domainspecs/pharma/testing.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/vertical-slices.domain.md +1 -1
- package/assets/docs/domainspecs/pharma/zero-trust.domain.md +1 -1
- package/assets/docs/governance/api-versioning.md +1 -1
- package/assets/docs/governance/coding-standards.md +1 -1
- package/assets/docs/governance/dependency-policy.md +1 -1
- package/assets/docs/requirement-spec.txt +27 -0
- package/assets/docs/security/auditing.md +54 -11
- package/assets/docs/security/authorization.md +1 -1
- package/assets/docs/security/data-classification.md +1 -1
- package/assets/docs/security/zero-trust.md +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +7 -54
- package/dist/commands/init.js.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/utils/paths.js +2 -2
- package/dist/utils/paths.js.map +1 -1
- package/package.json +1 -1
- package/assets/.agents/skills/aw-spec-addcomponent/SKILL.md +0 -129
- package/assets/.agents/skills/aw-spec-agent-context-update/SKILL.md +0 -31
- package/assets/.agents/skills/aw-spec-analyze/SKILL.md +0 -296
- package/assets/.agents/skills/aw-spec-checklist/SKILL.md +0 -374
- package/assets/.agents/skills/aw-spec-clarify/SKILL.md +0 -320
- package/assets/.agents/skills/aw-spec-constitution/SKILL.md +0 -194
- package/assets/.agents/skills/aw-spec-fast-implement/SKILL.md +0 -268
- package/assets/.agents/skills/aw-spec-foundation/SKILL.md +0 -358
- package/assets/.agents/skills/aw-spec-implement/SKILL.md +0 -279
- package/assets/.agents/skills/aw-spec-minimal-implementation/SKILL.md +0 -209
- package/assets/.agents/skills/aw-spec-plan/SKILL.md +0 -221
- package/assets/.agents/skills/aw-spec-select-domain/SKILL.md +0 -73
- package/assets/.agents/skills/aw-spec-specify/SKILL.md +0 -382
- package/assets/.agents/skills/aw-spec-tasks/SKILL.md +0 -259
- package/assets/.agents/skills/aw-spec-taskstoissues/SKILL.md +0 -107
- package/assets/.aw-spec/integrations/claude.manifest.json +0 -17
- package/assets/.aw-spec/scripts/bash/check-prerequisites.sh +0 -189
- package/assets/.aw-spec/scripts/bash/create-new-feature.sh +0 -299
- package/assets/.aw-spec/scripts/bash/setup-plan.sh +0 -84
- package/assets/.aw-spec/scripts/bash/setup-tasks.sh +0 -91
- package/assets/.aw-spec/templates/checklist-template.md +0 -40
- package/assets/.aw-spec/templates/constitution-template.md +0 -57
- package/assets/.aw-spec/templates/plan-template.md +0 -113
- package/assets/.aw-spec/templates/tasks-template.md +0 -252
- package/assets/.aw-spec/workflows/aw-spec/workflow.yml +0 -77
- package/assets/.aw-spec/workflows/workflow-registry.json +0 -13
- package/assets/.claude/skills/aw-spec-addcomponent/SKILL.md +0 -129
- package/assets/.claude/skills/aw-spec-agent-context-update/SKILL.md +0 -31
- package/assets/.claude/skills/aw-spec-analyze/SKILL.md +0 -296
- package/assets/.claude/skills/aw-spec-checklist/SKILL.md +0 -374
- package/assets/.claude/skills/aw-spec-clarify/SKILL.md +0 -320
- package/assets/.claude/skills/aw-spec-constitution/SKILL.md +0 -194
- package/assets/.claude/skills/aw-spec-fast-implement/SKILL.md +0 -268
- package/assets/.claude/skills/aw-spec-foundation/SKILL.md +0 -358
- package/assets/.claude/skills/aw-spec-implement/SKILL.md +0 -279
- package/assets/.claude/skills/aw-spec-minimal-implementation/SKILL.md +0 -209
- package/assets/.claude/skills/aw-spec-plan/SKILL.md +0 -221
- package/assets/.claude/skills/aw-spec-select-domain/SKILL.md +0 -73
- package/assets/.claude/skills/aw-spec-specify/SKILL.md +0 -382
- package/assets/.claude/skills/aw-spec-tasks/SKILL.md +0 -259
- package/assets/.claude/skills/aw-spec-taskstoissues/SKILL.md +0 -107
- package/assets/.kilocode/rules/specify-rules.md +0 -4
- package/assets/.kilocode/workflows/aw-spec-addcomponent.md +0 -129
- package/assets/.kilocode/workflows/aw-spec-agent-context.update.md +0 -31
- package/assets/.kilocode/workflows/aw-spec-analyze.md +0 -296
- package/assets/.kilocode/workflows/aw-spec-checklist.md +0 -374
- package/assets/.kilocode/workflows/aw-spec-clarify.md +0 -320
- package/assets/.kilocode/workflows/aw-spec-constitution.md +0 -194
- package/assets/.kilocode/workflows/aw-spec-fast-implement.md +0 -263
- package/assets/.kilocode/workflows/aw-spec-foundation.md +0 -358
- package/assets/.kilocode/workflows/aw-spec-implement.md +0 -279
- package/assets/.kilocode/workflows/aw-spec-minimal-implementation.md +0 -204
- package/assets/.kilocode/workflows/aw-spec-plan.md +0 -221
- package/assets/.kilocode/workflows/aw-spec-select-domain.md +0 -73
- package/assets/.kilocode/workflows/aw-spec-specify.md +0 -382
- package/assets/.kilocode/workflows/aw-spec-tasks.md +0 -259
- package/assets/.kilocode/workflows/aw-spec-taskstoissues.md +0 -107
- package/assets/docs/UI.Visualization/PACKAGING.md +0 -191
- package/assets/docs/UI.Visualization/UI.Visualization.Reference.pack.txt +0 -11768
- package/assets/docs/UI.Visualization/UI.Visualization.pack.txt +0 -11214
- package/assets/docs/UI.Visualization/pack-foundation.ps1 +0 -165
- package/assets/docs/UI.Visualization/pack-foundation.sh +0 -206
- package/assets/docs/UI.Visualization/pack-reference-foundation.ps1 +0 -159
- package/assets/docs/UI.Visualization/pack-reference-foundation.sh +0 -205
- package/assets/docs/UI.Visualization/unpack-foundation.ps1 +0 -126
- package/assets/docs/UI.Visualization/unpack-foundation.sh +0 -217
- package/assets/docs/UI.Visualization/unpack-reference-foundation.ps1 +0 -129
- package/assets/docs/UI.Visualization/unpack-reference-foundation.sh +0 -218
- package/assets/docs/command.txt +0 -295
- package/assets/docs/domainspecs/UIVisualization/chart-bubble.md +0 -70
- package/assets/docs/domainspecs/UIVisualization/chart-dimred.md +0 -58
- package/assets/docs/domainspecs/UIVisualization/chart-heatmap.md +0 -62
- package/assets/docs/domainspecs/UIVisualization/chart-network.md +0 -69
- package/assets/docs/domainspecs/UIVisualization/chart-parallel.md +0 -75
- package/assets/docs/domainspecs/UIVisualization/chart-scurve.md +0 -66
- package/assets/docs/domainspecs/UIVisualization/chart-survival.md +0 -69
- package/assets/docs/domainspecs/UIVisualization/chart-trellis.md +0 -68
- package/assets/docs/domainspecs/UIVisualization/chart-violin.md +0 -61
- package/assets/docs/domainspecs/UIVisualization/chart-volcano.md +0 -63
- package/assets/docs/domainspecs/UIVisualization/charting-standards.domain.md +0 -80
- package/assets/docs/domainspecs/UIVisualization/clean-architecture.domain.md +0 -87
- package/assets/docs/domainspecs/UIVisualization/coding-standards.domain.md +0 -47
- package/assets/docs/domainspecs/UIVisualization/comandrulemap.md +0 -130
- package/assets/docs/domainspecs/UIVisualization/component-contracts.domain.md +0 -67
- package/assets/docs/domainspecs/UIVisualization/data-source.domain.md +0 -68
- package/assets/docs/domainspecs/UIVisualization/domain-requirements.md +0 -110
- package/assets/docs/domainspecs/UIVisualization/folder-structure.domain.md +0 -55
- package/assets/docs/domainspecs/UIVisualization/state-management.domain.md +0 -67
- package/assets/docs/domainspecs/UIVisualization/testing.domain.md +0 -52
- package/assets/docs/domainspecs/UIVisualization/ui-viz-terms.md +0 -39
- 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.
|