From ce928eb99cc08e2a3a851210ed60521dd1b0cf40 Mon Sep 17 00:00:00 2001 From: Yan-Ying Liao Date: Mon, 25 Nov 2024 20:24:53 +0100 Subject: [PATCH] update for graphrag v0.5.0 (#26) --- README.md | 5 ++ src/app/components/GraphViewer.tsx | 13 ++-- src/app/components/Introduction.tsx | 12 ++++ src/app/hooks/useGraphData.ts | 28 +++----- src/app/models/community-report.ts | 61 ++++++++++------ src/app/models/community.ts | 44 +++++++++--- src/app/models/covariate.ts | 61 +++++----------- src/app/models/custom-graph-data.ts | 1 + src/app/models/document.ts | 19 +++-- src/app/models/entity.ts | 46 ++++-------- src/app/models/relationship.ts | 62 +++++++--------- src/app/models/text-unit.ts | 13 ++-- src/app/utils/parquet-utils.ts | 105 ++++++++++++++-------------- 13 files changed, 235 insertions(+), 235 deletions(-) diff --git a/README.md b/README.md index ba71983..afe60ee 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,11 @@ GraphRAG Visualizer is an application designed to visualize Microsoft [GraphRAG](https://github.com/microsoft/graphrag) artifacts. By uploading parquet files generated from the GraphRAG indexing pipeline, users can easily view and analyze data without needing additional software or scripts. +## Important Note + +If you are using **GraphRAG 0.3.x or below**, please use the legacy version of GraphRAG Visualizer available at: +👉 [GraphRAG Visualizer Legacy](https://noworneverev.github.io/graphrag-visualizer-legacy) + ## Features - **Graph Visualization**: View the graph in 2D or 3D in the "Graph Visualization" tab. diff --git a/src/app/components/GraphViewer.tsx b/src/app/components/GraphViewer.tsx index 4d7c194..f8de9ab 100644 --- a/src/app/components/GraphViewer.tsx +++ b/src/app/components/GraphViewer.tsx @@ -21,7 +21,6 @@ import { import FullscreenIcon from "@mui/icons-material/Fullscreen"; import FullscreenExitIcon from "@mui/icons-material/FullscreenExit"; import SearchIcon from "@mui/icons-material/Search"; -import DeleteIcon from "@mui/icons-material/Delete"; import Fuse from "fuse.js"; import { CSS2DRenderer, @@ -525,10 +524,10 @@ const GraphViewer: React.FC = ({ ? includeTextUnits && includeCommunities && includeCovariates : includeTextUnits && includeCommunities; - const clearSearchResults = () => { - setGraphData(initialGraphData.current); - setApiSearchResults(null); - }; + // const clearSearchResults = () => { + // setGraphData(initialGraphData.current); + // setApiSearchResults(null); + // }; return ( = ({ > Nodes: {nodeCount} Relationships: {linkCount} - + */} ); diff --git a/src/app/components/Introduction.tsx b/src/app/components/Introduction.tsx index 525a3a5..4ab22d4 100644 --- a/src/app/components/Introduction.tsx +++ b/src/app/components/Introduction.tsx @@ -20,6 +20,18 @@ const Introduction: React.FC = () => { Welcome to the GraphRAG Visualizer + + If you are using GraphRAG 0.3.x or below, please visit + the legacy site:{" "} + + GraphRAG Visualizer Legacy + + + Overview diff --git a/src/app/hooks/useGraphData.ts b/src/app/hooks/useGraphData.ts index 98152a3..3c23810 100644 --- a/src/app/hooks/useGraphData.ts +++ b/src/app/hooks/useGraphData.ts @@ -26,14 +26,12 @@ const useGraphData = ( useEffect(() => { const nodes: CustomNode[] = entities.map((entity) => ({ uuid: entity.id, - id: entity.name, - name: entity.name, + id: entity.title, + name: entity.title, type: entity.type, description: entity.description, - human_readable_id: entity.human_readable_id, - graph_embedding: entity.graph_embedding, - text_unit_ids: entity.text_unit_ids, - description_embedding: entity.description_embedding, + human_readable_id: entity.human_readable_id, + text_unit_ids: entity.text_unit_ids, neighbors: [], links: [], })); @@ -51,9 +49,7 @@ const useGraphData = ( text_unit_ids: relationship.text_unit_ids, id: relationship.id, human_readable_id: relationship.human_readable_id, - source_degree: relationship.source_degree, - target_degree: relationship.target_degree, - rank: relationship.rank, + combined_degree: relationship.combined_degree, })) .filter((link) => nodesMap[link.source] && nodesMap[link.target]); @@ -66,8 +62,9 @@ const useGraphData = ( name: document.title, title: document.title, type: "RAW_DOCUMENT", // avoid conflict with "DOCUMENT" type - raw_content: document.raw_content, + text: document.text, text_unit_ids: document.text_unit_ids, + human_readable_id: document.human_readable_id, neighbors: [], links: [], })); @@ -102,6 +99,7 @@ const useGraphData = ( document_ids: textunit.document_ids, entity_ids: textunit.entity_ids, relationship_ids: textunit.relationship_ids, + human_readable_id: textunit.human_readable_id, neighbors: [], links: [], })); @@ -230,17 +228,13 @@ const useGraphData = ( // type: "COVARIATE", type: covariate.type, description: covariate.description || "", - subject_id: covariate.subject_id, - subject_type: covariate.subject_type, - object_id: covariate.object_id, - object_type: covariate.object_type, + subject_id: covariate.subject_id, + object_id: covariate.object_id, status: covariate.status, start_date: covariate.start_date, end_date: covariate.end_date, source_text: covariate.source_text, - text_unit_id: covariate.text_unit_id, - document_ids: covariate.document_ids, - n_tokens: covariate.n_tokens, + text_unit_id: covariate.text_unit_id, neighbors: [], links: [], })); diff --git a/src/app/models/community-report.ts b/src/app/models/community-report.ts index f6a9414..e41c98d 100644 --- a/src/app/models/community-report.ts +++ b/src/app/models/community-report.ts @@ -6,66 +6,77 @@ export interface Finding { } export interface CommunityReport { + id: string; + human_readable_id: number; community: number; - full_content: string; level: number; - rank: number; title: string; - rank_explanation: string; summary: string; + full_content: string; + rank: number; + rank_explanation: string; findings: Finding[]; full_content_json: string; - id: string; + period: string; + size: number; } export const findingColumns: MRT_ColumnDef[] = [ { accessorKey: "id", - header: "ID", + header: "id", }, { accessorKey: "explanation", - header: "Explanation", + header: "explanation", }, { accessorKey: "summary", - header: "Summary", + header: "summary", }, ] export const communityReportColumns: MRT_ColumnDef[] = [ { - accessorKey: "community", - header: "Community", + accessorKey: "id", + header: "id", + }, + { + accessorKey: "human_readable_id", + header: "human_readable_id", }, { - accessorKey: "full_content", - header: "Full Content", + accessorKey: "community", + header: "community", }, { accessorKey: "level", - header: "Level", + header: "level", }, { - accessorKey: "rank", - header: "Rank", + accessorKey: "title", + header: "title", }, { - accessorKey: "title", - header: "Title", + accessorKey: "summary", + header: "summary", }, { - accessorKey: "rank_explanation", - header: "Rank Explanation", + accessorKey: "full_content", + header: "full_content", }, { - accessorKey: "summary", - header: "Summary", + accessorKey: "rank", + header: "rank", + }, + { + accessorKey: "rank_explanation", + header: "rank_explanation", }, { accessorKey: "findings", - header: "Findings", + header: "findings", Cell: ({ renderedCellValue }) => Array.isArray(renderedCellValue) ? JSON.stringify(renderedCellValue, null, 2) @@ -76,7 +87,11 @@ export const communityReportColumns: MRT_ColumnDef[] = [ header: "Full Content JSON", }, { - accessorKey: "id", - header: "ID", + accessorKey: "period", + header: "period", + }, + { + accessorKey: "size", + header: "size", }, ]; \ No newline at end of file diff --git a/src/app/models/community.ts b/src/app/models/community.ts index 9e671e3..c831a0c 100644 --- a/src/app/models/community.ts +++ b/src/app/models/community.ts @@ -2,33 +2,49 @@ import { MRT_ColumnDef } from "material-react-table"; export interface Community { id: number; - title: string; + human_readable_id: number; + community: number; level: number; - raw_community: number; + title: string; + entity_ids: string[]; relationship_ids: string[]; text_unit_ids: string[]; + period: string; + size: number; } export const communityColumns: MRT_ColumnDef[] = [ { accessorKey: "id", - header: "ID", + header: "id", }, { - accessorKey: "title", - header: "Title", + accessorKey: "human_readable_id", + header: "human_readable_id", + }, + { + accessorKey: "community", + header: "community", }, { accessorKey: "level", - header: "Level", + header: "level", }, { - accessorKey: "raw_community", - header: "Raw Community", + accessorKey: "title", + header: "title", + }, + { + accessorKey: "entity_ids", + header: "entity_ids", + Cell: ({ renderedCellValue }) => + Array.isArray(renderedCellValue) + ? JSON.stringify(renderedCellValue, null, 2) + : renderedCellValue, }, { accessorKey: "relationship_ids", - header: "Relationship IDs", + header: "relationship_ids", Cell: ({ renderedCellValue }) => Array.isArray(renderedCellValue) ? JSON.stringify(renderedCellValue, null, 2) @@ -36,10 +52,18 @@ export const communityColumns: MRT_ColumnDef[] = [ }, { accessorKey: "text_unit_ids", - header: "Text Unit IDs", + header: "text_unit_ids", Cell: ({ renderedCellValue }) => Array.isArray(renderedCellValue) ? JSON.stringify(renderedCellValue, null, 2) : renderedCellValue, }, + { + accessorKey: "period", + header: "period", + }, + { + accessorKey: "size", + header: "size", + }, ]; \ No newline at end of file diff --git a/src/app/models/covariate.ts b/src/app/models/covariate.ts index e794ef9..4d78ecf 100644 --- a/src/app/models/covariate.ts +++ b/src/app/models/covariate.ts @@ -6,87 +6,62 @@ export interface Covariate { covariate_type: string; type: string; description: string; - subject_id: string; - subject_type: string; - object_id: string; - object_type: string; + subject_id: string; + object_id: string; status: string; start_date: string; end_date: string; source_text: string; - text_unit_id: string; - document_ids: string[]; - n_tokens: number; + text_unit_id: string; } export const covariateColumns: MRT_ColumnDef[] = [ { accessorKey: "id", - header: "ID", + header: "id", }, { accessorKey: "human_readable_id", - header: "Human Readable ID", + header: "human_readable_id", }, { accessorKey: "covariate_type", - header: "Covariate Type", + header: "covariate_type", }, { accessorKey: "type", - header: "Type", + header: "type", }, { accessorKey: "description", - header: "Description", + header: "description", }, { accessorKey: "subject_id", - header: "Subject ID", - }, - { - accessorKey: "subject_type", - header: "Subject Type", - }, + header: "subject_id", + }, { accessorKey: "object_id", - header: "Object ID", - }, - { - accessorKey: "object_type", - header: "Object Type", - }, + header: "object_id", + }, { accessorKey: "status", - header: "Status", + header: "status", }, { accessorKey: "start_date", - header: "Start Date", + header: "start_date", }, { accessorKey: "end_date", - header: "End Date", + header: "end_date", }, { accessorKey: "source_text", - header: "Source Text", + header: "source_text", }, { accessorKey: "text_unit_id", - header: "Text Unit ID", - }, - { - accessorKey: "document_ids", - header: "Document IDs", - Cell: ({ renderedCellValue }) => - Array.isArray(renderedCellValue) - ? JSON.stringify(renderedCellValue, null, 2) - : renderedCellValue, - }, - { - accessorKey: "n_tokens", - header: "Number of Tokens", - }, - + header: "text_unit_id", + }, ]; \ No newline at end of file diff --git a/src/app/models/custom-graph-data.ts b/src/app/models/custom-graph-data.ts index f3bcdd4..0f69ebd 100644 --- a/src/app/models/custom-graph-data.ts +++ b/src/app/models/custom-graph-data.ts @@ -52,6 +52,7 @@ export interface CustomLink extends LinkObject { text_unit_ids?: string[]; id: string; human_readable_id?: number; + combined_degree?: number; source_degree?: number; target_degree?: number; rank?: number; diff --git a/src/app/models/document.ts b/src/app/models/document.ts index e66117b..9bd21e3 100644 --- a/src/app/models/document.ts +++ b/src/app/models/document.ts @@ -2,27 +2,32 @@ import { MRT_ColumnDef } from "material-react-table"; export interface Document { id: string; - text_unit_ids: string[]; - raw_content: string; + human_readable_id: number; title: string; + text: string; + text_unit_ids: string[]; } export const documentColumns: MRT_ColumnDef[] = [ { accessorKey: "id", - header: "ID", + header: "id", }, { - accessorKey: "raw_content", - header: "Raw Content", + accessorKey: "human_readable_id", + header: "human_readable_id", }, { accessorKey: "title", - header: "Title", + header: "title", }, + { + accessorKey: "text", + header: "text", + }, { accessorKey: "text_unit_ids", - header: "Text Unit IDs", + header: "text_unit_ids", Cell: ({ renderedCellValue }) => Array.isArray(renderedCellValue) ? JSON.stringify(renderedCellValue, null, 2) diff --git a/src/app/models/entity.ts b/src/app/models/entity.ts index 2ffee2e..c11ecaa 100644 --- a/src/app/models/entity.ts +++ b/src/app/models/entity.ts @@ -2,58 +2,40 @@ import { MRT_ColumnDef } from "material-react-table"; export interface Entity { id: string; - name: string; + human_readable_id: number; + title: string; type: string; description: string; - human_readable_id: number; - graph_embedding: number[]; - text_unit_ids: string[]; - description_embedding: number[]; + text_unit_ids: string[]; } export const entityColumns: MRT_ColumnDef[] = [ { accessorKey: "id", - header: "ID", + header: "id", }, { - accessorKey: "name", - header: "Name", + accessorKey: "human_readable_id", + header: "human_readable_id", }, + { + accessorKey: "title", + header: "title", + }, { accessorKey: "type", - header: "Type", + header: "type", }, { accessorKey: "description", - header: "Description", - }, - { - accessorKey: "human_readable_id", - header: "Human Readable ID", - }, - { - accessorKey: "graph_embedding", - header: "Graph Embedding", - Cell: ({ renderedCellValue }) => - Array.isArray(renderedCellValue) - ? JSON.stringify(renderedCellValue, null, 2) - : renderedCellValue, + header: "description", }, { accessorKey: "text_unit_ids", - header: "Text Unit IDs", - Cell: ({ renderedCellValue }) => - Array.isArray(renderedCellValue) - ? JSON.stringify(renderedCellValue, null, 2) - : renderedCellValue, - }, - { - accessorKey: "description_embedding", - header: "Description Embedding", + header: "text_unit_ids", Cell: ({ renderedCellValue }) => Array.isArray(renderedCellValue) ? JSON.stringify(renderedCellValue, null, 2) : renderedCellValue, - }, + }, ]; \ No newline at end of file diff --git a/src/app/models/relationship.ts b/src/app/models/relationship.ts index dc07037..8eecc7f 100644 --- a/src/app/models/relationship.ts +++ b/src/app/models/relationship.ts @@ -1,68 +1,56 @@ import { MRT_ColumnDef } from "material-react-table"; export interface Relationship { + id: string; + human_readable_id: number; source: string; target: string; - weight: number; description: string; - text_unit_ids: string[]; - id: string; - human_readable_id: number; - source_degree: number; - target_degree: number; - rank: number; + weight: number; + combined_degree: number; + text_unit_ids: string[]; type: string; // Custom field to match neo4j } export const relationshipColumns: MRT_ColumnDef[] = [ { - accessorKey: "source", - header: "Source", + accessorKey: "id", + header: "id", }, { - accessorKey: "target", - header: "Target", + accessorKey: "human_readable_id", + header: "human_readable_id", }, { - accessorKey: "type", - header: "Type", + accessorKey: "source", + header: "source", }, { - accessorKey: "weight", - header: "Weight", + accessorKey: "target", + header: "target", }, { accessorKey: "description", - header: "Description", - }, + header: "description", + }, + { + accessorKey: "weight", + header: "weight", + }, { accessorKey: "text_unit_ids", - header: "Text Unit IDs", + header: "text_unit_ids", Cell: ({ renderedCellValue }) => Array.isArray(renderedCellValue) ? JSON.stringify(renderedCellValue, null, 2) : renderedCellValue, }, { - accessorKey: "id", - header: "ID", - }, - { - accessorKey: "human_readable_id", - header: "Human Readable ID", - }, - { - accessorKey: "source_degree", - header: "Source Degree", - }, - { - accessorKey: "target_degree", - header: "Target Degree", + accessorKey: "combined_degree", + header: "combined_degree", }, { - accessorKey: "rank", - header: "Rank", - }, - - + accessorKey: "type", + header: "Type", + }, ]; \ No newline at end of file diff --git a/src/app/models/text-unit.ts b/src/app/models/text-unit.ts index f189b49..add8e35 100644 --- a/src/app/models/text-unit.ts +++ b/src/app/models/text-unit.ts @@ -2,6 +2,7 @@ import { MRT_ColumnDef } from "material-react-table"; export interface TextUnit { id: string; + human_readable_id: number; text: string; n_tokens: number; document_ids: string[]; @@ -12,19 +13,19 @@ export interface TextUnit { export const textUnitColumns: MRT_ColumnDef[] = [ { accessorKey: "id", - header: "ID", + header: "id", }, { accessorKey: "text", - header: "Text", + header: "text", }, { accessorKey: "n_tokens", - header: "Number of Tokens", + header: "n_tokens", }, { accessorKey: "document_ids", - header: "Document IDs", + header: "document_ids", Cell: ({ renderedCellValue }) => Array.isArray(renderedCellValue) ? JSON.stringify(renderedCellValue, null, 2) @@ -32,7 +33,7 @@ export const textUnitColumns: MRT_ColumnDef[] = [ }, { accessorKey: "entity_ids", - header: "Entity IDs", + header: "entity_ids", Cell: ({ renderedCellValue }) => Array.isArray(renderedCellValue) ? JSON.stringify(renderedCellValue, null, 2) @@ -40,7 +41,7 @@ export const textUnitColumns: MRT_ColumnDef[] = [ }, { accessorKey: "relationship_ids", - header: "Relationship IDs", + header: "relationship_ids", Cell: ({ renderedCellValue }) => Array.isArray(renderedCellValue) ? JSON.stringify(renderedCellValue, null, 2) diff --git a/src/app/utils/parquet-utils.ts b/src/app/utils/parquet-utils.ts index 249bdb2..6c2560a 100644 --- a/src/app/utils/parquet-utils.ts +++ b/src/app/utils/parquet-utils.ts @@ -39,80 +39,83 @@ export const readParquetFile = async ( resolve( rows.map((row) => ({ id: row[0], - name: row[1], - type: row[2], - description: row[3], - human_readable_id: parseValue(row[4], "number"), - graph_embedding: row[5], - text_unit_ids: row[6], - description_embedding: row[7], + human_readable_id: parseValue(row[1], "number"), + title: row[2], + type: row[3], + description: row[4], + text_unit_ids: row[5], })) ); } else if (schema === "relationship") { resolve( rows.map((row) => ({ - source: row[0], - target: row[1], - type: "RELATED", // Custom field to match neo4j - weight: row[2], - description: row[3], - text_unit_ids: row[4], - id: row[5], - human_readable_id: parseValue(row[6], "number"), - source_degree: parseValue(row[7], "number"), - target_degree: parseValue(row[8], "number"), - rank: parseValue(row[9], "number"), + id: row[0], + human_readable_id: parseValue(row[1], "number"), + source: row[2], + target: row[3], + description: row[4], + weight: row[5], + combined_degree: parseValue(row[6], "number"), + text_unit_ids: row[7], + type: "RELATED", // Custom field to match neo4j })) ); } else if (schema === "document") { resolve( rows.map((row) => ({ id: row[0], - text_unit_ids: row[1], - raw_content: row[2], - title: row[3], + human_readable_id: parseValue(row[1], "number"), + title: row[2], + text: row[3], + text_unit_ids: row[4], })) ); } else if (schema === "text_unit") { resolve( rows.map((row) => ({ id: row[0], - text: row[1], - n_tokens: parseValue(row[2], "number"), - document_ids: row[3], - entity_ids: row[4], - relationship_ids: row[5], + human_readable_id: parseValue(row[1], "number"), + text: row[2], + n_tokens: parseValue(row[3], "number"), + document_ids: row[4], + entity_ids: row[5], + relationship_ids: row[6], })) ); } else if (schema === "community") { resolve( rows.map((row) => ({ id: row[0], - title: row[1], - level: parseValue(row[2], "number"), - ...(row.length > 5 - ? { raw_community: parseValue(row[3], "number") } - : {}), // From graphrag 0.3.X onwards, raw_community is removed - relationship_ids: row[row.length > 5 ? 4 : 3], - text_unit_ids: row[row.length > 5 ? 5 : 4], + human_readable_id: parseValue(row[1], "number"), + community: parseValue(row[2], "number"), + level: parseValue(row[3], "number"), + title: row[4], + entity_ids: row[5], + relationship_ids: row[6], + text_unit_ids: row[7], + period: row[8], + size: parseValue(row[9], "number"), })) ); } else if (schema === "community_report") { resolve( rows.map((row) => ({ - community: parseValue(row[0], "number"), - full_content: row[1], - level: parseValue(row[2], "number"), - rank: parseValue(row[3], "number"), + id: row[0], + human_readable_id: parseValue(row[1], "number"), + community: parseValue(row[2], "number"), + level: parseValue(row[3], "number"), title: row[4], - rank_explanation: row[5], - summary: row[6], - findings: row[7].map((finding: any) => ({ + summary: row[5], + full_content: row[6], + rank: parseValue(row[7], "number"), + rank_explanation: row[8], + findings: row[9].map((finding: any) => ({ explanation: finding.explanation, summary: finding.summary, })), - full_content_json: row[8], - id: row[9], + full_content_json: row[10], + period: row[11], + size: parseValue(row[12], "number"), })) ); } else if (schema === "covariate") { @@ -123,17 +126,13 @@ export const readParquetFile = async ( covariate_type: row[2], type: row[3], description: row[4], - subject_id: row[5], - subject_type: row[6], - object_id: row[7], - object_type: row[8], - status: row[9], - start_date: row[10], - end_date: row[11], - source_text: row[12], - text_unit_id: row[13], - document_ids: row[14], - n_tokens: parseValue(row[15], "number"), + subject_id: row[5], + object_id: row[6], + status: row[7], + start_date: row[8], + end_date: row[9], + source_text: row[10], + text_unit_id: row[11], })) ); } else {