visualizer: initial tree visualizer

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-11-04 21:23:06 +01:00
parent db79a2026d
commit 4b3d0ec9e7
2 changed files with 59 additions and 0 deletions
@@ -21,6 +21,7 @@ import Box from '@material-ui/core/Box';
import React, { useState } from 'react';
import { GraphVisualizer } from './GraphVisualizer';
import { TextVisualizer } from './TextVisualizer';
import { TreeVisualizer } from './TreeVisualizer';
export function AppVisualizerPage() {
const appTreeApi = useApi(appTreeApiRef);
@@ -29,6 +30,7 @@ export function AppVisualizerPage() {
const tabs = [
{ id: 'graph', label: 'Graph', element: <GraphVisualizer tree={tree} /> },
{ id: 'tree', label: 'Tree', element: <TreeVisualizer tree={tree} /> },
{ id: 'text', label: 'Text', element: <TextVisualizer tree={tree} /> },
];
@@ -0,0 +1,57 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
DependencyGraph,
DependencyGraphTypes,
} from '@backstage/core-components';
import { AppTree } from '@backstage/frontend-plugin-api';
import Box from '@material-ui/core/Box';
import { useMemo } from 'react';
function resolveGraphData(tree: AppTree) {
const nodes = [...tree.nodes.values()]
.filter(n => n.instance)
.map(n => ({ ...n, id: n.spec.id }));
return {
nodes,
edges: nodes
.filter(n => n.edges.attachedTo)
.map(n => ({
from: n.spec.id,
to: n.edges.attachedTo!.node.spec.id,
label: n.edges.attachedTo!.input,
})),
};
}
export function TreeVisualizer({ tree }: { tree: AppTree }) {
const graphData = useMemo(() => resolveGraphData(tree), [tree]);
return (
<Box height="100%" flex="1 1 100%" flexDirection="column" overflow="hidden">
<DependencyGraph
fit="contain"
style={{ height: '100%', width: '100%' }}
{...graphData}
nodeMargin={10}
edgeMargin={30}
rankMargin={100}
direction={DependencyGraphTypes.Direction.BOTTOM_TOP}
/>
</Box>
);
}