3030 const { Graph } = window . G6 ;
3131
3232 // API base path
33- // const API_BASE = window.location.origin;
34- const API_BASE = "http://localhost:8080" ;
33+ const API_BASE = window . location . origin ;
34+ // dev mode
35+ // const API_BASE = "http://localhost:8080";
3536
3637 // Configuration constants
3738 const COLORS = [
308309 }
309310 } , [ selectedVertex ] ) ;
310311
312+ const excludedKeys = new Set ( [
313+ "id" ,
314+ "label" ,
315+ "style" ,
316+ "data" ,
317+ "weight" ,
318+ "source_id" ,
319+ ] ) ;
320+
311321 // Convert data to G6 Graph format
312322 const graphDataFormatted = useMemo ( ( ) => {
313323 if ( ! graphData ) return null ;
380390 key : `bubble-sets-${ key } ` ,
381391 type : "bubble-sets" ,
382392 members : nodes ,
383- keywords : edge . keywords || "" ,
384- summary : edge . summary || "" ,
385393 weight : edge . weight || nodes . length ,
386394 description : edge . description || edge . summary || "" ,
395+ edge : edge ,
387396 ...createBubbleStyle ( COLORS [ i % COLORS . length ] ) ,
388397 } ) ;
389398
418427 }
419428
420429 // Add tooltip plugin
421- const excludedKeys = new Set ( [
422- "id" ,
423- "entity_name" ,
424- "entity_type" ,
425- "style" ,
426- "data" ,
427- "description" ,
428- ] ) ;
429430
430431 plugins . push ( {
431432 type : "tooltip" ,
432433 getContent : ( e , items ) => {
433434 return items
434435 . map ( ( item ) => {
435- let result = `<h4>${ item . id } </h4>` ;
436- if ( item . entity_name )
437- result += `<p><strong>Name:</strong> ${ item . entity_name } </p>` ;
438- if ( item . entity_type )
439- result += `<p><strong>Type:</strong> ${ item . entity_type } </p>` ;
440- if ( item . description ) {
441- result += `<p><strong>Description:</strong> ${ formatDescription (
442- item . description
443- ) } </p>`;
444- }
436+ let result = `<h3><strong>${
437+ item . entity_name || item . id
438+ } </strong></h3>`;
445439 // Display all remaining properties
446440 Object . entries ( item ) . forEach ( ( [ key , value ] ) => {
447441 if ( ! excludedKeys . has ( key ) ) {
520514 if ( e . targetType === "bubble-sets" ) {
521515 const target = e . target . options ;
522516 const newHyperedge = {
523- ...target ,
517+ ...target . edge ,
524518 members : Array . isArray ( target . members ) ? target . members : [ ] ,
525519 } ;
526520 setHoverHyperedge ( ( prev ) => {
@@ -869,48 +863,95 @@ <h3 className="text-xl font-semibold text-gray-800 m-0">
869863 < div className = "text-base font-semibold text-gray-900" >
870864 Hyperedge
871865 </ div >
872- { hoverHyperedge . description && (
873- < div >
874- < div className = "font-medium" > Description: </ div >
875- < div className = "mt-1 text-gray-600 bg-gray-50 p-2 rounded" >
876- { hoverHyperedge . description }
877- </ div >
878- </ div >
879- ) }
880- { hoverHyperedge . keywords && (
881- < div >
882- < span className = "font-medium" > Keywords: </ span >
883- < div className = "flex flex-wrap gap-2 mt-2" >
884- { hoverHyperedge . keywords
885- . split ( / , | , | 、 | 。 | < S E P > / )
886- . map ( ( keyword , i ) => (
887- < span
888- key = { i }
889- className = "inline-block p-1 bg-primary-50 rounded"
890- >
891- { keyword }
866+ { Object . entries ( hoverHyperedge ) . map (
867+ ( [ key , value ] ) => {
868+ // Skip empty values
869+ if (
870+ ! value ||
871+ ( Array . isArray ( value ) && value . length === 0 ) ||
872+ excludedKeys . has ( key )
873+ ) {
874+ return null ;
875+ }
876+
877+ // Special handling for keywords
878+ if (
879+ key === "keywords" &&
880+ typeof value === "string"
881+ ) {
882+ return (
883+ < div key = { key } >
884+ < span className = "font-medium" >
885+ keywords:
892886 </ span >
893- ) ) }
894- </ div >
895- </ div >
896- ) }
897-
898- { hoverHyperedge . members ?. length > 0 && (
899- < div >
900- < div className = "font-medium" >
901- Nodes ({ hoverHyperedge . members . length } ):
902- </ div >
903- < div className = "flex flex-wrap gap-2 mt-2" >
904- { hoverHyperedge . members . map ( ( member , i ) => (
905- < span
906- key = { i }
907- className = "p-1 bg-primary-50 rounded"
908- >
909- { member }
910- </ span >
911- ) ) }
912- </ div >
913- </ div >
887+ < div className = "flex flex-wrap gap-2 mt-2" >
888+ { value
889+ . split ( / , | , | 、 | 。 | < S E P > / )
890+ . filter ( ( k ) => k . trim ( ) )
891+ . map ( ( keyword , i ) => (
892+ < span
893+ key = { i }
894+ className = "inline-block p-1 bg-primary-50 rounded text-xs"
895+ >
896+ { keyword . trim ( ) }
897+ </ span >
898+ ) ) }
899+ </ div >
900+ </ div >
901+ ) ;
902+ }
903+
904+ // Special handling for members
905+ if ( Array . isArray ( value ) ) {
906+ return (
907+ < div key = { key } >
908+ < div className = "font-medium" >
909+ { key } ({ value . length } ):
910+ </ div >
911+ < div className = "flex flex-wrap gap-2 mt-2" >
912+ { value . map ( ( member , i ) => (
913+ < span
914+ key = { i }
915+ className = "p-1 bg-primary-50 rounded text-xs"
916+ >
917+ { member }
918+ </ span >
919+ ) ) }
920+ </ div >
921+ </ div >
922+ ) ;
923+ }
924+
925+ // Convert value to string for length check
926+ const stringValue =
927+ typeof value === "object"
928+ ? JSON . stringify ( value , null , 2 )
929+ : String ( value ) . replace ( / < S E P > / g, " | " ) ;
930+
931+ // If value is less than 10 characters, display as tag
932+ if ( stringValue . length < 20 ) {
933+ return (
934+ < div key = { key } >
935+ < span className = "font-medium" > { key } :</ span >
936+ < div className = "mt-1" >
937+ < span className = "inline-block px-2 py-1 bg-gray-100 rounded text-xs" >
938+ { stringValue }
939+ </ span >
940+ </ div >
941+ </ div >
942+ ) ;
943+ }
944+
945+ // Default handling for longer values
946+ return (
947+ < div key = { key } >
948+ < span className = "font-medium" > { key } :</ span >
949+ < div className = "mt-1 text-gray-600 bg-gray-100 p-2 rounded text-xs" >
950+ { stringValue }
951+ </ div >
952+ </ div >
953+ ) ;
954+ }
914955 ) }
915956 </ div >
916957 ) }
@@ -919,42 +960,46 @@ <h3 className="text-xl font-semibold text-gray-800 m-0">
919960 < div className = "text-base font-semibold text-gray-900" >
920961 Node
921962 </ div >
922- { hoverNode . entity_name && (
923- < div >
924- < span className = "font-medium" > Name:</ span >
925- < span className = "ml-2" >
926- { hoverNode . entity_name }
927- </ span >
928- </ div >
929- ) }
930- { hoverNode . entity_type && (
931- < div >
932- < span className = "font-medium" > Type:</ span >
933- < span className = "ml-2 inline-block px-2 py-0.5 bg-gray-100 rounded" >
934- { hoverNode . entity_type }
935- </ span >
936- </ div >
937- ) }
938- { hoverNode . description && (
939- < div >
940- < span className = "font-medium" > Description:</ span >
941- < span className = "ml-2" >
942- { formatDescription ( hoverNode . description ) }
943- </ span >
944- </ div >
945- ) }
946- { hoverNode . additional_properties && (
947- < div >
948- < span className = "font-medium" >
949- Additional Properties:
950- </ span >
951- < span className = "ml-2" >
952- { formatDescription (
953- hoverNode . additional_properties
954- ) }
955- </ span >
956- </ div >
957- ) }
963+ { Object . entries ( hoverNode ) . map ( ( [ key , value ] ) => {
964+ // Skip empty values
965+ if (
966+ ! value ||
967+ ( Array . isArray ( value ) && value . length === 0 ) ||
968+ excludedKeys . has ( key )
969+ ) {
970+ return null ;
971+ }
972+
973+ // Convert value to string for length check
974+ const stringValue =
975+ typeof value === "object"
976+ ? JSON . stringify ( value , null , 2 )
977+ : String ( value ) . replace ( / < S E P > / g, " | " ) ;
978+
979+ // If value is less than 10 characters, display as tag
980+ if ( stringValue . length < 20 ) {
981+ return (
982+ < div key = { key } >
983+ < span className = "font-medium" > { key } :</ span >
984+ < div className = "mt-1" >
985+ < span className = "inline-block px-2 py-1 bg-gray-100 rounded text-xs" >
986+ { stringValue }
987+ </ span >
988+ </ div >
989+ </ div >
990+ ) ;
991+ }
992+
993+ // Default handling for longer values
994+ return (
995+ < div key = { key } >
996+ < span className = "font-medium" > { key } :</ span >
997+ < div className = "mt-1 text-gray-600 bg-gray-100 p-2 rounded text-xs" >
998+ { stringValue }
999+ </ div >
1000+ </ div >
1001+ ) ;
1002+ } ) }
9581003 </ div >
9591004 ) }
9601005 </ div >
0 commit comments