Skip to content
This repository has been archived by the owner on Jul 31, 2024. It is now read-only.

Commit

Permalink
f-dag-app code segregation
Browse files Browse the repository at this point in the history
  • Loading branch information
vikas-cldcvr committed Jun 26, 2024
1 parent 7a62260 commit aa96d8b
Show file tree
Hide file tree
Showing 10 changed files with 717 additions and 664 deletions.
110 changes: 110 additions & 0 deletions packages/flow-lineage/src/components/f-dag/add-group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { html } from "lit";
import type { FDag } from "./f-dag";
import type { FInput, FSelect, FTabNode } from "@ollion/flow-core";

export function addGroupPopover(this: FDag) {
return html` <f-popover size="small" id="add-group-popover" .overlay=${false} target="#add-group">
<f-div @wheel=${(e: Event) => e.stopPropagation()}>
<f-tab>
<f-tab-node
@click=${this.switchTab}
class="gr-selection-tabs"
active
content-id=${`existing-group-selection`}
>
<f-div width="100%" height="100%" align="middle-center" direction="column">
Exisiting
</f-div>
</f-tab-node>
<f-tab-node @click=${this.switchTab} class="gr-selection-tabs" content-id=${`new-group`}>
<f-div width="100%" height="100%" align="middle-center" direction="column">
Create New
</f-div>
</f-tab-node>
</f-tab>
<f-tab-content id="existing-group-selection">
<f-div padding="medium" gap="medium">
<f-select
id="f-group-dropdown"
placeholder="Select Group"
@input=${this.addToGroup}
.options=${this.config.groups.map(g => g.id)}
></f-select>
</f-div>
</f-tab-content>
<f-tab-content id="new-group">
<f-div direction="column">
<f-div padding="medium" gap="medium">
<f-input id="new-group-id" placeholder="New Group Id"></f-input>
<f-input id="new-group-label" placeholder="New Group Label"></f-input>
</f-div>
<f-div>
<f-button variant="block" label="Add" @click=${this.addToNewGroup}></f-button>
</f-div>
</f-div>
</f-tab-content>
</f-div>
</f-popover>`;
}

export function handleAddGroup(this: FDag) {
this.addGroupPopoverRef.open = true;
}

export function addSelectionToGroup(this: FDag, groupid: string) {
this.selectedNodes.forEach(sn => {
sn.group = groupid;
});

this.addGroupPopoverRef.open = false;

this.config.nodes.forEach(n => {
n.x = undefined;
n.y = undefined;
});
this.config.groups.forEach(n => {
n.x = undefined;
n.y = undefined;
});

this.config.links.forEach(l => {
l.from.x = undefined;
l.from.y = undefined;
l.to.x = undefined;
l.to.y = undefined;
});

this.selectedNodes = [];
this.addGroupButton.style.display = "none";
this.requestUpdate();
}

export function addToNewGroup(this: FDag) {
const groupIdInput = this.querySelector<FInput>("#new-group-id")!;
const groupLabelInput = this.querySelector<FInput>("#new-group-label")!;

this.config.groups.push({
id: groupIdInput.value as string,
label: groupLabelInput.value as string,
icon: "i-org"
});

this.addSelectionToGroup(groupIdInput.value as string);
}

export function addToGroup(this: FDag) {
const groupDropdown = this.querySelector<FSelect>(`#f-group-dropdown`)!;
const groupid = groupDropdown.value as string;

this.addSelectionToGroup(groupid);
}

export function switchTab(this: FDag, event: PointerEvent) {
const tabNodeElement = event.currentTarget as FTabNode;

this.groupSelectionTabs.forEach(tab => {
tab.active = false;
});
tabNodeElement.active = true;
}
22 changes: 22 additions & 0 deletions packages/flow-lineage/src/components/f-dag/background-svg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { html } from "lit";

export default function backgroundSVG() {
return html` <svg
class="background-svg"
style="position: absolute;width: 100%;height: 100%;top: 0px;left: 0px;"
>
<pattern
class="background-pattern"
id="pattern-1undefined"
x="0"
y="0"
width="24"
height="24"
patternUnits="userSpaceOnUse"
patternTransform="translate(-0.5,-0.5)"
>
<circle cx="0.5" cy="0.5" r="1" fill="var(--color-border-subtle)"></circle>
</pattern>
<rect x="0" y="0" width="100%" height="100%" fill="url(#pattern-1undefined)"></rect>
</svg>`;
}
242 changes: 242 additions & 0 deletions packages/flow-lineage/src/components/f-dag/compute-placement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
import type { FDag } from "./f-dag";
import buildHierarchy from "./hierarchy-builder";
import {
CustomPlacementByElement,
CustomPlacementBySection,
FDagElement,
FDagGroup,
HierarchyNode
} from "./types";

export default function computePlacement(this: FDag) {
this.groupsHTML = [];
this.nodesHTML = [];
const { roots: rootNodes, customPlacements } = buildHierarchy(this.config);

const positionNodes = (
containerId: string,
elements: HierarchyNode[],
x: number,
y: number,
isCollapsed: boolean,
spaceX = 100,
spaceY = 100
) => {
const elementIds = elements.map(e => e.id);
const conatinerElementObject = this.getElement(containerId) as FDagGroup;
const layoutDirection = (() => {
if (containerId === "root") {
return this.config.layoutDirection;
}
if (conatinerElementObject.layoutDirection === "vertical") {
return "horizontal";
}
return "vertical";
})();
const nodeLinks = this.config.links.filter(
l => elementIds.includes(l.from.elementId) && elementIds.includes(l.to.elementId)
);
const roots = new Set<HierarchyNode>(elements);
const nonroots = new Set<HierarchyNode>();
nodeLinks.forEach(link => {
const fromElement = elements.find(e => e.id === link.from.elementId)!;
if (!nonroots.has(fromElement)) {
roots.add(fromElement);
}
if (!fromElement.next) {
fromElement.next = [];
}

const toElement = elements.find(e => e.id === link.to.elementId)!;
if (roots.has(toElement)) {
roots.delete(toElement);
}
nonroots.add(toElement);
fromElement.next.push(toElement);
});

const initialY = y;
const initialX = x;
let maxX = 0;
let maxY = 0;
const minX = x;
const minY = y;
let section = 0;
const calculateCords = (ns: HierarchyNode[]) => {
const nexts: HierarchyNode[] = [];
let maxWidth = this.defaultElementWidth;
let maxHeight = this.defaultElementHeight;
section += 1;
const nextSection = () => {
if (!isCollapsed) {
if (layoutDirection === "vertical") {
y += maxHeight + spaceY;
x = initialX;
} else {
x += maxWidth + spaceX;
y = initialY;
}
}
};

let currentNodeId: string | null;
const isElementPlacement = (elementObject: FDagElement) =>
elementObject.placement &&
(elementObject.placement as CustomPlacementByElement).elementId === currentNodeId;
const isSectionPlacement = (elementObject: FDagElement) =>
elementObject.placement &&
(elementObject.placement as CustomPlacementBySection).section === section &&
containerId === "root";
const placeElement = (n: HierarchyNode) => {
const elementObject = this.getElement(n.id);
if (
!elementObject.placement ||
isSectionPlacement(elementObject) ||
isElementPlacement(elementObject)
) {
const customPlacementsByElements = this.getCustomPlacementElementsByElementId(
elementObject.id,
customPlacements
);
if (customPlacementsByElements.length > 0) {
currentNodeId = elementObject.id;
}
const beforeCustomElements = customPlacementsByElements.filter(
c => c?.placement?.position === "before"
);
const afterCustomElements = customPlacementsByElements.filter(
c => c?.placement?.position === "after"
);
beforeCustomElements.forEach(b => {
if (b) placeElement(b);
});

if (elementObject.x === undefined) {
elementObject.x = x;
} else {
x = elementObject.x;
}
if (elementObject.y === undefined) {
elementObject.y = y;
} else {
y = elementObject.y;
}

if (n.type === "group" && n.children && n.children.length > 0) {
const isCollapseRequired =
isCollapsed || Boolean((elementObject as FDagGroup).collapsed);
const { width, height } = positionNodes(
n.id,
n.children,
isCollapseRequired ? x : x + 20,
isCollapseRequired ? y : y + 60,
isCollapseRequired,
(elementObject as FDagGroup).spacing?.x,
(elementObject as FDagGroup).spacing?.y
);
if (isCollapsed) {
elementObject.hidden = true;
} else {
elementObject.hidden = false;
}
elementObject.width = width < 150 ? 150 : width;
elementObject.height = height + (isCollapseRequired ? 0 : 20);
} else if (isCollapsed) {
elementObject.hidden = true;
} else {
elementObject.hidden = false;
}

if (!elementObject.width) {
elementObject.width = this.defaultElementWidth;
}
if (!elementObject.height) {
elementObject.height = this.defaultElementHeight;
}

if (n.type === "group") {
this.groupsHTML.push(this.getNodeGroupTemplate(elementObject, "group"));
} else {
this.nodesHTML.push(this.getNodeGroupTemplate(elementObject));
}

if (x + elementObject.width > maxX) {
maxX = x + elementObject.width;
}
if (y + elementObject.height > maxY) {
maxY = y + elementObject.height;
}

if (!isCollapsed) {
if (layoutDirection === "vertical") {
x += elementObject.width + spaceX;
} else {
y += elementObject.height + spaceY;
}
}

if (elementObject.width > maxWidth) {
maxWidth = elementObject.width;
}
if (elementObject.height > maxHeight) {
maxHeight = elementObject.height;
}
afterCustomElements.forEach(b => {
if (b) placeElement(b);
});
currentNodeId = null;
if (n.next) nexts.push(...n.next);
}
};
const customPlacementsElements =
containerId === "root" ? this.getCustomPlacementElements(section, customPlacements) : [];

const beforeElements =
containerId === "root"
? customPlacementsElements.filter(c => c?.placement?.position === "before")
: [];
const afterElements =
containerId === "root"
? customPlacementsElements.filter(c => c?.placement?.position === "after")
: [];
beforeElements.forEach(b => {
if (b) placeElement(b);
});

if (beforeElements.length > 0) {
nextSection();
maxHeight = this.defaultElementHeight;
maxWidth = this.defaultElementWidth;
}

const skipTheseElements = [...beforeElements, ...afterElements].map(ba => ba?.id);
ns.filter(n => !skipTheseElements.includes(n.id)).forEach(placeElement);

if (afterElements.length > 0) {
nextSection();
maxHeight = this.defaultElementHeight;
maxWidth = this.defaultElementWidth;
}
afterElements.forEach(b => {
if (b) placeElement(b);
});
nextSection();

if (nexts.length > 0) calculateCords(nexts);
};
calculateCords(Array.from(roots));
if (isCollapsed) {
return {
width: this.collapsedNodeWidth,
height: this.collapsedNodeHeight
};
}

return {
width: maxX - minX + 40,
height: maxY - minY + 60
};
};

positionNodes("root", rootNodes, 0, 0, false, this.config.spacing?.x, this.config.spacing?.y);
}
Loading

0 comments on commit aa96d8b

Please sign in to comment.