choizhang commited on
Commit
cba1d17
·
1 Parent(s): c903e60

refactor(useLightragGraph): Optimize node color generation logic

Browse files
lightrag_webui/src/hooks/useLightragGraph.tsx CHANGED
@@ -11,6 +11,26 @@ import { useSettingsStore } from '@/stores/settings'
11
 
12
  import seedrandom from 'seedrandom'
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  const validateGraph = (graph: RawGraph) => {
15
  // Check if graph exists
16
  if (!graph) {
@@ -106,9 +126,6 @@ const fetchGraph = async (label: string, maxDepth: number, minDegree: number) =>
106
  const node = rawData.nodes[i]
107
  nodeIdMap[node.id] = i
108
 
109
- // const seed = node.labels.length > 0 ? node.labels[0] : node.id
110
- seedrandom(node.id, { global: true })
111
- node.color = randomColor()
112
  node.x = Math.random()
113
  node.y = Math.random()
114
  node.degree = 0
@@ -223,6 +240,9 @@ const useLightrangeGraph = () => {
223
  const nodeToExpand = useGraphStore.use.nodeToExpand()
224
  const nodeToPrune = useGraphStore.use.nodeToPrune()
225
 
 
 
 
226
  // Use ref to track if data has been loaded and initial load
227
  const dataLoadedRef = useRef(false)
228
  const initialLoadRef = useRef(false)
@@ -295,7 +315,7 @@ const useLightrangeGraph = () => {
295
  const currentMinDegree = minDegree
296
 
297
  // Declare a variable to store data promise
298
- let dataPromise;
299
 
300
  // 1. If query label is not empty, use fetchGraph
301
  if (currentQueryLabel) {
@@ -308,6 +328,15 @@ const useLightrangeGraph = () => {
308
 
309
  // 3. Process data
310
  dataPromise.then((data) => {
 
 
 
 
 
 
 
 
 
311
  const state = useGraphStore.getState()
312
 
313
  // Reset state
@@ -417,9 +446,9 @@ const useLightrangeGraph = () => {
417
  // Process nodes to add required properties for RawNodeType
418
  const processedNodes: RawNodeType[] = [];
419
  for (const node of extendedGraph.nodes) {
420
- // Generate random color values
421
- seedrandom(node.id, { global: true });
422
- const color = randomColor();
423
 
424
  // Create a properly typed RawNodeType
425
  processedNodes.push({
 
11
 
12
  import seedrandom from 'seedrandom'
13
 
14
+ // Helper function to generate a color based on type
15
+ const getNodeColorByType = (nodeType: string | undefined, typeColorMap: React.RefObject<Map<string, string>>): string => {
16
+ const defaultColor = '#CCCCCC'; // Default color for nodes without a type or undefined type
17
+ if (!nodeType) {
18
+ return defaultColor;
19
+ }
20
+ if (!typeColorMap.current.has(nodeType)) {
21
+ // Generate a color based on the type string itself for consistency
22
+ // Seed the global random number generator based on the node type
23
+ seedrandom(nodeType, { global: true });
24
+ // Call randomColor without arguments; it will use the globally seeded Math.random()
25
+ const newColor = randomColor();
26
+ typeColorMap.current.set(nodeType, newColor);
27
+ }
28
+ // Restore the default random seed if necessary, though usually not required for this use case
29
+ // seedrandom(Date.now().toString(), { global: true });
30
+ return typeColorMap.current.get(nodeType) || defaultColor; // Add fallback just in case
31
+ };
32
+
33
+
34
  const validateGraph = (graph: RawGraph) => {
35
  // Check if graph exists
36
  if (!graph) {
 
126
  const node = rawData.nodes[i]
127
  nodeIdMap[node.id] = i
128
 
 
 
 
129
  node.x = Math.random()
130
  node.y = Math.random()
131
  node.degree = 0
 
240
  const nodeToExpand = useGraphStore.use.nodeToExpand()
241
  const nodeToPrune = useGraphStore.use.nodeToPrune()
242
 
243
+ // Ref to store the mapping from node type to color
244
+ const typeColorMap = useRef<Map<string, string>>(new Map());
245
+
246
  // Use ref to track if data has been loaded and initial load
247
  const dataLoadedRef = useRef(false)
248
  const initialLoadRef = useRef(false)
 
315
  const currentMinDegree = minDegree
316
 
317
  // Declare a variable to store data promise
318
+ let dataPromise: Promise<RawGraph | null>;
319
 
320
  // 1. If query label is not empty, use fetchGraph
321
  if (currentQueryLabel) {
 
328
 
329
  // 3. Process data
330
  dataPromise.then((data) => {
331
+ // Assign colors based on entity_type *after* fetching
332
+ if (data && data.nodes) {
333
+ data.nodes.forEach(node => {
334
+ // Use entity_type instead of type
335
+ const nodeEntityType = node.properties?.entity_type as string | undefined;
336
+ node.color = getNodeColorByType(nodeEntityType, typeColorMap);
337
+ });
338
+ }
339
+
340
  const state = useGraphStore.getState()
341
 
342
  // Reset state
 
446
  // Process nodes to add required properties for RawNodeType
447
  const processedNodes: RawNodeType[] = [];
448
  for (const node of extendedGraph.nodes) {
449
+ // Get color based on entity_type using the helper function and the shared map
450
+ const nodeEntityType = node.properties?.entity_type as string | undefined; // Use entity_type
451
+ const color = getNodeColorByType(nodeEntityType, typeColorMap);
452
 
453
  // Create a properly typed RawNodeType
454
  processedNodes.push({
lightrag_webui/src/lib/constants.ts CHANGED
@@ -1,6 +1,6 @@
1
  import { ButtonVariantType } from '@/components/ui/Button'
2
 
3
- export const backendBaseUrl = ''
4
  export const webuiPrefix = '/webui/'
5
 
6
  export const controlButtonVariant: ButtonVariantType = 'ghost'
 
1
  import { ButtonVariantType } from '@/components/ui/Button'
2
 
3
+ export const backendBaseUrl = 'http://localhost:9621'
4
  export const webuiPrefix = '/webui/'
5
 
6
  export const controlButtonVariant: ButtonVariantType = 'ghost'