scitex 2.10.3__py3-none-any.whl → 2.11.0__py3-none-any.whl

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 (363) hide show
  1. scitex/__init__.py +1 -4
  2. scitex/__version__.py +1 -1
  3. scitex/_install_guide.py +14 -2
  4. scitex/bridge/_figrecipe.py +1 -1
  5. scitex/bridge/_helpers.py +1 -1
  6. scitex/bridge/_plt_vis.py +1 -1
  7. scitex/bridge/_stats_plt.py +1 -1
  8. scitex/bridge/_stats_vis.py +2 -2
  9. scitex/{fig → canvas}/__init__.py +84 -96
  10. scitex/{fig → canvas}/backend/_parser.py +1 -1
  11. scitex/{fig → canvas}/canvas.py +13 -14
  12. scitex/{fts/_fig/_editor → canvas/editor}/_defaults.py +2 -2
  13. scitex/{fig → canvas}/editor/edit/__init__.py +11 -14
  14. scitex/{fig → canvas}/editor/edit/bundle_resolver.py +56 -48
  15. scitex/{fig → canvas}/editor/edit/editor_launcher.py +79 -26
  16. scitex/{fts/_fig/_editor/_cui/_panel_loader.py → canvas/editor/edit/panel_loader.py} +8 -8
  17. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_bbox.py +2 -1
  18. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_core.py +84 -84
  19. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_renderer.py +7 -6
  20. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/static/css/features/canvas.css +2 -2
  21. scitex/{fig → canvas}/editor/flask_editor/static/css/features/panel-grid.css +1 -1
  22. scitex/{fig → canvas}/editor/flask_editor/static/js/core/api.js +3 -4
  23. scitex/{fig → canvas}/editor/flask_editor/static/js/editor/preview.js +5 -5
  24. scitex/{fig → canvas}/editor/flask_editor/templates/_html.py +3 -3
  25. scitex/{fig → canvas}/editor/flask_editor/templates/_scripts.py +10 -10
  26. scitex/{fig → canvas}/editor/flask_editor/templates/_styles.py +3 -3
  27. scitex/{fig → canvas}/io/__init__.py +32 -38
  28. scitex/{fig → canvas}/io/_bundle.py +217 -154
  29. scitex/{fig → canvas}/io/_canvas.py +1 -1
  30. scitex/{fig → canvas}/io/_data.py +1 -1
  31. scitex/{fig → canvas}/io/_export.py +1 -1
  32. scitex/{fig → canvas}/io/_load.py +1 -1
  33. scitex/{fig → canvas}/io/_panel.py +1 -1
  34. scitex/{fig → canvas}/io/_save.py +1 -1
  35. scitex/{fig → canvas}/model/__init__.py +1 -1
  36. scitex/{fig → canvas}/model/_annotations.py +1 -1
  37. scitex/{fig → canvas}/model/_axes.py +1 -1
  38. scitex/{fig → canvas}/model/_figure.py +1 -1
  39. scitex/{fig → canvas}/model/_guides.py +1 -1
  40. scitex/{fig → canvas}/model/_plot.py +1 -1
  41. scitex/{fig → canvas}/model/_styles.py +1 -1
  42. scitex/{fig → canvas}/utils/__init__.py +1 -1
  43. scitex/cli/convert.py +10 -6
  44. scitex/diagram/README.md +7 -7
  45. scitex/io/__init__.py +7 -19
  46. scitex/io/_load.py +15 -19
  47. scitex/io/_load_modules/_canvas.py +2 -2
  48. scitex/io/_load_modules/_con.py +5 -5
  49. scitex/io/_load_modules/_eeg.py +16 -12
  50. scitex/io/_save.py +11 -16
  51. scitex/io/_save_modules/__init__.py +6 -10
  52. scitex/io/_save_modules/_canvas.py +3 -3
  53. scitex/io/_save_modules/_plot_bundle.py +112 -0
  54. scitex/io/_save_modules/{_pltz_stx.py → _plot_scitex.py} +7 -7
  55. scitex/io/_save_modules/_stx_bundle.py +16 -16
  56. scitex/io/bundle/README.md +89 -80
  57. scitex/{fts/_bundle/_FTS.py → io/bundle/_Bundle.py} +197 -95
  58. scitex/io/bundle/__init__.py +67 -35
  59. scitex/{fts/_bundle → io/bundle}/_children.py +32 -40
  60. scitex/io/bundle/_core.py +184 -97
  61. scitex/{fts/_bundle/_dataclasses/_Node.py → io/bundle/_dataclasses/_Spec.py} +29 -23
  62. scitex/{fts/_bundle/_dataclasses/_NodeRefs.py → io/bundle/_dataclasses/_SpecRefs.py} +6 -6
  63. scitex/{fts/_bundle → io/bundle}/_dataclasses/__init__.py +4 -4
  64. scitex/{fts/_bundle → io/bundle}/_loader.py +19 -19
  65. scitex/io/bundle/_manifest.py +99 -0
  66. scitex/{fts/_bundle → io/bundle}/_mpl_helpers.py +119 -28
  67. scitex/io/bundle/_nested.py +113 -100
  68. scitex/{fts/_bundle → io/bundle}/_saver.py +13 -14
  69. scitex/{fts/_bundle → io/bundle}/_storage.py +3 -3
  70. scitex/io/bundle/_types.py +41 -16
  71. scitex/{fts/_bundle → io/bundle}/_validation.py +20 -18
  72. scitex/io/bundle/_zip.py +21 -31
  73. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_backend/_parser.py +1 -1
  74. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Annotations.py +1 -1
  75. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Axes.py +1 -1
  76. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Figure.py +1 -1
  77. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Guides.py +1 -1
  78. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Plot.py +1 -1
  79. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Styles.py +1 -1
  80. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_utils/_plot_layout.py +1 -1
  81. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/__init__.py +1 -1
  82. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/_app.py +1 -1
  83. scitex/{fts/_tables → io/bundle/kinds/_table}/_latex/_export.py +1 -1
  84. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_figure_exporter.py +1 -1
  85. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_table_exporter.py +1 -1
  86. scitex/io/bundle/schemas/__init__.py +30 -0
  87. scitex/parallel/_run.py +5 -4
  88. scitex/path/_find.py +60 -83
  89. scitex/path/_get_module_path.py +23 -21
  90. scitex/path/_get_spath.py +6 -27
  91. scitex/path/_getsize.py +23 -9
  92. scitex/path/_increment_version.py +31 -38
  93. scitex/path/_mk_spath.py +26 -29
  94. scitex/path/_path.py +5 -12
  95. scitex/path/_split.py +27 -15
  96. scitex/path/_this_path.py +23 -9
  97. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +2 -1
  98. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +2 -2
  99. scitex/plt/gallery/_generate.py +76 -50
  100. scitex/plt/io/__init__.py +17 -19
  101. scitex/plt/io/_bundle.py +99 -52
  102. scitex/plt/io/_layered_bundle.py +303 -168
  103. scitex/plt/utils/_csv_column_naming.py +250 -118
  104. scitex/schema/__init__.py +69 -73
  105. scitex/schema/_canvas.py +1 -1
  106. scitex/schema/_stats.py +2 -2
  107. scitex/stats/__init__.py +30 -33
  108. scitex/stats/_schema.py +1 -1
  109. scitex/stats/io/__init__.py +10 -11
  110. scitex/stats/io/_bundle.py +16 -16
  111. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/METADATA +190 -73
  112. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/RECORD +237 -360
  113. scitex/fig/editor/_defaults.py +0 -300
  114. scitex/fig/editor/edit/panel_loader.py +0 -232
  115. scitex/fig/editor/flask_editor/_bbox.py +0 -1299
  116. scitex/fig/editor/flask_editor/_core.py +0 -1429
  117. scitex/fig/editor/flask_editor/_renderer.py +0 -813
  118. scitex/fig/editor/flask_editor/static/css/features/canvas.css +0 -176
  119. scitex/fts/README.md +0 -262
  120. scitex/fts/TODO.md +0 -66
  121. scitex/fts/__init__.py +0 -90
  122. scitex/fts/_bundle/README_IN_BUNDLE.md +0 -102
  123. scitex/fts/_bundle/__init__.py +0 -38
  124. scitex/fts/_bundle/_utils/__init__.py +0 -55
  125. scitex/fts/_bundle/_utils/_const.py +0 -26
  126. scitex/fts/_bundle/_utils/_errors.py +0 -73
  127. scitex/fts/_bundle/_utils/_generate.py +0 -21
  128. scitex/fts/_bundle/_utils/_types.py +0 -76
  129. scitex/fts/_bundle/_zipbundle.py +0 -165
  130. scitex/fts/_fig/__init__.py +0 -22
  131. scitex/fts/_fig/_backend/_parser.py +0 -188
  132. scitex/fts/_fig/_editor/__init__.py +0 -14
  133. scitex/fts/_fig/_editor/_cui/__init__.py +0 -33
  134. scitex/fts/_fig/_editor/_cui/_backend_detector.py +0 -39
  135. scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +0 -366
  136. scitex/fts/_fig/_editor/_cui/_editor_launcher.py +0 -175
  137. scitex/fts/_fig/_editor/_cui/_manual_handler.py +0 -52
  138. scitex/fts/_fig/_editor/_cui/_path_resolver.py +0 -66
  139. scitex/fts/_fig/_editor/_gui/__init__.py +0 -11
  140. scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +0 -20
  141. scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +0 -664
  142. scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +0 -79
  143. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +0 -41
  144. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +0 -16
  145. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +0 -85
  146. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +0 -217
  147. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +0 -93
  148. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +0 -57
  149. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +0 -112
  150. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +0 -59
  151. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +0 -212
  152. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +0 -190
  153. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +0 -59
  154. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +0 -45
  155. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +0 -95
  156. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +0 -101
  157. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +0 -138
  158. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +0 -31
  159. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +0 -7
  160. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +0 -56
  161. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +0 -78
  162. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +0 -314
  163. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +0 -107
  164. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +0 -54
  165. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +0 -172
  166. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +0 -258
  167. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +0 -48
  168. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +0 -71
  169. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +0 -288
  170. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +0 -143
  171. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +0 -245
  172. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +0 -992
  173. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +0 -339
  174. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +0 -286
  175. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +0 -371
  176. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +0 -293
  177. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +0 -426
  178. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +0 -152
  179. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +0 -265
  180. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +0 -184
  181. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +0 -57
  182. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +0 -100
  183. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +0 -34
  184. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +0 -124
  185. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +0 -851
  186. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +0 -4932
  187. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +0 -1657
  188. scitex/fts/_fig/_editor/_gui/_flask_editor.py +0 -36
  189. scitex/fts/_fig/_models/_Annotations.py +0 -115
  190. scitex/fts/_fig/_models/_Axes.py +0 -152
  191. scitex/fts/_fig/_models/_Figure.py +0 -138
  192. scitex/fts/_fig/_models/_Plot.py +0 -123
  193. scitex/fts/_fig/_utils/_plot_layout.py +0 -397
  194. scitex/fts/_kinds/_figure/_composite.py +0 -345
  195. scitex/fts/_kinds/_plot/_backend/__init__.py +0 -53
  196. scitex/fts/_kinds/_plot/_backend/_export.py +0 -165
  197. scitex/fts/_kinds/_plot/_backend/_render.py +0 -538
  198. scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +0 -46
  199. scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +0 -82
  200. scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +0 -441
  201. scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +0 -52
  202. scitex/fts/_kinds/_plot/_dataclasses/__init__.py +0 -47
  203. scitex/fts/_kinds/_plot/_models/_Guides.py +0 -104
  204. scitex/fts/_kinds/_plot/_models/_Styles.py +0 -245
  205. scitex/fts/_kinds/_plot/_models/__init__.py +0 -80
  206. scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +0 -156
  207. scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +0 -43
  208. scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +0 -38
  209. scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +0 -36
  210. scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +0 -60
  211. scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +0 -30
  212. scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +0 -61
  213. scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +0 -57
  214. scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +0 -30
  215. scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +0 -121
  216. scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +0 -36
  217. scitex/fts/_kinds/_plot/_utils/__init__.py +0 -129
  218. scitex/fts/_kinds/_plot/_utils/_auto_layout.py +0 -127
  219. scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +0 -111
  220. scitex/fts/_kinds/_plot/_utils/_const_sizes.py +0 -48
  221. scitex/fts/_kinds/_plot/_utils/_convert_coords.py +0 -77
  222. scitex/fts/_kinds/_plot/_utils/_get_template.py +0 -178
  223. scitex/fts/_kinds/_plot/_utils/_normalize.py +0 -73
  224. scitex/fts/_kinds/_plot/_utils/_validate.py +0 -197
  225. scitex/fts/_kinds/_table/_latex/_export.py +0 -279
  226. scitex/fts/_stats/__init__.py +0 -48
  227. scitex/fts/_stats/_dataclasses/_Stats.py +0 -423
  228. scitex/fts/_stats/_dataclasses/__init__.py +0 -48
  229. scitex/fts/_tables/__init__.py +0 -65
  230. scitex/fts/_tables/_latex/__init__.py +0 -93
  231. scitex/fts/_tables/_latex/_editor/__init__.py +0 -11
  232. scitex/fts/_tables/_latex/_editor/_app.py +0 -725
  233. scitex/fts/_tables/_latex/_figure_exporter.py +0 -153
  234. scitex/fts/_tables/_latex/_stats_formatter.py +0 -274
  235. scitex/fts/_tables/_latex/_table_exporter.py +0 -362
  236. scitex/fts/_tables/_latex/_utils.py +0 -369
  237. scitex/fts/_tables/_latex/_validator.py +0 -445
  238. scitex/io/_save_modules/_pltz_bundle.py +0 -356
  239. /scitex/{fig → canvas}/README.md +0 -0
  240. /scitex/{fig → canvas}/backend/__init__.py +0 -0
  241. /scitex/{fig → canvas}/backend/_export.py +0 -0
  242. /scitex/{fig → canvas}/backend/_render.py +0 -0
  243. /scitex/{fig → canvas}/docs/CANVAS_ARCHITECTURE.md +0 -0
  244. /scitex/{fig → canvas}/editor/__init__.py +0 -0
  245. /scitex/{fig → canvas}/editor/_dearpygui_editor.py +0 -0
  246. /scitex/{fig → canvas}/editor/_flask_editor.py +0 -0
  247. /scitex/{fig → canvas}/editor/_mpl_editor.py +0 -0
  248. /scitex/{fig → canvas}/editor/_qt_editor.py +0 -0
  249. /scitex/{fig → canvas}/editor/_tkinter_editor.py +0 -0
  250. /scitex/{fig → canvas}/editor/edit/backend_detector.py +0 -0
  251. /scitex/{fig → canvas}/editor/edit/manual_handler.py +0 -0
  252. /scitex/{fig → canvas}/editor/edit/path_resolver.py +0 -0
  253. /scitex/{fig → canvas}/editor/flask_editor/__init__.py +0 -0
  254. /scitex/{fig → canvas}/editor/flask_editor/_plotter.py +0 -0
  255. /scitex/{fig → canvas}/editor/flask_editor/_utils.py +0 -0
  256. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/reset.css +0 -0
  257. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/typography.css +0 -0
  258. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/variables.css +0 -0
  259. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/buttons.css +0 -0
  260. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/context-menu.css +0 -0
  261. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/dropdown.css +0 -0
  262. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/forms.css +0 -0
  263. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/modal.css +0 -0
  264. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/sections.css +0 -0
  265. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/element-inspector.css +0 -0
  266. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/loading.css +0 -0
  267. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/overlay.css +0 -0
  268. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/selection.css +0 -0
  269. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/statistics.css +0 -0
  270. /scitex/{fig → canvas}/editor/flask_editor/static/css/index.css +0 -0
  271. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/container.css +0 -0
  272. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/controls.css +0 -0
  273. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/preview.css +0 -0
  274. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/axis.js +0 -0
  275. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/basic.js +0 -0
  276. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/distribute.js +0 -0
  277. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/canvas.js +0 -0
  278. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/dragging.js +0 -0
  279. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/resize.js +0 -0
  280. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/selection.js +0 -0
  281. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/state.js +0 -0
  282. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/utils.js +0 -0
  283. /scitex/{fig → canvas}/editor/flask_editor/static/js/dev/element-inspector.js +0 -0
  284. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/bbox.js +0 -0
  285. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/element-drag.js +0 -0
  286. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/overlay.js +0 -0
  287. /scitex/{fig → canvas}/editor/flask_editor/static/js/main.js +0 -0
  288. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/context-menu.js +0 -0
  289. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/keyboard.js +0 -0
  290. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/controls.js +0 -0
  291. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/download.js +0 -0
  292. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/help.js +0 -0
  293. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/theme.js +0 -0
  294. /scitex/{fig → canvas}/editor/flask_editor/templates/__init__.py +0 -0
  295. /scitex/{fig → canvas}/io/_directory.py +0 -0
  296. /scitex/{fig → canvas}/model/_plot_types.py +0 -0
  297. /scitex/{fig → canvas}/utils/_defaults.py +0 -0
  298. /scitex/{fig → canvas}/utils/_validate.py +0 -0
  299. /scitex/{fts/_bundle → io/bundle}/_conversion/__init__.py +0 -0
  300. /scitex/{fts/_bundle → io/bundle}/_conversion/_bundle2dict.py +0 -0
  301. /scitex/{fts/_bundle → io/bundle}/_conversion/_dict2bundle.py +0 -0
  302. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_Axes.py +0 -0
  303. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_BBox.py +0 -0
  304. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_ColumnDef.py +0 -0
  305. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataFormat.py +0 -0
  306. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataInfo.py +0 -0
  307. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataSource.py +0 -0
  308. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_SizeMM.py +0 -0
  309. /scitex/{fts/_bundle → io/bundle}/_extractors/__init__.py +0 -0
  310. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_bar.py +0 -0
  311. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_line.py +0 -0
  312. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_scatter.py +0 -0
  313. /scitex/{fts/_kinds → io/bundle/kinds}/__init__.py +0 -0
  314. /scitex/{fts/_kinds → io/bundle/kinds}/_figure/__init__.py +0 -0
  315. /scitex/{fts/_fig → io/bundle/kinds/_figure}/_composite.py +0 -0
  316. /scitex/{fts/_kinds → io/bundle/kinds}/_plot/__init__.py +0 -0
  317. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/__init__.py +0 -0
  318. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_export.py +0 -0
  319. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_render.py +0 -0
  320. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_ChannelEncoding.py +0 -0
  321. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Encoding.py +0 -0
  322. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Theme.py +0 -0
  323. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_TraceEncoding.py +0 -0
  324. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/__init__.py +0 -0
  325. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/__init__.py +0 -0
  326. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/__init__.py +0 -0
  327. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_bar.py +0 -0
  328. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_box.py +0 -0
  329. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_distribution.py +0 -0
  330. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_errorbar.py +0 -0
  331. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_histogram.py +0 -0
  332. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_image.py +0 -0
  333. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_line.py +0 -0
  334. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_scatter.py +0 -0
  335. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_seaborn.py +0 -0
  336. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_violin.py +0 -0
  337. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/__init__.py +0 -0
  338. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_auto_layout.py +0 -0
  339. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_calc_bounds.py +0 -0
  340. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_const_sizes.py +0 -0
  341. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_convert_coords.py +0 -0
  342. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_get_template.py +0 -0
  343. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_normalize.py +0 -0
  344. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_validate.py +0 -0
  345. /scitex/{fts/_kinds → io/bundle/kinds}/_shape/__init__.py +0 -0
  346. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/__init__.py +0 -0
  347. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/_Stats.py +0 -0
  348. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/__init__.py +0 -0
  349. /scitex/{fts/_kinds → io/bundle/kinds}/_table/__init__.py +0 -0
  350. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/__init__.py +0 -0
  351. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_stats_formatter.py +0 -0
  352. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_utils.py +0 -0
  353. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_validator.py +0 -0
  354. /scitex/{fts/_kinds → io/bundle/kinds}/_text/__init__.py +0 -0
  355. /scitex/{fts/_schemas → io/bundle/schemas}/data_info.schema.json +0 -0
  356. /scitex/{fts/_schemas → io/bundle/schemas}/encoding.schema.json +0 -0
  357. /scitex/{fts/_schemas → io/bundle/schemas}/node.schema.json +0 -0
  358. /scitex/{fts/_schemas → io/bundle/schemas}/render_manifest.schema.json +0 -0
  359. /scitex/{fts/_schemas → io/bundle/schemas}/stats.schema.json +0 -0
  360. /scitex/{fts/_schemas → io/bundle/schemas}/theme.schema.json +0 -0
  361. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/WHEEL +0 -0
  362. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/entry_points.txt +0 -0
  363. {scitex-2.10.3.dist-info → scitex-2.11.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,314 +0,0 @@
1
- /**
2
- * Axis-Based Alignment
3
- * Scientific plot alignment using axes bounding boxes
4
- */
5
-
6
- // ============================================================================
7
- // Get Axes Bbox for Panel
8
- // ============================================================================
9
- function getAxesBboxForPanel(panelName) {
10
- const cache = panelBboxesCache[panelName];
11
- if (!cache || !cache.bboxes) return null;
12
-
13
- const bboxes = cache.bboxes;
14
-
15
- // Method 1: Look for ax_00_panel, ax_01_panel, etc.
16
- for (const key of Object.keys(bboxes)) {
17
- if (key.endsWith('_panel') && key.startsWith('ax_')) {
18
- const bbox = bboxes[key];
19
- if (bbox && bbox.x0 !== undefined) {
20
- return {
21
- x0: bbox.x0,
22
- y0: bbox.y0,
23
- x1: bbox.x1,
24
- y1: bbox.y1,
25
- key: key
26
- };
27
- }
28
- }
29
- }
30
-
31
- // Method 2: Calculate axes bbox from spine bboxes (xaxis_spine + yaxis_spine)
32
- // This is the common case for matplotlib figures
33
- let xSpine = null, ySpine = null;
34
- for (const key of Object.keys(bboxes)) {
35
- if (key.endsWith('_xaxis_spine') && key.startsWith('ax_')) {
36
- xSpine = bboxes[key];
37
- }
38
- if (key.endsWith('_yaxis_spine') && key.startsWith('ax_')) {
39
- ySpine = bboxes[key];
40
- }
41
- }
42
-
43
- if (xSpine && ySpine) {
44
- // Combine spine bboxes to get axes area
45
- // Y-spine defines left edge, X-spine defines bottom edge
46
- const x0 = ySpine.x0 !== undefined ? ySpine.x0 : ySpine.x;
47
- const y0 = ySpine.y0 !== undefined ? ySpine.y0 : ySpine.y;
48
- const x1 = xSpine.x1 !== undefined ? xSpine.x1 : (xSpine.x + xSpine.width);
49
- const y1 = xSpine.y1 !== undefined ? xSpine.y1 : (xSpine.y + xSpine.height);
50
-
51
- return {
52
- x0: Math.min(x0, xSpine.x0 || xSpine.x || x0),
53
- y0: Math.min(y0, xSpine.y0 || xSpine.y || y0),
54
- x1: Math.max(x1, ySpine.x1 || (ySpine.x + ySpine.width) || x1),
55
- y1: Math.max(y1, ySpine.y1 || (ySpine.y + ySpine.height) || y1),
56
- key: 'derived_from_spines'
57
- };
58
- }
59
-
60
- // Method 3: Fallback to _meta.axes_bbox_px for single-axes plots
61
- if (bboxes._meta && bboxes._meta.axes_bbox_px) {
62
- const axBbox = bboxes._meta.axes_bbox_px;
63
- return {
64
- x0: axBbox.x0 || axBbox.x,
65
- y0: axBbox.y0 || axBbox.y,
66
- x1: axBbox.x1 || (axBbox.x + axBbox.width),
67
- y1: axBbox.y1 || (axBbox.y + axBbox.height),
68
- key: '_meta.axes_bbox_px'
69
- };
70
- }
71
-
72
- return null;
73
- }
74
-
75
- // ============================================================================
76
- // Calculate Axis Edge Offset
77
- // ============================================================================
78
- function getAxisEdgeOffset(panel, axesBbox, edge, imgSize) {
79
- if (!axesBbox || !imgSize) return 0;
80
-
81
- // Scale factor from image pixels to displayed panel pixels
82
- const panelEl = panel;
83
- const displayWidth = panelEl.offsetWidth;
84
- const displayHeight = panelEl.offsetHeight;
85
- const scaleX = displayWidth / imgSize.width;
86
- const scaleY = displayHeight / imgSize.height;
87
-
88
- switch(edge) {
89
- case 'left':
90
- // Y-axis left edge
91
- return axesBbox.x0 * scaleX;
92
- case 'right':
93
- // Right edge of axes
94
- return axesBbox.x1 * scaleX;
95
- case 'top':
96
- // Top edge of axes
97
- return axesBbox.y0 * scaleY;
98
- case 'bottom':
99
- // X-axis bottom edge
100
- return axesBbox.y1 * scaleY;
101
- case 'center-h':
102
- // Horizontal center of axes
103
- return ((axesBbox.x0 + axesBbox.x1) / 2) * scaleX;
104
- case 'center-v':
105
- // Vertical center of axes
106
- return ((axesBbox.y0 + axesBbox.y1) / 2) * scaleY;
107
- default:
108
- return 0;
109
- }
110
- }
111
-
112
- // ============================================================================
113
- // Align Panels by Axis
114
- // ============================================================================
115
- function alignPanelsByAxis(edge) {
116
- // Use selected panels only
117
- const panels = Array.from(document.querySelectorAll('.panel-canvas-item.selected'));
118
- if (panels.length < 2) {
119
- setStatus('Select at least 2 panels for axis alignment', true);
120
- return;
121
- }
122
-
123
- // Collect panel info with axes bboxes
124
- const panelInfos = [];
125
- for (const panel of panels) {
126
- const panelName = panel.dataset.panelName;
127
- const cache = panelBboxesCache[panelName];
128
- const axesBbox = getAxesBboxForPanel(panelName);
129
-
130
- if (!axesBbox || !cache) {
131
- console.warn(`Panel ${panelName}: no axes bbox found`);
132
- continue;
133
- }
134
-
135
- const currentPos = panelPositions[panelName];
136
- const axisOffset = getAxisEdgeOffset(panel, axesBbox, edge, cache.imgSize);
137
-
138
- panelInfos.push({
139
- panel,
140
- panelName,
141
- axesBbox,
142
- imgSize: cache.imgSize,
143
- currentPos,
144
- axisOffset
145
- });
146
- }
147
-
148
- if (panelInfos.length < 2) {
149
- setStatus('Not enough panels with axes info', true);
150
- return;
151
- }
152
-
153
- // Calculate target position - use the first panel's axis position as reference
154
- const referenceInfo = panelInfos[0];
155
- const referenceAxisPos = referenceInfo.currentPos.x + (edge.includes('h') || edge === 'left' || edge === 'right' ? referenceInfo.axisOffset : 0);
156
- const referenceAxisPosY = referenceInfo.currentPos.y + (edge.includes('v') || edge === 'top' || edge === 'bottom' ? referenceInfo.axisOffset : 0);
157
-
158
- if (edge === 'left' || edge === 'right' || edge === 'center-h') {
159
- // Align horizontally (match X positions of axis edges)
160
- // Target = first panel's axis X position in canvas coords
161
- for (const info of panelInfos) {
162
- const newX = referenceAxisPos - info.axisOffset;
163
- info.currentPos.x = newX;
164
- info.panel.style.left = newX + 'px';
165
- panelLayoutMm[info.panelName].x_mm = newX / canvasScale;
166
- }
167
- } else {
168
- // Align vertically (match Y positions of axis edges)
169
- // Target = first panel's axis Y position in canvas coords
170
- for (const info of panelInfos) {
171
- const newY = referenceAxisPosY - info.axisOffset;
172
- info.currentPos.y = newY;
173
- info.panel.style.top = newY + 'px';
174
- panelLayoutMm[info.panelName].y_mm = newY / canvasScale;
175
- }
176
- }
177
-
178
- // Update layout data
179
- updatePanelLayoutFromDOM();
180
- layoutModified = true;
181
- }
182
-
183
- // ============================================================================
184
- // Stack Panels Vertically
185
- // ============================================================================
186
- function stackPanelsVertically() {
187
- // Use selected panels only
188
- const panels = Array.from(document.querySelectorAll('.panel-canvas-item.selected'));
189
- if (panels.length < 2) {
190
- setStatus('Select at least 2 panels for stacking', true);
191
- return;
192
- }
193
-
194
- // Collect panel info with axes bboxes
195
- const panelInfos = [];
196
- for (const panel of panels) {
197
- const panelName = panel.dataset.panelName;
198
- const cache = panelBboxesCache[panelName];
199
- const axesBbox = getAxesBboxForPanel(panelName);
200
-
201
- if (!axesBbox || !cache) continue;
202
-
203
- const currentPos = panelPositions[panelName];
204
- const axisOffsetLeft = getAxisEdgeOffset(panel, axesBbox, 'left', cache.imgSize);
205
-
206
- panelInfos.push({
207
- panel,
208
- panelName,
209
- axesBbox,
210
- imgSize: cache.imgSize,
211
- currentPos,
212
- axisOffsetLeft,
213
- height: panel.offsetHeight
214
- });
215
- }
216
-
217
- if (panelInfos.length < 2) return;
218
-
219
- // Sort by current vertical position
220
- panelInfos.sort((a, b) => a.currentPos.y - b.currentPos.y);
221
-
222
- // Use first panel as reference for Y-axis alignment
223
- const referenceAxisX = panelInfos[0].currentPos.x + panelInfos[0].axisOffsetLeft;
224
-
225
- // Stack panels vertically with small gap, aligned by Y-axis
226
- const gap = 10; // pixels
227
- let currentY = panelInfos[0].currentPos.y;
228
-
229
- for (const info of panelInfos) {
230
- // Align Y-axis (left edge of axes)
231
- const newX = referenceAxisX - info.axisOffsetLeft;
232
- info.currentPos.x = newX;
233
- info.panel.style.left = newX + 'px';
234
-
235
- // Stack vertically
236
- info.currentPos.y = currentY;
237
- info.panel.style.top = currentY + 'px';
238
- currentY += info.height + gap;
239
- }
240
-
241
- // Update layout data
242
- updatePanelLayoutFromDOM();
243
- layoutModified = true;
244
- }
245
-
246
- // ============================================================================
247
- // Axis Alignment Shortcut Handler
248
- // ============================================================================
249
- function handleAlignByAxisShortcut(key) {
250
- const panels = document.querySelectorAll('.panel-canvas-item');
251
- if (panels.length < 2) {
252
- setStatus('Need multiple panels for axis alignment', true);
253
- return;
254
- }
255
-
256
- const dirNames = {
257
- 'l': 'Y-axis (left edge)',
258
- 'r': 'Right edge',
259
- 't': 'Top edge',
260
- 'b': 'X-axis (bottom edge)',
261
- 'c': 'Center horizontal',
262
- 'm': 'Center vertical',
263
- 's': 'Stacked vertically'
264
- };
265
-
266
- switch(key) {
267
- case 'l': alignPanelsByAxis('left'); break; // Y-axis left
268
- case 'r': alignPanelsByAxis('right'); break; // Right edge
269
- case 't': alignPanelsByAxis('top'); break; // Top edge
270
- case 'b': alignPanelsByAxis('bottom'); break; // X-axis bottom
271
- case 'c': alignPanelsByAxis('center-h'); break; // Horizontal center
272
- case 'm': alignPanelsByAxis('center-v'); break; // Vertical center
273
- case 's': stackPanelsVertically(); break; // Stack with Y-axis alignment
274
- default:
275
- setStatus('Unknown axis key: ' + key + '. Use L/R/T/B/C/M/S', true);
276
- return;
277
- }
278
- if (dirNames[key]) {
279
- setStatus(`Aligned by axis: ${dirNames[key]}`, false);
280
- }
281
- }
282
-
283
- // ============================================================================
284
- // Panel Movement (Arrow Keys)
285
- // ============================================================================
286
- function moveSelectedPanel(direction, amountMm) {
287
- const selected = document.querySelector('.panel-canvas-item.selected');
288
- if (!selected) return;
289
-
290
- const panelName = selected.dataset.panelName;
291
- const pos = panelPositions[panelName];
292
- if (!pos) return;
293
-
294
- switch(direction) {
295
- case 'left': pos.x -= amountMm * canvasScale; break;
296
- case 'right': pos.x += amountMm * canvasScale; break;
297
- case 'up': pos.y -= amountMm * canvasScale; break;
298
- case 'down': pos.y += amountMm * canvasScale; break;
299
- }
300
-
301
- // Update position in pixels (canvasScale = px/mm)
302
- selected.style.left = pos.x + 'px';
303
- selected.style.top = pos.y + 'px';
304
-
305
- // Update layout data
306
- panelLayoutMm[panelName] = {
307
- ...panelLayoutMm[panelName],
308
- x_mm: pos.x / canvasScale,
309
- y_mm: pos.y / canvasScale
310
- };
311
-
312
- layoutModified = true;
313
- setStatus(`Moved ${panelName} ${direction} by ${amountMm}mm`);
314
- }
@@ -1,107 +0,0 @@
1
- /**
2
- * Basic Panel Alignment
3
- * Bounding box-based alignment (non-scientific)
4
- */
5
-
6
- // ============================================================================
7
- // Basic Alignment (by bounding box)
8
- // ============================================================================
9
- function alignPanels(mode) {
10
- const selectedPanels = getSelectedPanels();
11
- if (selectedPanels.length < 2) return;
12
-
13
- // Get bounds
14
- let targetValue;
15
- switch(mode) {
16
- case 'left':
17
- targetValue = Math.min(...selectedPanels.map(p => p.pos.x));
18
- selectedPanels.forEach(p => {
19
- p.pos.x = targetValue;
20
- p.item.style.left = targetValue + 'px';
21
- });
22
- break;
23
- case 'right':
24
- targetValue = Math.max(...selectedPanels.map(p => p.pos.x + p.pos.width));
25
- selectedPanels.forEach(p => {
26
- p.pos.x = targetValue - p.pos.width;
27
- p.item.style.left = p.pos.x + 'px';
28
- });
29
- break;
30
- case 'top':
31
- targetValue = Math.min(...selectedPanels.map(p => p.pos.y));
32
- selectedPanels.forEach(p => {
33
- p.pos.y = targetValue;
34
- p.item.style.top = targetValue + 'px';
35
- });
36
- break;
37
- case 'bottom':
38
- targetValue = Math.max(...selectedPanels.map(p => p.pos.y + p.pos.height));
39
- selectedPanels.forEach(p => {
40
- p.pos.y = targetValue - p.pos.height;
41
- p.item.style.top = p.pos.y + 'px';
42
- });
43
- break;
44
- case 'center-h':
45
- const avgX = selectedPanels.reduce((sum, p) => sum + p.pos.x + p.pos.width/2, 0) / selectedPanels.length;
46
- selectedPanels.forEach(p => {
47
- p.pos.x = avgX - p.pos.width/2;
48
- p.item.style.left = p.pos.x + 'px';
49
- });
50
- break;
51
- case 'center-v':
52
- const avgY = selectedPanels.reduce((sum, p) => sum + p.pos.y + p.pos.height/2, 0) / selectedPanels.length;
53
- selectedPanels.forEach(p => {
54
- p.pos.y = avgY - p.pos.height/2;
55
- p.item.style.top = p.pos.y + 'px';
56
- });
57
- break;
58
- }
59
-
60
- // Update layout data
61
- updatePanelLayoutFromDOM();
62
- layoutModified = true;
63
- setStatus(`Aligned panels: ${mode}`);
64
- }
65
-
66
- // ============================================================================
67
- // Alignment Shortcut Handler
68
- // ============================================================================
69
- function handleAlignShortcut(key, isShift) {
70
- const panels = document.querySelectorAll('.panel-canvas-item');
71
- if (panels.length < 2) {
72
- setStatus('Need multiple panels for alignment', true);
73
- return;
74
- }
75
-
76
- switch(key) {
77
- case 'l': alignPanels('left'); break;
78
- case 'r': alignPanels('right'); break;
79
- case 't': alignPanels('top'); break;
80
- case 'b': alignPanels('bottom'); break;
81
- case 'c': alignPanels('center-h'); break;
82
- case 'm': alignPanels('center-v'); break;
83
- case 'h': distributePanels('horizontal'); break;
84
- case 'v': distributePanels('vertical'); break;
85
- default:
86
- setStatus('Unknown alignment key: ' + key, true);
87
- }
88
- }
89
-
90
- // ============================================================================
91
- // Z-Order Management
92
- // ============================================================================
93
- function bringPanelToFront() {
94
- const selected = document.querySelector('.panel-canvas-item.selected');
95
- if (selected) {
96
- selected.style.zIndex = (parseInt(selected.style.zIndex || 0) + 1).toString();
97
- setStatus('Brought panel to front');
98
- }
99
- }
100
-
101
- function sendPanelToBack() {
102
- const selected = document.querySelector('.panel-canvas-item.selected');
103
- if (selected) {
104
- selected.style.zIndex = (parseInt(selected.style.zIndex || 0) - 1).toString();
105
- setStatus('Sent panel to back');
106
- }
107
- }
@@ -1,54 +0,0 @@
1
- /**
2
- * Panel Distribution
3
- * Evenly distribute panels horizontally or vertically
4
- */
5
-
6
- // ============================================================================
7
- // Distribute Panels
8
- // ============================================================================
9
- function distributePanels(direction) {
10
- const selectedPanels = getSelectedPanels();
11
- if (selectedPanels.length < 3) {
12
- setStatus('Need at least 3 panels for distribution', true);
13
- return;
14
- }
15
-
16
- if (direction === 'horizontal') {
17
- // Sort by X position
18
- selectedPanels.sort((a, b) => a.pos.x - b.pos.x);
19
-
20
- const first = selectedPanels[0];
21
- const last = selectedPanels[selectedPanels.length - 1];
22
- const totalSpace = (last.pos.x + last.pos.width) - first.pos.x;
23
- const totalPanelWidth = selectedPanels.reduce((sum, p) => sum + p.pos.width, 0);
24
- const gap = (totalSpace - totalPanelWidth) / (selectedPanels.length - 1);
25
-
26
- let currentX = first.pos.x;
27
- selectedPanels.forEach(p => {
28
- p.pos.x = currentX;
29
- p.item.style.left = currentX + 'px';
30
- currentX += p.pos.width + gap;
31
- });
32
- } else {
33
- // Sort by Y position
34
- selectedPanels.sort((a, b) => a.pos.y - b.pos.y);
35
-
36
- const first = selectedPanels[0];
37
- const last = selectedPanels[selectedPanels.length - 1];
38
- const totalSpace = (last.pos.y + last.pos.height) - first.pos.y;
39
- const totalPanelHeight = selectedPanels.reduce((sum, p) => sum + p.pos.height, 0);
40
- const gap = (totalSpace - totalPanelHeight) / (selectedPanels.length - 1);
41
-
42
- let currentY = first.pos.y;
43
- selectedPanels.forEach(p => {
44
- p.pos.y = currentY;
45
- p.item.style.top = currentY + 'px';
46
- currentY += p.pos.height + gap;
47
- });
48
- }
49
-
50
- // Update layout data
51
- updatePanelLayoutFromDOM();
52
- layoutModified = true;
53
- setStatus(`Distributed panels ${direction}ly`);
54
- }
@@ -1,172 +0,0 @@
1
- /**
2
- * Canvas View Management
3
- * Handles the unified canvas view for multi-panel figures
4
- */
5
-
6
- // ============================================================================
7
- // Canvas Mode Control
8
- // ============================================================================
9
- function setCanvasMode(mode) {
10
- canvasMode = mode;
11
- document.getElementById('canvas-grid').classList.toggle('canvas-mode', mode === 'canvas');
12
- document.getElementById('canvas-grid').classList.toggle('grid-mode', mode === 'grid');
13
- }
14
-
15
- // ============================================================================
16
- // Canvas Rendering
17
- // ============================================================================
18
- function renderCanvasView() {
19
- const container = document.getElementById('canvas-grid');
20
- container.innerHTML = '';
21
-
22
- // Fetch panels if not cached
23
- if (!panelData || !panelData.panels) {
24
- return;
25
- }
26
-
27
- if (canvasMode === 'canvas') {
28
- // Calculate canvas size based on number of panels
29
- const panels = panelData.panels;
30
-
31
- panels.forEach((panel, idx) => {
32
- const item = document.createElement('div');
33
- item.className = 'panel-canvas-item';
34
- item.dataset.panelName = panel.name;
35
-
36
- // Initialize position if not set
37
- if (!panelPositions[panel.name]) {
38
- panelPositions[panel.name] = {
39
- x: idx * 150,
40
- y: idx * 150,
41
- width: panel.width_px || 400,
42
- height: panel.height_px || 300
43
- };
44
- }
45
-
46
- const pos = panelPositions[panel.name];
47
- item.style.left = pos.x + 'px';
48
- item.style.top = pos.y + 'px';
49
- item.style.width = pos.width + 'px';
50
- item.style.height = pos.height + 'px';
51
-
52
- item.innerHTML = `
53
- <div class="panel-drag-handle">☰</div>
54
- <div class="panel-label">${panel.name}</div>
55
- <img src="data:image/png;base64,${panel.image_base64}" style="width: 100%; height: 100%; object-fit: contain;">
56
- <canvas class="panel-overlay"></canvas>
57
- `;
58
-
59
- container.appendChild(item);
60
-
61
- // Double-click to edit
62
- item.addEventListener('dblclick', () => {
63
- loadPanelForEditing(panel.name);
64
- });
65
-
66
- // Drag start
67
- initPanelDrag(item, panel.name);
68
- });
69
-
70
- // Update canvas height to fit all panels
71
- updateCanvasSize();
72
- } else {
73
- // Grid mode - use CSS grid layout (simpler)
74
- loadPanelGrid();
75
- }
76
- }
77
-
78
- // ============================================================================
79
- // Interactive Element Detection Helper
80
- // ============================================================================
81
- function isInteractiveElement(target) {
82
- // SVG paths with hover-path class are interactive elements
83
- if (target.classList && target.classList.contains('hover-path')) {
84
- return true;
85
- }
86
- // Check parent elements for hover-path (click might be on child)
87
- let parent = target.parentElement;
88
- while (parent) {
89
- if (parent.tagName === 'path' || parent.classList.contains('hover-path')) {
90
- // Path elements in SVG overlay are interactive
91
- return true;
92
- }
93
- parent = parent.parentElement;
94
- }
95
- return false;
96
- }
97
-
98
- // ============================================================================
99
- // Canvas Size Management
100
- // ============================================================================
101
- function updateCanvasSize() {
102
- // Find the maximum extent of all panels
103
- let maxX = 0;
104
- let maxY = 0;
105
-
106
- Object.values(panelPositions).forEach(pos => {
107
- maxX = Math.max(maxX, pos.x + pos.width);
108
- maxY = Math.max(maxY, pos.y + pos.height);
109
- });
110
-
111
- // Add some padding
112
- const container = document.getElementById('canvas-grid');
113
- if (container && canvasMode === 'canvas') {
114
- container.style.minHeight = (maxY + 100) + 'px';
115
- container.style.minWidth = (maxX + 100) + 'px';
116
- }
117
- }
118
-
119
- // ============================================================================
120
- // Canvas Zoom Functions
121
- // ============================================================================
122
- function zoomCanvas(factor) {
123
- canvasZoom = Math.max(0.1, Math.min(5.0, canvasZoom * factor));
124
- const container = document.getElementById('canvas-grid');
125
- if (container) {
126
- container.style.transform = `scale(${canvasZoom})`;
127
- container.style.transformOrigin = 'top left';
128
- }
129
- }
130
-
131
- function fitCanvasToWindow() {
132
- const container = document.getElementById('canvas-grid');
133
- if (!container) return;
134
-
135
- const containerWidth = container.scrollWidth;
136
- const windowWidth = window.innerWidth - 400; // Account for side panels
137
- canvasZoom = Math.min(1.0, windowWidth / containerWidth);
138
- container.style.transform = `scale(${canvasZoom})`;
139
- container.style.transformOrigin = 'top left';
140
- }
141
-
142
- function resizeCanvas(factor) {
143
- const container = document.getElementById('canvas-grid');
144
- if (!container) return;
145
-
146
- // Scale all panel positions and sizes
147
- Object.keys(panelPositions).forEach(name => {
148
- const pos = panelPositions[name];
149
- pos.x *= factor;
150
- pos.y *= factor;
151
- pos.width *= factor;
152
- pos.height *= factor;
153
- });
154
-
155
- renderCanvasView();
156
- }
157
-
158
- // ============================================================================
159
- // Panel Layout Update from DOM
160
- // ============================================================================
161
- function updatePanelLayoutFromDOM() {
162
- document.querySelectorAll('.panel-canvas-item').forEach(item => {
163
- const name = item.dataset.panelName;
164
- const rect = item.getBoundingClientRect();
165
- panelPositions[name] = {
166
- x: parseFloat(item.style.left),
167
- y: parseFloat(item.style.top),
168
- width: rect.width,
169
- height: rect.height
170
- };
171
- });
172
- }