npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-kggraph

v0.1.74

Published

A knowledge graph visualization component based on Cytoscape

Downloads

2,202

Readme

react-kggraph

基于 Cytoscape.js 的 React 知识图谱可视化组件库。

特性

  • 🚀 基于 Cytoscape.js 强大的图可视化能力
  • 📊 支持多种布局算法(cose-bilkent、cise、fcose、cose、grid、circle、breadthfirst、concentric)
  • 🎨 自定义节点/边样式,支持 Drawer 编辑
  • 🔍 节点搜索、框选/点选模式、全选/反选
  • 📦 知识图谱展开/收起(concentric 环形动画 + 淡入淡出)
  • 📋 数据导出(JSON / Excel / PNG / JPG)
  • 📱 响应式设计,画布缩放、节点缩放、拖拽交互
  • ⚙️ ActionBar 工具栏可配置(位置、按钮、折叠)
  • 🖱️ 右键径向菜单(actionCircle)
  • 🗺️ 路径分析:多节点 A* 最短路径
  • 🔗 连接分析:BFS N 度关联节点
  • 📊 查询统计面板:实体/关系类型分布及筛选
  • 📝 知识卡片:节点详情抽屉
  • ✏️ 图谱编辑器:新增/删除节点和关系,属性编辑

安装

npm install react-kggraph

依赖

npm install react react-dom antd @ant-design/icons

使用

基础用法

import KgGraph from 'react-kggraph';
import 'react-kggraph/style.css';

const App = () => {
  const data = {
    nodes: [
      {
        id: 'Alice',
        label: 'Alice',
        varName: 'a',
        types: 'uri',
        properties: {
          id: 'Alice',
          type: 'uri',
          label: 'Alice',
          value: 'Alice',
        },
      },
      {
        id: 'Bob',
        label: 'Bob',
        varName: 'c',
        types: 'uri',
        properties: {
          id: 'Bob',
          type: 'uri',
          label: 'Bob',
          value: 'Bob',
        },
      },
    ],
    edges: [
      {
        id: '7b54a756-451c-4f80-ba7f-906d19d434a4',
        source: 'Alice',
        target: 'Bob',
        label: '关注',
      },
      {
        id: '1d2dfab4-b03f-4694-8c91-0ef532d67ad7',
        source: 'Bob',
        target: 'Alice',
        label: '关注',
      },
    ],
  };

  return (
    <div style={{ width: '100%', height: '600px' }}>
      <KgGraph data={data} />
    </div>
  );
};

完整示例(含展收 + 工具栏 + 右键菜单 + 编辑器)

import { useRef } from 'react';
import KgGraph, { CytoscapeReactRef } from 'react-kggraph';
import { actionList } from 'react-kggraph';
import 'react-kggraph/style.css';

const App = () => {
  const kgGraphRef = useRef<CytoscapeReactRef>(null);

  // 获取完整图谱数据回调
  const getAllGraphData = async (params) => {
    const response = await fetch('/api/graph', {
      method: 'POST',
      body: JSON.stringify(params),
    });
    return response.json();
  };

  // 节点展开/收起 API
  const stepNextApi = async (params) => {
    const response = await fetch('/api/stepNext', {
      method: 'POST',
      body: JSON.stringify(params),
    });
    return response.json();
  };

  // 知识卡片 API
  const knowledgeCardApi = async (params) => {
    const response = await fetch('/api/knowledgeCard', {
      method: 'POST',
      body: JSON.stringify(params),
    });
    return response.json();
  };

  // 保存操作记录
  const handleSave = () => {
    const saveData = kgGraphRef.current?.getSaveData();
    if (saveData) {
      console.log('保存数据:', saveData);
      kgGraphRef.current?.clearOperationHistory();
    }
  };

  return (
    <div style={{ width: '100%', height: '600px' }}>
      <button onClick={handleSave}>保存</button>
      <KgGraph
        ref={kgGraphRef}
        data={data}
        graphInfo={{ kgId: 3, searchNodes: ['Alice', 'Bob'] }}
        getAllGraphData={getAllGraphData}
        stepNextApi={stepNextApi}
        knowledgeCardApi={knowledgeCardApi}
        graphEditor={{ show: true, oprateFlowFunction: (flow) => console.log('操作流:', flow) }}
        actionBar={{
          position: 'left',
          isExpand: true,
          actionList: actionList.filter(item =>
            ['queryStatistics', 'layout', 'analysis', 'downloadData'].includes(item.key)
          ),
        }}
        actionCircle={[
          { ids: 'contract', label: '展收实体' },
          { ids: 'expanded', label: '展收属性' },
          { ids: 'nodeInfo', label: '节点样式' },
          { ids: 'knowledgeCard', label: '知识卡片' },
        ]}
      />
    </div>
  );
};

Ref 方法

通过 useRef<CytoscapeReactRef>(null) 可调用以下方法:

| 方法 | 说明 | |------|------| | cyRef | Cytoscape 实例引用,可直接操作画布(cyRef.current.nodes() 等) | | getSaveData() | 获取保存数据({ operationHistory, sparqlStr }) | | clearOperationHistory() | 清空操作历史记录 | | checkIsolatedNodes() | 检查孤立节点,返回标签数组 | | setTypeObj(obj) | 设置实体类型统计(如 { '人物': 10, '公司': 5 }) | | setRelationObj(obj) | 设置关系类型统计(如 { '任职': 3, '投资': 2 }) | | searchNode(keyword) | 搜索节点并居中高亮,传 '' 取消搜索恢复全局视图 |

// 直接操作画布
kgGraphRef.current?.cyRef.current?.nodes().forEach(node => {
  console.log(node.data());
});

// 搜索节点并居中
kgGraphRef.current?.searchNode('Alice');

// 取消搜索恢复全局视图
kgGraphRef.current?.searchNode('');

// 更新类型统计
kgGraphRef.current?.setTypeObj({ '人物': 10, '公司': 5 });
kgGraphRef.current?.setRelationObj({ '任职': 3 });

Props

| 属性 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | data | GraphData \| null | ❌ | — | 图谱数据,null 时显示空画布 | | getAllGraphData | (params?: any) => void | ❌ | — | 画布数据变化回调,返回 { graphData, data, paths, ... } | | highPathAnalysis | { nodes?: string[], links?: any[] } | ❌ | {} | 高亮路径分析 | | graphInfo | { kgId, searchNodes? } | ❌ | — | 图谱配置(kgId 用于展收 API,searchNodes 左右固定布局) | | stepNextApi | (params) => Promise | ❌ | — | 展开/收起 API | | knowledgeCardApi | (params) => Promise | ❌ | — | 知识卡片 API | | colors | GraphColors | ❌ | — | 颜色配置(与默认值合并) | | actionBar | boolean \| ActionBarConfig | ❌ | — | true=默认工具栏,false=隐藏 | | actionCircle | ActionCircleItem[] | ❌ | — | 右键菜单项(覆盖/追加默认项) | | graphEditor | GraphEditorConfig | ❌ | — | 图谱编辑器配置 | | queryStatisticsConfig | { label, key }[] | ❌ | — | 统计面板配置 | | isEditorGrahh | boolean | ❌ | false | 编辑模式,右键直接弹出节点操作面板 | | loading | boolean | ❌ | false | 加载状态 | | noDataDesc | string | ❌ | '暂无数据' | 无数据提示文案 | | className | string | ❌ | — | 外层容器 class |

数据格式

节点 (Node)

interface GraphNode {
  id: string;               // 唯一标识
  label: string;            // 显示标签
  types: string;            // 类型:'uri'=实体 / 'typed-literal'=属性
  varName?: string;         // SPARQL 变量名
  properties?: {            // 属性对象
    id: string;
    type: string;
    label: string;
    value: string;
    datatype?: string;
  };
}

边 (Edge)

interface GraphEdge {
  id?: string;              // 唯一标识
  source: string;           // 源节点 id
  target: string;           // 目标节点 id
  label: string;            // 关系标签
}

GraphData

interface GraphData {
  nodes: GraphNode[];
  edges: GraphEdge[];
  paths?: any[];            // 路径数据
  data2?: any;
  logId?: string;
  costtime?: number;
}

颜色配置

interface GraphColors {
  nodeLabelColor?: string;          // 默认 '#000'
  nodeLabelFontSize?: number;       // 默认 16
  edgeLabelColor?: string;          // 默认 '#666'
  edgeLabelFontSize?: number;       // 默认 16
  uriNodeColor?: string;            // URI 节点背景色,默认 '#f7de63'
  normalNodeColor?: string;         // 普通节点背景色,默认 '#1890FF'
  nodeBorderHoverColor?: string;    // 边框悬停色,默认 '#0d6ac2'
  edgeDefaultColor?: string;        // 边默认色,默认 '#a29e9e'
  edgeHoverColor?: string;          // 边悬停色,默认 '#145AFD'
  pathHighlightColor?: string;      // 路径高亮色,默认 '#145AFD'
  pathNodeColor?: string;           // 路径节点色,默认 '#145AFD'
}
<KgGraph
  data={data}
  colors={{
    nodeLabelColor: '#333',
    normalNodeColor: '#52c41a',
    uriNodeColor: '#faad14',
    edgeDefaultColor: '#d9d9d9',
    pathHighlightColor: '#f5222d',
  }}
/>

ActionBar 工具栏

ActionBarConfig

interface ActionBarConfig {
  position?: 'top' | 'bottom' | 'left' | 'right';   // 位置预设
  positionDetail?: { top?, right?, bottom?, left? }; // 微调偏移
  actionList?: ActionBarItem[];                        // 按钮列表
  isExpand?: boolean;                                  // 默认展开
}

interface ActionBarItem {
  key: string;                      // 唯一标识
  title: string;                    // 显示文本
  icon?: React.ReactNode[];         // 图标(antd icon)
  onClick?: (cyRef) => void;        // 点击回调(覆盖默认行为)
}

内置按钮

| key | 说明 | |-----|------| | queryStatistics | 实体/关系统计面板 | | layout | 8 种布局切换 | | graphDisplaySettings | 节点/边样式设置 | | analysis | 查询节点 / 连接分析 / 路径分析 | | select | 全选 / 反选 / 点选 / 框选 | | downloadData | JSON / Excel / PNG / JPG 导出 | | hideAttributes | 切换 typed-literal 节点显隐 | | textPosition | 文字位置(居中/上下左右) | | clearCanvas | 清空画布 | | nodeZoom | 节点缩放(0.1x - 5x) | | canvasZoom | 画布缩放(0.1x - 3x) | | tablelist | 节点/边数据表格 |

// 筛选内置按钮
<KgGraph
  actionBar={{
    position: 'left',
    isExpand: true,
    actionList: actionList.filter(item => ['queryStatistics', 'layout'].includes(item.key)),
  }}
/>

// 自定义按钮
<KgGraph
  actionBar={{
    actionList: [
      { key: 'customBtn', title: '自定义', icon: [<MyIcon key="1" />], onClick: () => console.log('click') },
    ],
  }}
/>

// 隐藏工具栏
<KgGraph data={data} actionBar={false} />

右键菜单(actionCircle)

interface ActionCircleItem {
  ids: string;                    // 唯一标识
  label: string;                  // 显示文本
  onClick?: (node) => void;       // 覆盖默认行为
}

内置菜单项

| ids | 说明 | |-----|------| | contract | 展收实体(types='uri',调用 stepNextApi) | | expanded | 展收属性(types='typed-literal',调用 stepNextApi) | | nodeInfo | 节点样式编辑 Drawer | | knowledgeCard | 知识卡片 Drawer | | nodeOperate | 节点操作面板(编辑模式) |

<KgGraph
  actionCircle={[
    { ids: 'contract', label: '展收实体' },
    { ids: 'expanded', label: '展收属性' },
    { ids: 'customNew', label: '自定义', onClick: (node) => alert(node.id()) },
  ]}
/>

图谱编辑器(graphEditor)

interface GraphEditorConfig {
  show?: boolean;                                    // 显示编辑器按钮
  oprateFlowFunction?: (flow: {                      // 操作流转回调
    operationHistory: OperationRecord[];
    sparqlStr: string;
  }) => void;
}

启用编辑器后,可新增/删除节点和关系,操作记录自动收集到 operationHistory

布局

| 布局 | 适用场景 | |------|---------| | cose-bilkent(默认) | 通用,大型图 | | fcose | 大型图,快速力导向 | | cose | 中大型图 | | cise | 聚类分组 | | grid | 规整排列 | | circle | 环状结构 | | breadthfirst | 树形/层级 | | concentric | 辐射状关系 |

展开节点时内部使用 concentric 环形布局 + 淡入淡出动画,自动寻找空白区域避免重叠。

数据导出

| 格式 | 说明 | |------|------| | JSON | 完整图谱数据 | | Excel | 节点/边表格 | | PNG | 画布截图(白色背景) | | JPG | 画布截图 |

License

MIT