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 |
-
//
|
421 |
-
|
422 |
-
const color =
|
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'
|