Coverage for src/plotly_gtk/widgets/annotation.py: 34%
38 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-08 21:22 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-11-08 21:22 +0000
1import random
3import gi
4import numpy as np
6gi.require_version("Gdk", "4.0")
7gi.require_version("Gtk", "4.0")
8from typing import TYPE_CHECKING
10from gi.repository import Gdk, Gtk, Pango # noqa: E402
12from plotly_gtk.utils import parse_font, update_dict
13from plotly_gtk.widgets.base import Base
15if TYPE_CHECKING:
16 from plotly_gtk.chart import PlotlyGtk
18Spec = None | list["Spec"] | dict[str, "Spec"]
21class Annotation(Base):
22 def __init__(self, plot: "PlotlyGtk", annotation: Spec):
23 super().__init__()
25 self.label = Gtk.Label(label=annotation["text"])
26 self.append(self.label)
28 self.spec = annotation
30 font = annotation["font"]
31 defaults = plot.layout["font"]
32 font = update_dict(defaults, font)
34 if "textangle" in annotation:
35 angle = annotation["textangle"]
36 else:
37 angle = 0
39 width = self.get_preferred_size()[-1].width
40 height = self.get_preferred_size()[-1].height
41 baseline_offset = height - self.measure(Gtk.Orientation.VERTICAL, -1)[-1]
42 xoffset = (
43 width * (1 - np.cos(np.deg2rad(angle))) / 2
44 - (height + 2 * baseline_offset) * np.sin(np.deg2rad(angle)) / 2
45 )
46 if annotation["xanchor"] == "left":
47 annotation["xoffset"] = -xoffset
48 elif annotation["xanchor"] == "right":
49 annotation["xoffset"] = xoffset
51 custom_css = Gtk.CssProvider()
52 index = random.random()
53 custom_css.load_from_string(
54 f"""
55 .plotly-annotation label {
56 color: {font["color"]};
57 font-family: {font["family"]};
58 font-size: {font["size"]}px;
59 font-style: {font["style"]};
60 font-variant: {font["variant"]};
61 font-weight: {font["weight"]};
62 }
63 .rotated-{angle}-text {
64 transform: rotate({angle}deg);
65 }
66 """
67 )
68 Gtk.StyleContext().add_provider_for_display(
69 Gdk.Display().get_default(),
70 custom_css,
71 Gtk.STYLE_PROVIDER_PRIORITY_USER,
72 )
74 self.add_css_class(f"plotly-annotation")
75 self.add_css_class(f"rotated-{angle}-text")