Echarts-知识图谱

Echarts-知识图谱

demo地址

打开CodePen

效果

思路

1. 生成根节点
2. 根据子节点距离与根节点的角度关系,生成子节点坐标,进而生成子节点
3. 从子节点上按角度生成对应的子节点
4. 递归将根节点与每一层级子节点连线

核心代码

  • 定义节点配置
function getNodeConfig() {return {/** 节点间距 */nodeLine: 120,/** 节点大小 */nodeSize: 100,/** 子节点间距 */subNodeLine: 40,/** 子节点大小 */subNodeSize: 60};
}
  • 创建节点位置
function createNodePos({ index: i, len: iLen }) {const { nodeLine } = getNodeConfig();const radioDeg = (Math.PI * 2) / iLen;const deg = i * radioDeg + Math.PI / 4;const x = nodeLine * Math.cos(deg);const y = nodeLine * Math.sin(deg);const pos = { x, y };return pos;
}
  • 创建子节点位置
function createSubNodePos({ index: i, len: iLen }, { index: j, len: jLen }) {const { nodeLine, subNodeLine } = getNodeConfig();const radioDeg = (Math.PI * 2) / iLen;const deg = i * radioDeg + Math.PI / 4;const parentX = nodeLine * Math.cos(deg);const parentY = nodeLine * Math.sin(deg);const subRadioDeg = (Math.PI * 2) / (jLen + 1);const subDeg = j * subRadioDeg + (Math.PI / 2) * 3 + deg;const x = parentX + subNodeLine * Math.cos(subDeg);const y = parentY + subNodeLine * Math.sin(subDeg);const pos = { x, y };return pos;
}
  • 创建节点和链接
function initOption(root) {root.categoryItem = categories?.[root?.category] || {};const list = chartList || [];const graph = {...createNodesLinks(list, root),categories};const chartOption = {color: categories?.map((item) => item?.color),legend: [{orient: 'vertical',left: 0,data: graph.categories.map(function (a) {return a.name;})}],tooltip: {formatter: (params) => {return params?.data?.name;}},animationDuration: 1500,animationEasingUpdate: 'quinticInOut',series: [{type: 'graph',layout: 'none',force: {repulsion: 100},data: graph.nodes,links: graph.links,categories: graph.categories,roam: true,label: {show: true,width: 36,height: 36,overflow: 'breakAll',color: '#f2f2f2',formatter: (params) => {const { name = '', id } = params?.data || {};const len = id === rootId ? 20 : 10;return name?.length > len ? name?.slice(0, len) + '...' : name;}},lineStyle: {color: 'source',curveness: 0.3},emphasis: {focus: 'adjacency',disabled: true,lineStyle: {width: 10}}}]};option = chartOption;
}function createNodesLinks(list = [], root = {}) {const nodes = [];const links = [];const { nodeSize, subNodeSize } = getNodeConfig();nodes.push({id: rootId,category: 0,name: '根节点',...root,symbolSize: nodeSize,x: 0,y: 0});for (let i = 0; i < list.length; i++) {const iIndex = String(i);const categoryItem = categories?.[i];nodes.push({id: iIndex,category: i,symbolSize: 1,label: {show: false},name: categoryItem?.name,...createNodePos({ index: i, len: list.length })});links.push({source: rootId,target: iIndex});for (let j = 0; j < list[i].length; j++) {const jIndex = `${i}.${j}`;const jItem = _.get(list, jIndex, {});nodes.push({id: jIndex,category: i,symbolSize: subNodeSize,...jItem,...createSubNodePos({ index: i, len: list.length }, { index: j, len: list[i].length })});links.push({source: iIndex,target: jIndex});}}return { nodes, links };
};
  • 初始化
function init() {const { id, name, key } = { id: '1', name: '青霉素', key: 'drug-research' }const category = categories?.findIndex((item) => item?.key === key);const categoryItem = categories?.[category];initOption({category,dataId: id,name,id: rootId})
}

完整代码

var dom = document.getElementById('chart-container');
var myChart = echarts.init(dom, null, {renderer: 'canvas',useDirtyRect: false
});
var app = {};var option;const categories = [{name: '药物',color: 'rgba(0, 136, 184, 1)',key: 'drug-research',enumKey: 'Drug',fieldKey: 'drug',idKey: 'drug_uid',nameKey: 'drug_name_cn',nameEnKey: 'drug_name_en'},{name: '靶点',color: 'rgba(7, 214, 205, 1)',key: 'target-spot',enumKey: 'Target',fieldKey: 'target',idKey: 'target_uid',nameKey: 'target_name'},{name: '适应症',color: 'rgba(236, 153, 41, 1)',key: 'indications',enumKey: 'Indication',fieldKey: 'indication',idKey: 'indication_uid',nameKey: 'indication_name'},{name: '企业',color: 'rgba(210, 142, 200, 1)',key: 'company',enumKey: 'Entity',fieldKey: 'entity',idKey: 'entity_uid',nameKey: 'entity_name'},{name: '药物设计技术',color: 'rgba(255, 192, 185, 1)',key: 'drug-tech',enumKey: 'Tech',fieldKey: 'tech',idKey: 'tech_name',nameKey: 'tech_name'}];const rootId = 'root';const serverMapData = {"drug": [{"drug_uid": "1","drug_name_cn": "药物1","drug_name_en": "药物en"},{"drug_uid": "2","drug_name_cn": "药物2","drug_name_en": "药物en"},{"drug_uid": "3","drug_name_cn": "药物3","drug_name_en": "药物en"},{"drug_uid": "4","drug_name_cn": "药物4","drug_name_en": "药物en"},{"drug_uid": "5","drug_name_cn": "药物5","drug_name_en": "药物en"},],"target": [{"target_uid": "1","target_name": "靶点1","target_code": ["string"]},{"target_uid": "2","target_name": "靶点2","target_code": ["string"]},{"target_uid": "3","target_name": "靶点3","target_code": ["string"]},{"target_uid": "4","target_name": "靶点4","target_code": ["string"]},{"target_uid": "5","target_name": "靶点5","target_code": ["string"]},],"indication": [{"indication_uid": "1","indication_name": "适应症1","indication_code": ["string"]},{"indication_uid": "2","indication_name": "适应症2","indication_code": ["string"]},{"indication_uid": "3","indication_name": "适应症3","indication_code": ["string"]},{"indication_uid": "4","indication_name": "适应症4","indication_code": ["string"]},{"indication_uid": "5","indication_name": "适应症5","indication_code": ["string"]},],"entity": [{"entity_uid": "1","entity_name": "企业1","entity_code": ["string"]},{"entity_uid": "2","entity_name": "企业2","entity_code": ["string"]},{"entity_uid": "3","entity_name": "企业3","entity_code": ["string"]},{"entity_uid": "4","entity_name": "企业4","entity_code": ["string"]},{"entity_uid": "5","entity_name": "企业5","entity_code": ["string"]},],"tech": [{"tech_name": "技术1"},{"tech_name": "技术2"},{"tech_name": "技术3"},{"tech_name": "技术4"},{"tech_name": "技术5"},]
}const chartList = categories?.map((categoryItem) => {const dataList = serverMapData?.[categoryItem?.fieldKey] || [];return dataList?.map((item) => {return {...item,categoryItem,dataId: item?.[categoryItem?.idKey],name: item?.[categoryItem?.nameKey] || item?.[categoryItem?.nameEnKey]};});
});init();function init() {const { id, name, key } = { id: '1', name: '青霉素', key: 'drug-research' }const category = categories?.findIndex((item) => item?.key === key);const categoryItem = categories?.[category];initOption({category,dataId: id,name,id: rootId})
}function initOption(root) {root.categoryItem = categories?.[root?.category] || {};const list = chartList || [];const graph = {...createNodesLinks(list, root),categories};const chartOption = {color: categories?.map((item) => item?.color),legend: [{orient: 'vertical',left: 0,data: graph.categories.map(function (a) {return a.name;})}],tooltip: {formatter: (params) => {return params?.data?.name;}},animationDuration: 1500,animationEasingUpdate: 'quinticInOut',series: [{type: 'graph',layout: 'none',force: {repulsion: 100},data: graph.nodes,links: graph.links,categories: graph.categories,roam: true,label: {show: true,width: 36,height: 36,overflow: 'breakAll',color: '#f2f2f2',formatter: (params) => {const { name = '', id } = params?.data || {};const len = id === rootId ? 20 : 10;return name?.length > len ? name?.slice(0, len) + '...' : name;}},lineStyle: {color: 'source',curveness: 0.3},emphasis: {focus: 'adjacency',disabled: true,lineStyle: {width: 10}}}]};console.log('chartOption', chartOption)option = chartOption;}function createNodesLinks(list = [], root = {}) {const nodes = [];const links = [];const { nodeSize, subNodeSize } = getNodeConfig();nodes.push({id: rootId,category: 0,name: '根节点',...root,symbolSize: nodeSize,x: 0,y: 0});for (let i = 0; i < list.length; i++) {const iIndex = String(i);const categoryItem = categories?.[i];nodes.push({id: iIndex,category: i,symbolSize: 1,label: {show: false},name: categoryItem?.name,...createNodePos({ index: i, len: list.length })});links.push({source: rootId,target: iIndex});for (let j = 0; j < list[i].length; j++) {const jIndex = `${i}.${j}`;const jItem = _.get(list, jIndex, {});nodes.push({id: jIndex,category: i,symbolSize: subNodeSize,...jItem,...createSubNodePos({ index: i, len: list.length }, { index: j, len: list[i].length })});links.push({source: iIndex,target: jIndex});}}return { nodes, links };};function getNodeConfig() {return {nodeLine: 120,nodeSize: 100,subNodeLine: 40,subNodeSize: 60};}function createNodePos({ index: i, len: iLen }) {const { nodeLine } = getNodeConfig();const radioDeg = (Math.PI * 2) / iLen;const deg = i * radioDeg + Math.PI / 4;const x = nodeLine * Math.cos(deg);const y = nodeLine * Math.sin(deg);const pos = { x, y };return pos;}function createSubNodePos({ index: i, len: iLen }, { index: j, len: jLen }) {const { nodeLine, subNodeLine } = getNodeConfig();const radioDeg = (Math.PI * 2) / iLen;const deg = i * radioDeg + Math.PI / 4;const parentX = nodeLine * Math.cos(deg);const parentY = nodeLine * Math.sin(deg);const subRadioDeg = (Math.PI * 2) / (jLen + 1);const subDeg = j * subRadioDeg + (Math.PI / 2) * 3 + deg;const x = parentX + subNodeLine * Math.cos(subDeg);const y = parentY + subNodeLine * Math.sin(subDeg);const pos = { x, y };return pos;}if (option && typeof option === 'object') {myChart.setOption(option);
}window.addEventListener('resize', myChart.resize);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/541.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot实现车辆管理系统设计项目【项目源码+论文说明】计算机毕业设计

基于springboot实现车辆管理系统演示 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了车辆管理系统的开发全过程。通过分析车辆管理系统管理的不足&#xff0c;创建了一个计算机管理车辆管理系统的方案。文章介…

黑洞路由、 DDoS 攻击 、 环路

黑洞路由 DDoS 攻击 DDoS 攻击是一种针对服务器、服务或网络的恶意行为。DDoS 攻击通过向目标发送大量流量&#xff0c;使其不堪重负&#xff0c;导致资源和带宽被耗尽。因此&#xff0c;目标可能会变慢或崩溃&#xff0c;无法正常处理合法的流量。DDoS 攻击通常是由僵尸网络…

在龙梦迷你电脑福珑2.0上使用Fedora 28 龙梦版

在龙梦迷你电脑福珑2.0上使用Fedora 28 龙梦版。这个版本的操作系统ISO文件是&#xff1a;Fedora28_for_loongson_MATE_Live_7.2.iso 。它在功能方面不错。能放音乐&#xff0c;能看cctv直播&#xff0c;有声音&#xff0c;能录屏&#xff0c;能在局域网里用PuTTY的ssh方式连接…

《苏东坡 传》一蓑烟雨任平生

《苏东坡 传》一蓑烟雨任平生 林语堂&#xff0c;中国现代著名作家、学者、翻译家、语言学家。 张振玉 译 文章目录 《苏东坡 传》一蓑烟雨任平生[toc]摘录小结感悟 摘录 苏东坡是个秉性难改的乐天派&#xff0c;是悲天悯人的道德家&#xff0c;是黎民百姓的好朋友&#xff0c;…

C语言C/S架构PACS影像归档和通信系统源码 医院PACS系统源码

C语言C/&#xff33;架构PACS影像归档和通信系统源码 医院PACS系统源码 医院影像科PACS系统&#xff0c;意为影像归档和通信系统。它是应用在医院影像科室的系统&#xff0c;主要的任务是把日常产生的各种医学影像&#xff08;包括核磁、CT、超声、各种X光机、各种红外仪、显微…

JAVA ASM总结篇-03

MethodVisitor ClassVisitor的visitMethod能够访问到类中某个方法的一些入口信息&#xff0c;那么针对具体方法中字节码的访问是由MethodVisitor来进行的 访问顺序如下&#xff0c;其中visitCode和visitMaxs仅调用一次&#xff0c;标志方法字节码访问的开始和结束 MethodVisi…

不羁联盟怎么参与测试 不羁联盟测试时间+参与测试方法分享

不羁联盟怎么参与测试 不羁联盟测试时间参与测试方法分享 《不羁联盟》是由育碧&#xff08;Ubisoft&#xff09;开发的一款6v6团队合作射击游戏。游戏的背景设定在一个后启示录时代的废土世界中&#xff0c;玩家能够身临其境地感受到废土世界的荒凉和残酷。游戏在内测时候就受…

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台级联时,下级平台未发流是什么原因?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

AUTOCAD输出或打印PDF文件时,如何将图形居中且布满图纸?

AUTOCAD输出或打印PDF文件时,如何将图形居中且布满图纸? 如下图所示,我们打开一份DWG格式的图纸文件,然后点击上方的“打印“图标, 如下图所示, 打印机/绘图仪这里选择“DWG To PDF“; 图纸尺寸:这里以普通的A4纸为例进行说明; 打印比例选择“布满图纸“; 打印偏移…

优维应用级数字化架构管理:让企业运维天堑变通途

在优维科技的产品视角中&#xff0c;数字化架构管理就像是一门精妙的艺术&#xff0c;它将上层应用模型的业务概念以可视化的方式呈现出来&#xff0c;使得业务逻辑和流程变得更加直观、清晰。我们将这样的管理方式理解为“给企业搭起一座桥梁”——在这座桥梁的搭建过程中&…

express服务器 authorization 前端获取不到的问题

服务器生成token 设置在响应头&#xff0c;但是前端获取不到 const token JWT.generate({ id: new Date().getTime(), userName }, 10s) res.header(Authorization, token) axios.interceptors.response.use((response) > {console.log(response);if (response.data?.co…

破解费用管理迷局,企业费用管理从不止于报销

数字化变革浪潮下&#xff0c;各种企业费用报销软件如雨后春笋般不断涌现&#xff0c;企业报销效率大幅提升&#xff0c;部分财务处理流程得到固化和优化&#xff0c;报销早已不再是企业费时费力的财务难题。那么&#xff0c;企业费用管里如何实现呢&#xff1f; 企业费用贯穿于…

ubuntu上安装调试SVN服务

刚成立团队需要临时搭建一台SVN服务器&#xff0c;所以对照网上的一些提示做了下&#xff0c;操作起来不复杂&#xff0c;还是踩了不少坑&#xff0c;顺便原理性了解了下。 主要操作步骤如下&#xff1a; 1&#xff1a;安装svn sudo apt-get install subversion 2: 创建svn版…

NVIDIA智算中心“产品”上市,AI工业革命的iPhone时刻

GTC 2024落下帷幕了&#xff0c;但这个大会的信息仍在AI产业和经济中发酵。咨询机构WIKIBON认为&#xff0c;GTC 2024在整个科技史中的意义超过了当年史蒂夫乔布斯的iPod和iPhone发布。在AI将永久改变人类的共识下&#xff0c;GTC 2024在广度、愿景、生态系统等方面都有着深远影…

Nacos注册中心的使用

一&#xff1a;服务注册 步骤如下&#xff1a; 引入依赖 配置Nacos地址 重启 1、添加依赖 在需要注册的项目的pom.xml中添加依赖&#xff1a; <!--nacos 服务注册发现--> <dependency><groupId>com.alibaba.cloud</groupId><artifactId>s…

利用Python进行大规模数据处理【第173篇—数据处理】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 利用Python进行大规模数据处理&#xff1a;Hadoop与Spark的对比 随着数据量的不断增长&…

ros仿真启动小龟

1.启动RosMaster&#xff08;管理Ros中各个节点的“大管家”&#xff0c;每次启动Ros时需要首先启动RosMaster&#xff09; roscorefangfang-inspiron-5580:~/ros2/download/rosdistro$ roscore ... logging to /home/fang/.ros/log/6ec2d790-fe1d-11ee-aba8-1c1bb5cdec7c/ros…

java多线程-线程通信

简介 最常见的模式&#xff1a;生产者-消费者模式 线程通信模型 常见API 生产者抢到资源&#xff0c;生成资源&#xff0c;自己进入等待&#xff0c;唤醒消费者消费者抢到资源&#xff0c;消费数据&#xff0c;自己进入等待&#xff0c;唤醒生产者 定义容器 定义一个容器&#…

python/pygame 挑战魂斗罗 笔记(二)

一、建立地面碰撞体&#xff1a; 现在主角Bill能够站立在游戏地图的地面&#xff0c;是因为我们初始化的时候把Bill的位置固定了self.rect.y 250。而不是真正的站在地图的地面上。 背景地图是一个完整的地图&#xff0c;没有地面、台阶的概念&#xff0c;就无法通过碰撞检测来…

上位机图像处理和嵌入式模块部署(树莓派4b实现固件主流程)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 软件开发一般有软件需求、架构设计和详细设计、软件测试这四个部分。软件需求和软件测试都比较好理解&#xff0c;前者是说要实现哪些功能&#xf…