| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- <template>
- <div data-theme="dark" class="flex flex-col h-screen">
- <!-- 顶部栏 -->
- <header class="navbar bg-base-200 min-h-0 px-4 py-2 shrink-0">
- <h1 class="text-sm font-medium text-primary">人设图谱</h1>
- <!-- Tab 切换 -->
- <div class="tabs tabs-boxed ml-4 bg-base-300">
- <a
- class="tab tab-sm"
- :class="{ 'tab-active': activeTab === 'persona' }"
- @click="activeTab = 'persona'"
- >人设图谱</a>
- <a
- class="tab tab-sm"
- :class="{ 'tab-active': activeTab === 'match' }"
- @click="activeTab = 'match'"
- >帖子匹配</a>
- </div>
- <!-- 节点颜色图例 -->
- <div class="flex gap-3 text-xs text-base-content/60 ml-6 border-l border-base-content/20 pl-4">
- <span class="text-base-content font-medium">节点颜色:</span>
- <div class="flex items-center gap-1">
- <span class="w-2.5 h-2.5 rounded-full bg-dim-persona"></span>人设
- </div>
- <div class="flex items-center gap-1">
- <span class="w-2.5 h-2.5 rounded-full bg-dim-inspiration"></span>灵感点
- </div>
- <div class="flex items-center gap-1">
- <span class="w-2.5 h-2.5 rounded-full bg-dim-purpose"></span>目的点
- </div>
- <div class="flex items-center gap-1">
- <span class="w-2.5 h-2.5 rounded-full bg-dim-key"></span>关键点
- </div>
- </div>
- <!-- 节点形状图例 -->
- <div class="flex gap-3 text-xs text-base-content/60 ml-4 border-l border-base-content/20 pl-4">
- <span class="text-base-content font-medium">节点形状:</span>
- <div class="flex items-center gap-1">○ 标签</div>
- <div class="flex items-center gap-1">□ 分类/点</div>
- </div>
- <!-- 边类型图例 -->
- <div class="flex gap-3 text-xs text-base-content/60 ml-4 border-l border-base-content/20 pl-4">
- <span class="text-base-content font-medium">边:</span>
- <div v-for="(color, type) in edgeTypesWithColors" :key="type" class="flex items-center gap-1">
- <span class="w-4 h-0.5" :style="{ backgroundColor: color }"></span>
- <span>{{ type }}</span>
- </div>
- </div>
- </header>
- <!-- 主内容区 - 人设图谱 Tab -->
- <main v-show="activeTab === 'persona'" class="flex flex-1 overflow-hidden">
- <TreeView class="w-[420px] shrink-0 bg-base-200 border-r border-base-300" />
- <GraphView class="flex-1" />
- </main>
- <!-- 主内容区 - 帖子匹配 Tab -->
- <main v-show="activeTab === 'match'" class="flex flex-1 overflow-hidden">
- <TreeView class="w-[320px] shrink-0 bg-base-200 border-r border-base-300" />
- <GraphView class="flex-1 min-w-[300px]" />
- <PostTreeView class="w-[360px] shrink-0 bg-base-200 border-l border-base-300" />
- </main>
- <!-- 详情面板 -->
- <DetailPanel />
- </div>
- </template>
- <script setup>
- import { ref, computed } from 'vue'
- import TreeView from './components/TreeView.vue'
- import GraphView from './components/GraphView.vue'
- import PostTreeView from './components/PostTreeView.vue'
- import DetailPanel from './components/DetailPanel.vue'
- import { useGraphStore } from './stores/graph'
- const store = useGraphStore()
- // 当前激活的 Tab
- const activeTab = ref('persona')
- // 边类型颜色调色板
- const edgeColorPalette = ['#9b59b6', '#3498db', '#2ecc71', '#f39c12', '#e74c3c', '#1abc9c']
- // 从数据中动态获取边类型及对应颜色
- const edgeTypesWithColors = computed(() => {
- const types = new Set()
- const edges = store.graphData.edges || {}
- for (const edge of Object.values(edges)) {
- if (edge.type) types.add(edge.type)
- }
- const result = {}
- Array.from(types).forEach((t, i) => {
- result[t] = edgeColorPalette[i % edgeColorPalette.length]
- })
- return result
- })
- </script>
|