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.rhkb.cn/news/314123.html

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

相关文章

10.接口自动化测试学习-Pytest框架(2)

1.mark标签 如果在每一个模块&#xff0c;每一个类&#xff0c;每一个方法和用例之前都加上mark标签&#xff0c;那么在pytest运行时就可以只运行带有该mark标签的模块、类、接口。 这样可以方便我们执行自动化时&#xff0c;自主选择执行全部用例、某个模块用例、某个流程用…

区块链技术与应用学习笔记(10-11节)——北大肖臻课程

目录 10.分岔 ①什么是分叉&#xff1f; ②导致分叉的原因&#xff1f; ③在比特币新共识规则发布会会导致什么分叉&#xff1f; 什么是硬分叉&#xff1f; 硬分叉例子&#xff1f; 什么是软分叉&#xff1f; 软分叉和硬分叉区别&#xff1f; 软分叉实例 11.问答 转…

茴香豆:搭建你的RAG智能助理-作业三

本次课程由书生浦语社区贡献者【北辰】老师讲解【茴香豆&#xff1a;搭建你的 RAG 智能助理】课程。分别是&#xff1a; RAG 基础介绍茴香豆产品简介使用茴香豆搭建RAG知识库实战 课程视频&#xff1a;https://www.bilibili.com/video/BV1QA4m1F7t4/ 课程文档&#xff1a;ht…

Scala的函数至简原则

对于scala语言来说&#xff0c;函数的至简原则是它的一大特色。下面让我们一起来看看分别有什么吧&#xff01; 函数至简原则&#xff1a;能省则省&#xff01; 初始函数 def test(name:String):String{return name }1、return可以省略&#xff0c;Scala会使用函数体的最后一…

Docker in Docker的原理与实战

Docker in Docker&#xff08;简称DinD&#xff09;是一种在Docker容器内部运行另一个Docker实例的技术。这种技术允许用户在一个隔离的Docker容器中创建、管理和运行其他Docker容器&#xff0c;从而提供了更灵活和可控的部署选项。以下是DinD的主要特点&#xff1a; 隔离性&am…

Linux下载及安装OpenSSL

文章目录 前言一、OpenSSL下载二、OpenSSL安装1.上传下载好的安装包到服务器2.解压3.切换目录4.配置config5.编译6.安装7.备份旧版本OpenSSL7.创建软链接8.添加OpenSSL动态链接库9.更新库缓存10.查看OpenSSL版本验证安装是否成功 前言 一般系统会自带有OpenSSL&#xff0c;我们…

ssm和springboot项目运行与部署

java项目可以打成jar包或者war包&#xff0c;以前SSM前后端不分离的项目&#xff0c;一般都是打成war包&#xff0c;现在前后端分离springboot项目&#xff0c;一般都是打成jar包&#xff0c;当然前后端分离springboot项目打成war包也可以。 总结&#xff1a; ssm项目 前后端分…

详细解析什么是期权交易的获利方法

期权交易的获利方法 在期权交易之前进行充分的准备工作和风险评估是至关重要的。其中行情结构、策略方法、预期收益和风险评估&#xff0c;是期权交易成功的关键要素。它们能帮助我们更好地制定交易计划&#xff0c;控制风险&#xff0c;并追求稳定的利润。以下是对这四点的详…

SpringBoot+MyBatis-Plus+jsqlparser实现多租户功能

前言 多租户技术&#xff08;multi-tenancy technology&#xff09;是一种软件架构技术&#xff0c;它允许在单个系统实例上为多个用户或组织提供服务&#xff0c;同时确保这些用户之间数据的隔离性。在多租户架构中&#xff0c;每个租户&#xff08;可以是个人用户、企业、组…

Golang | Leetcode Golang题解之第46题全排列

题目&#xff1a; 题解&#xff1a; func permute(nums []int) [][]int {var (n len(nums)dfs func(vals []int) // 已选择数 排列为vals 后续回溯继续选择 直至选完ans [][]int)dfs func(vals []int) {//边界if len(vals) n {ans append(ans, vals)}//转移 枚举选哪个f…

LM1875L-TB5-T 音频功率放大器 PDF中文资料_参数_引脚图

LM1875L-TB5-T 规格信息&#xff1a; 商品类型音频功率放大器 音频功率放大器的类型- 输出类型1-Channel (Mono) 作业电压16V ~ 60V 输出功率25W x 1 4Ω 额外特性过流保护,热保护 UTC LM1875是一款单片功率放大器&#xff0c;可为消费类音频应 用提供极低失真和高品质的…

Linux用户与权限

切换账户 su su [-] [用户名]- 可选&#xff0c;表示在切换用户后加载环境变量&#xff0c;一般都使用 用户名 可选&#xff0c;省略表示切换到root切换用户后&#xff0c;可以使用exit命令退回上一用户&#xff0c;或用快捷键ctrld 为普通命令授权 sudo sudo命令&#xff1a;…

算法06链表

算法06链表 一、链表概述1.1概述1.2链表的组成部分&#xff1a;1.3链表的优缺点&#xff1a; 二、链表典例力扣707.设计链表难点分析&#xff1a;&#xff08;1&#xff09;MyLinkedList成员变量的确定&#xff1a;&#xff08;2&#xff09;初始化自定义链表&#xff1a;&…

RIP最短路实验(华为)

思科设备参考&#xff1a;RIP最短路实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是一种基于距离矢量的内部网关协议&#xff0c;工作原理是每个路由器周期性地向邻居路由器发…

对EKS(AWS云k8s)启用AMP(AWS云Prometheus)监控+AMG(AWS云 grafana)

问题 需要在针对已有的EKS k8s集群启用Prometheus指标监控。而且&#xff0c;这里使用AMP即AWS云的Prometheus托管服务。好像这个服务&#xff0c;只有AWS国际云才有&#xff0c;AWS中国云没得这个托管服务。下面&#xff0c;我们就来尝试在已有的EKS集群上面启用AMP监控。 步…

vue 脚手架创建

脚手架创建 介绍 脚手架是什么呢&#xff0c;就是vue自动创建脚手架的项目模板&#xff0c;用于搭建项目的整体骨架&#xff0c;就比如后端开发时&#xff0c;咱们可以创建一个空项目&#xff0c;一步步创建为mvc项目&#xff0c;但是vs封装了mvc的框架&#xff0c;我们可以直…

[C++][算法基础]求组合数(I)

给定 &#x1d45b; 组询问&#xff0c;每组询问给定两个整数 &#x1d44e;&#xff0c;&#x1d44f;&#xff0c;请你输出 的值。 输入格式 第一行包含整数 &#x1d45b;。 接下来 &#x1d45b; 行&#xff0c;每行包含一组 &#x1d44e; 和 &#x1d44f;。 输出格…

VMware17Pro虚拟机安装macOS教程(超详细)

目录 1. 前言2. 下载所需文件3. 安装VMware3.1 安装3.2 启动并查看版本信息3.3 虚拟机默认位置配置 4. 安装补丁4.1 解压补丁4.2 结束VMware相关进程4.3 运行补丁包 5. 安装macOS5.1 新建虚拟机5.2 修改虚拟机配置5.3 安装操作系统5.3.1 选择 ISO 映像文件5.3.2 开启虚拟机5.2.…

07 流量回放实现自动化回归测试

在本模块的前四讲里&#xff0c;我向你介绍了可以直接落地的、能够支撑百万并发的读服务的系统架构&#xff0c;包含懒加载缓存、全量缓存&#xff0c;以及数据同步等方案的技术细节。 基于上述方案及细节&#xff0c;你可以直接对你所负责的读服务进行架构升级&#xff0c;将…

江苏开放大学2024年春《会计基础 050266》第二次任务:第二次过程性考核参考答案

电大搜题 多的用不完的题库&#xff0c;支持文字、图片搜题&#xff0c;包含国家开放大学、广东开放大学、超星等等多个平台题库&#xff0c;考试作业必备神器。 公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#…