From 1d9b9da0d180430d268d174663dea97779166db4 Mon Sep 17 00:00:00 2001 From: Ali Rostami Date: Mon, 20 Jun 2022 15:20:56 +0200 Subject: [PATCH 1/2] adding crossviz action --- .../extensions/actions/art/CrossViz.java | 205 +++++++++++++++++ .../extensions/actions/art/CrossViz2.java | 207 ++++++++++++++++++ 2 files changed, 412 insertions(+) create mode 100644 src/graphtea/extensions/actions/art/CrossViz.java create mode 100644 src/graphtea/extensions/actions/art/CrossViz2.java diff --git a/src/graphtea/extensions/actions/art/CrossViz.java b/src/graphtea/extensions/actions/art/CrossViz.java new file mode 100644 index 00000000..6e24f4ca --- /dev/null +++ b/src/graphtea/extensions/actions/art/CrossViz.java @@ -0,0 +1,205 @@ +package graphtea.extensions.actions.art; + +import graphtea.extensions.AlgorithmUtils; +import graphtea.graph.graph.*; +import graphtea.graph.old.GStroke; +import graphtea.plugins.main.GraphData; +import graphtea.plugins.main.extension.GraphActionExtension; + +import java.awt.*; +import java.awt.geom.GeneralPath; +import java.awt.geom.Line2D; +import java.awt.geom.QuadCurve2D; +import java.util.Iterator; + +/** + * @author M. Ali Rostami + */ +public class CrossViz implements GraphActionExtension { + public static final String CURVE_WIDTH = "Curve Width"; + @Override + public String getName() { + return "Cross Viz"; + } + + @Override + public String getDescription() { + return "Cross Viz"; + } + + @Override + public void action(GraphData graphData) { + Vertex.addGlobalUserDefinedAttribute(CURVE_WIDTH,1); + + GraphModel g1 = graphData.getGraph(); + GraphModel g2 = g1.getCopy(); + g2.setFont(new Font(g2.getFont().getName(),g2.getFont().getStyle(), 0)); + g2.setLabel("TreeG0"); + +// for(Vertex v : g2) +// v.setSize(new GPoint(15,15)); + + int i = 0; + for(Edge e : g2.getEdges()) { +// e.setStroke(new BasicStroke()); +// e.setColor(8); + } + + graphData.core.showGraph(g2); + AbstractGraphRenderer gr = AbstractGraphRenderer.getCurrentGraphRenderer(graphData.getBlackboard()); + gr.addPostPaintHandler(new CrossVizPainter(graphData)); + gr.repaint(); + } + + @Override + public String getCategory() { + return "Graph-based Visualization"; + } +} + + +class CrossVizPainter implements PaintHandler { + GraphData gd; + GraphModel G; + public CrossVizPainter(GraphData gd) { + this.gd = gd; + this.G = gd.getGraph(); + } + + public void paint(Graphics gr1d, Object destinationComponent, Boolean b) { + final Graphics2D gr = (Graphics2D) gr1d; + gr.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + final int n = G.getVerticesCount(); + if (n == 0) return; + +// System.out.println(); +// for(Component c : AbstractGraphRenderer.getCurrentGraphRenderer(gd.getBlackboard()).getComponents()) { +// System.out.println(c.getClass().getName()); +// } + AbstractGraphRenderer.getCurrentGraphRenderer(gd.getBlackboard()).ignoreRepaints(() -> { + Vertex[] V = G.getVertexArray(); + Iterator ie = G.edgeIterator(); + + int i = 0; + while (ie.hasNext()) { + Edge e = ie.next(); + int x1 = (int) e.source.getLocation().x; + int y1 = (int) e.source.getLocation().y; + int x2 = (int) e.target.getLocation().x; + int y2 = (int) e.target.getLocation().y; + Color color = new Color( i * 25,i*25,i*25); + i++; + gr.setColor(color); + gr.drawLine(x1,y1,x2,y2); +// Edge e = ie.next(); +// System.out.println(e); +// paint((Graphics2D) gg, e, getGraph(), drawExtras); + } + + for(Vertex v : G) { + int x = (int) v.getLocation().x; + int y = (int) v.getLocation().y; + gr.fillOval(x-50,y-50, 100, 100); + } +// int[][] E = G.getEdgeArray(); +// for(int i=0;i j && E[i][j] != 0) { +// Vertex v = G.getVertex(i); +// Vertex u = G.getVertex(i); +// GPoint gp1 = v.getLocation(); +// GPoint gp2 = u.getLocation(); +// Line2D l = new Line2D.Double(gp1.x, gp1.y, gp2.x, gp2.y ); +// +// } +// } +// } +// for(Vertex v : G) { +// for(Vertex u : G) { +// if(v.getId() > u.getId()) { +// if(G.isEdge(G.getVertex(v.getId()), G.getVertex(u.getId()))) { +// +// Line2D l1 = new Line2D.Double(); +// Polygon p = new Polygon(); +// p.addPoint((int) (gp1.x - 5), (int) (gp1.y - 5)); +// p.addPoint((int) (gp1.x + 5), (int) (gp1.y + 5)); +// p.addPoint((int) (gp2.x - 5), (int) (gp2.y - 5)); +// p.addPoint((int) (gp2.x + 5), (int) (gp2.y + 5)); +//// gr.setStroke(new Bas); +// gr.drawPolygon(p); +//// gr.drawRect((int) gp1.x, (int) gp1.y, (int) gp2.x, (int) gp2.y); +// } +// } +// } +// } +// +// for (Vertex v : G) { +// if (v.getId() == 0) continue; +// if (v.getColor() == 0) { +// Vertex v1 = parent[v.getId()]; +// if (v1 == null || v1.getColor() != 0) continue; +// +// Vertex v2 = parent[v1.getId()]; +// if (v2 == null || v2.getColor() != 0) continue; +// +// //generate the curve between v1, v2 and v3 +// GPoint p1 = v.getLocation(); +// GPoint p2 = v1.getLocation(); +// GPoint p3 = v2.getLocation(); +// +// GPoint m1 = AlgorithmUtils.getMiddlePoint(p1, p2); +// GPoint m2 = AlgorithmUtils.getMiddlePoint(p2, p3); +// +//// Integer w1 = numChild[v.getId()]/2; +// Integer w1 = v.getUserDefinedAttribute(GraphArt.CURVE_WIDTH); +//// Integer w2 = numChild[v1.getId()]/2; +// Integer w2 = v1.getUserDefinedAttribute(GraphArt.CURVE_WIDTH); +//// Integer w3 = numChild[v2.getId()]/2; +// Integer w3 = v2.getUserDefinedAttribute(GraphArt.CURVE_WIDTH); +// +// int startWidth = (w1 + w2) / 2; +// int endWidth = (w3 + w2) / 2; +// int middleWidth = w2; +// +// double teta1 = AlgorithmUtils.getAngle(p1, p2); +// double teta2 = AlgorithmUtils.getAngle(p1, p3); +// double teta3 = AlgorithmUtils.getAngle(p2, p3); +// +// //generate boundary curves +// QuadCurve2D c1 = new QuadCurve2D.Double( +// m1.x - startWidth * Math.sin(teta1), m1.y + startWidth * Math.cos(teta1), +// p2.x - middleWidth * Math.sin(teta2), p2.y + middleWidth * Math.cos(teta2), +// m2.x - endWidth * Math.sin(teta3), m2.y + endWidth * Math.cos(teta3)); +// +// QuadCurve2D c2 = new QuadCurve2D.Double( +// m2.x + endWidth * Math.sin(teta3), m2.y - endWidth * Math.cos(teta3), +// p2.x + middleWidth * Math.sin(teta2), p2.y - middleWidth * Math.cos(teta2), +// m1.x + startWidth * Math.sin(teta1), m1.y - startWidth * Math.cos(teta1)); +// +// //mix them +// GeneralPath gp = new GeneralPath(c1); +// gp.append(c2, true); +// gp.closePath(); +// gr.setColor(new Color(0,0,0)); +// +// //fill the curve +// gr.fill(gp); +// +// +// +//// double c11 = m1.x - startWidth * Math.sin(teta1); +//// double c22 = m1.y + startWidth * Math.cos(teta1); +// +//// if(G.getInDegree(v) + G.getOutDegree(v) == 2) { +//// gr.setColor(Color.gray); +//// gr.fillOval((int)c11-15,(int)c22-15,30,30); +//// } +// +// +// } +// } + }, false /* dont repaint after*/); + } +} \ No newline at end of file diff --git a/src/graphtea/extensions/actions/art/CrossViz2.java b/src/graphtea/extensions/actions/art/CrossViz2.java new file mode 100644 index 00000000..b049e65b --- /dev/null +++ b/src/graphtea/extensions/actions/art/CrossViz2.java @@ -0,0 +1,207 @@ +package graphtea.extensions.actions.art; + +import graphtea.graph.graph.*; +import graphtea.plugins.main.GraphData; +import graphtea.plugins.main.extension.GraphActionExtension; + +import java.awt.*; +import java.util.Iterator; + +/** + * @author M. Ali Rostami + */ +public class CrossViz2 implements GraphActionExtension { + public static final String CURVE_WIDTH = "Curve Width"; + @Override + public String getName() { + return "Cross Viz 2"; + } + + @Override + public String getDescription() { + return "Cross Viz 2"; + } + + @Override + public void action(GraphData graphData) { + Vertex.addGlobalUserDefinedAttribute(CURVE_WIDTH,1); + + GraphModel g1 = graphData.getGraph(); + GraphModel g2 = g1.getCopy(); + g2.setFont(new Font(g2.getFont().getName(),g2.getFont().getStyle(), 0)); + g2.setLabel("TreeG0"); + +// for(Vertex v : g2) +// v.setSize(new GPoint(15,15)); + + int i = 0; + for(Edge e : g2.getEdges()) { +// e.setStroke(new BasicStroke()); +// e.setColor(8); + } + + graphData.core.showGraph(g2); + AbstractGraphRenderer gr = AbstractGraphRenderer.getCurrentGraphRenderer(graphData.getBlackboard()); + gr.addPostPaintHandler(new CrossVizPainter2(graphData)); + gr.repaint(); + } + + @Override + public String getCategory() { + return "Graph-based Visualization"; + } +} + + +class CrossVizPainter2 implements PaintHandler { + GraphData gd; + GraphModel G; + public CrossVizPainter2(GraphData gd) { + this.gd = gd; + this.G = gd.getGraph(); + } + + public void paint(Graphics gr1d, Object destinationComponent, Boolean b) { + final Graphics2D gr = (Graphics2D) gr1d; + gr.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + + final int n = G.getVerticesCount(); + if (n == 0) return; + +// System.out.println(); +// for(Component c : AbstractGraphRenderer.getCurrentGraphRenderer(gd.getBlackboard()).getComponents()) { +// System.out.println(c.getClass().getName()); +// } + AbstractGraphRenderer.getCurrentGraphRenderer(gd.getBlackboard()).ignoreRepaints(() -> { + Vertex[] V = G.getVertexArray(); + Iterator ie = G.edgeIterator(); + + int i = 0; + while (ie.hasNext()) { + Edge e = ie.next(); + int x1 = (int) e.source.getLocation().x; + int y1 = (int) e.source.getLocation().y; + int x2 = (int) e.target.getLocation().x; + int y2 = (int) e.target.getLocation().y; + Color color = new Color( i * 25,i*25,i*25); + i++; + gr.setColor(Color.WHITE); + + gr.setStroke(new BasicStroke(10)); + gr.drawLine(x1,y1,x2,y2); + gr.setColor(color); + + gr.setStroke(new BasicStroke(2)); + gr.drawLine(x1,y1,x2,y2); +// +// Edge e = ie.next(); +// System.out.println(e); +// paint((Graphics2D) gg, e, getGraph(), drawExtras); + } + + for(Vertex v : G) { + int x = (int) v.getLocation().x; + int y = (int) v.getLocation().y; + gr.fillOval(x-50,y-50, 100, 100); + } +// int[][] E = G.getEdgeArray(); +// for(int i=0;i j && E[i][j] != 0) { +// Vertex v = G.getVertex(i); +// Vertex u = G.getVertex(i); +// GPoint gp1 = v.getLocation(); +// GPoint gp2 = u.getLocation(); +// Line2D l = new Line2D.Double(gp1.x, gp1.y, gp2.x, gp2.y ); +// +// } +// } +// } +// for(Vertex v : G) { +// for(Vertex u : G) { +// if(v.getId() > u.getId()) { +// if(G.isEdge(G.getVertex(v.getId()), G.getVertex(u.getId()))) { +// +// Line2D l1 = new Line2D.Double(); +// Polygon p = new Polygon(); +// p.addPoint((int) (gp1.x - 5), (int) (gp1.y - 5)); +// p.addPoint((int) (gp1.x + 5), (int) (gp1.y + 5)); +// p.addPoint((int) (gp2.x - 5), (int) (gp2.y - 5)); +// p.addPoint((int) (gp2.x + 5), (int) (gp2.y + 5)); +//// gr.setStroke(new Bas); +// gr.drawPolygon(p); +//// gr.drawRect((int) gp1.x, (int) gp1.y, (int) gp2.x, (int) gp2.y); +// } +// } +// } +// } +// +// for (Vertex v : G) { +// if (v.getId() == 0) continue; +// if (v.getColor() == 0) { +// Vertex v1 = parent[v.getId()]; +// if (v1 == null || v1.getColor() != 0) continue; +// +// Vertex v2 = parent[v1.getId()]; +// if (v2 == null || v2.getColor() != 0) continue; +// +// //generate the curve between v1, v2 and v3 +// GPoint p1 = v.getLocation(); +// GPoint p2 = v1.getLocation(); +// GPoint p3 = v2.getLocation(); +// +// GPoint m1 = AlgorithmUtils.getMiddlePoint(p1, p2); +// GPoint m2 = AlgorithmUtils.getMiddlePoint(p2, p3); +// +//// Integer w1 = numChild[v.getId()]/2; +// Integer w1 = v.getUserDefinedAttribute(GraphArt.CURVE_WIDTH); +//// Integer w2 = numChild[v1.getId()]/2; +// Integer w2 = v1.getUserDefinedAttribute(GraphArt.CURVE_WIDTH); +//// Integer w3 = numChild[v2.getId()]/2; +// Integer w3 = v2.getUserDefinedAttribute(GraphArt.CURVE_WIDTH); +// +// int startWidth = (w1 + w2) / 2; +// int endWidth = (w3 + w2) / 2; +// int middleWidth = w2; +// +// double teta1 = AlgorithmUtils.getAngle(p1, p2); +// double teta2 = AlgorithmUtils.getAngle(p1, p3); +// double teta3 = AlgorithmUtils.getAngle(p2, p3); +// +// //generate boundary curves +// QuadCurve2D c1 = new QuadCurve2D.Double( +// m1.x - startWidth * Math.sin(teta1), m1.y + startWidth * Math.cos(teta1), +// p2.x - middleWidth * Math.sin(teta2), p2.y + middleWidth * Math.cos(teta2), +// m2.x - endWidth * Math.sin(teta3), m2.y + endWidth * Math.cos(teta3)); +// +// QuadCurve2D c2 = new QuadCurve2D.Double( +// m2.x + endWidth * Math.sin(teta3), m2.y - endWidth * Math.cos(teta3), +// p2.x + middleWidth * Math.sin(teta2), p2.y - middleWidth * Math.cos(teta2), +// m1.x + startWidth * Math.sin(teta1), m1.y - startWidth * Math.cos(teta1)); +// +// //mix them +// GeneralPath gp = new GeneralPath(c1); +// gp.append(c2, true); +// gp.closePath(); +// gr.setColor(new Color(0,0,0)); +// +// //fill the curve +// gr.fill(gp); +// +// +// +//// double c11 = m1.x - startWidth * Math.sin(teta1); +//// double c22 = m1.y + startWidth * Math.cos(teta1); +// +//// if(G.getInDegree(v) + G.getOutDegree(v) == 2) { +//// gr.setColor(Color.gray); +//// gr.fillOval((int)c11-15,(int)c22-15,30,30); +//// } +// +// +// } +// } + }, false /* dont repaint after*/); + } +} \ No newline at end of file From 4cf2f99d18d6b46f6310d7a473aa76f906d05e55 Mon Sep 17 00:00:00 2001 From: Ali Rostami Date: Wed, 22 Feb 2023 15:56:11 +0100 Subject: [PATCH 2/2] changes regarding edge cross --- src/graphtea/extensions/actions/art/GraphArt.java | 2 ++ src/graphtea/graph/graph/FastRenderer.java | 5 ++++- src/graphtea/graph/old/ButtonTabComponent.java | 2 +- src/graphtea/graph/old/GStroke.java | 4 ++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/graphtea/extensions/actions/art/GraphArt.java b/src/graphtea/extensions/actions/art/GraphArt.java index 9c6878c9..b4f0addc 100644 --- a/src/graphtea/extensions/actions/art/GraphArt.java +++ b/src/graphtea/extensions/actions/art/GraphArt.java @@ -141,6 +141,8 @@ public void paint(Graphics gr1d, Object destinationComponent, Boolean b) { //fill the curve gr.fill(gp); + + // double c11 = m1.x - startWidth * Math.sin(teta1); // double c22 = m1.y + startWidth * Math.cos(teta1); diff --git a/src/graphtea/graph/graph/FastRenderer.java b/src/graphtea/graph/graph/FastRenderer.java index 277eafc7..0d48c92f 100644 --- a/src/graphtea/graph/graph/FastRenderer.java +++ b/src/graphtea/graph/graph/FastRenderer.java @@ -37,7 +37,7 @@ public class FastRenderer extends AbstractGraphRenderer implements VertexListene private static final GStroke markedStroke = GStroke.strong; @UserModifiableProperty(displayName = "Default Edge Stroke") - public static GStroke defaultStroke = GStroke.strong; + public static GStroke defaultStroke = GStroke.dashed_dashed_dotted; @UserModifiableProperty(displayName = "Default Vertex Shape") public static GShape defaultVertexShape = GShape.OVAL; @UserModifiableProperty(displayName = "Default Vertex Color") @@ -254,6 +254,7 @@ public void fastpaintGraph(Graphics g, Boolean drawExtras) { gg.setColor(c); if (!e.isLoop()) { + gg.setStroke(new BasicStroke(3)); gg.drawLine((int) (l.x * zoomFactor), (int) (l.y * zoomFactor), (int) (r.x * zoomFactor), (int) (r.y * zoomFactor)); } else { //Drawing loops @@ -337,6 +338,7 @@ public void paint(Graphics2D g, Edge model, GraphModel graph, Boolean drawExtras else color = GraphModel.getColor(model.getColor()); BasicStroke stroke = model.getStroke().stroke; + GPoint src = model.source.getLocation(); GPoint trg = model.target.getLocation(); @@ -374,6 +376,7 @@ public void paint(Graphics2D g, Edge model, GraphModel graph, Boolean drawExtras g.setColor(c1); g.setStroke(stroke); if (ctrlPnt.x == 0 && ctrlPnt.y == 0) { + g.setStroke(new BasicStroke(3)); g.drawLine(x1z, y1z, x2z, y2z); } else { //the control point of the curve is put another place so that the curve hits the real control point. diff --git a/src/graphtea/graph/old/ButtonTabComponent.java b/src/graphtea/graph/old/ButtonTabComponent.java index dad77035..48294574 100644 --- a/src/graphtea/graph/old/ButtonTabComponent.java +++ b/src/graphtea/graph/old/ButtonTabComponent.java @@ -92,7 +92,7 @@ protected void paintComponent(Graphics g) { if (getModel().isPressed()) { g2.translate(1, 1); } - g2.setStroke(new BasicStroke(2)); +// g2.setStroke(new BasicStroke(2)); g2.setColor(Color.BLACK); if (getModel().isRollover()) { g2.setColor(Color.MAGENTA); diff --git a/src/graphtea/graph/old/GStroke.java b/src/graphtea/graph/old/GStroke.java index 3efe88ef..bffe9423 100644 --- a/src/graphtea/graph/old/GStroke.java +++ b/src/graphtea/graph/old/GStroke.java @@ -29,12 +29,12 @@ public class GStroke implements Serializable, FromStringProvider { public static GStroke empty = new GStroke("Empty", 0, new float[]{0, 100000000f}); public static GStroke simple = new GStroke("simple", 1, new float[]{1, 0}); public static GStroke solid = new GStroke("solid", new float[]{1, 0}); - public static GStroke strong = new GStroke("strong", 4, new float[]{1, 0}); + public static GStroke strong = new GStroke("strong", 10, new float[]{1, 0}); public static GStroke dashed = new GStroke("dashed", new float[]{6, 2}); public static GStroke dotted = new GStroke("dotted", new float[]{2, 4}); public static GStroke dashed_dotted = new GStroke("dashed-dotted", new float[]{6, 2, 2, 6}); public static GStroke dashed_dotted_dotted = new GStroke("dashed-dotted-dotted", new float[]{6, 2, 2, 6, 2, 6}); - public static GStroke dashed_dashed_dotted = new GStroke("dashed-dashed-dotted", new float[]{6, 2, 6, 2, 2, 4}); + public static GStroke dashed_dashed_dotted = new GStroke("dashed-dashed-dotted", 15, new float[]{6, 2, 6, 2, 2, 4}); public String name; public BasicStroke stroke;