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

1import random 

2 

3import gi 

4import numpy as np 

5 

6gi.require_version("Gdk", "4.0") 

7gi.require_version("Gtk", "4.0") 

8from typing import TYPE_CHECKING 

9 

10from gi.repository import Gdk, Gtk, Pango # noqa: E402 

11 

12from plotly_gtk.utils import parse_font, update_dict 

13from plotly_gtk.widgets.base import Base 

14 

15if TYPE_CHECKING: 

16 from plotly_gtk.chart import PlotlyGtk 

17 

18Spec = None | list["Spec"] | dict[str, "Spec"] 

19 

20 

21class Annotation(Base): 

22 def __init__(self, plot: "PlotlyGtk", annotation: Spec): 

23 super().__init__() 

24 

25 self.label = Gtk.Label(label=annotation["text"]) 

26 self.append(self.label) 

27 

28 self.spec = annotation 

29 

30 font = annotation["font"] 

31 defaults = plot.layout["font"] 

32 font = update_dict(defaults, font) 

33 

34 if "textangle" in annotation: 

35 angle = annotation["textangle"] 

36 else: 

37 angle = 0 

38 

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 

50 

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 ) 

73 

74 self.add_css_class(f"plotly-annotation") 

75 self.add_css_class(f"rotated-{angle}-text")