yangdx commited on
Commit
68d8046
·
1 Parent(s): 66ba24d

Map node type to fix color

Browse files
lightrag_webui/src/hooks/useLightragGraph.tsx CHANGED
@@ -11,112 +11,148 @@ import { useSettingsStore } from '@/stores/settings'
11
 
12
  import seedrandom from 'seedrandom'
13
 
14
- // Predefined node colors - Primary colors
15
- const NODE_COLORS = [
16
- '#fdd868', // Yellow - UNKNOWN
17
- '#e3493b', // Google Red - geo
18
- '#1212a1', // Deep Cyan - weapon
19
- '#0f705d', // Green - organization
20
- '#b300b3', // Purple - technology
21
- '#f46a9b', // Magenta
22
- '#bd7ebe', // Light Violet
23
- '#fdcce5', // Pale Pink - category
24
- '#0f558a', // Blue - location
25
- '#b2e061', // Yellow Green
26
- '#00bfa0', // Turquoise - event
27
- '#439bd6', // Cyan - person
28
- '#094338', // Deep Green
29
- '#5a2c6d', // Deep Violet
30
- '#fd7f6f', // Light Brown - location
31
- '#adc2eb', // Sky Blue - animal
32
- ];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
- // Extended colors - Used when node types exceed primary colors
35
  const EXTENDED_COLORS = [
36
- '#742b25', // Dark Brown
37
- '#9efacc', // Light Green
38
- '#ffbf80', // Light Brown
39
- '#003366', // Dark Blue
40
- '#996600', // Yellow Brown
41
- '#4421af', // Deep Purple
42
- '#cf6d17', // Carrot
43
- '#ff1a1a', // Pure Red
 
 
 
 
44
  ];
45
 
46
- // All available colors combined
47
- const ALL_COLORS = [...NODE_COLORS, ...EXTENDED_COLORS];
48
-
49
- // Helper function to get color based on node type
50
  const getNodeColorByType = (nodeType: string | undefined): string => {
51
- const defaultColor = '#5D6D7E'; // Default color for nodes without a type or undefined type
52
-
53
- // Return default color if node type is undefined
54
- if (!nodeType) {
55
- return defaultColor;
56
- }
57
 
58
- // Get type color map from store
59
  const typeColorMap = useGraphStore.getState().typeColorMap;
60
 
61
- // If this type already has an assigned color, return it
62
- if (typeColorMap.has(nodeType)) {
63
- return typeColorMap.get(nodeType) || defaultColor;
64
  }
65
 
66
- // Get all currently used colors
67
- const usedColors = new Set<string>();
68
- typeColorMap.forEach(color => {
69
- usedColors.add(color);
70
- });
71
-
72
- // Assign color for new node type
73
- // Use a simple hash function to map node type to color index
74
- const getColorIndex = (str: string): number => {
75
- let hash = 0;
76
- for (let i = 0; i < str.length; i++) {
77
- hash = ((hash << 5) - hash) + str.charCodeAt(i);
78
- hash |= 0; // Convert to 32bit integer
79
- }
80
- // Ensure result is positive and within NODE_COLORS range only
81
- return Math.abs(hash) % NODE_COLORS.length;
82
- };
83
-
84
- // Get initial color index from hash
85
- const colorIndex = getColorIndex(nodeType);
86
- let newColor = NODE_COLORS[colorIndex];
87
-
88
- // If the color is already used, find the next available color
89
- if (usedColors.has(newColor) && usedColors.size < ALL_COLORS.length) {
90
- // First try to find an unused color in NODE_COLORS
91
- let foundUnused = false;
92
- for (let i = 0; i < NODE_COLORS.length; i++) {
93
- const candidateColor = NODE_COLORS[i];
94
- if (!usedColors.has(candidateColor)) {
95
- newColor = candidateColor;
96
- foundUnused = true;
97
- break;
98
- }
99
- }
100
-
101
- // If all NODE_COLORS are used, then try EXTENDED_COLORS
102
- if (!foundUnused) {
103
- newColor = defaultColor;
104
- for (let i = 0; i < EXTENDED_COLORS.length; i++) {
105
- const candidateColor = EXTENDED_COLORS[i];
106
- if (!usedColors.has(candidateColor)) {
107
- newColor = candidateColor;
108
- break;
109
- }
110
- }
111
- }
112
  }
113
 
114
- // If all colors are used, we'll still use the hashed color
115
- // In a more advanced implementation, we could create color variants here
116
-
 
 
 
 
 
 
 
 
 
117
  // Update color mapping
118
  const newMap = new Map(typeColorMap);
119
- newMap.set(nodeType, newColor);
120
  useGraphStore.setState({ typeColorMap: newMap });
121
 
122
  return newColor;
 
11
 
12
  import seedrandom from 'seedrandom'
13
 
14
+ // 同义词列表 - 用于快速查找节点类型
15
+ const TYPE_SYNONYMS: Record<string, string> = {
16
+ // unknown 类型及其同义词
17
+ 'unknown': 'unknown',
18
+ '未知': 'unknown',
19
+ 'other': 'unknown',
20
+
21
+ // category 类型及其同义词
22
+ 'category': 'category',
23
+ '类别': 'category',
24
+ 'type': 'category',
25
+ '分类': 'category',
26
+
27
+ // organization 类型及其同义词
28
+ 'organization': 'organization',
29
+ '组织': 'organization',
30
+ 'org': 'organization',
31
+ 'company': 'organization',
32
+ '公司': 'organization',
33
+ '机构': 'organization',
34
+
35
+ // event 类型及其同义词
36
+ 'event': 'event',
37
+ '事件': 'event',
38
+ 'activity': 'event',
39
+ '活动': 'event',
40
+
41
+ // person 类型及其同义词
42
+ 'person': 'person',
43
+ '人物': 'person',
44
+ 'people': 'person',
45
+ 'human': 'person',
46
+ '人': 'person',
47
+
48
+ // animal 类型及其同义词
49
+ 'animal': 'animal',
50
+ '动物': 'animal',
51
+ 'creature': 'animal',
52
+ '生物': 'animal',
53
+
54
+ // geo 类型及其同义词
55
+ 'geo': 'geo',
56
+ '地理': 'geo',
57
+ 'geography': 'geo',
58
+ '地域': 'geo',
59
+
60
+ // location 类型及其同义词
61
+ 'location': 'location',
62
+ '地点': 'location',
63
+ 'place': 'location',
64
+ 'address': 'location',
65
+ '位置': 'location',
66
+ '地址': 'location',
67
+
68
+ // technology 类型及其同义词
69
+ 'technology': 'technology',
70
+ '技术': 'technology',
71
+ 'tech': 'technology',
72
+ '科技': 'technology',
73
+
74
+ // equipment 类型及其同义词
75
+ 'equipment': 'equipment',
76
+ '设备': 'equipment',
77
+ 'device': 'equipment',
78
+ '装备': 'equipment',
79
+
80
+ // weapon 类型及其同义词
81
+ 'weapon': 'weapon',
82
+ '武器': 'weapon',
83
+ 'arms': 'weapon',
84
+ '军火': 'weapon'
85
+ };
86
+
87
+ // 节点类型到颜色的映射
88
+ const NODE_TYPE_COLORS: Record<string, string> = {
89
+ 'unknown': '#f4d371', // Yellow
90
+ 'category': '#e3493b', // GoogleRed
91
+ 'organization': '#0f705d', // Green
92
+ 'event': '#00bfa0', // Turquoise
93
+ 'person': '#4169E1', // RoyalBlue
94
+ 'animal': '#84a3e1', // SkyBlue
95
+ 'geo': '#ff99cc', // Pale Pink
96
+ 'location': '#cf6d17', // Carrot
97
+ 'technology': '#b300b3', // Purple
98
+ 'equipment': '#2F4F4F', // DarkSlateGray
99
+ 'weapon': '#0f558a', // NavyBlue
100
+ };
101
 
102
+ // Extended colors pool - Used for unknown node types
103
  const EXTENDED_COLORS = [
104
+ '#4421af', // DeepPurple
105
+ '#cd071e', // ChinaRed
106
+ '#5a2c6d', // DeepViolet
107
+ '#0000ff', // Blue
108
+ '#00cc00', // Green
109
+ '#9b3a31', // DarkBrown
110
+ '#003366', // DarkBlue
111
+ '#00CED1', // DarkTurquoise
112
+ '#DEB887', // BurlyWood
113
+ '#bd7ebe', // LightViolet
114
+ '#b2e061', // YellowGreen
115
+ '#6ef7b3', // LightGreen
116
  ];
117
 
118
+ // Select color based on node type
 
 
 
119
  const getNodeColorByType = (nodeType: string | undefined): string => {
120
+
121
+ const defaultColor = '#5D6D7E';
 
 
 
 
122
 
123
+ const normalizedType = nodeType ? nodeType.toLowerCase() : 'unknown';
124
  const typeColorMap = useGraphStore.getState().typeColorMap;
125
 
126
+ // Return previous color if already mapped
127
+ if (typeColorMap.has(normalizedType)) {
128
+ return typeColorMap.get(normalizedType) || defaultColor;
129
  }
130
 
131
+ const standardType = TYPE_SYNONYMS[normalizedType];
132
+ if (standardType) {
133
+ const color = NODE_TYPE_COLORS[standardType];
134
+ // Update color mapping
135
+ const newMap = new Map(typeColorMap);
136
+ newMap.set(normalizedType, color);
137
+ useGraphStore.setState({ typeColorMap: newMap });
138
+ return color;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
 
141
+ // For unpredefind nodeTypes, use extended colors
142
+ // Find used extended colors
143
+ const usedExtendedColors = new Set(
144
+ Array.from(typeColorMap.entries())
145
+ .filter(([, color]) => !Object.values(NODE_TYPE_COLORS).includes(color))
146
+ .map(([, color]) => color)
147
+ );
148
+
149
+ // Find and use the first unused extended color
150
+ const unusedColor = EXTENDED_COLORS.find(color => !usedExtendedColors.has(color));
151
+ const newColor = unusedColor || defaultColor;
152
+
153
  // Update color mapping
154
  const newMap = new Map(typeColorMap);
155
+ newMap.set(normalizedType, newColor);
156
  useGraphStore.setState({ typeColorMap: newMap });
157
 
158
  return newColor;