当前位置: 首页 > article >正文

echarts graphChart关系图简单逻辑实现

ECharts 的 graph 图表类型非常适合用来展示节点之间的关系,比如社交网络分析、系统架构图等。下面是一个简单的关系图功能,用来展示疾病与一些因素的关联关系。
在这里插入图片描述

1、数据之间的关系

首先,你需要准备数据来表示节点(nodes)和它们之间的边(links)。节点通常包括节点的名称或 ID,而边则包含两个节点之间的连接信息。

var data = {
    nodes: [
   	   {
         name: '疾病名称',
         symbolSize: [100, 100],
         itemStyle: {
           color: '#C280FF',
           borderColor: '#000'
         },
         value: '123456'
       }, {
         name: '食物1',
         symbolSize: [80, 80],
         itemStyle: {
           color: '#CAF982'
         },
         value: '123457'
       }, {
         name: '化合物1',
         symbolSize: [80, 80],
         itemStyle: {
           color: '#FACD91'
         },
         value: '123458'
       }, {
         name: '生活方式1',
         symbolSize: [80, 80],
         itemStyle: {
           color: '#FFFF80'
         },
         value: '123459'
       }, {
         name: '膳食模式1',
         symbolSize: [80, 80],
         itemStyle: {
           color: '#80FFFF'
         },
         value: '1234510'
       }
    ],
    links: [
        {
           target: '食物1',
           source: '疾病名称',
           category: 'Food'
         }, {
           target: '化合物1',
           source: '疾病名称',
           category: 'Compound'
         }, {
           target: '生活方式1',
           source: '疾病名称',
           category: 'lifestyle'
         }, {
           target: '膳食模式1',
           source: '疾病名称',
           category: 'dietary_pattern'
         }
    ]
};

通过仔细观察你会发现,nodes里面的数组存放的是将要展示倒关系图中的节点数据,links里面的数组存放的是,节点直接的联系。在我这个功能里,nodes的第一个节点元素是中间节点,其他节点要以它为中心进行环形分布。links中节点的target属性表示指向那个node节点,source表示将要围绕的节点,category是节点的分类,在下面的操作中我们将根据这个属性找到节点关系饼图的数据。

2、点击事件

chartClick (params) {
  console.log('click', params)
  if (params.componentType === 'series') {
    if (params.seriesType === 'graph') {
      if (params.dataType === 'edge') {
        // 点击到了 graph 的 edge(边)上。
        console.log('点击到了 graph 的 edge(边)上')
        this.showLinkModal(params)
      } else {
        // 点击到了 graph 的 node(节点)上。
        console.log('点击到了 graph 的 node(节点)上')
        if (params.dataIndex > 0) {
          this.showNodeModal(params)
        }
      }
    }
  }
}

通过click事件执行一个回调函数,就可以拿到我们想要的信息,然后去执行一些业务操作。

this.myChart.on('click', function (params) {
 _this.$emit('chartClick', params)
})

3、echarts 组件模板

<template>
  <div
    :ref="`echartsComponent${random}`"
    :style="{ width: width, 'height': height }"
  ></div>
</template>

<script>
import { createRandomId } from '@/libs'
import * as echarts from 'echarts'
export default {
  computed: {
    random: function () {
      return createRandomId()
    }
  },
  props: {
    width: {
      default: '100%',
      type: String
    },
    height: {
      default: '100px',
      type: String
    }
  },
  data () {
    return {
      myChart: null
    }
  },
  mounted () {
  },
  methods: {
    initData (data) {
      const _this = this
      this.$nextTick(() => {
        this.myChart = echarts.init(this.$refs[`echartsComponent${this.random}`])
        this.myChart.setOption(data)
        this.myChart.on('click', function (params) {
          _this.$emit('chartClick', params)
        })
      })
    },
    disposeCharts () {
      this.myChart.dispose()
    },
    resetData (data) {
      this.myChart.setOption(data)
    }

  }
}
</script>

4、简单关系图示例

<template>
  <Modal
    v-model="visible"
    :title="title"
    width="1000"
    footer-hide
    @on-cancel="cancel"
  >
    <echarts-item ref="graphChart" height="900px" @chartClick="chartClick" />
    <node-modal ref="nodeModalRef" />
    <link-modal ref="linkModalRef" />
  </Modal>
</template>
<script>
  import EchartsItem from '@/components/EchartsItem'
  import NodeModal from './NodeModal'
  import LinkModal from './LinkModal'
  export default {
    components: {
      EchartsItem,
      NodeModal,
      LinkModal
    },
    data () {
      return {
        title: '',
        visible: false,
        // 关系图数据
        nodeData: [],
        chartData: []
      }
    },
    methods: {
      init (nodeData, options) {
        this.visible = true
        this.nodeData = nodeData
        this.$nextTick(() => {
          this.initChart(options)
        })
      },
      cancel () {
        this.visible = false
        this.$refs.nodeModalRef.cancel()
        this.$refs.linkModalRef.cancel()
      },
      initChart () {
        const options = {
          title: '',
          tooltip: {
            show: false
          },
          legend: {
            show: false
          },
          xAxis: {
            show: false
          },
          yAxis: {
            show: false
          },
          series: [{
            type: 'graph',
            roam: true,
            focusNodeAdjacency: true,
            force: {
              // 节点之间的斥力因子
              repulsion: 1400,
              // 边的两个节点之间的距离
              edgeLength: [300, 350]
            },
            layout: 'force',
            symbol: 'circle',
            // 图形是否不响应和触发鼠标事件,默认为 false,即响应和触发鼠标事件。
            // silent: true,
            // 是否开启动画
            animation: false,
            itemStyle: {
              borderColor: '#333'
            },
            lineStyle: {
              color: '#333',
              width: 2,
              type: 'solid',
              opacity: 0.5,
              // curveness: 0.5
            },
            label: {
              show: true,
              position: 'inside',
              textStyle: {
                fontSize: 16
              }
            },
            // 关系线上的lable
            edgeLabel: {
              normal: {
                show: false,
                textStyle: {},
                formatter: function (param) {
                  return param.data.category
                }
              }
            },
            data: [{
              name: '疾病名称',
              symbolSize: [100, 100],
              itemStyle: {
                color: '#C280FF',
                borderColor: '#000'
              },
              value: '123456'
            }, {
              name: '食物1',
              symbolSize: [80, 80],
              itemStyle: {
                color: '#CAF982'
              },
              value: '123457'
            }, {
              name: '化合物1',
              symbolSize: [80, 80],
              itemStyle: {
                color: '#FACD91'
              },
              value: '123458'
            }, {
              name: '生活方式1',
              symbolSize: [80, 80],
              itemStyle: {
                color: '#FFFF80'
              },
              value: '123459'
            }, {
              name: '膳食模式1',
              symbolSize: [80, 80],
              itemStyle: {
                color: '#80FFFF'
              },
              value: '1234510'
            }],
            // 节点间的关系数据
            links: [{
              target: '食物1',
              source: '疾病名称',
              category: 'Food'
            }, {
              target: '化合物1',
              source: '疾病名称',
              category: 'Compound'
            }, {
              target: '生活方式1',
              source: '疾病名称',
              category: 'lifestyle'
            }, {
              target: '膳食模式1',
              source: '疾病名称',
              category: 'dietary_pattern'
            }]
          }]
        }
        this.$refs.graphChart.initData(options)      
      },
      chartClick (params) {
        console.log('click', params)
        if (params.componentType === 'series') {
          if (params.seriesType === 'graph') {
            if (params.dataType === 'edge') {
              // 点击到了 graph 的 edge(边)上。
              console.log('点击到了 graph 的 edge(边)上')
              this.showLinkModal(params)
            } else {
              // 点击到了 graph 的 node(节点)上。
              console.log('点击到了 graph 的 node(节点)上')
              if (params.dataIndex > 0) {
                this.showNodeModal(params)
              }
            }
          }
        }
      },
      showNodeModal (params) {
        const node = this.nodeData[params.dataIndex - 1]
        const options = {
          legend: {
            icon: 'circle',
            left: 'center',
            bottom: '5%',
            itemWidth: 10
          },
          label: {
            formatter: '{c}'
          },
          color: ['#6395fa','#f56e53','#fbb120'],
          series: [
            {
              name: 'Access From',
              type: 'pie',
              radius: '50%',
              center: ['50%', '40%'],
              data: [
                { value: 1048, name: 'Positive' },
                { value: 735, name: 'Negative' },
                { value: 580, name: 'Relative' }
              ],
              emphasis: {
                itemStyle: {
                  shadowBlur: 10,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
              }
            }
          ]
        }
        // 食物和化合物的时候显示
        if (node.category === 'Disease' || node.category === 'Food' || node.category === 'Compound') {
          this.$refs.nodeModalRef.init(node.name, node.category, options, node.showType)
        }
      },
      showLinkModal (params) {
        const infoList = [
          {
            category: 'Ariticles',
            list: [
              {
                id: 1,
                title: 'The optimal ratio of fat-to-carbohydrate in the diet.'
              },
              {
                id: 2,
                title: 'The hypobetalipoproteinemias.'
              }
            ]
          },
          {
            category: 'Clinical Trials',
            list: [
              {
                id: 3,
                title: 'Microbiota, Metabolome and Nutrition: an \'Artificially Intelligent\' Way to Personalized Nutrition'
              }
            ]
          }
        ]
        this.$refs.linkModalRef.init(infoList)
      }
    }
  }
</script>

你可以根据需要调整各种配置项来改善图表的外观和交互性。例如,改变颜色方案、增加更多动画效果等。

总结

以上就是一个简单的使用 ECharts 绘制关系图的例子。


http://www.kler.cn/a/288223.html

相关文章:

  • 【重生之我要苦学C语言】深入理解指针6
  • 使用阿里云快速搭建 DataLight 平台
  • 企业一站式管理系统odoo的研究——PLM插件的搭建
  • `node-gyp` 无法找到版本为 `10.0.19041.0` 的 Windows SDK
  • 蓝队知识浅谈(上)
  • HTTP常见的状态码有哪些,都代表什么意思
  • linux-squid代理服务器
  • 微信小程序垃圾回收的前景方向
  • 09-02 周一 Ubuntu上使用docker-compose部署elasticsearch和kibana服务
  • k8s-pod 实战七 (PreStop 和 PostStart 详细分析)
  • .NET 一款具备签名用于绕过防护的工具
  • Git之2.35版本重要特性及用法实例(六十三)
  • 【前端面试】挖掘做过的nextJS项目4——全栈性案例
  • CNN在处理文本和图像时有什么共同点和不同点
  • Clobotics 计算机视觉场景存储实践:多云架构、 POSIX 全兼容、低运维的统一存储
  • 【Java】继承性【主线学习笔记】
  • React 入门第九天:与后端API的集成与数据管理
  • MySQL 使用C语言链接
  • 力扣238题详解:除自身以外数组的乘积的多种解法与模拟面试问答
  • 【Qt】对话框
  • K8s系列之:解释Kubernetes Operators
  • 71. 简化路径算法实现详解(goalng版)
  • 快速了解Rust 的数据分析库Polars
  • 常见概念 -- WSS光层环回
  • Django Admin优化查询
  • 金融知识普及月答题活动