├── .gitignore ├── LICENSE ├── README.md ├── cli ├── pom.xml └── src │ └── main │ ├── java │ └── org │ │ └── graphper │ │ ├── Arguments.java │ │ ├── Command.java │ │ ├── CommandUnit.java │ │ ├── CommandUnits.java │ │ ├── Main.java │ │ ├── Version.java │ │ └── WrongCommandException.java │ └── resources │ └── logback.xml ├── core ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ ├── apache_gs │ │ │ └── commons │ │ │ │ ├── lang3 │ │ │ │ ├── ArrayUtils.java │ │ │ │ ├── CharSequenceUtils.java │ │ │ │ ├── CharUtils.java │ │ │ │ ├── Range.java │ │ │ │ └── StringUtils.java │ │ │ │ └── text │ │ │ │ ├── StringEscapeUtils.java │ │ │ │ └── translate │ │ │ │ ├── AggregateTranslator.java │ │ │ │ ├── CharSequenceTranslator.java │ │ │ │ ├── CodePointTranslator.java │ │ │ │ ├── CsvTranslators.java │ │ │ │ ├── EntityArrays.java │ │ │ │ ├── JavaUnicodeEscaper.java │ │ │ │ ├── LookupTranslator.java │ │ │ │ ├── NumericEntityEscaper.java │ │ │ │ ├── NumericEntityUnescaper.java │ │ │ │ ├── OctalUnescaper.java │ │ │ │ ├── SinglePassTranslator.java │ │ │ │ ├── UnicodeEscaper.java │ │ │ │ ├── UnicodeUnescaper.java │ │ │ │ ├── UnicodeUnpairedSurrogateRemover.java │ │ │ │ └── package-info.java │ │ │ └── graphper │ │ │ ├── api │ │ │ ├── Assemble.java │ │ │ ├── Cluster.java │ │ │ ├── ClusterAttrs.java │ │ │ ├── FileType.java │ │ │ ├── FloatLabel.java │ │ │ ├── GraphAttrs.java │ │ │ ├── GraphContainer.java │ │ │ ├── GraphResource.java │ │ │ ├── Graphviz.java │ │ │ ├── Html.java │ │ │ ├── Line.java │ │ │ ├── LineAttrs.java │ │ │ ├── Node.java │ │ │ ├── NodeAttrs.java │ │ │ ├── Subgraph.java │ │ │ ├── attributes │ │ │ │ ├── ArrowShape.java │ │ │ │ ├── ClusterShape.java │ │ │ │ ├── ClusterShapeEnum.java │ │ │ │ ├── ClusterStyle.java │ │ │ │ ├── Color.java │ │ │ │ ├── Dir.java │ │ │ │ ├── FontStyle.java │ │ │ │ ├── InitPos.java │ │ │ │ ├── Labeljust.java │ │ │ │ ├── Labelloc.java │ │ │ │ ├── Layout.java │ │ │ │ ├── LineStyle.java │ │ │ │ ├── NodeShape.java │ │ │ │ ├── NodeShapeEnum.java │ │ │ │ ├── NodeStyle.java │ │ │ │ ├── Port.java │ │ │ │ ├── Rank.java │ │ │ │ ├── Rankdir.java │ │ │ │ ├── Splines.java │ │ │ │ ├── Style.java │ │ │ │ └── Tend.java │ │ │ └── ext │ │ │ │ ├── Box.java │ │ │ │ ├── CirclePropCalc.java │ │ │ │ ├── ClusterShapePost.java │ │ │ │ ├── CylinderPropCalc.java │ │ │ │ ├── DefaultBox.java │ │ │ │ ├── DiamondPropCalc.java │ │ │ │ ├── EllipsePropCalc.java │ │ │ │ ├── LabelPositionCalc.java │ │ │ │ ├── NodeShapePost.java │ │ │ │ ├── NotePropCalc.java │ │ │ │ ├── ParallelogramPropCalc.java │ │ │ │ ├── PlainPropCalc.java │ │ │ │ ├── PointPropCalc.java │ │ │ │ ├── PortPosition.java │ │ │ │ ├── RatioPortPosition.java │ │ │ │ ├── RecordPropCalc.java │ │ │ │ ├── RectanglePropCalc.java │ │ │ │ ├── RegularPolylinePropCalc.java │ │ │ │ ├── ShapeCenterCalc.java │ │ │ │ ├── ShapePosition.java │ │ │ │ ├── ShapePropCalc.java │ │ │ │ ├── StarPropCalc.java │ │ │ │ ├── SymmetryShapeCenterCalc.java │ │ │ │ ├── TrapeziumPropCalc.java │ │ │ │ └── TrianglePropCalc.java │ │ │ ├── def │ │ │ ├── AbstractBaseGraph.java │ │ │ ├── AbstractDirectedEdge.java │ │ │ ├── AbstractEdge.java │ │ │ ├── AbstractUndirectedEdge.java │ │ │ ├── AdjEdgeGraph.java │ │ │ ├── AdjVertexGraph.java │ │ │ ├── Bag.java │ │ │ ├── BaseEdge.java │ │ │ ├── BaseGraph.java │ │ │ ├── ColorFormatException.java │ │ │ ├── ConcatIterable.java │ │ │ ├── Curves.java │ │ │ ├── CycleDependencyException.java │ │ │ ├── Dedigraph.java │ │ │ ├── DedirectedEdgeGraph.java │ │ │ ├── DedirectedGraph.java │ │ │ ├── Digraph.java │ │ │ ├── DirectedEdge.java │ │ │ ├── DirectedEdgeGraph.java │ │ │ ├── DirectedGraph.java │ │ │ ├── Edge.java │ │ │ ├── EdgeDedigraph.java │ │ │ ├── EdgeOpGraph.java │ │ │ ├── FlatPoint.java │ │ │ ├── Graph.java │ │ │ ├── ProxyDedigraph.java │ │ │ ├── RectangleTree.java │ │ │ ├── UnaryConcatIterable.java │ │ │ ├── UndirectedEdgeGraph.java │ │ │ ├── UndirectedGraph.java │ │ │ ├── UnfeasibleException.java │ │ │ ├── UnmodifiableBagException.java │ │ │ ├── UnmodifiablePointException.java │ │ │ ├── Vectors.java │ │ │ ├── VertexDedigraph.java │ │ │ ├── VertexIndex.java │ │ │ └── VertexOpGraph.java │ │ │ ├── draw │ │ │ ├── AbstractPipelineTrigger.java │ │ │ ├── AbstractRenderEngine.java │ │ │ ├── ArrowDrawProp.java │ │ │ ├── Brush.java │ │ │ ├── ClusterDrawProp.java │ │ │ ├── ClusterEditor.java │ │ │ ├── ClusterPipelineTrigger.java │ │ │ ├── ContainerDrawProp.java │ │ │ ├── CustomizeShapeRender.java │ │ │ ├── DefaultGraphResource.java │ │ │ ├── DefaultPipelineFactory.java │ │ │ ├── DefaultShapePosition.java │ │ │ ├── DrawBoard.java │ │ │ ├── DrawGraph.java │ │ │ ├── Editor.java │ │ │ ├── ExecuteException.java │ │ │ ├── FailInitResourceException.java │ │ │ ├── GraphEditor.java │ │ │ ├── GraphPipelineTrigger.java │ │ │ ├── GraphvizDrawProp.java │ │ │ ├── LineDrawProp.java │ │ │ ├── LineEditor.java │ │ │ ├── LinePipelineTrigger.java │ │ │ ├── NodeDrawProp.java │ │ │ ├── NodeEditor.java │ │ │ ├── NodePipelineTrigger.java │ │ │ ├── PipelineFactory.java │ │ │ ├── PipelineRenderEngine.java │ │ │ ├── Rectangle.java │ │ │ ├── RenderEngine.java │ │ │ ├── common │ │ │ │ ├── AWTextRender.java │ │ │ │ ├── AndroidImgConverter.java │ │ │ │ ├── BatikImgConverter.java │ │ │ │ ├── CommonDrawBoard.java │ │ │ │ ├── CommonRenderEngine.java │ │ │ │ ├── DefaultImgConverter.java │ │ │ │ ├── SvgConverter.java │ │ │ │ └── SvgToPdfConverter.java │ │ │ └── svg │ │ │ │ ├── Document.java │ │ │ │ ├── Element.java │ │ │ │ ├── SvgBrush.java │ │ │ │ ├── SvgConstants.java │ │ │ │ ├── SvgDocument.java │ │ │ │ ├── SvgDrawBoard.java │ │ │ │ ├── SvgEditor.java │ │ │ │ ├── SvgElement.java │ │ │ │ ├── SvgRenderEngine.java │ │ │ │ ├── cluster │ │ │ │ ├── ClusterColorEditor.java │ │ │ │ ├── ClusterHrefEditor.java │ │ │ │ ├── ClusterLabelEditor.java │ │ │ │ ├── ClusterShapeEditor.java │ │ │ │ └── ClusterStyleEditor.java │ │ │ │ ├── graphviz │ │ │ │ ├── GraphBasicEditor.java │ │ │ │ ├── GraphGridEditor.java │ │ │ │ └── GraphLabelEditor.java │ │ │ │ ├── line │ │ │ │ ├── LineArrowEditor.java │ │ │ │ ├── LineBoxesEditor.java │ │ │ │ ├── LineControlPointsEditor.java │ │ │ │ ├── LineFloatLabelsEditor.java │ │ │ │ ├── LineHrefEditor.java │ │ │ │ ├── LineLabelEditor.java │ │ │ │ ├── LinePathEditor.java │ │ │ │ └── LineStyleEditor.java │ │ │ │ ├── node │ │ │ │ ├── AbstractNodeShapeEditor.java │ │ │ │ ├── NodeColorEditor.java │ │ │ │ ├── NodeHrefEditor.java │ │ │ │ ├── NodeImageEditor.java │ │ │ │ ├── NodeLabelEditor.java │ │ │ │ ├── NodeShapeEditor.java │ │ │ │ └── NodeStyleEditor.java │ │ │ │ └── shape │ │ │ │ ├── CircleShapeRender.java │ │ │ │ ├── EllipseShapeRender.java │ │ │ │ ├── InvtrapeziumShapeRender.java │ │ │ │ ├── ParallelogramShapeRender.java │ │ │ │ ├── RectShapeRender.java │ │ │ │ ├── RegularShapeRender.java │ │ │ │ └── TrapeziumShapeRender.java │ │ │ ├── layout │ │ │ ├── ALine.java │ │ │ ├── ANode.java │ │ │ ├── AWTMeasureText.java │ │ │ ├── AbstractFontSelector.java │ │ │ ├── AbstractLayoutEngine.java │ │ │ ├── AbstractOrthogonalRouter.java │ │ │ ├── AbstractShifterStrategy.java │ │ │ ├── AndroidMeasureText.java │ │ │ ├── Cell.java │ │ │ ├── CellLabelCompiler.java │ │ │ ├── CombineShifter.java │ │ │ ├── CurvePathClip.java │ │ │ ├── DefaultFontOrder.java │ │ │ ├── DefaultVal.java │ │ │ ├── EnvStrategy.java │ │ │ ├── FlatShifterStrategy.java │ │ │ ├── FlipShifterStrategy.java │ │ │ ├── FontOrder.java │ │ │ ├── FontSelector.java │ │ │ ├── Grid.java │ │ │ ├── HtmlConvertor.java │ │ │ ├── LabelAttributes.java │ │ │ ├── LabelFormatException.java │ │ │ ├── LayoutAttach.java │ │ │ ├── LayoutEngine.java │ │ │ ├── LayoutGraph.java │ │ │ ├── LineClip.java │ │ │ ├── LineHandler.java │ │ │ ├── LineHelper.java │ │ │ ├── LineRouter.java │ │ │ ├── Mark.java │ │ │ ├── Maze.java │ │ │ ├── MeasureText.java │ │ │ ├── NodeSizeExpander.java │ │ │ ├── OrthoNodeSizeExpander.java │ │ │ ├── OrthoVisGraph.java │ │ │ ├── PathClip.java │ │ │ ├── PortHelper.java │ │ │ ├── PortNodeSizeExpander.java │ │ │ ├── PortNodeSizeExpanderV2.java │ │ │ ├── RoughMeasureText.java │ │ │ ├── Shifter.java │ │ │ ├── ShifterStrategy.java │ │ │ ├── StaticFontOrder.java │ │ │ ├── StraightPathClip.java │ │ │ ├── dot │ │ │ │ ├── AbstractCoordinate.java │ │ │ │ ├── AbstractDotLineRouter.java │ │ │ │ ├── Acyclic.java │ │ │ │ ├── BasicCrossRank.java │ │ │ │ ├── BoxGuideLineRouter.java │ │ │ │ ├── ContainerCollapse.java │ │ │ │ ├── Coordinate.java │ │ │ │ ├── CoordinateV2.java │ │ │ │ ├── CrossRank.java │ │ │ │ ├── CurveFitBoxRouter.java │ │ │ │ ├── DLine.java │ │ │ │ ├── DNode.java │ │ │ │ ├── DotAttachment.java │ │ │ │ ├── DotDigraph.java │ │ │ │ ├── DotGraph.java │ │ │ │ ├── DotLayoutEngine.java │ │ │ │ ├── DotLineRouterFactory.java │ │ │ │ ├── DotMaze.java │ │ │ │ ├── FeasibleTree.java │ │ │ │ ├── LabelSupplement.java │ │ │ │ ├── MinCross.java │ │ │ │ ├── NetworkSimplex.java │ │ │ │ ├── OrthogonalRouter.java │ │ │ │ ├── PolyLineRouter.java │ │ │ │ ├── RankContent.java │ │ │ │ ├── RootCrossRank.java │ │ │ │ ├── RoundedRouter.java │ │ │ │ ├── RouterBox.java │ │ │ │ ├── SameRankAdjacentRecord.java │ │ │ │ ├── SplineRouter.java │ │ │ │ ├── StraightLineRouter.java │ │ │ │ ├── SubgrahOppositRankException.java │ │ │ │ ├── SubgraphMerge.java │ │ │ │ └── ULine.java │ │ │ └── fdp │ │ │ │ ├── AbstractFdpLayout.java │ │ │ │ ├── AbstractFdpLineRouter.java │ │ │ │ ├── AroundLineRouter.java │ │ │ │ ├── FLine.java │ │ │ │ ├── FNode.java │ │ │ │ ├── FdpAttachment.java │ │ │ │ ├── FdpGraph.java │ │ │ │ ├── FdpLayoutEngine.java │ │ │ │ ├── FdpMaze.java │ │ │ │ ├── GFdpLayoutEngine.java │ │ │ │ ├── JFdpLayoutEngine.java │ │ │ │ ├── LineRouterFactory.java │ │ │ │ ├── OrthogonalRouter.java │ │ │ │ ├── PolylineRouter.java │ │ │ │ ├── RoundedRouter.java │ │ │ │ ├── SplineRouter.java │ │ │ │ └── StraightLineRouter.java │ │ │ └── util │ │ │ ├── Asserts.java │ │ │ ├── BoxUtils.java │ │ │ ├── ClassUtils.java │ │ │ ├── CollectionUtils.java │ │ │ ├── EnvProp.java │ │ │ ├── FontUtils.java │ │ │ ├── GraphvizUtils.java │ │ │ ├── LabelTagUtils.java │ │ │ └── ValueUtils.java │ └── resources │ │ └── META-INF │ │ └── services │ │ ├── org.graphper.draw.CustomizeShapeRender │ │ ├── org.graphper.draw.common.SvgConverter │ │ ├── org.graphper.layout.FontOrder │ │ ├── org.graphper.layout.FontSelector │ │ └── org.graphper.layout.MeasureText │ └── test │ ├── java │ ├── helper │ │ ├── DocumentUtils.java │ │ ├── GraphAssert.java │ │ ├── SerialHelper.java │ │ └── TableUtils.java │ └── org │ │ └── graphper │ │ ├── api │ │ ├── GraphvizTest.java │ │ ├── HtmlTagTest.java │ │ ├── LineTest.java │ │ ├── NodeTest.java │ │ ├── attributes │ │ │ └── PortTest.java │ │ └── ext │ │ │ ├── StarPropCalcTest.java │ │ │ └── TrianglePropCalcTest.java │ │ ├── def │ │ ├── BagTest.java │ │ ├── DedirectedEdgeGraphTest.java │ │ ├── DedirectedGraphTest.java │ │ ├── DirectedEdgeGraphTest.java │ │ ├── DirectedGraphTest.java │ │ ├── FlatPointTest.java │ │ ├── GEdge.java │ │ ├── GNode.java │ │ ├── GUEdge.java │ │ ├── RectangleTreeTest.java │ │ ├── UnaryConcatIterableTest.java │ │ ├── UndirectedEdgeGraphTest.java │ │ ├── UndirectedGraphTest.java │ │ └── VectorsTest.java │ │ ├── draw │ │ ├── DrawGraphTest.java │ │ └── svg │ │ │ └── SvgDocumentTest.java │ │ ├── layout │ │ ├── CellLabelCompilerTest.java │ │ ├── OrthoVisGraphTest.java │ │ └── dot │ │ │ ├── DotLayoutEngineTest.java │ │ │ ├── SubgraphMergeTest.java │ │ │ └── TLayout.java │ │ └── util │ │ └── LabelTagUtilsTest.java │ └── resources │ └── table │ ├── table_1.html │ ├── table_2.html │ ├── table_3.html │ ├── table_4.html │ ├── table_5.html │ ├── table_6.html │ ├── table_7.html │ └── table_8.html ├── docs ├── Color Intro.md ├── Image Security Warning.md ├── LabelTag.md ├── Table.md ├── cluster │ ├── Color.md │ ├── FillColor.md │ ├── FontColor.md │ ├── FontName.md │ ├── FontSize.md │ ├── Href.md │ ├── ID.md │ ├── Label.md │ ├── Labeljust.md │ ├── Labelloc.md │ ├── Margin.md │ ├── PenWidth.md │ ├── Shape.md │ ├── Style.md │ └── ToolTip.md ├── edge │ ├── ArrowHead.md │ ├── ArrowSize.md │ ├── ArrowTail.md │ ├── Color.md │ ├── ControlPoints.md │ ├── Dir.md │ ├── FontColor.md │ ├── FontName.md │ ├── FontSize.md │ ├── HeadCell.md │ ├── HeadClip.md │ ├── HeadLabel.md │ ├── HeadPort.md │ ├── Href.md │ ├── ID.md │ ├── Label.md │ ├── MinLen.md │ ├── PenWidth.md │ ├── Radian.md │ ├── ShowBoxes.md │ ├── Style.md │ ├── TailCell.md │ ├── TailCilp.md │ ├── TailLabel.md │ ├── TailPort.md │ ├── Tooltip.md │ ├── Weight.md │ ├── lhead.md │ └── ltail.md ├── graph │ ├── FillColor.md │ ├── FontColor.md │ ├── FontName.md │ ├── FontSize.md │ ├── Href.md │ ├── Initpos.md │ ├── K.md │ ├── Label.md │ ├── Labeljust.md │ ├── Labelloc.md │ ├── Layout.md │ ├── Margin.md │ ├── Maxiter.md │ ├── Mclimit.md │ ├── Nodesep.md │ ├── Nslimit.md │ ├── Nslimit1.md │ ├── Overlap.md │ ├── Rankdir.md │ ├── Ranksep.md │ ├── Showgrid.md │ ├── Size.md │ ├── Splines.md │ └── Tooltip.md ├── images │ ├── node_record.png │ ├── node_shape.png │ └── node_style.png ├── node │ ├── Color.md │ ├── FillColor.md │ ├── FixedSize.md │ ├── FontColor.md │ ├── FontName.md │ ├── FontSize.md │ ├── Href.md │ ├── ID.md │ ├── Image.md │ ├── ImageSize.md │ ├── Label.md │ ├── Labeljust.md │ ├── Labelloc.md │ ├── Margin.md │ ├── PenWidth.md │ ├── Shape.md │ ├── Sides.md │ ├── Size.md │ ├── Style.md │ └── Tooltip.md └── subgraph │ └── Rank.md ├── dot ├── pom.xml └── src │ └── main │ ├── antlr4 │ └── org │ │ └── graphper │ │ └── parser │ │ └── grammar │ │ ├── DOTLexer.g4 │ │ ├── DOTParser.g4 │ │ ├── HTMLLexer.g4 │ │ └── HTMLParser.g4 │ └── java │ └── org │ └── graphper │ └── parser │ ├── DotParser.java │ ├── DotSyntaxErrorListener.java │ ├── DotTempAttrListener.java │ ├── GraphvizListener.java │ ├── HtmlListener.java │ ├── HtmlParser.java │ ├── HtmlSyntaxErrorListener.java │ ├── NodeExtractor.java │ ├── ParseException.java │ ├── ParserUtils.java │ ├── PostGraphComponents.java │ └── grammar │ ├── DOTLexer.interp │ ├── DOTLexer.java │ ├── DOTLexer.tokens │ ├── DOTParser.interp │ ├── DOTParser.java │ ├── DOTParser.tokens │ ├── DOTParserBaseListener.java │ ├── DOTParserBaseVisitor.java │ ├── DOTParserListener.java │ ├── DOTParserVisitor.java │ ├── HTMLLexer.interp │ ├── HTMLLexer.java │ ├── HTMLLexer.tokens │ ├── HTMLParser.interp │ ├── HTMLParser.java │ ├── HTMLParser.tokens │ ├── HTMLParserBaseListener.java │ ├── HTMLParserBaseVisitor.java │ ├── HTMLParserListener.java │ └── HTMLParserVisitor.java ├── pom.xml └── test ├── picture ├── case_visual.png ├── fdp.png ├── layout.png ├── line_port.png ├── line_router.png ├── node_record.png ├── node_shape.png ├── rich_text.png ├── show_boxes.png ├── show_control_points.png ├── show_grid.png ├── table.png ├── table_assemble.png └── table_example.png ├── pom.xml └── src └── test ├── java ├── dot │ └── DotCasesTest.java ├── helper │ ├── DocumentUtils.java │ ├── GraphvizVisual.java │ └── TableUtils.java ├── regression │ ├── ClusterTest.java │ ├── CoordinateTest.java │ ├── LineTest.java │ ├── PortTest.java │ ├── SubgraphTest.java │ └── TempTest.java └── visual_case │ ├── BugCaseTest.java │ ├── CellLabelTest.java │ ├── ClusterAttrTest.java │ ├── ClusterTest.java │ ├── DocCaseTest.java │ ├── FdpTest.java │ ├── GraphAttrTest.java │ ├── LabelTest.java │ ├── LineAttrTest.java │ ├── MultiFontDisplayTest.java │ ├── NodeAttrTest.java │ ├── OrthoPortTest.java │ ├── SelfLineTest.java │ ├── SubgraphAttrTest.java │ └── TableCaseTest.java └── resources ├── dot ├── manual │ ├── attrs_test.dot │ ├── big_fdp_case.dot │ ├── case1.dot │ ├── case10.dot │ ├── case11.dot │ ├── case12.dot │ ├── case13.dot │ ├── case14.dot │ ├── case15.dot │ ├── case16.dot │ ├── case17.dot │ ├── case18.dot │ ├── case19.dot │ ├── case2.dot │ ├── case20.dot │ ├── case3.dot │ ├── case4.dot │ ├── case5.dot │ ├── case6.dot │ ├── case7.dot │ ├── case8.dot │ ├── case9.dot │ ├── cluster.dot │ ├── clusterAttrs.dot │ ├── clusterIdMixedCase.dot │ ├── clusterLabel.dot │ ├── cluster_alloc_bug.dot │ ├── cluster_case1.dot │ ├── cluster_case2.dot │ ├── cluster_case3.dot │ ├── cluster_nest.dot │ ├── cluster_optimize.dot │ ├── cluster_same_rank.dot │ ├── edgeSubgraphCombined.dot │ ├── edgeSubgraphLeft.dot │ ├── edgeSubgraphMiddle.dot │ ├── edgeSubgraphRight.dot │ ├── embedTable.dot │ ├── fdp1.dot │ ├── fdp2.dot │ ├── fdp3.dot │ ├── fdp4.dot │ ├── fdp5.dot │ ├── fdp6.dot │ ├── fdp7.dot │ ├── fdp8.dot │ ├── fdp9.dot │ ├── fdp_ortho_selfline.dot │ ├── flow.dot │ ├── grid.dot │ ├── htmlTag.dot │ ├── html_example.dot │ ├── language.dot │ ├── lhead.dot │ ├── nodeDefinePriority.dot │ ├── port.dot │ ├── self_line.dot │ ├── sequence_eg.dot │ ├── stringCase.dot │ ├── subgraphEndpointsEdges.dot │ ├── template.dot │ ├── timeline.dot │ └── uml_eg.dot └── random │ ├── 121.dot │ ├── 1221.dot │ ├── 1314.dot │ ├── 14.dot │ ├── 1408.dot │ ├── 1436.dot │ ├── 1437.dot │ ├── 1444-2.dot │ ├── 1444.dot │ ├── 144_no_ortho.dot │ ├── 144_ortho.dot │ ├── 1624.dot │ ├── 165.dot │ ├── 1658.dot │ ├── 165_2.dot │ ├── 165_3.dot │ ├── 167.dot │ ├── 1724.dot │ ├── 1767.dot │ ├── 1783.dot │ ├── 1845.dot │ ├── 1855.dot │ ├── 1856.dot │ ├── 1865.dot │ ├── 1879.dot1 │ ├── 1880.dot │ ├── 1898.dot │ ├── 358.dot1 │ ├── 42.dot │ ├── 56.dot │ └── 925.dot ├── graph-visual-template.html ├── log4j.xml └── table ├── table_1.html ├── table_2.html ├── table_3.html ├── table_4.html ├── table_5.html ├── table_6.html ├── table_7.html └── table_8.html /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | target/ 3 | workspace.xml 4 | graph-support.iml -------------------------------------------------------------------------------- /cli/src/main/java/org/graphper/WrongCommandException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper; 18 | 19 | /** 20 | * Exception thrown when an invalid or unrecognized command is encountered. 21 | * This is typically used in command-line argument parsing to indicate incorrect usage. 22 | * 23 | * @author Jamison Jiang 24 | */ 25 | public class WrongCommandException extends Exception { 26 | 27 | private static final long serialVersionUID = 7129182882393292716L; 28 | 29 | public WrongCommandException() { 30 | super(); 31 | } 32 | 33 | public WrongCommandException(String message) { 34 | super(message); 35 | } 36 | 37 | public WrongCommandException(Throwable cause) { 38 | super(cause); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /cli/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | %msg%n 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /core/src/main/java/org/apache_gs/commons/text/translate/UnicodeUnpairedSurrogateRemover.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.apache_gs.commons.text.translate; 18 | 19 | import java.io.IOException; 20 | import java.io.Writer; 21 | 22 | /** 23 | * Helper subclass to CharSequenceTranslator to remove unpaired surrogates. 24 | * 25 | * @since 1.0 26 | */ 27 | public class UnicodeUnpairedSurrogateRemover extends CodePointTranslator { 28 | /** 29 | * Implementation of translate that throws out unpaired surrogates. 30 | * {@inheritDoc} 31 | */ 32 | @Override 33 | public boolean translate(final int codePoint, final Writer writer) throws IOException { 34 | // If true, it is a surrogate. Write nothing and say we've translated. Otherwise return false, and don't translate it. 35 | return codePoint >= Character.MIN_SURROGATE && codePoint <= Character.MAX_SURROGATE; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /core/src/main/java/org/apache_gs/commons/text/translate/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | /** 18 | *

An API for creating text translation routines from a set of smaller building blocks. Initially created to make it 19 | * possible for the user to customize the rules in the StringEscapeUtils class.

20 | *

These classes are immutable, and therefore thread-safe.

21 | * 22 | * @since 1.0 23 | */ 24 | package org.apache_gs.commons.text.translate; 25 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/FileType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api; 18 | 19 | /** 20 | * File type enumeration. 21 | * 22 | * @author Jamison Jiang 23 | */ 24 | public enum FileType { 25 | SVG("svg"), PNG("png"), JPG("jpg"), JPEG("jpeg"), GIF("gif"), 26 | 27 | // Need external plugin: Apache Batik 28 | TIFF("tiff"), 29 | // Need external plugin: Apache FOP 30 | PDF("pdf") 31 | ; 32 | 33 | FileType(String type) { 34 | this.type = type; 35 | } 36 | 37 | private final String type; 38 | 39 | public String getType() { 40 | return type; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/attributes/ArrowShape.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.attributes; 18 | 19 | /** 20 | * An enumeration of the different shapes of the line's arrowhead. 21 | * 22 | * @author Jamison Jiang 23 | */ 24 | public enum ArrowShape { 25 | 26 | VEE(0.75, true), 27 | 28 | CURVE(1, false), 29 | 30 | BOX(0.75, true), 31 | 32 | DOT(0.75, true), 33 | 34 | NONE(1, false), 35 | 36 | NORMAL(1, true); 37 | 38 | ArrowShape(double clipRatio, boolean needFill) { 39 | this.clipRatio = clipRatio; 40 | this.needFill = needFill; 41 | } 42 | 43 | private final double clipRatio; 44 | 45 | private final boolean needFill; 46 | 47 | /** 48 | * Returns the basic size ratio of arrow shape. 49 | * 50 | * @return the basic size ratio 51 | */ 52 | public double getClipRatio() { 53 | return clipRatio; 54 | } 55 | 56 | /** 57 | * Returns whether this arrow's shape needs filled. 58 | * 59 | * @return true if arrow's shape need filled 60 | */ 61 | public boolean isNeedFill() { 62 | return needFill; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/attributes/ClusterStyle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.attributes; 18 | 19 | /** 20 | * Cluster style. 21 | * 22 | * @author Jamison Jiang 23 | */ 24 | public enum ClusterStyle implements Style { 25 | 26 | /** 27 | * Dashed cluster consisting of a series of line segment. 28 | */ 29 | DASHED, 30 | 31 | /** 32 | * Dotted cluster consisting of a series of points. 33 | */ 34 | DOTTED, 35 | 36 | /** 37 | * Hide cluster when rendering (but the attributes are valid during layout). 38 | */ 39 | INVIS, 40 | 41 | /** 42 | * Draws the line segment boldly. 43 | */ 44 | BOLD, 45 | 46 | /** 47 | * Use rounded angles for clusters. 48 | */ 49 | ROUNDED; 50 | } 51 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/attributes/Dir.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.attributes; 18 | 19 | import org.graphper.api.Graphviz; 20 | 21 | /** 22 | * Line type for drawing arrowheads, indicates which ends of the edge should be decorated with an 23 | * arrowhead. It will only take effect under {@link Graphviz#digraph()}. 24 | * 25 | * @author Jamison Jiang 26 | */ 27 | public enum Dir { 28 | 29 | /** 30 | * The directed line from T to H, draw as T -> H. 31 | */ 32 | FORWARD, 33 | 34 | /** 35 | * The directed line from T to H, draw as T <- H. 36 | */ 37 | BACK, 38 | 39 | /** 40 | * The directed line from T to H, draw as T <-> H. 41 | */ 42 | BOTH, 43 | 44 | /** 45 | * The directed line from T to H, draw as T - H. 46 | */ 47 | NONE; 48 | } 49 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/attributes/InitPos.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.attributes; 18 | 19 | /** 20 | * Enumeration representing the initialization position algorithms for 21 | * Force-Directed Placement (FDP) graph layout. 22 | *

23 | * These algorithms determine the initial positions of nodes in the layout. 24 | *

25 | * 26 | * @author Jamison Jiang 27 | */ 28 | public enum InitPos { 29 | 30 | /** 31 | * Initializes nodes in a grid pattern. 32 | */ 33 | GRID, 34 | 35 | /** 36 | * Arranges nodes in a circular pattern. 37 | */ 38 | CIRCLE, 39 | 40 | /** 41 | * Distributes nodes in sectors. 42 | */ 43 | SECTOR; 44 | } 45 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/attributes/LineStyle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.attributes; 18 | 19 | /** 20 | * Line style. 21 | * 22 | * @author Jamison Jiang 23 | */ 24 | public enum LineStyle { 25 | 26 | /** 27 | * Dashed line consisting of a series of line segment. 28 | */ 29 | DASHED, 30 | 31 | /** 32 | * Dotted line consisting of a series of points. 33 | */ 34 | DOTTED, 35 | 36 | /** 37 | * Line segments are drawn as solid lines. 38 | */ 39 | SOLID, 40 | 41 | /** 42 | * Hide line segments when rendering (but the attributes are valid during layout). 43 | */ 44 | INVIS, 45 | 46 | /** 47 | * Draws the line segment boldly. 48 | */ 49 | BOLD 50 | } 51 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/attributes/NodeStyle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.attributes; 18 | 19 | /** 20 | * Node style. 21 | * 22 | * @author Jamison Jiang 23 | */ 24 | public enum NodeStyle implements Style { 25 | 26 | /** 27 | * Dashed node border consisting of a series of line segment. 28 | */ 29 | DASHED, 30 | 31 | /** 32 | * Dotted node border consisting of a series of points. 33 | */ 34 | DOTTED, 35 | 36 | /** 37 | * Node border are drawn as solid lines. 38 | */ 39 | SOLID, 40 | 41 | /** 42 | * Hide node when rendering (but the attributes are valid during layout). 43 | */ 44 | INVIS, 45 | 46 | /** 47 | * Draws the node border boldly. 48 | */ 49 | BOLD, 50 | 51 | /** 52 | * Use rounded angles for nodes. 53 | */ 54 | ROUNDED 55 | } 56 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/attributes/Rankdir.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.attributes; 18 | 19 | import org.apache_gs.commons.lang3.StringUtils; 20 | 21 | /** 22 | * Sets direction of graph layout, only valid for {@link Layout#DOT}. 23 | * 24 | * @author Jamison Jiang 25 | */ 26 | public enum Rankdir { 27 | 28 | /** 29 | * Horizontal layout, left to right 30 | */ 31 | LR, 32 | 33 | /** 34 | * Horizontal layout, right to left 35 | */ 36 | RL, 37 | 38 | /** 39 | * Vertical layout, top to bottom 40 | */ 41 | TB, 42 | 43 | /** 44 | * Vertical layout, bottom to top 45 | */ 46 | BT; 47 | 48 | public static Rankdir rankdir(String rankdir) { 49 | if (StringUtils.isEmpty(rankdir)) { 50 | return Rankdir.TB; 51 | } 52 | 53 | try { 54 | return valueOf(rankdir); 55 | } catch (Exception e) { 56 | return Rankdir.TB; 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/attributes/Style.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.attributes; 18 | 19 | public interface Style { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/attributes/Tend.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.attributes; 18 | 19 | import org.graphper.api.FloatLabel; 20 | 21 | /** 22 | * The placement tendency of {@link FloatLabel}. 23 | * 24 | * @author Jamison Jiang 25 | */ 26 | public enum Tend { 27 | /** 28 | * Float Label as close as possible to the tail node. 29 | */ 30 | TAIL, 31 | 32 | /** 33 | * Float Label as close as possible to the head node. 34 | */ 35 | HEAD; 36 | } 37 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/CirclePropCalc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | import java.io.Serializable; 20 | import org.graphper.def.FlatPoint; 21 | 22 | public class CirclePropCalc implements ShapePropCalc, Serializable { 23 | 24 | private static final long serialVersionUID = 4004804900027011314L; 25 | 26 | @Override 27 | public FlatPoint minContainerSize(double innerHeight, double innerWidth) { 28 | double diameter = Math.sqrt(Math.pow(innerHeight, 2) + Math.pow(innerWidth, 2)); 29 | return new FlatPoint(diameter, diameter); 30 | } 31 | 32 | @Override 33 | public boolean in(Box box, FlatPoint flatPoint) { 34 | double r = Math.pow(flatPoint.getX() - box.getX(), 2) 35 | + Math.pow(flatPoint.getY() - box.getY(), 2); 36 | return Math.sqrt(r) <= box.getWidth() / 2; 37 | } 38 | 39 | @Override 40 | public void ratio(FlatPoint boxSize) { 41 | squareRatio(boxSize); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/ClusterShapePost.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | import org.graphper.api.ClusterAttrs; 20 | import org.graphper.api.attributes.ClusterShape; 21 | import org.graphper.util.Asserts; 22 | 23 | /** 24 | * {@link ClusterShape} post processing. 25 | * 26 | * @author Jamison Jiang 27 | */ 28 | public interface ClusterShapePost { 29 | 30 | /** 31 | * When some characteristics of the shape need to be changed according to the rest of the cluster 32 | * attributes, use this method to post-create the enhanced {@link ClusterShape} to replace the 33 | * original {@link ClusterShape}. 34 | * 35 | * @param clusterAttrs cluster attribute 36 | * @return post {@code ClusterShape} 37 | */ 38 | default ClusterShape post(ClusterAttrs clusterAttrs) { 39 | Asserts.nullArgument(clusterAttrs, "clusterAttrs"); 40 | return clusterAttrs.getShape(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/CylinderPropCalc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | import java.io.Serializable; 20 | import org.graphper.def.FlatPoint; 21 | import org.graphper.api.attributes.NodeShapeEnum; 22 | 23 | public class CylinderPropCalc implements ShapePropCalc, Serializable { 24 | 25 | private static final long serialVersionUID = 2065821057594213750L; 26 | 27 | public static final int TOP_LEN = 6; 28 | 29 | @Override 30 | public FlatPoint minContainerSize(double innerHeight, double innerWidth) { 31 | return new FlatPoint(innerHeight + (3 * TOP_LEN), innerWidth); 32 | } 33 | 34 | @Override 35 | public boolean in(Box box, FlatPoint point) { 36 | return NodeShapeEnum.RECT.in(box, point); 37 | } 38 | 39 | @Override 40 | public FlatPoint labelCenter(FlatPoint labelSize, Box box) { 41 | return new FlatPoint(box.getX(), box.getY() + ((double) TOP_LEN / 2)); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/NodeShapePost.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | import org.graphper.api.attributes.NodeShape; 20 | import org.graphper.util.Asserts; 21 | import org.graphper.api.NodeAttrs; 22 | 23 | /** 24 | * {@link NodeShape} post processing. 25 | * 26 | * @author Jamison Jiang 27 | */ 28 | public interface NodeShapePost { 29 | 30 | /** 31 | * When some characteristics of the shape need to be changed according to the rest of the node 32 | * attributes, use this method to post-create the enhanced {@link NodeShape} to replace the 33 | * original {@link NodeShape}. 34 | * 35 | * @param nodeAttrs node attribute 36 | * @return post {@code NodeShape} 37 | */ 38 | default NodeShape post(NodeAttrs nodeAttrs) { 39 | Asserts.nullArgument(nodeAttrs, "nodeAttrs"); 40 | return nodeAttrs.getShape(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/PlainPropCalc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | public class PlainPropCalc extends RectanglePropCalc { 20 | 21 | private static final long serialVersionUID = -5011222556684270924L; 22 | 23 | @Override 24 | public boolean needMargin() { 25 | return false; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/PointPropCalc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | import org.graphper.api.attributes.Color; 20 | 21 | public class PointPropCalc extends CirclePropCalc { 22 | 23 | private static final long serialVersionUID = -3153454718323111406L; 24 | 25 | @Override 26 | public boolean needMargin() { 27 | return false; 28 | } 29 | 30 | @Override 31 | public boolean ignoreLabel() { 32 | return true; 33 | } 34 | 35 | @Override 36 | public Color defaultFillColor() { 37 | return Color.BLACK; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/PortPosition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | public interface PortPosition { 20 | 21 | double horOffset(Box box); 22 | 23 | double verOffset(Box box); 24 | } -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/RatioPortPosition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | import java.io.Serializable; 20 | import org.graphper.util.Asserts; 21 | 22 | public class RatioPortPosition implements PortPosition, Serializable { 23 | 24 | private static final long serialVersionUID = -1767859727952040562L; 25 | 26 | private final double xRatio; 27 | 28 | private final double yRatio; 29 | 30 | public RatioPortPosition(double xRatio, double yRatio) { 31 | this.xRatio = xRatio; 32 | this.yRatio = yRatio; 33 | } 34 | 35 | @Override 36 | public double horOffset(Box box) { 37 | Asserts.nullArgument(box, "box"); 38 | return box.getWidth() * xRatio; 39 | } 40 | 41 | @Override 42 | public double verOffset(Box box) { 43 | Asserts.nullArgument(box, "box"); 44 | return box.getHeight() * yRatio; 45 | } 46 | 47 | public double getxRatio() { 48 | return xRatio; 49 | } 50 | 51 | public double getyRatio() { 52 | return yRatio; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/RecordPropCalc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | import java.io.Serializable; 20 | import org.graphper.def.FlatPoint; 21 | 22 | public class RecordPropCalc implements ShapePropCalc, Serializable { 23 | 24 | private static final long serialVersionUID = -8655733264629048199L; 25 | 26 | public static final int CORNER_LEN = 40; 27 | 28 | private final boolean radianCorner; 29 | 30 | public RecordPropCalc(boolean radianCorner) { 31 | this.radianCorner = radianCorner; 32 | } 33 | 34 | @Override 35 | public FlatPoint minContainerSize(double innerHeight, double innerWidth) { 36 | return new FlatPoint(innerHeight, innerWidth); 37 | } 38 | 39 | @Override 40 | public boolean in(Box box, FlatPoint point) { 41 | return Math.abs(box.getX() - point.getX()) <= box.getWidth() / 2 42 | && Math.abs(box.getY() - point.getY()) <= box.getHeight() / 2; 43 | } 44 | 45 | public boolean isRadianCorner() { 46 | return radianCorner; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/RectanglePropCalc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | import java.io.Serializable; 20 | import org.graphper.def.FlatPoint; 21 | 22 | public class RectanglePropCalc implements ShapePropCalc, Serializable { 23 | 24 | private static final long serialVersionUID = 5056940900129881225L; 25 | 26 | @Override 27 | public FlatPoint minContainerSize(double innerHeight, double innerWidth) { 28 | return new FlatPoint(innerHeight, innerWidth); 29 | } 30 | 31 | @Override 32 | public boolean in(Box box, FlatPoint point) { 33 | return Math.abs(box.getX() - point.getX()) <= box.getWidth() / 2 34 | && Math.abs(box.getY() - point.getY()) <= box.getHeight() / 2; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/ShapePosition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | import org.graphper.api.attributes.NodeShape; 20 | 21 | /** 22 | * Use ShapePosition to describe an element with container properties and shape properties. 23 | * 24 | * @author Jamison Jiang 25 | */ 26 | public interface ShapePosition extends Box { 27 | 28 | /** 29 | * Returns a primitive describing the shape the current object should conform to. Although 30 | * {@link NodeShape} is used to describe, the current element is not necessarily a node. 31 | * 32 | * @return current shape properties describe function 33 | */ 34 | ShapePropCalc shapeProp(); 35 | } 36 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/api/ext/SymmetryShapeCenterCalc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | import java.io.Serializable; 20 | 21 | public class SymmetryShapeCenterCalc implements ShapeCenterCalc, Serializable { 22 | 23 | private static final long serialVersionUID = -299277822910531114L; 24 | 25 | public static final SymmetryShapeCenterCalc SSPC = new SymmetryShapeCenterCalc(); 26 | 27 | @Override 28 | public double leftWidth(Double width) { 29 | return half(width); 30 | } 31 | 32 | @Override 33 | public double rightWidth(Double width) { 34 | return half(width); 35 | } 36 | 37 | @Override 38 | public double topHeight(Double height) { 39 | return half(height); 40 | } 41 | 42 | @Override 43 | public double bottomHeight(Double height) { 44 | return half(height); 45 | } 46 | 47 | private double half(Double val) { 48 | if (val == null) { 49 | return 0; 50 | } 51 | 52 | return val / 2; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/def/ColorFormatException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.def; 18 | 19 | /** 20 | * Color format exception. 21 | * 22 | * @author Jamison Jiang 23 | */ 24 | public class ColorFormatException extends RuntimeException { 25 | 26 | private static final long serialVersionUID = 1033876844829922354L; 27 | 28 | /** 29 | * Constructs a {@code ColorFormatException} with no verbose message. 30 | */ 31 | public ColorFormatException() { 32 | } 33 | 34 | /** 35 | * Constructs a {@code ColorFormatException} with verbose message. 36 | * 37 | * @param message error message 38 | */ 39 | public ColorFormatException(String message) { 40 | super(message); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/def/CycleDependencyException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.def; 18 | 19 | /** 20 | * An exception is thrown when some circular dependencies are found. 21 | * 22 | * @author Jamison Jiang 23 | */ 24 | public class CycleDependencyException extends RuntimeException { 25 | 26 | private static final long serialVersionUID = -3107358271649259443L; 27 | 28 | public CycleDependencyException() { 29 | } 30 | 31 | public CycleDependencyException(String message) { 32 | super(message); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/def/Edge.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.def; 18 | 19 | /** 20 | * Basic identification of graph undirected edges. 21 | * 22 | * @param vertex type 23 | * @param subclass type 24 | * @author Jamison Jiang 25 | */ 26 | public interface Edge> extends BaseEdge { 27 | 28 | /** 29 | * Return weight of edge. 30 | * 31 | * @return weight of edge 32 | */ 33 | @Override 34 | double weight(); 35 | 36 | /** 37 | * Returns another vertex of the edge based on the vertex of the edge, or null if the vertex is 38 | * not part of the edge. 39 | * 40 | * @param v endpoint of edge 41 | * @return edge another vertex 42 | */ 43 | @Override 44 | V other(V v); 45 | 46 | /** 47 | * Returns an endpoint of an undirected edge. 48 | * 49 | * @return edge endpoint 50 | */ 51 | @Override 52 | V either(); 53 | 54 | /** 55 | * Create a copy of the edge. 56 | * 57 | * @return a copy of the edge 58 | */ 59 | @Override 60 | E copy(); 61 | } -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/def/UnfeasibleException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.def; 18 | 19 | public class UnfeasibleException extends Exception { 20 | 21 | private static final long serialVersionUID = 724199542997633250L; 22 | 23 | public UnfeasibleException() { 24 | super(); 25 | } 26 | 27 | public UnfeasibleException(String message) { 28 | super(message); 29 | } 30 | 31 | public UnfeasibleException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | 35 | public UnfeasibleException(Throwable cause) { 36 | super(cause); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/def/UnmodifiableBagException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.def; 18 | 19 | public class UnmodifiableBagException extends RuntimeException { 20 | 21 | private static final long serialVersionUID = 1033876844829922354L; 22 | 23 | public UnmodifiableBagException(String message) { 24 | super(message); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/def/UnmodifiablePointException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.def; 18 | 19 | public class UnmodifiablePointException extends RuntimeException { 20 | 21 | private static final long serialVersionUID = 1033876844829922354L; 22 | 23 | public UnmodifiablePointException(String message) { 24 | super(message); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/Brush.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | /** 20 | * Property brush, use this object to paint elements. 21 | * 22 | * @author Jamison Jiang 23 | */ 24 | public interface Brush { 25 | 26 | /** 27 | * Returns the current draw board. 28 | * 29 | * @param node brush type 30 | * @param line brush type 31 | * @param cluster brush type 32 | * @param graphviz brush type 33 | * @return current draw board 34 | */ 35 | DrawBoard drawBoard(); 36 | } 37 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/ClusterEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | /** 20 | * Cluster editor. 21 | * 22 | * @param cluster editor type 23 | */ 24 | public interface ClusterEditor extends Editor { 25 | 26 | /** 27 | * Edit cluster, return false if you want to terminate the process. 28 | * 29 | * @param cluster cluster to be drawn 30 | * @param brush cluster brush 31 | * @return true if the next editor continues editing 32 | */ 33 | @Override 34 | boolean edit(ClusterDrawProp cluster, B brush); 35 | } -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/ClusterPipelineTrigger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | import java.util.Collection; 20 | import java.util.Comparator; 21 | import java.util.List; 22 | import java.util.stream.Collectors; 23 | 24 | public class ClusterPipelineTrigger> 25 | extends AbstractPipelineTrigger> { 26 | 27 | protected ClusterPipelineTrigger(List editors, DrawGraph drawGraph) { 28 | super(editors, drawGraph); 29 | } 30 | 31 | @Override 32 | public Iterable renderItems() { 33 | Collection clusters = drawGraph.clusters(); 34 | return clusters.stream() 35 | .sorted(Comparator.comparing(ClusterDrawProp::getClusterNo).reversed()) 36 | .collect(Collectors.toList()); 37 | } 38 | } -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/Editor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | /** 20 | * An editor for editing drawing elements, the basic unit of pipeline arrangement. 21 | * 22 | * @param type of element 23 | * @param brush type 24 | * @author Jamison Jiang 25 | */ 26 | public interface Editor { 27 | 28 | /** 29 | * Draw the elements in the graph, return true or false to indicate whether to continue to the 30 | * next editor. 31 | * 32 | * @param drawnEle elements to be drawn 33 | * @param brush draw brush 34 | * @return true if the next editor continues editing 35 | */ 36 | boolean edit(T drawnEle, B brush); 37 | } 38 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/ExecuteException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | /** 20 | * Some exceptions caused by rendering or layout. 21 | * 22 | * @author Jamison Jiang 23 | */ 24 | public class ExecuteException extends Exception { 25 | 26 | private static final long serialVersionUID = 4454202917141572265L; 27 | 28 | public ExecuteException(String message) { 29 | super(message); 30 | } 31 | 32 | public ExecuteException(Throwable cause) { 33 | super(cause); 34 | } 35 | 36 | public ExecuteException(String message, Throwable cause) { 37 | super(message, cause); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/FailInitResourceException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | public class FailInitResourceException extends Exception { 20 | 21 | private static final long serialVersionUID = 591810568877839236L; 22 | 23 | public FailInitResourceException(String message) { 24 | super(message); 25 | } 26 | 27 | public FailInitResourceException(Throwable cause) { 28 | super(cause); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/GraphEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | /** 20 | * Graphviz editor. 21 | * 22 | * @param graphviz editor type 23 | */ 24 | public interface GraphEditor extends Editor { 25 | 26 | /** 27 | * Edit graphviz, return false if you want to terminate the process. 28 | * 29 | * @param graphviz graphviz to be drawn 30 | * @param brush graphviz brush 31 | * @return true if the next editor continues editing 32 | */ 33 | @Override 34 | boolean edit(GraphvizDrawProp graphviz, B brush); 35 | } 36 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/GraphPipelineTrigger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | import java.util.Collections; 20 | import java.util.List; 21 | 22 | public class GraphPipelineTrigger> 23 | extends AbstractPipelineTrigger> { 24 | 25 | public GraphPipelineTrigger(List editors, DrawGraph drawGraph) { 26 | super(editors, drawGraph); 27 | } 28 | 29 | @Override 30 | public Iterable renderItems() { 31 | return Collections.singleton(drawGraph.getGraphvizDrawProp()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/LineEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | import java.util.Objects; 20 | import org.graphper.api.Line; 21 | 22 | /** 23 | * Line editor. 24 | * 25 | * @param line editor type 26 | */ 27 | public interface LineEditor extends Editor { 28 | 29 | /** 30 | * Edit line, return false if you want to terminate the process. 31 | * 32 | * @param lineDrawProp line to be drawn 33 | * @param brush line brush 34 | * @return true if the next editor continues editing 35 | */ 36 | @Override 37 | default boolean edit(LineDrawProp lineDrawProp, B brush) { 38 | Objects.requireNonNull(lineDrawProp); 39 | 40 | return edit(lineDrawProp.getLine(), brush); 41 | } 42 | 43 | /** 44 | * Edit line, return false if you want to terminate the process. 45 | * 46 | * @param line line to be drawn 47 | * @param brush line brush 48 | * @return true if the next editor continues editing 49 | */ 50 | default boolean edit(Line line, B brush) { 51 | return true; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/LinePipelineTrigger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | import java.util.List; 20 | 21 | public class LinePipelineTrigger> 22 | extends AbstractPipelineTrigger> { 23 | 24 | protected LinePipelineTrigger(List editors, DrawGraph drawGraph) { 25 | super(editors, drawGraph); 26 | } 27 | 28 | @Override 29 | public Iterable renderItems() { 30 | return drawGraph.lines(); 31 | } 32 | } -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/NodeEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | import java.util.Objects; 20 | import org.graphper.api.Node; 21 | 22 | /** 23 | * Node editor. 24 | * 25 | * @param node editor type 26 | */ 27 | public interface NodeEditor extends Editor { 28 | 29 | /** 30 | * Edit node, return false if you want to terminate the process. 31 | * 32 | * @param nodeDrawProp node to be drawn 33 | * @param brush node brush 34 | * @return true if the next editor continues editing 35 | */ 36 | @Override 37 | default boolean edit(NodeDrawProp nodeDrawProp, B brush) { 38 | Objects.requireNonNull(nodeDrawProp); 39 | 40 | return edit(nodeDrawProp.getNode(), brush); 41 | } 42 | 43 | /** 44 | * Edit node, return false if you want to terminate the process. 45 | * 46 | * @param node node to be drawn 47 | * @param brush node brush 48 | * @return true if the next editor continues editing 49 | */ 50 | default boolean edit(Node node, B brush) { 51 | return true; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/NodePipelineTrigger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | import java.util.List; 20 | 21 | public class NodePipelineTrigger> 22 | extends AbstractPipelineTrigger> { 23 | 24 | public NodePipelineTrigger(List editors, DrawGraph drawGraph) { 25 | super(editors, drawGraph); 26 | } 27 | 28 | @Override 29 | public Iterable renderItems() { 30 | return drawGraph.nodes(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/PipelineFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | import java.util.List; 20 | 21 | public interface PipelineFactory { 22 | 23 | > NodePipelineTrigger nodeExecutePipeline( 24 | List editors, DrawGraph graphviz 25 | ); 26 | 27 | > LinePipelineTrigger lineExecutePipeline( 28 | List editors, DrawGraph graphviz 29 | ); 30 | 31 | > ClusterPipelineTrigger clusterExecutePipeline( 32 | List editors, DrawGraph graphviz 33 | ); 34 | 35 | > GraphPipelineTrigger graphExecutePipeline( 36 | List editors, DrawGraph graphviz 37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/Rectangle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw; 18 | 19 | import org.graphper.api.ext.DefaultBox; 20 | 21 | public class Rectangle extends DefaultBox { 22 | 23 | public Rectangle() { 24 | init(); 25 | } 26 | 27 | public void init() { 28 | leftBorder = Double.MAX_VALUE; 29 | rightBorder = -Double.MAX_VALUE; 30 | upBorder = Double.MAX_VALUE; 31 | downBorder = -Double.MAX_VALUE; 32 | } 33 | 34 | public void flip() { 35 | double tmp = leftBorder; 36 | leftBorder = upBorder; 37 | upBorder = tmp; 38 | tmp = rightBorder; 39 | rightBorder = downBorder; 40 | downBorder = tmp; 41 | } 42 | 43 | public void updateXAxisRange(double x) { 44 | leftBorder = Math.min(x, leftBorder); 45 | rightBorder = Math.max(x, rightBorder); 46 | } 47 | 48 | public void updateYAxisRange(double y) { 49 | upBorder = Math.min(y, upBorder); 50 | downBorder = Math.max(y, downBorder); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/svg/node/AbstractNodeShapeEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw.svg.node; 18 | 19 | import org.graphper.api.attributes.NodeShape; 20 | import org.graphper.api.attributes.NodeShapeEnum; 21 | import org.graphper.draw.NodeDrawProp; 22 | import org.graphper.draw.NodeEditor; 23 | import org.graphper.draw.svg.SvgBrush; 24 | import org.graphper.draw.svg.SvgConstants; 25 | 26 | public abstract class AbstractNodeShapeEditor implements NodeEditor, SvgConstants { 27 | 28 | protected String getShapeElement(NodeDrawProp nodeDrawProp) { 29 | NodeShape nodeShape = nodeDrawProp.nodeAttrs().getShape(); 30 | 31 | if (nodeShape == NodeShapeEnum.CIRCLE 32 | || nodeShape == NodeShapeEnum.ELLIPSE 33 | || nodeShape == NodeShapeEnum.POINT) { 34 | return NodeShapeEnum.ELLIPSE.getName(); 35 | } 36 | 37 | return SvgConstants.POLYGON_ELE; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/svg/node/NodeColorEditor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw.svg.node; 18 | 19 | import org.graphper.api.NodeAttrs; 20 | import org.graphper.api.attributes.Color; 21 | import org.graphper.draw.NodeDrawProp; 22 | import org.graphper.draw.svg.Element; 23 | import org.graphper.draw.svg.SvgBrush; 24 | import org.graphper.draw.svg.SvgConstants; 25 | 26 | public class NodeColorEditor extends AbstractNodeShapeEditor { 27 | 28 | @Override 29 | public boolean edit(NodeDrawProp node, SvgBrush brush) { 30 | NodeAttrs nodeAttrs = node.nodeAttrs(); 31 | 32 | for (Element element : brush.getEleGroup(SHAPE_GROUP_KEY)) { 33 | Color color = nodeAttrs.getColor(); 34 | element.setAttribute(SvgConstants.STROKE, color.value()); 35 | 36 | Color fillColor = nodeAttrs.getFillColor(); 37 | if (fillColor == null) { 38 | fillColor = nodeAttrs.getShape().defaultFillColor(); 39 | } 40 | if (fillColor == null) { 41 | continue; 42 | } 43 | element.setAttribute(FILL, fillColor.value()); 44 | } 45 | 46 | return true; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/draw/svg/shape/CircleShapeRender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.draw.svg.shape; 18 | 19 | import org.graphper.api.attributes.NodeShapeEnum; 20 | import org.graphper.api.ext.Box; 21 | import org.graphper.draw.svg.Element; 22 | import org.graphper.draw.svg.SvgConstants; 23 | 24 | public class CircleShapeRender extends EllipseShapeRender { 25 | 26 | @Override 27 | public String getShapeName() { 28 | return NodeShapeEnum.CIRCLE.getName(); 29 | } 30 | 31 | @Override 32 | protected void draw(Box box, Element shapeEle) { 33 | double radius = Math.min(box.getHeight() / 2, box.getWidth() / 2); 34 | shapeEle.setAttribute(SvgConstants.CX, String.valueOf(box.getX())); 35 | shapeEle.setAttribute(SvgConstants.CY, String.valueOf(box.getY())); 36 | shapeEle.setAttribute(SvgConstants.RX, String.valueOf(radius)); 37 | shapeEle.setAttribute(SvgConstants.RY, String.valueOf(radius)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/layout/AbstractShifterStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout; 18 | 19 | import java.util.List; 20 | import org.graphper.util.CollectionUtils; 21 | import org.graphper.draw.ContainerDrawProp; 22 | import org.graphper.draw.GraphvizDrawProp; 23 | import org.graphper.layout.OrthoVisGraph.Segment; 24 | 25 | public abstract class AbstractShifterStrategy implements ShifterStrategy { 26 | 27 | protected void moveGrid(ContainerDrawProp containerDrawProp) { 28 | if (!(containerDrawProp instanceof GraphvizDrawProp)) { 29 | return; 30 | } 31 | 32 | List grid = ((GraphvizDrawProp) containerDrawProp).getGrid(); 33 | if (CollectionUtils.isEmpty(grid)) { 34 | return; 35 | } 36 | 37 | for (Segment segment : grid) { 38 | movePoint(segment.getStart()); 39 | movePoint(segment.getEnd()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/layout/EnvStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout; 18 | 19 | /** 20 | * When there are different dependencies in the environment, use different implementations to ensure 21 | * the implementation of certain functions follows a degradation strategy. 22 | * 23 | * @author Jamison Jiang 24 | */ 25 | public interface EnvStrategy { 26 | 27 | /** 28 | * When there are multiple available implementations, use this attribute to sort, and the one with 29 | * the smaller value will be used first, and if they are the same, one will be randomly selected 30 | * for use. 31 | * 32 | * @return priority of the current env strategy 33 | */ 34 | int order(); 35 | 36 | /** 37 | * Returns whether the current environment supports the corresponding strategy. 38 | * 39 | * @return true if current environment support 40 | */ 41 | boolean envSupport(); 42 | } 43 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/layout/LabelFormatException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout; 18 | 19 | public class LabelFormatException extends RuntimeException { 20 | 21 | private static final long serialVersionUID = 27577065681271306L; 22 | 23 | public LabelFormatException(String message) { 24 | super(message); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/layout/LineRouter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout; 18 | 19 | /** 20 | * Line routing interface. 21 | * 22 | * @author Jamison Jiang 23 | */ 24 | public interface LineRouter { 25 | 26 | /** 27 | * Routing the line. 28 | */ 29 | void route(); 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/layout/ShifterStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout; 18 | 19 | import org.graphper.def.FlatPoint; 20 | import org.graphper.layout.dot.RouterBox; 21 | import org.graphper.draw.ContainerDrawProp; 22 | 23 | /** 24 | * A translation strategy for basic elements. 25 | * 26 | * @author Jamison Jiang 27 | */ 28 | public interface ShifterStrategy { 29 | 30 | /** 31 | * The point movement strategy. 32 | * 33 | * @param point point to move 34 | */ 35 | void movePoint(FlatPoint point); 36 | 37 | /** 38 | * The {@link ContainerDrawProp} movement strategy. 39 | * 40 | * @param containerDrawProp ContainerDrawProp to move 41 | */ 42 | void moveContainerDrawProp(ContainerDrawProp containerDrawProp); 43 | 44 | /** 45 | * The {@link RouterBox} movement strategy. 46 | * 47 | * @param routerBox RouterBox to move 48 | */ 49 | void moveBox(RouterBox routerBox); 50 | } 51 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/layout/dot/CrossRank.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout.dot; 18 | 19 | import java.util.Comparator; 20 | import org.graphper.api.GraphContainer; 21 | 22 | interface CrossRank { 23 | 24 | int getRankIndex(DNode node); 25 | 26 | Integer safeGetRankIndex(DNode node); 27 | 28 | DNode getNode(int rank, int rankIdx); 29 | 30 | void addNode(DNode node); 31 | 32 | int rankSize(int rank); 33 | 34 | int minRank(); 35 | 36 | int maxRank(); 37 | 38 | void exchange(DNode v, DNode w); 39 | 40 | void sort(Comparator comparator); 41 | 42 | void sort(int rank, Comparator comparator); 43 | 44 | GraphContainer container(); 45 | } 46 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/layout/dot/DotDigraph.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout.dot; 18 | 19 | import java.util.Map; 20 | import org.graphper.api.Graphviz; 21 | import org.graphper.api.Node; 22 | import org.graphper.def.Digraph.EdgeDigraph; 23 | import org.graphper.def.DirectedEdgeGraph; 24 | import org.graphper.layout.LayoutGraph; 25 | 26 | class DotDigraph extends LayoutGraph { 27 | 28 | public DotDigraph(int capacity) { 29 | super(capacity); 30 | } 31 | 32 | public DotDigraph(int capacity, Graphviz graphviz, 33 | Map nodeMap) { 34 | super(capacity, graphviz, nodeMap); 35 | } 36 | 37 | @Override 38 | protected EdgeDigraph newGraph(int capacity) { 39 | return new DirectedEdgeGraph<>(capacity); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/layout/dot/DotLineRouterFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout.dot; 18 | 19 | import org.graphper.api.attributes.Splines; 20 | import org.graphper.def.EdgeDedigraph; 21 | import org.graphper.draw.DrawGraph; 22 | import org.graphper.layout.LineRouter; 23 | 24 | /** 25 | * Factory of the router. 26 | * 27 | * @param router type 28 | */ 29 | abstract class DotLineRouterFactory { 30 | 31 | /** 32 | * Determine whether the current router needs to process the current {@link Splines } attribute. 33 | * 34 | * @param splines Splines 35 | * @return true if router need handle the splines attribute 36 | */ 37 | protected boolean needDeal(Splines splines) { 38 | return splines != Splines.NONE; 39 | } 40 | 41 | protected abstract T newInstance(DrawGraph drawGraph, DotDigraph dotDigraph, 42 | RankContent rankContent, 43 | EdgeDedigraph digraphProxy); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/layout/dot/SubgrahOppositRankException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout.dot; 18 | 19 | public class SubgrahOppositRankException extends RuntimeException { 20 | 21 | private static final long serialVersionUID = -36599932715465366L; 22 | 23 | public SubgrahOppositRankException() { 24 | this("Nodes are set to two opposite rank"); 25 | } 26 | 27 | public SubgrahOppositRankException(String message) { 28 | super(message); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/layout/fdp/FLine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout.fdp; 18 | 19 | import org.graphper.api.Line; 20 | import org.graphper.api.LineAttrs; 21 | import org.graphper.layout.ALine; 22 | 23 | public class FLine extends ALine { 24 | 25 | private static final long serialVersionUID = -2526416728355227232L; 26 | 27 | public FLine(FNode from, FNode to, LineAttrs lineAttrs) { 28 | super(from, to, null, lineAttrs); 29 | } 30 | 31 | public FLine(FNode from, FNode to, Line line, LineAttrs lineAttrs) { 32 | super(from, to, line, lineAttrs); 33 | } 34 | 35 | public FLine(FNode from, FNode to, double weight, Line line, LineAttrs lineAttrs) { 36 | super(from, to, weight, line, lineAttrs); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/layout/fdp/FdpMaze.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout.fdp; 18 | 19 | import org.graphper.draw.DrawGraph; 20 | import org.graphper.layout.Grid.GridBuilder; 21 | import org.graphper.layout.Maze; 22 | 23 | public class FdpMaze extends Maze { 24 | 25 | private final FdpGraph fdpGraph; 26 | 27 | public FdpMaze(DrawGraph drawGraph, FdpGraph fdpGraph) { 28 | super(drawGraph, true); 29 | this.fdpGraph = fdpGraph; 30 | init(); 31 | } 32 | 33 | @Override 34 | protected void initGrid(GridBuilder gridBuilder) { 35 | for (FNode node : fdpGraph) { 36 | if (node.isVirtual()) { 37 | continue; 38 | } 39 | 40 | addCell(node, new NodeCell(node), gridBuilder); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /core/src/main/java/org/graphper/util/CollectionUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.util; 18 | 19 | import java.util.Collection; 20 | 21 | /** 22 | * A collection function aggregates. 23 | * 24 | * @author Jamison Jiang 25 | */ 26 | public final class CollectionUtils { 27 | 28 | private CollectionUtils() { 29 | } 30 | 31 | /** 32 | * Determine whether the collection is a null value or an empty collection. 33 | * 34 | * @param collection the collection which be detected 35 | * @return true if the collections is null or empty 36 | */ 37 | public static boolean isEmpty(Collection collection) { 38 | return collection == null || collection.isEmpty(); 39 | } 40 | 41 | /** 42 | * Determine whether the collection is not a null value and an empty collection. 43 | * 44 | * @param collection the collection which be detected 45 | * @return true if the collections is not null and empty 46 | */ 47 | public static boolean isNotEmpty(Collection collection) { 48 | return !isEmpty(collection); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /core/src/main/resources/META-INF/services/org.graphper.draw.CustomizeShapeRender: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 The graph-support project 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | org.graphper.draw.svg.shape.RectShapeRender 18 | org.graphper.draw.svg.shape.CircleShapeRender 19 | org.graphper.draw.svg.shape.RegularShapeRender 20 | org.graphper.draw.svg.shape.EllipseShapeRender 21 | org.graphper.draw.svg.shape.TrapeziumShapeRender 22 | org.graphper.draw.svg.shape.InvtrapeziumShapeRender 23 | org.graphper.draw.svg.shape.ParallelogramShapeRender 24 | org.graphper.draw.svg.shape.RegularShapeRender$PentagonShapeRender 25 | org.graphper.draw.svg.shape.RegularShapeRender$HexagonShapeRender 26 | org.graphper.draw.svg.shape.RegularShapeRender$SeptagonShapeRender 27 | org.graphper.draw.svg.shape.RegularShapeRender$OctagonShapeRender 28 | -------------------------------------------------------------------------------- /core/src/main/resources/META-INF/services/org.graphper.draw.common.SvgConverter: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 The graph-support project 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | org.graphper.draw.common.BatikImgConverter 18 | org.graphper.draw.common.DefaultImgConverter 19 | org.graphper.draw.common.AndroidImgConverter 20 | org.graphper.draw.common.SvgToPdfConverter 21 | -------------------------------------------------------------------------------- /core/src/main/resources/META-INF/services/org.graphper.layout.FontOrder: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 The graph-support project 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | org.graphper.layout.DefaultFontOrder -------------------------------------------------------------------------------- /core/src/main/resources/META-INF/services/org.graphper.layout.FontSelector: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 The graph-support project 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | org.graphper.layout.AWTMeasureText 18 | org.graphper.layout.AndroidMeasureText 19 | -------------------------------------------------------------------------------- /core/src/main/resources/META-INF/services/org.graphper.layout.MeasureText: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2022 The graph-support project 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | org.graphper.layout.AWTMeasureText 18 | org.graphper.layout.AndroidMeasureText 19 | org.graphper.layout.RoughMeasureText 20 | -------------------------------------------------------------------------------- /core/src/test/java/org/graphper/api/HtmlTagTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api; 18 | 19 | import static org.graphper.api.Html.bold; 20 | import static org.graphper.api.Html.italic; 21 | import static org.graphper.api.Html.underline; 22 | 23 | import org.graphper.api.Html.LabelTag; 24 | import org.graphper.draw.ExecuteException; 25 | import org.junit.jupiter.api.Assertions; 26 | import org.junit.jupiter.api.Test; 27 | 28 | public class HtmlTagTest { 29 | 30 | @Test 31 | public void testLabelTagCycleDependency() { 32 | LabelTag t1 = bold("text"); 33 | 34 | Graphviz graphviz = Graphviz.digraph() 35 | .addNode(Node.builder().labelTag(t1.br().font("font").bold(italic(underline(t1)))).build()) 36 | .build(); 37 | Assertions.assertThrowsExactly(ExecuteException.class, graphviz::toSvgStr); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /core/src/test/java/org/graphper/api/ext/TrianglePropCalcTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.api.ext; 18 | 19 | import org.graphper.api.attributes.NodeShapeEnum; 20 | import org.graphper.api.ext.TrianglePropCalc; 21 | import org.graphper.def.FlatPoint; 22 | import org.graphper.draw.DefaultShapePosition; 23 | import org.junit.jupiter.api.Assertions; 24 | import org.junit.jupiter.api.Test; 25 | 26 | public class TrianglePropCalcTest { 27 | 28 | @Test 29 | public void testIn() { 30 | TrianglePropCalc calc = new TrianglePropCalc(true); 31 | 32 | DefaultShapePosition shapePosition = new DefaultShapePosition(0, 1, 2, 4, NodeShapeEnum.TRIANGLE); 33 | Assertions.assertTrue(calc.in(shapePosition, new FlatPoint(0, 0.1))); 34 | Assertions.assertFalse(calc.in(shapePosition, new FlatPoint(0, -0.1))); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /core/src/test/java/org/graphper/def/GNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.def; 18 | 19 | import java.io.Serializable; 20 | import java.util.Objects; 21 | 22 | public class GNode extends VertexIndex implements Serializable { 23 | 24 | private final String value; 25 | 26 | private GNode(String value) { 27 | this.value = value; 28 | } 29 | 30 | public String getValue() { 31 | return value; 32 | } 33 | 34 | public static GNode newNode(String value) { 35 | return new GNode(value); 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) { 41 | return true; 42 | } 43 | if (o == null || getClass() != o.getClass()) { 44 | return false; 45 | } 46 | GNode gNode = (GNode) o; 47 | return Objects.equals(value, gNode.value); 48 | } 49 | 50 | @Override 51 | public int hashCode() { 52 | return Objects.hash(value); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /core/src/test/java/org/graphper/def/GUEdge.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.def; 18 | 19 | public class GUEdge extends AbstractUndirectedEdge { 20 | 21 | private static final long serialVersionUID = -8287058500544888071L; 22 | 23 | protected GUEdge(GNode left, GNode right) { 24 | super(left, right); 25 | } 26 | 27 | @Override 28 | public GUEdge copy() { 29 | return clone(); 30 | } 31 | 32 | public static GUEdge newEdge(GNode left, GNode right) { 33 | return new GUEdge(left, right); 34 | } 35 | 36 | @Override 37 | protected GUEdge clone() { 38 | try { 39 | return (GUEdge) super.clone(); 40 | } catch (CloneNotSupportedException e) { 41 | return new GUEdge(either(), other(either())); 42 | } 43 | } 44 | 45 | @Override 46 | public boolean equals(Object obj) { 47 | return super.equals(obj) && obj.getClass() == GUEdge.class; 48 | } 49 | 50 | @Override 51 | public int hashCode() { 52 | return super.hashCode() + GUEdge.class.hashCode(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /core/src/test/java/org/graphper/layout/dot/TLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.layout.dot; 18 | 19 | import java.util.List; 20 | import org.graphper.draw.DrawGraph; 21 | import org.graphper.layout.LayoutAttach; 22 | import org.graphper.layout.ShifterStrategy; 23 | 24 | public class TLayout extends DotLayoutEngine { 25 | 26 | DotAttachment dotAttachment; 27 | 28 | @Override 29 | public void layout(DrawGraph drawGraph, LayoutAttach attach) { 30 | this.dotAttachment = (DotAttachment) attach; 31 | } 32 | 33 | @Override 34 | public List shifterStrategies(DrawGraph drawGraph) { 35 | return super.shifterStrategies(drawGraph); 36 | } 37 | 38 | @Override 39 | protected void afterRenderShifter(LayoutAttach drawGraph) { 40 | } 41 | } -------------------------------------------------------------------------------- /core/src/test/java/org/graphper/util/LabelTagUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.graphper.util; 18 | 19 | import static org.graphper.api.Html.bold; 20 | import static org.graphper.api.Html.italic; 21 | import static org.graphper.api.Html.underline; 22 | 23 | import org.graphper.api.Html.LabelTag; 24 | import org.graphper.def.CycleDependencyException; 25 | import org.graphper.layout.LabelAttributes; 26 | import org.junit.jupiter.api.Assertions; 27 | import org.junit.jupiter.api.Test; 28 | 29 | public class LabelTagUtilsTest { 30 | 31 | @Test 32 | public void testLabelTagCycleDependency() { 33 | LabelTag t1 = bold("text"); 34 | LabelTag t2 = t1.br().font("font").bold(italic(underline(t1))); 35 | 36 | Assertions.assertThrowsExactly(CycleDependencyException.class, 37 | () -> LabelTagUtils.measure(t2, new LabelAttributes())); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /core/src/test/resources/table/table_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
1111111111111111
22222222222222222222
1111111111111111111111111111
-------------------------------------------------------------------------------- /core/src/test/resources/table/table_3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
First NameLast NameEmail Address
HillaryNyakunditables@mail.com
LaryMakdeveloper@mail.com
-------------------------------------------------------------------------------- /core/src/test/resources/table/table_4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
NameSubjectMarks
HillaryAdvanced Web75
Operating Syatem60
LaryAdvanced Web80
Operating Syatem75
Total Average: 72.5
-------------------------------------------------------------------------------- /core/src/test/resources/table/table_5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Animals
Hippopotamus
HorseMare
Stallion
Crocodile
ChickenHen
Rooster
26 | -------------------------------------------------------------------------------- /core/src/test/resources/table/table_6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
title1title2title3
9 | 10 | 11 | 12 | 13 | 14 | 15 |
cell1cell2cell3
16 |
cell2cell3
cell4cell5cell6
26 | -------------------------------------------------------------------------------- /core/src/test/resources/table/table_7.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 |
First Column of Outer Table 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
First row of Inner Table
Second row of Inner Table
13 |
-------------------------------------------------------------------------------- /core/src/test/resources/table/table_8.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
NameAge
JillSmith43
EveJackson57
-------------------------------------------------------------------------------- /docs/Image Security Warning.md: -------------------------------------------------------------------------------- 1 | ## Security Warning 2 | 3 | ### 1. Remote URL Risks 4 | 5 | - Loading images from **untrusted URLs** may expose the application to **Server-Side Request Forgery (SSRF)** attacks. 6 | - External images may cause **slow network requests** or **serve malicious payloads**. 7 | 8 | ### 2. Local File Risks 9 | 10 | - Unvalidated local file paths can lead to **unauthorized system file access (Path Traversal vulnerability)**. 11 | - If the application runs with **high privileges**, it may **expose sensitive files**. 12 | 13 | ### 3. Large Image Risks 14 | 15 | - **Very large images** can cause **high memory usage**, leading to **Denial of Service (DoS) attacks**. 16 | - Excessive image requests can slow down rendering and increase resource consumption. 17 | 18 | ------ 19 | 20 | ### **Recommended Security Practices** 21 | 22 | ✅ **Use only trusted domains** or pre-validated image URLs. 23 | ✅ **Restrict local file paths** to a dedicated, controlled directory. 24 | ✅ **Limit image file sizes** to prevent excessive memory usage. 25 | ✅ **Sanitize file extensions** and **content types** to allow only valid image formats (`PNG`, `JPG`, `JPEG`). -------------------------------------------------------------------------------- /docs/cluster/FillColor.md: -------------------------------------------------------------------------------- 1 | # FillColor 2 | 3 | The **fillcolor** [alias `bgcolor`] attribute sets the **background color of a cluster**. This allows clusters to be visually distinct, improving readability in complex graphs. 4 | 5 | ------ 6 | 7 | ## **Usage in DOT** 8 | 9 | ```dot 10 | digraph G { 11 | subgraph cluster_0 { 12 | label="Red Background"; 13 | fillcolor="red"; 14 | a; b; 15 | } 16 | 17 | subgraph cluster_1 { 18 | label="Hex Color Background"; 19 | fillcolor="#ADD8E6"; 20 | c; d; 21 | } 22 | 23 | subgraph cluster_2 { 24 | label="Gradient Fill"; 25 | bgcolor="blue"; 26 | e; f; 27 | } 28 | } 29 | 30 | ``` 31 | 32 | ------ 33 | 34 | ## **Usage in Java** 35 | 36 | ```java 37 | Cluster redCluster = Cluster.builder() 38 | .id("cluster_0") 39 | .label("Red Background") 40 | .bgColor(Color.RED) 41 | .addNode(Node.builder().id("a").build()) 42 | .addNode(Node.builder().id("b").build()) 43 | .build(); 44 | 45 | Cluster hexColorCluster = Cluster.builder() 46 | .id("cluster_1") 47 | .label("Hex Color Background") 48 | .bgColor(Color.ofRGB("#ADD8E6")) 49 | .addNode(Node.builder().id("c").build()) 50 | .addNode(Node.builder().id("d").build()) 51 | .build(); 52 | 53 | Cluster gradientCluster = Cluster.builder() 54 | .id("cluster_2") 55 | .label("Gradient Fill") 56 | .bgColor(Color.BLUE) 57 | .addNode(Node.builder().id("e").build()) 58 | .addNode(Node.builder().id("f").build()) 59 | .build(); 60 | 61 | Graphviz graph = Graphviz.digraph() 62 | .cluster(redCluster) 63 | .cluster(hexColorCluster) 64 | .cluster(gradientCluster) 65 | .build(); 66 | ``` 67 | 68 | Color detail see [Color Intro](../Color Intro) -------------------------------------------------------------------------------- /docs/cluster/Href.md: -------------------------------------------------------------------------------- 1 | # Href 2 | 3 | The **href** [alias `url`] attribute adds a **clickable hyperlink** to a cluster, making it interactive in `SVG` output. 4 | 5 | ------ 6 | 7 | ## **Behavior** 8 | 9 | - **Affects only clusters (`subgraph cluster_X {}`)**. 10 | - **Makes the entire cluster a clickable link** in **SVG** output. 11 | - **Does not work in PNG, JPG, or other raster formats**. 12 | - **Supports absolute URLs (`https://example.com`) **. 13 | - **Alias:** `URL` (Both `href` and `URL` work the same). 14 | 15 | ------ 16 | 17 | ## **Usage in DOT** 18 | 19 | ```dot 20 | digraph G { 21 | subgraph cluster_0 { 22 | label="Clickable Cluster"; 23 | href="https://github.com/"; // Links to an external website 24 | a; b; 25 | } 26 | } 27 | ``` 28 | 29 | ### **Explanation** 30 | 31 | - **`href="https://example.com"`** → Clicking the cluster **opens an external webpage**. 32 | 33 | ------ 34 | 35 | ## **Usage in Java** 36 | 37 | ```java 38 | Cluster externalLinkCluster = Cluster.builder() 39 | .id("cluster_0") 40 | .label("Clickable Cluster") 41 | .href("https://example.com") // Links to an external website 42 | .addNode(Node.builder().id("a").build()) 43 | .addNode(Node.builder().id("b").build()) 44 | .build(); 45 | 46 | Graphviz graph = Graphviz.digraph() 47 | .cluster(externalLinkCluster) 48 | .build(); 49 | ``` -------------------------------------------------------------------------------- /docs/edge/Color.md: -------------------------------------------------------------------------------- 1 | # Color 2 | 3 | Specifies the color of the edge. The edge color can be used to highlight or distinguish edges from one another. 4 | 5 | **Usage**: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a -> b[label="Default Color"]; 12 | a -> c[label="Red Color" color=red]; 13 | } 14 | ``` 15 | 16 | Java 17 | 18 | ```dot 19 | Node a = Node.builder().id("a").build(); 20 | Node b = Node.builder().id("b").build(); 21 | Node c = Node.builder().id("c").build(); 22 | 23 | Line defaultColor = Line.builder(a, b) 24 | .label("Default Color") 25 | .build(); 26 | 27 | Line redColor = Line.builder(a, c) 28 | .label("Red Color") 29 | .color(Color.RED) 30 | .build(); 31 | 32 | Graphviz graph = Graphviz.digraph() 33 | .addLine(defaultColor) 34 | .addLine(redColor) 35 | .build(); 36 | ``` 37 | 38 | Color detail see [Color Intro](../Color Intro) -------------------------------------------------------------------------------- /docs/edge/ControlPoints.md: -------------------------------------------------------------------------------- 1 | # ControlPoints 2 | 3 | The **controlPoints** attribute allows **visualizing all routing points** along an edge. When enabled, it displays **intermediate points** used in **edge path calculation**, whether the edge is **straight or curved**. 4 | 5 | ------ 6 | 7 | ## **Behavior** 8 | 9 | - **`controlPoints = true`** → Displays all **intermediate routing points** along the edge. 10 | - **`controlPoints = false`** (default) → Only renders the **final path** without visible control points. 11 | 12 | ## Examples 13 | 14 | Dot 15 | 16 | ```dot 17 | digraph G { 18 | a -> b [label="Default Edge"]; 19 | b -> c [label="Edge with Control Points", controlPoints=true]; 20 | } 21 | ``` 22 | 23 | Java 24 | 25 | ```java 26 | Node a = Node.builder().id("a").build(); 27 | Node b = Node.builder().id("b").build(); 28 | Node c = Node.builder().id("c").build(); 29 | 30 | // Standard edge without control points 31 | Line defaultEdge = Line.builder(a, b) 32 | .label("Default Edge") 33 | .build(); 34 | 35 | // Edge with control points enabled 36 | Line controlEdge = Line.builder(b, c) 37 | .label("Edge with Control Points") 38 | .controlPoints(true) // Enables control point visualization 39 | .build(); 40 | 41 | Graphviz graph = Graphviz.digraph() 42 | .addLine(defaultEdge, controlEdge) 43 | .build(); 44 | ``` 45 | 46 | ✅ **`.controlPoints(true)`** → Enables **control point visualization** along the edge. -------------------------------------------------------------------------------- /docs/edge/FontColor.md: -------------------------------------------------------------------------------- 1 | ### **Font Color** 2 | 3 | The **font color** controls the color of the edge label. 4 | 5 | ------ 6 | 7 | ## Examples 8 | 9 | Dot 10 | 11 | ```dot 12 | digraph G { 13 | a -> b [label="Black Text", fontcolor=black]; 14 | a -> c [label="Red Text", fontcolor=red]; 15 | a -> d [label="Blue Text", fontcolor=blue]; 16 | } 17 | ``` 18 | 19 | Java 20 | 21 | ```java 22 | Node a = Node.builder().id("a").build(); 23 | Node b = Node.builder().id("b").build(); 24 | Node c = Node.builder().id("c").build(); 25 | Node d = Node.builder().id("d").build(); 26 | 27 | // Edge with black font color 28 | Line blackTextEdge = Line.builder(a, b) 29 | .label("Black Text") 30 | .fontColor(Color.BLACK) // Black text color 31 | .build(); 32 | 33 | // Edge with red font color 34 | Line redTextEdge = Line.builder(a, c) 35 | .label("Red Text") 36 | .fontColor(Color.RED) // Red text color 37 | .build(); 38 | 39 | // Edge with blue font color 40 | Line blueTextEdge = Line.builder(a, d) 41 | .label("Blue Text") 42 | .fontColor(Color.BLUE) // Blue text color 43 | .build(); 44 | 45 | Graphviz graph = Graphviz.digraph() 46 | .addLine(blackTextEdge) 47 | .addLine(redTextEdge) 48 | .addLine(blueTextEdge) 49 | .build(); 50 | ``` -------------------------------------------------------------------------------- /docs/edge/FontName.md: -------------------------------------------------------------------------------- 1 | # Font Name 2 | 3 | The **font name** controls the typeface used for edge label. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a -> b [label="Default Font"]; 12 | b -> c [label="Elephant Font", fontname="Elephant"]; 13 | c -> d [label="Impact Font", fontname="Impact"]; 14 | } 15 | ``` 16 | 17 | Java 18 | 19 | ```java 20 | Node a = Node.builder().id("a").build(); 21 | Node b = Node.builder().id("b").build(); 22 | Node c = Node.builder().id("c").build(); 23 | Node d = Node.builder().id("d").build(); 24 | 25 | // Edge with default font 26 | Line defaultFontEdge = Line.builder(a, b) 27 | .label("Default Font") // Uses the default font 28 | .build(); 29 | 30 | // Edge with "Elephant" font 31 | Line elephantFontEdge = Line.builder(b, c) 32 | .label("Elephant Font") 33 | .fontName("Elephant") // Sets font name to "Elephant" 34 | .build(); 35 | 36 | // Edge with "Impact" font 37 | Line impactFontEdge = Line.builder(c, d) 38 | .label("Impact Font") 39 | .fontName("Impact") // Sets font name to "Impact" 40 | .build(); 41 | 42 | Graphviz graph = Graphviz.digraph() 43 | .addLine(defaultFontEdge) 44 | .addLine(elephantFontEdge) 45 | .addLine(impactFontEdge) 46 | .build(); 47 | ``` -------------------------------------------------------------------------------- /docs/edge/FontSize.md: -------------------------------------------------------------------------------- 1 | # FontSize 2 | 3 | The **fontsize** attribute sets the **size of the edge label**. Larger values make the text bigger, while smaller values make it smaller. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a -> b [label="Small Text", fontsize=10]; 12 | b -> c [label="Default Text"]; // Uses the default fontsize (typically 14) 13 | c -> d [label="Large Text", fontsize=24]; 14 | } 15 | ``` 16 | 17 | - **`fontsize=10`** → Small text size. 18 | - **No `fontsize` specified** → Uses the default size (typically `14`). 19 | - **`fontsize=24`** → Large text size. 20 | 21 | Java 22 | 23 | ```java 24 | Node a = Node.builder().id("a").build(); 25 | Node b = Node.builder().id("b").build(); 26 | Node c = Node.builder().id("c").build(); 27 | Node d = Node.builder().id("d").build(); 28 | 29 | // Edge with small font size 30 | Line smallTextEdge = Line.builder(a, b) 31 | .label("Small Text") 32 | .fontSize(10) // Sets font size to 10 33 | .build(); 34 | 35 | // Edge with default font size (typically 14) 36 | Line defaultTextEdge = Line.builder(b, c) 37 | .label("Default Text") // No font size set, uses default 38 | .build(); 39 | 40 | // Edge with large font size 41 | Line largeTextEdge = Line.builder(c, d) 42 | .label("Large Text") 43 | .fontSize(24) // Sets font size to 24 44 | .build(); 45 | 46 | Graphviz graph = Graphviz.digraph() 47 | .addLine(smallTextEdge) 48 | .addLine(defaultTextEdge) 49 | .addLine(largeTextEdge) 50 | .build(); 51 | ``` 52 | -------------------------------------------------------------------------------- /docs/edge/HeadClip.md: -------------------------------------------------------------------------------- 1 | # HeadClip 2 | 3 | The **headclip** attribute controls whether an edge **clips at the boundary of the head node** (the target node) or extends **inside the node shape**. 4 | 5 | ------ 6 | 7 | ## **Behavior** 8 | 9 | - **`headclip=true` (default)** → The edge stops at the **boundary of the head node**. 10 | - **`headclip=false`** → The edge extends **inside the head node**, connecting directly to its center. 11 | 12 | ------ 13 | 14 | ## **Usage in DOT** 15 | 16 | ```dot 17 | digraph G { 18 | a -> b [label="Default (Clipped)"]; // Default behavior (headclip=true) 19 | a -> c [label="Not Clipped", headclip=false]; 20 | } 21 | ``` 22 | 23 | ### **Explanation** 24 | 25 | - **`a -> b`** → Default behavior (**headclip=true**), edge **stops at the boundary** of node `b`. 26 | - **`a -> c`** → Edge extends **inside** node `c` (**headclip=false**). 27 | 28 | ------ 29 | 30 | ## **Usage in Java** 31 | 32 | ```java 33 | Node a = Node.builder().id("a").build(); 34 | Node b = Node.builder().id("b").build(); 35 | Node c = Node.builder().id("c").build(); 36 | 37 | // Default behavior (clipped at the head node boundary) 38 | Line defaultEdge = Line.builder(a, b) 39 | .label("Default (Clipped)") 40 | .build(); 41 | 42 | // Edge extends inside the head node 43 | Line unclippedEdge = Line.builder(a, c) 44 | .label("Not Clipped") 45 | .headclip(false) // Allows the edge to extend inside the target node 46 | .build(); 47 | 48 | Graphviz graph = Graphviz.digraph() 49 | .addLine(defaultEdge) 50 | .addLine(unclippedEdge) 51 | .build(); 52 | ``` -------------------------------------------------------------------------------- /docs/edge/Href.md: -------------------------------------------------------------------------------- 1 | # Href 2 | 3 | The **href** (alias: **url**) attribute adds a **clickable hyperlink** to an edge, making it interactive in `SVG` outputs. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a -> b [label="Clickable Edge", href="https://github.com/"]; 12 | } 13 | ``` 14 | 15 | - **`href="URL"`** → Clicking the edge **opens the link** in `SVG` exports. 16 | - **Works in `svg` formats** but not in plain images (`png`, `jpg` etc). 17 | 18 | Java 19 | 20 | ```java 21 | Node a = Node.builder().id("a").build(); 22 | Node b = Node.builder().id("b").build(); 23 | 24 | Line hrefEdge = Line.builder(a, b) 25 | .label("Href Edge") 26 | .href("https://github.com/") 27 | .build(); 28 | 29 | Graphviz graph = Graphviz.digraph() 30 | .addLine(hrefEdge) 31 | .build(); 32 | ``` 33 | 34 | - **`href(String url)`** → Adds a hyperlink to the edge. 35 | - **Works in `svg` formats** but not in plain images (`png`, `jpg` etc). -------------------------------------------------------------------------------- /docs/edge/ID.md: -------------------------------------------------------------------------------- 1 | ## ID 2 | 3 | Sets a unique identifier for the edge. If not specified, it is automatically assigned during rendering. 4 | **Note**: If multiple edges share the same ID, only one will be rendered. 5 | 6 | **Usage**: 7 | 8 | Dot 9 | ```dot 10 | digraph G { 11 | // Id 'a' automatically set to node 12 | a -> b; 13 | // Explicitly specify an id 14 | c -> d[id="edge_1"]; 15 | // If two nodes id are same, only one node can be rendered. 16 | e -> f[id="edge_1"]; 17 | } 18 | ``` 19 | 20 | Java 21 | 22 | ```java 23 | // Create individual nodes 24 | Node a = Node.builder().id("a").build(); 25 | Node b = Node.builder().id("b").build(); 26 | Node c = Node.builder().id("c").build(); 27 | Node d = Node.builder().id("d").build(); 28 | Node e = Node.builder().id("e").build(); 29 | Node f = Node.builder().id("f").build(); 30 | 31 | // Create edges (lines) 32 | Line edge1 = Line.builder(c, d).id("edge_1").build(); 33 | Line edge2 = Line.builder(e, f).id("edge_1").build(); // Duplicate ID, only one edge will be rendered 34 | 35 | // Build the Graphviz graph 36 | Graphviz graphviz = Graphviz.digraph() 37 | .addLine(a, b) // Simple direct connection 38 | .addLine(edge1) // Explicitly set edge ID for c -> d 39 | .addLine(edge2) // Duplicate edge ID, one will be used 40 | .build(); 41 | ``` 42 | 43 | -------------------------------------------------------------------------------- /docs/edge/TailCilp.md: -------------------------------------------------------------------------------- 1 | # TailCilp 2 | 3 | The **tailclip** attribute controls whether an edge **clips at the boundary of the tail node** (the source node) or extends **inside the node shape**. 4 | 5 | ------ 6 | 7 | ## **Behavior** 8 | 9 | - **`tailclip=true` (default)** → The edge stops at the **boundary of the tail node**. 10 | - **`tailclip=false`** → The edge extends **inside the tail node**, connecting directly to its center. 11 | 12 | ------ 13 | 14 | ## **Usage in DOT** 15 | 16 | ```dot 17 | digraph G { 18 | a -> b [label="Default (Clipped)"]; // Default behavior (tailclip=true) 19 | c -> d [label="Not Clipped", tailclip=false]; 20 | } 21 | ``` 22 | 23 | ### **Explanation** 24 | 25 | - **`a -> b`** → Default behavior (**tailclip=true**), edge **stops at the boundary** of node `a`. 26 | - **`c -> d`** → Edge extends **inside** node `c` (**tailclip=false**). 27 | 28 | ------ 29 | 30 | ## **Usage in Java** 31 | 32 | ```java 33 | Node a = Node.builder().id("a").build(); 34 | Node b = Node.builder().id("b").build(); 35 | Node c = Node.builder().id("c").build(); 36 | Node d = Node.builder().id("d").build(); 37 | 38 | // Default behavior (clipped at the tail node boundary) 39 | Line defaultEdge = Line.builder(a, b) 40 | .label("Default (Clipped)") 41 | .build(); 42 | 43 | // Edge extends inside the tail node 44 | Line unclippedEdge = Line.builder(c, d) 45 | .label("Not Clipped") 46 | .tailclip(false) // Allows the edge to extend inside the source node 47 | .build(); 48 | 49 | Graphviz graph = Graphviz.digraph() 50 | .addLine(defaultEdge) 51 | .addLine(unclippedEdge) 52 | .build(); 53 | ``` -------------------------------------------------------------------------------- /docs/edge/Tooltip.md: -------------------------------------------------------------------------------- 1 | # Tooltip 2 | 3 | The **tooltip** attribute defines **hover text**, but it only works when the edge has an **href (clickable link)** and is rendered in **SVG format**. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a -> b [label="Clickable Edge", href="https://github.com/" tooltip="github"]; 12 | } 13 | ``` 14 | 15 | - **`tooltip="text"`** → Displays hover text **only if `href` is set**. 16 | - **Works only in SVG output.** 17 | 18 | Java 19 | 20 | ```java 21 | Node a = Node.builder().id("a").build(); 22 | Node b = Node.builder().id("b").build(); 23 | 24 | Line hrefEdge = Line.builder(a, b) 25 | .label("Href Edge") 26 | .href("https://github.com/") 27 | .tooltip("github") 28 | .build(); 29 | 30 | Graphviz graph = Graphviz.digraph() 31 | .addLine(hrefEdge) 32 | .build(); 33 | ``` 34 | 35 | - **`tooltip(String text)`** → Sets hover text, but only works if `href` is also set. 36 | - **Only works in SVG output.** -------------------------------------------------------------------------------- /docs/graph/FillColor.md: -------------------------------------------------------------------------------- 1 | # FillColor 2 | 3 | The **fillcolor** attribute sets the **background color** of the entire graph. 4 | It has an **alias `bgcolor`**, meaning **both attributes function identically**. 5 | 6 | ------ 7 | 8 | ## **Behavior** 9 | 10 | - **Affects the entire graph background color.** 11 | - **If not set, the default background is transparent.** 12 | - **Supports named colors (e.g., `lightgrey`, `blue`, `red`).** 13 | - **Supports hexadecimal colors (e.g., `#FFD700` for gold).** 14 | - **Does NOT support gradient colors.** 15 | 16 | ------ 17 | 18 | ## **Usage in DOT** 19 | 20 | ```dot 21 | digraph G { 22 | fillcolor=lightgrey; // Sets the graph background color 23 | bgcolor=lightgrey; // Same as fillcolor (alias) 24 | 25 | node [fillcolor=white]; 26 | 27 | A -> B; 28 | B -> C; 29 | } 30 | ``` 31 | 32 | ### **Explanation**: 33 | 34 | - **`fillcolor=lightgrey`** → Sets the **background color of the entire graph**. 35 | - **`bgcolor=lightgrey`** → Works **exactly the same as `fillcolor`**. 36 | - **Nodes use `fillcolor=white`** to differentiate from the background. 37 | 38 | ------ 39 | 40 | ## **Usage in Java** 41 | 42 | ```java 43 | Graphviz graph = Graphviz.digraph() 44 | .bgColor(Color.LIGHT_GREY) // Sets the background color of the graph (same as bgColor) 45 | .addNode(Node.builder().id("A").fillColor(Color.WHITE).build()) 46 | .addNode(Node.builder().id("B").fillColor(Color.WHITE).build()) 47 | .build(); 48 | ``` 49 | 50 | Color detail see [Color Intro](../Color Intro) -------------------------------------------------------------------------------- /docs/graph/FontColor.md: -------------------------------------------------------------------------------- 1 | # FontColor 2 | 3 | The **fontcolor** attribute sets the **color of text labels** for the entire **graph**. 4 | It **does not affect nodes, edges, or cluster text**, only the **graph-level label**. 5 | 6 | ------ 7 | 8 | ## **Behavior** 9 | 10 | - **Affects the color of the graph’s label text**. 11 | - **Does NOT affect node or edge labels** (use `node[fontcolor=...]` or `edge[fontcolor=...]` instead). 12 | - **Supports named colors** (e.g., `red`, `blue`, `green`). 13 | - **Supports hexadecimal colors** (e.g., `#FF4500` for orange-red). 14 | 15 | ------ 16 | 17 | ## **Usage in DOT** 18 | 19 | ```dot 20 | digraph G { 21 | label="Graph Label"; 22 | fontcolor=blue; // Sets the graph label color 23 | 24 | A -> B; 25 | B -> C; 26 | } 27 | ``` 28 | 29 | ### **Explanation**: 30 | 31 | - **`label="Graph Label"`** → Defines a **text label for the entire graph**. 32 | - **`fontcolor=blue`** → Makes the **graph label text blue**. 33 | - **Does not affect node labels** (they remain black unless specified separately). 34 | 35 | ------ 36 | 37 | ## **Usage in Java** 38 | 39 | ```java 40 | Graphviz graph = Graphviz.digraph() 41 | .label("Graph Label") 42 | .fontColor(Color.BLUE) // Sets the color of the graph label 43 | .addNode(Node.builder().id("A").fillColor(Color.WHITE).build()) 44 | .addNode(Node.builder().id("B").fillColor(Color.WHITE).build()) 45 | .build(); 46 | ``` 47 | 48 | Color detail see [Color Intro](../Color Intro) -------------------------------------------------------------------------------- /docs/graph/FontSize.md: -------------------------------------------------------------------------------- 1 | # **Fontsize** 2 | 3 | The **fontsize** attribute controls the **default font size** for the entire graph, including the **graph title (label)**. It sets the base text size for graph-related labels. 4 | 5 | ------ 6 | 7 | ## **Usage in DOT** 8 | 9 | ### **Increase Font Size for Graph Title** 10 | 11 | ```dot 12 | digraph G { 13 | fontsize=24; // Sets title font size to 24 pt 14 | label="Large Graph Title"; 15 | a -> b; 16 | } 17 | ``` 18 | 19 | ------ 20 | 21 | ## **Usage in Java** 22 | 23 | ### **Increase Font Size for Graph Title** 24 | 25 | ```java 26 | Node a = Node.builder().label("a").build(); 27 | Node b = Node.builder().label("b").build(); 28 | 29 | Graphviz graph = Graphviz.digraph() 30 | .fontSize(24) // Sets title font size 31 | .label("Large Graph Title") 32 | .addLine(a, b) 33 | .build(); 34 | ``` 35 | 36 | -------------------------------------------------------------------------------- /docs/graph/Href.md: -------------------------------------------------------------------------------- 1 | # **Href** 2 | 3 | The **href** attribute (alias: **url**) adds a **clickable hyperlink** to the entire graph, making the graph title interactive in `SVG` outputs. 4 | 5 | ------ 6 | 7 | ## **Examples** 8 | 9 | ### **DOT Syntax** 10 | 11 | ```dot 12 | digraph G { 13 | href="https://github.com/"; // Clickable graph link 14 | label="Clickable Graph"; 15 | a 16 | } 17 | ``` 18 | 19 | ------ 20 | 21 | ### **Java Usage** 22 | 23 | ```java 24 | Node a = Node.builder().label("a").build(); 25 | 26 | Graphviz graph = Graphviz.digraph() 27 | .label("Clickable Graph") 28 | .href("https://github.com/") // Set hyperlink 29 | .addNode(a) 30 | .build(); 31 | ``` -------------------------------------------------------------------------------- /docs/graph/K.md: -------------------------------------------------------------------------------- 1 | # **K ** 2 | 3 | The **k** attribute sets the **spring constant** for force-directed layouts, specifically **FDP, JFDP, and GFDP**. It controls the "stiffness" of the virtual springs that determine node spacing. 4 | 5 | ------ 6 | 7 | ## **Usage in DOT** 8 | 9 | ```dot 10 | graph G { 11 | layout=fdp; 12 | K=2.0; // Stronger springs pull nodes closer 13 | 14 | a -- b; 15 | b -- c; 16 | c -- d; 17 | } 18 | ``` 19 | 20 | ------ 21 | 22 | ## **Usage in Java** 23 | 24 | ```java 25 | Node a = Node.builder().label("a").build(); 26 | Node b = Node.builder().label("b").build(); 27 | Node c = Node.builder().label("c").build(); 28 | 29 | Graphviz graph = Graphviz.graph() 30 | .layout(Layout.FDP) // Use FDP layout 31 | .k(2.0) // Stronger springs pull nodes closer 32 | .addLine(a, b, c) 33 | .build(); 34 | ``` 35 | 36 | -------------------------------------------------------------------------------- /docs/graph/Margin.md: -------------------------------------------------------------------------------- 1 | # Margin 2 | 3 | The **margin** attribute controls the **padding around the graph drawing area**. It defines the extra space between the **graph content** and the **bounding box**. 4 | 5 | ------ 6 | 7 | ## **Usage in DOT** 8 | 9 | ### **Set Uniform Margin Around Graph** 10 | 11 | ```dot 12 | digraph G { 13 | margin=0.5; // Adds 0.5-inch padding around the graph 14 | a -> b; 15 | b -> c; 16 | } 17 | ``` 18 | 19 | ------ 20 | 21 | ## **Usage in Java** 22 | 23 | ### **Set Uniform Margin Around Graph** 24 | 25 | ```java 26 | Node a = Node.builder().label("a").build(); 27 | Node b = Node.builder().label("b").build(); 28 | Node c = Node.builder().label("c").build(); 29 | 30 | Graphviz graph = Graphviz.digraph() 31 | .margin(0.5) // Adds 0.5-inch padding around the graph 32 | .addLine(a, b) 33 | .addLine(b, c) 34 | .build(); 35 | ``` -------------------------------------------------------------------------------- /docs/graph/Nodesep.md: -------------------------------------------------------------------------------- 1 | # Nodesep 2 | 3 | The **nodesep** attribute **controls the minimum spacing between adjacent nodes** in the **same rank (horizontal or vertical distance)** depending on the `rankdir` setting. 4 | 5 | ------ 6 | 7 | ## **Behavior** 8 | 9 | - **Defines the minimum space between nodes in the same rank (row or column).** 10 | - **Higher values increase spacing, making graphs more spread out.** 11 | - **Smaller values reduce spacing, making graphs more compact.** 12 | - **Only applies to `DOT` layout** (ignored in `FDP`, `GFDP`, `JFDP`, etc.).** 13 | 14 | ------ 15 | 16 | ## **Usage in DOT** 17 | 18 | ```dot 19 | digraph G { 20 | nodesep=0.8; // Increase spacing between nodes in the same rank 21 | 22 | A -> B; 23 | A -> C; 24 | A -> D; 25 | } 26 | ``` 27 | 28 | ------ 29 | 30 | ## **Usage in Java** 31 | 32 | ```java 33 | // Define nodes 34 | Node a = Node.builder().label("a").build(); 35 | Node b = Node.builder().label("b").build(); 36 | Node c = Node.builder().label("c").build(); 37 | Node d = Node.builder().label("d").build(); 38 | 39 | Graphviz graph = Graphviz.digraph() 40 | .nodeSep(0.8) // Increase spacing between nodes in the same rank 41 | .addLine(Line.builder(a, b).build()) 42 | .addLine(Line.builder(a, c).build()) 43 | .addLine(Line.builder(a, d).build()) 44 | .build(); 45 | ``` -------------------------------------------------------------------------------- /docs/graph/Overlap.md: -------------------------------------------------------------------------------- 1 | # **Overlap** 2 | 3 | The **overlap** attribute controls whether and how **node overlaps** are removed in **force-directed layout**. It helps improve **graph readability** by adjusting node positions to avoid overlap. 4 | 5 | ------ 6 | 7 | ## **Usage in DOT** 8 | 9 | ### **Allow Node Overlap (Default in Some Layouts)** 10 | 11 | ```dot 12 | graph { 13 | layout=fdp 14 | overlap=true 15 | maxiter=1 16 | a -- b; 17 | b -- c; 18 | c -- d; 19 | d -- e; 20 | e -- f; 21 | a -- f; 22 | a -- c; 23 | a -- d; 24 | a -- e; 25 | b -- d; 26 | b -- e; 27 | b -- f; 28 | c -- e; 29 | c -- f; 30 | d -- f; 31 | } 32 | ``` 33 | 34 | ------ 35 | 36 | ## **Usage in Java** 37 | 38 | ### **Allow Node Overlap (Default in Some Layouts)** 39 | 40 | ```java 41 | Node a = Node.builder().label("a").build(); 42 | Node b = Node.builder().label("b").build(); 43 | Node c = Node.builder().label("c").build(); 44 | 45 | Graphviz graph = Graphviz.graph() 46 | .layout(Layout.FDP) // Use FDP layout 47 | .overlap(true) // Stronger springs pull nodes closer 48 | .maxiter(1) 49 | .addLine(a, b, c) 50 | .build(); 51 | ``` 52 | 53 | -------------------------------------------------------------------------------- /docs/graph/Showgrid.md: -------------------------------------------------------------------------------- 1 | # Showgrid 2 | 3 | The **showgrid** attribute controls the **visibility of the grid used in the orthogonal spline routing algorithm**. This grid helps in edge routing by aligning edges to a structured orthogonal layout. 4 | 5 | ------ 6 | 7 | ## **Usage in DOT** 8 | 9 | ### **Enable Grid Display** 10 | 11 | ```dot 12 | digraph G { 13 | splines=ortho 14 | showgrid=true; // Enables grid for orthogonal edge routing 15 | a -> b; 16 | a -> c; 17 | } 18 | ``` 19 | 20 | ------ 21 | 22 | ## **Usage in Java** 23 | 24 | ### **Enable Grid Display** 25 | 26 | ```java 27 | Node a = Node.builder().label("a").build(); 28 | Node b = Node.builder().label("b").build(); 29 | Node c = Node.builder().label("c").build(); 30 | 31 | Graphviz graph = Graphviz.digraph() 32 | .splines(Splines.ORTHO) 33 | .showGrid(true) // Enables grid for orthogonal edge routing 34 | .addLine(a, b) 35 | .addLine(a, c) 36 | .build(); 37 | ``` -------------------------------------------------------------------------------- /docs/graph/Size.md: -------------------------------------------------------------------------------- 1 | # Size 2 | 3 | The **size** attribute controls the **overall bounding box size** of the graph layout. It limits the **width and height** of the rendered graph. 4 | 5 | ## **Usage in DOT** 6 | 7 | ### **Limit Graph to 5×3 Inches** 8 | 9 | ```dot 10 | digraph G { 11 | size="5,3"; // Sets maximum width to 5 inches and height to 3 inches 12 | a -> b; 13 | b -> c; 14 | } 15 | ``` 16 | 17 | ------ 18 | 19 | ## **Usage in Java** 20 | 21 | ```java 22 | Node a = Node.builder().label("a").build(); 23 | Node b = Node.builder().label("b").build(); 24 | Node c = Node.builder().label("c").build(); 25 | 26 | Graphviz graph = Graphviz.digraph() 27 | .scale(5, 3) // Sets maximum width to 5 inches and height to 3 inches 28 | .addLine(a, b) 29 | .addLine(b, c) 30 | .build(); 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /docs/graph/Tooltip.md: -------------------------------------------------------------------------------- 1 | # **Tooltip** 2 | 3 | The **tooltip** attribute defines **hover text** for the entire graph, but it only works when the graph has an **href (clickable link)** and is rendered in **SVG format**. 4 | 5 | ------ 6 | 7 | ## **Examples** 8 | 9 | ### **DOT Syntax** 10 | 11 | ```dot 12 | digraph G { 13 | href="https://github.com/"; // Tooltip requires href 14 | tooltip="This is a graph tooltip"; // Hover text for the graph 15 | label="Hover Over Me"; 16 | 17 | subgraph cluster_0 { 18 | label="Subgraph"; 19 | a -> b; 20 | } 21 | } 22 | ``` 23 | 24 | ------ 25 | 26 | ### **Java Usage** 27 | 28 | ```java 29 | Node a = Node.builder().label("a").build(); 30 | 31 | Graphviz graph = Graphviz.digraph() 32 | .href("https://example.com") // Tooltip requires href 33 | .tooltip("This is a graph tooltip") // Set hover text 34 | .label("Hover Over Me") 35 | .addNode(a) 36 | .build(); 37 | ``` -------------------------------------------------------------------------------- /docs/images/node_record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/docs/images/node_record.png -------------------------------------------------------------------------------- /docs/images/node_shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/docs/images/node_shape.png -------------------------------------------------------------------------------- /docs/images/node_style.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/docs/images/node_style.png -------------------------------------------------------------------------------- /docs/node/Color.md: -------------------------------------------------------------------------------- 1 | # Color 2 | 3 | Specifies the border color of the node. The node color can be used to highlight or distinguish nodes from one another. 4 | 5 | **Usage**: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a [color=red]; 12 | } 13 | ``` 14 | 15 | Java 16 | 17 | ```dot 18 | Node node = Node.builder() 19 | .color(Color.RED) 20 | .build(); 21 | ``` 22 | 23 | Color detail see [Color Intro](../Color Intro) -------------------------------------------------------------------------------- /docs/node/FillColor.md: -------------------------------------------------------------------------------- 1 | # **Fill Color** 2 | 3 | **Fill color** controls the background color of a node. The `fillcolor` attribute has an alias, `bgcolor`, so `a[fillcolor=red]` is equivalent to `b[bgcolor=red]`. 4 | 5 | ### **Example:** 6 | 7 | #### DOT Example 8 | 9 | ```dot 10 | digraph G { 11 | a [label="Filled Node 1", bgcolor=yellow]; 12 | b [label="Filled Node 2", fillcolor=green]; 13 | } 14 | ``` 15 | 16 | #### Java Example 17 | 18 | ```java 19 | Node node1 = Node.builder() 20 | .label("Filled Node 1") 21 | .fillColor(Color.YELLOW) // Fill with yellow 22 | .build(); 23 | ``` 24 | 25 | Color detail see [Color Intro](../Color Intro) -------------------------------------------------------------------------------- /docs/node/FontColor.md: -------------------------------------------------------------------------------- 1 | ### **Font Color** 2 | 3 | The **font color** controls the color of the text inside a node. 4 | 5 | ------ 6 | 7 | ## Examples 8 | 9 | Dot 10 | 11 | ```dot 12 | digraph G { 13 | a [label="Black Text", fontcolor=black]; 14 | b [label="Red Text", fontcolor=red]; 15 | c [label="Blue Text", fontcolor=blue]; 16 | } 17 | ``` 18 | 19 | Java 20 | 21 | ```java 22 | Node node1 = Node.builder() 23 | .label("Black Text") 24 | .fontColor(Color.BLACK) // Set text color to black 25 | .build(); 26 | 27 | Node node2 = Node.builder() 28 | .label("Red Text") 29 | .fontColor(Color.RED) // Set text color to red 30 | .build(); 31 | 32 | Node node3 = Node.builder() 33 | .label("Blue Text") 34 | .fontColor(Color.BLUE) // Set text color to blue 35 | .build(); 36 | ``` -------------------------------------------------------------------------------- /docs/node/FontName.md: -------------------------------------------------------------------------------- 1 | # Font Name 2 | 3 | The **font name** controls the typeface used for text inside a node. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a [label="Default Font"]; 12 | b [label="Elephant Font", fontname="Elephant"]; 13 | c [label="Impact Font", fontname="Impact"]; 14 | } 15 | ``` 16 | 17 | Java 18 | 19 | ```java 20 | Node node1 = Node.builder() 21 | .label("Default Font") 22 | .build(); 23 | 24 | Node node2 = Node.builder() 25 | .label("Elephant Font") 26 | .fontName("Elephant") 27 | .build(); 28 | 29 | Node node3 = Node.builder() 30 | .label("Impact Font") 31 | .fontName("Impact") 32 | .fontColor(Color.BLUE) 33 | .build(); 34 | ``` -------------------------------------------------------------------------------- /docs/node/FontSize.md: -------------------------------------------------------------------------------- 1 | # FontSize 2 | 3 | The **fontsize** attribute sets the **size of the text inside a node**. Larger values make the text bigger, while smaller values make it smaller. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a [label="Small Text", fontsize=10]; 12 | b [label="Default Text"]; // Uses the default fontsize (typically 14) 13 | c [label="Large Text", fontsize=24]; 14 | } 15 | ``` 16 | 17 | - **`fontsize=10`** → Small text size. 18 | - **No `fontsize` specified** → Uses the default size (typically `14`). 19 | - **`fontsize=24`** → Large text size. 20 | 21 | Java 22 | 23 | ```java 24 | Node smallText = Node.builder() 25 | .label("Small Text") 26 | .fontSize(10) // Set font size to 10 27 | .build(); 28 | 29 | Node defaultText = Node.builder() 30 | .label("Default Text") // Uses default font size (typically 14) 31 | .build(); 32 | 33 | Node largeText = Node.builder() 34 | .label("Large Text") 35 | .fontSize(24) // Set font size to 24 36 | .build(); 37 | ``` 38 | 39 | - **`fontSize(int size)`** → Sets the text size in points (pt). 40 | - **If `fontSize` is not set, the default is used (typically 14pt).** -------------------------------------------------------------------------------- /docs/node/Href.md: -------------------------------------------------------------------------------- 1 | # Href 2 | 3 | The **href** attribute (alias: **url**) adds a **clickable hyperlink** to a node, making it interactive in `SVG` outputs. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a [label="Clickable Node", href="https://example.com"]; 12 | } 13 | ``` 14 | 15 | - **`href="URL"`** → Clicking the node **opens the link** in `SVG` exports. 16 | - **Works in `svg` formats** but not in plain images (`png`, `jpg` etc). 17 | 18 | Java 19 | 20 | ```java 21 | Node clickableNode = Node.builder() 22 | .label("Clickable Node") 23 | .href("https://example.com") // Set hyperlink 24 | .build(); 25 | ``` 26 | 27 | - **`href(String url)`** → Adds a hyperlink to the node. 28 | - **Works in `svg` formats** but not in plain images (`png`, `jpg` etc). -------------------------------------------------------------------------------- /docs/node/ID.md: -------------------------------------------------------------------------------- 1 | ## ID 2 | 3 | Sets a unique identifier for the node. If not specified, it is automatically assigned during rendering. 4 | **Note**: If multiple nodes share the same ID, only one will be rendered. 5 | 6 | **Usage**: 7 | 8 | Dot 9 | ```dot 10 | digraph G { 11 | // Id 'a' automatically set to node 12 | a; 13 | // Explicitly specify an id 14 | b[id="node_b"]; 15 | // If two nodes id are same, only one node can be rendered. 16 | B[id="node_b"]; 17 | } 18 | ``` 19 | 20 | Java 21 | 22 | ```java 23 | Node A = Node.builder().id("node_a").build(); 24 | // If two nodes id are same, only one node can be rendered. 25 | Node a = Node.builder().id("node_A").build(); 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /docs/node/Image.md: -------------------------------------------------------------------------------- 1 | ## Image 2 | 3 | The **image** attribute allows setting an **image** as the node’s content. The image can be **a local file** (using the `file://` format) or **a URL** (`http://` or `https://`). 4 | 5 | See here check [Image Security Warning](../Image Security Warning.md) 6 | 7 | ## Examples: 8 | 9 | Dot 10 | 11 | ```dot 12 | digraph G { 13 | a [label="Local Image", shape=box, image="file:///absolute/path/to/image.png"]; 14 | b [label="Online Image", shape=box, image="https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png"]; 15 | } 16 | ``` 17 | 18 | - **`image="file:///absolute/path/to/image.png"`** → Uses a **local image file** with an absolute file path. 19 | - **`image="https://example.com/image.png"`** → Loads an **image from a URL**. 20 | - **`shape=box`** (or another non-record shape) is required for images to be displayed properly. 21 | 22 | Java 23 | 24 | ```java 25 | Node localImageNode = Node.builder() 26 | .label("Local Image") 27 | .shape(NodeShapeEnum.BOX) // Required for proper image rendering 28 | .image("file:///absolute/path/to/image.png") // Local file with file:// format 29 | .build(); 30 | 31 | Node urlImageNode = Node.builder() 32 | .label("URL Image") 33 | .shape(NodeShapeEnum.BOX) // Required for proper image rendering 34 | .image("https://example.com/image.png") // Image from URL 35 | .build(); 36 | 37 | Graphviz graph = Graphviz.digraph() 38 | .addNode(localImageNode, urlImageNode) 39 | .build(); 40 | ``` 41 | 42 | - **`image("file:///absolute/path/to/image.png")`** → Loads an image from a **local file** using `file://`. 43 | - **`image("https://example.com/image.png")`** → Loads an image from **an online source**. 44 | - **Requires `shape=box` (or similar) to display properly.** -------------------------------------------------------------------------------- /docs/node/ImageSize.md: -------------------------------------------------------------------------------- 1 | # ImageSize 2 | 3 | The **imageWidth** and **imageHeight** attributes control the **display size** of an image inside a node. These attributes are only effective when an **image is set** using the `image` attribute. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a [label="Scaled Image", 12 | image="https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png", imageWidth=0.5, imageHeight=3]; 13 | 14 | b [label="Default Size", 15 | image="https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png"]; 16 | } 17 | ``` 18 | 19 | - **`imageWidth=0.5`** → Sets the image width relative to the node size. 20 | - **`imageHeight=3`** → Sets the image height relative to the node size. 21 | - **If `imageWidth` or `imageHeight` is not set**, the image scales automatically based on its original size. 22 | 23 | Java 24 | 25 | ```java 26 | Node scaledImageNode = Node.builder() 27 | .label("Scaled Image") 28 | .image("https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png") 29 | .imageSize(0.5, 3.0) 30 | .build(); 31 | 32 | Node defaultImageNode = Node.builder() 33 | .label("Default Size") 34 | .image("https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png") 35 | .build(); 36 | ``` 37 | 38 | - **`imageWidth(double width)`** → Defines the **relative width** of the image inside the node. 39 | - **`imageHeight(double height)`** → Defines the **relative height** of the image inside the node. 40 | - **If `imageWidth` or `imageHeight` is not specified**, the image keeps its default size **relative to the node size**. 41 | 42 | -------------------------------------------------------------------------------- /docs/node/Labeljust.md: -------------------------------------------------------------------------------- 1 | # LabelJust (Label Justification) 2 | 3 | The **labeljust** attribute controls the **horizontal alignment of the label relative to the node container**. By default, the label is **centered** within the node. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | node[shape=box, margin="2,0.5"] 12 | a [label="Left Aligned", labeljust=l]; 13 | b [label="Centered Aligned", labeljust=c]; 14 | c [label="Right Aligned", labeljust=r]; 15 | } 16 | ``` 17 | 18 | - **`labeljust=l`** → Aligns text to the **left**. 19 | - **`labeljust=c`** → Centers the text (**default**). 20 | - **`labeljust=r`** → Aligns text to the **right**. 21 | 22 | Java 23 | 24 | ```java 25 | Node leftAligned = Node.builder() 26 | .label("Left Aligned") 27 | .shape(NodeShapeEnum.BOX) 28 | .labeljust(Labeljust.LEFT) // Align text to the left 29 | .margin(2, 0.5) 30 | .build(); 31 | 32 | Node centered = Node.builder() 33 | .label("Centered Aligned") 34 | .shape(NodeShapeEnum.BOX) 35 | .labeljust(Labeljust.CENTER) // Centered text (default) 36 | .margin(2, 0.5) 37 | .build(); 38 | 39 | Node rightAligned = Node.builder() 40 | .label("Right Aligned") 41 | .shape(NodeShapeEnum.BOX) 42 | .labeljust(Labeljust.RIGHT) // Align text to the right 43 | .margin(2, 0.5) 44 | .build(); 45 | ``` 46 | 47 | - **`labelJust(LabelJust.LEFT)`** → Left-aligns text. 48 | - **`labelJust(LabelJust.CENTER)`** → Centers text (default). 49 | - **`labelJust(LabelJust.RIGHT)`** → Right-aligns text. -------------------------------------------------------------------------------- /docs/node/Labelloc.md: -------------------------------------------------------------------------------- 1 | # LabelLoc (Label Vertical Alignment) 2 | 3 | The **labelloc** attribute controls the **vertical alignment** of a node’s label within the node container. By default, the label is positioned **in the center** of the node. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | node[shape=box, margin="0.5,1"] 12 | a [label="Top Label", labelloc=t]; // Align label to the top 13 | b [label="Centered Label\n(Default)", labelloc=c]; // Default center alignment 14 | c [label="Bottom Label", labelloc=b]; // Align label to the bottom 15 | } 16 | ``` 17 | 18 | - **`labelloc=t`** → Positions the label at the **top** of the node. 19 | - **`labelloc=c`** → Centers the label (**default**). 20 | - **`labelloc=b`** → Positions the label at the **bottom** of the node. 21 | 22 | Java 23 | 24 | ```java 25 | Node topLabel = Node.builder() 26 | .label("Top Label") 27 | .shape(NodeShapeEnum.BOX) 28 | .labelloc(Labelloc.TOP) // Align label to the top 29 | .margin(0.5, 1) 30 | .build(); 31 | 32 | Node centerLabel = Node.builder() 33 | .label("Centered Label\n(Default)") 34 | .shape(NodeShapeEnum.BOX) 35 | .labelloc(Labelloc.CENTER) // Default: Centered label 36 | .margin(0.5, 1) 37 | .build(); 38 | 39 | Node bottomLabel = Node.builder() 40 | .label("Bottom Label") 41 | .shape(NodeShapeEnum.BOX) 42 | .labelloc(Labelloc.BOTTOM) // Align label to the bottom 43 | .margin(0.5, 1) 44 | .build(); 45 | ``` 46 | 47 | - **`labelLoc(LabelLoc.TOP)`** → Aligns the label to the **top**. 48 | - **`labelLoc(LabelLoc.CENTER)`** → Keeps the label **centered** (**default**). 49 | - **`labelLoc(LabelLoc.BOTTOM)`** → Aligns the label to the **bottom**. -------------------------------------------------------------------------------- /docs/node/Margin.md: -------------------------------------------------------------------------------- 1 | # Node Margin 2 | 3 | The **margin** attribute defines the **horizontal and vertical padding** inside a node, controlling the space between the label and the node boundary. It supports **two values**: 4 | 5 | - **`margin="width, height"`** → Sets different padding for width and height. 6 | - **`margin="value"`** → Sets uniform padding for both width and height. 7 | 8 | ## Examples: 9 | 10 | Dot 11 | 12 | ```dot 13 | digraph G { 14 | a [label="Uniform Margin", shape=box, margin=1]; // Same margin for width and height 15 | b [label="Different Margins", shape=box, margin="2,0.5"]; // 2 for width, 0.5 for height 16 | } 17 | ``` 18 | 19 | - **`margin=1`** → Both width and height have a margin of `1`. 20 | - **`margin="2,0.5"`** → `2` for width (horizontal padding), `0.5` for height (vertical padding). 21 | 22 | Java 23 | 24 | ```java 25 | Node uniformMargin = Node.builder() 26 | .label("Uniform Margin") 27 | .shape(NodeShapeEnum.BOX) 28 | .margin(1) // Same margin for width and height 29 | .build(); 30 | 31 | Node differentMargins = Node.builder() 32 | .label("Different Margins") 33 | .shape(NodeShapeEnum.BOX) 34 | .margin(2.0, 0.5) // 2.0 for width, 0.5 for height 35 | .build(); 36 | ``` 37 | 38 | - **`margin(double value)`** → Sets uniform padding for width and height. 39 | - **`margin(double width, double height)`** → Sets **different** padding for width and height. -------------------------------------------------------------------------------- /docs/node/PenWidth.md: -------------------------------------------------------------------------------- 1 | # PenWidth 2 | 3 | The **penwidth** attribute controls the **thickness of the node's border**. A higher value makes the border **thicker**, while a lower value makes it **thinner**. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a [label="Thin Border", shape=box, penwidth=1]; // Default thickness 12 | b [label="Thick Border", shape=box, penwidth=3]; // Thicker border 13 | c [label="Extra Thick Border", shape=box, penwidth=5]; // Very thick border 14 | } 15 | ``` 16 | 17 | - **`penwidth=1`** → Default border thickness. 18 | - **`penwidth=3`** → Thicker border for emphasis. 19 | - **`penwidth=5`** → Extra thick border for highlighting important nodes. 20 | 21 | Java 22 | 23 | ```java 24 | Node thinBorder = Node.builder() 25 | .label("Thin Border") 26 | .shape(NodeShapeEnum.BOX) 27 | .penWidth(1) // Default thickness 28 | .build(); 29 | 30 | Node thickBorder = Node.builder() 31 | .label("Thick Border") 32 | .shape(NodeShapeEnum.BOX) 33 | .penWidth(3) // Thicker border 34 | .build(); 35 | 36 | Node extraThickBorder = Node.builder() 37 | .label("Extra Thick Border") 38 | .shape(NodeShapeEnum.BOX) 39 | .penWidth(5) // Very thick border 40 | .build(); 41 | ``` 42 | 43 | - **`penWidth(double width)`** → Sets the border thickness of the node. 44 | - **Larger values create bolder borders, improving visibility.** 45 | 46 | -------------------------------------------------------------------------------- /docs/node/Sides.md: -------------------------------------------------------------------------------- 1 | # Sides 2 | 3 | The **sides** attribute defines the **number of edges for `regular_polyline` shapes**. It allows the creation of polygonal nodes, but the **minimum supported value is 4**, meaning it cannot create triangles. (**Maximum supported value is 20**) 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a [label="Square (4 Sides)", shape=regular_polyline, sides=4]; 12 | b [label="Pentagon (5 Sides)", shape=regular_polyline, sides=5]; 13 | c [label="Hexagon (6 Sides)", shape=regular_polyline, sides=6]; 14 | } 15 | ``` 16 | 17 | - **`sides=4`** → Creates a **square** (minimum supported value). 18 | - **`sides=5`** → Creates a **pentagon**. 19 | - **`sides=6`** → Creates a **hexagon**. 20 | 21 | Java 22 | 23 | ```java 24 | Node square = Node.builder() 25 | .label("Square (4 Sides)") 26 | .shape(NodeShapeEnum.REGULAR_POLYLINE) // Use regular polyline shape 27 | .sides(4) // 4 sides = Square (Minimum value) 28 | .build(); 29 | 30 | Node pentagon = Node.builder() 31 | .label("Pentagon (5 Sides)") 32 | .shape(NodeShapeEnum.REGULAR_POLYLINE) 33 | .sides(5) // 5 sides = Pentagon 34 | .build(); 35 | 36 | Node hexagon = Node.builder() 37 | .label("Hexagon (6 Sides)") 38 | .shape(NodeShapeEnum.REGULAR_POLYLINE) 39 | .sides(6) // 6 sides = Hexagon 40 | .build(); 41 | ``` 42 | 43 | - **`sides(int n)`** → Defines the number of sides for `regular_polyline` shapes. 44 | - **Minimum supported value is `4` (no triangles).** 45 | - **Higher values (`sides=8, sides=12, etc.`) create more circular-like polygons.** -------------------------------------------------------------------------------- /docs/node/Size.md: -------------------------------------------------------------------------------- 1 | ## Size 2 | 3 | ## **Height** 4 | 5 | Sets the height of the node. The height setting takes effect in the following situations: 6 | 7 | - When **`fixedsize` is `true`**, the actual height of the node is exactly equal to the set value. 8 | - When **`fixedsize` is `false`**, this height serves as the minimum limit. The actual height will be at least the specified value, but may increase based on content or shape. 9 | - If no height is manually set, the height will be automatically determined based on the node's content and shape during rendering. 10 | 11 | **Usage**: 12 | 13 | Dot 14 | 15 | ```dot 16 | digraph G { 17 | node [shape=box, height=3.0]; 18 | a; 19 | b [height=2.5]; 20 | } 21 | ``` 22 | 23 | Java 24 | 25 | ```java 26 | Node node = Node.builder() 27 | .height(3.0) 28 | .build(); 29 | ``` 30 | 31 | ------ 32 | 33 | ## **Width** 34 | 35 | Sets the width of the node. The width setting takes effect in the following situations: 36 | 37 | - When **`fixedsize` is `true`**, the actual width of the node will be exactly equal to the set value. 38 | - When **`fixedsize` is `false`**, this width serves as the minimum width. The actual width will be at least the specified value, but may increase based on the content and shape. 39 | - If no width is manually set, the width will be automatically determined based on the node's content and shape during rendering. 40 | 41 | **Usage**: 42 | 43 | Dot 44 | 45 | ```dot 46 | digraph G { 47 | node [shape=ellipse, width=2.5]; 48 | a; 49 | b [width=2.0]; 50 | }. 51 | ``` 52 | 53 | Java 54 | 55 | ```java 56 | Node node = Node.builder() 57 | .width(2.5) 58 | .build(); 59 | ``` 60 | 61 | -------------------------------------------------------------------------------- /docs/node/Tooltip.md: -------------------------------------------------------------------------------- 1 | # Tooltip 2 | 3 | The **tooltip** attribute defines **hover text**, but it only works when the node has an **href (clickable link)** and is rendered in **SVG format**. 4 | 5 | ## Examples: 6 | 7 | Dot 8 | 9 | ```dot 10 | digraph G { 11 | a [label="Hover Me", href="https://example.com", tooltip="This is a tooltip"]; 12 | b [label="No Tooltip", tooltip="This won't work"]; // Tooltip ignored (no href) 13 | } 14 | ``` 15 | 16 | - **`tooltip="text"`** → Displays hover text **only if `href` is set**. 17 | - **Works only in SVG output.** 18 | 19 | Java 20 | 21 | ```java 22 | Node tooltipNode = Node.builder() 23 | .label("Hover Me") 24 | .href("https://example.com") // Tooltip requires href 25 | .tooltip("This is a tooltip") // Set hover text 26 | .build(); 27 | 28 | Node noTooltipNode = Node.builder() 29 | .label("No Tooltip") 30 | .tooltip("This won't work") // Tooltip ignored (no href) 31 | .build(); 32 | ``` 33 | 34 | - **`tooltip(String text)`** → Sets hover text, but only works if `href` is also set. 35 | - **Only works in SVG output.** -------------------------------------------------------------------------------- /dot/src/main/java/org/graphper/parser/ParseException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The graph-support project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.graphper.parser; 17 | 18 | /** 19 | * A custom unchecked exception indicating a parsing error in DOT or HTML-like inputs. 20 | * 21 | * @author johannes 22 | */ 23 | public class ParseException extends RuntimeException { 24 | 25 | private static final long serialVersionUID = 6494880405240898272L; 26 | 27 | public ParseException(String message) { 28 | 29 | super(message); 30 | } 31 | 32 | public ParseException(String message, Throwable cause) { 33 | 34 | super(message, cause); 35 | } 36 | 37 | public ParseException(Throwable cause) { 38 | 39 | super(cause); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dot/src/main/java/org/graphper/parser/grammar/DOTLexer.tokens: -------------------------------------------------------------------------------- 1 | STRICT=1 2 | GRAPH=2 3 | DIGRAPH=3 4 | NODE=4 5 | EDGE=5 6 | SUBGRAPH=6 7 | TABLE=7 8 | TR=8 9 | TD=9 10 | NUMBER=10 11 | STRING=11 12 | HTML_STRING=12 13 | ID=13 14 | COMMENT=14 15 | LINE_COMMENT=15 16 | PREPROC=16 17 | WS=17 18 | LB=18 19 | RB=19 20 | LSB=20 21 | RSB=21 22 | COLON=22 23 | SEMI_COLON=23 24 | COMMA=24 25 | EQUAL=25 26 | SLASH=26 27 | DA=27 28 | UDA=28 29 | '{'=18 30 | '}'=19 31 | '['=20 32 | ']'=21 33 | ':'=22 34 | ';'=23 35 | ','=24 36 | '='=25 37 | '/'=26 38 | '->'=27 39 | '--'=28 40 | -------------------------------------------------------------------------------- /dot/src/main/java/org/graphper/parser/grammar/DOTParser.tokens: -------------------------------------------------------------------------------- 1 | STRICT=1 2 | GRAPH=2 3 | DIGRAPH=3 4 | NODE=4 5 | EDGE=5 6 | SUBGRAPH=6 7 | TABLE=7 8 | TR=8 9 | TD=9 10 | NUMBER=10 11 | STRING=11 12 | HTML_STRING=12 13 | ID=13 14 | COMMENT=14 15 | LINE_COMMENT=15 16 | PREPROC=16 17 | WS=17 18 | LB=18 19 | RB=19 20 | LSB=20 21 | RSB=21 22 | COLON=22 23 | SEMI_COLON=23 24 | COMMA=24 25 | EQUAL=25 26 | SLASH=26 27 | DA=27 28 | UDA=28 29 | '{'=18 30 | '}'=19 31 | '['=20 32 | ']'=21 33 | ':'=22 34 | ';'=23 35 | ','=24 36 | '='=25 37 | '/'=26 38 | '->'=27 39 | '--'=28 40 | -------------------------------------------------------------------------------- /dot/src/main/java/org/graphper/parser/grammar/HTMLLexer.tokens: -------------------------------------------------------------------------------- 1 | HTML_COMMENT=1 2 | HTML_CONDITIONAL_COMMENT=2 3 | WS=3 4 | TAG_OPEN=4 5 | HTML_TEXT=5 6 | TABLE=6 7 | TR=7 8 | TD=8 9 | FONT=9 10 | B=10 11 | I=11 12 | U=12 13 | S=13 14 | O=14 15 | SUB=15 16 | SUP=16 17 | BR=17 18 | VT=18 19 | VB=19 20 | VC=20 21 | HL=21 22 | HR=22 23 | HC=23 24 | COMMA=24 25 | SEMI_COLON=25 26 | TAG_CLOSE=26 27 | TAG_SLASH_CLOSE=27 28 | TAG_SLASH=28 29 | TAG_EQUALS=29 30 | TAG_NAME=30 31 | TAG_WHITESPACE=31 32 | ATTVALUE_VALUE=32 33 | ATTRIBUTE=33 34 | '<'=4 35 | ','=24 36 | ';'=25 37 | '>'=26 38 | '/>'=27 39 | '/'=28 40 | '='=29 41 | -------------------------------------------------------------------------------- /dot/src/main/java/org/graphper/parser/grammar/HTMLParser.tokens: -------------------------------------------------------------------------------- 1 | HTML_COMMENT=1 2 | HTML_CONDITIONAL_COMMENT=2 3 | WS=3 4 | TAG_OPEN=4 5 | HTML_TEXT=5 6 | TABLE=6 7 | TR=7 8 | TD=8 9 | FONT=9 10 | B=10 11 | I=11 12 | U=12 13 | S=13 14 | O=14 15 | SUB=15 16 | SUP=16 17 | BR=17 18 | VT=18 19 | VB=19 20 | VC=20 21 | HL=21 22 | HR=22 23 | HC=23 24 | COMMA=24 25 | SEMI_COLON=25 26 | TAG_CLOSE=26 27 | TAG_SLASH_CLOSE=27 28 | TAG_SLASH=28 29 | TAG_EQUALS=29 30 | TAG_NAME=30 31 | TAG_WHITESPACE=31 32 | ATTVALUE_VALUE=32 33 | ATTRIBUTE=33 34 | '<'=4 35 | ','=24 36 | ';'=25 37 | '>'=26 38 | '/>'=27 39 | '/'=28 40 | '='=29 41 | -------------------------------------------------------------------------------- /test/picture/case_visual.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/case_visual.png -------------------------------------------------------------------------------- /test/picture/fdp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/fdp.png -------------------------------------------------------------------------------- /test/picture/layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/layout.png -------------------------------------------------------------------------------- /test/picture/line_port.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/line_port.png -------------------------------------------------------------------------------- /test/picture/line_router.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/line_router.png -------------------------------------------------------------------------------- /test/picture/node_record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/node_record.png -------------------------------------------------------------------------------- /test/picture/node_shape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/node_shape.png -------------------------------------------------------------------------------- /test/picture/rich_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/rich_text.png -------------------------------------------------------------------------------- /test/picture/show_boxes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/show_boxes.png -------------------------------------------------------------------------------- /test/picture/show_control_points.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/show_control_points.png -------------------------------------------------------------------------------- /test/picture/show_grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/show_grid.png -------------------------------------------------------------------------------- /test/picture/table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/table.png -------------------------------------------------------------------------------- /test/picture/table_assemble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/table_assemble.png -------------------------------------------------------------------------------- /test/picture/table_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamisonjiang/graph-support/2abf3dddffd85a7e4dbf6c65ce4be96b382aa4c8/test/picture/table_example.png -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case1.dot: -------------------------------------------------------------------------------- 1 | digraph unix { 2 | splines=ortho 3 | sh0006 [shape=rect,width=0.861111,height=0.543335,color="#000006"]; 4 | sh0007 [shape=rect,width=1.236111,height=0.543335,color="#000007"]; 5 | sh0008 [shape=rect,width=0.694444,height=0.543335,color="#000008"]; 6 | sh0009 [shape=rect,width=0.958333,height=0.543335,color="#000009"]; 7 | sh0010 [shape=plain,label=<
>]; 8 | 9 | sh0010:p1->sh0006[tailcell="p1",tailport="e",arrowsize=0.5,minlen=0,color="#00000B"]; 10 | sh0010:p2->sh0007[tailcell="p2",tailport="w",arrowsize=0.5,minlen=1,color="#00000F"]; 11 | sh0010:p2->sh0007[tailcell="p2",tailport="w",arrowsize=0.5,minlen=1,color="#00000F"]; 12 | sh0010:p3->sh0008[tailcell="p3",tailport="e",arrowsize=0.5,minlen=2,color="#000013"]; 13 | sh0010:p3->sh0008[tailcell="p3",tailport="e",arrowsize=0.5,minlen=2,color="#000013"]; 14 | sh0009->sh0010:p2[headcell="p2",headport="e"arrowsize=0.5,minlen=1,color="#000017"]; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case10.dot: -------------------------------------------------------------------------------- 1 | digraph { 2 | node [ fontname="Handlee" ]; 3 | subgraph cluster_website { 4 | label="Website"; 5 | subgraph cluster_frontend { 6 | label="Frontend"; 7 | React; 8 | Bootstrap; 9 | } 10 | subgraph cluster_backend { 11 | label="Backend"; 12 | expressjs; 13 | "aws-sdk"; 14 | } 15 | } 16 | 17 | subgraph cluster_aws { 18 | label="AWS"; 19 | DynamoDb; 20 | S3; 21 | } 22 | 23 | React -> expressjs; 24 | expressjs -> "aws-sdk" [constraint=false]; 25 | "aws-sdk" -> S3; 26 | "aws-sdk" -> DynamoDb; 27 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case11.dot: -------------------------------------------------------------------------------- 1 | digraph { 2 | rankdir=RL 3 | ranksep="1.5" 4 | node [shape=record] 5 | edge [color=red] 6 | frame [label="<0>X|<1>X|<2>X|<3>X|<4>X|<5>X|<6>X|<7>X|<8>X|<9>X|<10>X|<11>X|<12>.|<13>.|<14>.|<15>.|<16>.|<17>.|<18>.|<19>.|<20>.|<21>.|<22>.|<23>.|<24>.|<25>.|<26>.|<27>.|<28>.|<29>.|<30>.|<31>.|"] 7 | { 8 | rank=source 9 | p2 [label="<2>2|<3>3|<4>4|<5>5|<6>6|<7>7|"] 10 | } 11 | { 12 | rank=sink 13 | p3 [label="<0>0|<1>1|<8>8|<9>9|<10>10|<11>11|"] 14 | } 15 | p2 -> frame[tailcell="2" headcell="2"] 16 | p2 -> frame[tailcell="3" headcell="3"] 17 | p2 -> frame[tailcell="4" headcell="4"] 18 | p2 -> frame[tailcell="5" headcell="5"] 19 | p2 -> frame[tailcell="6" headcell="6"] 20 | p2 -> frame[tailcell="7" headcell="7"] 21 | p3 -> frame[tailcell="0" headcell="0"] 22 | p3 -> frame[tailcell="1" headcell="1"] 23 | p3 -> frame[tailcell="8" headcell="8"] 24 | p3 -> frame[tailcell="9" headcell="9"] 25 | p3 -> frame[tailcell="10" headcell="10"] 26 | p3 -> frame[tailcell="11" headcell="11"] 27 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case13.dot: -------------------------------------------------------------------------------- 1 | strict digraph G { 2 | psvg=t 3 | node[shape=rect, color = black, style = filled]; 4 | node[dir = back]; 5 | 1 -> "G is the midpoint of DE"; 6 | 1 -> 2; 7 | 2 -> 3; 8 | 3 -> "F is the midpoint of CB"; 9 | 3 -> "DC ⊥ DB"; 10 | 2 -> 4; 11 | 4 -> "F is the midpoint of CB"; 12 | 4 -> "EC ⊥ EB"; 13 | 1 [ shape="invtrapezium" fillcolor="#C0FFFF" href="https://github.com/kovzol/Java-Geometry-Expert/blob/master/src/docs/help/images_a/rectangle.gif" tooltips="8. szabály: Pitagorasz-tétel" label=< 14 | 15 | 16 | 17 |
18) ∠[EBA] = ∠[HFA]
Rule 31.
18 | >]; 19 | 2 [ label = "18) ∠[EBA] = ∠[HFA]\nRule 31", fillcolor = "#FFA0A0" ]; 20 | 3 [ label = "3) CF = DF", fillcolor = "#C0FFFF"]; 21 | 4 [ label = "4) CF = EF", fillcolor = "#C0FFFF"]; 22 | "G is the midpoint of DE" [ fillcolor = "#F7CAC9", shape = ellipse, style = filled ]; 23 | "F is the midpoint of CB" [ fillcolor = "#F7CAC9", shape = ellipse, style = filled ]; 24 | "DC ⊥ DB" [ fillcolor = "#F7CAC9", shape = oval, style = filled ]; 25 | "F is the midpoint of CB" [ fillcolor = "#F7CAC9", shape = ellipse, style = filled ]; 26 | "EC ⊥ EB" [ fillcolor = "#F7CAC9", shape = ellipse, style = filled ]; 27 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case16.dot: -------------------------------------------------------------------------------- 1 | digraph unix { 2 | size="5" 3 | edge [style=dashed]; 4 | "5th Edition" -> "6th Edition"; 5 | "5th Edition" -> "PWB 1.0"; 6 | "6th Edition" -> "LSX"; 7 | "6th Edition" -> "1 BSD"; 8 | "6th Edition" -> "Mini Unix"; 9 | "6th Edition" -> "Wollongong"; 10 | "6th Edition" -> "Interdata"; 11 | "Interdata" -> "Unix/TS 3.0"; 12 | "Interdata" -> "PWB 2.0"; 13 | "Interdata" -> "7th Edition"; 14 | "7th Edition" -> "8th Edition"; 15 | "7th Edition" -> "32V"; 16 | "7th Edition" -> "V7M"; 17 | "7th Edition" -> "Ultrix-11"; 18 | "7th Edition" -> "Xenix"; 19 | "7th Edition" -> "UniPlus+"; 20 | "V7M" -> "Ultrix-11"; 21 | "8th Edition" -> "9th Edition"; 22 | "1 BSD" -> "2 BSD"; 23 | "2 BSD" -> "2.8 BSD"; 24 | "2.8 BSD" -> "Ultrix-11"; 25 | "2.8 BSD" -> "2.9 BSD"; 26 | "32V" -> "3 BSD"; 27 | "3 BSD" -> "4 BSD"; 28 | "4 BSD" -> "4.1 BSD"; 29 | "4.1 BSD" -> "4.2 BSD"; 30 | "4.1 BSD" -> "2.8 BSD"; 31 | "4.1 BSD" -> "8th Edition"; 32 | "4.2 BSD" -> "4.3 BSD"; 33 | "4.2 BSD" -> "Ultrix-32"; 34 | "PWB 1.0" -> "PWB 1.2"; 35 | "PWB 1.0" -> "USG 1.0"; 36 | "PWB 1.2" -> "PWB 2.0"; 37 | "USG 1.0" -> "CB Unix 1"; 38 | "USG 1.0" -> "USG 2.0"; 39 | "CB Unix 1" -> "CB Unix 2"; 40 | "CB Unix 2" -> "CB Unix 3"; 41 | "CB Unix 3" -> "Unix/TS++"; 42 | "CB Unix 3" -> "PDP-11 Sys V"; 43 | "USG 2.0" -> "USG 3.0"; 44 | "USG 3.0" -> "Unix/TS 3.0"; 45 | "PWB 2.0" -> "Unix/TS 3.0"; 46 | "Unix/TS 1.0" -> "Unix/TS 3.0"; 47 | "Unix/TS 3.0" -> "TS 4.0"; 48 | "Unix/TS++" -> "TS 4.0"; 49 | "CB Unix 3" -> "TS 4.0"; 50 | "TS 4.0" -> "System V.0"; 51 | "System V.0" -> "System V.2"; 52 | "System V.2" -> "System V.3"; 53 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case2.dot: -------------------------------------------------------------------------------- 1 | digraph unix { 2 | splines=ortho 3 | showgrid=true 4 | sh0006 [shape=record,label="{|sh0006|}"]; 5 | sh0007 [shape=record,label="{|sh0007|}"]; 6 | sh0010 [shape=record,label="{p1|p2|p3|p4}"]; 7 | 8 | sh0007->sh0010[tailcell="t",tailport="w",headcell="p4",headport="e",minlen=0]; 9 | sh0010->sh0007[tailcell="p2",tailport="e",headcell="p4",headport="w",minlen=0]; 10 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case3.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | splines=ortho 3 | node [shape=box, ordering=out, fillcolor=white] 4 | "0?7 ?A?" -> "0?1 'a'" 5 | "0?7 ?A?" -> "1?7 ?A?" 6 | "1?7 ?A?" -> "1?2 'a'" 7 | "1?7 ?A?" -> "2?7 ?A?" 8 | "2?7 ?A?" -> "2?3 'a'" 9 | "2?7 ?A?" -> "3?7 ?A?" 10 | "3?7 ?A?" -> "3?4 'a'" 11 | "3?7 ?A?" -> "4?7 ?A?" 12 | "4?7 ?A?" -> "4?5 'a'" 13 | "4?7 ?A?" -> "5?7 ?A?" 14 | "5?7 ?A?" -> "5?6 'a'" 15 | "5?7 ?A?" -> "6?7 ?A?" 16 | "6?7 ?A?" -> "6?7 'a'" 17 | "6?7 ?A?" -> "7?7 ?A?" 18 | } 19 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case4.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | label="My Cool Graph" 3 | 4 | subgraph cluster_0 { 5 | q0->x2 6 | subgraph cluster_1 { 7 | x2->y2 8 | x2->z2 9 | subgraph cluster_2 { 10 | label="C2" 11 | x21->x22 12 | } 13 | } 14 | subgraph cluster_3 { 15 | x1->y1 16 | x1->z1 17 | } 18 | z2->x1 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case6.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | splines=ortho 3 | showgrid=true 4 | a[shape=record,label="12|32|{sd|fs|f}|32"] 5 | b[shape=record,label="{sss|ssdf|ssdf|{

ff|sdf|{s|s|s1}|ttt}|sdfsd}"] 6 | 7 | a->b[tailcell=l,headcell=p] 8 | a->b[tailcell=k,headcell=t] 9 | a->b[tailcell=u,headcell=b] 10 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case7.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | b[shape=plain,label=< 3 | 4 | 5 | 12 | 18 | 19 | 20 |
foobarbaz
6 | 7 | 8 | 9 | 10 |
onetwothree
fourfivesix
seveneightnine
11 |
13 | 14 | 15 | 16 |
einszweisechs
vierffff
17 |
abc
21 | >]; 22 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case8.dot: -------------------------------------------------------------------------------- 1 | digraph unix { 2 | nodesep=0.486111; 3 | ranksep=0.833333; 4 | remincross=true; 5 | searchsize=500; 6 | sh0006 [shape=rect,label="sh0006",width=0.861111,height=0.543335,color="#000006"]; 7 | sh0007 [shape=rect,label="sh0007",width=1.236111,height=0.543335,color="#000007"]; 8 | sh0008 [shape=rect,label="sh0008",width=0.694444,height=0.543335,color="#000008"]; 9 | sh0009 [shape=rect,label="sh0009",width=0.958333,height=0.543335,color="#000009"]; 10 | sh0010 [shape=plain,label=<
>]; 11 | 12 | sh0010->sh0006[tailcell="p76423d8352c9e8fc8d7d65f62c55eae9",arrowsize=0.5,minlen=0,color="#00000B"]; 13 | sh0010->sh0007[tailcell="pf75d91cdd36b85cc4a8dfeca4f24fa14",arrowsize=0.5,minlen=1,color="#00000F",showboxes=true]; 14 | sh0010->sh0008[tailcell="pd8b00929dec65d422303256336ada04f",arrowsize=0.5,minlen=2,color="#000013"]; 15 | sh0009->sh0010[headcell="pf75d91cdd36b85cc4a8dfeca4f24fa14",arrowsize=0.5,minlen=1,color="#000017"]; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/case9.dot: -------------------------------------------------------------------------------- 1 | digraph unix { 2 | splines=ortho 3 | 4 | subgraph cluster_0 { 5 | label="cluster" 6 | margin="1.5,1" 7 | style=dashed 8 | sh0006 9 | sh0007 10 | } 11 | 12 | sh0006 [shape=record,label="{{|sh0006|}}"]; 13 | t->t 14 | t->t 15 | t->t[label="hehehe"] 16 | t->t[label="niu bi"] 17 | t->t[label="iiiiii\\niii"] 18 | t->t 19 | t->t 20 | t->t 21 | t->t 22 | 23 | k->k[tailport=w,headport=se] 24 | k->k[tailport=ne,headport=s] 25 | 26 | sh0007 [shape=record,label="{{|{|

sh0007}|}}"]; 27 | sh0006->sh0007[headcell="p"] 28 | sh0006->sh0007[headcell="p"] 29 | sh0006->sh0007[headcell="r",headport="e"] 30 | sh0006->sh0007[headcell="r",headport="se"] 31 | 32 | sh0006->k 33 | } 34 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/cluster.dot: -------------------------------------------------------------------------------- 1 | digraph cluster { 2 | // Node attribute template 3 | node [shape=rect]; 4 | 5 | // Node definition 6 | nd_1 [label = "Node 1"]; 7 | nd_2 [label = "Node 2"]; 8 | nd_3_a [label = "Above Right Node 3"]; 9 | nd_3_l [label = "Left of Node 3"]; 10 | nd_3 [label = "Node 3"]; 11 | nd_3_r [label = "Right of Node 3"]; 12 | nd_4 [label = "Node 4"]; 13 | 14 | // Edges in root graph 15 | nd_3_a -> nd_3_r; 16 | nd_1 -> nd_2 -> nd_3 -> nd_4; 17 | 18 | // Use Cluster to wrap the corresponding nodes and edges 19 | subgraph cluster_R { 20 | // Edge attribute template 21 | edge[color=grey arrowhead=none] 22 | // Use Subgraph to limit nodes to the same level 23 | { 24 | rank=same 25 | nd_3_l 26 | nd_3 27 | nd_3_r 28 | } 29 | 30 | // Edges in cluster 31 | nd_3_l -> nd_3 -> nd_3_r; 32 | } 33 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/clusterAttrs.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | label=123> 3 | subgraph cluster_0 { 4 | color=lightgrey; 5 | bgcolor=lightgrey; 6 | node[color=white,fillcolor=white]; 7 | a0 -> a1 -> a2 -> a3; 8 | label = #1>; 9 | } 10 | 11 | subgraph cluster_1 { 12 | node[fillcolor=grey]; 13 | b0 -> b1 -> b2 -> b3; 14 | label = <process



#2
>; 15 | color=blue 16 | } 17 | start -> a0[label=label
> taillabel=label> headlabel=label>]; 18 | start -> b0; 19 | a1 -> b3; 20 | b2 -> a3; 21 | a3 -> a0; 22 | a3 -> end; 23 | b3 -> end; 24 | 25 | start [shape=diamond]; 26 | end [shape=rect]; 27 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/clusterIdMixedCase.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 3 | subgraph CLUSTeR_1 { 4 | a 5 | } 6 | 7 | subgraph CLUSTeR1 { 8 | b 9 | } 10 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/clusterLabel.dot: -------------------------------------------------------------------------------- 1 | digraph axionalterm { 2 | rankdir="LR" 3 | size="7" 4 | subgraph cluster_backend { 5 | margin="1,0.5" 6 | subgraph cluster_0 { 7 | style="filled" 8 | fillcolor="#EEEEEE" 9 | label="Bauuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu\nddddddddddddddddddd\nfffffffffffffffffffffffffffffffffffffff\nkkkkkkkkkkkkkkkkkkkkkk\nggggggggggggggggg\nkkkkkkkkkkkkkkkkkklllllllllllllllllllllllllllllllll\n11111111111111111111111111111111111111111111111111\n888888888888" 10 | soap 11 | jdbc 12 | k 13 | m 14 | } 15 | } 16 | 17 | jdbc [label="JDBC", shape="cylinder", style="filled", fillcolor="#0277BD", fontcolor="#FFFFFF"] 18 | LOCAL [label="LOCAL/JAVA-UEL"] 19 | a->jdbc->k->m->e 20 | t->LOCAL->p->f 21 | 22 | subgraph cluster_1 { 23 | label="sssssssssssssssssssssssssssssssssssssssssssssssssssssssss\nkkkkkkkkkkkkkkkkkkkkkkkkkkk\nooooooooooooooooooo" 24 | subgraph cluster_2 { 25 | label="sssssssssssssssssssssssssssssss" 26 | p,t 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/cluster_alloc_bug.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 3 | subgraph cluster_1 { 4 | a;b;e;f 5 | } 6 | 7 | subgraph cluster_2 { 8 | d;c 9 | } 10 | 11 | subgraph cluster_3 { 12 | g;h 13 | } 14 | 15 | a->b->c->f 16 | a->d->e->f 17 | a->g->h->f 18 | b->e 19 | d->c 20 | e->c 21 | h->e 22 | b->h 23 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/cluster_case1.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | layout=fdp 3 | edge [label="test\ntest\ntest\ntresttttttttttttttttttttt" controlPoints=true] 4 | C[fillcolor=red fontcolor=blue fontsize=100 fontname="宋体" labelloc="b" labeljust="r" fixedsize=false style=dashed penWidth="5"] 5 | C->BB 6 | B->F 7 | F->GG 8 | F->SS 9 | B->D 10 | C->D 11 | AA->D 12 | L->AA 13 | B->45 14 | A->12 15 | 34->gg 16 | C->34 17 | subgraph cluster_A { 18 | label="Cluster A" 19 | A->C 20 | B->C 21 | subgraph cluster_A_A { 22 | label="Cluster A Iner" 23 | B->K 24 | C->U 25 | subgraph cluster_frontend { 26 | label="Frontend"; 27 | React; 28 | Bootstrap; 29 | } 30 | subgraph cluster_backend { 31 | label="Backend"; 32 | expressjs; 33 | "aws-sdk"; 34 | } 35 | React -> expressjs; 36 | expressjs -> "aws-sdk"; 37 | "aws-sdk" -> S3; 38 | "aws-sdk" -> DynamoDb; 39 | } 40 | } 41 | subgraph cluster_B { 42 | label="Cluster B" 43 | AA->CC 44 | BB->CC 45 | } 46 | subgraph cluster_C { 47 | label="Cluster C" 48 | SS->TT 49 | GG->PP 50 | D->F 51 | L->FF 52 | FF->SS 53 | { 54 | rank=same; 55 | L -> D 56 | } 57 | } 58 | subgraph cluster_D { 59 | label="Cluster D" 60 | 12->45 61 | 34->98 62 | 34->45 63 | 45->98 64 | } 65 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/cluster_case2.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | nodesep=1 3 | a[shape=pentagon style="bold,dashed" color=orange] 4 | a->d[minlen=0 label="requires" dir=back ltail="cluster_0" lhead="cluster_2"] 5 | b->e[minlen=0 label="opens" dir=back ltail="cluster_0" ] 6 | b->f[minlen=0 label="exports" lhead="cluster_2" style="bold,dashed" color=blue] 7 | subgraph cluster_0 { 8 | label="ModuleA" 9 | style="rounded,bold,dotted" 10 | subgraph cluster_1 { 11 | label="coo.foo" 12 | penwidth=2 13 | a[label="api"] 14 | b[label="internal"] 15 | a->b[style=invis] 16 | b->c[style=invis] 17 | c[style=invis height=0 fixedsize=true] 18 | } 19 | } 20 | 21 | subgraph cluster_2 { 22 | label="ModuleB" 23 | shape="octagon" 24 | color=red 25 | style="rounded,dashed" 26 | d->e[style=invis] 27 | d[style=invis height=0 fixedsize=true] 28 | f[style=invis height=0 fixedsize=true] 29 | subgraph cluster_3 { 30 | label="com.bar" 31 | e[label="impl"] 32 | e->f[style=invis] 33 | } 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/cluster_case3.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 3 | subgraph cluster_A { 4 | label="machine cluster" 5 | bgcolor=orange 6 | style=rounded 7 | e; 8 | c; 9 | 10 | subgraph cluster_B { 11 | label="test" 12 | style="rounded" 13 | subgraph cluster_C { 14 | label="kkk" 15 | shape=parallelogram 16 | style="rounded,dashed,bold" 17 | color=red 18 | f 19 | } 20 | subgraph { 21 | rank=same 22 | e->g->f 23 | } 24 | } 25 | 26 | subgraph { 27 | rank=same 28 | a->b->c->d 29 | } 30 | 31 | subgraph cluster_D { 32 | { 33 | rank=same 34 | o->t 35 | } 36 | l->o->p 37 | } 38 | 39 | subgraph { 40 | c->e 41 | d->f 42 | e->f 43 | } 44 | 45 | a->c 46 | b->e 47 | 48 | a->f 49 | a->g 50 | d->p 51 | d->t 52 | } 53 | 54 | o->f[ltail="cluster_d", lhead="cluster_l" headclip=false] 55 | o->f[ltail="cluster_d", lhead="cluster_c"] 56 | t->m 57 | f->m[weight=5] 58 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/cluster_nest.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | subgraph cluster_1 { 3 | style="bold" 4 | label="cluster_1" 5 | 1 6 | o 7 | subgraph cluster_2 { 8 | style="bold" 9 | label="cluster_2" 10 | k 11 | h 12 | subgraph cluster_3 { 13 | style="bold" 14 | label="cluster_3" 15 | subgraph cluster_4 { 16 | style="bold" 17 | label="cluster_4" 18 | subgraph cluster_5 { 19 | style="bold" 20 | label="cluster_5" 21 | 2 22 | } 23 | } 24 | } 25 | } 26 | } 27 | subgraph cluster_6 { 28 | style="bold" 29 | label="cluster_6" 30 | 9 31 | 5 32 | } 33 | 3->2 34 | 4->3 35 | 4->5 36 | 5->2 37 | 5->1 38 | 3->1 39 | 9->o 40 | 5->o 41 | 9->2 42 | k 43 | } 44 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/cluster_optimize.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | edge [dir=back] 3 | C->BB 4 | B->F 5 | F->GG 6 | F->SS 7 | B->D 8 | subgraph cluster_A { 9 | label="Cluster A" 10 | A->C 11 | B->C 12 | } 13 | subgraph cluster_B { 14 | label="Cluster B" 15 | AA->CC 16 | BB->CC 17 | } 18 | subgraph cluster_C { 19 | label="Cluster C" 20 | SS->TT 21 | GG->PP 22 | d->f 23 | L->FF 24 | FF->SS 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/cluster_same_rank.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | layout=fdp 3 | subgraph cluster_A { 4 | e; 5 | c; 6 | 7 | subgraph cluster_B { 8 | label="test" 9 | subgraph { 10 | rank=same 11 | e->g 12 | } 13 | } 14 | 15 | subgraph { 16 | 17 | rank=same 18 | a->b->c->d 19 | 20 | } 21 | 22 | subgraph { 23 | c->e 24 | d->f 25 | e->f 26 | } 27 | 28 | 29 | 30 | a->c 31 | b->e 32 | 33 | a->f 34 | a->g 35 | } 36 | 37 | 38 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/edgeSubgraphCombined.dot: -------------------------------------------------------------------------------- 1 | digraph edgeSubgraphCombined { 2 | // Node attribute template 3 | node [shape=rect]; 4 | 5 | // Node definition 6 | nd_1 [label = "Node 1"]; 7 | nd_2 [label = "Node 2"]; 8 | 9 | nd_3_l [label = "Left of Node 3"]; 10 | nd_3 [label = "Node 3"]; 11 | nd_3_r [label = "Right of Node 3"]; 12 | nd_4 [label = "Node 4"]; 13 | 14 | nd_4; 15 | 16 | { nd_1 nd_2 } -> 17 | // Use Cluster to wrap the corresponding nodes and edges 18 | subgraph cluster_R { 19 | // Edge attribute template 20 | edge[color=grey arrowhead=none] 21 | // Use Subgraph to limit nodes to the same level 22 | { 23 | rank=same 24 | nd_3_l 25 | nd_3 26 | nd_3_r 27 | } 28 | 29 | // Edges in cluster 30 | nd_3_l -> nd_3 -> nd_3_r; 31 | }; 32 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/edgeSubgraphLeft.dot: -------------------------------------------------------------------------------- 1 | digraph edgeSubgraphLeft { 2 | // Node attribute template 3 | node [shape=rect]; 4 | 5 | // Node definition 6 | nd_1 [label = "Node 1"]; 7 | 8 | nd_3_l [label = "Left of Node 3"]; 9 | nd_3 [label = "Node 3"]; 10 | nd_3_r [label = "Right of Node 3"]; 11 | 12 | 13 | // Use Cluster to wrap the corresponding nodes and edges 14 | subgraph cluster_R { 15 | // Edge attribute template 16 | edge[color=grey arrowhead=none] 17 | // Use Subgraph to limit nodes to the same level 18 | { 19 | rank=same 20 | nd_3_l 21 | nd_3 22 | nd_3_r 23 | } 24 | 25 | // Edges in cluster 26 | nd_3_l -> nd_3 -> nd_3_r; 27 | } -> nd_1; 28 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/edgeSubgraphMiddle.dot: -------------------------------------------------------------------------------- 1 | digraph edgeSubgraphMiddle { 2 | // Node attribute template 3 | node [shape=rect]; 4 | 5 | // Node definition 6 | nd_1 [label = "Node 1"]; 7 | nd_2 [label = "Node 2"]; 8 | 9 | nd_3_l [label = "Left of Node 3"]; 10 | nd_3 [label = "Node 3"]; 11 | nd_3_r [label = "Right of Node 3"]; 12 | 13 | 14 | nd_1 -> 15 | // Use Cluster to wrap the corresponding nodes and edges 16 | subgraph cluster_R { 17 | // Edge attribute template 18 | edge[color=grey arrowhead=none] 19 | // Use Subgraph to limit nodes to the same level 20 | { 21 | rank=same 22 | nd_3_l 23 | nd_3 24 | nd_3_r 25 | } 26 | 27 | // Edges in cluster 28 | nd_3_l -> nd_3 -> nd_3_r; 29 | } -> nd_2; 30 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/edgeSubgraphRight.dot: -------------------------------------------------------------------------------- 1 | digraph edgeSubgraphRight { 2 | // Node attribute template 3 | node [shape=rect]; 4 | 5 | // Node definition 6 | nd_1 [label = "Node 1"]; 7 | 8 | nd_3_l [label = "Left of Node 3"]; 9 | nd_3 [label = "Node 3"]; 10 | nd_3_r [label = "Right of Node 3"]; 11 | 12 | nd_1 -> 13 | // Use Cluster to wrap the corresponding nodes and edges 14 | subgraph cluster_R { 15 | // Edge attribute template 16 | edge[color=grey arrowhead=none] 17 | // Use Subgraph to limit nodes to the same level 18 | { 19 | rank=same 20 | nd_3_l 21 | nd_3 22 | nd_3_r 23 | } 24 | 25 | // Edges in cluster 26 | nd_3_l -> nd_3 -> nd_3_r; 27 | }; 28 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/embedTable.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 3 | b [label=< 4 | 5 | 12 | 13 |
foobarbaz
quxquux 6 | 7 | 8 | 9 | 10 |
foobarbaz
quxquuxcorge
11 |
>]; 14 | 15 | a [label=<
>]; 16 | 17 | c [label=< 18 | 24 |
19 | 20 | 21 | 22 |
foobarbaz
quxquuxcorge
23 |
>]; 25 | 26 | k [label=< 27 | 28 | 29 | 35 | 36 | 37 |
30 | 31 | 32 | 33 |
111
222
34 |
second 333
>]; 38 | 39 | t [label=< 40 | < table border = 1 color = red > 41 | < tr > 42 | < td color = red 43 | fontsize = "1" colspan=1 > 1 2 3 4 5678 \n \r < / td > 44 | < / tr > 45 | < / table > 46 | >]; 47 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/fdp1.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | layout=fdp 3 | a--b 4 | a--b 5 | a--c 6 | a--c 7 | a--d 8 | a--d 9 | a--e 10 | a--e 11 | b--c 12 | b--c 13 | b--d 14 | b--d 15 | b--e 16 | b--e 17 | c--d 18 | c--d 19 | c--e 20 | c--e 21 | d--e 22 | d--e 23 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/fdp2.dot: -------------------------------------------------------------------------------- 1 | graph { 2 | layout=fdp 3 | a -- b; 4 | b -- c; 5 | a -- c; 6 | d -- c; 7 | e -- c; 8 | e -- a; 9 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/fdp3.dot: -------------------------------------------------------------------------------- 1 | graph { 2 | layout=fdp 3 | a -- b; 4 | b -- c; 5 | c -- d; 6 | d -- e; 7 | e -- f; 8 | a -- f; 9 | a -- c; 10 | a -- d; 11 | a -- e; 12 | b -- d; 13 | b -- e; 14 | b -- f; 15 | c -- e; 16 | c -- f; 17 | d -- f; 18 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/fdp4.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | layout=fdp 3 | a--b 4 | b--c 5 | c--d 6 | d--e 7 | e--f 8 | f--g 9 | 10 | h[style=invis] 11 | h--a[style=invis] 12 | h--b[style=invis] 13 | h--c[style=invis] 14 | h--d[style=invis] 15 | h--e[style=invis] 16 | h--f[style=invis] 17 | h--g[style=invis] 18 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/fdp6.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | layout=fdp 3 | a--b 4 | b--c 5 | a--c 6 | c--d 7 | d--e 8 | e--f 9 | f--g 10 | g--h 11 | h--i 12 | g--i 13 | 14 | j[style=invis] 15 | j--c[weight=2 style=invis] 16 | j--d[weight=2 style=invis] 17 | j--e[weight=2 style=invis] 18 | j--f[weight=2 style=invis] 19 | j--g[weight=2 style=invis] 20 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/fdp7.dot: -------------------------------------------------------------------------------- 1 | graph G { 2 | layout=fdp 3 | size="7" 4 | a--b 5 | b--c 6 | a--c 7 | c--d 8 | d--e 9 | e--f 10 | f--g 11 | g--h 12 | h--i 13 | i--j 14 | j--k 15 | k--m 16 | j--m 17 | 18 | o[style=invis] 19 | o--c[style=invis] 20 | o--d[style=invis] 21 | o--e[style=invis] 22 | o--f[style=invis] 23 | o--g[style=invis] 24 | o--h[style=invis] 25 | o--i[style=invis] 26 | o--j[style=invis] 27 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/fdp_ortho_selfline.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | layout=fdp 3 | splines=ortho 4 | a->a[label="ffffffff\nfffffffffffff\nfffffff" dir=back]; 5 | a->a[label="324234324324"]; 6 | a->a; 7 | a->a; 8 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/grid.dot: -------------------------------------------------------------------------------- 1 | graph grid { 2 | fontname="Helvetica,Arial,sans-serif" 3 | node [fontname="Helvetica,Arial,sans-serif"] 4 | edge [fontname="Helvetica,Arial,sans-serif"] 5 | layout=dot 6 | labelloc = "t" 7 | node [shape=plaintext] 8 | A0 -- B1 -- C2 -- D3 -- E4 -- F5 -- G6 -- H7 9 | H0 -- G1 -- F2 -- E3 -- D4 -- C5 -- B6 -- A7 10 | 11 | edge [weight=1000 style=dashed color=dimgrey] 12 | 13 | A0 -- A1 -- A2 -- A3 -- A4 -- A5 -- A6 -- A7 14 | B0 -- B1 -- B2 -- B3 -- B4 -- B5 -- B6 -- B7 15 | C0 -- C1 -- C2 -- C3 -- C4 -- C5 -- C6 -- C7 16 | D0 -- D1 -- D2 -- D3 -- D4 -- D5 -- D6 -- D7 17 | E0 -- E1 -- E2 -- E3 -- E4 -- E5 -- E6 -- E7 18 | F0 -- F1 -- F2 -- F3 -- F4 -- F5 -- F6 -- F7 19 | G0 -- G1 -- G2 -- G3 -- G4 -- G5 -- G6 -- G7 20 | H0 -- H1 -- H2 -- H3 -- H4 -- H5 -- H6 -- H7 21 | 22 | {rank=same;A0 -- B0 -- C0 -- D0 -- E0 -- F0 -- G0 -- H0} 23 | {rank=same;A1 -- B1 -- C1 -- D1 -- E1 -- F1 -- G1 -- H1} 24 | {rank=same;A2 -- B2 -- C2 -- D2 -- E2 -- F2 -- G2 -- H2} 25 | {rank=same;A3 -- B3 -- C3 -- D3 -- E3 -- F3 -- G3 -- H3} 26 | {rank=same;A4 -- B4 -- C4 -- D4 -- E4 -- F4 -- G4 -- H4} 27 | {rank=same;A5 -- B5 -- C5 -- D5 -- E5 -- F5 -- G5 -- H5} 28 | {rank=same;A6 -- B6 -- C6 -- D6 -- E6 -- F6 -- G6 -- H6} 29 | {rank=same;A7 -- B7 -- C7 -- D7 -- E7 -- F7 -- G7 -- H7} 30 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/html_example.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | rankdir=LR 3 | node[shape=plaintext] 4 | { rank=same;b;c;} 5 | a [label=< 6 | 7 | 8 | 9 |
class
qualifier
>] 10 | b [label=< 11 | 12 | 13 | 14 | 16 | 17 | 18 | 25 | 26 | 27 | 28 | 29 | 30 |
elephanttwo
19 | 20 | 21 | 22 | 23 |
corn
c
f
24 |
penguin
4
>] 31 | 32 | a-> b [dir=both arrowtail=diamond tailcell=here headcell=there] 33 | c -> b 34 | d [shape=triangle] 35 | d -> c [label=< 36 | 37 | 38 | 39 | 40 | 41 | 42 |
Edge labels also
>] 43 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/lhead.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | subgraph cluster_a { 3 | a;b; 4 | } 5 | 6 | c->b[lhead=cluster_a] 7 | c->a 8 | } 9 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/nodeDefinePriority.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | a[label="111"] 3 | subgraph cluster_A { 4 | 5 | a[label="222"] 6 | 7 | subgraph cluster_B { 8 | subgraph cluster_C { 9 | a[label="333"] 10 | } 11 | a->b 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/port.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | node[shape=record] 3 | a[label="||{p1|{|p2}||}||"] 4 | 5 | a:p1:se->b:k1:s 6 | 7 | b[label="|||{|||{||k1||}|||||{t1||}|}||"] 8 | 9 | a:p1:se->a:p1:se 10 | b:t1:w->b:t1:w 11 | b:t1:ne->b:k1:sw 12 | 13 | c[label="<1>1|<2>2|<3>3"] 14 | d[label="<4>4|<5>5|<6>6"] 15 | c->d[tailcell=1 tailport=w headcell=6 headport=sw] 16 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/self_line.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | layout=fdp 3 | 4 | a->a[label=< 5 | 6 | 7 | 8 | 10 | 11 | 12 | 19 | 20 | 21 | 22 | 23 | 24 |
elephanttwo
13 | 14 | 15 | 16 | 17 |
corn
c
f
18 |
penguin
4
>] 25 | 26 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/sequence_eg.dot: -------------------------------------------------------------------------------- 1 | digraph time { 2 | rankdir = "LR"; 3 | node[shape = "point" width=0 height=0]; 4 | edge[arrowhead = "none", style = "dashed",tailclip=false,tailclip=false]; 5 | 6 | { 7 | rank = "same" 8 | APP[shape = "plaintext"]; 9 | APP -> step00 -> step01 -> step02 -> step03 -> step04 -> step05; 10 | } 11 | 12 | { 13 | rank="same"; 14 | SDK[shape="plaintext"]; 15 | SDK -> step10 -> step11 -> step12 -> step13 -> step14 -> step15; 16 | } 17 | { 18 | rank="same"; 19 | AliPay[shape="plaintext"]; 20 | AliPay -> step20 -> step21 -> step22 -> step23 -> step24 -> step25; 21 | } 22 | { 23 | rank="same"; 24 | Server[shape="plaintext"]; 25 | Server -> step30 -> step31 -> step32 -> step33 -> step34 -> step35; 26 | } 27 | 28 | step00 -> step10 [label="sends order info", arrowhead="normal"]; 29 | step11 -> step21 [label="open AliPay", arrowhead="normal"]; 30 | step22 -> step12 [label="pay success", arrowhead="normal"]; 31 | step13 -> step03 [label="pay success", arrowhead="normal"]; 32 | step24 -> step34 [label="pay success", arrowhead="normal"]; 33 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/stringCase.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | "a"[label="\\\\\\\\\\\\\\\\\\\\\\\\\\\"a\"\\"] 3 | "b"[label="'b'\\nbb"] 4 | "c"[label="c\ncdd\"d"] 5 | "d"[label="d\rd"] 6 | "e"[label="e\r\ne"] 7 | "f"[label="f\n\rf"] 8 | "node1" [label="Line1\nLine2"]; 9 | "node2" [label="Tab\tCharacter"]; 10 | "node3" [label="Quote:\"Inside Quote\""]; 11 | "node4" [label="Backslash:\\Path\\"]; 12 | "node5" [label="Backspace:\b"]; 13 | "node6" [label="FormFeed:\f"]; 14 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/subgraphEndpointsEdges.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | 3 | subgraph cluster_0 { 4 | color=lightgrey; 5 | bgcolor=lightgrey; 6 | node[color=white,fillcolor=white]; 7 | a0 -> a1 -> a2 -> a3; 8 | label = "process #1"; 9 | } 10 | -> 11 | subgraph cluster_1 { 12 | node[fillcolor=grey]; 13 | b0 -> b1 -> b2 -> b3; 14 | label = "process #2"; 15 | color=blue 16 | }->t[color=red style="dashed"] 17 | start -> a0; 18 | start -> b0; 19 | a1 -> b3; 20 | b2 -> a3; 21 | a3 -> a0; 22 | a3 -> end; 23 | b3 -> end; 24 | 25 | start [shape=diamond]; 26 | end [shape=rect]; 27 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/template.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | node[shape=rect] 3 | node[fontsize=57] 4 | a0[fontcolor=yellow] 5 | 6 | subgraph cluster_0 { 7 | node[style=dashed fontcolor=red] 8 | 9 | a0[fontcolor=blue] 10 | } 11 | a0[style=dashed] 12 | a0[color=red] 13 | 14 | edge[color=red] 15 | edge[dir=both] 16 | 17 | subgraph cluster_1 { 18 | edge[style=dashed] 19 | a->b[penwidth=3 minlen=2] 20 | } 21 | 22 | node[fontsize=20] 23 | edge[color=red] 24 | a->b 25 | 26 | edge[color=blue] 27 | c->d 28 | 29 | edge[style=dashed] 30 | e->f 31 | 32 | subgraph cluster_2 { 33 | edge[dir=both] 34 | g->h 35 | 36 | subgraph cluster_3 { 37 | edge[arrowhead=vee color=GREEN] 38 | i->j 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/manual/uml_eg.dot: -------------------------------------------------------------------------------- 1 | digraph UML { 2 | 3 | node[fontname = "Courier New", fontsize = 10, shape = record]; 4 | edge[fontname = "Courier New", fontsize = 10, arrowhead = "empty"]; 5 | 6 | Car[label = "{Car | v : float\nt : float | run() : float}"] 7 | 8 | subgraph clusterSome{ 9 | bgcolor = "yellow"; 10 | Bus[label = "{Bus | | carryPeople() : void}"]; 11 | Bike[label = "{bike | | ride() : void}"]; 12 | } 13 | Bus -> Car 14 | Bike -> Car 15 | } -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/121.dot: -------------------------------------------------------------------------------- 1 | digraph G 2 | { 3 | subgraph cluster_G1 4 | { 5 | { 6 | rank=same; 7 | A -> B; 8 | } 9 | 10 | C -> A; 11 | } 12 | 13 | subgraph cluster_G2 14 | { 15 | { 16 | rank=same; 17 | D -> E; 18 | } 19 | 20 | F -> E; 21 | } 22 | 23 | B -> D [ constraint=none ]; 24 | B -> D [ constraint=none ]; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1221.dot: -------------------------------------------------------------------------------- 1 | digraph "Graph d718cbc6-5e20-4417-a41a-e1e380469dd2" { 2 | graph [ 3 | newrank=true 4 | ]; 5 | subgraph "cluster_1" { 6 | 1; 7 | } 8 | subgraph "cluster_2" { 9 | 1 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1314.dot: -------------------------------------------------------------------------------- 1 | digraph { 2 | s [ fontsize = "1836031967s8"] 3 | n0} 4 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/14.dot: -------------------------------------------------------------------------------- 1 | digraph g { 2 | layout=twopi 3 | splines=ortho 4 | a -> b 5 | } 6 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1408.dot: -------------------------------------------------------------------------------- 1 | digraph map { 2 | splines=ortho; 3 | layout="dot"; 4 | rankdir="LR"; 5 | 6 | # Clusters 7 | subgraph "cluster_1" { 8 | node [style=filled]; 9 | style=filled; 10 | 11 | label="Cluster 1"; 12 | color="pink"; 13 | 14 | #Nodes 15 | "node1" [fillcolor=red,shape=house] 16 | } 17 | subgraph "cluster_2" { 18 | node [style=filled]; 19 | style=filled; 20 | 21 | label="Cluster 2"; 22 | color="lightblue"; 23 | 24 | #Nodes: 25 | "node2" [fillcolor=red,shape=box3d] 26 | } 27 | 28 | 29 | # Edges 30 | "node2" -> "node1" [color=red,arrowhead=dot] 31 | } 32 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1444-2.dot: -------------------------------------------------------------------------------- 1 | digraph { 2 | { rank=same; n1; n2 } 3 | 4 | n2 -> n1 [ arrowhead=normal, headport=s ] 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1444.dot: -------------------------------------------------------------------------------- 1 | digraph { 2 | { rank=same; n1; n2 } 3 | 4 | n2 -> n1 [ headport=s, arrowhead=normal ] 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/144_no_ortho.dot: -------------------------------------------------------------------------------- 1 | digraph Test { 2 | nodesep = 1.0; 3 | ranksep = 1.0; 4 | edge [dir = both, arrowhead = dot, arrowtail = curve, headlabel="Head", taillabel="Tail"]; 5 | A -> B; 6 | A -> C; 7 | D -> C; 8 | } 9 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/144_ortho.dot: -------------------------------------------------------------------------------- 1 | digraph Test { 2 | splines = ortho; 3 | nodesep = 1.0; 4 | ranksep = 1.0; 5 | edge [dir = both, arrowhead = dot, arrowtail = curve, headlabel="Head", taillabel="Tail"]; 6 | A -> B; 7 | A -> C; 8 | D -> C; 9 | } 10 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1624.dot: -------------------------------------------------------------------------------- 1 | digraph cluster { 2 | node [ shape = "record"] 3 | 4 | subgraph cluster_dc1 { 5 | label = "dc1"; 6 | cas1 7 | app1 8 | } 9 | subgraph cluster_dc2 { 10 | label = "dc2"; 11 | cas2 12 | app2 13 | } 14 | app1 -> cas1 15 | app1 -> cas2 16 | app2 -> cas1 17 | } 18 | 19 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/165.dot: -------------------------------------------------------------------------------- 1 | // see test_regression.py:test_165() 2 | digraph { 3 | a [label="hello \\\" world"]; 4 | } 5 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1658.dot: -------------------------------------------------------------------------------- 1 | graph { 2 | # comment out this line and it works ok 3 | splines="ortho"; 4 | 5 | node [shape="point"]; 6 | 7 | 3; 8 | 2; 9 | 1; 10 | 0; 11 | 12 | node [shape="box"]; 13 | 14 | Charger -- IHall1 -- 3; 15 | Charger -- IHall2 -- 2; 16 | Charger -- IHall3 -- 1; 17 | Charger -- 0; 18 | 19 | 20 | 21 | 3 -- V3 -- 2 -- V2 -- 1 -- V1 -- 0 -- GND; 22 | 23 | 24 | node [shape="triangle",orientation=270]; 25 | 26 | OpAmp3; 27 | OpAmp2; 28 | OpAmp1; 29 | 30 | node [shape="box"]; 31 | 32 | 3 -- OpAmp3; 33 | 2 -- OpAmp3; 34 | 35 | 2 -- OpAmp2; 36 | 1 -- OpAmp2; 37 | 38 | 1 -- OpAmp1; 39 | 0 -- OpAmp1; 40 | 41 | #OpAmp3 -- ADC3 -- 0; 42 | #OpAmp2 -- ADC2 -- 0; 43 | #OpAmp1 -- ADC1 -- 0; 44 | 45 | # or comment out these 3 lines and it works ok 46 | ADC3 -- 0; 47 | ADC2 -- 0; 48 | ADC1 -- 0; 49 | 50 | 51 | OpAmp3 -- ADC3; 52 | OpAmp2 -- ADC2; 53 | OpAmp1 -- ADC1; 54 | 55 | V1 -- Temp1 [style=dashed]; 56 | V2 -- Temp2 [style=dashed]; 57 | V3 -- Temp3 [style=dashed]; 58 | 59 | } 60 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/165_2.dot: -------------------------------------------------------------------------------- 1 | // see test_regression.py:test_165_2() 2 | digraph { 3 | a -> b [label="hello \\\" world"]; 4 | } 5 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/165_3.dot: -------------------------------------------------------------------------------- 1 | // see test_regression.py:test_165_3() 2 | digraph { 3 | label="hello \\\" world"; 4 | a; 5 | } 6 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/167.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | concentrate=true; 3 | a -> 4 -> b 4 | a -> b 5 | a -> b 6 | b -> a 7 | } 8 | 9 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1724.dot: -------------------------------------------------------------------------------- 1 | digraph{ 2 | newrank= 3 | D a->ÿ 4 | 0pack=8} 5 | 6 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1767.dot: -------------------------------------------------------------------------------- 1 | digraph clusters { 2 | subgraph cluster_0 { 3 | a -> b -> c -> d -> e 4 | } 5 | 6 | subgraph cluster_1 { 7 | a -> f -> c 8 | } 9 | 10 | subgraph cluster_2 { 11 | rank = same 12 | p1 13 | p2 14 | p3->f 15 | } 16 | 17 | subgraph cluster_3 { 18 | rank = same 19 | S1->a 20 | S2->f 21 | S3->p1 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1783.dot: -------------------------------------------------------------------------------- 1 | digraph code { 2 | edge [weight=1073741824]; 3 | "1" -> "0"; 4 | } 5 | 6 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1845.dot: -------------------------------------------------------------------------------- 1 | digraph { 2 | fear -> anger; 3 | } 4 | 5 | digraph { 6 | anger -> hate; 7 | } 8 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1855.dot: -------------------------------------------------------------------------------- 1 | digraph { 2 | graph[size="10.0624,6.11863",ratio=fill]; 3 | overlap=false; 4 | splines=true; 5 | node[fontname="Helvetica"]; 6 | edge[fontname="Helvetica"]; 7 | 2->1[color=black]; 8 | 3->1[color=black]; 9 | 4->1[color=black]; 10 | 5->1[color=black]; 11 | 6->1[color=black]; 12 | 7->1[color=black]; 13 | 8->1[color=black]; 14 | 9->1[color=black]; 15 | 10->1[color=black]; 16 | 11->1[color=black]; 17 | 12->1[color=black]; 18 | 13->1[color=black]; 19 | 14->1[color=black]; 20 | 15->1[color=black]; 21 | 16->1[color=black]; 22 | 17->1[color=black]; 23 | 18->1[color=black]; 24 | 19->1[color=black]; 25 | 20->1[color=black]; 26 | 21->1[color=black]; 27 | 22->1[color=black]; 28 | 23->1[color=black]; 29 | 24->1[color=black]; 30 | 25->1[color=black]; 31 | 26->1[color=black]; 32 | 27->1[color=black]; 33 | 28->1[color=black]; 34 | 29->1[color=black]; 35 | 30->1[color=black]; 36 | 31->1[color=black]; 37 | 32->1[color=black]; 38 | 1[label=""]; 39 | 2[label=""]; 40 | 3[label=""]; 41 | 4[label=""]; 42 | 5[label=""]; 43 | 6[label=""]; 44 | 7[label=""]; 45 | 8[label=""]; 46 | 9[label=""]; 47 | 10[label=""]; 48 | 11[label=""]; 49 | 12[label=""]; 50 | 13[label=""]; 51 | 14[label=""]; 52 | 15[label=""]; 53 | 16[label=""]; 54 | 17[label=""]; 55 | 18[label=""]; 56 | 19[label=""]; 57 | 20[label=""]; 58 | 21[label=""]; 59 | 22[label=""]; 60 | 23[label=""]; 61 | 24[label=""]; 62 | 25[label=""]; 63 | 26[label=""]; 64 | 27[label=""]; 65 | 28[label=""]; 66 | 29[label=""]; 67 | 30[label=""]; 68 | 31[label=""]; 69 | 32[label="",style=filled,color=pink]; 70 | 1[style=filled,color=black,fillcolor=lightcyan2]; 71 | } 72 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1856.dot: -------------------------------------------------------------------------------- 1 | digraph graphname 2 | { 3 | splines=ortho; 4 | 1 [ width=1, height=1, shape=rect ]; 5 | 2 [ width=1, height=1, shape=rect ]; 6 | 3 [ width=3, height=3, shape=rect ]; 7 | 4 [ width=1, height=1, shape=rect ]; 8 | 5 [ width=1, height=1, shape=rect ]; 9 | 1 -> 2[arrowhead=none, headport=n, tailport=s]; 10 | 1 -> 3[arrowhead=none, headport=n, tailport=s]; 11 | 1 -> 4[arrowhead=none, headport=n, tailport=s]; 12 | 2 -> 4[arrowhead=none, headport=n, tailport=s]; 13 | 2 -> 5[arrowhead=none, headport=n, tailport=s]; 14 | 3 -> 4[arrowhead=none, headport=n, tailport=s]; 15 | 3 -> 5[arrowhead=none, headport=n, tailport=s]; 16 | 4 -> 5[arrowhead=none, headport=n, tailport=s]; 17 | } 18 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/1865.dot: -------------------------------------------------------------------------------- 1 | strict digraph "FTC/BTC" { 2 | subgraph cluster_Inputs { 3 | "Base (FTC) holding" 4 | } 5 | } 6 | 7 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/358.dot1: -------------------------------------------------------------------------------- 1 | digraph H { 2 | xdotversion=1.7 3 | rankdir=LR 4 | a [label=<Bold text>] 5 | b [label=<Italic text>] 6 | c [label=<Underlined text>] 7 | d [label=<Overstrike text>] 8 | e [label=<Subscript text>] 9 | f [label=<Superscript text>] 10 | g [label=<Strikethrough text>] 11 | h [label=<Courier text>] 12 | i [label=<fontsize 36 text>] 13 | } 14 | 15 | -------------------------------------------------------------------------------- /test/src/test/resources/dot/random/925.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | rankdir=LR; 3 | node[shape=record style=rounded]; 4 | reclat[label="Ok with spaces (en):|{ AAA AAA AAA | BBB BBB BBB | CCC CCC CCC }"]; 5 | recrus[label="Eats spaces (utf):|{ ААА ААА ААА | ВВВ ВВВ ВВВ | ССС ССС ССС }"]; 6 | } 7 | -------------------------------------------------------------------------------- /test/src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /test/src/test/resources/table/table_1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
1111111111111111
22222222222222222222
1111111111111111111111111111
-------------------------------------------------------------------------------- /test/src/test/resources/table/table_3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
First NameLast NameEmail Address
HillaryNyakunditables@mail.com
LaryMakdeveloper@mail.com
-------------------------------------------------------------------------------- /test/src/test/resources/table/table_4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
NameSubjectMarks
HillaryAdvanced Web75
Operating Syatem60
LaryAdvanced Web80
Operating Syatem75
Total Average: 72.5
-------------------------------------------------------------------------------- /test/src/test/resources/table/table_5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
Animals
Hippopotamus
HorseMare
Stallion
Crocodile
ChickenHen
Rooster
26 | -------------------------------------------------------------------------------- /test/src/test/resources/table/table_6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
title1title2title3
9 | 10 | 11 | 12 | 13 | 14 | 15 |
cell1cell2cell3
16 |
cell2cell3
cell4cell5cell6
26 | -------------------------------------------------------------------------------- /test/src/test/resources/table/table_7.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 |
First Column of Outer Table 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
First row of Inner Table
Second row of Inner Table
13 |
-------------------------------------------------------------------------------- /test/src/test/resources/table/table_8.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
NameAge
JillSmith43
EveJackson57
--------------------------------------------------------------------------------