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',
},
]