Skip to content

Commit

Permalink
[2483] Take the header into account in the reactflow layout
Browse files Browse the repository at this point in the history
Bug: #2483
Signed-off-by: Guillaume Coutable <guillaume.coutable@obeo.fr>
  • Loading branch information
gcoutable committed Oct 30, 2023
1 parent 9000391 commit 5bf84f8
Show file tree
Hide file tree
Showing 13 changed files with 38 additions and 15 deletions.
Expand Up @@ -75,7 +75,13 @@ const toRectangularNode = (
data.label = {
id: insideLabel.id,
text: insideLabel.text,
isHeader: insideLabel.isHeader,
style: {
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
padding: '8px 16px',
textAlign: 'center',
...convertLabelStyle(labelStyle),
},
Expand All @@ -85,6 +91,9 @@ const toRectangularNode = (
const alignement = AlignmentMap[insideLabel.insideLabelLocation];
if (alignement.isPrimaryVerticalAlignment) {
if (alignement.primaryAlignment === 'TOP') {
if (data.label.isHeader) {
data.label.style.borderBottom = `${style.borderSize}px ${style.borderStyle} ${style.borderColor}`;
}
data.style = { ...data.style, display: 'flex', flexDirection: 'column', justifyContent: 'flex-start' };
}
if (alignement.secondaryAlignment === 'CENTER') {
Expand Down Expand Up @@ -212,6 +221,7 @@ const toListNode = (
id: insideLabel.id,
text: insideLabel.text,
iconURL: labelStyle.iconURL,
isHeader: insideLabel.isHeader,
style: {
display: 'flex',
flexDirection: 'row',
Expand All @@ -226,7 +236,7 @@ const toListNode = (
const alignement = AlignmentMap[insideLabel.insideLabelLocation];
if (alignement.isPrimaryVerticalAlignment) {
if (alignement.primaryAlignment === 'TOP') {
if (insideLabel.isHeader) {
if (data.label.isHeader) {
data.label.style.borderBottom = `${style.borderSize}px ${style.borderStyle} ${style.borderColor}`;
}
data.style = { ...data.style, display: 'flex', flexDirection: 'column', justifyContent: 'flex-start' };
Expand Down
Expand Up @@ -82,4 +82,5 @@ export interface Label {
text: string;
iconURL: string[];
style: React.CSSProperties;
isHeader?: boolean;
}
Expand Up @@ -81,6 +81,7 @@ export class ListNodeLayoutHandler implements INodeLayoutHandler<ListNodeData> {

const nodeIndex = findNodeIndex(visibleNodes, node.id);
const labelElement = document.getElementById(`${node.id}-label-${nodeIndex}`);
const withHeader = node.data.label?.isHeader;

const borderNodes = directChildren.filter((node) => node.data.isBorderNode);
const directNodesChildren = directChildren.filter((child) => !child.data.isBorderNode);
Expand All @@ -103,7 +104,7 @@ export class ListNodeLayoutHandler implements INodeLayoutHandler<ListNodeData> {
directNodesChildren.forEach((child, index) => {
child.position = {
x: borderWidth,
y: borderWidth + (labelElement?.getBoundingClientRect().height ?? 0),
y: borderWidth + (withHeader ? labelElement?.getBoundingClientRect().height ?? 0 : 0),
};
const previousSibling = directNodesChildren[index - 1];
if (previousSibling) {
Expand All @@ -116,8 +117,7 @@ export class ListNodeLayoutHandler implements INodeLayoutHandler<ListNodeData> {
const labelOnlyWidth = labelElement?.getBoundingClientRect().width ?? 0;
const nodeWidth = Math.max(childrenContentBox.width, labelOnlyWidth) + borderWidth * 2;

const directChildrenAwareNodeHeight =
(labelElement?.getBoundingClientRect().height ?? 0) + childrenContentBox.height + borderWidth * 2;
const directChildrenAwareNodeHeight = childrenContentBox.y + childrenContentBox.height + borderWidth;

const eastBorderNodeFootprintHeight = getEastBorderNodeFootprintHeight(visibleNodes, borderNodes, previousDiagram);
const westBorderNodeFootprintHeight = getWestBorderNodeFootprintHeight(visibleNodes, borderNodes, previousDiagram);
Expand Down
Expand Up @@ -68,6 +68,7 @@ export class RectangleNodeLayoutHandler implements INodeLayoutHandler<Rectangula

const nodeIndex = findNodeIndex(visibleNodes, node.id);
const labelElement = document.getElementById(`${node.id}-label-${nodeIndex}`);
const withHeader = node.data.label?.isHeader ?? false;

const borderNodes = directChildren.filter((node) => node.data.isBorderNode);
const directNodesChildren = directChildren.filter((child) => !child.data.isBorderNode);
Expand All @@ -79,10 +80,17 @@ export class RectangleNodeLayoutHandler implements INodeLayoutHandler<Rectangula
if (previousNode) {
child.position = previousNode.position;
} else {
child.position = getChildNodePosition(visibleNodes, child, labelElement, borderWidth);
child.position = getChildNodePosition(visibleNodes, child, labelElement, withHeader, borderWidth);
const previousSibling = directNodesChildren[index - 1];
if (previousSibling) {
child.position = getChildNodePosition(visibleNodes, child, labelElement, borderWidth, previousSibling);
child.position = getChildNodePosition(
visibleNodes,
child,
labelElement,
withHeader,
borderWidth,
previousSibling
);
}
}
});
Expand Down
Expand Up @@ -67,10 +67,12 @@ export const getNodeOrMinHeight = (nodeHeight: number | undefined): number => {
return Math.max(nodeHeight ?? -Infinity, defaultHeight);
};

// WARN: should be moved in RectangularNodeLayoutHandler.ts
export const getChildNodePosition = (
allVisibleNodes: Node<NodeData>[],
child: Node<NodeData>,
labelElement: HTMLElement | null,
withHeader: boolean,
borderWidth: number,
previousSibling?: Node<NodeData>
) => {
Expand All @@ -85,14 +87,11 @@ export const getChildNodePosition = (
.reduce((a, b) => Math.max(a, b), 0);

if (!previousSibling) {
const headerFootprint = withHeader ? labelElement?.getBoundingClientRect().height ?? 0 : 0;

return {
x: rectangularNodePadding + borderWidth + maxWestBorderNodeWidth,
y:
borderWidth +
rectangularNodePadding +
maxNorthBorderNodeHeight +
(labelElement?.getBoundingClientRect().height ?? 0) +
rectangularNodePadding,
y: borderWidth + headerFootprint + rectangularNodePadding + maxNorthBorderNodeHeight,
};
} else {
const previousSiblingsMaxEastBorderNodeWidth = getChildren(previousSibling, allVisibleNodes)
Expand Down
Expand Up @@ -29,7 +29,6 @@ const rectangularNodeStyle = (
faded: boolean
): React.CSSProperties => {
const rectangularNodeStyle: React.CSSProperties = {
padding: '8px',
width: '100%',
height: '100%',
opacity: faded ? '0.4' : '',
Expand Down
Expand Up @@ -45,6 +45,7 @@ public NodeDescription create() {
nodeStyle.setColor(this.colorProvider.getColor("color_blue_7"));
nodeStyle.setBorderColor(this.colorProvider.getColor("border_blue_3"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
nodeStyle.setWithHeader(true);

var builder = new PapayaViewBuilder();
var domainType = builder.domainType(builder.entity("Package"));
Expand Down
Expand Up @@ -47,7 +47,7 @@ public NodeDescription create() {
nodeStyle.setColor(this.colorProvider.getColor("color_blue"));
nodeStyle.setBorderColor(this.colorProvider.getColor("border_blue"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_white"));
nodeStyle.setWithHeader(false);
nodeStyle.setWithHeader(true);

var nodeDescription = new PapayaViewBuilder().createNodeDescription("Class");
nodeDescription.setSemanticCandidatesExpression("aql:self.types");
Expand All @@ -70,7 +70,7 @@ public NodeDescription create() {
abstractNodeStyle.setColor(this.colorProvider.getColor("color_green"));
abstractNodeStyle.setBorderColor(this.colorProvider.getColor("border_green"));
abstractNodeStyle.setLabelColor(this.colorProvider.getColor("label_white"));
abstractNodeStyle.setWithHeader(false);
abstractNodeStyle.setWithHeader(true);

var abstractConditionalNodeStyle = DiagramFactory.eINSTANCE.createConditionalNodeStyle();
abstractConditionalNodeStyle.setCondition("aql:self.abstract");
Expand Down
Expand Up @@ -43,6 +43,7 @@ public NodeDescription create() {
nodeStyle.setColor(this.colorProvider.getColor("color_blue_4"));
nodeStyle.setBorderColor(this.colorProvider.getColor("border_blue_4"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
nodeStyle.setWithHeader(true);

var nodeDescription = new PapayaViewBuilder().createNodeDescription("Component");
nodeDescription.setSemanticCandidatesExpression("aql:self.components");
Expand Down
Expand Up @@ -45,6 +45,7 @@ public NodeDescription create() {
nodeStyle.setColor(this.colorProvider.getColor("color_blue_7"));
nodeStyle.setBorderColor(this.colorProvider.getColor("border_blue_3"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
nodeStyle.setWithHeader(true);

var nodeDescription = new PapayaViewBuilder().createNodeDescription("Package");
nodeDescription.setSemanticCandidatesExpression("aql:self.eContents()");
Expand Down
Expand Up @@ -42,6 +42,7 @@ public NodeDescription create() {
operationalActorNodeStyle.setColor(this.colorProvider.getColor("color_gray"));
operationalActorNodeStyle.setBorderColor(this.colorProvider.getColor("border_gray"));
operationalActorNodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
operationalActorNodeStyle.setWithHeader(true);

var operationalActorEmptyNodeStyle = DiagramFactory.eINSTANCE.createImageNodeStyleDescription();
operationalActorEmptyNodeStyle.setShape("4d9a22c0-dc36-31c9-bb6a-c18c66b51d93");
Expand Down
Expand Up @@ -42,6 +42,7 @@ public NodeDescription create() {
nodeStyle.setColor(this.colorProvider.getColor("color_gray"));
nodeStyle.setBorderColor(this.colorProvider.getColor("border_gray"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
nodeStyle.setWithHeader(true);

var builder = new PapayaViewBuilder();

Expand Down
Expand Up @@ -43,6 +43,7 @@ public NodeDescription create() {
nodeStyle.setColor(this.colorProvider.getColor("color_gray_2"));
nodeStyle.setBorderColor(this.colorProvider.getColor("border_gray_2"));
nodeStyle.setLabelColor(this.colorProvider.getColor("label_black"));
nodeStyle.setWithHeader(true);

var nodeDescription = new PapayaViewBuilder().createNodeDescription("OperationalPerimeter");
nodeDescription.setSemanticCandidatesExpression("aql:self.operationalPerimeters");
Expand Down

0 comments on commit 5bf84f8

Please sign in to comment.