-
Notifications
You must be signed in to change notification settings - Fork 38
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
Support for gradients #94
Conversation
Reviewer's Guide by SourceryThis pull request adds support for gradients in the graphviz2drawio library. The changes primarily affect the parsing of SVG elements and the creation of nodes with gradient fills. The implementation includes new functions for extracting gradient information from SVG elements and modifications to existing functions to handle gradient fills in nodes. File-Level Changes
Tips
|
Warning Rate limit exceeded@hbmartin has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 16 minutes and 26 seconds before requesting another review. How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. WalkthroughThe recent changes enhance the functionality and robustness of the SVG handling modules. Key updates include replacing the tag counting functionality with a list retrieval method, improving gradient parsing capabilities, and enhancing node styling to support gradient fills. Error handling was added to color adjustments, and new linting rules were introduced for better code quality. Collectively, these modifications promote greater versatility, usability, and maintainability in the SVG processing workflow. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant SvgParser
participant NodeFactory
participant Node
User->>SvgParser: Parse SVG
SvgParser->>NodeFactory: Create nodes with gradients
NodeFactory->>Node: Create Node with fill/gradient
Node-->>NodeFactory: Return Node
NodeFactory-->>SvgParser: Return nodes and edges
SvgParser-->>User: Return parsed SVG structure
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @hbmartin - I've reviewed your changes and they look great!
Here's what I looked at during the review
- 🟡 General issues: 4 issues found
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟡 Complexity: 1 issue found
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment to tell me if it was helpful.
from ..models.Rect import Rect | ||
from .GraphObj import GraphObj | ||
from .MxConst import VERTICAL_ALIGN | ||
from .Styles import Styles | ||
from .Text import Text | ||
|
||
Gradient: TypeAlias = tuple[str, str | None, str] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Consider using a class or dataclass for Gradient instead of a tuple
Using a tuple for Gradient might lead to less self-documenting code. Consider defining a proper class or dataclass for Gradient, which would provide better type hinting and make the code more readable and maintainable.
from dataclasses import dataclass
@dataclass
class Gradient:
start_color: str
end_color: str | None
direction: str
@@ -46,21 +50,29 @@ | |||
def get_node_style(self) -> str: | |||
style_for_shape = Styles.get_for_shape(self.shape) | |||
dashed = 1 if self.dashed else 0 | |||
additional_styling = "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (complexity): Consider using a dictionary to manage attributes for the Gradient
type.
The new code introduces additional complexity due to type checking for the fill
attribute, which can now be either a str
or a Gradient
tuple. This adds extra logic to handle different types, making the code harder to read and maintain. The get_node_style
method now includes logic for the Gradient
type, increasing cognitive load. Additionally, string concatenation for additional_styling
can be error-prone and less efficient. To simplify, consider using a more structured approach to handle the Gradient
type, such as using a dictionary to manage attributes and updating it in a single step if fill
is a Gradient
. This will improve readability and maintainability by reducing branching and string concatenation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Files selected for processing (6)
- graphviz2drawio/models/SVG.py (1 hunks)
- graphviz2drawio/models/SvgParser.py (3 hunks)
- graphviz2drawio/mx/Node.py (3 hunks)
- graphviz2drawio/mx/NodeFactory.py (6 hunks)
- graphviz2drawio/mx/utils.py (1 hunks)
- pyproject.toml (1 hunks)
Additional comments not posted (8)
graphviz2drawio/models/SVG.py (1)
14-15
: LGTM! But verify the function usage in the codebase.The
findall
function provides more flexibility by returning a list of elements. Ensure that all code usingcount_tags
has been updated to handle the new return type.Verification successful
Function Usage Verified:
findall
Handles List Return Type CorrectlyThe
findall
function's usage throughout the codebase correctly handles the list of elements it returns. Instances intest/test_graphs.py
,graphviz2drawio/models/SvgParser.py
, andgraphviz2drawio/mx/NodeFactory.py
show appropriate handling such as iterating over the list and checking its length. No further action is needed.Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify all function calls to `findall` handle the new return type. # Test: Search for the function usage. Expect: Code handling the list of elements returned. rg --type python -A 5 $'findall'Length of output: 62
Script:
#!/bin/bash # Description: Verify all function calls to `findall` handle the new return type. # Test: Search for the function usage. Expect: Code handling the list of elements returned. rg --type py -A 5 $'findall'Length of output: 2620
pyproject.toml (1)
32-32
: Approved: Enhanced linting configuration.Adding
SvgParser.py
to the linting configuration for complexity and parameter checks is a positive step towards maintaining code quality.graphviz2drawio/mx/Node.py (2)
1-2
: Addition ofGradient
type alias.The
Gradient
type alias is defined as a tuple of three strings, which seems appropriate for handling gradient information. Ensure that this aligns with the expected structure throughout the codebase.
19-19
: Update to__init__
method to support gradients.The
fill
parameter now accepts astr
orGradient
, enhancing flexibility. Ensure that all instances ofNode
are updated to handle this change.graphviz2drawio/mx/NodeFactory.py (2)
21-26
: Modification offrom_svg
method to include gradients.The method now accepts a
gradients
dictionary, allowing for more dynamic SVG processing. Ensure that the dictionary is correctly populated and used throughout the SVG parsing process.
100-105
: Introduction of_extract_stroke
method.The separation of fill and stroke extraction improves clarity and maintainability. The method correctly adjusts stroke opacity. Ensure consistent usage across the codebase.
graphviz2drawio/models/SvgParser.py (2)
37-58
: Enhancements inparse_nodes_edges_clusters
for gradient handling.The introduction of a
gradients
dictionary and its integration into node parsing improves SVG rendering capabilities. Ensure that gradient definitions are correctly identified and processed.
92-127
: Gradient extraction logic in_extract_gradients
.The method effectively handles both radial and linear gradients, yielding structured gradient data. Consider optimizing the extraction process if performance becomes an issue with large SVG files.
_fill_url_re = re.compile(r"url\(#([^)]+)\)") | ||
|
||
@staticmethod | ||
def _extract_fill_and_stroke(g: Element) -> tuple[str, str]: | ||
def _extract_fill(g: Element, gradients: dict[str, Gradient]) -> str | Gradient: | ||
fill = g.attrib.get("fill", MxConst.NONE) | ||
stroke = g.attrib.get("stroke", MxConst.NONE) | ||
if fill.startswith("url"): | ||
match = NodeFactory._fill_url_re.search(fill) | ||
if match is not None: | ||
return gradients[match.group(1)] | ||
if "fill-opacity" in g.attrib and fill != MxConst.NONE: | ||
fill = adjust_color_opacity(fill, float(g.attrib["fill-opacity"])) | ||
return fill |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tip
Codebase Verification
Enhance Error Handling in _extract_fill
Method
The _extract_fill
method currently lacks handling for cases where a gradient ID is not found in the gradients
dictionary, which may result in a KeyError
. Consider implementing error handling or a fallback mechanism to improve robustness.
- File:
graphviz2drawio/mx/NodeFactory.py
- Lines: 87-98
Analysis chain
Enhancements in _extract_fill
method for gradient handling.
The method correctly identifies and retrieves gradients using a regex pattern. Consider handling cases where the gradient ID is not found in the dictionary to prevent potential KeyError
.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify handling of missing gradient IDs in `_extract_fill`.
# Test: Search for `_extract_fill` calls. Expect: Proper error handling or fallback for missing gradient IDs.
rg --type python -A 5 $'_extract_fill('
Length of output: 119
Script:
#!/bin/bash
# Corrected script to verify handling of missing gradient IDs in `_extract_fill`.
# Search for `_extract_fill` calls in the codebase. Expect proper error handling or fallback for missing gradient IDs.
rg --type python -A 5 '_extract_fill\('
Length of output: 72
Script:
#!/bin/bash
# Corrected script with the right file type for Python to verify handling of missing gradient IDs in `_extract_fill`.
# Search for `_extract_fill` calls in the codebase. Expect proper error handling or fallback for missing gradient IDs.
rg --type py -A 5 '_extract_fill\('
Length of output: 1595
graphviz2drawio/models/SvgParser.py
Outdated
def _extract_stop_color(stop: ElementTree.Element) -> str | None: | ||
if (color := _stop_color_re.search(stop.attrib["style"])) is not None: | ||
if (opacity := _stop_opacity_re.search(stop.attrib["style"])) is not None: | ||
return adjust_color_opacity(color.group(1), float(opacity.group(1))) | ||
return color.group(1) | ||
return None | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introduction of _extract_stop_color
method.
This method encapsulates color and opacity extraction, enhancing modularity. Consider adding error handling for cases where style attributes are missing or malformed.
- if (color := _stop_color_re.search(stop.attrib["style"])) is not None:
+ if (style := stop.attrib.get("style")) and (color := _stop_color_re.search(style)):
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
def _extract_stop_color(stop: ElementTree.Element) -> str | None: | |
if (color := _stop_color_re.search(stop.attrib["style"])) is not None: | |
if (opacity := _stop_opacity_re.search(stop.attrib["style"])) is not None: | |
return adjust_color_opacity(color.group(1), float(opacity.group(1))) | |
return color.group(1) | |
return None | |
def _extract_stop_color(stop: ElementTree.Element) -> str | None: | |
if (style := stop.attrib.get("style")) and (color := _stop_color_re.search(style)): | |
if (opacity := _stop_opacity_re.search(style)) is not None: | |
return adjust_color_opacity(color.group(1), float(opacity.group(1))) | |
return color.group(1) | |
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Files selected for processing (2)
- README.md (1 hunks)
- graphviz2drawio/models/SvgParser.py (3 hunks)
Additional comments not posted (5)
README.md (1)
Line range hint
1-1
:
Note the removal of fill gradient support from the roadmap.The removal of the roadmap item for fill gradient support may imply a shift in project priorities or a reevaluation of this feature's importance. Ensure that this aligns with the project's current objectives.
graphviz2drawio/models/SvgParser.py (4)
37-37
: Initialize gradients dictionary.The initialization of the
gradients
dictionary is appropriate for collecting gradient definitions. Ensure that this dictionary is correctly populated and utilized throughout the function.
43-45
: Ensure correct extraction and usage of gradients.The extraction of gradients from both the root and group elements is crucial for applying them correctly. Verify that all necessary gradient definitions are captured and used appropriately.
Also applies to: 50-52
92-131
: Verify support for all gradient types and data correctness.The
_extract_gradients
function processes radial and linear gradients. Ensure that all necessary gradient types are supported and that the extracted data is correctly formatted for use in the application.Verification successful
Function supports necessary gradient types and data extraction is correct.
The
_extract_gradients
function inSvgParser.py
correctly handlesradialGradient
andlinearGradient
, which are the only gradient types present in the codebase. The extracted data is formatted appropriately for application use. No additional gradient types need to be supported at this time.
- Location:
graphviz2drawio/models/SvgParser.py
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify support for all gradient types and correctness of extracted data. # Test: Search for radialGradient and linearGradient to ensure all types are handled. rg --type python 'radialGradient|linearGradient'Length of output: 81
Script:
#!/bin/bash # Description: Verify support for all gradient types and correctness of extracted data. # Search for radialGradient and linearGradient in the codebase. rg 'radialGradient|linearGradient' # Search for any other gradient types that might be used. rg 'gradient'Length of output: 24562
54-58
: Incorporate gradients into node and cluster creation.The integration of gradient data into the
from_svg
calls for nodes and clusters enhances their visual representation. Ensure that theNodeFactory
correctly applies these gradients.Also applies to: 71-75
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
Quality Gate passedIssues Measures |
Summary by Sourcery
Introduce support for SVG gradients in the graph visualization conversion process, allowing nodes and clusters to use gradient fills. Enhance the SVG parsing logic to extract and apply gradients, and improve error handling in color opacity adjustments.
New Features:
Enhancements:
Summary by CodeRabbit
New Features
Bug Fixes
Documentation