@genome-spy/core 0.78.0 → 0.79.0

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 (289) hide show
  1. package/dist/bundle/{browser-KWU9rWZT.js → browser-CETrb2cm.js} +53 -33
  2. package/dist/bundle/esm-BdLYkz-m.js +248 -0
  3. package/dist/bundle/esm-BwiDsqSb.js +1367 -0
  4. package/dist/bundle/esm-CDFd1cjk.js +441 -0
  5. package/dist/bundle/{esm-DVOHLB1e.js → esm-CTUHLDbv.js} +30 -30
  6. package/dist/bundle/{esm-NIYEaYkc.js → esm-Cx-EbkOj.js} +13 -13
  7. package/dist/bundle/esm-DlYGqi79.js +128 -0
  8. package/dist/bundle/{esm-BygJiwh0.js → esm-k9p3oHkt.js} +133 -158
  9. package/dist/bundle/{esm-CT3ygiMq.js → esm-zAZJQO6D.js} +226 -212
  10. package/dist/bundle/index.es.js +14840 -11661
  11. package/dist/bundle/index.js +119 -108
  12. package/dist/bundle/{parquetRead-DG_-F5j5.js → parquetRead-Cad1SOVV.js} +473 -399
  13. package/dist/schema.json +18940 -6914
  14. package/dist/src/config/axisConfig.d.ts +2 -2
  15. package/dist/src/config/axisConfig.d.ts.map +1 -1
  16. package/dist/src/config/axisConfig.js +28 -44
  17. package/dist/src/config/configLayers.d.ts +45 -0
  18. package/dist/src/config/configLayers.d.ts.map +1 -0
  19. package/dist/src/config/configLayers.js +110 -0
  20. package/dist/src/config/defaultConfig.d.ts.map +1 -1
  21. package/dist/src/config/defaultConfig.js +8 -1
  22. package/dist/src/config/defaults/legendDefaults.d.ts +14 -0
  23. package/dist/src/config/defaults/legendDefaults.d.ts.map +1 -0
  24. package/dist/src/config/defaults/legendDefaults.js +46 -0
  25. package/dist/src/config/defaults/titleDefaults.d.ts.map +1 -1
  26. package/dist/src/config/defaults/titleDefaults.js +26 -18
  27. package/dist/src/config/legendConfig.d.ts +11 -0
  28. package/dist/src/config/legendConfig.d.ts.map +1 -0
  29. package/dist/src/config/legendConfig.js +63 -0
  30. package/dist/src/config/styleUtils.d.ts +8 -2
  31. package/dist/src/config/styleUtils.d.ts.map +1 -1
  32. package/dist/src/config/styleUtils.js +25 -1
  33. package/dist/src/config/themes.d.ts.map +1 -1
  34. package/dist/src/config/themes.js +21 -2
  35. package/dist/src/config/titleConfig.d.ts.map +1 -1
  36. package/dist/src/config/titleConfig.js +2 -18
  37. package/dist/src/data/collector.d.ts.map +1 -1
  38. package/dist/src/data/collector.js +40 -18
  39. package/dist/src/data/flowInit.d.ts +6 -0
  40. package/dist/src/data/flowInit.d.ts.map +1 -1
  41. package/dist/src/data/flowInit.js +1 -1
  42. package/dist/src/data/flowNode.d.ts +32 -0
  43. package/dist/src/data/flowNode.d.ts.map +1 -1
  44. package/dist/src/data/flowNode.js +59 -0
  45. package/dist/src/data/sources/lazy/bamSource.d.ts +0 -1
  46. package/dist/src/data/sources/lazy/bamSource.d.ts.map +1 -1
  47. package/dist/src/data/sources/lazy/bamSource.js +39 -30
  48. package/dist/src/data/sources/lazy/bigBedSource.d.ts +0 -10
  49. package/dist/src/data/sources/lazy/bigBedSource.d.ts.map +1 -1
  50. package/dist/src/data/sources/lazy/bigBedSource.js +127 -62
  51. package/dist/src/data/sources/lazy/bigWigSource.d.ts +2 -2
  52. package/dist/src/data/sources/lazy/bigWigSource.d.ts.map +1 -1
  53. package/dist/src/data/sources/lazy/bigWigSource.js +234 -81
  54. package/dist/src/data/sources/lazy/gff3Source.d.ts +7 -3
  55. package/dist/src/data/sources/lazy/gff3Source.d.ts.map +1 -1
  56. package/dist/src/data/sources/lazy/gff3Source.js +7 -8
  57. package/dist/src/data/sources/lazy/indexedFastaSource.d.ts +1 -1
  58. package/dist/src/data/sources/lazy/indexedFastaSource.d.ts.map +1 -1
  59. package/dist/src/data/sources/lazy/indexedFastaSource.js +28 -19
  60. package/dist/src/data/sources/lazy/legendEntriesSource.d.ts +24 -0
  61. package/dist/src/data/sources/lazy/legendEntriesSource.d.ts.map +1 -0
  62. package/dist/src/data/sources/lazy/legendEntriesSource.js +217 -0
  63. package/dist/src/data/sources/lazy/legendGradientSource.d.ts +30 -0
  64. package/dist/src/data/sources/lazy/legendGradientSource.d.ts.map +1 -0
  65. package/dist/src/data/sources/lazy/legendGradientSource.js +388 -0
  66. package/dist/src/data/sources/lazy/mockLazySource.d.ts +4 -1
  67. package/dist/src/data/sources/lazy/mockLazySource.d.ts.map +1 -1
  68. package/dist/src/data/sources/lazy/mockLazySource.js +49 -4
  69. package/dist/src/data/sources/lazy/registerCoreLazySources.js +2 -0
  70. package/dist/src/data/sources/lazy/singleAxisWindowedSource.d.ts.map +1 -1
  71. package/dist/src/data/sources/lazy/singleAxisWindowedSource.js +3 -4
  72. package/dist/src/data/sources/lazy/tabixSource.d.ts +9 -4
  73. package/dist/src/data/sources/lazy/tabixSource.d.ts.map +1 -1
  74. package/dist/src/data/sources/lazy/tabixSource.js +201 -70
  75. package/dist/src/data/sources/lazy/tabixTsvSource.d.ts +2 -3
  76. package/dist/src/data/sources/lazy/tabixTsvSource.d.ts.map +1 -1
  77. package/dist/src/data/sources/lazy/tabixTsvSource.js +14 -12
  78. package/dist/src/data/sources/lazy/vcfSource.d.ts +7 -3
  79. package/dist/src/data/sources/lazy/vcfSource.d.ts.map +1 -1
  80. package/dist/src/data/sources/lazy/vcfSource.js +7 -8
  81. package/dist/src/data/sources/urlDescriptor.d.ts +165 -0
  82. package/dist/src/data/sources/urlDescriptor.d.ts.map +1 -0
  83. package/dist/src/data/sources/urlDescriptor.js +473 -0
  84. package/dist/src/data/sources/urlDescriptorController.d.ts +25 -0
  85. package/dist/src/data/sources/urlDescriptorController.d.ts.map +1 -0
  86. package/dist/src/data/sources/urlDescriptorController.js +72 -0
  87. package/dist/src/data/sources/urlDescriptorState.d.ts +47 -0
  88. package/dist/src/data/sources/urlDescriptorState.d.ts.map +1 -0
  89. package/dist/src/data/sources/urlDescriptorState.js +129 -0
  90. package/dist/src/data/sources/urlSource.d.ts.map +1 -1
  91. package/dist/src/data/sources/urlSource.js +101 -61
  92. package/dist/src/data/transforms/packLegendLabels.d.ts +21 -0
  93. package/dist/src/data/transforms/packLegendLabels.d.ts.map +1 -0
  94. package/dist/src/data/transforms/packLegendLabels.js +189 -0
  95. package/dist/src/data/transforms/transformFactory.d.ts.map +1 -1
  96. package/dist/src/data/transforms/transformFactory.js +4 -0
  97. package/dist/src/data/transforms/truncateText.d.ts +27 -0
  98. package/dist/src/data/transforms/truncateText.d.ts.map +1 -0
  99. package/dist/src/data/transforms/truncateText.js +94 -0
  100. package/dist/src/debug/dataflowDebugSnapshot.d.ts +58 -0
  101. package/dist/src/debug/dataflowDebugSnapshot.d.ts.map +1 -0
  102. package/dist/src/debug/dataflowDebugSnapshot.js +159 -0
  103. package/dist/src/debug/markDebugSnapshot.d.ts +54 -0
  104. package/dist/src/debug/markDebugSnapshot.d.ts.map +1 -0
  105. package/dist/src/debug/markDebugSnapshot.js +100 -0
  106. package/dist/src/debug/paramDebugSnapshot.d.ts +53 -0
  107. package/dist/src/debug/paramDebugSnapshot.d.ts.map +1 -0
  108. package/dist/src/debug/paramDebugSnapshot.js +86 -0
  109. package/dist/src/debug/resolutionDebugSnapshot.d.ts +155 -0
  110. package/dist/src/debug/resolutionDebugSnapshot.d.ts.map +1 -0
  111. package/dist/src/debug/resolutionDebugSnapshot.js +291 -0
  112. package/dist/src/debug/valuePreview.d.ts +9 -0
  113. package/dist/src/debug/valuePreview.d.ts.map +1 -0
  114. package/dist/src/debug/valuePreview.js +57 -0
  115. package/dist/src/debug/viewDebugSnapshot.d.ts +131 -0
  116. package/dist/src/debug/viewDebugSnapshot.d.ts.map +1 -0
  117. package/dist/src/debug/viewDebugSnapshot.js +390 -0
  118. package/dist/src/embedFactory.d.ts.map +1 -1
  119. package/dist/src/embedFactory.js +6 -1
  120. package/dist/src/encoder/encoder.d.ts +2 -2
  121. package/dist/src/encoder/encoder.d.ts.map +1 -1
  122. package/dist/src/encoder/encoder.js +5 -4
  123. package/dist/src/fonts/bmFontManager.d.ts +1 -1
  124. package/dist/src/fonts/bmFontManager.d.ts.map +1 -1
  125. package/dist/src/fonts/bmFontManager.js +45 -10
  126. package/dist/src/fonts/textMetrics.d.ts +69 -0
  127. package/dist/src/fonts/textMetrics.d.ts.map +1 -0
  128. package/dist/src/fonts/textMetrics.js +73 -0
  129. package/dist/src/genomeSpy/headlessBootstrap.d.ts.map +1 -1
  130. package/dist/src/genomeSpy/headlessBootstrap.js +6 -0
  131. package/dist/src/genomeSpy/renderCoordinator.d.ts.map +1 -1
  132. package/dist/src/genomeSpy/renderCoordinator.js +25 -3
  133. package/dist/src/genomeSpy/viewDataInit.d.ts +14 -0
  134. package/dist/src/genomeSpy/viewDataInit.d.ts.map +1 -1
  135. package/dist/src/genomeSpy/viewDataInit.js +45 -8
  136. package/dist/src/genomeSpyBase.d.ts +6 -0
  137. package/dist/src/genomeSpyBase.d.ts.map +1 -1
  138. package/dist/src/genomeSpyBase.js +20 -3
  139. package/dist/src/gl/glslScaleGenerator.d.ts +17 -0
  140. package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
  141. package/dist/src/gl/glslScaleGenerator.js +39 -2
  142. package/dist/src/gl/includes/common.glsl.js +1 -1
  143. package/dist/src/gl/vertexRangeIndex.d.ts.map +1 -1
  144. package/dist/src/gl/vertexRangeIndex.js +4 -2
  145. package/dist/src/gl/webGLHelper.d.ts +1 -1
  146. package/dist/src/gl/webGLHelper.d.ts.map +1 -1
  147. package/dist/src/gl/webGLHelper.js +13 -8
  148. package/dist/src/marks/__snapshots__/shaderSnapshot.test.js.snap +140 -3
  149. package/dist/src/marks/mark.d.ts +47 -4
  150. package/dist/src/marks/mark.d.ts.map +1 -1
  151. package/dist/src/marks/mark.js +158 -54
  152. package/dist/src/marks/point.d.ts.map +1 -1
  153. package/dist/src/marks/point.js +4 -0
  154. package/dist/src/marks/point.vertex.glsl.js +1 -1
  155. package/dist/src/marks/text.d.ts +1 -1
  156. package/dist/src/marks/text.d.ts.map +1 -1
  157. package/dist/src/marks/text.js +2 -7
  158. package/dist/src/marks/text.vertex.glsl.js +1 -1
  159. package/dist/src/paramRuntime/paramUtils.d.ts +43 -9
  160. package/dist/src/paramRuntime/paramUtils.d.ts.map +1 -1
  161. package/dist/src/paramRuntime/paramUtils.js +61 -1
  162. package/dist/src/paramRuntime/viewParamRuntime.d.ts +32 -0
  163. package/dist/src/paramRuntime/viewParamRuntime.d.ts.map +1 -1
  164. package/dist/src/paramRuntime/viewParamRuntime.js +63 -0
  165. package/dist/src/scales/axisResolution.d.ts +35 -0
  166. package/dist/src/scales/axisResolution.d.ts.map +1 -1
  167. package/dist/src/scales/axisResolution.js +115 -7
  168. package/dist/src/scales/legendResolution.d.ts +83 -0
  169. package/dist/src/scales/legendResolution.d.ts.map +1 -0
  170. package/dist/src/scales/legendResolution.js +461 -0
  171. package/dist/src/scales/scaleResolution.d.ts +36 -0
  172. package/dist/src/scales/scaleResolution.d.ts.map +1 -1
  173. package/dist/src/scales/scaleResolution.js +59 -0
  174. package/dist/src/scales/viewLevelGuideConfig.d.ts +53 -0
  175. package/dist/src/scales/viewLevelGuideConfig.d.ts.map +1 -0
  176. package/dist/src/scales/viewLevelGuideConfig.js +224 -0
  177. package/dist/src/scales/viewLevelScaleConfig.d.ts.map +1 -1
  178. package/dist/src/scales/viewLevelScaleConfig.js +13 -2
  179. package/dist/src/spec/axis.d.ts +109 -3
  180. package/dist/src/spec/channel.d.ts +23 -4
  181. package/dist/src/spec/config.d.ts +59 -4
  182. package/dist/src/spec/data.d.ts +177 -17
  183. package/dist/src/spec/legend.d.ts +246 -0
  184. package/dist/src/spec/mark.d.ts +16 -4
  185. package/dist/src/spec/title.d.ts +58 -1
  186. package/dist/src/spec/transform.d.ts +149 -0
  187. package/dist/src/spec/view.d.ts +39 -6
  188. package/dist/src/types/embedApi.d.ts +262 -6
  189. package/dist/src/types/rendering.d.ts +19 -3
  190. package/dist/src/types/viewContext.d.ts +18 -2
  191. package/dist/src/utils/arrayUtils.d.ts +11 -0
  192. package/dist/src/utils/arrayUtils.d.ts.map +1 -1
  193. package/dist/src/utils/arrayUtils.js +23 -0
  194. package/dist/src/utils/suspension.d.ts +17 -0
  195. package/dist/src/utils/suspension.d.ts.map +1 -0
  196. package/dist/src/utils/suspension.js +41 -0
  197. package/dist/src/view/axisGridView.d.ts.map +1 -1
  198. package/dist/src/view/axisGridView.js +1 -4
  199. package/dist/src/view/axisView.d.ts +18 -2
  200. package/dist/src/view/axisView.d.ts.map +1 -1
  201. package/dist/src/view/axisView.js +180 -75
  202. package/dist/src/view/concatView.d.ts +10 -2
  203. package/dist/src/view/concatView.d.ts.map +1 -1
  204. package/dist/src/view/concatView.js +46 -9
  205. package/dist/src/view/containerMutationHelper.d.ts +20 -1
  206. package/dist/src/view/containerMutationHelper.d.ts.map +1 -1
  207. package/dist/src/view/containerMutationHelper.js +196 -33
  208. package/dist/src/view/facetView.d.ts +1 -1
  209. package/dist/src/view/gridView/gridChild.d.ts +54 -4
  210. package/dist/src/view/gridView/gridChild.d.ts.map +1 -1
  211. package/dist/src/view/gridView/gridChild.js +301 -120
  212. package/dist/src/view/gridView/gridChildLegends.d.ts +57 -0
  213. package/dist/src/view/gridView/gridChildLegends.d.ts.map +1 -0
  214. package/dist/src/view/gridView/gridChildLegends.js +503 -0
  215. package/dist/src/view/gridView/gridView.d.ts +25 -0
  216. package/dist/src/view/gridView/gridView.d.ts.map +1 -1
  217. package/dist/src/view/gridView/gridView.js +454 -78
  218. package/dist/src/view/gridView/legendLayout.d.ts +26 -0
  219. package/dist/src/view/gridView/legendLayout.d.ts.map +1 -0
  220. package/dist/src/view/gridView/legendLayout.js +111 -0
  221. package/dist/src/view/gridView/scrollbar.d.ts.map +1 -1
  222. package/dist/src/view/gridView/scrollbar.js +1 -4
  223. package/dist/src/view/gridView/selectionRect.d.ts.map +1 -1
  224. package/dist/src/view/gridView/selectionRect.js +1 -4
  225. package/dist/src/view/gridView/separatorView.d.ts.map +1 -1
  226. package/dist/src/view/gridView/separatorView.js +1 -4
  227. package/dist/src/view/layerView.d.ts +9 -2
  228. package/dist/src/view/layerView.d.ts.map +1 -1
  229. package/dist/src/view/layerView.js +18 -1
  230. package/dist/src/view/layout/flexLayout.d.ts +20 -4
  231. package/dist/src/view/layout/flexLayout.d.ts.map +1 -1
  232. package/dist/src/view/layout/flexLayout.js +331 -31
  233. package/dist/src/view/layout/rectangle.d.ts +14 -0
  234. package/dist/src/view/layout/rectangle.d.ts.map +1 -1
  235. package/dist/src/view/layout/rectangle.js +40 -0
  236. package/dist/src/view/legend/legendEntries.d.ts +20 -0
  237. package/dist/src/view/legend/legendEntries.d.ts.map +1 -0
  238. package/dist/src/view/legend/legendEntries.js +21 -0
  239. package/dist/src/view/legendView.d.ts +134 -0
  240. package/dist/src/view/legendView.d.ts.map +1 -0
  241. package/dist/src/view/legendView.js +1611 -0
  242. package/dist/src/view/renderingContext/bufferedViewRenderingContext.d.ts.map +1 -1
  243. package/dist/src/view/renderingContext/bufferedViewRenderingContext.js +26 -4
  244. package/dist/src/view/renderingContext/clipOptions.d.ts +44 -0
  245. package/dist/src/view/renderingContext/clipOptions.d.ts.map +1 -0
  246. package/dist/src/view/renderingContext/clipOptions.js +140 -0
  247. package/dist/src/view/renderingContext/simpleViewRenderingContext.d.ts.map +1 -1
  248. package/dist/src/view/renderingContext/simpleViewRenderingContext.js +12 -1
  249. package/dist/src/view/resolutionPlanner.d.ts +2 -1
  250. package/dist/src/view/resolutionPlanner.d.ts.map +1 -1
  251. package/dist/src/view/resolutionPlanner.js +89 -25
  252. package/dist/src/view/testUtils.d.ts +4 -2
  253. package/dist/src/view/testUtils.d.ts.map +1 -1
  254. package/dist/src/view/testUtils.js +29 -7
  255. package/dist/src/view/titleView.d.ts +37 -0
  256. package/dist/src/view/titleView.d.ts.map +1 -0
  257. package/dist/src/view/titleView.js +584 -0
  258. package/dist/src/view/unitView.d.ts +3 -3
  259. package/dist/src/view/unitView.d.ts.map +1 -1
  260. package/dist/src/view/unitView.js +3 -2
  261. package/dist/src/view/view.d.ts +25 -24
  262. package/dist/src/view/view.d.ts.map +1 -1
  263. package/dist/src/view/view.js +121 -16
  264. package/dist/src/view/viewFactory.d.ts +2 -5
  265. package/dist/src/view/viewFactory.d.ts.map +1 -1
  266. package/dist/src/view/viewFactory.js +1 -2
  267. package/dist/src/view/viewIdentityRegistry.d.ts +37 -0
  268. package/dist/src/view/viewIdentityRegistry.d.ts.map +1 -0
  269. package/dist/src/view/viewIdentityRegistry.js +71 -0
  270. package/dist/src/view/viewMutationAcidTestUtils.d.ts +112 -0
  271. package/dist/src/view/viewMutationAcidTestUtils.d.ts.map +1 -0
  272. package/dist/src/view/viewMutationAcidTestUtils.js +234 -0
  273. package/dist/src/view/viewMutationApi.d.ts +42 -0
  274. package/dist/src/view/viewMutationApi.d.ts.map +1 -0
  275. package/dist/src/view/viewMutationApi.js +811 -0
  276. package/dist/src/view/viewSelectors.d.ts +10 -0
  277. package/dist/src/view/viewSelectors.d.ts.map +1 -1
  278. package/dist/src/view/viewSelectors.js +23 -1
  279. package/package.json +4 -4
  280. package/dist/bundle/esm-CuMSzCHy.js +0 -298
  281. package/dist/bundle/esm-DAnOffpD.js +0 -1426
  282. package/dist/bundle/esm-DMXpJXM4.js +0 -369
  283. package/dist/bundle/esm-DNtC3H80.js +0 -121
  284. package/dist/src/view/title.d.ts +0 -13
  285. package/dist/src/view/title.d.ts.map +0 -1
  286. package/dist/src/view/title.js +0 -154
  287. /package/dist/bundle/{AbortablePromiseCache-3gHJdF3E.js → AbortablePromiseCache-BTmAcN-t.js} +0 -0
  288. /package/dist/bundle/{esm-CuVa5T98.js → esm-VvpZ9hsq.js} +0 -0
  289. /package/dist/bundle/{chunk-DmhlhrBa.js → rolldown-runtime-Dy4uBu1J.js} +0 -0
@@ -0,0 +1,584 @@
1
+ import ContainerView from "./containerView.js";
2
+ import UnitView from "./unitView.js";
3
+ import { isString } from "vega-util";
4
+ import { isExprRef } from "../paramRuntime/paramUtils.js";
5
+ import {
6
+ getProjectedTextExtent,
7
+ measureText,
8
+ requestFont,
9
+ } from "../fonts/textMetrics.js";
10
+ import Padding from "./layout/padding.js";
11
+ import { markViewAsChrome, markViewAsNonAddressable } from "./viewSelectors.js";
12
+ import {
13
+ getConfiguredStyleConfig,
14
+ getConfiguredTitleConfig,
15
+ } from "../config/titleConfig.js";
16
+
17
+ /** @type {Record<import("../spec/title.js").TitleAnchor, number>} */
18
+ const ANCHORS = {
19
+ start: 0,
20
+ middle: 0.5,
21
+ end: 1,
22
+ };
23
+
24
+ /** @type {Record<import("../spec/title.js").TitleAnchor, import("../spec/font.js").Align>} */
25
+ const ANCHOR_TO_ALIGN = {
26
+ start: "left",
27
+ middle: "center",
28
+ end: "right",
29
+ };
30
+
31
+ const DEFAULT_TITLE_STYLE = "group-title";
32
+ const DEFAULT_SUBTITLE_STYLE = "group-subtitle";
33
+
34
+ /**
35
+ * @param {import("../spec/config.js").StyleConfig} styleConfig
36
+ * @returns {Partial<import("../spec/title.js").Title>}
37
+ */
38
+ function subtitleStyleToTitleConfig(styleConfig) {
39
+ return pickDefined({
40
+ subtitleColor: styleConfig.color,
41
+ subtitleFont: styleConfig.font,
42
+ subtitleFontSize: styleConfig.fontSize,
43
+ subtitleFontStyle: styleConfig.fontStyle,
44
+ subtitleFontWeight: styleConfig.fontWeight,
45
+ });
46
+ }
47
+
48
+ /**
49
+ * @param {import("../spec/config.js").TitleConfig} titleConfig
50
+ * @returns {Partial<import("../spec/title.js").Title>}
51
+ */
52
+ function pickSubtitleTitleConfig(titleConfig) {
53
+ return pickDefined({
54
+ subtitleColor: titleConfig.subtitleColor,
55
+ subtitleFont: titleConfig.subtitleFont,
56
+ subtitleFontSize: titleConfig.subtitleFontSize,
57
+ subtitleFontStyle: titleConfig.subtitleFontStyle,
58
+ subtitleFontWeight: titleConfig.subtitleFontWeight,
59
+ subtitlePadding: titleConfig.subtitlePadding,
60
+ });
61
+ }
62
+
63
+ /**
64
+ * @param {Partial<import("../spec/title.js").Title>} config
65
+ */
66
+ function pickDefined(config) {
67
+ return Object.fromEntries(
68
+ Object.entries(config).filter(([, value]) => value !== undefined)
69
+ );
70
+ }
71
+
72
+ /**
73
+ * @param {import("../spec/title.js").Title} spec
74
+ */
75
+ function getTitleOrientMetadata(spec) {
76
+ /** @type {Partial<import("../spec/title.js").Title>} */
77
+ let orientConfig = {};
78
+ let xy = { x: 0, y: 0 };
79
+
80
+ const anchorPos = ANCHORS[spec.anchor ?? "middle"];
81
+
82
+ switch (spec.orient) {
83
+ case "top":
84
+ xy = { x: anchorPos, y: 1 };
85
+ orientConfig = { baseline: "alphabetic", angle: 0 };
86
+ break;
87
+ case "right":
88
+ xy = { x: 1, y: 1 - anchorPos };
89
+ orientConfig = { baseline: "alphabetic", angle: 90 };
90
+ break;
91
+ case "bottom":
92
+ xy = { x: anchorPos, y: 0 };
93
+ orientConfig = { baseline: "top", angle: 0 };
94
+ break;
95
+ case "left":
96
+ xy = { x: 0, y: anchorPos };
97
+ orientConfig = { baseline: "alphabetic", angle: -90 };
98
+ break;
99
+ default:
100
+ }
101
+
102
+ return { orientConfig, xy };
103
+ }
104
+
105
+ /**
106
+ * @param {string | import("../spec/title.js").Title} title
107
+ * @param {import("../spec/config.js").GenomeSpyConfig[]} [configScopes]
108
+ * @returns {import("../spec/title.js").Title}
109
+ */
110
+ function resolveTitleSpec(title, configScopes = []) {
111
+ if (!title) {
112
+ return;
113
+ }
114
+
115
+ /** @type {import("../spec/title.js").Title} */
116
+ const titleSpec = isString(title) ? { text: title } : title;
117
+
118
+ if (!titleSpec.text) {
119
+ return;
120
+ }
121
+
122
+ const titleConfig = getConfiguredTitleConfig(configScopes);
123
+ const styleConfig = /** @type {import("../spec/config.js").TitleConfig} */ (
124
+ getConfiguredStyleConfig(
125
+ configScopes,
126
+ titleSpec.style ?? DEFAULT_TITLE_STYLE
127
+ )
128
+ );
129
+ const subtitleStyleConfig = subtitleStyleToTitleConfig(
130
+ getConfiguredStyleConfig(configScopes, DEFAULT_SUBTITLE_STYLE)
131
+ );
132
+
133
+ /** @type {import("../spec/title.js").Title} */
134
+ const preliminarySpec = {
135
+ ...titleConfig,
136
+ ...styleConfig,
137
+ ...subtitleStyleConfig,
138
+ ...pickSubtitleTitleConfig(titleConfig),
139
+ ...titleSpec,
140
+ };
141
+
142
+ if (preliminarySpec.orient == "none") {
143
+ return;
144
+ }
145
+
146
+ const { orientConfig } = getTitleOrientMetadata(preliminarySpec);
147
+
148
+ return {
149
+ ...titleConfig,
150
+ ...orientConfig,
151
+ ...styleConfig,
152
+ ...subtitleStyleConfig,
153
+ ...pickSubtitleTitleConfig(titleConfig),
154
+ ...titleSpec,
155
+ };
156
+ }
157
+
158
+ /**
159
+ * @param {import("../spec/title.js").Title} spec
160
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
161
+ * @returns {{ xOffset: number, yOffset: number }}
162
+ */
163
+ function getTitleOffsets(spec, context) {
164
+ const subtitleSpacing = spec.subtitle
165
+ ? getSubtitleTextPerpendicularExtent(spec, context) +
166
+ (spec.subtitlePadding ?? 0)
167
+ : 0;
168
+ const distance =
169
+ spec.offset +
170
+ (isTitleOutsideSubtitle(spec.orient) ? subtitleSpacing : 0);
171
+
172
+ return getOrientOffset(spec.orient, distance);
173
+ }
174
+
175
+ /**
176
+ * @param {import("../spec/title.js").Title} spec
177
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
178
+ * @returns {{ xOffset: number, yOffset: number }}
179
+ */
180
+ function getSubtitleOffsets(spec, context) {
181
+ const spacing =
182
+ getTitleTextPerpendicularExtent(spec, context) +
183
+ (spec.subtitlePadding ?? 0);
184
+ const distance =
185
+ spec.offset + (isTitleOutsideSubtitle(spec.orient) ? 0 : spacing);
186
+
187
+ return getOrientOffset(spec.orient, distance);
188
+ }
189
+
190
+ /**
191
+ * @param {import("../spec/title.js").TitleOrient} orient
192
+ */
193
+ function isTitleOutsideSubtitle(orient) {
194
+ switch (orient) {
195
+ case "top":
196
+ case "left":
197
+ return true;
198
+ case "right":
199
+ case "bottom":
200
+ return false;
201
+ default:
202
+ return false;
203
+ }
204
+ }
205
+
206
+ /**
207
+ * @param {import("../spec/title.js").TitleOrient} orient
208
+ * @param {number} distance
209
+ * @returns {{ xOffset: number, yOffset: number }}
210
+ */
211
+ function getOrientOffset(orient, distance) {
212
+ const offsets = { xOffset: 0, yOffset: 0 };
213
+ switch (orient) {
214
+ case "top":
215
+ offsets.yOffset = -distance;
216
+ break;
217
+ case "right":
218
+ offsets.xOffset = distance;
219
+ break;
220
+ case "bottom":
221
+ offsets.yOffset = distance;
222
+ break;
223
+ case "left":
224
+ offsets.xOffset = -distance;
225
+ break;
226
+ default:
227
+ }
228
+ return offsets;
229
+ }
230
+
231
+ /**
232
+ * @param {import("../spec/title.js").Title | undefined} spec
233
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
234
+ */
235
+ function requestTitleFont(spec, context) {
236
+ return requestFont(context.fontManager, spec ?? {});
237
+ }
238
+
239
+ /**
240
+ * @param {import("../spec/title.js").Title} spec
241
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
242
+ */
243
+ function requestSubtitleFont(spec, context) {
244
+ return requestFont(context.fontManager, getSubtitleFontConfig(spec));
245
+ }
246
+
247
+ /**
248
+ * Requests title fonts so asynchronous font loading is registered before
249
+ * layout uses title metrics.
250
+ *
251
+ * @param {import("../spec/title.js").Title} spec
252
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
253
+ */
254
+ function requestTitleFonts(spec, context) {
255
+ requestTitleFont(spec, context);
256
+ if (spec.subtitle) {
257
+ requestSubtitleFont(spec, context);
258
+ }
259
+ }
260
+
261
+ /**
262
+ * @param {import("../spec/title.js").Title} spec
263
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
264
+ * @returns {Padding}
265
+ */
266
+ function getTitleOverhang(spec, context) {
267
+ if (
268
+ !spec ||
269
+ spec.reserve === false ||
270
+ spec.orient == "none" ||
271
+ spec.offset < 0
272
+ ) {
273
+ return Padding.zero();
274
+ }
275
+
276
+ const extent = getTitlePerpendicularExtent(spec, context);
277
+ const reserved = Math.ceil(extent + Math.max(spec.offset ?? 0, 0));
278
+
279
+ switch (spec.orient) {
280
+ case "top":
281
+ return new Padding(reserved, 0, 0, 0);
282
+ case "right":
283
+ return new Padding(0, reserved, 0, 0);
284
+ case "bottom":
285
+ return new Padding(0, 0, reserved, 0);
286
+ case "left":
287
+ return new Padding(0, 0, 0, reserved);
288
+ default:
289
+ return Padding.zero();
290
+ }
291
+ }
292
+
293
+ /**
294
+ * @param {import("../spec/title.js").Title} spec
295
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
296
+ */
297
+ function getTitlePerpendicularExtent(spec, context) {
298
+ const titleExtent = getTitleTextPerpendicularExtent(spec, context);
299
+ if (!spec.subtitle) {
300
+ return titleExtent;
301
+ }
302
+
303
+ const subtitleExtent = getSubtitleTextPerpendicularExtent(spec, context);
304
+
305
+ return titleExtent + (spec.subtitlePadding ?? 0) + subtitleExtent;
306
+ }
307
+
308
+ /**
309
+ * @param {import("../spec/title.js").Title} spec
310
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
311
+ */
312
+ function getTitleTextPerpendicularExtent(spec, context) {
313
+ const font = requestTitleFont(spec, context);
314
+ const fontSize = getFontSize(spec.fontSize, 12);
315
+
316
+ return getTextPerpendicularExtent(
317
+ spec,
318
+ context,
319
+ spec.text,
320
+ font.metrics,
321
+ fontSize
322
+ );
323
+ }
324
+
325
+ /**
326
+ * @param {import("../spec/title.js").Title} spec
327
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
328
+ */
329
+ function getSubtitleTextPerpendicularExtent(spec, context) {
330
+ const font = requestSubtitleFont(spec, context);
331
+ const fontSize = getFontSize(spec.subtitleFontSize, 11);
332
+
333
+ return getTextPerpendicularExtent(
334
+ spec,
335
+ context,
336
+ spec.subtitle,
337
+ font.metrics,
338
+ fontSize
339
+ );
340
+ }
341
+
342
+ /**
343
+ * @param {number | import("../spec/parameter.js").ExprRef | undefined} fontSize
344
+ * @param {number} fallback
345
+ */
346
+ function getFontSize(fontSize, fallback) {
347
+ return isExprRef(fontSize) ? fallback : (fontSize ?? fallback);
348
+ }
349
+
350
+ /**
351
+ * @param {import("../spec/title.js").Title} spec
352
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
353
+ * @param {string | import("../spec/parameter.js").ExprRef} text
354
+ * @param {import("../fonts/textMetrics.js").FontEntryLike["metrics"]} metrics
355
+ * @param {number} fontSize
356
+ */
357
+ function getTextPerpendicularExtent(spec, context, text, metrics, fontSize) {
358
+ const angle = isExprRef(spec.angle) ? 0 : (spec.angle ?? 0);
359
+ const direction =
360
+ spec.orient == "top" || spec.orient == "bottom"
361
+ ? "vertical"
362
+ : "horizontal";
363
+
364
+ return getProjectedTextExtent(
365
+ measureTextWithFallback(text, context, metrics, fontSize),
366
+ angle,
367
+ direction
368
+ );
369
+ }
370
+
371
+ /**
372
+ * @param {import("../spec/title.js").Title} spec
373
+ * @returns {import("../fonts/textMetrics.js").FontConfig}
374
+ */
375
+ function getSubtitleFontConfig(spec) {
376
+ return {
377
+ font: spec.subtitleFont,
378
+ fontStyle: spec.subtitleFontStyle,
379
+ fontWeight: spec.subtitleFontWeight,
380
+ };
381
+ }
382
+
383
+ /**
384
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
385
+ * @param {string | import("../spec/parameter.js").ExprRef} text
386
+ * @param {import("../fonts/textMetrics.js").FontEntryLike["metrics"]} metrics
387
+ * @param {number} fontSize
388
+ */
389
+ function measureTextWithFallback(text, context, metrics, fontSize) {
390
+ if (metrics) {
391
+ return measureTextValue(text, metrics, fontSize);
392
+ }
393
+
394
+ const fallbackMetrics = context.fontManager.getDefaultFont().metrics;
395
+ if (fallbackMetrics) {
396
+ return measureTextValue(text, fallbackMetrics, fontSize);
397
+ }
398
+
399
+ return { width: 0, height: fontSize };
400
+ }
401
+
402
+ /**
403
+ * @param {string | import("../spec/parameter.js").ExprRef} text
404
+ * @param {import("../fonts/bmFontManager.js").BMFontMetrics} metrics
405
+ * @param {number} fontSize
406
+ */
407
+ function measureTextValue(text, metrics, fontSize) {
408
+ const value = typeof text == "string" ? text : String(text.expr);
409
+ return measureText(metrics, value, fontSize);
410
+ }
411
+
412
+ /**
413
+ * @param {import("../spec/title.js").Title} spec
414
+ * @param {{ x: number, y: number }} xy
415
+ * @param {{ xOffset: number, yOffset: number }} offsets
416
+ * @param {boolean} subtitle
417
+ * @returns {import("../spec/mark.js").TextProps}
418
+ */
419
+ function createTitleTextMark(spec, xy, offsets, subtitle) {
420
+ return {
421
+ type: "text",
422
+ tooltip: null,
423
+ clip: false,
424
+
425
+ ...xy,
426
+ ...offsets,
427
+
428
+ text: subtitle ? spec.subtitle : spec.text,
429
+
430
+ align: spec.align ?? ANCHOR_TO_ALIGN[spec.anchor ?? "middle"],
431
+ angle: spec.angle,
432
+ baseline: spec.baseline,
433
+ dx: spec.dx,
434
+ dy: spec.dy,
435
+ color: subtitle ? spec.subtitleColor : spec.color,
436
+ font: subtitle ? spec.subtitleFont : spec.font,
437
+ size: subtitle ? spec.subtitleFontSize : spec.fontSize,
438
+ fontStyle: subtitle ? spec.subtitleFontStyle : spec.fontStyle,
439
+ fontWeight: subtitle ? spec.subtitleFontWeight : spec.fontWeight,
440
+ };
441
+ }
442
+
443
+ /**
444
+ * @param {import("../spec/title.js").Title} titleSpec
445
+ * @param {{ fontManager: import("../fonts/textMetrics.js").FontManagerLike }} context
446
+ * @returns {import("../spec/view.js").UnitSpec[]}
447
+ */
448
+ function createTitleUnitSpecs(titleSpec, context) {
449
+ const { xy } = getTitleOrientMetadata(titleSpec);
450
+ const specs = [
451
+ {
452
+ name: "title",
453
+ data: { values: [{}] },
454
+ mark: createTitleTextMark(
455
+ titleSpec,
456
+ xy,
457
+ getTitleOffsets(titleSpec, context),
458
+ false
459
+ ),
460
+ },
461
+ ];
462
+
463
+ if (titleSpec.subtitle) {
464
+ specs.push({
465
+ name: "subtitle",
466
+ data: { values: [{}] },
467
+ mark: createTitleTextMark(
468
+ titleSpec,
469
+ xy,
470
+ getSubtitleOffsets(titleSpec, context),
471
+ true
472
+ ),
473
+ });
474
+ }
475
+
476
+ return specs;
477
+ }
478
+
479
+ /**
480
+ * Generated chrome view for view titles.
481
+ *
482
+ * @extends {ContainerView<import("../spec/view.js").LayerSpec>}
483
+ */
484
+ export default class TitleView extends ContainerView {
485
+ /** @type {UnitView[]} */
486
+ #children;
487
+
488
+ /** @type {import("../spec/title.js").Title} */
489
+ titleSpec;
490
+
491
+ /**
492
+ * @param {string | import("../spec/title.js").Title} title
493
+ * @param {import("../spec/config.js").GenomeSpyConfig[]} configScopes
494
+ * @param {import("../types/viewContext.js").default} context
495
+ * @param {ContainerView} layoutParent
496
+ * @param {import("./view.js").default} dataParent
497
+ * @param {string} name
498
+ * @param {import("./view.js").ViewOptions} [options]
499
+ * @returns {TitleView | undefined}
500
+ */
501
+ static create(
502
+ title,
503
+ configScopes,
504
+ context,
505
+ layoutParent,
506
+ dataParent,
507
+ name,
508
+ options
509
+ ) {
510
+ const titleSpec = resolveTitleSpec(title, configScopes);
511
+ return titleSpec
512
+ ? new TitleView(
513
+ titleSpec,
514
+ context,
515
+ layoutParent,
516
+ dataParent,
517
+ name,
518
+ options
519
+ )
520
+ : undefined;
521
+ }
522
+
523
+ /**
524
+ * @param {import("../spec/title.js").Title} titleSpec
525
+ * @param {import("../types/viewContext.js").default} context
526
+ * @param {ContainerView} layoutParent
527
+ * @param {import("./view.js").default} dataParent
528
+ * @param {string} name
529
+ * @param {import("./view.js").ViewOptions} [options]
530
+ */
531
+ constructor(titleSpec, context, layoutParent, dataParent, name, options) {
532
+ requestTitleFonts(titleSpec, context);
533
+
534
+ const childSpecs = createTitleUnitSpecs(titleSpec, context);
535
+ const spec = /** @type {import("../spec/view.js").LayerSpec} */ ({
536
+ layer: [],
537
+ });
538
+ super(spec, context, layoutParent, dataParent, name, options);
539
+ this.titleSpec = titleSpec;
540
+ markViewAsNonAddressable(this, { skipSubtree: true });
541
+ markViewAsChrome(this, { skipSubtree: true });
542
+
543
+ this.#children = childSpecs.map(
544
+ (unitSpec, index) =>
545
+ new UnitView(
546
+ unitSpec,
547
+ context,
548
+ this,
549
+ dataParent,
550
+ name + "-" + (unitSpec.name ?? index)
551
+ )
552
+ );
553
+ }
554
+
555
+ /**
556
+ * @returns {IterableIterator<UnitView>}
557
+ */
558
+ *[Symbol.iterator]() {
559
+ yield* this.#children;
560
+ }
561
+
562
+ getOverhang() {
563
+ return getTitleOverhang(this.titleSpec, this.context);
564
+ }
565
+
566
+ /**
567
+ * @param {import("./renderingContext/viewRenderingContext.js").default} context
568
+ * @param {import("./layout/rectangle.js").default} coords
569
+ * @param {import("../types/rendering.js").RenderingOptions} [options]
570
+ */
571
+ render(context, coords, options = {}) {
572
+ super.render(context, coords, options);
573
+
574
+ if (!this.isConfiguredVisible()) {
575
+ return;
576
+ }
577
+
578
+ context.pushView(this, coords);
579
+ for (const child of this.#children) {
580
+ child.render(context, coords, options);
581
+ }
582
+ context.popView(this);
583
+ }
584
+ }
@@ -21,10 +21,10 @@ export default class UnitView<TSpec extends import("../spec/view.js").UnitSpec =
21
21
  constructor(spec: TSpec, context: import("../types/viewContext.js").default, layoutParent: import("./containerView.js").default, dataParent: import("./view.js").default, name: string, options?: import("./view.js").ViewOptions);
22
22
  /** @type {import("../marks/mark.js").default} */
23
23
  mark: import("../marks/mark.js").default;
24
- getMarkType(): "text" | "point" | "link" | "rect" | "rule" | "tick";
24
+ getMarkType(): "rect" | "point" | "rule" | "tick" | "text" | "link";
25
25
  /**
26
- * Pulls scales and axes up in the view hierarcy according to the resolution rules, using dataParents.
27
- * TODO: legends
26
+ * Pulls scales and axes up in the view hierarchy according to the resolution rules, using dataParents.
27
+ * Legends are registered after scales so their resolution can refer to the source scale.
28
28
  *
29
29
  * @param {ResolutionTarget} [type] If not specified, both scales and axes are resolved.
30
30
  */
@@ -1 +1 @@
1
- {"version":3,"file":"unitView.d.ts","sourceRoot":"","sources":["../../../src/view/unitView.js"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,wBAHU,MAAM,CAAC,OAAO,iBAAiB,EAAE,QAAQ,EAAE,cAAc,kBAAkB,EAAE,OAAO,CAAC,CAgB7F;AAEF;;;GAGG;AACH,8BAHmD,KAAK,SAA3C,OAAQ,iBAAiB,EAAE,QAAS;IA2B7C;;;;;;;;OAQG;IACH,kBAPW,KAAK,WACL,OAAO,yBAAyB,EAAE,OAAO,gBACzC,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,WAAW,EAAE,OAAO,QAC3B,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAmDzC;IA1CO,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IAiLlC,oEAIC;IAoBD;;;;;OAKG;IACH,iEAOC;IAUD;;;;;OAKG;IACH,4IAQC;IAED;;;;OAIG;IACH,sBAFa,OAAO,WAAW,EAAE,UAAU,EAAE,CAS5C;IAkBD;;OAEG;IACH,uDAEC;IAED;;OAEG;IACH,oCAsFC;IAED,uBAQC;IAgBD;;;;OAIG;IACH,8BAJW,MAAM,+DAEJ,OAAO,iBAAiB,EAAE,kBAAkB,CAKxD;;CACJ;iBAjegB,WAAW"}
1
+ {"version":3,"file":"unitView.d.ts","sourceRoot":"","sources":["../../../src/view/unitView.js"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,wBAHU,MAAM,CAAC,OAAO,iBAAiB,EAAE,QAAQ,EAAE,cAAc,kBAAkB,EAAE,OAAO,CAAC,CAgB7F;AAEF;;;GAGG;AACH,8BAHmD,KAAK,SAA3C,OAAQ,iBAAiB,EAAE,QAAS;IA2B7C;;;;;;;;OAQG;IACH,kBAPW,KAAK,WACL,OAAO,yBAAyB,EAAE,OAAO,gBACzC,OAAO,oBAAoB,EAAE,OAAO,cACpC,OAAO,WAAW,EAAE,OAAO,QAC3B,MAAM,YACN,OAAO,WAAW,EAAE,WAAW,EAmDzC;IA1CO,iDAAiD;IACjD,MADW,OAAO,kBAAkB,EAAE,OAAO,CACnB;IAiLlC,oEAIC;IAoBD;;;;;OAKG;IACH,iEAQC;IAUD;;;;;OAKG;IACH,4IAQC;IAED;;;;OAIG;IACH,sBAFa,OAAO,WAAW,EAAE,UAAU,EAAE,CAS5C;IAkBD;;OAEG;IACH,uDAEC;IAED;;OAEG;IACH,oCAsFC;IAED,uBAQC;IAgBD;;;;OAIG;IACH,8BAJW,MAAM,+DAEJ,OAAO,iBAAiB,EAAE,kBAAkB,CAKxD;;CACJ;iBAlegB,WAAW"}
@@ -293,8 +293,8 @@ export default class UnitView extends View {
293
293
  }
294
294
 
295
295
  /**
296
- * Pulls scales and axes up in the view hierarcy according to the resolution rules, using dataParents.
297
- * TODO: legends
296
+ * Pulls scales and axes up in the view hierarchy according to the resolution rules, using dataParents.
297
+ * Legends are registered after scales so their resolution can refer to the source scale.
298
298
  *
299
299
  * @param {ResolutionTarget} [type] If not specified, both scales and axes are resolved.
300
300
  */
@@ -302,6 +302,7 @@ export default class UnitView extends View {
302
302
  if (!type) {
303
303
  this.resolve("scale");
304
304
  this.resolve("axis");
305
+ this.resolve("legend");
305
306
  return;
306
307
  }
307
308
  resolveViewResolutions(this, type);