GithubHelp home page GithubHelp logo

layout's People

Contributors

azriel91 avatar ekinimo avatar holtjma avatar lucasvr avatar mizardx avatar nadavrot avatar nilslice avatar nokome avatar xenon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

layout's Issues

Integration with egui

I’d love to be able to integrate graphs from this crate into my UI through egui :)

[Feature Request] Foreign object, Vertex and Edge property generation

Hello! Ive been using your library to create interactive graphs via wasm. Its been a great experience so far!
Ive bodged your svg writer a bit to support foreign objects however its a horrible hack.

It would be really useful if there was an element kind like Box(impl ForeignObejct) where foreign object trait dictates how it would be rendered.

Another thing that would be really nice is to generate ids for vertices and edges. Currently i do that via requiring a queue of edges in the svg writer constructor , dequeue it at each draw_arrow/line call to generate edge ids and
creating an empty stack, pushing vertex names into the stack and generating an id string based on the vertex counts replacing it at the finalize call from the stack. Although it works mechanism is really flimsy. it would be really nice if RenderBackend trait supported that natively.

Here is what ive done so far. You can click on edges to remove them and click two vertices in row to bind them .Dont judge the code ive been messing with it for couple of days purely explotarily

crash: Boxes must not intersect

This input

digraph G {
node [width=0.13,height=0.13,fontsize=10,shape=point];
edge [fontsize=18,penwidth=1.3,arrowsize=1.3,fontname=Arial];
rankdir=LR;
labeljust=l;
margin=0;
10 -> 2 [minlen=1,color=black,label="0 (len=31,supp=56)"];
11 -> 10 [minlen=2,color=red,label="1 (len=402,supp=496)"];
10 -> 2 [minlen=1,color=black,label="2 (len=31,supp=20)"];
0 -> 8 [minlen=2,color=red,label="3 (len=154,supp=113)"];
5 -> 0 [minlen=1,color=black,label="4 (len=20,supp=27)"];
5 -> 0 [minlen=1,color=black,label="5 (len=20,supp=12)"];
2 -> 5 [minlen=1,color=black,label="6 (len=19,supp=51)"];
}

yields this error

Boxes must not intersect

0: ◼ layout-rs-0.1.1/src/topo/placer/verifier.rs:22

1: layout::topo::placer::verifier
   ◼ at layout-rs-0.1.1/src/topo/placer/verifier.rs:22:13
   layout::topo::placer::verifier
   ◼ at layout-rs-0.1.1/src/topo/placer/verifier.rs:5:5

2: layout::topo::placer::place::Placer
   ◼ at layout-rs-0.1.1/src/topo/placer/place.rs:60:9

3: layout::topo::layout::VisualGraph
   ◼ at layout-rs-0.1.1/src/topo/layout.rs:146:9

Feature request for ability to render UML class or erd diagrams

I found your library and it looks it has a great support for rendering orthogonal edge connections and nodes from dot files however I couldn’t find in Rust ecosystem any library thigh might support erd diagrams rendering from ie. dot format. From my research I found only GraphViz is able to render html tables embedded in node labels or edges with from and to arrow with cardianity. Have you considered to extend your library in such direction in the future?

The example dot file:

graph {
    graph [
        label=<<FONT POINT-SIZE="20">nfldb Entity-Relationship diagram (condensed)</FONT>>,
        labeljust=l,
        labelloc=t,
        rankdir=LR,
        splines=spline,
    ];
    node [
        label="\N",
        shape=plaintext,
    ];
    edge [
        color=gray50,
        minlen=2,
        style=dashed,
    ];
    "player" [
        label=<
<FONT FACE="Helvetica">
  <TABLE BORDER="0" CELLBORDER="1" CELLPADDING="4" CELLSPACING="0" BGCOLOR="#d0e0d0">
    <TR><TD><B><FONT POINT-SIZE="16">player</FONT></B></TD></TR>
    <TR><TD ALIGN="LEFT"><U>player_id</U> [varchar, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">full_name [varchar, null]</TD></TR>
    <TR><TD ALIGN="LEFT">team [varchar, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">position [player_pos, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">status [player_status, not null]</TD></TR>
  </TABLE>
</FONT>
>];
    "team" [
        label=<
<FONT FACE="Helvetica">
  <TABLE BORDER="0" CELLBORDER="1" CELLPADDING="4" CELLSPACING="0" BGCOLOR="#d0e0d0">
    <TR><TD><B><FONT POINT-SIZE="16">team</FONT></B></TD></TR>
    <TR><TD ALIGN="LEFT"><U>team_id</U> [varchar, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">city [varchar, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">name [varchar, not null]</TD></TR>
  </TABLE>
</FONT>
>];
    "game" [
        label=<
<FONT FACE="Helvetica">
  <TABLE BORDER="0" CELLBORDER="1" CELLPADDING="4" CELLSPACING="0" BGCOLOR="#ececfc">
    <TR><TD><B><FONT POINT-SIZE="16">game</FONT></B></TD></TR>
    <TR><TD ALIGN="LEFT"><U>gsis_id</U> [gameid, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">start_time [utctime, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">week [usmallint, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">season_year [usmallint, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">season_type [season_phase, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">finished [boolean, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">home_team [varchar, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">home_score [usmallint, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">away_team [varchar, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">away_score [usmallint, not null]</TD></TR>
  </TABLE>
</FONT>
>];
    "drive" [
        label=<
<FONT FACE="Helvetica">
  <TABLE BORDER="0" CELLBORDER="1" CELLPADDING="4" CELLSPACING="0" BGCOLOR="#ececfc">
    <TR><TD><B><FONT POINT-SIZE="16">drive</FONT></B></TD></TR>
    <TR><TD ALIGN="LEFT"><I><U>gsis_id</U></I> [gameid, not null]</TD></TR>
    <TR><TD ALIGN="LEFT"><U>drive_id</U> [usmallint, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">start_field [field_pos, null]</TD></TR>
    <TR><TD ALIGN="LEFT">start_time [game_time, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">end_field [field_pos, null]</TD></TR>
    <TR><TD ALIGN="LEFT">end_time [game_time, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">pos_team [varchar, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">pos_time [pos_period, null]</TD></TR>
  </TABLE>
</FONT>
>];
    "play" [
        label=<
<FONT FACE="Helvetica">
  <TABLE BORDER="0" CELLBORDER="1" CELLPADDING="4" CELLSPACING="0" BGCOLOR="#ececfc">
    <TR><TD><B><FONT POINT-SIZE="16">play</FONT></B></TD></TR>
    <TR><TD ALIGN="LEFT"><I><U>gsis_id</U></I> [gameid, not null]</TD></TR>
    <TR><TD ALIGN="LEFT"><I><U>drive_id</U></I> [usmallint, not null]</TD></TR>
    <TR><TD ALIGN="LEFT"><U>play_id</U> [usmallint, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">time [game_time, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">pos_team [varchar, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">yardline [field_pos, null]</TD></TR>
    <TR><TD ALIGN="LEFT">down [smallint, null]</TD></TR>
    <TR><TD ALIGN="LEFT">yards_to_go [smallint, null]</TD></TR>
  </TABLE>
</FONT>
>];
    "play_player" [
        label=<
<FONT FACE="Helvetica">
  <TABLE BORDER="0" CELLBORDER="1" CELLPADDING="4" CELLSPACING="0" BGCOLOR="#ececfc">
    <TR><TD><B><FONT POINT-SIZE="16">play_player</FONT></B></TD></TR>
    <TR><TD ALIGN="LEFT"><I><U>gsis_id</U></I> [gameid, not null]</TD></TR>
    <TR><TD ALIGN="LEFT"><I><U>drive_id</U></I> [usmallint, not null]</TD></TR>
    <TR><TD ALIGN="LEFT"><I><U>play_id</U></I> [usmallint, not null]</TD></TR>
    <TR><TD ALIGN="LEFT"><I><U>player_id</U></I> [varchar, not null]</TD></TR>
    <TR><TD ALIGN="LEFT">team [varchar, not null]</TD></TR>
  </TABLE>
</FONT>
>];
    "meta" [
        label=<
<FONT FACE="Helvetica">
  <TABLE BORDER="0" CELLBORDER="1" CELLPADDING="4" CELLSPACING="0" BGCOLOR="#fcecec">
    <TR><TD><B><FONT POINT-SIZE="16">meta</FONT></B></TD></TR>
    <TR><TD ALIGN="LEFT">version [smallint, null]</TD></TR>
    <TR><TD ALIGN="LEFT">season_type [season_phase, null]</TD></TR>
    <TR><TD ALIGN="LEFT">season_year [usmallint, null]</TD></TR>
    <TR><TD ALIGN="LEFT">week [usmallint, null]</TD></TR>
  </TABLE>
</FONT>
>];
    "player" -- "team" [ headlabel="1", taillabel="0..N" ];
    "game" -- "team" [ headlabel="1", taillabel="0..N" ];
    "game" -- "team" [ headlabel="1", taillabel="0..N" ];
    "drive" -- "team" [ headlabel="1", taillabel="0..N" ];
    "play" -- "team" [ headlabel="1", taillabel="0..N" ];
    "play_player" -- "team" [ headlabel="1", taillabel="0..N" ];
    "game" -- "drive" [ headlabel="0..N", taillabel="1" ];
    "game" -- "play" [ headlabel="0..N", taillabel="1" ];
    "game" -- "play_player" [ headlabel="0..N", taillabel="1" ];
    "drive" -- "play" [ headlabel="0..N", taillabel="1" ];
    "drive" -- "play_player" [ headlabel="0..N", taillabel="1" ];
    "play" -- "play_player" [ headlabel="0..N", taillabel="1" ];
    "player" -- "play_player" [ headlabel="0..N", taillabel="1" ];
}

Would it be some better method to draw tables than html tables? I generated this dot syntax by https://github.com/BurntSushi/erd which parses some custom markup syntax and produces dot files but as in all similar projects it uses GraphViz to render final digram. I would be nice to have everything in Rust to use it in eg wasm. I also think erd or class diagrams might need some different way of rendering in square grid not in top down hierarchy, I think similarly as in your example here https://github.com/nadavrot/layout/blob/master/inputs/5.dot but more compact also arrows should point the whole table node or given record from FK if it would match relation key also it shouldn't cross the node but anchored on the outside edge.

[Feature Request] Color Gradient support

Hello!
Thank you for this crate! I needed a quick way to draw graph in the browser and update it in real-time (I am using Yew as the frontend Framework), and it works great!

It would be nice to have a way to support something similar to the ColorList feature of graphivz:
https://graphviz.org/docs/attr-types/colorList/

In my specific use case I would like to represent the State of Charge of a battery as the fill color gradient. A bit like so as showed in the previous link:
image

If there is already another existing way to do so please let me know!
Thank you for your time

[Feature request] Make SVG arrowheads match the line color

Hello,

Fairly simple problem: when I generate an SVG image with a directed edge that is some non-black color (e.g., red blue etc.), the arrow head that is generated seems to always be black. I did not see an option to change this via API.

I manually modified the output files and added fill="context-stroke" to each marker and that resolved it, while also allowing for multiple edge colors in the output graph. I hypothesize that it's as simple as modifying the static at this line to resolve this:

<polygon points="0 0, 10 3.5, 0 7" />

Happy to submit a PR myself if it is that simple, but I wasn't sure if there are some non-obvious issues with those changes.

generated svg different to expected spec

generated with layout-rs
generated with cli tool dot -Tsvg foo > x.svg

The source dot file is both times:

digraph {
node [colorscheme=rdylgn10]
    0 [ label="GoblinTower"]
    1 [ label="Goldmine"]
    2 [ label="💀",fillcolor=black,shape=doublecircle,style=filled,fontname="NotoColorEmoji"]
    3 [ label="",fillcolor=black,shape=doublecircle,style=filled,fontname="NotoColorEmoji"]
    1 -> 0 [ label="Plinko"]

}

Can be checked out in paritytech/orchestra#43 when run with cargo test --all-features

The expectation would be to obtain the identical rendering as retrieved.

Is there anything else you'd need or how I can help?

Stuck or slow with big graph

Hi,

Wanted to compare the perf. of your lib with Graphviz dot on some examples where dot is really slow at making the layout.
The DOT file I tried may have hit either a bug in the lib, or there is some algorithm that is slow.

The input file has around 700 nodes and at least that many edges - it's the CFG of a function being optimized by MSVC.
With Graphviz, dot took 1m 52s to complete. layout after >10 min is still not done. Built it on a Mac and took with the Process monitor several samples, all seem to be similar, with this deep call tree showing up each time. Build is done in release mode.

2330 layout::topo::layout::VisualGraph::do_it::h4815c5196694548a (in run) + 181 [0x104ef6fd5] 2330 layout::topo::layout::VisualGraph::to_valid_dag::hd5e8ba77059eb154 (in run) + 1129 [0x104ef7a19] 2330 layout::adt::dag::DAG::verify::h0fcd6cdb9de61321 (in run) + 406 [0x104eec266] 2330 layout::adt::dag::DAG::is_reachable_inner::h765e6031c3bd508a (in run) + 152 [0x104eec488] 2330 layout::adt::dag::DAG::is_reachable_inner::h765e6031c3bd508a (in run) + 152 [0x104eec488] 2330 layout::adt::dag::DAG::is_reachable_inner::h765e6031c3bd508a (in run) + 152 [0x104eec488] and lots more calls to is_reachable_inner

Sharing the input DOT file here:
https://gist.github.com/gratianlup/f51dd6efc7ebc314d12a317dd0b01c60

And the sampling summary with the call graph here:
https://gist.github.com/gratianlup/8e7d8fd3c9883108ba9e55a87f0464eb

Thanks,
Gratian

Feature request: add geometry methods to support edge rendering edge case

Given more than one edge between two nodes exists, all sibling edges should be spaced appropriately to minimize intersections and overlapping between siblings.

In this example, the dashed and normal edges between Node 1 and Node 2 follow along the same path between nodes.

use layout::adt::dag::NodeHandle;
use layout::core::base::Orientation;
use layout::core::style::LineStyleKind;
use layout::core::style::StyleAttr;
use layout::std_shapes::shapes::Element;
use layout::std_shapes::shapes::LineEndKind;
use layout::std_shapes::shapes::ShapeKind;

let mut svg_writer: layout::backends::svg::SVGWriter = layout::backends::svg::SVGWriter::new();
let mut graph: layout::topo::layout::VisualGraph = layout::topo::layout::VisualGraph::new(layout::core::base::Orientation::LeftToRight);

let node_1: Element = Element::create(
    ShapeKind::new_circle(&"Node 1"),
    StyleAttr::simple(),
    Orientation::LeftToRight,
    layout::core::geometry::Point::new(100., 100.));
let node_2: Element = Element::create(
    ShapeKind::new_circle(&"Node 2"),
    StyleAttr::simple(),
    Orientation::LeftToRight,
    layout::core::geometry::Point::new(100., 100.));
let handle_1: NodeHandle = graph.add_node(node_1);
let handle_2: NodeHandle = graph.add_node(node_2);
// Dashed edge.
graph.add_edge(layout::std_shapes::shapes::Arrow::new(
    LineEndKind::Arrow,
    LineEndKind::None,
    LineStyleKind::Dashed,
    &"",
    &StyleAttr::simple(),
    &None,
    &None),
    handle_2,
    handle_1);
// Normal edge
graph.add_edge(layout::std_shapes::shapes::Arrow::new(
    LineEndKind::Arrow,
    LineEndKind::None,
    LineStyleKind::Normal,
    &"",
    &StyleAttr::simple(),
    &None,
    &None),
    handle_1,
    handle_2);

graph.do_it(false, false, false, &mut svg_writer);
std::fs::write(path, &svg_writer.finalize());

edges

Any plans to publish this to crates.io?

Hi,
I've discovered the project from HN, as you probably have guessed. I would be excited to add this as a dependency for one of my personal projects. The way I'm used to is by configuring the dependency in Cargo.toml, which pulls crates from crates.io (I think this is best practice). Are there any plans to publish this crate as well?

Feature request: support some GraphViz features

Hi -- this crate is really cool!!

I tested an example

digraph G {
node [width=0.13,height=0.13,fontsize=10,shape=point];
edge [fontsize=18,penwidth=1.3,arrowsize=1.3,fontname=Arial];
rankdir=LR;
labeljust=l;
margin=0;
15 -> 10 [minlen=2,color=red,label="0 (len=173,supp=807)"];
5 -> 15 [minlen=2,color=red,label="1 (len=430,supp=1567)"];
10 -> 7 [minlen=1,color=black,label="2 (len=26,supp=541)"];
7 -> 10 [minlen=1,color=black,label="3 (len=30,supp=951)"];
0 -> 7 [minlen=2,color=red,label="4 (len=618,supp=3220)"];
14 -> 13 [minlen=2,color=red,label="5 (len=632,supp=269)"];
11 -> 15 [minlen=1,color=black,label="6 (len=43,supp=40)"];
}

and got this output

image

as compared to what running dot yields

image

It would be awesome to get closer to the dot output.

Thank you very much!!

Can I use this in a browser?

So it seems rust can easily be compiled to WebAssembly, at least that's what I read. Is there anything stopping me from throwing this in a compiler and having it generate an svg in the browser by throwing my dot source into the module? I don't really understand how to build or integrate WASM yet, this is like my first try of understanding that.

Feature request: support portPos

Hi!

As a user, I would like to request support for compass points in the src_port/tailport and dst_port/headport properties of arrows in graphviz. This would allow me to specify which side of a node an arrow should originate from or end at, without having to manually define ports.

Doc for the portPos type.

Example:

digraph G {
  B -> A:sw;
}

Rendered:
image

With a box shape:

digraph G {
    {
        a [shape=box]
        b [shape=box]
    }
  a:e -> b:nw;
}

image

License?

What license is the code being published under?

I suspect a related question will be: How much of it was developed via inspection of the original graphviz code? (That may make it subject to the license for that code, which is presented here; that document says it uses "The Common Public License Version 1.0" that was produced from the Eclipse project.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.