{"id":13591006,"url":"https://github.com/nidi3/graphviz-java","last_synced_at":"2025-05-14T20:10:14.652Z","repository":{"id":10806147,"uuid":"43552369","full_name":"nidi3/graphviz-java","owner":"nidi3","description":"Use graphviz with pure java","archived":false,"fork":false,"pushed_at":"2023-05-25T04:52:52.000Z","size":10036,"stargazers_count":953,"open_issues_count":71,"forks_count":109,"subscribers_count":31,"default_branch":"master","last_synced_at":"2025-04-13T16:53:32.226Z","etag":null,"topics":["graphviz","java"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nidi3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null},"funding":{"github":"nidi3"}},"created_at":"2015-10-02T12:46:51.000Z","updated_at":"2025-04-13T01:06:50.000Z","dependencies_parsed_at":"2024-01-14T04:34:42.512Z","dependency_job_id":"fdc9d4ad-70ac-41ed-a811-aae2d5b4cb15","html_url":"https://github.com/nidi3/graphviz-java","commit_stats":null,"previous_names":[],"tags_count":58,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nidi3%2Fgraphviz-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nidi3%2Fgraphviz-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nidi3%2Fgraphviz-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nidi3%2Fgraphviz-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nidi3","download_url":"https://codeload.github.com/nidi3/graphviz-java/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253305707,"owners_count":21887433,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["graphviz","java"],"created_at":"2024-08-01T16:00:52.657Z","updated_at":"2025-05-14T20:10:14.629Z","avatar_url":"https://github.com/nidi3.png","language":"Java","readme":"# graphviz-java \u003cimg src=\"logo.png\" height=\"100\" align=\"middle\"\u003e\n[![Build Status](https://travis-ci.org/nidi3/graphviz-java.svg)](https://travis-ci.org/nidi3/graphviz-java)\n[![codecov](https://codecov.io/gh/nidi3/graphviz-java/branch/master/graph/badge.svg)](https://codecov.io/gh/nidi3/graphviz-java)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/guru.nidi/graphviz-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/guru.nidi/graphviz-java)\n[![](https://img.shields.io/github/sponsors/nidi3?style=social)](https://github.com/sponsors/nidi3)\n\nUse graphviz with pure java. Create graphviz models using java code and convert them into nice graphics.\n\n#### [How it works ](#user-content-how-it-works)\n#### [Prerequisites ](#user-content-prerequisites)\n#### [API ](#user-content-api)\n#### [Parsing ](#user-content-parsing)\n#### [Examples ](#user-content-examples)\n#### [Images ](#user-content-images)\n#### [Configuration ](#user-content-configuration)\n#### [Javadoc ](#javadoc)\n#### [Sketchy ](#sketchy)\n\n\n## How it works\nTo execute the graphviz layout engine, one of these options is used:\n- If the machine has graphviz installed and a `dot` command is available, spawn a new process running `dot`.\n- Use this [javascript version](https://github.com/mdaines/viz.js) of graphviz and execute it on the V8 javascript engine.\nThis is done with the bundled [J2V8](https://github.com/eclipsesource/J2V8) library.\n- Alternatively, the javascript can be executed on Java's own Nashorn or GraalVM engine (preferring Graal if both are available).\n\nThe method(s) to be used can be configured with the `Graphviz.useEngine()` method. \n\n## Prerequisites\n\nThis project heavily uses classes from `java.awt`. Therefore, **it does not work on android.**\n\n### Maven\n\nThis project is available via Maven:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eguru.nidi\u003c/groupId\u003e\n    \u003cartifactId\u003egraphviz-java\u003c/artifactId\u003e\n    \u003cversion\u003e0.18.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n`graphviz-java` contains all needed dependencies including one to `J2V8` for the current platform (Linux, Mac OS X, Windows). \nThis should be ok for most use cases. \n  \n**gradle does not support this way of defining a dependency.** Gradle users have to manually add a dependency to J2V8,\ne.g. `com.eclipsesource.j2v8:j2v8_linux_x86_64:4.6.0`\n\nInstead of `graphviz-java` there are two alternative dependencies that can be used: \n- `graphviz-java-all-j2v8` additionally contains dependencies to _all_ `J2V8` platforms. \n    So the same application can run on Linux, Mac OS X and Windows.  \n- `graphviz-java-min-deps` contains only dependencies that are absolutely necessary. \n    All other dependencies are marked as `optional` and must added manually. See the [pom.xml](graphviz-java-min-deps/pom.xml#L64-L90) for details.\n    \nInstead of `J2V8`, one can also use the JDK javascript engine Nashorn.\nIf Nashorn is too slow or on JDK version 15 or newer (where Nashorn has been removed),\nthe graal [javascript](https://github.com/graalvm/graaljs) engine is a third option.\nIt needs this additional dependency:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.graalvm.js\u003c/groupId\u003e\n    \u003cartifactId\u003ejs\u003c/artifactId\u003e\n    \u003cversion\u003e20.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n \n### Logging\nGraphviz-java uses the [SLF4J](https://www.slf4j.org/) facade to log. \nUsers must therefore provide a logging implementation like [LOGBack](https://logback.qos.ch/)\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ech.qos.logback\u003c/groupId\u003e\n    \u003cartifactId\u003elogback-classic\u003c/artifactId\u003e\n    \u003cversion\u003e1.2.3\u003c/version\u003e\n\u003c/dependency\u003e\n```\nor [Log4j](https://logging.apache.org/log4j/2.x/)\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.apache.logging.log4j\u003c/groupId\u003e\n    \u003cartifactId\u003elog4j-core\u003c/artifactId\u003e\n    \u003cversion\u003e2.13.0\u003c/version\u003e\n\u003c/dependency\u003e\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.apache.logging.log4j\u003c/groupId\u003e\n    \u003cartifactId\u003elog4j-slf4j-impl\u003c/artifactId\u003e\n    \u003cversion\u003e2.13.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## API\nThe API is separated into a mutable and immutable part.\nThe basic usage is as follows (assuming `import static guru.nidi.graphviz.model.Factory.*`).\n\n### Immutable\n[//]: # (basic)\n```java\nGraph g = graph(\"example1\").directed()\n        .graphAttr().with(Rank.dir(LEFT_TO_RIGHT))\n        .nodeAttr().with(Font.name(\"arial\"))\n        .linkAttr().with(\"class\", \"link-class\")\n        .with(\n                node(\"a\").with(Color.RED).link(node(\"b\")),\n                node(\"b\").link(\n                        to(node(\"c\")).with(attr(\"weight\", 5), Style.DASHED)\n                )\n        );\nGraphviz.fromGraph(g).height(100).render(Format.PNG).toFile(new File(\"example/ex1.png\"));\n```\n[//]: # (end)\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex1.png\" height=\"100\"\u003e\n\n- Global attributes are set using the `graphAttr`, `linkAttr` and `nodeAttr` methods.\n- Nodes are styled using the `with` method. \n- To style edges, use the static method `to` which returns a `Link` that also has a `with` method.\n- The `with` method accepts predefined attributes like `Style`, `Arrow` or `Shape` \nas well as everything defined in the [Graphviz reference](https://graphviz.gitlab.io/_pages/doc/info/attrs.html)\ne.g. `with(\"weight\", 5)` or even arbitrary custom attributes.\n- Custom attribute classes can be defined by extending `SingleAttributes` or `MapAttributes`.\n \n**Attention:** `Node a = node(\"a\"); a.with(Color.RED);` Is not working as it might be expected. \nAll \"mutating\" methods like `with` on nodes, links and graphs create new objects and leave the original object unchanged.\nSo in the example above, variable `a` contains a node that is NOT red.\nIf you want a red node, do `a = a.with(Color.RED)` or use the mutable API.\n\n### Mutable\n[//]: # (mutable)\n```java\nMutableGraph g = mutGraph(\"example1\").setDirected(true).add(\n        mutNode(\"a\").add(Color.RED).addLink(mutNode(\"b\")));\nGraphviz.fromGraph(g).width(200).render(Format.PNG).toFile(new File(\"example/ex1m.png\"));\n```\n[//]: # (end)\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex1m.png\" width=\"100\"\u003e\n\nThe mutable API provides similar functions as the immutable one with slightly different syntax:\n- `mutGraph` instead of `graph`, `mutNode` instead of `node`\n- use setters: `setDirected` instead of `directed`\n- `add` instead of `width`  \n\n### Imperative\nThere is a third possibility to use the API, based on the mutable version.\nIts form is closer to the way dot files are written.\nIn the lambda of the `MutableGraph.use` method, all referenced nodes, links and graphs are automatically added to the parent graph,\nwithout explicitly calling the `add` method. \n\n[//]: # (imperative)\n```java\nMutableGraph g = mutGraph(\"example1\").setDirected(true).use((gr, ctx) -\u003e {\n    mutNode(\"b\");\n    nodeAttrs().add(Color.RED);\n    mutNode(\"a\").addLink(mutNode(\"b\"));\n});\nGraphviz.fromGraph(g).width(200).render(Format.PNG).toFile(new File(\"example/ex1i.png\"));\n```\n[//]: # (end)\nThis corresponds to the following `dot` file:\n```dot\ndigraph example1 {\n    b\n    node[color=red]\n    a -\u003e b\n}\n```\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex1i.png\" width=\"100\"\u003e\n\n### Kotlin DSL\n**Kotlin DSL is still experimental.** Things can change and any feedback is very welcome.\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eguru.nidi\u003c/groupId\u003e\n    \u003cartifactId\u003egraphviz-kotlin\u003c/artifactId\u003e\n    \u003cversion\u003e0.18.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nThe kotlin DSL based on the imperative API. It defines that following elements:\n\n- `edge`, `node`, `graph` variables to define global attributes.\n- `-`, `/`, `[]` operators on MutableNode which link, define ports, set attributes.\n- `-`, `/`, `[]` operators on String so that strings can be used directly to define nodes.\n- `-`, `[]` operators on Link which allow to chain links and set attributes.  \n\nTo enable the functions, use `import guru.nidi.graphviz.*`\n\n[//]: # (kotlin)\n```kotlin\ngraph(directed = true) {\n    edge[\"color\" eq \"red\", Arrow.TEE]\n    node[Color.GREEN]\n    graph[Rank.dir(LEFT_TO_RIGHT)]\n\n    \"a\" - \"b\" - \"c\"\n    (\"c\"[Color.RED] - \"d\"[Color.BLUE])[Arrow.VEE]\n    \"d\" / NORTH - \"e\" / SOUTH\n}.toGraphviz().render(PNG).toFile(File(\"example/ex1.png\"))\n```\n[//]: # (end)\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-kotlin/example/ex1.png\" width=\"500\"\u003e\n\n## Parsing\n\nDot files can be parsed and thus manipulated. Given this file `color.dot`:\n\n```\ngraph {\n    { rank=same; white}\n    { rank=same; cyan; yellow; pink}\n    { rank=same; red; green; blue}\n    { rank=same; black}\n\n    white -- cyan -- blue\n    white -- yellow -- green\n    white -- pink -- red\n\n    cyan -- green -- black\n    yellow -- red -- black\n    pink -- blue -- black\n}\n```\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex4-1.png\" width=\"400\"\u003e\n\nThen running this program:\n\n[//]: # (manipulate)\n```java\ntry (InputStream dot = getClass().getResourceAsStream(\"/color.dot\")) {\n    MutableGraph g = new Parser().read(dot);\n    Graphviz.fromGraph(g).width(700).render(Format.PNG).toFile(new File(\"example/ex4-1.png\"));\n\n    g.graphAttrs()\n            .add(Color.WHITE.gradient(Color.rgb(\"888888\")).background().angle(90))\n            .nodeAttrs().add(Color.WHITE.fill())\n            .nodes().forEach(node -\u003e\n            node.add(\n                    Color.named(node.name().toString()),\n                    Style.lineWidth(4), Style.FILLED));\n    Graphviz.fromGraph(g).width(700).render(Format.PNG).toFile(new File(\"example/ex4-2.png\"));\n}\n```\n[//]: # (end)\n\nresults in this graphics:\n\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex4-2.png\" width=\"400\"\u003e\n\n## Examples\n\n### Complex example\n\n[//]: # (complex)\n```java\nNode\n        main = node(\"main\").with(Label.html(\"\u003cb\u003emain\u003c/b\u003e\u003cbr/\u003estart\"), Color.rgb(\"1020d0\").font()),\n        init = node(Label.markdown(\"**_init_**\")),\n        execute = node(\"execute\"),\n        compare = node(\"compare\").with(Shape.RECTANGLE, Style.FILLED, Color.hsv(.7, .3, 1.0)),\n        mkString = node(\"mkString\").with(Label.lines(LEFT, \"make\", \"a\", \"multi-line\")),\n        printf = node(\"printf\");\n\nGraph g = graph(\"example2\").directed().with(\n        main.link(\n                to(node(\"parse\").link(execute)).with(LinkAttr.weight(8)),\n                to(init).with(Style.DOTTED),\n                node(\"cleanup\"),\n                to(printf).with(Style.BOLD, Label.of(\"100 times\"), Color.RED)),\n        execute.link(\n                graph().with(mkString, printf),\n                to(compare).with(Color.RED)),\n        init.link(mkString));\n\nGraphviz.fromGraph(g).width(900).render(Format.PNG).toFile(new File(\"example/ex2.png\"));\n```\n[//]: # (end)\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex2.png\" width=\"500\"\u003e\n\n### Example with records\n```java\nimport static guru.nidi.graphviz.attribute.Records.*;\nimport static guru.nidi.graphviz.model.Compass.*;\n```\n[//]: # (records)\n```java\nNode\n        node0 = node(\"node0\").with(Records.of(rec(\"f0\", \"\"), rec(\"f1\", \"\"), rec(\"f2\", \"\"), rec(\"f3\", \"\"), rec(\"f4\", \"\"))),\n        node1 = node(\"node1\").with(Records.of(turn(rec(\"n4\"), rec(\"v\", \"719\"), rec(\"\")))),\n        node2 = node(\"node2\").with(Records.of(turn(rec(\"a1\"), rec(\"805\"), rec(\"p\", \"\")))),\n        node3 = node(\"node3\").with(Records.of(turn(rec(\"i9\"), rec(\"718\"), rec(\"\")))),\n        node4 = node(\"node4\").with(Records.of(turn(rec(\"e5\"), rec(\"989\"), rec(\"p\", \"\")))),\n        node5 = node(\"node5\").with(Records.of(turn(rec(\"t2\"), rec(\"v\", \"959\"), rec(\"\")))),\n        node6 = node(\"node6\").with(Records.of(turn(rec(\"o1\"), rec(\"794\"), rec(\"\")))),\n        node7 = node(\"node7\").with(Records.of(turn(rec(\"s7\"), rec(\"659\"), rec(\"\"))));\nGraph g = graph(\"example3\").directed()\n        .graphAttr().with(Rank.dir(LEFT_TO_RIGHT))\n        .with(\n                node0.link(\n                        between(port(\"f0\"), node1.port(\"v\", SOUTH)),\n                        between(port(\"f1\"), node2.port(WEST)),\n                        between(port(\"f2\"), node3.port(WEST)),\n                        between(port(\"f3\"), node4.port(WEST)),\n                        between(port(\"f4\"), node5.port(\"v\", NORTH))),\n                node2.link(between(port(\"p\"), node6.port(NORTH_WEST))),\n                node4.link(between(port(\"p\"), node7.port(SOUTH_WEST))));\nGraphviz.fromGraph(g).width(900).render(Format.PNG).toFile(new File(\"example/ex3.png\"));\n```\n[//]: # (end)\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex3.png\" width=\"500\"\u003e\n\n## Images\nImages can be included in graphviz in two ways.\n\nOne possibility is using the \\\u003cimg\u003e tag inside a HTML label:\n\n[//]: # (img)\n```java\nGraphviz.useEngine(new GraphvizCmdLineEngine());\nGraphviz g = Graphviz.fromGraph(graph()\n        .with(node(Label.html(\"\u003ctable border='0'\u003e\u003ctr\u003e\u003ctd\u003e\u003cimg src='graphviz.png' /\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/table\u003e\"))));\ng.basedir(new File(\"example\")).render(Format.PNG).toFile(new File(\"example/ex7.png\"));\n```\n[//]: # (end)\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex7.png\" width=\"200\"\u003e\n\nBecause viz.js [does not support \\\u003cimg\u003e tags](https://github.com/mdaines/viz.js/issues/125),\n**this works only when using the command line engine**. \n\nThe other possibility is the `image` attribute of a node:\n\n[//]: # (image)\n```java\nGraphviz g = Graphviz.fromGraph(graph()\n        .with(node(\" \").with(Size.std().margin(.8, .7), Image.of(\"graphviz.png\"))));\ng.basedir(new File(\"example\")).render(Format.PNG).toFile(new File(\"example/ex8.png\"));\n```\n[//]: # (end)\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex8.png\" width=\"200\"\u003e\n\nThis works with all engines.\n\nIn both cases, the `basedir()` method can be used to define where relative paths are looked up.\n\n## Configuration\nThe size of the resulting image, the rendering engine and the output format can be configured:\n\n[//]: # (config)\n```java\nGraphviz.useEngine(new GraphvizCmdLineEngine()); // Rasterizer.builtIn() works only with CmdLineEngine\nGraph g = graph(\"example5\").directed().with(node(\"abc\").link(node(\"xyz\")));\nGraphviz viz = Graphviz.fromGraph(g);\nviz.width(200).render(Format.SVG).toFile(new File(\"example/ex5.svg\"));\nviz.width(200).rasterize(Rasterizer.BATIK).toFile(new File(\"example/ex5b.png\"));\nviz.width(200).rasterize(Rasterizer.SALAMANDER).toFile(new File(\"example/ex5s.png\"));\nviz.width(200).rasterize(Rasterizer.builtIn(\"pdf\")).toFile(new File(\"example/ex5p\"));\nString dot = viz.render(Format.DOT).toString();\nString json = viz.engine(Engine.NEATO).render(Format.JSON).toString();\nBufferedImage image = viz.render(Format.PNG).toImage();\n```\n[//]: # (end)\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex5.svg\" width=\"100\"\u003e\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex5b.png\" width=\"100\"\u003e\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex5s.png\" width=\"100\"\u003e\n\nTo rasterize with batik, provide this library on the classpath: \n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.apache.xmlgraphics\u003c/groupId\u003e\n    \u003cartifactId\u003ebatik-rasterizer\u003c/artifactId\u003e\n    \u003cversion\u003e1.13\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### Processors\nProcessors can be registered to further customize what goes in and out of the graphviz engine. \n- Pre processors change the dot file that is fed into the graphviz engine.\n- Post processor change the result of the graphviz engine (image, svg,...). \n\n[//]: # (processor)\n```java\nGraph graph = graph().with(node(\"bad word\").link(\"good word\"));\nGraphviz g = Graphviz.fromGraph(graph)\n        .preProcessor((source, options, processOptions) -\u003e source.replace(\"bad word\", \"unicorn\"))\n        .postProcessor((result, options, processOptions) -\u003e\n                result.mapString(svg -\u003e\n                        SvgElementFinder.use(svg, finder -\u003e {\n                            finder.findNode(\"unicorn\").setAttribute(\"class\", \"pink\");\n                        })));\ng.render(Format.PNG).toFile(new File(\"example/ex9.png\"));\n```\n[//]: # (end)\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-java/example/ex9.png\" width=\"200\"\u003e\n\n## Javadoc\nTo use graphviz inside javadoc comments, add this to `pom.xml`:\n```xml\n\u003cbuild\u003e\n  \u003cplugins\u003e\n    \u003cplugin\u003e\n      \u003cartifactId\u003emaven-javadoc-plugin\u003c/artifactId\u003e\n      \u003cversion\u003e3.1.0\u003c/version\u003e\n      \u003cconfiguration\u003e\n        \u003ctaglet\u003eguru.nidi.graphviz.taglet.GraphvizTaglet\u003c/taglet\u003e\n        \u003ctagletArtifact\u003e\n          \u003cgroupId\u003eguru.nidi\u003c/groupId\u003e\n          \u003cartifactId\u003egraphviz-taglet\u003c/artifactId\u003e\n          \u003cversion\u003e0.18.1\u003c/version\u003e\n        \u003c/tagletArtifact\u003e\n      \u003c/configuration\u003e\n    \u003c/plugin\u003e\n  \u003c/plugins\u003e\n\u003c/build\u003e\n```\nTo use this with JDK 9 or later, replace `graphviz-taglet`\nwith `graphviz-taglet9`.\n\nThe usage inside javadoc is then as follows:\n```java\n/**\n * Support graphviz inside javadoc.\n * \u003cp\u003e\n * {@graphviz\n * graph test { a -- b }\n * }\n * \u003c/p\u003e\n * So easy.\n */\npublic class GraphvizTaglet implements Taglet {}\n```\n\n## Sketchy\nTo change the appearance of the graph into something more sketchy / hand drawn, the `Roughifyer` processor can be used.\nFirst, add the rough module to the dependencies: \n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eguru.nidi\u003c/groupId\u003e\n    \u003cartifactId\u003egraphviz-rough\u003c/artifactId\u003e\n    \u003cversion\u003e0.18.1\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nThen, apply the `Roughifyer` to the graph: \n\n[//]: # (rough)\n```java\nfinal Graph g = graph(\"ex1\").directed().with(\n        graph().cluster()\n                .nodeAttr().with(Style.FILLED, Color.WHITE)\n                .graphAttr().with(Style.FILLED, Color.LIGHTGREY, Label.of(\"process #1\"))\n                .with(node(\"a0\").link(node(\"a1\").link(node(\"a2\")))),\n        graph(\"x\").cluster()\n                .nodeAttr().with(Style.FILLED)\n                .graphAttr().with(Color.BLUE, Label.of(\"process #2\"))\n                .with(node(\"b0\").link(node(\"b1\").link(node(\"b2\")))),\n        node(\"start\").with(Shape.M_DIAMOND).link(\"a0\", \"b0\"),\n        node(\"a0\").with(Style.FILLED, Color.RED.gradient(Color.BLUE)).link(\"b1\"),\n        node(\"b1\").link(\"a2\"),\n        node(\"a2\").link(\"end\"),\n        node(\"b2\").link(\"end\"),\n        node(\"end\").with(Shape.M_SQUARE)\n);\n\nGraphviz.fromGraph(g)\n        .processor(new Roughifyer()\n                .bowing(2)\n                .curveStepCount(6)\n                .roughness(1)\n                .fillStyle(FillStyle.hachure().width(2).gap(5).angle(0))\n                .font(\"*serif\", \"Comic Sans MS\"))\n        .render(Format.PNG)\n        .toFile(new File(\"example/ex1-rough.png\"));\n```\n[//]: # (end)\n\u003cimg src=\"https://rawgit.com/nidi3/graphviz-java/master/graphviz-rough/example/ex1-rough.png\" width=\"200\"\u003e\n","funding_links":["https://github.com/sponsors/nidi3"],"categories":["Java"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnidi3%2Fgraphviz-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnidi3%2Fgraphviz-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnidi3%2Fgraphviz-java/lists"}