do some graph things

This commit is contained in:
nora 2022-03-26 15:46:12 +01:00
parent d77c31aaad
commit f1bded7192
6 changed files with 433 additions and 25 deletions

View file

@ -15,3 +15,7 @@ td {
border-collapse: collapse;
padding: 10px;
}
.graph {
height: 50vh;
}

View file

@ -0,0 +1,112 @@
import React from 'react';
import { GraphView } from 'react-digraph';
import { Binding, Data, Exchange } from '../types';
const sample = {
nodes: [
{
id: 1,
title: 'Exchange A',
type: 'empty',
},
{
id: 2,
title: 'Queue A',
type: 'empty',
},
],
edges: [
{
source: 1,
target: 2,
type: 'emptyEdge',
},
{
source: 2,
target: 4,
type: 'emptyEdge',
},
],
};
const graphConfig = {
nodeTypes: {
exchange: {
// required to show empty nodes
typeText: 'Exchange',
shapeId: '#empty', // relates to the type property of a node
shape: (
<symbol viewBox="0 0 100 100" id="empty" key="0">
<circle cx='50' cy='50' r='45'/>
</symbol>
),
},
queue: {
// required to show empty nodes
typeText: 'Queue',
shapeId: '#empty', // relates to the type property of a node
shape: (
<symbol viewBox="0 0 100 100" id="empty" key="0">
<circle cx='50' cy='50' r='45'/>
</symbol>
),
},
},
nodeSubtypes: {},
edgeTypes: {},
};
type Props = {
data: Data;
};
const SPACE = 200;
const EntityGraph = ({ data }: Props) => {
const queueTotal = data.queues.length * SPACE / 2;
const queues = data.queues.map((q, i) => ({
id: q.name,
title: q.name,
y: 300,
x: (i * SPACE) - queueTotal,
type: 'queue',
}));
const exchTotal = data.exchanges.length * SPACE / 2;
const exchanges = data.exchanges.map((e, i) => ({
id: e.name,
title: e.name,
y: 0,
x: (i * SPACE) - exchTotal,
type: 'exchange',
}));
const nodes = [...queues, ...exchanges];
const edges = data.exchanges
.flatMap((e) => e.bindings.map((b) => [b, e] as [Binding, Exchange]))
.map(([b, e]) => ({
source: b.queue,
target: e.name,
label_to: `'${b.routingKey}'`,
type: 'emptyEdge'
}));
const nodeTypes = graphConfig.nodeTypes;
const nodeSubtypes = graphConfig.nodeSubtypes;
const edgeTypes = graphConfig.edgeTypes;
return (
<div className="graph">
<GraphView
nodeKey="id"
nodes={nodes}
edges={edges}
nodeTypes={nodeTypes}
nodeSubtypes={nodeSubtypes}
edgeTypes={edgeTypes}
/>
</div>
);
};
export default EntityGraph;

View file

@ -1,6 +1,7 @@
import React, { FC, useCallback, useEffect, useState } from 'react';
import Table from './table';
import type { Data } from '../types';
import EntityGraph from './EntityGraph';
const fetchData = async (prefix: string): Promise<Data> => {
const url = `${prefix}api/data`;
@ -27,6 +28,10 @@ const DataPage: FC<Props> = ({ prefix }) => {
return (
<div>
<section>
<h2>Graph</h2>
{data ? <EntityGraph data={data} /> : <div>Loading...</div>}
</section>
<section>
<h2>Connections</h2>
{data ? (
@ -42,22 +47,6 @@ const DataPage: FC<Props> = ({ prefix }) => {
<div>Loading...</div>
)}
</section>
<section>
<h2>Queues</h2>
{data ? (
<Table
headers={['Queue ID', 'Name', 'Durable', 'Message Count']}
rows={data.queues.map((queue) => [
queue.id,
queue.name,
queue.durable ? 'Yes' : 'No',
queue.messages,
])}
/>
) : (
<div>Loading...</div>
)}
</section>
<section>
<h2>Channels</h2>
{data ? (
@ -81,6 +70,37 @@ const DataPage: FC<Props> = ({ prefix }) => {
<div>Loading...</div>
)}
</section>
<section>
<h2>Queues</h2>
{data ? (
<Table
headers={['Queue ID', 'Name', 'Durable', 'Message Count']}
rows={data.queues.map((queue) => [
queue.id,
queue.name,
queue.durable ? 'Yes' : 'No',
queue.messages,
])}
/>
) : (
<div>Loading...</div>
)}
</section>
<section>
<h2>Exchanges</h2>
{data ? (
<Table
headers={['Name', 'Durable', 'Bindings']}
rows={data.exchanges.map((exchange) => [
exchange.name,
exchange.durable ? 'Yes' : 'No',
exchange.bindings.length,
])}
/>
) : (
<div>Loading...</div>
)}
</section>
</div>
);
};

View file

@ -16,7 +16,19 @@ export type Queue = {
messages: number;
};
export type Binding = {
queue: string;
routingKey: string;
};
export type Exchange = {
name: string;
durable: boolean;
bindings: ReadonlyArray<Binding>;
};
export type Data = {
connections: ReadonlyArray<Connection>;
queues: ReadonlyArray<Queue>;
exchanges: ReadonlyArray<Exchange>;
};