Skip to content

Commit

Permalink
Implemented CartesianNodeComparator
Browse files Browse the repository at this point in the history
  • Loading branch information
pvlasov committed Jul 1, 2024
1 parent 95773ad commit 498a229
Showing 1 changed file with 166 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package org.nasdanika.drawio.comparators;

import java.util.Comparator;

import java.util.Objects;
import org.nasdanika.drawio.Rectangle;
import org.nasdanika.drawio.Node;

/**
Expand All @@ -10,12 +11,175 @@
*
*/
public class CartesianNodeComparator implements Comparator<Node> {

public enum Direction {
rightDown,
rightUp,
leftDown,
leftUp,
downRight,
downLeft,
upRight,
upLeft
}

private Direction direction;
private Comparator<? super Node> fallback;

public CartesianNodeComparator(Direction direction, Comparator<? super Node> fallback) {
this.direction = direction;
this.fallback = fallback;
}

// Modes - right-down, right-up, left-down, left-up, down-right, ... - 3 boolean flags, 8 combinations. enum?

@Override
public int compare(Node o1, Node o2) {
// TODO Auto-generated method stub
if (Objects.equals(o1, o2)) {
return 0;
}

if (o1 == null) {
return 1;
}

if (o2 == null) {
return -1;
}

if (!Objects.equals(o1.getModel().getPage(), o2.getModel().getPage())) {
throw new IllegalArgumentException("Nodes belong to different pages");
}

switch (direction) {
case downLeft: {
// Horizontal first - to the left is smaller than to the right
int hcmp = compareHorizontal(o1, o2);
if (hcmp != 0) {
return hcmp;
}
// Vertical
int vcmp = compareVertical(o1, o2);
return vcmp == 0 ? fallback.compare(o1, o2) : vcmp;
}
case downRight: {
// Horizontal first - to the left is smaller than to the right
int hcmp = compareHorizontal(o1, o2);
if (hcmp != 0) {
return -hcmp;
}
// Vertical
int vcmp = compareVertical(o1, o2);
return vcmp == 0 ? fallback.compare(o1, o2) : vcmp;
}
case leftDown: {
// Vertical first - to the left is smaller than to the right
int vcmp = compareVertical(o1, o2);
if (vcmp != 0) {
return vcmp;
}
// Horizontal
int hcmp = compareHorizontal(o1, o2);
return hcmp == 0 ? fallback.compare(o1, o2) : -hcmp;
}
case leftUp: {
// Vertical first - to the left is smaller than to the right
int vcmp = compareVertical(o1, o2);
if (vcmp != 0) {
return -vcmp;
}
// Horizontal
int hcmp = compareHorizontal(o1, o2);
return hcmp == 0 ? fallback.compare(o1, o2) : -hcmp;
}
case rightUp: {
// Vertical first - to the left is smaller than to the right
int vcmp = compareVertical(o1, o2);
if (vcmp != 0) {
return -vcmp;
}
// Horizontal
int hcmp = compareHorizontal(o1, o2);
return hcmp == 0 ? fallback.compare(o1, o2) : hcmp;
}
case rightDown: {
// Vertical first - to the left is smaller than to the right
int vcmp = compareVertical(o1, o2);
if (vcmp != 0) {
return vcmp;
}
// Horizontal
int hcmp = compareHorizontal(o1, o2);
return hcmp == 0 ? fallback.compare(o1, o2) : hcmp;
}
case upLeft: {
// Horizontal first - to the left is smaller than to the right
int hcmp = compareHorizontal(o1, o2);
if (hcmp != 0) {
return -hcmp;
}
// Vertical
int vcmp = compareVertical(o1, o2);
return vcmp == 0 ? fallback.compare(o1, o2) : -vcmp;
}
case upRight: {
// Horizontal first - to the left is smaller than to the right
int hcmp = compareHorizontal(o1, o2);
if (hcmp != 0) {
return -hcmp;
}
// Vertical
int vcmp = compareVertical(o1, o2);
return vcmp == 0 ? fallback.compare(o1, o2) : vcmp;
}
default:
break;

}
return fallback.compare(o1, o2);
}

/**
* Returns true if the second node is below the first node
* @param o1
* @param o2
*/
private static boolean below(Node o1, Node o2) {
// System.out.println("Below: " + Jsoup.parse(o1.getLabel()).text() + " - " + Jsoup.parse(o2.getLabel()).text());

Rectangle g1 = AngularNodeComparator.getAbsoluteGeometry(o1);
return g1.getY() + g1.getHeight() < AngularNodeComparator.getAbsoluteGeometry(o2).getY();
}

/**
* Returns true if the second node is below the first node
* @param o1
* @param o2
*/
private static boolean after(Node o1, Node o2) {
// System.out.println("After " + Jsoup.parse(o1.getLabel()).text() + " - " + Jsoup.parse(o2.getLabel()).text());

Rectangle g1 = AngularNodeComparator.getAbsoluteGeometry(o1);
return g1.getX() + g1.getWidth() < AngularNodeComparator.getAbsoluteGeometry(o2).getX();
}

protected int compareVertical(Node o1, Node o2) {
if (below(o1, o2)) {
return -1;
}
if (below(o2, o1)) {
return 1;
}
return 0;
}

protected int compareHorizontal(Node o1, Node o2) {
if (after(o1, o2)) {
return -1;
}
if (after(o2, o1)) {
return 1;
}
return 0;
}

Expand Down

0 comments on commit 498a229

Please sign in to comment.