mirror of
https://github.com/checktheroads/hyperglass
synced 2024-05-11 05:55:08 +00:00
fix as path graph layout
This commit is contained in:
69
CHANGELOG.md
69
CHANGELOG.md
@@ -5,13 +5,18 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## 1.0.0-beta75 - 2021-01-28
|
||||
## 1.0.0-beta.77 - 2021-02-01
|
||||
|
||||
### Fixed
|
||||
- AS Path graph view now uses [dagre](https://github.com/dagrejs/dagre) to properly arrange each AS.
|
||||
|
||||
## 1.0.0-beta.75 - 2021-01-28
|
||||
|
||||
### Changed
|
||||
- Default UI build timeout is now 180 seconds.
|
||||
- The hyperglass `build-ui` CLI command now accepts a `--timeout` argument to override the UI build timeout.
|
||||
|
||||
## 1.0.0-beta74 - 2021-01-25
|
||||
## 1.0.0-beta.74 - 2021-01-25
|
||||
|
||||
### Changed
|
||||
- The Scrapli driver no longer specifically ignores the system's SSH config file.
|
||||
@@ -20,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Fixed
|
||||
- [#109](https://github.com/checktheroads/hyperglass/issues/109): Remove the custom error page, because it doesn't work and doesn't really add much.
|
||||
|
||||
## 1.0.0-beta73 - 2021-01-18
|
||||
## 1.0.0-beta.73 - 2021-01-18
|
||||
|
||||
### Added
|
||||
- [#106](https://github.com/checktheroads/hyperglass/issues/106): Add built-in support for Nokia SR OS (thanks @paunadeu!).
|
||||
@@ -32,7 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Fixed
|
||||
- [#107](https://github.com/checktheroads/hyperglass/issues/107): Fix footer menu styling so it doesn't overflow the viewport, especially on mobile.
|
||||
|
||||
## 1.0.0-beta72 - 2021-01-16
|
||||
## 1.0.0-beta.72 - 2021-01-16
|
||||
|
||||
### Fixed
|
||||
- [#104](https://github.com/checktheroads/hyperglass/issues/104): Handle the usage of `juniper_junos` as a NOS. `juniper_junos` will now automatically be mapped to `juniper`.
|
||||
@@ -41,7 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Changed
|
||||
- **BREAKING**: The installer no longer generates a Systemd service file. While this was likely convenient for most, it introduced significant complexity and caused most installations using `~/hyperglass` as the app path to fail, with no clear way to resolve it. Further, while Systemd is arguably the most common, it is not the *only* process manager available. As such, the docs will be updated with a Systemd example, much like the current reverse proxy documentation.
|
||||
|
||||
## 1.0.0-beta71 - 2021-01-10
|
||||
## 1.0.0-beta.71 - 2021-01-10
|
||||
|
||||
### Added
|
||||
- Added Google Analytics Support. Use the `google_analytics` field for the tracking ID in `hyperglass.yaml`.
|
||||
@@ -49,7 +54,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Changed
|
||||
- Minor frontend code improvements.
|
||||
|
||||
## 1.0.0-beta70 - 2021-01-05
|
||||
## 1.0.0-beta.70 - 2021-01-05
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -58,7 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Changed
|
||||
- Query results now automatically cancel when each result panel unmounts (e.g. when one clicks the back button).
|
||||
|
||||
## 1.0.0-beta69 - 2021-01-03
|
||||
## 1.0.0-beta.69 - 2021-01-03
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -69,14 +74,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Setup no longer adds example files
|
||||
|
||||
## 1.0.0-beta67 - 2021-01-02
|
||||
## 1.0.0-beta.67 - 2021-01-02
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix handling of `web.theme.default_color_mode`. Starting in 1.0.0-beta.65, it was completely ignored and used the library's default of `light`. Now, it's handled properly.
|
||||
- Fix table output layout issues, particularly on mobile.
|
||||
|
||||
## 1.0.0-beta66 - 2021-01-02
|
||||
## 1.0.0-beta.66 - 2021-01-02
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -87,7 +92,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- `web.theme.colors.black` and `web.theme.colors.white` are now `web.theme.colors.dark` and `web.theme.colors.light respectively`
|
||||
|
||||
## 1.0.0-beta65 - 2021-01-01
|
||||
## 1.0.0-beta.65 - 2021-01-01
|
||||
|
||||
### Added
|
||||
|
||||
@@ -102,7 +107,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- `web.text.title` and `web.text.subtitle` now carry a 32 character limit for simpler styling.
|
||||
- Various UI layout, styling improvements, and stability improvements.
|
||||
|
||||
## 1.0.0-beta63 - 2020-10-18
|
||||
## 1.0.0-beta.63 - 2020-10-18
|
||||
|
||||
### Added
|
||||
|
||||
@@ -112,13 +117,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
- Fix an issue causing hyperglass custom exceptions to not be properly raised, which caused more generic error messages in the UI/API.
|
||||
|
||||
## 1.0.0-beta62 - 2020-10-17
|
||||
## 1.0.0-beta.62 - 2020-10-17
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix an issue causing exceptions not to be logged to the log file (but logged to stdout).
|
||||
|
||||
## 1.0.0-beta61 - 2020-10-11
|
||||
## 1.0.0-beta.61 - 2020-10-11
|
||||
|
||||
### POTENTIALLY BREAKING CHANGE
|
||||
|
||||
@@ -132,7 +137,7 @@ When hyperglass starts up, it will check to see if `~/hyperglass` or `/etc/hyper
|
||||
|
||||
- [#81](https://github.com/checktheroads/hyperglass/issues/81): Add support for SSH key authentication. See [the docs](https://hyperglass.io/docs/adding-devices#credential) for more details.
|
||||
|
||||
## 1.0.0-beta60 - 2020-10-10
|
||||
## 1.0.0-beta.60 - 2020-10-10
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -154,7 +159,7 @@ This would correspond with the following stanza in the Redis configuration file:
|
||||
requirepass examplepassword
|
||||
```
|
||||
|
||||
## 1.0.0-beta59 - 2020-10-05
|
||||
## 1.0.0-beta.59 - 2020-10-05
|
||||
|
||||
### Added
|
||||
|
||||
@@ -166,7 +171,7 @@ requirepass examplepassword
|
||||
- Improve output parsing scalability - parsers can now be defined on a per-NOS basis regardless of whether or not structured-data is used.
|
||||
- Restructure model locations & importing to remove some complexities.
|
||||
|
||||
## 1.0.0-beta58 - 2020-09-28
|
||||
## 1.0.0-beta.58 - 2020-09-28
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -183,7 +188,7 @@ requirepass examplepassword
|
||||
- [#77](https://github.com/checktheroads/hyperglass/issues/77): Allow dashes in FQDN validation pattern.
|
||||
- [#83](https://github.com/checktheroads/hyperglass/issues/83): Fix lack of support for `protocol-nh` field in Juniper XML BGP table.
|
||||
|
||||
## 1.0.0-beta57 - 2020-07-30
|
||||
## 1.0.0-beta.57 - 2020-07-30
|
||||
|
||||
### BREAKING CHANGE
|
||||
|
||||
@@ -201,7 +206,7 @@ $ hyperglass-agent send-certificate
|
||||
- Refactored device, query, proxy models to no longer scrub unsupported characters from the device name for the purposes of Python class attribute accessing.
|
||||
- Updated hyperglass-agent docs.
|
||||
|
||||
## 1.0.0-beta56 - 2020-07-28
|
||||
## 1.0.0-beta.56 - 2020-07-28
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -212,19 +217,19 @@ $ hyperglass-agent send-certificate
|
||||
|
||||
- [#56](https://github.com/checktheroads/hyperglass/issues/56): Fix a silent Redis connection error if the Redis server was anything other than `localhost`, preventing hyperglass from starting.
|
||||
|
||||
## 1.0.0-beta55 - 2020-07-27
|
||||
## 1.0.0-beta.55 - 2020-07-27
|
||||
|
||||
### Changed
|
||||
|
||||
- Removed JS favicon build process in favor of native Python implementation ([favicons](https://github/checktheroads/favicons))
|
||||
|
||||
## 1.0.0-beta54 - 2020-07-25
|
||||
## 1.0.0-beta.54 - 2020-07-25
|
||||
|
||||
### Fixed
|
||||
|
||||
- Queries to hyperglass-agent devices failed due to the error `AttributeError: 'AgentConnection' object has no attribute 'collect'`
|
||||
|
||||
## 1.0.0-beta53 - 2020-07-23
|
||||
## 1.0.0-beta.53 - 2020-07-23
|
||||
|
||||
### Added
|
||||
|
||||
@@ -240,7 +245,7 @@ $ hyperglass-agent send-certificate
|
||||
|
||||
- UI: Error messages couldn't be copied with the copy button
|
||||
|
||||
## 1.0.0-beta52 - 2020-07-19
|
||||
## 1.0.0-beta.52 - 2020-07-19
|
||||
|
||||
### Added
|
||||
|
||||
@@ -264,7 +269,7 @@ $ hyperglass-agent send-certificate
|
||||
- Improve command customization docs.
|
||||
- [#61](https://github.com/checktheroads/hyperglass/issues/61): Fixed copy output for table data. Output is now a bulleted list of parsed data.
|
||||
|
||||
## 1.0.0-beta51 - 2020-07-13
|
||||
## 1.0.0-beta.51 - 2020-07-13
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -276,7 +281,7 @@ $ hyperglass-agent send-certificate
|
||||
- [#54](https://github.com/checktheroads/hyperglass/issues/54): A Junos parsing error caused routes with no communities to raise an error.
|
||||
- Pre-validated config files are no longer logged on startup unless debugging is enabled.
|
||||
|
||||
## 1.0.0-beta50 - 2020-07-12
|
||||
## 1.0.0-beta.50 - 2020-07-12
|
||||
|
||||
### Added
|
||||
|
||||
@@ -296,7 +301,7 @@ $ hyperglass-agent send-certificate
|
||||
- [#54](https://github.com/checktheroads/hyperglass/issues/54): A Junos structured/table output parsing error caused routes with multiple next-hops to raise an error.
|
||||
- RPKI validation no longer occurs twice (once on serialization of the output, once on validation of the API response).
|
||||
|
||||
## 1.0.0-beta49 - 2020-07-05
|
||||
## 1.0.0-beta.49 - 2020-07-05
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -308,7 +313,7 @@ $ hyperglass-agent send-certificate
|
||||
|
||||
- Route lookups for private (RFC 1918) addresses failed due to an unnecessary lookup to [bgp.tools](https://bgp.tools)
|
||||
|
||||
## 1.0.0-beta48 - 2020-07-04
|
||||
## 1.0.0-beta.48 - 2020-07-04
|
||||
|
||||
### Added
|
||||
|
||||
@@ -320,7 +325,7 @@ $ hyperglass-agent send-certificate
|
||||
- When copying the opengraph image, the copied image was not deleted.
|
||||
- Default traceroute help link now _actually_ points to the new docs site.
|
||||
|
||||
## 1.0.0-beta47 - 2020-07-04
|
||||
## 1.0.0-beta.47 - 2020-07-04
|
||||
|
||||
### Added
|
||||
|
||||
@@ -341,13 +346,13 @@ $ hyperglass-agent send-certificate
|
||||
- Generated favicon manifest files now go to the correct directory.
|
||||
- Various docs site fixes
|
||||
|
||||
## 1.0.0-beta46 - 2020-06-28
|
||||
## 1.0.0-beta.46 - 2020-06-28
|
||||
|
||||
### Added
|
||||
|
||||
- Support for hyperglass-agent [0.1.5](https://github.com/checktheroads/hyperglass-agent)
|
||||
|
||||
## 1.0.0-beta45 - 2020-06-27
|
||||
## 1.0.0-beta.45 - 2020-06-27
|
||||
|
||||
### Changed
|
||||
|
||||
@@ -358,7 +363,7 @@ $ hyperglass-agent send-certificate
|
||||
- Webhook construction bugs that caused webhooks not to send
|
||||
- Empty response handling for table output
|
||||
|
||||
## 1.0.0-beta44 - 2020-06-26
|
||||
## 1.0.0-beta.44 - 2020-06-26
|
||||
|
||||
### Added
|
||||
|
||||
@@ -368,13 +373,13 @@ $ hyperglass-agent send-certificate
|
||||
|
||||
- If webhooks were enabled, a hung test connection to RIPEStat would cause the query to time out
|
||||
|
||||
## 1.0.0-beta43 - 2020-06-22
|
||||
## 1.0.0-beta.43 - 2020-06-22
|
||||
|
||||
### Fixed
|
||||
|
||||
- Logo path handling in UI
|
||||
|
||||
## 1.0.0-beta42 - 2020-06-21
|
||||
## 1.0.0-beta.42 - 2020-06-21
|
||||
|
||||
### Added
|
||||
|
||||
|
@@ -1,14 +1,12 @@
|
||||
import { useMemo } from 'react';
|
||||
import { Box, Flex, SkeletonText, Badge, VStack } from '@chakra-ui/react';
|
||||
import ReactFlow from 'react-flow-renderer';
|
||||
import { Background, ReactFlowProvider } from 'react-flow-renderer';
|
||||
import { Handle, Position } from 'react-flow-renderer';
|
||||
import { useConfig, useColorValue, useColorToken, useBreakpointValue } from '~/context';
|
||||
import { useConfig, useColorValue, useColorToken } from '~/context';
|
||||
import { useASNDetail } from '~/hooks';
|
||||
import { Controls } from './controls';
|
||||
import { buildElements } from './util';
|
||||
import { useElements } from './useElements';
|
||||
|
||||
import type { ReactFlowProps } from 'react-flow-renderer';
|
||||
import type { TChart, TNode, TNodeData } from './types';
|
||||
|
||||
export const Chart: React.FC<TChart> = (props: TChart) => {
|
||||
@@ -17,19 +15,17 @@ export const Chart: React.FC<TChart> = (props: TChart) => {
|
||||
|
||||
const dots = useColorToken('colors', 'blackAlpha.500', 'whiteAlpha.400');
|
||||
|
||||
const flowProps = useBreakpointValue<Omit<ReactFlowProps, 'elements'>>({
|
||||
base: { defaultPosition: [0, 300], defaultZoom: 0 },
|
||||
lg: { defaultPosition: [100, 300], defaultZoom: 0.7 },
|
||||
}) ?? { defaultPosition: [100, 300], defaultZoom: 0.7 };
|
||||
|
||||
const elements = useMemo(() => [...buildElements({ asn: primary_asn, name: org_name }, data)], [
|
||||
data,
|
||||
]);
|
||||
const elements = useElements({ asn: primary_asn, name: org_name }, data);
|
||||
|
||||
return (
|
||||
<ReactFlowProvider>
|
||||
<Box boxSize="100%" zIndex={1}>
|
||||
<ReactFlow elements={elements} nodeTypes={{ ASNode }} {...flowProps}>
|
||||
<ReactFlow
|
||||
snapToGrid
|
||||
elements={elements}
|
||||
nodeTypes={{ ASNode }}
|
||||
onLoad={inst => setTimeout(() => inst.fitView(), 0)}
|
||||
>
|
||||
<Background color={dots} />
|
||||
<Controls />
|
||||
</ReactFlow>
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import {
|
||||
Modal,
|
||||
Skeleton,
|
||||
ModalBody,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
useDisclosure,
|
||||
Skeleton,
|
||||
ModalCloseButton,
|
||||
} from '@chakra-ui/react';
|
||||
import { useColorValue, useBreakpointValue } from '~/context';
|
||||
|
115
hyperglass/ui/components/path/useElements.ts
Normal file
115
hyperglass/ui/components/path/useElements.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import dagre from 'dagre';
|
||||
import { useMemo } from 'react';
|
||||
import isEqual from 'react-fast-compare';
|
||||
|
||||
import type { FlowElement } from 'react-flow-renderer';
|
||||
import type { BasePath } from './types';
|
||||
|
||||
const NODE_WIDTH = 200;
|
||||
const NODE_HEIGHT = 48;
|
||||
|
||||
export function useElements(base: BasePath, data: TStructuredResponse): FlowElement[] {
|
||||
return useMemo(() => {
|
||||
return [...buildElements(base, data)];
|
||||
}, [data.routes.length]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the positions for each AS Path.
|
||||
* @see https://github.com/MrBlenny/react-flow-chart/issues/61
|
||||
*/
|
||||
function* buildElements(base: BasePath, data: TStructuredResponse): Generator<FlowElement> {
|
||||
const { routes } = data;
|
||||
// Eliminate empty AS paths & deduplicate non-empty AS paths. Length should be same as count minus empty paths.
|
||||
const asPaths = routes.filter(r => r.as_path.length !== 0).map(r => [...new Set(r.as_path)]);
|
||||
|
||||
const totalPaths = asPaths.length - 1;
|
||||
|
||||
const g = new dagre.graphlib.Graph();
|
||||
g.setGraph({ marginx: 20, marginy: 20 });
|
||||
g.setDefaultEdgeLabel(() => ({}));
|
||||
|
||||
// Set the origin (i.e., the hyperglass user) at the base.
|
||||
g.setNode(base.asn, { width: NODE_WIDTH, height: NODE_HEIGHT });
|
||||
|
||||
for (const [groupIdx, pathGroup] of asPaths.entries()) {
|
||||
// For each ROUTE's AS Path:
|
||||
|
||||
// Find the route after this one.
|
||||
const nextGroup = groupIdx < totalPaths ? asPaths[groupIdx + 1] : [];
|
||||
|
||||
// Connect the first hop in the AS Path to the base (for dagre).
|
||||
g.setEdge(base.asn, `${groupIdx}-${pathGroup[0]}`);
|
||||
|
||||
// Eliminate duplicate AS Paths.
|
||||
if (!isEqual(pathGroup, nextGroup)) {
|
||||
for (const [idx, asn] of pathGroup.entries()) {
|
||||
// For each ASN in the ROUTE:
|
||||
|
||||
const node = `${groupIdx}-${asn}`;
|
||||
const endIdx = pathGroup.length - 1;
|
||||
|
||||
// Add the AS as a node.
|
||||
g.setNode(node, { width: NODE_WIDTH, height: NODE_HEIGHT });
|
||||
|
||||
// Connect the first hop in the AS Path to the base (for react-flow).
|
||||
if (idx === 0) {
|
||||
yield {
|
||||
id: `e${base.asn}-${node}`,
|
||||
source: base.asn,
|
||||
target: node,
|
||||
};
|
||||
}
|
||||
// Connect every intermediate hop to each other.
|
||||
if (idx !== endIdx) {
|
||||
const next = `${groupIdx}-${pathGroup[idx + 1]}`;
|
||||
g.setEdge(node, next);
|
||||
yield {
|
||||
id: `e${node}-${next}`,
|
||||
source: node,
|
||||
target: next,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now that that nodes are added, create the layout.
|
||||
dagre.layout(g, { rankdir: 'BT', align: 'UR' });
|
||||
|
||||
// Get the base ASN's positions.
|
||||
const x = g.node(base.asn).x - NODE_WIDTH / 2;
|
||||
const y = g.node(base.asn).y + NODE_HEIGHT * 6;
|
||||
|
||||
yield {
|
||||
id: base.asn,
|
||||
type: 'ASNode',
|
||||
position: { x, y },
|
||||
data: { asn: base.asn, name: base.name, hasChildren: true, hasParents: false },
|
||||
};
|
||||
|
||||
for (const [groupIdx, pathGroup] of asPaths.entries()) {
|
||||
const nextGroup = groupIdx < totalPaths ? asPaths[groupIdx + 1] : [];
|
||||
if (!isEqual(pathGroup, nextGroup)) {
|
||||
for (const [idx, asn] of pathGroup.entries()) {
|
||||
const node = `${groupIdx}-${asn}`;
|
||||
const endIdx = pathGroup.length - 1;
|
||||
const x = g.node(node).x - NODE_WIDTH / 2;
|
||||
const y = g.node(node).y - NODE_HEIGHT * (idx * 6);
|
||||
|
||||
// Get each ASN's positions.
|
||||
yield {
|
||||
id: node,
|
||||
type: 'ASNode',
|
||||
position: { x, y },
|
||||
data: {
|
||||
asn,
|
||||
name: `AS${asn}`,
|
||||
hasChildren: idx < endIdx,
|
||||
hasParents: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,68 +0,0 @@
|
||||
import { arrangeIntoTree } from '~/util';
|
||||
|
||||
import type { FlowElement, Elements } from 'react-flow-renderer';
|
||||
import type { PathPart } from '~/types';
|
||||
import type { BasePath } from './types';
|
||||
|
||||
function treeToElement(part: PathPart, len: number, index: number): FlowElement[] {
|
||||
const x = index * 250;
|
||||
const y = -(len * 10);
|
||||
const elements = [
|
||||
{
|
||||
id: String(part.base),
|
||||
type: 'ASNode',
|
||||
position: { x, y },
|
||||
data: {
|
||||
asn: part.base,
|
||||
name: `AS${part.base}`,
|
||||
hasChildren: part.children.length !== 0,
|
||||
hasParents: true,
|
||||
},
|
||||
},
|
||||
] as Elements;
|
||||
|
||||
for (const child of part.children) {
|
||||
let xc = index;
|
||||
if (part.children.length !== 0) {
|
||||
elements.push({
|
||||
id: `e${part.base}-${child.base}`,
|
||||
source: String(part.base),
|
||||
target: String(child.base),
|
||||
});
|
||||
} else {
|
||||
xc = x;
|
||||
}
|
||||
elements.push(...treeToElement(child, part.children.length * 12 + len, xc));
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
export function* buildElements(base: BasePath, data: TStructuredResponse): Generator<FlowElement> {
|
||||
const { routes } = data;
|
||||
// Eliminate empty AS paths & deduplicate non-empty AS paths. Length should be same as count minus empty paths.
|
||||
const asPaths = routes.filter(r => r.as_path.length !== 0).map(r => [...new Set(r.as_path)]);
|
||||
const asTree = arrangeIntoTree(asPaths);
|
||||
const numHops = asPaths.flat().length;
|
||||
const childPaths = asTree.map((a, i) => {
|
||||
return treeToElement(a, asTree.length, i);
|
||||
});
|
||||
|
||||
// Add the first hop at the base.
|
||||
yield {
|
||||
id: base.asn,
|
||||
type: 'ASNode',
|
||||
position: { x: 150, y: numHops * 10 },
|
||||
data: { asn: base.asn, name: base.name, hasChildren: true, hasParents: false },
|
||||
};
|
||||
|
||||
for (const path of childPaths) {
|
||||
// path = Each unique path from origin
|
||||
const first = path[0];
|
||||
yield { id: `e${base.asn}-${first.id}`, source: base.asn, target: first.id };
|
||||
// Add link from base to each first hop.
|
||||
yield { id: `e${base.asn}-${first.id}`, source: base.asn, target: first.id };
|
||||
for (const hop of path) {
|
||||
yield hop;
|
||||
}
|
||||
}
|
||||
}
|
2
hyperglass/ui/package.json
vendored
2
hyperglass/ui/package.json
vendored
@@ -26,6 +26,7 @@
|
||||
"@hookstate/persistence": "^3.0.0",
|
||||
"@meronex/icons": "^4.0.0",
|
||||
"color2k": "^1.1.1",
|
||||
"dagre": "^0.8.5",
|
||||
"dayjs": "^1.8.25",
|
||||
"framer-motion": "^3.2.2-rc.1",
|
||||
"lodash": "^4.17.15",
|
||||
@@ -47,6 +48,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@hookstate/devtools": "^3.0.0",
|
||||
"@types/dagre": "^0.7.44",
|
||||
"@types/node": "^14.14.17",
|
||||
"@types/react": "^17.0.0",
|
||||
"@types/react-select": "^3.0.28",
|
||||
|
20
hyperglass/ui/yarn.lock
vendored
20
hyperglass/ui/yarn.lock
vendored
@@ -1055,6 +1055,11 @@
|
||||
dependencies:
|
||||
tslib "^2.0.0"
|
||||
|
||||
"@types/dagre@^0.7.44":
|
||||
version "0.7.44"
|
||||
resolved "https://registry.yarnpkg.com/@types/dagre/-/dagre-0.7.44.tgz#8f4b796b118ca29c132da7068fbc0d0351ee5851"
|
||||
integrity sha512-N6HD+79w77ZVAaVO7JJDW5yJ9LAxM62FpgNGO9xEde+KVYjDRyhIMzfiErXpr1g0JPon9kwlBzoBK6s4fOww9Q==
|
||||
|
||||
"@types/eslint-visitor-keys@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
||||
@@ -2735,6 +2740,14 @@ d@1, d@^1.0.1:
|
||||
es5-ext "^0.10.50"
|
||||
type "^1.0.1"
|
||||
|
||||
dagre@^0.8.5:
|
||||
version "0.8.5"
|
||||
resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee"
|
||||
integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==
|
||||
dependencies:
|
||||
graphlib "^2.1.8"
|
||||
lodash "^4.17.15"
|
||||
|
||||
damerau-levenshtein@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz#143c1641cb3d85c60c32329e26899adea8701791"
|
||||
@@ -3971,6 +3984,13 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2:
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
||||
|
||||
graphlib@^2.1.8:
|
||||
version "2.1.8"
|
||||
resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da"
|
||||
integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==
|
||||
dependencies:
|
||||
lodash "^4.17.15"
|
||||
|
||||
has-ansi@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
|
||||
|
Reference in New Issue
Block a user