Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Potential fix to the tooltip with special characters bug #1203

Merged
merged 25 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b5c395e
Potential solution
anushkrishnav May 30, 2024
e1c93e1
Push update
anushkrishnav May 31, 2024
e6fdc4c
Fixed linting issues
anushkrishnav Jun 1, 2024
a33216f
Fix to linting issues
anushkrishnav Jun 1, 2024
0e91fcd
minor fix
anushkrishnav Jun 1, 2024
62c5330
using serde_json instead of manually escaping
anushkrishnav Jun 1, 2024
1198483
fix import, and added test case
anushkrishnav Jun 3, 2024
779cf41
Updated test logic
anushkrishnav Jun 4, 2024
08db533
updated test to check to_dot
anushkrishnav Jun 6, 2024
e34992d
fix clippy issues
anushkrishnav Jun 6, 2024
eada72e
created release notes
anushkrishnav Jun 6, 2024
5d80799
fix release notes
anushkrishnav Jun 6, 2024
c4b08b7
fix linting issue in test
anushkrishnav Jun 8, 2024
8efa8f5
remove unused import
anushkrishnav Jun 9, 2024
2f61dcd
fixing quotes issue
anushkrishnav Jun 10, 2024
90b147b
fixing "\" issue and updating tests
anushkrishnav Jun 10, 2024
15dd143
updating more test to have quotes
anushkrishnav Jun 10, 2024
ea682d7
Update dot_utils.rs
anushkrishnav Jun 11, 2024
98549c8
Apply suggestions from code review
IvanIsCoding Jun 11, 2024
fc3d0e6
Collect vector of results in Rust
IvanIsCoding Jun 11, 2024
d69397f
Fix error handling
IvanIsCoding Jun 11, 2024
f75b894
Merge branch 'main' into anush_unitary
IvanIsCoding Jun 11, 2024
ddbe304
Update releasenotes/notes/fix-graphviz-draw-tooltip-3f697d71c4b79e60.…
IvanIsCoding Jun 11, 2024
84f800e
Update releasenotes/notes/fix-graphviz-draw-tooltip-3f697d71c4b79e60.…
IvanIsCoding Jun 11, 2024
01cd323
Update releasenotes/notes/fix-graphviz-draw-tooltip-3f697d71c4b79e60.…
IvanIsCoding Jun 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions releasenotes/notes/fix-graphviz-draw-tooltip-3f697d71c4b79e60.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
fixes:
- |
Fix to `attr_map_to_string` method not handling escaped characters in tooltip correctly issue, Issue #750
:meth:`attr_map_to_string` now escapes characters in tooltip using `serde_json::to_string()`
Added relevant test to ensure it escapes characters correctly.
IvanIsCoding marked this conversation as resolved.
Show resolved Hide resolved

.. jupyter-execute::

import rustworkx as rx
from rustworkx.visualization import graphviz_draw

graphviz_draw(
rx.generators.path_graph(2),
filename="graph.svg",
image_type="svg",
node_attr_fn=lambda x: {"label": "the\nlabel", "tooltip": "the\ntooltip"},
)
IvanIsCoding marked this conversation as resolved.
Show resolved Hide resolved
IvanIsCoding marked this conversation as resolved.
Show resolved Hide resolved
15 changes: 8 additions & 7 deletions src/dot_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,18 @@ fn attr_map_to_string<'a>(
if attrs.is_empty() {
return Ok("".to_string());
}

let attr_string = attrs
.iter()
.map(|(key, value)| {
if key == "label" {
format!("{}=\"{}\"", key, value)
} else {
format!("{}={}", key, value)
}
let escaped_value = serde_json::to_string(value).map_err(|_err| {
pyo3::exceptions::PyValueError::new_err("could not escape character")
})?;
let escaped_value = &escaped_value.get(1..escaped_value.len() - 1).ok_or(
pyo3::exceptions::PyValueError::new_err("could not escape character"),
)?;
Ok(format!("{}=\"{}\"", key, escaped_value))
})
.collect::<Vec<String>>()
.collect::<PyResult<Vec<String>>>()?
.join(", ");
Ok(format!("[{}]", attr_string))
}
6 changes: 3 additions & 3 deletions tests/digraph/test_dot.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def test_digraph_to_dot_to_file(self):
)
graph.add_edge(0, 1, dict(label="1", name="1"))
expected = (
'digraph {\n0 [color=black, fillcolor=green, label="a", '
'style=filled];\n1 [color=black, fillcolor=red, label="a", '
'style=filled];\n0 -> 1 [label="1", name=1];\n}\n'
'digraph {\n0 [color="black", fillcolor="green", label="a", '
'style="filled"];\n1 [color="black", fillcolor="red", label="a", '
'style="filled"];\n0 -> 1 [label="1", name="1"];\n}\n'
)
res = graph.to_dot(lambda node: node, lambda edge: edge, filename=self.path)
self.addCleanup(os.remove, self.path)
Expand Down
18 changes: 9 additions & 9 deletions tests/graph/test_dot.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ def test_graph_to_dot(self):
)
graph.add_edge(0, 1, dict(label="1", name="1"))
expected = (
'graph {\n0 [color=black, fillcolor=green, label="a", style=filled'
'];\n1 [color=black, fillcolor=red, label="a", style=filled];'
'\n0 -- 1 [label="1", name=1];\n}\n'
'graph {\n0 [color="black", fillcolor="green", label="a", style="filled"'
'];\n1 [color="black", fillcolor="red", label="a", style="filled"];'
'\n0 -- 1 [label="1", name="1"];\n}\n'
)
res = graph.to_dot(lambda node: node, lambda edge: edge)
self.assertEqual(expected, res)
Expand All @@ -70,9 +70,9 @@ def test_digraph_to_dot(self):
)
graph.add_edge(0, 1, dict(label="1", name="1"))
expected = (
'digraph {\n0 [color=black, fillcolor=green, label="a", '
'style=filled];\n1 [color=black, fillcolor=red, label="a", '
'style=filled];\n0 -> 1 [label="1", name=1];\n}\n'
'digraph {\n0 [color="black", fillcolor="green", label="a", '
'style="filled"];\n1 [color="black", fillcolor="red", label="a", '
'style="filled"];\n0 -> 1 [label="1", name="1"];\n}\n'
)
res = graph.to_dot(lambda node: node, lambda edge: edge)
self.assertEqual(expected, res)
Expand All @@ -97,9 +97,9 @@ def test_graph_to_dot_to_file(self):
)
graph.add_edge(0, 1, dict(label="1", name="1"))
expected = (
'graph {\n0 [color=black, fillcolor=green, label="a", '
'style=filled];\n1 [color=black, fillcolor=red, label="a", '
'style=filled];\n0 -- 1 [label="1", name=1];\n}\n'
'graph {\n0 [color="black", fillcolor="green", label="a", '
'style="filled"];\n1 [color="black", fillcolor="red", label="a", '
'style="filled"];\n0 -- 1 [label="1", name="1"];\n}\n'
)
res = graph.to_dot(lambda node: node, lambda edge: edge, filename=self.path)
self.addCleanup(os.remove, self.path)
Expand Down
34 changes: 33 additions & 1 deletion tests/visualization/test_graphviz.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import subprocess
import tempfile
import unittest

import rustworkx
from rustworkx.visualization import graphviz_draw

Expand Down Expand Up @@ -150,3 +149,36 @@ def test_filename(self):
self.assertTrue(os.path.isfile("test_graphviz_filename.svg"))
if not SAVE_IMAGES:
self.addCleanup(os.remove, "test_graphviz_filename.svg")

def test_escape_sequences(self):
anushkrishnav marked this conversation as resolved.
Show resolved Hide resolved
# Create a simple graph
graph = rustworkx.generators.path_graph(2)

escape_sequences = {
"\\n": "\n", # Newline
"\\t": "\t", # Horizontal tab
"\\'": "'", # Single quote
'\\"': '"', # Double quote
"\\\\": "\\", # Backslash
"\\r": "\r", # Carriage return
"\\b": "\b", # Backspace
"\\f": "\f", # Form feed
}

for escaped_seq, raw_seq in escape_sequences.items():

def node_attr(node):
"""
Define node attributes including escape sequences for labels and tooltips.
"""
label = f"label{escaped_seq}"
tooltip = f"tooltip{escaped_seq}"
return {"label": label, "tooltip": tooltip}

# Draw the graph using graphviz_draw
dot_str = graph.to_dot(node_attr)

# Assert that the escape sequences are correctly placed and escaped in the dot string
self.assertIn(
escaped_seq, dot_str, f"Escape sequence {escaped_seq} not found in dot output"
)
Loading