App.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <template>
  2. <div data-theme="dark" class="flex flex-col h-screen">
  3. <!-- 顶部栏 -->
  4. <header class="navbar bg-base-200 min-h-0 px-4 py-2 shrink-0">
  5. <h1 class="text-sm font-medium text-primary">人设图谱</h1>
  6. <!-- Tab 切换 -->
  7. <div class="tabs tabs-boxed ml-4 bg-base-300">
  8. <a
  9. class="tab tab-sm"
  10. :class="{ 'tab-active': activeTab === 'persona' }"
  11. @click="activeTab = 'persona'"
  12. >人设图谱</a>
  13. <a
  14. class="tab tab-sm"
  15. :class="{ 'tab-active': activeTab === 'match' }"
  16. @click="activeTab = 'match'"
  17. >帖子匹配</a>
  18. </div>
  19. <!-- 节点颜色图例 -->
  20. <div class="flex gap-3 text-xs text-base-content/60 ml-6 border-l border-base-content/20 pl-4">
  21. <span class="text-base-content font-medium">节点颜色:</span>
  22. <div class="flex items-center gap-1">
  23. <span class="w-2.5 h-2.5 rounded-full bg-dim-persona"></span>人设
  24. </div>
  25. <div class="flex items-center gap-1">
  26. <span class="w-2.5 h-2.5 rounded-full bg-dim-inspiration"></span>灵感点
  27. </div>
  28. <div class="flex items-center gap-1">
  29. <span class="w-2.5 h-2.5 rounded-full bg-dim-purpose"></span>目的点
  30. </div>
  31. <div class="flex items-center gap-1">
  32. <span class="w-2.5 h-2.5 rounded-full bg-dim-key"></span>关键点
  33. </div>
  34. </div>
  35. <!-- 节点形状图例 -->
  36. <div class="flex gap-3 text-xs text-base-content/60 ml-4 border-l border-base-content/20 pl-4">
  37. <span class="text-base-content font-medium">节点形状:</span>
  38. <div class="flex items-center gap-1">○ 标签</div>
  39. <div class="flex items-center gap-1">□ 分类/点</div>
  40. </div>
  41. <!-- 边类型图例 -->
  42. <div class="flex gap-3 text-xs text-base-content/60 ml-4 border-l border-base-content/20 pl-4">
  43. <span class="text-base-content font-medium">边:</span>
  44. <div v-for="(color, type) in edgeTypesWithColors" :key="type" class="flex items-center gap-1">
  45. <span class="w-4 h-0.5" :style="{ backgroundColor: color }"></span>
  46. <span>{{ type }}</span>
  47. </div>
  48. </div>
  49. </header>
  50. <!-- 主内容区 - 人设图谱 Tab -->
  51. <main v-show="activeTab === 'persona'" class="flex flex-1 overflow-hidden">
  52. <TreeView class="w-[420px] shrink-0 bg-base-200 border-r border-base-300" />
  53. <GraphView class="flex-1" />
  54. </main>
  55. <!-- 主内容区 - 帖子匹配 Tab -->
  56. <main v-show="activeTab === 'match'" class="flex flex-1 overflow-hidden">
  57. <TreeView class="w-[320px] shrink-0 bg-base-200 border-r border-base-300" />
  58. <GraphView class="flex-1 min-w-[300px]" />
  59. <PostTreeView class="w-[360px] shrink-0 bg-base-200 border-l border-base-300" />
  60. </main>
  61. <!-- 详情面板 -->
  62. <DetailPanel />
  63. </div>
  64. </template>
  65. <script setup>
  66. import { ref, computed } from 'vue'
  67. import TreeView from './components/TreeView.vue'
  68. import GraphView from './components/GraphView.vue'
  69. import PostTreeView from './components/PostTreeView.vue'
  70. import DetailPanel from './components/DetailPanel.vue'
  71. import { useGraphStore } from './stores/graph'
  72. const store = useGraphStore()
  73. // 当前激活的 Tab
  74. const activeTab = ref('persona')
  75. // 边类型颜色调色板
  76. const edgeColorPalette = ['#9b59b6', '#3498db', '#2ecc71', '#f39c12', '#e74c3c', '#1abc9c']
  77. // 从数据中动态获取边类型及对应颜色
  78. const edgeTypesWithColors = computed(() => {
  79. const types = new Set()
  80. const edges = store.graphData.edges || {}
  81. for (const edge of Object.values(edges)) {
  82. if (edge.type) types.add(edge.type)
  83. }
  84. const result = {}
  85. Array.from(types).forEach((t, i) => {
  86. result[t] = edgeColorPalette[i % edgeColorPalette.length]
  87. })
  88. return result
  89. })
  90. </script>