besok / graphviz-rust Goto Github PK
View Code? Open in Web Editor NEWThe library provides basic functions to work with Graphviz dot lang from rust code.
Home Page: https://crates.io/crates/graphviz-rust
License: MIT License
The library provides basic functions to work with Graphviz dot lang from rust code.
Home Page: https://crates.io/crates/graphviz-rust
License: MIT License
Hi,
I noticed after enabling semi-colons the DotPrinter is adding an uneeded space after edges and before semicolons when there are no edge attributes.
Current Output Snippet:
node1 -> node2 [label=TRUE];
node2 -> node3 [label=FALSE];
node3 -> node4 ;
node4 -> node5 ;
node5 -> node6 ;
node4 -> node5 ;
Expected Results:
node1 -> node2 [label=TRUE];
node2 -> node3 [label=FALSE];
node3 -> node4;
node4 -> node5;
node5 -> node6;
node4 -> node5;
The parser is forbidding many characters it should not within the "double quoted string" variant of IDs.
FROM https://graphviz.org/doc/info/lang.html:
An ID is one of the following:
--
This graph doesn't parse yet it is valid dot.
digraph graph_test {
start [
label="This shouln't error"
];
end [
label="End"
];
start-> end;
}
--> 4:11
|
4 | label="This shouln't error"
| ^---
|
= expected id
--- it looks like the issue is here:
char = _{
!("\"" | "\\" | "\'") ~ ANY
| "\\" ~ ("\"" | "\'" | "\\" | "/" | "b" | "f" | "n" | "r" | "t")
// TODO: the following option is only valid for some attributes: https://graphviz.org/docs/attr-types/escString/
| "\\" ~ ("G" | "N" | "E" | "H" | "T" | "L")
| "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4})
}
Hi! Thanks for the wonderful package, but I have a problem on macOS. I tried to perform export to svg example and faced the error No such file or directory
.
Then I ran your tests and faced the same error
running 24 tests
test attributes::tests::test ... ok
test parser::test::edge_test ... ok
test parser::test::attr_test ... ok
test parser::test::comments_test ... ok
test parser::test::attr_stmts_test ... ok
test parser::test::edge_stmt_test ... ok
test parser::test::attr_list_test ... ok
test parser::test::node_test ... ok
test parser::test::node_id_test ... ok
test printer::tests::attr_test ... ok
test parser::test::vertex_test ... ok
test printer::tests::edge_test ... ok
test parser::test::stmt_test ... ok
test printer::tests::graph_attr_test ... ok
test parser::test::id_test ... ok
test printer::tests::graph_test ... ok
test printer::tests::node_id_test ... ok
test printer::tests::node_test ... ok
test parser::test::graph_test ... ok
test printer::tests::subgraph_test ... ok
test parser::test::graph_html_test ... ok
test tests::parse_test ... ok
test tests::exec_test ... FAILED
test tests::print_test ... ok
failures:
---- tests::exec_test stdout ----
thread 'tests::exec_test' panicked at 'called `Result::unwrap()` on an `Err` value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', src/lib.rs:194:12
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
tests::exec_test
test result: FAILED. 23 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
I tried running it with sudo
and it didn't help.
I have a graph that I want to parse which ends like this:
node_425887->node_425122
} // end G
And I get a parsing error:
thread 'main' panicked at 'called Result::unwrap()
on an Err
value: " --> 8685:3\n |\n8685 | } // end G\n | ^---\n |\n = expected EOI"', src/main.rs:7:62
The following graph is not parsed correctly:
digraph "test" {
A:s0 -> B;
}
It's parsed as
DiGraph {
id: Escaped("\"test\""), strict: false,
stmts: [
Node(Node { id: NodeId(Plain("A"), Some(Port(None, Some("s")))), attributes: [] }),
Edge(Edge { ty: Pair(N(NodeId(Plain("0"), None)), N(NodeId(Plain("B"), None))), attributes: [] })
]
}
while I would expect
DiGraph {
id: Escaped("\"test\""), strict: false,
stmts: [
Edge(Edge { ty: Pair(N(NodeId(Plain("A"), Some(Port(Some(Plain("s0")), None)))), N(NodeId(Plain("B"), None))), attributes: [] })
]
}
I'm able to fix this by swapping the parsing expressions for port
graphviz-rust/src/grammar/dot.pest
Line 19 in b9593c6
port = { (":" ~ id ~ (":" ~ compass)?) | (":" ~ compass) }
but this seems to fail to parse actual "compass" nodes (e.g. nodeId:n
, nodeId:s
, etc).
I created a simple test binary, but parsing fails:
use graphviz_rust as gv;
use color_eyre::{self, eyre::{Result, Report}};
use gv::{printer::PrinterContext, cmd::{CommandArg, Layout}};
const TEST: &'static str = "graph { a -- b }";
fn main() -> Result<()> {
color_eyre::install()?;
let graph = gv::parse(TEST).map_err(Report::msg)?;
let mut ctx = PrinterContext::default();
let layed_out = gv::exec(graph, &mut ctx, vec![CommandArg::Layout(Layout::Dot)])?;
println!("{}", &layed_out);
let graph = gv::parse(&layed_out).map_err(Report::msg)?;
gv::print(graph, &mut ctx);
Ok(())
}
This prints the following Layout
output:
graph {
graph [bb="0,0,54,108"];
node [label="\N"];
a [height=0.5,
pos="27,90",
width=0.75];
b [height=0.5,
pos="27,18",
width=0.75];
a -- b [pos="27,71.697 27,60.846 27,46.917 27,36.104"];
}
And then fails to parse the generated node
statement:
Error:
0: --> 3:14
|
3 | node [label="\N"];
| ^---
|
= expected id
Trying to parse Xdot
output fails even earlier:
Error:
0: --> 2:9
|
2 | graph [_draw_="c 9 -#fffffe00 C 7 -#ffffff P 4 0 0 0 108 54 108 54 0 ",
| ^---
|
= expected id
(obtained by adding , CommandArg::Format(Format::Xdot)
to the above exec
call`
Example:
let graph = {
use graphviz_rust::dot_generator::*;
graph!(strict di id!("h[t]"))
};
let mut ctx = PrinterContext::default();
ctx.with_indent_step(2);
let out = graph.print(&mut ctx);
Output (invalid DOT):
strict digraph h[t] {
}
Expected output:
strict digraph "h[t]" {
}
The structure of parsing GraphAttributes follows the notation but the fact that the seq of extra elements following after the node is concealed:
graph {
node[style=filled]; a b c d;
}
Therefore now it is being parsed as a set of independent statements but apparently, they have to be merged.
Hello,
The DotPrinter is adding an extra level of indentation for all statements of a graph. The default indentation is 2 spaces but statements have 4 spaces before them. I created issue #29 for the floating semi-colons.
With the following PrinterContext I am getting the below example output.
let flow_source = graph.print(PrinterContext::default().with_semi());
Example Output:
digraph graph_id {
node1[label="Label1"shape="Mrecord"];
node2[label="Label2",shape="Mrecord"];
node3[label="Label3",shape="Mrecord"];
node1 -> node2 ;
node2 -> node3 ;
}
Expected Output:
digraph graph_id {
node1[label="Label1"shape="Mrecord"];
node2[label="Label2",shape="Mrecord"];
node3[label="Label3",shape="Mrecord"];
node1 -> node2;
node2 -> node3;
}
I've implemented a fix for this issue, but I'd prefer to get #29 fixed before I create the a PR for this issue.
let id = i;
let label = format!(
"\"data={:.4} grad={:.4} {}\"",
value.borrow().data,
value.borrow().grad,
value.borrow().op.as_ref().unwrap_or(&"".to_string())
);
let node = stmt!(node!(id; attr!("shape", "box"), attr!("label", label)));
The above code works but if I take the \"
's away like so:
let id = i;
let label = format!(
"data={:.4} grad={:.4} {}",
value.borrow().data,
value.borrow().grad,
value.borrow().op.as_ref().unwrap_or(&"".to_string())
);
let node = stmt!(node!(id; attr!("shape", "box"), attr!("label", label)));
and try and save this graph to a file with
exec(
graph,
&mut PrinterContext::default(),
vec![
Format::Png.into(),
CommandArg::Output("./graph2.png".to_string()),
],
)
.unwrap();
println!("saved to file");
I crash with
saving to file
thread 'main' panicked at src\graph_rust.rs:86:6:
called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: "Error: C:\\Users\\BRIOCH~1\\AppData\\Local\\Temp\\.tmpKczFpE: syntax error in line 2 near '='\r\n" }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\debug\micrograd-rust.exe` (exit code: 101)
This is intuitive and the displayed labels don't even display "
at the beginning or end of my strings. I think them macro should encapsulate strings with "
on it's own, instead of leaving it as an exercise for the library user.
Hi, I'm currently using graphviz-rust to build some dependency graph visualizations and I've run into some small issues with the API that mildly affect UX.
No way to clone a cmd::Format
.
cmd::Format
doesn't implement Clone, so there's no way to set constants for default layouts, or take a desired layout as a command-line argument. It seems that it should be possible to derive Clone
on this type given that it's a simple enum.
No way to cache the result of print
ing a Graph
before passing it to exec
.
I'm currently building a Graph
then rendering it to svg, but I'd like to export the rendered .dot file as well. The exec
function exported from the crate root only takes a Graph
as an argument, but runs print
on it immediately. There's no way to reuse the result of print
and pass it directly to exec
afterward - this results in the graph needing to be print
ed twice in order to both save the raw .dot
markup and call graphviz on it. It would be nice to have a similar function, e.g. exec_from_dot_file
, that takes a string as input.
Nondescriptive error message when graphviz is missing from PATH
If the user doesn't have dot
in their PATH, exec
fails with an error No file or directory found
. It isn't immediately obvious what the source of this error is, or how to remedy it. exec
should ideally return a message telling the user to install graphviz
; this caveat is mentioned in the docs but buried inside the cmd
module.
Thank you for releasing this crate, it's super useful!
It is no way to use GraphAttributes
or any other builders like that:
GraphAttributes::attribute("val") == attr!("attribute", esc "\"val\"")
I would like to add support for printing attributes for nodes with multiple attributes on separate lines.
I will submit a PR for this shortly. Thanks for your consideration!
For example:
digraph multi {
a[shape=square]
aa[
color=blue,
shape=Mrecord
]
subgraph v {
aaa[shape=square]
aaaa[
color=red,
shape=Mrecord
]
aaa -> aaaa [label=FALSE]
}
a -> aa [label=TRUE,color=green]
}
Up until now, the docs are either absent or misleading.
WE need to update the docs for the macroses to make it more readable.
into-attr-derive is still using dot-generator v0.1.0 on creates.io. A new release will fix this
https://github.com/besok/graphviz-rust/blob/173c98f4e9d9d763c08c0a31abbc512ef56cb137/into-attr-derive/Cargo.toml
Likewise, all the dependent crates need to be updated.
I'm trying to build a graph programmatically.
I tried to create a list of Stmt
using a map like this:
let nodes : Vec<_> = some_collection.map(|n| {
let id = ...
let label = ...
node!(id; attr!("label",label))
}).collect();
let g = graph!(strict di id!("t"); nodes);
However it does not work, as node!
returns ()
and not a Stmt
.
Is there a way to do what I'm trying ?
The Graph enum and its fields should be visible.
For reasons where the printer interface does not satisfy more complex use-cases, e.g. interact with a graph database or such stuff
It seems attr!
lacks the graph attributes.
Needs to provide them
let subgraph_nodes: Vec<Stmt> = //...
subgraph!(subgraph_id.as_u128(), subgraph_nodes)
Works for me, but my subgraphs have no color or border. I want to assign SubgraphAttributes::label
in order to attempt to make the subgraphs visible. What is the valid syntax for that?
Hey!
First of all, thanks for the awesome library!
I am trying to create a uml diagram for my db and have issues with the parse function specifically on the code
<tr><td>address_id: int</td></tr>
I suspect its the dot.pest file the needs to be updated to handle special characters like : or _
thanks
I am trying to generate a png from a graph and am running into a problem.
The exec function returns Option and it looks like String cannot properly represent the contents of a png file.
When I write the contents of the string to a file, it is not a valid png file.
let graph_png = graphviz_rust::exec(
self.graph.clone(),
&mut PrinterContext::default(),
vec![graphviz_rust::cmd::Format::Png.into()],
)
.unwrap()
.as_bytes()
.to_vec();
std::fs::write("./generated.png", &graph_png).unwrap();
Makes exec
calls easier to write:
gv::exec(graph, &mut ctx, vec![Layout::Dot.into(), Format::Xdot.into()])?;
instead of
gv::exec(graph, &mut ctx, vec![CommandArg::Layout(Layout::Dot), CommandArg::Format(Format::Xdot)])?;
I'm wondering why NodeId
does not derive Eq
:
graphviz-rust/dot-structures/src/lib.rs
Lines 51 to 52 in d9e1ea0
Both Id
and Port
derive Eq
so NodeId
can derive it too.
crates.io classifies this package license as "non-standard". I was wondering if that's because there is no license
entry in the project's Cargo.toml.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.