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 = thisthis.$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><Modalv-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 = truethis.nodeData = nodeDatathis.$nextTick(() => {this.initChart(options)})},cancel () {this.visible = falsethis.$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}},// 关系线上的lableedgeLabel: {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 绘制关系图的例子。