Skip to content

chemdiagrams.managers.difference_manager

DifferenceManager

Container for methods related to calculating difference values for object collision avoidance and label placement. This manager does not store any state or rendered artists, but is kept separate for organizational purposes and to avoid circular imports.

Source code in src/chemdiagrams/managers/difference_manager.py
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
class DifferenceManager:
    """
    Container for methods related to calculating difference values
    for object collision avoidance and label placement. This manager does not store
    any state or rendered artists, but is kept separate for organizational
    purposes and to avoid circular imports.
    """

    @staticmethod
    def _get_diff_img_plateau(
        margins: dict[str, tuple],
        figsize: tuple[float, float],
    ) -> float:
        """Compute vertical spacing value for image plateau distance in data coordinates."""
        diff_to_plateau = (
            (margins["y"][1] - margins["y"][0]) / figsize[1] * constants.DISTANCE_IMAGE_LINE
        )
        return diff_to_plateau

    @staticmethod
    def _get_diff_img_number(
        margins: dict[str, tuple], figsize: tuple[float, float], fontsize
    ) -> float:
        """Compute vertical spacing value for image number distance in data coordinates."""
        diff_to_number = (
            (fontsize / constants.STD_FONTSIZE)
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
            * constants.DISTANCE_NUMBER_LINE
        )
        return diff_to_number

    @staticmethod
    def _get_diff_img_label(
        margins: dict[str, tuple],
        figsize: tuple[float, float],
        fontsize: int,
        labeltext: str,
    ) -> float:
        """Compute vertical spacing value for image label distance in data coordinates."""
        n_linebreaks = len(findall("\n", labeltext))
        diff_to_label = (
            (fontsize / constants.STD_FONTSIZE)
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
            * (
                constants.DISTANCE_IMAGE_LABEL
                + n_linebreaks * constants.DISTANCE_LABEL_NEWLINE
            )
        )
        return diff_to_label

    @staticmethod
    def _get_diff_plateau_label(
        margins: dict[str, tuple],
        figsize: tuple[float, float],
        fontsize: int,
        labeltext: str,
    ) -> float:
        """Compute vertical spacing value for plateau label distance in data coordinates."""
        n_linebreaks = len(findall("\n", labeltext))
        diff_to_label = (
            (fontsize / constants.STD_FONTSIZE)
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
            * (constants.DISTANCE_LABEL_LINE + n_linebreaks * constants.DISTANCE_LABEL_NEWLINE)
        )
        return diff_to_label

    @staticmethod
    def _get_number_diffs(
        margins: dict[str, tuple],
        figsize: tuple[float, float],
        fontsize: int,
    ) -> tuple[float, float]:
        """
        Compute vertical spacing values for label placement in data coordinates.

        Both values scale proportionally with font size, y-axis range, and
        figure height so that spacing remains visually consistent regardless
        of the diagram's scale.

        Returns
        -------
        diff_bias : float
            The vertical gap between an energy bar and the first label.
        diff_per_step : float
            The vertical distance between consecutive stacked labels.
        """
        diff_bias = (
            (fontsize / constants.STD_FONTSIZE)
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
            * constants.DISTANCE_NUMBER_LINE
        )
        diff_per_step = (
            (fontsize / constants.STD_FONTSIZE)
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
            * constants.DISTANCE_NUMBER_NUMBER
        )
        return diff_bias, diff_per_step

    @staticmethod
    def _get_axis_break_stopper_differences(
        margins: dict[str, tuple],
        figsize: tuple[float, float],
        angle: float,
    ) -> tuple[float, float]:
        """
        Compute data coordinate differences for axis break stoppers in x and y directions.
        """
        delta_x = (
            np.cos(angle * np.pi / 180)
            * 0.001
            * (margins["x"][1] - margins["x"][0])
            / figsize[0]
        )
        delta_y = (
            np.sin(angle * np.pi / 180)
            * 0.001
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
        )
        return delta_x, delta_y

    @staticmethod
    def _get_axis_break_whitespace_cover_width(
        margins: dict[str, tuple],
        figsize: tuple[float, float],
    ) -> float:
        """Compute data coordinate width for axis break whitespace cover."""
        cover_width = (
            constants.MERGED_PLATEAU_COVER_WIDTH
            * (margins["y"][1] - margins["y"][0])
            / figsize[1]
        )
        return cover_width