Skip to content

Commit

Permalink
Merge pull request patternfly#144 from jeff-phillips-18/rm-lodash
Browse files Browse the repository at this point in the history
fix(lodash): Remove dependency on lodash
  • Loading branch information
jeff-phillips-18 authored Feb 16, 2024
2 parents d1b08ab + b0c87aa commit bed1c18
Show file tree
Hide file tree
Showing 17 changed files with 89 additions and 80 deletions.
3 changes: 1 addition & 2 deletions packages/demo-app-ts/src/components/GroupHull.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import { observer } from 'mobx-react';
import { polygonHull } from 'd3-polygon';
import * as _ from 'lodash';
import {
WithDragNodeProps,
WithSelectionProps,
Expand Down Expand Up @@ -85,7 +84,7 @@ const GroupHull: React.FunctionComponent<GroupHullProps> = ({
return null;
}
const points: PointWithSize[] = [];
_.forEach(nodeChildren, c => {
nodeChildren.forEach(c => {
if (c.getNodeShape() === NodeShape.ellipse) {
const { width, height } = c.getBounds();
const { x, y } = c.getBounds().getCenter();
Expand Down
7 changes: 3 additions & 4 deletions packages/demo-app-ts/src/demos/TopologyPackage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import { action } from 'mobx';
import * as _ from 'lodash';
import {
Controller,
createTopologyControlButtons,
Expand Down Expand Up @@ -146,8 +145,8 @@ const TopologyViewComponent: React.FunctionComponent<TopologyViewComponentProps>
}, [controller, lowScale, medScale]);

const topologySideBar = (
<TopologySideBar show={_.size(selectedIds) > 0} resizable={sideBarResizable} onClose={() => setSelectedIds([])}>
<div style={{ marginTop: 27, marginLeft: 20, height: '800px' }}>{_.head(selectedIds)}</div>
<TopologySideBar show={!!selectedIds?.length} resizable={sideBarResizable} onClose={() => setSelectedIds([])}>
<div style={{ marginTop: 27, marginLeft: 20, height: '800px' }}>{selectedIds?.[0]}</div>
</TopologySideBar>
);

Expand Down Expand Up @@ -208,7 +207,7 @@ const TopologyViewComponent: React.FunctionComponent<TopologyViewComponentProps>
contextToolbar={contextToolbar}
viewToolbar={viewToolbar}
sideBar={useSidebar && topologySideBar}
sideBarOpen={useSidebar && _.size(selectedIds) > 0}
sideBarOpen={useSidebar && !!selectedIds?.length}
sideBarResizable={sideBarResizable}
>
<VisualizationSurface state={{ selectedIds }} />
Expand Down
22 changes: 16 additions & 6 deletions packages/demo-app-ts/src/utils/useTopologyOptions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from 'react';
import * as _ from 'lodash';
import {
Button,
Dropdown,
Expand All @@ -21,9 +20,6 @@ import { DefaultEdgeOptions, DefaultNodeOptions, GeneratorEdgeOptions, Generator
import { EDGE_ANIMATION_SPEEDS, EDGE_STYLES, EDGE_TERMINAL_TYPES, NODE_SHAPES, NODE_STATUSES } from './styleUtils';
import { Controller, Model, NodeShape } from '@patternfly/react-topology';

const GRAPH_LAYOUT_OPTIONS = ['x', 'y', 'visible', 'style', 'layout', 'scale', 'scaleExtent', 'layers'];
const NODE_LAYOUT_OPTIONS = ['x', 'y', 'visible', 'style', 'collapsed', 'width', 'height', 'shape'];

export const useTopologyOptions = (
controller: Controller
): {
Expand Down Expand Up @@ -380,7 +376,14 @@ export const useTopologyOptions = (
const currentModel = controller.toModel();
currentModel.graph = {
...currentModel.graph,
..._.pick(savedModel.graph, GRAPH_LAYOUT_OPTIONS)
x: savedModel.graph.x,
y: savedModel.graph.y,
visible: savedModel.graph.visible,
style: savedModel.graph.style,
layout: savedModel.graph.layout,
scale: savedModel.graph.scale,
scaleExtent: savedModel.graph.scaleExtent,
layers: savedModel.graph.layers,
};
currentModel.nodes = currentModel.nodes.map((n) => {
const savedNode = savedModel.nodes.find((sn) => sn.id === n.id);
Expand All @@ -389,7 +392,14 @@ export const useTopologyOptions = (
}
return {
...n,
..._.pick(savedNode, NODE_LAYOUT_OPTIONS)
x: savedNode.x,
y: savedNode.y,
visible: savedNode.visible,
style: savedNode.style,
collapsed: savedNode.collapsed,
width: savedNode.width,
height: savedNode.height,
shape: savedNode.shape,
};
});
controller.fromModel(currentModel, false);
Expand Down
2 changes: 0 additions & 2 deletions packages/module/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
"@types/react-measure": "^2.0.6",
"d3": "^7.8.0",
"dagre": "0.8.2",
"lodash": "^4.17.19",
"mobx": "^6.9.0",
"mobx-react": "^7.6.0",
"point-in-svg-path": "^1.0.1",
Expand All @@ -61,7 +60,6 @@
"@patternfly/patternfly-a11y": "^4.3.1",
"@patternfly/react-code-editor": "^5.1.1",
"@patternfly/react-table": "^5.1.1",
"@types/lodash": "^4.14.191",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"camel-case": "^3.0.0",
Expand Down
8 changes: 4 additions & 4 deletions packages/module/src/Visualization.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ComponentType } from 'react';
import { action, computed, observable, makeObservable, configure } from 'mobx';
import * as _ from 'lodash';
import {
Controller,
Graph,
Expand Down Expand Up @@ -97,7 +96,7 @@ export class Visualization extends Stateful implements Controller {

// If not merging, clear out the old elements
if (!merge) {
_.forIn(this.elements, element => this.removeElement(element));
Object.keys(this.elements).forEach(element => this.removeElement(this.elements[element]));
}

// Create the graph if given in the model
Expand Down Expand Up @@ -150,7 +149,8 @@ export class Visualization extends Stateful implements Controller {

// remove all stale elements
if (merge) {
_.forIn(this.elements, element => {
Object.keys(this.elements).forEach(key => {
const element = this.elements[key];
if (!validIds.includes(element.getId())) {
this.removeElement(element);
}
Expand Down Expand Up @@ -189,7 +189,7 @@ export class Visualization extends Stateful implements Controller {
}

getElements(): GraphElement[] {
return _.values(this.elements);
return Object.values(this.elements);
}

toModel(): Model {
Expand Down
24 changes: 17 additions & 7 deletions packages/module/src/components/VisualizationSurface.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import * as React from 'react';
import * as _ from 'lodash';
import { action } from 'mobx';
// https://github.com/mobxjs/mobx-react#observer-batching
import 'mobx-react/batchingForReactDom';
import { observer } from 'mobx-react';
import ReactMeasure from 'react-measure';
import ReactMeasure, { ContentRect } from 'react-measure';
import { css } from '@patternfly/react-styles';
import styles from '../css/topology-components';
import { State } from '../types';
Expand All @@ -29,25 +28,36 @@ const VisualizationSurface: React.FunctionComponent<VisualizationSurfaceProps> =
state
}: VisualizationSurfaceProps) => {
const controller = useVisualizationController();
const timerId = React.useRef<NodeJS.Timer>();

const debounceMeasure = React.useCallback((func: (contentRect: ContentRect) => void, delay?: number) => {
return (contentRect: ContentRect) => {
if (!timerId.current) {
func(contentRect)
}
clearTimeout(timerId.current)

timerId.current = setTimeout(() => func(contentRect), delay)
}
}, []);

React.useEffect(() => {
state && controller.setState(state);
}, [controller, state]);

const onMeasure = React.useMemo(
() =>
_.debounce<any>(
action((contentRect: { client: { width: number; height: number } }) => {
debounceMeasure(
action((contentRect: ContentRect) => {
controller.getGraph().setDimensions(new Dimensions(contentRect.client.width, contentRect.client.height));
}),
100,
{ leading: true, trailing: true }
),
[controller]
[controller, debounceMeasure]
);

// dispose of onMeasure
React.useEffect(() => () => onMeasure.cancel(), [onMeasure]);
React.useEffect(() => () => clearTimeout(timerId.current), [onMeasure]);

if (!controller.hasGraph()) {
return null;
Expand Down
7 changes: 3 additions & 4 deletions packages/module/src/components/edges/DefaultEdge.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import * as _ from 'lodash';
import { observer } from 'mobx-react';
import { Edge, EdgeTerminalType, GraphElement, isEdge, isNode, NodeStatus, ScaleDetailsLevel } from '../../types';
import { ConnectDragSource, OnSelect } from '../../behavior';
Expand Down Expand Up @@ -134,15 +133,15 @@ const DefaultEdgeInner: React.FunctionComponent<DefaultEdgeInnerProps> = observe
const bgStartPoint =
!startTerminalType || startTerminalType === EdgeTerminalType.none
? [startPoint.x, startPoint.y]
: getConnectorStartPoint(_.head(bendpoints) || endPoint, startPoint, startTerminalSize);
: getConnectorStartPoint(bendpoints?.[0] || endPoint, startPoint, startTerminalSize);
const bgEndPoint =
!endTerminalType || endTerminalType === EdgeTerminalType.none
? [endPoint.x, endPoint.y]
: getConnectorStartPoint(_.last(bendpoints) || startPoint, endPoint, endTerminalSize);
: getConnectorStartPoint(bendpoints?.[bendpoints.length - 1] || startPoint, endPoint, endTerminalSize);
const backgroundPath = `M${bgStartPoint[0]} ${bgStartPoint[1]} ${bendpoints
.map((b: Point) => `L${b.x} ${b.y} `)
.join('')}L${bgEndPoint[0]} ${bgEndPoint[1]}`;

const showTag = tag && (detailsLevel === ScaleDetailsLevel.high || hover);
const scale = element.getGraph().getScale();
const tagScale = hover && !(detailsLevel === ScaleDetailsLevel.high) ? Math.max(1, 1 / scale) : 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as React from 'react';
import * as _ from 'lodash';
import { css } from '@patternfly/react-styles';
import styles from '../../../css/topology-components';
import Point from '../../../geom/Point';
Expand All @@ -15,8 +14,8 @@ interface ConnectorArrowProps {
dragRef?: ConnectDragSource;
}

const pointsStringFromPoints = (points: [number, number][]): string =>
_.reduce(points, (result: string, nextPoint: [number, number]) => `${result} ${nextPoint[0]},${nextPoint[1]}`, '');
const pointsStringFromPoints = (points?: [number, number][]): string =>
points?.reduce((result: string, nextPoint: [number, number]) => `${result} ${nextPoint[0]},${nextPoint[1]}`, '') ?? '';

const ConnectorArrow: React.FunctionComponent<ConnectorArrowProps> = ({
startPoint,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import { observer } from 'mobx-react';
import * as _ from 'lodash';
import { css } from '@patternfly/react-styles';
import styles from '../../../css/topology-components';
import { Edge, EdgeTerminalType, NodeStatus } from '../../../types';
Expand Down Expand Up @@ -55,7 +54,7 @@ const DefaultConnectorTerminal: React.FunctionComponent<EdgeConnectorArrowProps>
return null;
}
const bendPoints = edge.getBendpoints();
const startPoint = isTarget ? _.last(bendPoints) || edge.getStartPoint() : _.head(bendPoints) || edge.getEndPoint();
const startPoint = isTarget ? bendPoints[bendPoints.length - 1] || edge.getStartPoint() : bendPoints[0] || edge.getEndPoint();
const endPoint = isTarget ? edge.getEndPoint() : edge.getStartPoint();
const classes = css(styles.topologyEdge, className, StatusModifier[status]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const getConnectorStartPoint = (startPoint: Point, endPoint: Point, size:
export const getConnectorRotationAngle = (startPoint: Point, endPoint: Point): number =>
180 - (Math.atan2(endPoint.y - startPoint.y, startPoint.x - endPoint.x) * 180) / Math.PI;

export const getConnectorBoundingBox = (startPoint: Point, endPoint: Point, size: number): [number, number][] => {
export const getConnectorBoundingBox = (startPoint: Point, endPoint: Point, size: number): [number, number][] | null => {
const length = Math.sqrt((endPoint.x - startPoint.x) ** 2 + (endPoint.y - startPoint.y) ** 2);
if (!length) {
return null;
Expand Down
19 changes: 13 additions & 6 deletions packages/module/src/components/groups/DefaultGroupExpanded.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react';
import { observer } from 'mobx-react';
import { polygonHull } from 'd3-polygon';
import * as _ from 'lodash';
import { css } from '@patternfly/react-styles';
import styles from '../../css/topology-components';
import CollapseIcon from '@patternfly/react-icons/dist/esm/icons/compress-alt-icon';
Expand Down Expand Up @@ -89,7 +88,7 @@ export function computeLabelLocation(points: PointWithSize[], labelPosition?: La
];
}

_.forEach(points, p => {
points.forEach(p => {
const delta = !lowPoints ? Infinity : Math.round(p[1]) - Math.round(lowPoints[0][1]);
if (delta > threshold) {
lowPoints = [p];
Expand All @@ -98,11 +97,19 @@ export function computeLabelLocation(points: PointWithSize[], labelPosition?: La
}
});

const minX = lowPoints.reduce((acc, point) => {
return Math.min(acc, point[0]);
}, Number.POSITIVE_INFINITY);
const maxX = lowPoints.reduce((acc, point) => {
return Math.max(acc, point[0]);
}, Number.NEGATIVE_INFINITY);
const maxSize = lowPoints.reduce((acc, point) => {
return Math.max(acc, point[2]);
}, Number.NEGATIVE_INFINITY);
return [
(_.minBy(lowPoints, p => p[0])[0] + _.maxBy(lowPoints, p => p[0])[0]) / 2,
(minX + maxX) / 2,
lowPoints[0][1],
// use the max size value
_.maxBy(lowPoints, p => p[2])[2]
maxSize,
];
}

Expand Down Expand Up @@ -166,7 +173,7 @@ const DefaultGroupExpanded: React.FunctionComponent<DefaultGroupExpandedProps> =
return null;
}
const points: (PointWithSize | PointTuple)[] = [];
_.forEach(children, c => {
children.forEach(c => {
if (c.getNodeShape() === NodeShape.circle) {
const bounds = c.getBounds();
const { width, height } = bounds;
Expand Down
12 changes: 7 additions & 5 deletions packages/module/src/elements/BaseElement.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { observable, computed, makeObservable } from 'mobx';
import * as _ from 'lodash';
import {
ElementModel,
Graph,
Expand Down Expand Up @@ -60,7 +59,10 @@ export default abstract class BaseElement<E extends ElementModel = ElementModel,
controller: observable.ref,
label: observable,
style: observable,
ordering: computed({ equals: _.isEqual })
ordering: computed({
equals: (a: number[], b: number[]) =>
a.length === b.length && a.every((val, i) => val === b[i])
})
});
}

Expand Down Expand Up @@ -255,10 +257,10 @@ export default abstract class BaseElement<E extends ElementModel = ElementModel,
});

// remove children
_.difference(this.children, childElements).forEach(child => this.removeChild(child));
this.children.filter(c => !childElements.includes(c)).forEach(child => this.removeChild(child));

// add children
const toAdd = _.difference(childElements, this.children);
const toAdd = childElements.filter(c => !this.children.includes(c));
toAdd.reverse().forEach(child => this.insertChild(child, 0));
}
if ('data' in model) {
Expand All @@ -268,7 +270,7 @@ export default abstract class BaseElement<E extends ElementModel = ElementModel,
this.label = model.label;
}
if ('style' in model) {
_.merge(this.style, model.style);
this.style = { ...this.style, ...model.style };
}
}

Expand Down
8 changes: 4 additions & 4 deletions packages/module/src/layouts/BaseLayout.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import * as _ from 'lodash';
import { action, makeObservable } from 'mobx';
import {
Edge,
Expand Down Expand Up @@ -253,9 +252,10 @@ export class BaseLayout implements Layout {
return undefined;
}

let layoutNode = _.find(nodes, { id: node.getId() });
if (!layoutNode && _.size(node.getNodes())) {
layoutNode = _.find(nodes, { id: node.getChildren()[0].getId() });
let layoutNode = nodes.find(n => n.id === node.getId());
if (!layoutNode && node.getNodes().length) {
const id = node.getChildren()[0].getId();
layoutNode = nodes.find(n => n.id === id);
}
if (!layoutNode) {
layoutNode = this.getLayoutNode(nodes, getClosestVisibleParent(node));
Expand Down
Loading

0 comments on commit bed1c18

Please sign in to comment.