OntologyCanvas.tsx
2.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import { useEffect, useState } from 'react'
import { Spin, Alert, Button, Typography } from 'antd'
import { ReloadOutlined } from '@ant-design/icons'
import { loadOntology } from '../ontology/build'
import type { Ontology } from '../ontology/types'
import NetworkGraph from './NetworkGraph'
import ERDiagram from './ERDiagram'
import ProcessDiagram from './ProcessDiagram'
const { Title, Text } = Typography
const META: Record<string, { title: string; desc: string }> = {
network: { title: '本体网络图', desc: '对象 + 行为 + 规则 + 事件的关联网络(M1/M2/ME/MetaRule 动态合成)' },
er: { title: '数据结构图(ER)', desc: '聚合根/子实体的字段结构、外键引用与组合关系(M1 动态合成)' },
process: { title: '场景流程图(BPMN)', desc: '端到端场景流程(M4 flowSteps → bpmn-elk-layout 自动布局 → bpmn-js 渲染)' },
}
/** 可视化画布宿主:加载一次本体 IR,全高渲染选中的视图。 */
export function OntologyCanvas({ which }: { which: 'network' | 'er' | 'process' }) {
const [onto, setOnto] = useState<Ontology | null>(null)
const [err, setErr] = useState('')
const [key, setKey] = useState(0)
useEffect(() => {
setOnto(null); setErr('')
loadOntology().then(setOnto).catch((e) => setErr(String(e?.message || e)))
}, [key])
const m = META[which]
return (
<div style={{ padding: 16 }}>
<div style={{ display: 'flex', alignItems: 'center', marginBottom: 10 }}>
<div>
<Title level={4} style={{ margin: 0 }}>{m.title}</Title>
<Text type="secondary" style={{ fontSize: 13 }}>{m.desc}</Text>
</div>
<div style={{ flex: 1 }} />
<Button icon={<ReloadOutlined />} onClick={() => setKey((k) => k + 1)}>刷新</Button>
</div>
<div style={{ position: 'relative', height: 'calc(100vh - 190px)', minHeight: 420, border: '1px solid #f0f0f0', borderRadius: 10, background: '#fff', overflow: 'hidden' }}>
{err ? (
<div style={{ padding: 24 }}><Alert type="error" showIcon message="加载本体失败" description={err} /></div>
) : !onto ? (
<div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}><Spin tip="合成本体视图…"><div style={{ width: 80, height: 40 }} /></Spin></div>
) : which === 'network' ? (
<NetworkGraph ontology={onto} />
) : which === 'er' ? (
<ERDiagram ontology={onto} />
) : (
<ProcessDiagram ontology={onto} />
)}
</div>
</div>
)
}