You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by pa...@apache.org on 2022/03/03 20:07:31 UTC
[beam] branch master updated: [BEAM-13999] playground - support vertical orientation for graph
This is an automated email from the ASF dual-hosted git repository.
pabloem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/beam.git
The following commit(s) were added to refs/heads/master by this push:
new 43804b5 [BEAM-13999] playground - support vertical orientation for graph
new fa5fffd Merge pull request #16963 from [BEAM-13999] [Playground] support vertical orientation for graph
43804b5 is described below
commit 43804b5b67c91554749b7400437ffa48fcd3c3ac
Author: Aydar Farrakhov <st...@gmail.com>
AuthorDate: Mon Feb 28 17:08:54 2022 +0300
[BEAM-13999] playground - support vertical orientation for graph
---
.../modules/graph/graph_builder/canvas_drawer.dart | 11 +-
.../modules/graph/graph_builder/graph_builder.dart | 25 +++--
.../graph/graph_builder/painters/edge_painter.dart | 118 ++++++++++++++++++---
.../graph_builder/painters/graph_painter.dart | 18 +++-
.../lib/modules/output/components/graph.dart | 15 ++-
.../lib/modules/output/components/output_area.dart | 22 ++--
6 files changed, 172 insertions(+), 37 deletions(-)
diff --git a/playground/frontend/lib/modules/graph/graph_builder/canvas_drawer.dart b/playground/frontend/lib/modules/graph/graph_builder/canvas_drawer.dart
index df870aa..59cbda7 100644
--- a/playground/frontend/lib/modules/graph/graph_builder/canvas_drawer.dart
+++ b/playground/frontend/lib/modules/graph/graph_builder/canvas_drawer.dart
@@ -104,7 +104,7 @@ class CanvasDrawer {
canvas.drawCircle(Offset(x1, y1), radius, linePaint);
}
- drawArrow(double x1, double y1) {
+ drawRightArrow(double x1, double y1) {
final path = Path();
path.moveTo(x1 - kArrowSize, y1 - kArrowSize);
path.lineTo(x1 + kArrowSize, y1);
@@ -113,6 +113,15 @@ class CanvasDrawer {
canvas.drawPath(path, linePaint);
}
+ drawBottomArrow(double x1, double y1) {
+ final path = Path();
+ path.moveTo(x1 - kArrowSize, y1);
+ path.lineTo(x1, y1 + kArrowSize);
+ path.lineTo(x1 + kArrowSize, y1);
+ path.lineTo(x1 - kArrowSize, y1);
+ canvas.drawPath(path, linePaint);
+ }
+
drawRect(
double left,
double top,
diff --git a/playground/frontend/lib/modules/graph/graph_builder/graph_builder.dart b/playground/frontend/lib/modules/graph/graph_builder/graph_builder.dart
index 1c78b4f..53901aa 100644
--- a/playground/frontend/lib/modules/graph/graph_builder/graph_builder.dart
+++ b/playground/frontend/lib/modules/graph/graph_builder/graph_builder.dart
@@ -60,7 +60,7 @@ abstract class GraphBuilder {
void parseNextLine(String line);
- GraphPainter getPainter() {
+ GraphPainter getPainter(GraphDirection direction) {
final List<Node> nodeElements = elements
.where((element) => element.type == NodeType.node)
.toList()
@@ -80,14 +80,21 @@ abstract class GraphBuilder {
);
return GraphPainter(
+ direction: direction,
elementsPainter: elements
.where((element) => element.type == NodeType.node)
- .map<NodeElementPainter>((element) => NodeElementPainter(
- element: element as Node,
- row: nodeToCellMap[element.name]!.row,
- column: nodeToCellMap[element.name]!.column,
- ))
- .toList(),
+ .map<NodeElementPainter>((element) {
+ final cell = nodeToCellMap[element.name]!;
+ final row =
+ direction == GraphDirection.horizontal ? cell.row : cell.column;
+ final column =
+ direction == GraphDirection.horizontal ? cell.column : cell.row;
+ return NodeElementPainter(
+ element: element as Node,
+ row: row,
+ column: column,
+ );
+ }).toList(),
edges: edges.map((e) => EdgePainter(e)).toList(),
);
}
@@ -237,8 +244,8 @@ class PythonGraphBuilder extends GraphBuilder {
if (elementsMap[name] != null) {
return;
}
- final label =
- name.replaceFirst(kPythonDefaultCollectionLabel, kPythonCollectionLabel);
+ final label = name.replaceFirst(
+ kPythonDefaultCollectionLabel, kPythonCollectionLabel);
Node node = Node(label: label, depth: 1, name: name);
elementsMap[name] = node;
elements.add(node);
diff --git a/playground/frontend/lib/modules/graph/graph_builder/painters/edge_painter.dart b/playground/frontend/lib/modules/graph/graph_builder/painters/edge_painter.dart
index 63be832..d676105 100644
--- a/playground/frontend/lib/modules/graph/graph_builder/painters/edge_painter.dart
+++ b/playground/frontend/lib/modules/graph/graph_builder/painters/edge_painter.dart
@@ -20,22 +20,43 @@ import 'dart:math';
import 'package:collection/collection.dart';
import 'package:playground/constants/sizes.dart';
import 'package:playground/modules/graph/graph_builder/canvas_drawer.dart';
+import 'package:playground/modules/graph/graph_builder/painters/graph_painter.dart';
import 'package:playground/modules/graph/graph_builder/painters/node_painter.dart';
import 'package:playground/modules/graph/models/graph.dart';
+const kEdgeSpacing = 2 * kXlSpacing;
+
class EdgePainter {
final Edge edge;
EdgePainter(this.edge);
void paint(
- CanvasDrawer drawer,
- Map<String, NodeElementPainter> elementsMap,
- Map<int, double> rowStarts,
- Map<int, double> columnStarts,
- Map<int, double> rowSizes,
- Map<int, double> columnSizes,
- ) {
+ CanvasDrawer drawer,
+ Map<String, NodeElementPainter> elementsMap,
+ Map<int, double> rowStarts,
+ Map<int, double> columnStarts,
+ Map<int, double> rowSizes,
+ Map<int, double> columnSizes,
+ GraphDirection direction,
+ ) {
+ if (direction == GraphDirection.vertical) {
+ _drawVertical(
+ drawer, elementsMap, rowStarts, columnStarts, rowSizes, columnSizes);
+ } else {
+ _drawHorizontal(
+ drawer, elementsMap, rowStarts, columnStarts, rowSizes, columnSizes);
+ }
+ }
+
+ _drawHorizontal(
+ CanvasDrawer drawer,
+ Map<String, NodeElementPainter> elementsMap,
+ Map<int, double> rowStarts,
+ Map<int, double> columnStarts,
+ Map<int, double> rowSizes,
+ Map<int, double> columnSizes,
+ ) {
final startNode = elementsMap[edge.startId]!;
final endNode = elementsMap[edge.endId]!;
final startColumn = startNode.column;
@@ -48,16 +69,16 @@ class EdgePainter {
var y = startNode.top! + startNode.size!.height / 2;
drawer.drawCircle(x, y, 4.0);
movePoints.add(Point(x, y));
- // 1. Go to the closest border
- x = columnStarts[startColumn]! + columnSizes[startColumn]! + 2 * kXlSpacing;
+ // 1. Go to the closest border (right)
+ x = columnStarts[startColumn]! + columnSizes[startColumn]! + kEdgeSpacing;
movePoints.add(Point(x, y));
// 2. Go to the correct row
- y = rowStarts[endRow]! + rowSizes[endRow]! + 2 * kXlSpacing;
+ y = rowStarts[endRow]! + rowSizes[endRow]! + kEdgeSpacing;
movePoints.add(Point(x, y));
// 3. Go to the correct column
- x = columnStarts[endColumn]! - 2 * kXlSpacing;
+ x = columnStarts[endColumn]! - kEdgeSpacing;
movePoints.add(Point(x, y));
// 4. Go to the middle of the row
@@ -87,14 +108,83 @@ class EdgePainter {
optimizedMovePoints.add(element);
});
- drawer.drawArrow(
+ drawer.drawRightArrow(
optimizedMovePoints[0].x + kXlSpacing, optimizedMovePoints[0].y);
- optimizedMovePoints.forEachIndexed((index, point) {
+ _drawLine(drawer, optimizedMovePoints);
+ }
+
+ _drawVertical(
+ CanvasDrawer drawer,
+ Map<String, NodeElementPainter> elementsMap,
+ Map<int, double> rowStarts,
+ Map<int, double> columnStarts,
+ Map<int, double> rowSizes,
+ Map<int, double> columnSizes,
+ ) {
+ final startNode = elementsMap[edge.startId]!;
+ final endNode = elementsMap[edge.endId]!;
+ final startRow = startNode.row;
+ final endColumn = endNode.column;
+ final endRow = endNode.row;
+
+ final List<Point<double>> movePoints = [];
+
+ var x = startNode.left! + startNode.size!.width / 2;
+ var y = startNode.top! + rowSizes[startRow]!;
+ drawer.drawCircle(x, y, 4.0);
+ movePoints.add(Point(x, y));
+ // 1. Go to the closest border (bottom)
+ y = rowStarts[startRow]! + rowSizes[startRow]! + kEdgeSpacing;
+ movePoints.add(Point(x, y));
+
+ // 2. Go to the correct column
+ x = columnStarts[endColumn]! + columnSizes[endColumn]! + kEdgeSpacing;
+ movePoints.add(Point(x, y));
+
+ // 3. Go to the correct row
+ y = rowStarts[endRow]! - kEdgeSpacing;
+ movePoints.add(Point(x, y));
+
+ // 4. Go to the middle of the column
+ x = columnStarts[endColumn]! + endNode.size!.width / 2;
+ movePoints.add(Point(x, y));
+
+ // 5. Go to the element
+ y = rowStarts[endRow]!;
+ movePoints.add(Point(x, y));
+ drawer.drawCircle(x, y, 4.0);
+
+ List<Point<double>> optimizedMovePoints = [];
+
+ movePoints.forEachIndexed((index, element) {
+ if (index == 0 || index == movePoints.length - 1) {
+ optimizedMovePoints.add(element);
+ return;
+ }
+ if (movePoints[index - 1].x == movePoints[index].x &&
+ movePoints[index].x == movePoints[index + 1].x) {
+ return;
+ }
+ if (movePoints[index - 1].y == movePoints[index].y &&
+ movePoints[index].y == movePoints[index + 1].y) {
+ return;
+ }
+ optimizedMovePoints.add(element);
+ });
+
+ drawer.drawBottomArrow(
+ optimizedMovePoints[0].x, optimizedMovePoints[0].y + kXlSpacing);
+
+ _drawLine(drawer, optimizedMovePoints);
+ }
+
+ _drawLine(CanvasDrawer drawer, List<Point<double>> points) {
+ points.forEachIndexed((index, point) {
if (index == 0) {
return;
}
- final prevPoint = optimizedMovePoints[index - 1];
+ final prevPoint = points[index - 1];
if (edge.isPrimary) {
drawer.drawLine(prevPoint.x, prevPoint.y, point.x, point.y);
} else {
diff --git a/playground/frontend/lib/modules/graph/graph_builder/painters/graph_painter.dart b/playground/frontend/lib/modules/graph/graph_builder/painters/graph_painter.dart
index 7e846c4..81d5635 100644
--- a/playground/frontend/lib/modules/graph/graph_builder/painters/graph_painter.dart
+++ b/playground/frontend/lib/modules/graph/graph_builder/painters/graph_painter.dart
@@ -25,9 +25,12 @@ import 'package:playground/modules/graph/graph_builder/painters/edge_painter.dar
import 'package:playground/modules/graph/graph_builder/painters/node_painter.dart';
import 'package:playground/modules/graph/models/graph.dart';
+enum GraphDirection { vertical, horizontal }
+
class GraphPainter {
final List<NodeElementPainter> elementsPainter;
final List<EdgePainter> edges;
+ final GraphDirection direction;
final Map<String, NodeElementPainter> elementsMap = {};
final Map<int, double> rowSizes = {};
final Map<int, double> columnSizes = {};
@@ -43,7 +46,11 @@ class GraphPainter {
return Size(width, height);
}
- GraphPainter({required this.elementsPainter, required this.edges}) {
+ GraphPainter({
+ required this.elementsPainter,
+ required this.edges,
+ required this.direction,
+ }) {
for (var element in elementsPainter) {
elementsMap[element.element.name] = element;
}
@@ -80,7 +87,14 @@ class GraphPainter {
});
for (var element in edges) {
element.paint(
- drawer, elementsMap, rowStarts, columnStarts, rowSizes, columnSizes);
+ drawer,
+ elementsMap,
+ rowStarts,
+ columnStarts,
+ rowSizes,
+ columnSizes,
+ direction,
+ );
}
}
}
diff --git a/playground/frontend/lib/modules/output/components/graph.dart b/playground/frontend/lib/modules/output/components/graph.dart
index 62a9596..01fcfbd 100644
--- a/playground/frontend/lib/modules/output/components/graph.dart
+++ b/playground/frontend/lib/modules/output/components/graph.dart
@@ -42,11 +42,13 @@ class GraphCustomPainter extends CustomPainter {
class GraphTab extends StatefulWidget {
final String graph;
final SDK sdk;
+ final GraphDirection direction;
const GraphTab({
Key? key,
required this.graph,
required this.sdk,
+ required this.direction,
}) : super(key: key);
@override
@@ -59,17 +61,20 @@ class _GraphTabState extends State<GraphTab> {
@override
void initState() {
if (widget.graph.isNotEmpty) {
- graphPainter =
- GraphBuilder.parseDot(widget.graph, widget.sdk)?.getPainter();
+ graphPainter = GraphBuilder.parseDot(widget.graph, widget.sdk)
+ ?.getPainter(widget.direction);
}
super.initState();
}
@override
void didUpdateWidget(GraphTab oldWidget) {
- if (widget.graph.isNotEmpty && oldWidget.graph != widget.graph) {
- graphPainter =
- GraphBuilder.parseDot(widget.graph, widget.sdk)?.getPainter();
+ final graphChanged =
+ widget.graph.isNotEmpty && oldWidget.graph != widget.graph;
+ final directionChanged = widget.direction != oldWidget.direction;
+ if (graphChanged || directionChanged) {
+ graphPainter = GraphBuilder.parseDot(widget.graph, widget.sdk)
+ ?.getPainter(widget.direction);
}
if (widget.graph.isEmpty) {
graphPainter = null;
diff --git a/playground/frontend/lib/modules/output/components/output_area.dart b/playground/frontend/lib/modules/output/components/output_area.dart
index 8ab9763..2bc9af8 100644
--- a/playground/frontend/lib/modules/output/components/output_area.dart
+++ b/playground/frontend/lib/modules/output/components/output_area.dart
@@ -17,8 +17,11 @@
*/
import 'package:flutter/material.dart';
+import 'package:playground/modules/graph/graph_builder/painters/graph_painter.dart';
import 'package:playground/modules/output/components/graph.dart';
import 'package:playground/modules/output/components/output_result.dart';
+import 'package:playground/modules/output/models/output_placement.dart';
+import 'package:playground/modules/output/models/output_placement_state.dart';
import 'package:playground/pages/playground/states/playground_state.dart';
import 'package:provider/provider.dart';
@@ -36,24 +39,25 @@ class OutputArea extends StatelessWidget {
Widget build(BuildContext context) {
return Container(
color: Theme.of(context).backgroundColor,
- child: Consumer<PlaygroundState>(
- builder: (context, state, child) {
+ child: Consumer2<PlaygroundState, OutputPlacementState>(
+ builder: (context, playgroundState, placementState, child) {
return TabBarView(
controller: tabController,
physics: const NeverScrollableScrollPhysics(),
children: <Widget>[
OutputResult(
- text: state.result?.output ?? '',
+ text: playgroundState.result?.output ?? '',
isSelected: tabController.index == 0,
),
OutputResult(
- text: state.result?.log ?? '',
+ text: playgroundState.result?.log ?? '',
isSelected: tabController.index == 1,
),
if (showGraph)
GraphTab(
- graph: state.result?.graph ?? '',
- sdk: state.sdk,
+ graph: playgroundState.result?.graph ?? '',
+ sdk: playgroundState.sdk,
+ direction: _getGraphDirection(placementState.placement),
),
],
);
@@ -61,4 +65,10 @@ class OutputArea extends StatelessWidget {
),
);
}
+
+ GraphDirection _getGraphDirection(OutputPlacement placement) {
+ return placement == OutputPlacement.bottom
+ ? GraphDirection.horizontal
+ : GraphDirection.vertical;
+ }
}