echarts关系图参考 https://echarts.apache.org/examples/zh/editor.html?c=graph-circular-layout
import React, { useEffect, useState } from 'react';import { array, bool, number } from 'prop-types';import { TooltipComponent, LegendComponent } from 'echarts/components';import { GraphChart } from 'echarts/charts';import Echarts, { chartHeight, sanKeyColor } from '@/components/Echarts';import nodeObj from './nodes.json';function nodeSource({ nodes, calls }) {const nodeTypes = nodes.map(it => it.type);// [{name: "tcp"}, {name: "http"}]const legendData = [...new Set(nodeTypes)].map(name => ({ name }));const links = (calls || []).reduce((prev, next, index) => {const { source, target } = next;const item = { index, source: source.id, target: target.id };prev.push(item);return prev;}, []);const _nodes = (nodes || []).reduce((prev, next, index) => {const { id, name, type } = next;const item = { id, name, category: type, label: { show: true } };prev.push(item);return prev;}, []);return { nodes: _nodes, links, legendData };}Chart.propTypes = {dataSource: array,height: number,loading: bool,};Chart.defaultProps = {dataSource: [],height: chartHeight,loading: false,};function Chart({ dataSource, height, loading }) {const [options, setOptions] = useState({});useEffect(update, [dataSource]);function update() {const OPTIONS = getOptions();setOptions(OPTIONS);}function getOptions() {const { nodes, links, legendData } = nodeSource(nodeObj);return {'tooltip': {},'color': ['#6be6c1','#a0a7e6','#96dee8','#3f96e3','#3fb1e3','#6be6c1','#626c91','#a0a7e6','#c4ebad','#96dee8',],'legend': {'top': 24,'textStyle': {'color': '#ddd',},'data': legendData,},'series': [{'top': '20%','height': '60%','name': '服务','type': 'graph','layout': 'circular','circular': {'rotateLabel': true,},data: nodes,links,'categories': legendData,'roam': true,'label': {'position': 'right','formatter': '{b}',},'lineStyle': {'color': 'source','curveness': 0.3,},},],};}const attrs = {options,height: 640,loading,components: [TooltipComponent,LegendComponent,GraphChart,],renderType: 'svg'};return (<Echarts {...attrs} />);}export default Chart;
click

function onClick() {const myChart = this.$refs.radial.myChart;myChart.on('click', (params) => {const currentNode = nodes.find(it => it.id === params.data.id);const payload = currentNode || {};this.$store.commit('rocketTopo/SET_NODE', payload);});}

关系图数据
const links = [{'index': 0,'source': 'Ym9va2luZm86OnByb2R1Y3RwYWdl.1','target': 'Ym9va2luZm86OmRldGFpbHM=.1',},{'index': 1,'source': 'Ym9va2luZm86OnByb2R1Y3RwYWdl.1','target': 'Ym9va2luZm86OnJldmlld3M=.1',},{'index': 2,'source': 'Ym9va2luZm86OnJhdGluZ3M=.1','target': 'Ym9va2luZm86Om1vbmdvZGI=.1',},{'index': 3,'source': 'Ym9va2luZm86OnJldmlld3M=.1','target': 'Ym9va2luZm86OnJhdGluZ3M=.1',},{'index': 4,'source': 'Ym9va2luZm86Om1vbmdvZGI=.1','target': 'Ym9va2luZm86Om1vbmdvZGI=.1',},{'index': 5,'source': 'Ym9va2luZm86OnJldmlld3M=.1','target': 'Ym9va2luZm86Om1vbmdvZGI=.1',},{'index': 6,'source': 'Ym9va2luZm86OnJhdGluZ3M=.1','target': 'a3ViZS1zeXN0ZW06Omt1YmUtZG5z.1',},{'index': 7,'source': 'Ym9va2luZm86OnRyYWZmaWNnZW5lcmF0b3I=.1','target': 'Ym9va2luZm86OnByb2R1Y3RwYWdl.1',},{'index': 8,'source': 'Ym91dGlxdWU6OmVtYWlsc2VydmljZQ==.1','target': 'Ym9va2luZm86OmRldGFpbHM=.1',},{'index': 9,'source': 'Ym91dGlxdWU6OmVtYWlsc2VydmljZQ==.1','target': 'Ym9va2luZm86OnJldmlld3M=.1',},{'index': 10,'source': 'Ym91dGlxdWU6OmZyb250ZW5kLWV4dGVybmFs.1','target': 'Ym9va2luZm86OnJldmlld3M=.1',},{'index': 11,'source': 'Y2VydC1tYW5hZ2VyOjpjZXJ0LW1hbmFnZXItd2ViaG9vaw==.1','target': 'Ym9va2luZm86OnByb2R1Y3RwYWdl.1',},]const nodes = [{'id': 'Ym9va2luZm86OnRyYWZmaWNnZW5lcmF0b3I=.1','name': 'bookinfo::trafficgenerator','label': {'show': true,},},{'id': 'a3ViZS1zeXN0ZW06Omt1YmUtZG5z.1','name': 'kube-system::kube-dns','label': {'show': true,},'category': 'tcp',},{'id': 'Ym9va2luZm86OmRldGFpbHM=.1','name': 'bookinfo::details','label': {'show': true,},'category': 'http',},{'id': 'Y2VydC1tYW5hZ2VyOjpjZXJ0LW1hbmFnZXItd2ViaG9vaw==.1','name': 'cert-manager::cert-manager-webhook','label': {'show': true,},},{'id': 'Ym9va2luZm86OnByb2R1Y3RwYWdl.1','name': 'bookinfo::productpage','label': {'show': true,},'category': 'http',},{'id': 'Ym9va2luZm86OnJldmlld3M=.1','name': 'bookinfo::reviews','label': {'show': true,},'category': 'http',},{'id': 'Ym91dGlxdWU6OmVtYWlsc2VydmljZQ==.1','name': 'boutique::emailservice','label': {'show': true,},},{'id': 'Ym91dGlxdWU6OmZyb250ZW5kLWV4dGVybmFs.1','name': 'boutique::frontend-external','label': {'show': true,},},{'id': 'Ym9va2luZm86OnJhdGluZ3M=.1','name': 'bookinfo::ratings','label': {'show': true,},'category': 'http',},{'id': 'Ym9va2luZm86Om1vbmdvZGI=.1','name': 'bookinfo::mongodb','label': {'show': true,},'category': 'http',},]
