@groupviz/react 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +353 -0
- package/README.md +47 -16
- package/components/Canvas/ActionScene.d.ts +5 -1
- package/components/Canvas/Cayley3DScene.d.ts +4 -1
- package/components/Canvas/CayleyView.d.ts +7 -1
- package/components/Canvas/CosetStripScene.d.ts +13 -1
- package/components/Canvas/CycleView.d.ts +7 -1
- package/components/Canvas/HomomorphismScene.d.ts +5 -1
- package/components/Canvas/SceneHoverBubble.d.ts +28 -0
- package/components/Canvas/SceneThemeRoot.d.ts +24 -0
- package/components/Canvas/SetView.d.ts +7 -1
- package/components/Canvas/SublatticeScene.d.ts +4 -1
- package/components/Canvas/SymmetryViewScene.d.ts +11 -1
- package/components/Canvas/TableView.d.ts +9 -1
- package/context/cayleyActions.d.ts +4 -1
- package/hooks/useSceneState.d.ts +116 -0
- package/i18n/I18nContext.d.ts +8 -2
- package/index.js +1748 -1327
- package/index.js.map +1 -1
- package/package/react.d.ts +8 -0
- package/package.json +2 -2
- package/utils/elementRef.d.ts +9 -0
package/API.md
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
# 引擎 API 参考(@groupviz/core · @groupviz/react)
|
|
2
|
+
|
|
3
|
+
> 本文件随 npm 包发布(`node_modules/@groupviz/{core,react}/API.md`),是**包消费端**的权威 props 表。
|
|
4
|
+
> 面向主应用开发者 / 内嵌者;仓库内部实现细节见 [docs/VIEWS.md](VIEWS.md) · [docs/GROUPS.md](GROUPS.md) · [docs/CAYLEY.md](CAYLEY.md)。
|
|
5
|
+
>
|
|
6
|
+
> 口径:**Scene 是纯受控渲染内核**(不读应用级 context);状态、hover 气泡、主题开关全部由宿主经 props 注入。
|
|
7
|
+
> `@groupviz/react` 收录 10 个 Scene(sylow / tree / prestable 未 props 化,不入包)。
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 0. 最小可用示例(推荐写法)
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { createGroupFromSymbol } from '@groupviz/core'
|
|
15
|
+
import { useSceneState, SetView } from '@groupviz/react'
|
|
16
|
+
import '@groupviz/react/theme.css'
|
|
17
|
+
|
|
18
|
+
const group = createGroupFromSymbol('S_{4}')
|
|
19
|
+
|
|
20
|
+
export function Figure() {
|
|
21
|
+
const s = useSceneState(group, { theme: 'light' }) // ← 四件套 + 交互 + 气泡全包
|
|
22
|
+
return (
|
|
23
|
+
<div {...s.hostProps} style={{ width: 480, height: 360 }}>
|
|
24
|
+
<SetView group={group} {...s.sceneProps} theme="light" />
|
|
25
|
+
{s.hoverBubble}
|
|
26
|
+
</div>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`useSceneState` 之前,同一张图需要宿主自备:`selectedElements` / `canvasTransform` / `viewBoxSize`
|
|
32
|
+
(ResizeObserver 量尺寸)+ `onSelect` / `onHover` + 滚轮缩放贴光标 + 拖拽平移 + hover 气泡 ≈ 80 行胶水。
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 1. 元素引用(element reference)—— 所有元素类 props 的通用约定
|
|
37
|
+
|
|
38
|
+
群元素同时有两种记号:
|
|
39
|
+
|
|
40
|
+
| 记号 | 来源 | 例子(S₄) |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `id` | 机器键,`GroupElement.id` | `"1,3,4,2"` |
|
|
43
|
+
| `label` | 人类记号,`GroupElement.label` | `"34"` / `"e"` |
|
|
44
|
+
| `value` | 数组,`GroupElement.value` | `[1,3,4,2]` |
|
|
45
|
+
|
|
46
|
+
**下列 props 接受任一记号**,内部统一经 `core.resolveElement` 解析(匹配序 `id` → `label` → `value`,忽略空白):
|
|
47
|
+
|
|
48
|
+
| 归属 | prop |
|
|
49
|
+
|---|---|
|
|
50
|
+
| `SymmetryViewScene` | `actionElementId` |
|
|
51
|
+
| `CayleyView` / `Cayley3DScene` | `actions[].elementId` |
|
|
52
|
+
| `CosetStripScene` | `subgroup[]` |
|
|
53
|
+
| `@groupviz/core` | `resolveElement` / `findElement` / `resolveElementRefs` / `resolveElementIds` / `buildCosetViewData` / `subgroupFromElementIds` 的入参 |
|
|
54
|
+
|
|
55
|
+
**未命中不再静默**:解析失败会 `console.warn` 一次(按「上下文 + 群 + 引用」去重),该项被忽略、渲染不炸。
|
|
56
|
+
需要自行诊断时用 core 的纯函数 `resolveElement(group, ref)`(返回 `null`,不告警)。
|
|
57
|
+
|
|
58
|
+
> 其余以元素 id 为语义的 props(`selectedElements` / `subsets[].elementIds` / `Cayley3DScene.faceFill.subgroup` /
|
|
59
|
+
> `CycleView.getNodePosition(elId)`)仍按 **id** 消费;需要 label 输入时先自行 `resolveElement`。
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 2. `useSceneState`(`@groupviz/react`)
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
const s = useSceneState(group?, options?)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
| option | 缺省 | 说明 |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| `initialTransform` | `{x:0,y:0,scale:1}` | 初始平移 / 缩放 |
|
|
72
|
+
| `locked` | `false` | 锁交互(同时透传给 Scene 的 `locked`) |
|
|
73
|
+
| `enableZoom` / `enablePan` | `true` | 滚轮缩放 / 拖拽平移开关 |
|
|
74
|
+
| `minScale` / `maxScale` | `0.25` / `8` | 缩放区间(与主画布一致) |
|
|
75
|
+
| `selectedElements` | — | **传入即受控**,配合 `onSelectionChange` |
|
|
76
|
+
| `onSelectionChange` | — | 选中集合变更回调(受控 / 非受控都会触发) |
|
|
77
|
+
| `fallbackViewBoxSize` | `{800,600}` | ResizeObserver 首帧前的兜底尺寸 |
|
|
78
|
+
| `hostStyle` | — | 宿主容器附加样式(与内建样式合并) |
|
|
79
|
+
| `theme` | `'dark'` | 内建 hover 气泡主题 |
|
|
80
|
+
| `renderHoverBubble` | — | 自绘气泡;返回 `null` 表示不要内建气泡 |
|
|
81
|
+
|
|
82
|
+
返回值:
|
|
83
|
+
|
|
84
|
+
| 字段 | 用途 |
|
|
85
|
+
|---|---|
|
|
86
|
+
| `hostProps` | **一次 spread 即挂好宿主容器**:内含 `ref`(回调 ref)、事件(拖拽平移)与内建样式(`position:relative`、`100%`、`touchAction:none`、光标)|
|
|
87
|
+
| `sceneProps` | **可直接 spread 到 SetView / CycleView / CayleyView / CosetStripScene**:`selectedElements` `canvasTransform` `viewBoxSize` `onSelect` `onHover` |
|
|
88
|
+
| `viewBoxSize` | 容器实测尺寸 |
|
|
89
|
+
| `getHostElement()` | 需要 DOM 节点时用(如导出 SVG)|
|
|
90
|
+
| `canvasTransform` / `setCanvasTransform` / `resetTransform` / `zoomBy(factor)` | 视图变换 |
|
|
91
|
+
| `selectedElements` / `setSelectedElements` / `select(elId, additive?)` / `clearSelection()` | 选中态(`additive` = ⊕/Ctrl/⌘ 语义:切换成员;否则单选替换) |
|
|
92
|
+
| `hovered` / `hoverAnchor` / `hoverBubble` | 悬停元素、锚点、现成气泡节点 |
|
|
93
|
+
| `locked` | 透传给 Scene |
|
|
94
|
+
| `getNodePosition` / `onNodePositionChange` / `resetNodePositions` | 共享节点位置:把前两者传给 `CycleView` 即可多视图共用一套坐标 |
|
|
95
|
+
|
|
96
|
+
**行为要点**
|
|
97
|
+
|
|
98
|
+
- ⚠️ **不要在 spread 之后自己再写 `ref`** —— 会顶掉 `hostProps.ref`,尺寸测量与气泡换算会静默失效。需要节点用 `getHostElement()`。
|
|
99
|
+
- `hostProps` 里的 `ref` 之所以是回调 ref 且**只嵌套在 `hostProps` 内**:React Compiler 的 `react-hooks/refs` 规则会把「顶层返回 ref 写入函数 / 含 `RefObject`」的 hook 整体判为 ref 载体,此后宿主每次 `s.xxx` 读取都会报 *Cannot access refs during render*。保持嵌套即无此副作用(`SceneState` 顶层字段已做运行时断言守卫)。
|
|
100
|
+
- 拖拽平移用 **React 合成事件**,与 Scene 内节点自身的 `stopPropagation()` 同处一套冒泡序 → **拖节点不会连带拖动画布**;只有左键生效。
|
|
101
|
+
- 滚轮缩放走 **原生 non-passive 监听**(React root 级 `wheel` 是 passive,`preventDefault` 无效),锚定光标下的 viewBox 坐标;指针坐标缺失 / 非有限时退回容器中心,**不会把变换写成 NaN**。
|
|
102
|
+
- 换群(`group` 引用变化)会清空悬停 / 非受控选中 / 节点位置,避免旧 id 命中新群(渲染期校正,不额外多一帧残留)。
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 3. 主题(`theme`)
|
|
107
|
+
|
|
108
|
+
| 组件 | 主题 prop |
|
|
109
|
+
|---|---|
|
|
110
|
+
| 7 个 2D Scene:`SetView` `CycleView` `CayleyView` `TableView` `CosetStripScene` `ActionScene` `HomomorphismScene` | `theme?: 'dark' \| 'light'` |
|
|
111
|
+
| `SymmetryViewScene` | `theme?: 'dark' \| 'light'`(`dark?: boolean` 为兼容别名,`theme` 优先) |
|
|
112
|
+
| `Cayley3DScene` `SublatticeScene` | `theme?: 'dark' \| 'light'` |
|
|
113
|
+
|
|
114
|
+
- **缺省不传 → 不注入任何主题作用域**,Scene 沿用外层主题(`theme.css` 的 `:root` 变量 / ThemeContext),
|
|
115
|
+
与既有行为逐位一致(无额外 DOM)。
|
|
116
|
+
- **显式传值 → 在该 Scene 子树内注入 `data-theme` 作用域**(`SceneThemeRoot`),命中 `theme.css`
|
|
117
|
+
里对应的变量块。宿主须 `import '@groupviz/react/theme.css'`,否则变量缺失(此时仅剩内联兜底色)。
|
|
118
|
+
- `SublatticeScene` 例外:不做外层包装(其 `<svg>` 必须是宿主 flex 的直接子元素才能正确测量),
|
|
119
|
+
主题经 palette 计算而非 CSS 作用域。
|
|
120
|
+
|
|
121
|
+
`SceneThemeRoot` 也可独立使用,把多张图一起罩进同一主题作用域。
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 4. Scene props 全表
|
|
126
|
+
|
|
127
|
+
> 四件套 `group` / `selectedElements` / `canvasTransform` / `viewBoxSize` 除表格内单独说明外均为**必填**受控项。
|
|
128
|
+
|
|
129
|
+
### 4.1 `SetView`
|
|
130
|
+
|
|
131
|
+
| prop | 类型 | 缺省 | 说明 |
|
|
132
|
+
|---|---|---|---|
|
|
133
|
+
| `group` | `Group \| null` | — | `null` 渲染空态 |
|
|
134
|
+
| `selectedElements` | `Set<string>` | — | 选中元素 id |
|
|
135
|
+
| `canvasTransform` | `{x,y,scale}` | — | |
|
|
136
|
+
| `viewBoxSize` | `{width,height}` | — | |
|
|
137
|
+
| `subsets` | `{elementIds,color}[]` | — | 子集着色(id) |
|
|
138
|
+
| `selfInverseElementId` | `string \| null` | — | 自逆元素标记(id) |
|
|
139
|
+
| `cosetElementMap` / `cosetHighlightSet` / `cosetColors` | `Map<id,number>` / `Set<number>` / `string[]` | — | 陪集着色三件套 |
|
|
140
|
+
| `onSelect` | `(elId, additive) => void` | — | |
|
|
141
|
+
| `onHover` | `(el \| null, anchor?) => void` | — | `anchor` = 视口内屏幕坐标 |
|
|
142
|
+
| `noGroupText` | `string` | `''` | |
|
|
143
|
+
| `nodeRadius` / `gap` / `columns` | `number` | 自动 | 布局微调 |
|
|
144
|
+
| `showLabels` | `boolean` | `true` | 常驻标签总开关 |
|
|
145
|
+
| `largeGroupThreshold` | `number` | `60` | 群阶 > 该值时「仅选中节点显示常驻标签」 |
|
|
146
|
+
| `theme` | `'dark' \| 'light'` | — | 不传 = 跟随外层 |
|
|
147
|
+
|
|
148
|
+
### 4.2 `CycleView`
|
|
149
|
+
|
|
150
|
+
在 `SetView` 四件套 + `subsets` / `selfInverseElementId` / 陪集三件套 / `onSelect` / `onHover` / `noGroupText` 之外:
|
|
151
|
+
|
|
152
|
+
| prop | 类型 | 缺省 | 说明 |
|
|
153
|
+
|---|---|---|---|
|
|
154
|
+
| `showMaximalCycles` | `boolean` | `true` | 仅显示极大循环并启用 planar 布局 |
|
|
155
|
+
| `nodeRadius` | `number` | `24` | |
|
|
156
|
+
| `showLabels` | `boolean` | `true` | |
|
|
157
|
+
| `showCycleLabels` | `boolean` | `true` | 显示 `⟨g⟩ ≅ Z_n` 标注 |
|
|
158
|
+
| `locked` | `boolean` | `false` | 禁用节点拖拽(点击选中保留) |
|
|
159
|
+
| `getNodePosition` / `onNodePositionChange` | 函数 | — | 外部持久化节点位置(不传用局部态) |
|
|
160
|
+
| `largeGroupThreshold` | `number` | `60` | |
|
|
161
|
+
| `theme` | `'dark' \| 'light'` | — | |
|
|
162
|
+
|
|
163
|
+
### 4.3 `CayleyView`
|
|
164
|
+
|
|
165
|
+
| prop | 类型 | 缺省 | 说明 |
|
|
166
|
+
|---|---|---|---|
|
|
167
|
+
| `shape2D` | `CayleyShape2D` | 按群自动 | 不支持的形状自动回退 `circular` |
|
|
168
|
+
| `multiplyType` | `'right' \| 'left'` | `'right'` | |
|
|
169
|
+
| `actions` | `{elementId, enabled?, color?}[]` | 群生成元 | **`elementId` 接受元素引用** |
|
|
170
|
+
| `nodeRadius` | `number` | `28` | |
|
|
171
|
+
| `showLabels` | `boolean` | `true` | 嵌入小窗常传 `false`(读元素靠 hover 气泡) |
|
|
172
|
+
| `locked` | `boolean` | `false` | |
|
|
173
|
+
| `hoveredElementId` | `string \| null` | — | 悬停高亮环(id) |
|
|
174
|
+
| `largeGroupThreshold` | `number` | `60` | |
|
|
175
|
+
| `theme` | `'dark' \| 'light'` | — | |
|
|
176
|
+
|
|
177
|
+
### 4.4 `TableView`
|
|
178
|
+
|
|
179
|
+
| prop | 类型 | 缺省 | 说明 |
|
|
180
|
+
|---|---|---|---|
|
|
181
|
+
| `subsets` / `cosetElementMap` / `cosetColors` / `cosetData` / `cosetType` / `showAllCosets` | — | — | 子群 / 陪集着色 |
|
|
182
|
+
| `forceShowLargeGroup` / `onForceShowLargeGroup` | `boolean` / `fn` | `false` / — | 解除大群告警 |
|
|
183
|
+
| `strategy` | `'subgroup' \| 'random' \| 'full'` | `'subgroup'` | 大群(>16 阶)策略 |
|
|
184
|
+
| `cellSize` | `number` | `50` | |
|
|
185
|
+
| `showHeatmap` | `boolean` | `false` | 热力图模式(不显示元素与表头) |
|
|
186
|
+
| `onStrategyChange` | `fn` | — | |
|
|
187
|
+
| `onLayoutSize` | `(size \| null) => void` | — | 实际表格尺寸回传(供窗口定最小尺寸) |
|
|
188
|
+
| `maxTableOrder` | `number` | `100` | 文字表过大阈值 |
|
|
189
|
+
| `maxHeatmapOrder` | `number` | `240` | 热力图过大阈值 |
|
|
190
|
+
| `theme` | `'dark' \| 'light'` | — | |
|
|
191
|
+
| `onHover` | `(el \| null) => void` | — | **不提供 anchor**(无就地气泡) |
|
|
192
|
+
|
|
193
|
+
### 4.5 `CosetStripScene`
|
|
194
|
+
|
|
195
|
+
| prop | 类型 | 缺省 | 说明 |
|
|
196
|
+
|---|---|---|---|
|
|
197
|
+
| `cosetElementMap` / `cosetColors` / `cosetHighlightSet` | — | — | 陪集三件套(显式传入优先) |
|
|
198
|
+
| `subgroup` | `string[] \| null` | — | **便捷入口**:只给 H(id/label 皆可),内部经 `core.buildCosetViewData` 一键派生三件套 |
|
|
199
|
+
| `cosetType` | `'left' \| 'right'` | `'left'` | 便捷入口配套 |
|
|
200
|
+
| `highlightAllCosets` | `boolean` | `false` | 便捷入口配套 |
|
|
201
|
+
| `showLabels` | `boolean` | `true` | |
|
|
202
|
+
| `showSubgroupCayley` | `boolean` | `true` | H 条带上方画 H 自身 Cayley 小圈 |
|
|
203
|
+
| `subsets` / `onSelect` / `onHover` / `noGroupText` / `noCosetsText` | — | — | |
|
|
204
|
+
| `theme` | `'dark' \| 'light'` | — | |
|
|
205
|
+
|
|
206
|
+
### 4.6 `ActionScene`
|
|
207
|
+
|
|
208
|
+
| prop | 类型 | 说明 |
|
|
209
|
+
|---|---|---|
|
|
210
|
+
| `group` | `Group`(必填,非 null) | |
|
|
211
|
+
| `kind` | `GroupActionKind` | 窗口范围:`conjugation` / `regular` / `custom` |
|
|
212
|
+
| `computation` | `GroupActionComputation \| null` | |
|
|
213
|
+
| `editing` / `setSize` / `arrows` / `error` | — | custom 编辑模式 |
|
|
214
|
+
| `onAddArrow` / `onBindArrow` / `onRemoveArrow` / `onReplaceGenArrows` | 函数 | 编辑回调 |
|
|
215
|
+
| `selectedElement` / `onSelectedElementChange` | `number \| null` / `fn` | 集合元素索引(OST 交互) |
|
|
216
|
+
| `hoveredElement` / `onHoverElementChange` | `string \| null` / `fn` | |
|
|
217
|
+
| `onSetElementSelect` | `fn` | chips 点击 → 主画布全局选中 |
|
|
218
|
+
| `showLabels` | `boolean`(缺省 `true`) | 关掉 = 空圈节点 + hover 气泡 |
|
|
219
|
+
| `onHover` | `(el \| null, anchor?) => void` | |
|
|
220
|
+
| `canvasTransform` / `viewBoxSize` | 可选(有内建缺省) | |
|
|
221
|
+
| `prime` | `number \| null` | sylow banner 标题 |
|
|
222
|
+
| `theme` | `'dark' \| 'light'` | |
|
|
223
|
+
|
|
224
|
+
### 4.7 `HomomorphismScene`
|
|
225
|
+
|
|
226
|
+
| prop | 类型 | 说明 |
|
|
227
|
+
|---|---|---|
|
|
228
|
+
| `source` / `target` | `Group \| null` | |
|
|
229
|
+
| `mapping` | `Map<srcId, tgtId>` | |
|
|
230
|
+
| `result` | `HomomorphismResult \| null` | 不传则内部 `verifyHomomorphism` 推导 |
|
|
231
|
+
| `name` | `string` | 显示名(TeX 或纯文本) |
|
|
232
|
+
| `theoremMode` / `onTheoremModeChange` | `boolean` / `fn` | 第一同构定理动画开关 |
|
|
233
|
+
| `theoremAnimation` | `ReactNode` | 动画内容(主应用注入) |
|
|
234
|
+
| `showLabels` | `boolean`(缺省 `true`) | |
|
|
235
|
+
| `onHover` | `(el \| null, anchor?) => void` | |
|
|
236
|
+
| `theme` | `'dark' \| 'light'` | |
|
|
237
|
+
|
|
238
|
+
### 4.8 `SymmetryViewScene`
|
|
239
|
+
|
|
240
|
+
| prop | 类型 | 缺省 | 说明 |
|
|
241
|
+
|---|---|---|---|
|
|
242
|
+
| `group` | `Group`(非 null) | — | |
|
|
243
|
+
| `symmetryType` | `SymmetryType` | 按群推导 | `unsupported` 群渲染提示层 |
|
|
244
|
+
| `theme` | `'dark' \| 'light'` | — | 优先 |
|
|
245
|
+
| `dark` | `boolean` | `false` | 兼容别名 |
|
|
246
|
+
| `variant` | `boolean` | `false` | 对偶多面体(cube↔octahedron / icosahedron↔dodecahedron) |
|
|
247
|
+
| `showAction` | `boolean` | `false` | 元素作用演示 |
|
|
248
|
+
| `actionElementId` | `string \| null` | `null` | **接受元素引用**(id/label) |
|
|
249
|
+
| `rotateSpeed` | `number` | `1` | 0.2–5 |
|
|
250
|
+
| `showFigureTitle` | `boolean` | `true` | 顶部群名 + 几何描述 |
|
|
251
|
+
| `locked` | `boolean` | `false` | 锁相机交互 |
|
|
252
|
+
| `onHint` | `(msg: string) => void` | — | 演示状态提示 |
|
|
253
|
+
| `hintOnIdle` | `boolean` | `true` | 无演示目标时是否上抛引导文案 |
|
|
254
|
+
| `replaySignal` | `number` | `0` | 自增即重播一次动画 |
|
|
255
|
+
| `lockCameraOnAction` | `boolean` | `false` | 演示期间是否禁用相机旋转/平移 |
|
|
256
|
+
| `onAnimationEnd` | `() => void` | — | 姿态落定(动画播完)回调 |
|
|
257
|
+
|
|
258
|
+
> **行为变更提示**:`lockCameraOnAction` 缺省 `false`。旧实现等价于恒 `true`
|
|
259
|
+
> (`enableRotate = !showAction && !locked`),会出现「演示元素未命中 → 动画没跑,视角却被锁死」。
|
|
260
|
+
> 需要旧行为请显式传 `true`。
|
|
261
|
+
|
|
262
|
+
### 4.9 `Cayley3DScene`
|
|
263
|
+
|
|
264
|
+
| prop | 类型 | 缺省 | 说明 |
|
|
265
|
+
|---|---|---|---|
|
|
266
|
+
| `actions` / `multiplyType` | — | 群生成元 / `'right'` | `actions[].elementId` 接受元素引用 |
|
|
267
|
+
| `layout3D` | `Layout3D` | 按群自动 | |
|
|
268
|
+
| `nodeScale` | `number` | `1` | 0.5–2.0 |
|
|
269
|
+
| `autoRotate` | `boolean` | `false` | |
|
|
270
|
+
| `showLabels` | `boolean` | `true` | |
|
|
271
|
+
| `locked` | `boolean` | `false` | |
|
|
272
|
+
| `subsetHighlights` | `{elementIds,color}[]` | — | |
|
|
273
|
+
| `faceFill` | `Cayley3DFaceFillParams` | — | 子群陪集面填充 |
|
|
274
|
+
| `theme` | `'dark' \| 'light'` | `'dark'` | |
|
|
275
|
+
| `onSelectElement` | `fn` | — | |
|
|
276
|
+
|
|
277
|
+
### 4.10 `SublatticeScene`
|
|
278
|
+
|
|
279
|
+
| prop | 类型 | 缺省 | 说明 |
|
|
280
|
+
|---|---|---|---|
|
|
281
|
+
| `group` | `Group \| null` | — | |
|
|
282
|
+
| `lattice` | `LatticeData \| null` | — | 外部提供(大群后端通路)优先 |
|
|
283
|
+
| `canvasTransform` / `availableSize` | 可选 | — | 不传则自测容器 |
|
|
284
|
+
| `labelDetail` | `LatticeLabelDetail` | `'auto'` | 名片细节档 |
|
|
285
|
+
| `mergeConjugates` | `boolean` | `false` | 共轭子群合并为轨道节点 |
|
|
286
|
+
| `nodeScale` | `number` | `1` | |
|
|
287
|
+
| `showSeriesPanel` | `boolean` | `true` | |
|
|
288
|
+
| `series` / `centerIds` / `subsets` / `activeNodeIdx` / `onActivateNode` / `noGroupText` | — | — | |
|
|
289
|
+
| `theme` | `'dark' \| 'light'` | ThemeContext | |
|
|
290
|
+
| `maxEnumerateOrder` | `number` | `60` | 本地枚举子群格的群阶上限 |
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## 5. `SceneWindow`
|
|
295
|
+
|
|
296
|
+
窗口 chrome 壳(标题栏 / 拖拽 / resize / ⚙ View Config / localStorage 持久化),**不接管 Scene 状态**。
|
|
297
|
+
|
|
298
|
+
| prop | 类型 | 缺省 | 说明 |
|
|
299
|
+
|---|---|---|---|
|
|
300
|
+
| `title` / `group` | `string` / `Group \| null` | `group.symbol` | 标题与 info 区 |
|
|
301
|
+
| `theme` | `'dark' \| 'light'` | `'dark'` | 窗口配色 |
|
|
302
|
+
| `shell` | `'none' \| 'chrome'` | `'chrome'` | `'none'` = 裸内容容器 |
|
|
303
|
+
| `capabilities` | `SceneWindowCaps` | 全开 | 逐项裁剪:`titlebar` `drag` `resize` `lockMove` `toggleInfo` `params` `close` `persist` |
|
|
304
|
+
| `config` / `onConfigChange` | `SceneWindowConfig` | — | `locked` `showInfo` `resizable` `viewportFixed` `showControls` |
|
|
305
|
+
| `storageKey` / `defaultPosition` / `defaultSize` / `onClose` / `children` | — | — | `storageKey` 给键才持久化(键空间 `gv-sw-*`) |
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## 6. i18n
|
|
310
|
+
|
|
311
|
+
```tsx
|
|
312
|
+
import { I18nProvider, useTranslation } from '@groupviz/react'
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
| API | 说明 |
|
|
316
|
+
|---|---|
|
|
317
|
+
| `<I18nProvider lang? persist?>` | `lang` = 初始语言(缺省读 localStorage / 浏览器);`persist` 缺省 `true`,嵌入宿主不想共用 `groupviz-lang` key 时传 `false` |
|
|
318
|
+
| `useTranslation()` | `{ lang, setLang, t }` |
|
|
319
|
+
|
|
320
|
+
**无 Provider 也可用**:缺省 `t` 直接查真实词典(中文优先、英文兜底),不再回落成 key。
|
|
321
|
+
只有真正缺失的 key 才返回 key 本身,并 `console.warn`。
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 7. `@groupviz/core` 本批次新增
|
|
326
|
+
|
|
327
|
+
| 导出 | 签名 | 说明 |
|
|
328
|
+
|---|---|---|
|
|
329
|
+
| `resolveElement` | `(group, ref) => GroupElement \| null` | 元素引用解析(`id` → `label` → `value`,忽略空白) |
|
|
330
|
+
| `findElement` | 同上 | `resolveElement` 的别名 |
|
|
331
|
+
| `resolveElementRefs` | `(group, refs) => { elements, ids, unresolved }` | 批量解析 + 未命中回收 |
|
|
332
|
+
| `resolveElementIds` | `(group, refs) => string[]` | 批量解析为规范 id(去重、丢未命中) |
|
|
333
|
+
| `normalizeElementRef` | `(ref) => string` | 去空白归一化 |
|
|
334
|
+
| `elementOrder` | `(group, el) => number` | 元素阶(group-first 公共入口) |
|
|
335
|
+
| `elementOrderDistribution` | `(group) => Map<number, number>` | 阶分布 |
|
|
336
|
+
| `elementOrderDistributionOf` | `(elements, group) => Map<number, number>` | 子集阶分布 |
|
|
337
|
+
| `subgroupFromElementIds` | `(group, refs, opts?) => Subgroup \| null` | 由元素引用装配 Subgroup(默认含封闭校验 + 极小生成集;`validate:false` / `computeGenerators:false` 可省开销) |
|
|
338
|
+
| `isSubgroupElementSet` | `(group, refs) => boolean` | 是否构成子群(含单位元 + 乘法封闭) |
|
|
339
|
+
| `buildCosetViewData` | `(group, subgroupRefs, opts?) => CosetViewData \| null` | **陪集视图一键装配**:`cosetElementMap` / `cosetColors` / `cosetHighlightSet` |
|
|
340
|
+
| `computeCosetElementMap` / `computeCosetColors` / `computeCosetHighlightSet` | 见源码 | 三件套单独入口 |
|
|
341
|
+
| `sizeLimitFor` | `(view) => number` | 各视图默认「过大」阈值(可读) |
|
|
342
|
+
| `isTooLarge` | `(order, view, limitOverride?) => boolean` | 第三参可覆盖阈值 |
|
|
343
|
+
| `listCosetStripSubgroups` / `findCosetStripSubgroup` / `cosetDataForSubgroup` | 见源码 | 陪集条带候选子群(此前未出门面,现已公开) |
|
|
344
|
+
|
|
345
|
+
**陪集视图最省事写法**(宿主不再需要拼三件套):
|
|
346
|
+
|
|
347
|
+
```tsx
|
|
348
|
+
import { buildCosetViewData } from '@groupviz/core'
|
|
349
|
+
|
|
350
|
+
const data = buildCosetViewData(group, ['e0', 'e3'], { side: 'left' }) // H 也可用 label
|
|
351
|
+
<CosetStripScene group={group} viewBoxSize={vb} {...data} />
|
|
352
|
+
// 或者更直接:<CosetStripScene group={group} viewBoxSize={vb} subgroup={['e0','e3']} />
|
|
353
|
+
```
|
package/README.md
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
# @groupviz/react
|
|
2
2
|
|
|
3
|
-
GroupViz 群论可视化的 **React 视图组件**。与 [@groupviz/core](
|
|
3
|
+
GroupViz 群论可视化的 **React 视图组件**。与 [@groupviz/core](https://www.npmjs.com/package/@groupviz/core) 配套:core 出数据,react 出图。
|
|
4
4
|
|
|
5
5
|
**包含**:10 个视图 Scene(`SetView` / `CycleView` / `CayleyView` / `TableView` / `CosetStripScene` /
|
|
6
6
|
`ActionScene` / `HomomorphismScene` / `SublatticeScene` / `Cayley3DScene` / `SymmetryViewScene`)、
|
|
7
|
-
|
|
7
|
+
**便利层 `useSceneState`**(受控四件套 + ResizeObserver + 滚轮缩放/拖拽平移 + 就地气泡)、
|
|
8
|
+
窗口容器壳 `SceneWindow`、主题作用域 `SceneThemeRoot`、悬停气泡 `SceneHoverBubble`、
|
|
9
|
+
`I18nProvider` / `useTranslation`(内置中 / 英文语言包,**无 Provider 也返回真实文案**)、
|
|
10
|
+
`theme.css`(深 / 浅色主题变量)。
|
|
11
|
+
|
|
12
|
+
> 口径说明:主应用 **GroupViz 共 13 种视图**(另含 sylow / tree / prestable 与构建面板内嵌视图);
|
|
13
|
+
> 本包收录其中可作为受控组件嵌入宿主的 10 个 Scene(sylow / tree / prestable 视图未 props 化,暂不入包)。
|
|
8
14
|
|
|
9
15
|
**安装**(npm 自动解析 peer:react 19 / three / @react-three/fiber / @react-three/drei / katex)
|
|
10
16
|
|
|
@@ -12,37 +18,62 @@ GroupViz 群论可视化的 **React 视图组件**。与 [@groupviz/core](../cor
|
|
|
12
18
|
npm i @groupviz/core @groupviz/react
|
|
13
19
|
```
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
**快速开始**(推荐:`useSceneState` 把受控四件套 + 交互 + 气泡一次给全)
|
|
16
22
|
|
|
17
23
|
```tsx
|
|
18
|
-
import {
|
|
24
|
+
import { useSceneState, SetView } from '@groupviz/react'
|
|
19
25
|
import '@groupviz/react/theme.css'
|
|
20
26
|
import { createGroupFromSymbol } from '@groupviz/core'
|
|
21
27
|
|
|
22
28
|
const group = createGroupFromSymbol('C_{6}')
|
|
23
29
|
|
|
24
30
|
export function App() {
|
|
31
|
+
const s = useSceneState(group, { theme: 'light' })
|
|
25
32
|
return (
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
selectedElements={new Set()}
|
|
31
|
-
canvasTransform={{ x: 0, y: 0, scale: 1 }}
|
|
32
|
-
viewBoxSize={{ width: 480, height: 360 }}
|
|
33
|
-
/>
|
|
34
|
-
</div>
|
|
35
|
-
</I18nProvider>
|
|
33
|
+
<div {...s.hostProps} style={{ width: 480, height: 360 }}>
|
|
34
|
+
<SetView group={group} {...s.sceneProps} theme="light" />
|
|
35
|
+
{s.hoverBubble}
|
|
36
|
+
</div>
|
|
36
37
|
)
|
|
37
38
|
}
|
|
38
39
|
```
|
|
39
40
|
|
|
41
|
+
> `hostProps` 内含回调 ref,**一次 spread 就够**;别再自己写 `ref`(会顶掉内建 ref,
|
|
42
|
+
> 尺寸测量与气泡换算会静默失效)。需要 DOM 节点用 `s.getHostElement()`。
|
|
43
|
+
|
|
44
|
+
也可以完全受控(Scene 是纯渲染内核,状态由宿主自持):
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
<SetView
|
|
48
|
+
group={group}
|
|
49
|
+
selectedElements={new Set()}
|
|
50
|
+
canvasTransform={{ x: 0, y: 0, scale: 1 }}
|
|
51
|
+
viewBoxSize={{ width: 480, height: 360 }}
|
|
52
|
+
/>
|
|
53
|
+
```
|
|
54
|
+
|
|
40
55
|
```ts
|
|
41
56
|
import '@groupviz/react/theme.css' // 主题样式(模块化工程可 import 到全局)
|
|
42
57
|
```
|
|
43
58
|
|
|
59
|
+
**三个常见坑,本版已修**
|
|
60
|
+
|
|
61
|
+
- **元素引用**:`actionElementId` / `actions[].elementId` / `CosetStripScene.subgroup` 等元素类 props
|
|
62
|
+
**同时接受 `id`(`"1,3,4,2"`)与 `label`(`"34"`)**;解析不到会 `console.warn` 一次并忽略该项,
|
|
63
|
+
不再「动画不动、相机还被锁死」的静默失败。
|
|
64
|
+
- **主题**:全部 10 个 Scene 统一支持 `theme?: 'dark' | 'light'`(含 2D 视图;不传则跟随外层主题);
|
|
65
|
+
`SymmetryViewScene` 的 `dark` 保留为兼容别名。
|
|
66
|
+
- **文案**:漏包 `I18nProvider` 不再整屏回落成 key。
|
|
67
|
+
|
|
44
68
|
**交互约定**:Scene 是纯受控内核——标签显隐 / hover 气泡 / 选中高亮等由宿主通过 props
|
|
45
|
-
(`showLabels` / `onHover` / `onSelect
|
|
69
|
+
(`showLabels` / `onHover` / `onSelect`)注入。
|
|
70
|
+
|
|
71
|
+
**完整 props 全表**:见包内 [API.md](./API.md)(10 个 Scene 逐项 + 便利层 + core 新增导出);
|
|
72
|
+
更多组合示例见仓库 `examples/host-minimal/`。
|
|
73
|
+
|
|
74
|
+
**稳定性**:当前公开 API 为 2.x——破坏性变更才会升 major(core 与 react 成对同版发布,react peer 锁 core `^2.x`),
|
|
75
|
+
非破坏性演进在 minor/patch 内进行;变更记录见 [GroupViz CHANGELOG](https://github.com/rrCathy/GroupViz/blob/main/docs/CHANGELOG.md)。
|
|
46
76
|
|
|
47
|
-
|
|
77
|
+
**来源**:本包由 GroupViz 主仓库 `src/package/` 门面构建发布(单仓库内子目录产出,非 monorepo),
|
|
78
|
+
完整组件 / 交互文档:[GroupViz 主仓库](https://github.com/rrCathy/GroupViz)(docs/VIEWS.md · docs/PRESENTATION.md)。
|
|
48
79
|
MIT License。
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SceneTheme } from './SceneThemeRoot.js';
|
|
1
2
|
import type { Group, GroupActionArrow, GroupActionComputation, GroupActionKind, GroupElement, CanvasTransform } from '@groupviz/core';
|
|
2
3
|
import { type CustomArrowError } from '@groupviz/core';
|
|
3
4
|
export interface ActionSceneProps {
|
|
@@ -42,5 +43,8 @@ export interface ActionSceneProps {
|
|
|
42
43
|
};
|
|
43
44
|
/** sylow 作用的素数(banner 标题用);窗口不传 */
|
|
44
45
|
prime?: number | null;
|
|
46
|
+
/** 视图主题作用域(`'dark' | 'light'`)。缺省不注入、跟随外层主题;显式传值时在本子树内
|
|
47
|
+
* 应用 `theme.css` 对应变量块(需宿主已 `import '@groupviz/react/theme.css'`) */
|
|
48
|
+
theme?: SceneTheme;
|
|
45
49
|
}
|
|
46
|
-
export declare function ActionScene(
|
|
50
|
+
export declare function ActionScene(props: ActionSceneProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Group, MultiplyType, Layout3D } from '@groupviz/core';
|
|
2
|
-
import type { CayleyActionParam } from '@groupviz/core';
|
|
2
|
+
import type { CayleyActionParam, Cayley3DFaceFillParams } from '@groupviz/core';
|
|
3
3
|
export interface Cayley3DSceneProps {
|
|
4
4
|
/** 群;null → .view-empty 占位 */
|
|
5
5
|
group: Group | null;
|
|
@@ -29,6 +29,9 @@ export interface Cayley3DSceneProps {
|
|
|
29
29
|
/** 渲染主题(canvas 背景 / label 阴影)。缺省回落到 ThemeContext(无 Provider 时 'dark');
|
|
30
30
|
* 主应用壳不传即保持现状(读全局主题),包消费端显式传以与容器主题解耦 */
|
|
31
31
|
theme?: 'dark' | 'light';
|
|
32
|
+
/** 子群陪集面填充(面 = 某真子群单个陪集在布局中占满的平面凸多边形)。
|
|
33
|
+
* 作者在 ⚙ 面板选择子群 H 后,几何上成面的陪集以半透明多边形显示,可逐面指定颜色 */
|
|
34
|
+
faceFill?: Cayley3DFaceFillParams;
|
|
32
35
|
}
|
|
33
36
|
/** 受控 3D 凯莱图(props 驱动;ViewWindow 与测试用)。空群渲染占位,非空渲染 R3F 场景。 */
|
|
34
37
|
export declare function Cayley3DScene(props: Cayley3DSceneProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SceneTheme } from './SceneThemeRoot.js';
|
|
1
2
|
import type { CanvasTransform, CayleyShape2D, Group, GroupElement, MultiplyType } from '@groupviz/core';
|
|
2
3
|
import type { CayleyActionParam } from '@groupviz/core';
|
|
3
4
|
export interface CayleyViewProps {
|
|
@@ -32,5 +33,10 @@ export interface CayleyViewProps {
|
|
|
32
33
|
/** 当前悬停元素 id;用于在该节点外圈绘制高亮环(让"悬停→信息"在视觉上立得住) */
|
|
33
34
|
hoveredElementId?: string | null;
|
|
34
35
|
noGroupText?: string;
|
|
36
|
+
/** 节点标签自适应阈值:`group.order > 该值` 时仅选中节点显示常驻标签;缺省 60(主画布规则) */
|
|
37
|
+
largeGroupThreshold?: number;
|
|
38
|
+
/** 视图主题作用域(`'dark' | 'light'`)。缺省不注入、跟随外层主题;显式传值时在本子树内
|
|
39
|
+
* 应用 `theme.css` 对应变量块(需宿主已 `import '@groupviz/react/theme.css'`) */
|
|
40
|
+
theme?: SceneTheme;
|
|
35
41
|
}
|
|
36
|
-
export declare function CayleyView(
|
|
42
|
+
export declare function CayleyView(props: CayleyViewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SceneTheme } from './SceneThemeRoot.js';
|
|
1
2
|
import type { Group, GroupElement } from '@groupviz/core';
|
|
2
3
|
export interface CosetStripSceneProps {
|
|
3
4
|
group: Group | null;
|
|
@@ -37,5 +38,16 @@ export interface CosetStripSceneProps {
|
|
|
37
38
|
/** 有群但无陪集数据时的文案(缺省 i18n canvas.cosetStripNoCosets,主应用语境);
|
|
38
39
|
* 窗口引擎可传自定义提示(如本地枚举上限) */
|
|
39
40
|
noCosetsText?: string;
|
|
41
|
+
/** **便捷入口**:给定子群 H(元素引用数组,`id` 或 `label` 皆可),内部经
|
|
42
|
+
* `@groupviz/core` 的 `buildCosetViewData` 自动派生 `cosetElementMap` /
|
|
43
|
+
* `cosetColors` / `cosetHighlightSet`。与显式传三件套二选一——显式传入者优先。 */
|
|
44
|
+
subgroup?: string[] | null;
|
|
45
|
+
/** 便捷入口配套:左 / 右陪集族;缺省 `'left'` */
|
|
46
|
+
cosetType?: 'left' | 'right';
|
|
47
|
+
/** 便捷入口配套:是否高亮全部陪集;缺省 `false`(仅高亮含选中元素的陪集) */
|
|
48
|
+
highlightAllCosets?: boolean;
|
|
49
|
+
/** 视图主题作用域(`'dark' | 'light'`)。缺省不注入、跟随外层主题;显式传值时在本子树内
|
|
50
|
+
* 应用 `theme.css` 对应变量块(需宿主已 `import '@groupviz/react/theme.css'`) */
|
|
51
|
+
theme?: SceneTheme;
|
|
40
52
|
}
|
|
41
|
-
export declare function CosetStripScene(
|
|
53
|
+
export declare function CosetStripScene(props: CosetStripSceneProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SceneTheme } from './SceneThemeRoot.js';
|
|
1
2
|
import type { CanvasTransform, Group, GroupElement, NodePosition } from '@groupviz/core';
|
|
2
3
|
export interface CycleViewProps {
|
|
3
4
|
group: Group | null;
|
|
@@ -36,5 +37,10 @@ export interface CycleViewProps {
|
|
|
36
37
|
y: number;
|
|
37
38
|
} | null) => void;
|
|
38
39
|
noGroupText?: string;
|
|
40
|
+
/** 节点标签自适应阈值:`group.order > 该值` 时仅选中节点显示常驻标签;缺省 60(主画布规则) */
|
|
41
|
+
largeGroupThreshold?: number;
|
|
42
|
+
/** 视图主题作用域(`'dark' | 'light'`)。缺省不注入、跟随外层主题;显式传值时在本子树内
|
|
43
|
+
* 应用 `theme.css` 对应变量块(需宿主已 `import '@groupviz/react/theme.css'`) */
|
|
44
|
+
theme?: SceneTheme;
|
|
39
45
|
}
|
|
40
|
-
export declare function CycleView(
|
|
46
|
+
export declare function CycleView(props: CycleViewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
+
import { type SceneTheme } from './SceneThemeRoot.js';
|
|
2
3
|
import type { Group, GroupElement, HomomorphismResult } from '@groupviz/core';
|
|
3
4
|
export interface HomomorphismSceneProps {
|
|
4
5
|
source: Group | null;
|
|
@@ -20,5 +21,8 @@ export interface HomomorphismSceneProps {
|
|
|
20
21
|
x: number;
|
|
21
22
|
y: number;
|
|
22
23
|
} | null) => void;
|
|
24
|
+
/** 视图主题作用域(`'dark' | 'light'`)。缺省不注入、跟随外层主题;显式传值时在本子树内
|
|
25
|
+
* 应用 `theme.css` 对应变量块(需宿主已 `import '@groupviz/react/theme.css'`) */
|
|
26
|
+
theme?: SceneTheme;
|
|
23
27
|
}
|
|
24
|
-
export declare function HomomorphismScene(
|
|
28
|
+
export declare function HomomorphismScene(props: HomomorphismSceneProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Group, GroupElement } from '@groupviz/core';
|
|
2
|
+
/**
|
|
3
|
+
* SceneHoverBubble —— 悬停就地气泡(默认实现)。
|
|
4
|
+
*
|
|
5
|
+
* 配合 `useSceneState().hoverBubble` 使用;也可在自建宿主里独立渲染。
|
|
6
|
+
* 配色读 `theme.css` 的自定义属性(经 `data-theme` 作用域),因此天然跟随视图主题,
|
|
7
|
+
* 不写死颜色;未引入 `theme.css` 时由内联兜底色保证可读。
|
|
8
|
+
*
|
|
9
|
+
* 定位:`anchor` 是元素在容器内的屏幕坐标(Scene 的 `onHover` 第二参),
|
|
10
|
+
* 气泡默认浮在锚点正上方居中。`anchor` 为空(如表格视图不提供锚点)时不渲染。
|
|
11
|
+
*/
|
|
12
|
+
export interface SceneHoverBubbleProps {
|
|
13
|
+
element: GroupElement | null;
|
|
14
|
+
anchor?: {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
} | null;
|
|
18
|
+
/** 缺省 `'dark'`(与 `theme.css` 默认块一致) */
|
|
19
|
+
theme?: 'dark' | 'light';
|
|
20
|
+
/** 传入则在气泡里补一行「阶 = n」(元素阶是排名第一的高频信息) */
|
|
21
|
+
group?: Group | null;
|
|
22
|
+
/** 相对锚点的额外偏移;缺省 `{ x: 0, y: -14 }` */
|
|
23
|
+
offset?: {
|
|
24
|
+
x: number;
|
|
25
|
+
y: number;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export declare function SceneHoverBubble({ element, anchor, theme, group, offset, }: SceneHoverBubbleProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* SceneThemeRoot —— 视图主题作用域(FGVE「主题统一」)。
|
|
4
|
+
*
|
|
5
|
+
* 问题:主应用把主题做成**全局 CSS 变量**(`src/index.css` 的 `:root` /
|
|
6
|
+
* `[data-theme="light"]`);`@groupviz/react` 里 3D 系 Scene 各自带 `theme` prop,
|
|
7
|
+
* 而全部 2D Scene 没有——外部嵌入想「单独把某张图切成浅色」只能靠外层 div 隐式挂
|
|
8
|
+
* `data-theme`,且各视图行为不一致(`dark` / `theme` / 无)。
|
|
9
|
+
*
|
|
10
|
+
* 方案:2D Scene 统一新增 `theme?: 'dark' | 'light'`,内部用本组件包一层。
|
|
11
|
+
* **缺省不传 → 直接渲染 children(零额外 DOM)**,完全保留「跟随外层主题」的既有行为,
|
|
12
|
+
* 因此主应用与既有宿主不受影响;显式传值时才注入 `data-theme` 作用域,
|
|
13
|
+
* 让 `theme.css` 里的浅/深色变量块在该子树内生效。
|
|
14
|
+
*/
|
|
15
|
+
export type SceneTheme = 'dark' | 'light';
|
|
16
|
+
export interface SceneThemeRootProps {
|
|
17
|
+
/** 缺省 `undefined`(不注入作用域,继承外层主题) */
|
|
18
|
+
theme?: SceneTheme;
|
|
19
|
+
children: ReactNode;
|
|
20
|
+
/** 附加样式(与内建 `width/height:100%` 合并,内建在前) */
|
|
21
|
+
style?: CSSProperties;
|
|
22
|
+
className?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function SceneThemeRoot({ theme, children, style, className }: SceneThemeRootProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SceneTheme } from './SceneThemeRoot.js';
|
|
1
2
|
import type { Group } from '@groupviz/core';
|
|
2
3
|
export interface SetViewProps {
|
|
3
4
|
group: Group | null;
|
|
@@ -29,5 +30,10 @@ export interface SetViewProps {
|
|
|
29
30
|
gap?: number;
|
|
30
31
|
columns?: number;
|
|
31
32
|
showLabels?: boolean;
|
|
33
|
+
/** 节点标签自适应阈值:`group.order > 该值` 时仅选中节点显示常驻标签;缺省 60(主画布规则) */
|
|
34
|
+
largeGroupThreshold?: number;
|
|
35
|
+
/** 视图主题作用域(`'dark' | 'light'`)。缺省不注入、跟随外层主题;显式传值时在本子树内
|
|
36
|
+
* 应用 `theme.css` 对应变量块(需宿主已 `import '@groupviz/react/theme.css'`) */
|
|
37
|
+
theme?: SceneTheme;
|
|
32
38
|
}
|
|
33
|
-
export declare function SetView(
|
|
39
|
+
export declare function SetView(props: SetViewProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -45,6 +45,9 @@ export interface SublatticeSceneProps {
|
|
|
45
45
|
/** 渲染主题(格取色 palette)。缺省回落到 ThemeContext(无 Provider 时 'dark');
|
|
46
46
|
* 主应用壳不传即保持现状(读全局主题),包消费端显式传以与容器主题解耦 */
|
|
47
47
|
theme?: 'dark' | 'light';
|
|
48
|
+
/** 本地枚举子群格的群阶上限(`order > 该值` 且未显式传 `lattice` 时不枚举、渲染空态);
|
|
49
|
+
* 缺省 60(与 `findAllSubgroups` 内建守卫一致)。放开需自行确认性能与后端通路 */
|
|
50
|
+
maxEnumerateOrder?: number;
|
|
48
51
|
}
|
|
49
52
|
interface SeriesPanelProps {
|
|
50
53
|
group: Group;
|
|
@@ -66,5 +69,5 @@ export declare function SeriesPanel({ group, series, color, theme: themeProp }:
|
|
|
66
69
|
* 3. 省掉的文字不丢——底部 caption 行按 hover ?? 选中给出完整名片;密度真的高时
|
|
67
70
|
* 用 `mergeConjugates` 把共轭子群合成一个轨道节点(×n,n = |G : N_G(H)|)。
|
|
68
71
|
*/
|
|
69
|
-
export declare function SublatticeScene({ group, lattice, canvasTransform, availableSize, labelDetail, mergeConjugates, nodeScale, showSeriesPanel, series, centerIds, subsets, activeNodeIdx: activeNodeIdxProp, onActivateNode, noGroupText, theme: themeProp, }: SublatticeSceneProps): import("react/jsx-runtime").JSX.Element;
|
|
72
|
+
export declare function SublatticeScene({ group, lattice, canvasTransform, availableSize, labelDetail, mergeConjugates, nodeScale, showSeriesPanel, series, centerIds, subsets, activeNodeIdx: activeNodeIdxProp, onActivateNode, noGroupText, theme: themeProp, maxEnumerateOrder, }: SublatticeSceneProps): import("react/jsx-runtime").JSX.Element;
|
|
70
73
|
export {};
|