eea.plotly 1.5__tar.gz → 1.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. {eea_plotly-1.5/eea.plotly.egg-info → eea_plotly-1.6}/PKG-INFO +8 -2
  2. {eea_plotly-1.5 → eea_plotly-1.6}/docs/HISTORY.txt +6 -0
  3. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/browser/preview.py +4 -1
  4. eea_plotly-1.6/eea/plotly/browser/preview_adapter/soer_miniature.py +148 -0
  5. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/deserializer/dxcontent.py +4 -1
  6. eea_plotly-1.6/eea/plotly/io_json.py +12 -0
  7. eea_plotly-1.6/eea/plotly/version.txt +1 -0
  8. {eea_plotly-1.5 → eea_plotly-1.6/eea.plotly.egg-info}/PKG-INFO +8 -2
  9. {eea_plotly-1.5 → eea_plotly-1.6}/eea.plotly.egg-info/SOURCES.txt +1 -0
  10. {eea_plotly-1.5 → eea_plotly-1.6}/eea.plotly.egg-info/requires.txt +1 -1
  11. {eea_plotly-1.5 → eea_plotly-1.6}/setup.py +1 -1
  12. eea_plotly-1.5/eea/plotly/browser/preview_adapter/soer_miniature.py +0 -80
  13. eea_plotly-1.5/eea/plotly/version.txt +0 -1
  14. {eea_plotly-1.5 → eea_plotly-1.6}/CONTRIBUTING.md +0 -0
  15. {eea_plotly-1.5 → eea_plotly-1.6}/MANIFEST.in +0 -0
  16. {eea_plotly-1.5 → eea_plotly-1.6}/README.rst +0 -0
  17. {eea_plotly-1.5 → eea_plotly-1.6}/docs/LICENSE.GPL +0 -0
  18. {eea_plotly-1.5 → eea_plotly-1.6}/docs/LICENSE.txt +0 -0
  19. {eea_plotly-1.5 → eea_plotly-1.6}/eea/__init__.py +0 -0
  20. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/README.txt +0 -0
  21. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/__init__.py +0 -0
  22. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/behaviors.py +0 -0
  23. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/browser/__init__.py +0 -0
  24. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/browser/configure.zcml +0 -0
  25. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/browser/controlpanel.py +0 -0
  26. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/browser/preview_adapter/adapter.py +0 -0
  27. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/browser/pt/visualization_view.pt +0 -0
  28. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/configure.zcml +0 -0
  29. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/controlpanel.py +0 -0
  30. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/deserializer/blocks.py +0 -0
  31. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/deserializer/configure.zcml +0 -0
  32. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/deserializer/dxfields.py +0 -0
  33. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/interfaces.py +0 -0
  34. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/io_csv.py +0 -0
  35. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/__init__.py +0 -0
  36. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/bg/LC_MESSAGES/eea.po +0 -0
  37. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/bg/LC_MESSAGES/plone.po +0 -0
  38. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/cs/LC_MESSAGES/eea.po +0 -0
  39. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/cs/LC_MESSAGES/plone.po +0 -0
  40. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/da/LC_MESSAGES/eea.po +0 -0
  41. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/da/LC_MESSAGES/plone.po +0 -0
  42. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/de/LC_MESSAGES/eea.po +0 -0
  43. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/de/LC_MESSAGES/plone.po +0 -0
  44. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/eea.pot +0 -0
  45. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/el/LC_MESSAGES/eea.po +0 -0
  46. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/el/LC_MESSAGES/plone.po +0 -0
  47. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/en/LC_MESSAGES/eea.po +0 -0
  48. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/en/LC_MESSAGES/plone.po +0 -0
  49. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/es/LC_MESSAGES/eea.po +0 -0
  50. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/es/LC_MESSAGES/plone.po +0 -0
  51. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/et/LC_MESSAGES/eea.po +0 -0
  52. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/et/LC_MESSAGES/plone.po +0 -0
  53. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/eu/LC_MESSAGES/eea.po +0 -0
  54. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/eu/LC_MESSAGES/plone.po +0 -0
  55. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/fi/LC_MESSAGES/eea.po +0 -0
  56. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/fi/LC_MESSAGES/plone.po +0 -0
  57. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/fr/LC_MESSAGES/eea.po +0 -0
  58. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/fr/LC_MESSAGES/plone.po +0 -0
  59. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/hr/LC_MESSAGES/eea.po +0 -0
  60. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/hr/LC_MESSAGES/plone.po +0 -0
  61. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/hu/LC_MESSAGES/eea.po +0 -0
  62. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/hu/LC_MESSAGES/plone.po +0 -0
  63. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/is/LC_MESSAGES/eea.po +0 -0
  64. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/is/LC_MESSAGES/plone.po +0 -0
  65. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/it/LC_MESSAGES/eea.po +0 -0
  66. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/it/LC_MESSAGES/plone.po +0 -0
  67. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/kl/LC_MESSAGES/eea.po +0 -0
  68. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/kl/LC_MESSAGES/plone.po +0 -0
  69. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/lt/LC_MESSAGES/eea.po +0 -0
  70. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/lt/LC_MESSAGES/plone.po +0 -0
  71. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/lv/LC_MESSAGES/eea.po +0 -0
  72. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/lv/LC_MESSAGES/plone.po +0 -0
  73. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/mt/LC_MESSAGES/eea.po +0 -0
  74. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/mt/LC_MESSAGES/plone.po +0 -0
  75. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/nl/LC_MESSAGES/eea.po +0 -0
  76. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/nl/LC_MESSAGES/plone.po +0 -0
  77. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/no/LC_MESSAGES/eea.po +0 -0
  78. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/no/LC_MESSAGES/plone.po +0 -0
  79. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/pl/LC_MESSAGES/eea.po +0 -0
  80. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/pl/LC_MESSAGES/plone.po +0 -0
  81. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/plone-manual.pot +0 -0
  82. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/pt/LC_MESSAGES/eea.po +0 -0
  83. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/pt/LC_MESSAGES/plone.po +0 -0
  84. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/pt_BR/LC_MESSAGES/eea.po +0 -0
  85. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/pt_BR/LC_MESSAGES/plone.po +0 -0
  86. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/ro/LC_MESSAGES/eea.po +0 -0
  87. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/ro/LC_MESSAGES/plone.po +0 -0
  88. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/ru/LC_MESSAGES/eea.po +0 -0
  89. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/ru/LC_MESSAGES/plone.po +0 -0
  90. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/sk/LC_MESSAGES/eea.po +0 -0
  91. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/sk/LC_MESSAGES/plone.po +0 -0
  92. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/sl/LC_MESSAGES/eea.po +0 -0
  93. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/sl/LC_MESSAGES/plone.po +0 -0
  94. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/sv/LC_MESSAGES/eea.po +0 -0
  95. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/sv/LC_MESSAGES/plone.po +0 -0
  96. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/tr/LC_MESSAGES/eea.po +0 -0
  97. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/tr/LC_MESSAGES/plone.po +0 -0
  98. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/update.sh +0 -0
  99. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/zh_TW/LC_MESSAGES/eea.po +0 -0
  100. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/locales/zh_TW/LC_MESSAGES/plone.po +0 -0
  101. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/permissions.zcml +0 -0
  102. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles/default/browserlayer.xml +0 -0
  103. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles/default/controlpanel.json +0 -0
  104. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles/default/controlpanel.xml +0 -0
  105. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles/default/metadata.xml +0 -0
  106. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles/default/registry.xml +0 -0
  107. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles/default/rolemap.xml +0 -0
  108. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles/default/types/visualization.xml +0 -0
  109. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles/default/types.xml +0 -0
  110. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles/uninstall/browserlayer.xml +0 -0
  111. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles/uninstall/controlpanel.xml +0 -0
  112. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles/uninstall/registry.xml +0 -0
  113. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/profiles.zcml +0 -0
  114. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/restapi/__init__.py +0 -0
  115. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/restapi/configure.zcml +0 -0
  116. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/restapi/controlpanel/__init__.py +0 -0
  117. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/restapi/controlpanel/configure.zcml +0 -0
  118. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/restapi/controlpanel/get.py +0 -0
  119. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/restapi/controlpanel/reset.py +0 -0
  120. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/restapi/visualization/configure.zcml +0 -0
  121. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/restapi/visualization/get.py +0 -0
  122. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/serializer/blocks.py +0 -0
  123. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/serializer/configure.zcml +0 -0
  124. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/serializer/dxfields.py +0 -0
  125. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/serializer/utils.py +0 -0
  126. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/setuphandlers.py +0 -0
  127. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/tests/__init__.py +0 -0
  128. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/tests/base.py +0 -0
  129. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/tests/test_doctests.py +0 -0
  130. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/upgrades/__init__.py +0 -0
  131. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/upgrades/configure.zcml +0 -0
  132. {eea_plotly-1.5 → eea_plotly-1.6}/eea/plotly/utils.py +0 -0
  133. {eea_plotly-1.5 → eea_plotly-1.6}/eea.plotly.egg-info/dependency_links.txt +0 -0
  134. {eea_plotly-1.5 → eea_plotly-1.6}/eea.plotly.egg-info/entry_points.txt +0 -0
  135. {eea_plotly-1.5 → eea_plotly-1.6}/eea.plotly.egg-info/namespace_packages.txt +0 -0
  136. {eea_plotly-1.5 → eea_plotly-1.6}/eea.plotly.egg-info/not-zip-safe +0 -0
  137. {eea_plotly-1.5 → eea_plotly-1.6}/eea.plotly.egg-info/top_level.txt +0 -0
  138. {eea_plotly-1.5 → eea_plotly-1.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eea.plotly
3
- Version: 1.5
3
+ Version: 1.6
4
4
  Summary: volto-plotlycharts backend support
5
5
  Home-page: https://github.com/eea/eea.plotly
6
6
  Author: European Environment Agency: IDM2 A-Team
@@ -23,7 +23,7 @@ Requires-Dist: setuptools
23
23
  Requires-Dist: plone.volto
24
24
  Requires-Dist: collective.folderishtypes
25
25
  Requires-Dist: plotly==5.24.1
26
- Requires-Dist: kaleido
26
+ Requires-Dist: kaleido==0.2.1
27
27
  Provides-Extra: test
28
28
  Requires-Dist: plone.app.testing; extra == "test"
29
29
  Dynamic: author
@@ -145,6 +145,12 @@ EEA_ - European Environment Agency (EU)
145
145
  Changelog
146
146
  =========
147
147
 
148
+ 1.6 - (2025-06-24)
149
+ ---------------------------
150
+ * Change: pin kaleido version to 0.2.1
151
+ * Refactor: soer_miniature adapter logic (new step functions, data trimming, axis ranges)
152
+ [razvanMiu]
153
+
148
154
  1.5 - (2025-06-05)
149
155
  ---------------------------
150
156
  * Change: soer_miniature: hide xaxis ticklabels if no data
@@ -1,6 +1,12 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ 1.6 - (2025-06-24)
5
+ ---------------------------
6
+ * Change: pin kaleido version to 0.2.1
7
+ * Refactor: soer_miniature adapter logic (new step functions, data trimming, axis ranges)
8
+ [razvanMiu]
9
+
4
10
  1.5 - (2025-06-05)
5
11
  ---------------------------
6
12
  * Change: soer_miniature: hide xaxis ticklabels if no data
@@ -9,6 +9,7 @@ from zope.publisher.interfaces import IPublishTraverse
9
9
  from Products.Five.browser import BrowserView
10
10
  from eea.plotly.controlpanel import IPlotlySettings
11
11
  from eea.plotly.utils import sanitizeVisualization
12
+ from eea.plotly.io_json import JSONEncoder
12
13
 
13
14
  from .preview_adapter.adapter import get_preview_adapter
14
15
 
@@ -74,7 +75,9 @@ class PlotlyPreview(BrowserView):
74
75
 
75
76
  get_preview_adapter(self, self.name)
76
77
 
77
- fig = pio.from_json(json.dumps(self.visualization), skip_invalid=True)
78
+ fig = pio.from_json(
79
+ json.dumps(self.visualization, cls=JSONEncoder),
80
+ skip_invalid=True)
78
81
 
79
82
  if "template" not in self.visualization["layout"]:
80
83
  fig.update_layout(template=None)
@@ -0,0 +1,148 @@
1
+ """ SOER miniature theme for Plotly visualizations. """
2
+ import math
3
+
4
+
5
+ def nice_step(vmin, vmax, target_ticks=5):
6
+ """Calculate a 'nice' step size for axis ticks, similar to Plotly/D3."""
7
+ span = abs(vmax - vmin)
8
+ if span == 0:
9
+ return 1 # fallback
10
+
11
+ raw_step = span / max(target_ticks - 1, 1)
12
+ magnitude = 10 ** math.floor(math.log10(raw_step))
13
+ residual = raw_step / magnitude
14
+
15
+ # D3/Plotly uses [1, 2, 2.5, 5, 10]
16
+ if residual <= 1:
17
+ nice_multiplier = 1
18
+ elif residual <= 2:
19
+ nice_multiplier = 2
20
+ elif residual <= 2.5:
21
+ nice_multiplier = 2.5
22
+ elif residual <= 5:
23
+ nice_multiplier = 5
24
+ else:
25
+ nice_multiplier = 10
26
+
27
+ return nice_multiplier * magnitude
28
+
29
+
30
+ def exact_step(vmin, vmax, target_ticks=5):
31
+ """Get the exact step size to have target_ticks between vmin and vmax."""
32
+ if target_ticks < 2:
33
+ raise ValueError("target_ticks must be at least 2 to define a range.")
34
+ return abs(vmax - vmin) / (target_ticks - 1)
35
+
36
+
37
+ def getMin(arr):
38
+ """ Get minimum value from array """
39
+ return min(float(v) for v in arr if v is not None)
40
+
41
+
42
+ def getMax(arr):
43
+ """ Get maximum value from array """
44
+ return max(float(v) for v in arr if v is not None)
45
+
46
+
47
+ def serialize(context):
48
+ """ Serialize the context for SOER miniature theme"""
49
+ if context.visualization is None:
50
+ return False
51
+
52
+ data = context.visualization["data"]
53
+ layout = context.visualization["layout"]
54
+ min_year = float("inf")
55
+ max_year = float("-inf")
56
+ first_val = None
57
+ new_x = []
58
+ new_y = []
59
+
60
+ if len(data) < 5:
61
+ layout["xaxis"]["showticklabels"] = False
62
+ return False
63
+
64
+ if "y" in data[0] and "x" in data[0]:
65
+ for index, val in enumerate(data[0]["y"]):
66
+ if val and not first_val:
67
+ first_val = val
68
+ if not first_val:
69
+ continue
70
+ year = data[0]["x"][index]
71
+ new_x.append(year)
72
+ new_y.append(val)
73
+ if val and year > max_year:
74
+ max_year = year
75
+ if val and year < min_year:
76
+ min_year = year
77
+
78
+ text_len = len(data[0]["text"])
79
+ data[0]["x"] = new_x
80
+ data[0]["y"] = new_y
81
+ data[0]["text"] = data[0]["text"][text_len - len(new_y):text_len + 1]
82
+
83
+ if data[4].get("x") and data[4].get("y"):
84
+ y_len = len(data[0]["y"])
85
+ y4_len = len(data[4]["y"])
86
+ data[4]["x"] = new_x
87
+ data[4]["y"] = data[4]["y"][y4_len - y_len:y4_len + 1]
88
+ else:
89
+ data[4] = {
90
+ "type": "scatter",
91
+ "x": new_x,
92
+ "y": [None] * len(new_y),
93
+ "visible": True,
94
+ "marker": {
95
+ "color": "rgba(0, 0, 0, 0)",
96
+ "line": {
97
+ "color": "rgba(0, 0, 0, 0)"
98
+ }
99
+ }
100
+ }
101
+ data[4]["y"][len(data[4]["y"]) - 1] = new_y[-1]
102
+
103
+ layout["xaxis"]["tickmode"] = "array"
104
+ layout["xaxis"]["tickvals"] = [min_year, max_year, 2030]
105
+ layout["xaxis"]["range"] = [
106
+ min_year - 1, 2032]
107
+ layout["xaxis"]["autorange"] = True
108
+
109
+ y_values = (
110
+ (data[0].get("y") or []) +
111
+ (data[1].get("y") or []) +
112
+ (data[4].get("y") or [])
113
+ )
114
+
115
+ if y_values:
116
+ top = layout["margin"]["t"] or layout["template"]["margin"]["t"]
117
+ min_y = getMin(y_values)
118
+ max_y = getMax(y_values)
119
+
120
+ min_y = min_y if min_y < 0 else 0
121
+ max_y = max_y if max_y > 0 else 0
122
+
123
+ nticks = max(int((context.height - top) / 100), 2)
124
+
125
+ step = exact_step(min_y, max_y, nticks)
126
+
127
+ layout["yaxis"]["tickmode"] = "linear"
128
+ layout["yaxis"]["nticks"] = nticks
129
+ layout["yaxis"]["tick0"] = min_y - step
130
+ layout["yaxis"]["dtick"] = step
131
+
132
+ layout["yaxis"]["range"] = [
133
+ min_y - step, max_y + 2 * step]
134
+ layout["yaxis"]["autorange"] = False
135
+
136
+ if "text" in data[0]:
137
+ data[0]["text"] = [
138
+ (t if t is None else " " + str(t))
139
+ for t in data[0]["text"]]
140
+
141
+ data[1]["x"] = None
142
+ data[1]["y"] = None
143
+ data[2]["x"] = None
144
+ data[2]["y"] = None
145
+ data[3]["x"] = None
146
+ data[3]["y"] = None
147
+
148
+ return True
@@ -12,6 +12,7 @@ from zope.event import notify
12
12
  from zope.lifecycleevent import Attributes, ObjectModifiedEvent
13
13
  from eea.plotly.behaviors import IPlotlyVisualization
14
14
  from eea.plotly.io_csv import CsvWriter
15
+ from eea.plotly.io_json import JSONEncoder
15
16
 
16
17
 
17
18
  @implementer(IDeserializeFromJson)
@@ -99,7 +100,9 @@ class DeserializeVisualizationFromJson(DeserializeFromJson):
99
100
  "data": self.context.visualization.get("data", []),
100
101
  "layout": self.context.visualization.get("layout", {}),
101
102
  "frames": self.context.visualization.get("frames", [])
102
- }),
103
+ },
104
+ cls=JSONEncoder
105
+ ),
103
106
  skip_invalid=True
104
107
  )
105
108
 
@@ -0,0 +1,12 @@
1
+ """JSON encoder that handles Decimal values."""
2
+ import decimal
3
+ import json
4
+
5
+
6
+ class JSONEncoder(json.JSONEncoder):
7
+ """JSON encoder that handles Decimal values."""
8
+
9
+ def default(self, o):
10
+ if isinstance(o, decimal.Decimal):
11
+ return str(o)
12
+ return super().default(o)
@@ -0,0 +1 @@
1
+ 1.6
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eea.plotly
3
- Version: 1.5
3
+ Version: 1.6
4
4
  Summary: volto-plotlycharts backend support
5
5
  Home-page: https://github.com/eea/eea.plotly
6
6
  Author: European Environment Agency: IDM2 A-Team
@@ -23,7 +23,7 @@ Requires-Dist: setuptools
23
23
  Requires-Dist: plone.volto
24
24
  Requires-Dist: collective.folderishtypes
25
25
  Requires-Dist: plotly==5.24.1
26
- Requires-Dist: kaleido
26
+ Requires-Dist: kaleido==0.2.1
27
27
  Provides-Extra: test
28
28
  Requires-Dist: plone.app.testing; extra == "test"
29
29
  Dynamic: author
@@ -145,6 +145,12 @@ EEA_ - European Environment Agency (EU)
145
145
  Changelog
146
146
  =========
147
147
 
148
+ 1.6 - (2025-06-24)
149
+ ---------------------------
150
+ * Change: pin kaleido version to 0.2.1
151
+ * Refactor: soer_miniature adapter logic (new step functions, data trimming, axis ranges)
152
+ [razvanMiu]
153
+
148
154
  1.5 - (2025-06-05)
149
155
  ---------------------------
150
156
  * Change: soer_miniature: hide xaxis ticklabels if no data
@@ -21,6 +21,7 @@ eea/plotly/configure.zcml
21
21
  eea/plotly/controlpanel.py
22
22
  eea/plotly/interfaces.py
23
23
  eea/plotly/io_csv.py
24
+ eea/plotly/io_json.py
24
25
  eea/plotly/permissions.zcml
25
26
  eea/plotly/profiles.zcml
26
27
  eea/plotly/setuphandlers.py
@@ -2,7 +2,7 @@ setuptools
2
2
  plone.volto
3
3
  collective.folderishtypes
4
4
  plotly==5.24.1
5
- kaleido
5
+ kaleido==0.2.1
6
6
 
7
7
  [test]
8
8
  plone.app.testing
@@ -46,7 +46,7 @@ setup(
46
46
  # -*- Extra requirements: -*-
47
47
  "collective.folderishtypes",
48
48
  'plotly==5.24.1',
49
- 'kaleido',
49
+ 'kaleido==0.2.1',
50
50
  ],
51
51
  extras_require={
52
52
  'test': [
@@ -1,80 +0,0 @@
1
- """ SOER miniature theme for Plotly visualizations. """
2
- import math
3
-
4
-
5
- def nice_step(vmin, vmax, target_ticks=5):
6
- """ Calculate a 'nice' step size for the axis ticks. """
7
- span = abs(vmax - vmin)
8
- if span == 0:
9
- return 1 # arbitrary fallback
10
-
11
- # Initial guess for raw step size
12
- raw_step = span / target_ticks
13
-
14
- # Determine the power of 10
15
- magnitude = 10 ** math.floor(math.log10(raw_step))
16
- residual = raw_step / magnitude
17
-
18
- # Choose a nice multiplier
19
- if residual < 1.5:
20
- nice_multiplier = 1
21
- elif residual < 3:
22
- nice_multiplier = 2
23
- elif residual < 7:
24
- nice_multiplier = 5
25
- else:
26
- nice_multiplier = 10
27
-
28
- return nice_multiplier * magnitude
29
-
30
-
31
- def getMin(arr):
32
- """ Get minimum value from array """
33
- return min(float(v) for v in arr if v is not None)
34
-
35
-
36
- def getMax(arr):
37
- """ Get maximum value from array """
38
- return max(float(v) for v in arr if v is not None)
39
-
40
-
41
- def serialize(context):
42
- """ Serialize the context for SOER miniature theme"""
43
-
44
- # Solve x axis range
45
- if context.visualization is None or len(context.visualization["data"]) < 2:
46
- context.visualization["layout"]["xaxis"]["showticklabels"] = False
47
- return False
48
-
49
- years = context.visualization["data"][0].get("x", [])
50
- tickvals = context.visualization["layout"]["xaxis"].get("tickvals", [])
51
-
52
- if tickvals and years:
53
- min_year = getMin(tickvals)
54
- max_year = getMax(years)
55
-
56
- context.visualization["layout"]["xaxis"]["range"] = [
57
- min_year - 2, max_year + 2]
58
- context.visualization["layout"]["xaxis"]["autorange"] = False
59
-
60
- # Solve y axis range
61
-
62
- y_values = context.visualization["data"][0].get(
63
- "y", []) + context.visualization["data"][1].get("y", [])
64
-
65
- if y_values:
66
- min_y = getMin(y_values)
67
- max_y = getMax(y_values)
68
-
69
- step = nice_step(min_y, max_y, 10)
70
-
71
- context.visualization["layout"]["yaxis"]["range"] = [
72
- min_y - step, max_y + step]
73
- context.visualization["layout"]["yaxis"]["autorange"] = False
74
-
75
- if "text" in context.visualization["data"][0]:
76
- context.visualization["data"][0]["text"] = [
77
- (t if t is None else " " + str(t))
78
- for t in context.visualization["data"][0]["text"]]
79
-
80
- return True
@@ -1 +0,0 @@
1
- 1.5
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes