use of org.eclipse.elk.alg.disco.graph.DCElement in project elk by eclipse.
the class DisCoGraphRenderer method renderComponentGraph.
// added by mic
/**
* Paints all elements of the DCGraph that fall into the given dirty area.
*
* @param componentGraph
* The DCGraph to paint
* @param graphics
* the graphics context used to paint
* @param area
* dirty area that needs painting
* @param offset
* offset to be added to relative coordinates
* @param nodeAlpha
* alpha value for nodes
* @param fillingAlpha
* alpha value for node fillings
*/
private void renderComponentGraph(final ElkNode parent, final DCGraph componentGraph, final GC graphics, final Rectangle area, final KVector offset, final int nodeAlpha, final int fillingAlpha, final int levelNumber) {
KVector boundaries = new KVector(parent.getWidth(), parent.getHeight());
for (DCComponent comp : componentGraph.getComponents()) {
for (DCElement el : comp.getElements()) {
PaintPolygon poly = polygonMap.get(el);
if (poly == null) {
poly = new PaintPolygon(el, offset, getScale());
polygonMap.put(el, poly);
}
if (!poly.painted && poly.intersects(area)) {
// paint this node
graphics.setAlpha(fillingAlpha);
if (configurator.getDCElementFillColor() != null) {
graphics.setBackground(configurator.getDCElementFillColor());
graphics.fillPolygon(poly.coordsScaledAndRounded);
}
graphics.setAlpha(nodeAlpha);
if (configurator.getDCElementBorderTextColor() != null) {
graphics.setForeground(configurator.getDCElementBorderTextColor());
graphics.drawPolygon(poly.coordsScaledAndRounded);
if (configurator.getNodeLabelFont() != null) {
graphics.setFont(configurator.getNodeLabelFont());
}
if (state.drawLabels()) {
String levelprefix = levelNumber + "_";
if (state.removeLvl()) {
levelprefix = "";
}
graphics.drawString(levelprefix + Integer.toString(comp.getId()), poly.coordsScaledAndRounded[0], poly.coordsScaledAndRounded[1], true);
}
}
poly.painted = true;
}
ElkRectangle bounds = el.getBounds();
Rectangle2D.Double elementBounding = new Rectangle2D.Double(bounds.x, bounds.y, bounds.width, bounds.height);
double offsetX = elementBounding.getX() + el.getOffset().x;
double offsetY = elementBounding.getY() + el.getOffset().y;
elementBounding = new Rectangle2D.Double(offsetX, offsetY, elementBounding.getWidth(), elementBounding.getHeight());
for (DCExtension ext : el.getExtensions()) {
PaintRectangle rect = dcExtensionMap.get(ext);
if (rect == null) {
rect = new PaintRectangle(ext, elementBounding, boundaries, offset, getScale());
dcExtensionMap.put(ext, rect);
}
if (!rect.painted && rect.intersects(area)) {
graphics.setAlpha(fillingAlpha);
// CHECKSTYLEOFF MagicNumber
if (configurator.getDCElementExternalFillColor() != null) {
graphics.setBackgroundPattern(patterns.getDCExtensionPattern(state.makeSolid() ? 255 : fillingAlpha));
graphics.fillRectangle(rect.x, rect.y, rect.width, rect.height);
}
// CHECKSTYLEON MagicNumber
graphics.setAlpha(nodeAlpha);
if (configurator.getNodeBorderColor() != null) {
graphics.setForeground(configurator.getDCElementExternalBorderTextColor());
graphics.drawRectangle(rect.x, rect.y, rect.width, rect.height);
}
if (configurator.getDCElementExternalBorderTextColor() != null) {
graphics.setForeground(configurator.getDCElementExternalBorderTextColor());
if (configurator.getNodeLabelFont() != null) {
graphics.setFont(configurator.getNodeLabelFont());
}
if (state.drawLabels()) {
String levelprefix = levelNumber + "_";
if (state.removeLvl()) {
levelprefix = "";
}
graphics.drawString(levelprefix + Integer.toString(comp.getId()), rect.x, rect.y, true);
}
}
rect.painted = true;
}
}
}
}
}
use of org.eclipse.elk.alg.disco.graph.DCElement in project elk by eclipse.
the class ElkGraphTransformer method importElkShape.
/**
* Transforms a {@link ElkNode}, {@link ElkLabel} or {@link ElkPort} into a {@link DCElement} without destroying it.
* An offset may be applied, as some of these elements may have coordinates relative to another element, but the
* {@link DCGraph} only works with absolute coordinates.
*
* @param element
* Elemment to be transformed
* @param considerWhenApplyingOffset
* true - a key-value pair consisting of the original element and its {@link DCElement} representation
* will be saved and used later by {@link ElkGraphTransformer#applyLayout()} to set the original element
* to its new position after the layouting process has finished. false - the original element has
* coordinates relative to another element already moved and doesn't need new coordinates after
* layouting.
* @param offsetX
* X-Coordinate of the offset needed to make the given element's coordinates absolute (only needed, when
* the element has coordinates not relative to its parent {@link ElkNode}).
* @param offsetY
* Y-Coordinate of the offset needed to make the given element's coordinates absolute (only needed, when
* the element has coordinates not relative to its parent {@link ElkNode}).
* @return result of transformation
* @throws IllegalArgumentException
* A {@link ElkGraphElement} other than {@link ElkNode}, {@link ElkLabel} or {@link ElkPort} has been
* given as an argument.
*/
private <E extends ElkShape> DCElement importElkShape(final E element, final boolean considerWhenApplyingOffset, final double offsetX, final double offsetY) throws IllegalArgumentException {
if (!(element instanceof ElkNode || element instanceof ElkLabel || element instanceof ElkPort)) {
throw new IllegalArgumentException("Method only works for ElkNode-, ElkLabel and ElkPort-objects.");
}
double halfComponentSpacing = componentSpacing / 2;
double x0 = element.getX() + offsetX - halfComponentSpacing;
double y0 = element.getY() + offsetY - halfComponentSpacing;
double x1 = x0 + element.getWidth() + componentSpacing;
double y1 = y0 + element.getHeight() + componentSpacing;
KVectorChain coords = new KVectorChain();
coords.add(newPoint(x0, y0));
coords.add(newPoint(x0, y1));
coords.add(newPoint(x1, y1));
coords.add(newPoint(x1, y0));
DCElement shape = new DCElement(coords);
// copy all properties of original layout
shape.copyProperties(element);
if (considerWhenApplyingOffset) {
elementMapping.put(element, shape);
}
return shape;
}
use of org.eclipse.elk.alg.disco.graph.DCElement in project elk by eclipse.
the class ElkGraphTransformer method importElkEdge.
/**
* Transforms a {@link ElkEdge} into a {@link DCElement} without destroying it. Edges can have their own
* {@link ElkLabel ElkLabels}, so they will be transformed, too.
*
* @param edge
* Edge to be transformed into a {@link DCElement}
* @param newComponent
* Collection representing the component the edge and its associated labels (if any) belong to. Newly
* generated {@link DCElement DCElements} will be added to it
* @return {@link DCElement} resulting from the transformation
*/
private DCElement importElkEdge(final ElkEdge edge, final Collection<DCElement> newComponent) {
ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(edge, false, false);
List<KVector> points = ElkUtil.createVectorChain(edgeSection);
double thickness = edge.getProperty(DisCoOptions.EDGE_THICKNESS);
KVectorChain contour = getContour(points, thickness + componentSpacing);
DCElement shape = new DCElement(contour);
shape.copyProperties(edge);
elementMapping.put(edge, shape);
newComponent.add(shape);
// ElkEdges can have labels, too!
List<ElkLabel> labels = edge.getLabels();
for (ElkLabel label : labels) {
// "true" - ElkLabels belonging to an ElkEdge have absolute coordinates and have to be considered when
// applying
// changes to the DCGraph back to the original graph.
DCElement componentLabel = importElkShape(label, true, 0.0f, 0.0f);
newComponent.add(componentLabel);
}
return shape;
}
use of org.eclipse.elk.alg.disco.graph.DCElement in project elk by eclipse.
the class ElkGraphTransformer method importExtension.
/**
* Transforms a {@link ElkEdge} into a {@link DCElement} without destroying it. Edges can have their own
* {@link ElkLabel ElkLabels}, so they will be transformed, too.
*
* @param edge
* Edge to be transformed into a {@link DCElement}
* @param newComponent
* Collection representing the component the edge and its associated labels (if any) belong to. Newly
* generated {@link DCElement DCElements} will be added to it
* @return {@link DCElement} resulting from the transformation
*/
/**
* Transforms a short hierarchical {@link ElkEdge} into a {@link DCExtension} without destroying it. Edges can have
* their own {@link ElkLabel ElkLabels}, so they will be transformed, too.
*
* @param edge
* Edge to be transformed into a {@link DCExtension}
* @param newComponent
* component the extension will belong to
* @param outgoingExtension
* true, if the edge should be handled as an outgoing extension; false, otherwise
*/
private void importExtension(final ElkEdge edge, final Collection<DCElement> newComponent, final boolean outgoingExtension) {
ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(edge, false, false);
KVectorChain points = ElkUtil.createVectorChain(edgeSection);
if (outgoingExtension) {
points = KVectorChain.reverse(points);
}
// Is going to hold the extension
DCElement shape;
double thickness = edge.getProperty(DisCoOptions.EDGE_THICKNESS);
KVector outerPoint = points.getFirst();
KVector innerPoint = points.get(1);
if (points.size() > 2) {
List<KVector> fixedEdgePoints = Lists.newArrayList();
fixedEdgePoints.addAll(points.subList(1, points.size()));
KVectorChain contour = getContour(fixedEdgePoints, thickness + componentSpacing);
shape = new DCElement(contour);
shape.copyProperties(edge);
newComponent.add(shape);
} else {
if (outgoingExtension) {
shape = elementMapping.get(ElkGraphUtil.getSourceNode(edge));
} else {
shape = elementMapping.get(ElkGraphUtil.getTargetNode(edge));
}
}
// Construct the extension and add to mapping
ElkNode extParent = ElkGraphUtil.getSourceNode(edge);
if (outgoingExtension) {
extParent = ElkGraphUtil.getTargetNode(edge);
}
DCDirection dir = nearestSide(outerPoint, extParent);
double extensionWidth = thickness + componentSpacing;
KVector middlePos;
if (dir.isHorizontal()) {
// West or east extension
extensionWidth += Math.abs(outerPoint.y - innerPoint.y);
middlePos = new KVector(innerPoint.x, (innerPoint.y + outerPoint.y) / 2);
} else {
extensionWidth += Math.abs(outerPoint.x - innerPoint.x);
middlePos = new KVector((innerPoint.x + outerPoint.x) / 2, innerPoint.y);
}
if (outgoingExtension) {
outgoingExtensionsMapping.put(edge, new DCExtension(shape, dir, middlePos, extensionWidth));
} else {
incomingExtensionsMapping.put(edge, new DCExtension(shape, dir, middlePos, extensionWidth));
}
elementMapping.put(edge, shape);
// ElkEdges can have labels, too!
List<ElkLabel> labels = edge.getLabels();
for (ElkLabel label : labels) {
// "true" - ElkLabels belonging to an ElkEdge have absolute coordinates and have to be considered when
// applying
// changes to the DCGraph back to the original graph.
DCElement componentLabel = importElkShape(label, true, 0.0f, 0.0f);
newComponent.add(componentLabel);
}
}
use of org.eclipse.elk.alg.disco.graph.DCElement in project elk by eclipse.
the class ElkGraphTransformer method importGraph.
// /////////////////////////////////////////////////////////////////////////////
// Implementation of interface methods
@Override
public DCGraph importGraph(final ElkNode graph) {
parent = graph;
// Split graph into components
List<List<ElkNode>> components = ElkGraphComponentsProcessor.split(graph);
// This list of lists is used to construct the DCGraph from its smallest units, so called DCElements.
List<List<DCElement>> result = Lists.newArrayList();
for (List<ElkNode> component : components) {
// Each of the subResult lists will represent a connected component in the DCGraph.
List<DCElement> subResult = Lists.newArrayList();
result.add(subResult);
Set<ElkEdge> edgeSet = Sets.newHashSet();
for (ElkNode node : component) {
// "true" indicates - we need to consider the position of ElkNodes when applying the new layout of the
// DCGraph back to the KGraph.
DCElement componentNode = importElkShape(node, true, 0.0f, 0.0f);
subResult.add(componentNode);
// Compute offset for labels (used for computing absolute position)
double nodeX = node.getX();
double nodeY = node.getY();
// For use in the Debugview only
componentNode.setParentCoords(new KVector(nodeX, nodeY));
// next look at all labels of this ElkNode ...
List<ElkLabel> labels = node.getLabels();
for (ElkLabel label : labels) {
// "false" indicates - ElkLabels belonging to nodes have coordinates relative to their ElkNode. So
// don't
// adjust their position when applying the layout of the DCGraph back to the KGraph.
DCElement componentLabel = importElkShape(label, false, nodeX, nodeY);
subResult.add(componentLabel);
}
// ... then the ports of the ElkNode
List<ElkPort> ports = node.getPorts();
for (ElkPort port : ports) {
// "false" - ElkPorts have coordinates relative to their ElkNode
DCElement componentPort = importElkShape(port, false, nodeX, nodeY);
subResult.add(componentPort);
// ElkPorts can have labels, too!
// Compute offset for labels of ElkPorts
double portX = port.getX() + nodeX;
double portY = port.getY() + nodeY;
labels = port.getLabels();
for (ElkLabel label : labels) {
// false - ElkLabels have coordinates relative to their ElkPort
DCElement componentLabel = importElkShape(label, false, portX, portY);
subResult.add(componentLabel);
}
}
edgeSet.addAll(Sets.newHashSet(ElkGraphUtil.allIncidentEdges(node)));
}
importElkEdges(edgeSet, subResult);
}
// Finally create the DCGraph
transformedGraph = new DCGraph(result, componentSpacing / 2);
// Don't forget to copy properties of parent ElkNode to the DCGraph
transformedGraph.copyProperties(graph);
return transformedGraph;
}
Aggregations