Echarts-知识图谱

慈云数据 2024-04-23 技术支持 49 0

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  
          
          • 初始化
            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 
                            
                            
                            
微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon