@genome-spy/core 0.30.0 → 0.30.2

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 (234) hide show
  1. package/dist/index.es.js +16373 -0
  2. package/dist/index.js +43 -43
  3. package/package.json +10 -7
  4. package/src/data/collector.js +0 -183
  5. package/src/data/collector.test.js +0 -84
  6. package/src/data/dataFlow.js +0 -148
  7. package/src/data/dataFlow.test.js +0 -5
  8. package/src/data/facetNode.js +0 -17
  9. package/src/data/flow.test.js +0 -72
  10. package/src/data/flowBatch.d.ts +0 -40
  11. package/src/data/flowNode.js +0 -283
  12. package/src/data/flowNode.test.js +0 -50
  13. package/src/data/flowOptimizer.js +0 -123
  14. package/src/data/flowOptimizer.test.js +0 -193
  15. package/src/data/flowTestUtils.js +0 -63
  16. package/src/data/formats/fasta.js +0 -32
  17. package/src/data/formats/fasta.test.js +0 -27
  18. package/src/data/sources/dataSource.js +0 -22
  19. package/src/data/sources/dataSourceFactory.js +0 -24
  20. package/src/data/sources/dataUtils.js +0 -78
  21. package/src/data/sources/dynamicCallbackSource.js +0 -57
  22. package/src/data/sources/dynamicSource.js +0 -37
  23. package/src/data/sources/inlineSource.js +0 -67
  24. package/src/data/sources/inlineSource.test.js +0 -56
  25. package/src/data/sources/namedSource.js +0 -79
  26. package/src/data/sources/sequenceSource.js +0 -46
  27. package/src/data/sources/sequenceSource.test.js +0 -46
  28. package/src/data/sources/urlSource.js +0 -74
  29. package/src/data/transforms/aggregate.js +0 -70
  30. package/src/data/transforms/clone.js +0 -40
  31. package/src/data/transforms/clone.test.js +0 -11
  32. package/src/data/transforms/coverage.js +0 -187
  33. package/src/data/transforms/coverage.test.js +0 -123
  34. package/src/data/transforms/filter.js +0 -37
  35. package/src/data/transforms/filter.test.js +0 -18
  36. package/src/data/transforms/filterScoredLabels.js +0 -134
  37. package/src/data/transforms/flattenCompressedExons.js +0 -57
  38. package/src/data/transforms/flattenDelimited.js +0 -74
  39. package/src/data/transforms/flattenDelimited.test.js +0 -87
  40. package/src/data/transforms/flattenSequence.js +0 -39
  41. package/src/data/transforms/flattenSequence.test.js +0 -34
  42. package/src/data/transforms/formula.js +0 -39
  43. package/src/data/transforms/formula.test.js +0 -19
  44. package/src/data/transforms/identifier.js +0 -108
  45. package/src/data/transforms/identifier.test.js +0 -83
  46. package/src/data/transforms/linearizeGenomicCoordinate.js +0 -101
  47. package/src/data/transforms/measureText.js +0 -44
  48. package/src/data/transforms/pileup.js +0 -128
  49. package/src/data/transforms/pileup.test.js +0 -70
  50. package/src/data/transforms/project.js +0 -41
  51. package/src/data/transforms/project.test.js +0 -32
  52. package/src/data/transforms/regexExtract.js +0 -61
  53. package/src/data/transforms/regexExtract.test.js +0 -67
  54. package/src/data/transforms/regexFold.js +0 -141
  55. package/src/data/transforms/regexFold.test.js +0 -160
  56. package/src/data/transforms/sample.js +0 -101
  57. package/src/data/transforms/sample.test.js +0 -38
  58. package/src/data/transforms/stack.js +0 -137
  59. package/src/data/transforms/stack.test.js +0 -91
  60. package/src/data/transforms/transformFactory.js +0 -60
  61. package/src/embedApi.d.ts +0 -67
  62. package/src/encoder/accessor.js +0 -82
  63. package/src/encoder/accessor.test.js +0 -47
  64. package/src/encoder/encoder.js +0 -394
  65. package/src/encoder/encoder.test.js +0 -98
  66. package/src/fonts/Lato-Regular.json +0 -1267
  67. package/src/fonts/Lato-Regular.png +0 -0
  68. package/src/fonts/OFL.txt +0 -93
  69. package/src/fonts/README.md +0 -3
  70. package/src/fonts/bmFont.d.ts +0 -58
  71. package/src/fonts/bmFontManager.js +0 -357
  72. package/src/fonts/bmFontMetrics.js +0 -108
  73. package/src/genome/genome.js +0 -317
  74. package/src/genome/genome.test.js +0 -188
  75. package/src/genome/genomeStore.js +0 -54
  76. package/src/genome/locusFormat.js +0 -31
  77. package/src/genome/scaleIndex.d.ts +0 -38
  78. package/src/genome/scaleIndex.js +0 -166
  79. package/src/genome/scaleIndex.test.js +0 -78
  80. package/src/genome/scaleLocus.d.ts +0 -11
  81. package/src/genome/scaleLocus.js +0 -108
  82. package/src/genome/scaleLocus.test.js +0 -4
  83. package/src/genomeSpy.js +0 -785
  84. package/src/gl/arrayBuilder.js +0 -199
  85. package/src/gl/dataToVertices.js +0 -636
  86. package/src/gl/includes/common.glsl +0 -63
  87. package/src/gl/includes/picking.fragment.glsl +0 -1
  88. package/src/gl/includes/picking.vertex.glsl +0 -27
  89. package/src/gl/includes/sampleFacet.glsl +0 -107
  90. package/src/gl/includes/scales.glsl +0 -112
  91. package/src/gl/link.fragment.glsl +0 -18
  92. package/src/gl/link.vertex.glsl +0 -111
  93. package/src/gl/point.fragment.glsl +0 -123
  94. package/src/gl/point.vertex.glsl +0 -129
  95. package/src/gl/rect.fragment.glsl +0 -51
  96. package/src/gl/rect.vertex.glsl +0 -114
  97. package/src/gl/rule.fragment.glsl +0 -52
  98. package/src/gl/rule.vertex.glsl +0 -89
  99. package/src/gl/text.fragment.glsl +0 -31
  100. package/src/gl/text.vertex.glsl +0 -246
  101. package/src/gl/webGLHelper.js +0 -504
  102. package/src/img/bowtie.svg +0 -1
  103. package/src/img/genomespy-favicon.svg +0 -34
  104. package/src/index.html +0 -11
  105. package/src/index.js +0 -128
  106. package/src/marks/link.js +0 -175
  107. package/src/marks/mark.js +0 -975
  108. package/src/marks/markUtils.js +0 -125
  109. package/src/marks/pointMark.js +0 -251
  110. package/src/marks/rectMark.js +0 -241
  111. package/src/marks/rule.js +0 -250
  112. package/src/marks/text.js +0 -278
  113. package/src/node_modules/.vitest/results.json +0 -1
  114. package/src/scale/colorUtils.js +0 -184
  115. package/src/scale/glslScaleGenerator.js +0 -502
  116. package/src/scale/scale.js +0 -451
  117. package/src/scale/scale.test.js +0 -324
  118. package/src/scale/ticks.js +0 -203
  119. package/src/scale/ticks.test.js +0 -40
  120. package/src/singlePageApp.js +0 -13
  121. package/src/spec/axis.d.ts +0 -296
  122. package/src/spec/channel.d.ts +0 -430
  123. package/src/spec/data.d.ts +0 -196
  124. package/src/spec/font.d.ts +0 -15
  125. package/src/spec/genome.d.ts +0 -35
  126. package/src/spec/mark.d.ts +0 -429
  127. package/src/spec/root.d.ts +0 -17
  128. package/src/spec/sampleView.d.ts +0 -180
  129. package/src/spec/scale.d.ts +0 -273
  130. package/src/spec/title.d.ts +0 -102
  131. package/src/spec/tooltip.d.ts +0 -9
  132. package/src/spec/transform.d.ts +0 -479
  133. package/src/spec/view.d.ts +0 -201
  134. package/src/styles/genome-spy.scss +0 -153
  135. package/src/tooltip/dataTooltipHandler.js +0 -64
  136. package/src/tooltip/refseqGeneTooltipHandler.js +0 -78
  137. package/src/tooltip/tooltipHandler.ts +0 -12
  138. package/src/types/filetypes.d.ts +0 -14
  139. package/src/types/flatqueue.d.ts +0 -53
  140. package/src/types/glsl.d.ts +0 -4
  141. package/src/types/internmap.d.ts +0 -22
  142. package/src/types/object.d.ts +0 -21
  143. package/src/types/vega-loader.d.ts +0 -1
  144. package/src/types/vega-scale.d.ts +0 -60
  145. package/src/utils/addBaseUrl.js +0 -19
  146. package/src/utils/addBaseUrl.test.js +0 -22
  147. package/src/utils/animator.js +0 -83
  148. package/src/utils/arrayUtils.js +0 -61
  149. package/src/utils/binnedIndex.js +0 -167
  150. package/src/utils/binnedIndex.test.js +0 -155
  151. package/src/utils/clamp.js +0 -8
  152. package/src/utils/cloner.js +0 -34
  153. package/src/utils/cloner.test.js +0 -24
  154. package/src/utils/coalesce.js +0 -11
  155. package/src/utils/coalesce.test.js +0 -16
  156. package/src/utils/concatIterables.js +0 -26
  157. package/src/utils/concatIterables.test.js +0 -8
  158. package/src/utils/debounce.js +0 -37
  159. package/src/utils/domainArray.js +0 -216
  160. package/src/utils/domainArray.test.js +0 -130
  161. package/src/utils/eerp.js +0 -13
  162. package/src/utils/expression.js +0 -32
  163. package/src/utils/field.js +0 -28
  164. package/src/utils/formatObject.js +0 -31
  165. package/src/utils/indexer.js +0 -43
  166. package/src/utils/indexer.test.js +0 -47
  167. package/src/utils/inertia.js +0 -124
  168. package/src/utils/interactionEvent.js +0 -33
  169. package/src/utils/iterateNestedMaps.js +0 -21
  170. package/src/utils/iterateNestedMaps.test.js +0 -33
  171. package/src/utils/kWayMerge.js +0 -42
  172. package/src/utils/kWayMerge.test.js +0 -26
  173. package/src/utils/layout/flexLayout.js +0 -368
  174. package/src/utils/layout/flexLayout.test.js +0 -311
  175. package/src/utils/layout/grid.js +0 -95
  176. package/src/utils/layout/grid.test.js +0 -71
  177. package/src/utils/layout/padding.js +0 -120
  178. package/src/utils/layout/point.js +0 -23
  179. package/src/utils/layout/rectangle.js +0 -288
  180. package/src/utils/layout/rectangle.test.js +0 -172
  181. package/src/utils/mergeObjects.js +0 -99
  182. package/src/utils/mergeObjects.test.js +0 -42
  183. package/src/utils/numberExtractor.js +0 -24
  184. package/src/utils/numberExtractor.test.js +0 -6
  185. package/src/utils/point.js +0 -14
  186. package/src/utils/propertyCacher.js +0 -70
  187. package/src/utils/propertyCacher.test.js +0 -85
  188. package/src/utils/propertyCoalescer.js +0 -42
  189. package/src/utils/propertyCoalescer.test.js +0 -22
  190. package/src/utils/reservationMap.js +0 -103
  191. package/src/utils/reservationMap.test.js +0 -20
  192. package/src/utils/scaleNull.js +0 -19
  193. package/src/utils/setOperations.js +0 -75
  194. package/src/utils/smoothstep.js +0 -10
  195. package/src/utils/throttle.js +0 -34
  196. package/src/utils/topK.js +0 -76
  197. package/src/utils/topK.test.js +0 -64
  198. package/src/utils/transition.js +0 -74
  199. package/src/utils/ui/tooltip.js +0 -189
  200. package/src/utils/url.js +0 -22
  201. package/src/utils/variableTools.js +0 -24
  202. package/src/utils/variableTools.test.js +0 -13
  203. package/src/view/axisResolution.js +0 -140
  204. package/src/view/axisResolution.test.js +0 -201
  205. package/src/view/axisView.js +0 -747
  206. package/src/view/concatView.js +0 -45
  207. package/src/view/containerView.js +0 -159
  208. package/src/view/facetView.js +0 -491
  209. package/src/view/flowBuilder.js +0 -367
  210. package/src/view/flowBuilder.test.js +0 -125
  211. package/src/view/gridView.js +0 -786
  212. package/src/view/implicitRootView.js +0 -14
  213. package/src/view/importView.js +0 -19
  214. package/src/view/layerView.js +0 -74
  215. package/src/view/rendering.d.ts +0 -44
  216. package/src/view/renderingContext/compositeViewRenderingContext.js +0 -51
  217. package/src/view/renderingContext/deferredViewRenderingContext.js +0 -176
  218. package/src/view/renderingContext/layoutRecorderViewRenderingContext.js +0 -128
  219. package/src/view/renderingContext/simpleViewRenderingContext.js +0 -64
  220. package/src/view/renderingContext/svgViewRenderingContext.js +0 -125
  221. package/src/view/renderingContext/viewRenderingContext.js +0 -41
  222. package/src/view/scaleResolution.js +0 -797
  223. package/src/view/scaleResolution.test.js +0 -572
  224. package/src/view/scaleResolutionApi.d.ts +0 -40
  225. package/src/view/testUtils.js +0 -51
  226. package/src/view/title.js +0 -165
  227. package/src/view/unitView.js +0 -382
  228. package/src/view/view.js +0 -612
  229. package/src/view/view.test.js +0 -214
  230. package/src/view/viewContext.d.ts +0 -62
  231. package/src/view/viewFactory.js +0 -181
  232. package/src/view/viewFactory.test.js +0 -17
  233. package/src/view/viewUtils.js +0 -327
  234. package/src/view/zoom.js +0 -89
@@ -1,125 +0,0 @@
1
- import {
2
- isValueDef,
3
- getSecondaryChannel,
4
- isChannelDefWithScale,
5
- } from "../encoder/encoder";
6
-
7
- /**
8
- *
9
- * @typedef {import("../spec/channel").Encoding} Encoding
10
- * @typedef {import("../spec/channel").Channel} Channel
11
- */
12
-
13
- /**
14
- * @param {Encoding} encoding
15
- * @param {import("../spec/channel").PrimaryPositionalChannel} channel
16
- */
17
- export function fixPositional(encoding, channel) {
18
- const secondaryChannel = getSecondaryChannel(channel);
19
-
20
- // Must make copies because the definition may be shared with other views/marks
21
- let primary = encoding[channel] && { ...encoding[channel] };
22
- let secondary = encoding[secondaryChannel] && {
23
- ...encoding[secondaryChannel],
24
- };
25
-
26
- if (isValueDef(primary) || isValueDef(secondary)) {
27
- return;
28
- }
29
-
30
- if (primary) {
31
- // TODO: fix. May not be a proper type guard.
32
- if (!isChannelDefWithScale(encoding[channel])) {
33
- // nop
34
- return;
35
- }
36
-
37
- if (!secondary) {
38
- if (primary.type == "quantitative") {
39
- // Bar plot, anchor the other end to zero
40
- secondary = { datum: 0 };
41
- } else {
42
- secondary = { ...primary };
43
-
44
- // Fill the bands (bar plot / heatmap)
45
- // We are following the Vega-Lite convention:
46
- // the band property works differently on rectangular marks, i.e., it adjusts the band coverage.
47
- const adjustment = (1 - (primary.band ?? 1)) / 2;
48
- primary.band = 0 + adjustment;
49
- secondary.band = 1 - adjustment;
50
-
51
- // TODO: If the secondary channel duplicates the primary channel
52
- // the data should be uploaded to the GPU only once.
53
- }
54
- } else if (primary.type != "quantitative") {
55
- const adjustment = (1 - (primary.band || 1)) / 2;
56
- primary.band = adjustment;
57
- secondary.band = -adjustment;
58
- }
59
- } else {
60
- // Nothing specified, fill the whole viewport
61
- primary = { value: 0 };
62
- secondary = { value: 1 };
63
- }
64
-
65
- encoding[channel] = primary;
66
- encoding[secondaryChannel] = secondary;
67
- }
68
-
69
- /**
70
- * @param {import("../spec/channel").Encoding} encoding
71
- * @param {boolean} filled
72
- */
73
- export function fixStroke(encoding, filled) {
74
- if (!encoding.stroke) {
75
- if (filled) {
76
- encoding.stroke = { value: null };
77
- } else {
78
- encoding.stroke = {
79
- resolutionChannel: "color",
80
- ...encoding.color,
81
- };
82
- // TODO: Whattabout default strokeWidth?
83
- }
84
- }
85
-
86
- if (isValueDef(encoding.stroke) && encoding.stroke.value === null) {
87
- encoding.strokeWidth = { value: 0 };
88
- }
89
-
90
- if (!encoding.strokeOpacity) {
91
- encoding.strokeOpacity = {
92
- resolutionChannel: "opacity",
93
- ...encoding.opacity,
94
- };
95
- }
96
- }
97
-
98
- /**
99
- * @param {import("../spec/channel").Encoding} encoding
100
- * @param {boolean} filled
101
- */
102
- export function fixFill(encoding, filled) {
103
- if (isValueDef(encoding.fill) && encoding.fill.value === null) {
104
- encoding.fillOpacity = { value: 0 };
105
- } else if (!encoding.fill) {
106
- encoding.fill = {
107
- resolutionChannel: "color",
108
- ...encoding.color,
109
- };
110
- if (!filled && !encoding.fillOpacity) {
111
- encoding.fillOpacity = { value: 0 };
112
- }
113
- }
114
-
115
- if (!encoding.fillOpacity) {
116
- if (filled) {
117
- encoding.fillOpacity = {
118
- resolutionChannel: "opacity",
119
- ...encoding.opacity,
120
- };
121
- } else {
122
- encoding.fillOpacity = { value: 0 };
123
- }
124
- }
125
- }
@@ -1,251 +0,0 @@
1
- import { drawBufferInfo, setBuffersAndAttributes, setUniforms } from "twgl.js";
2
- import { quantileSorted } from "d3-array";
3
- import { PointVertexBuilder } from "../gl/dataToVertices";
4
- import VERTEX_SHADER from "../gl/point.vertex.glsl";
5
- import FRAGMENT_SHADER from "../gl/point.fragment.glsl";
6
-
7
- import Mark from "./mark";
8
- import { sampleIterable } from "../data/transforms/sample";
9
- import { fixFill, fixStroke } from "./markUtils";
10
-
11
- /** @type {Record<string, import("../view/viewUtils").ChannelDef>} */
12
- const defaultEncoding = {};
13
-
14
- export default class PointMark extends Mark {
15
- /**
16
- * @param {import("../view/unitView").default} unitView
17
- */
18
- constructor(unitView) {
19
- super(unitView);
20
-
21
- Object.defineProperties(
22
- this.defaultProperties,
23
- Object.getOwnPropertyDescriptors({
24
- x: 0.5,
25
- y: 0.5,
26
- color: "#4c78a8",
27
- filled: true,
28
- opacity: 1.0,
29
- size: 100.0,
30
- semanticScore: 0.0, // TODO: Should be datum instead of value. But needs fixing.
31
- shape: "circle",
32
- strokeWidth: 2.0,
33
- fillGradientStrength: 0.0,
34
- dx: 0,
35
- dy: 0,
36
- angle: 0,
37
-
38
- sampleFacetPadding: 0.1,
39
-
40
- semanticZoomFraction: 0.02,
41
- })
42
- );
43
- }
44
-
45
- getAttributes() {
46
- return [
47
- "inwardStroke",
48
- "uniqueId",
49
- "facetIndex",
50
- "x",
51
- "y",
52
- "size",
53
- "semanticScore",
54
- "shape",
55
- "strokeWidth",
56
- "gradientStrength",
57
- "dx",
58
- "dy",
59
- "fill",
60
- "stroke",
61
- "fillOpacity",
62
- "strokeOpacity",
63
- "angle",
64
- ];
65
- }
66
-
67
- /**
68
- * @returns {import("../spec/channel").Channel[]}
69
- */
70
- getSupportedChannels() {
71
- return [
72
- ...super.getSupportedChannels(),
73
- "size",
74
- "semanticScore",
75
- "shape",
76
- "strokeWidth",
77
- "dx",
78
- "dy",
79
- "fill",
80
- "stroke",
81
- "fillOpacity",
82
- "strokeOpacity",
83
- "angle",
84
- ];
85
- }
86
-
87
- getDefaultEncoding() {
88
- return { ...super.getDefaultEncoding(), ...defaultEncoding };
89
- }
90
-
91
- /**
92
- * @param {import("../spec/channel").Encoding} encoding
93
- * @returns {import("../spec/channel").Encoding}
94
- */
95
- fixEncoding(encoding) {
96
- fixStroke(encoding, this.properties.filled);
97
- fixFill(encoding, this.properties.filled);
98
-
99
- // TODO: Function for getting rid of extras. Also should validate that all attributes are defined
100
- delete encoding.color;
101
- delete encoding.opacity;
102
-
103
- return encoding;
104
- }
105
-
106
- initializeData() {
107
- super.initializeData();
108
-
109
- // Semantic zooming is currently solely a feature of point mark.
110
- // Build a sorted sample that allows for computing p-quantiles
111
- const semanticScoreAccessor =
112
- this.unitView.getAccessor("semanticScore");
113
- if (semanticScoreAccessor) {
114
- // n chosen using Stetson-Harrison
115
- // TODO: Throw on missing scores
116
- this.sampledSemanticScores = Float32Array.from(
117
- sampleIterable(
118
- 10000,
119
- this.unitView.getCollector().getData(),
120
- semanticScoreAccessor
121
- )
122
- );
123
- this.sampledSemanticScores.sort((a, b) => a - b);
124
- }
125
- }
126
-
127
- async initializeGraphics() {
128
- await super.initializeGraphics();
129
- this.createAndLinkShaders(VERTEX_SHADER, FRAGMENT_SHADER);
130
- }
131
-
132
- finalizeGraphicsInitialization() {
133
- super.finalizeGraphicsInitialization();
134
-
135
- this.gl.useProgram(this.programInfo.program);
136
-
137
- const props = this.properties;
138
- setUniforms(this.programInfo, {
139
- uInwardStroke: props.inwardStroke,
140
- uGradientStrength: props.fillGradientStrength,
141
- uMaxRelativePointDiameter: 1 - 2 * props.sampleFacetPadding,
142
- });
143
- }
144
-
145
- updateGraphicsData() {
146
- const collector = this.unitView.getCollector();
147
- const itemCount = collector.getItemCount();
148
-
149
- const builder = new PointVertexBuilder({
150
- encoders: this.encoders,
151
- attributes: this.getAttributes(),
152
- numItems: Math.max(itemCount, this.properties.minBufferSize || 0),
153
- });
154
-
155
- builder.addBatches(collector.facetBatches);
156
-
157
- const vertexData = builder.toArrays();
158
- this.rangeMap.migrateEntries(vertexData.rangeMap);
159
- this.updateBufferInfo(vertexData);
160
- }
161
-
162
- _getGeometricScaleFactor() {
163
- const zoomLevel = Math.pow(2, this.properties.geometricZoomBound || 0);
164
-
165
- return Math.pow(
166
- Math.min(1, this.unitView.getZoomLevel() / zoomLevel),
167
- 1 / 3
168
- // note: 1/3 appears to yield perceptually more uniform result than 1/2. I don't know why!
169
- );
170
- }
171
-
172
- /**
173
- * Returns the maximum size of the points in the data, before any scaling
174
- */
175
- _getMaxPointSize() {
176
- const e = this.encoders.size;
177
- if (e.constant) {
178
- return e(null);
179
- } else {
180
- return /** @type {number[]} */ (e.scale.range()).reduce((a, b) =>
181
- Math.max(a, b)
182
- );
183
- }
184
- }
185
-
186
- getSemanticThreshold() {
187
- if (this.sampledSemanticScores) {
188
- const p = Math.max(
189
- 0,
190
- 1 -
191
- this.properties.semanticZoomFraction *
192
- this.unitView.getZoomLevel()
193
- );
194
- if (p <= 0) {
195
- // The sampled scores may be missing the min/max values
196
- return -Infinity;
197
- } else if (p >= 1) {
198
- return Infinity;
199
- } else {
200
- const scores = /** @type {any} */ (this.sampledSemanticScores);
201
- return quantileSorted(/** @type {number[]} */ (scores), p);
202
- }
203
- } else {
204
- return -1;
205
- }
206
- }
207
-
208
- /**
209
- * @param {import("../view/rendering").GlobalRenderingOptions} options
210
- */
211
- prepareRender(options) {
212
- const ops = super.prepareRender(options);
213
-
214
- ops.push(() =>
215
- setUniforms(this.programInfo, {
216
- uMaxPointSize: this._getMaxPointSize(),
217
- uScaleFactor: this._getGeometricScaleFactor(),
218
- uSemanticThreshold: this.getSemanticThreshold(),
219
- })
220
- );
221
-
222
- ops.push(() =>
223
- setBuffersAndAttributes(
224
- this.gl,
225
- this.programInfo,
226
- this.vertexArrayInfo
227
- )
228
- );
229
-
230
- return ops;
231
- }
232
-
233
- /**
234
- * @param {import("./Mark").MarkRenderingOptions} options
235
- */
236
- render(options) {
237
- const gl = this.gl;
238
-
239
- return this.createRenderCallback((offset, count) => {
240
- if (count) {
241
- drawBufferInfo(
242
- gl,
243
- this.vertexArrayInfo,
244
- gl.POINTS,
245
- count,
246
- offset
247
- );
248
- }
249
- }, options);
250
- }
251
- }
@@ -1,241 +0,0 @@
1
- import { drawBufferInfo, setBuffersAndAttributes, setUniforms } from "twgl.js";
2
- import VERTEX_SHADER from "../gl/rect.vertex.glsl";
3
- import FRAGMENT_SHADER from "../gl/rect.fragment.glsl";
4
- import { RectVertexBuilder } from "../gl/dataToVertices";
5
-
6
- import Mark from "./mark";
7
- import { fixFill, fixPositional, fixStroke } from "./markUtils";
8
- import { asArray } from "../utils/arrayUtils";
9
- import { isValueDef } from "../encoder/encoder";
10
- import { getCachedOrCall } from "../utils/propertyCacher";
11
-
12
- export default class RectMark extends Mark {
13
- /**
14
- * @param {import("../view/unitView").default} unitView
15
- */
16
- constructor(unitView) {
17
- super(unitView);
18
-
19
- Object.defineProperties(
20
- this.defaultProperties,
21
- Object.getOwnPropertyDescriptors({
22
- x2: undefined,
23
- y2: undefined,
24
- filled: true,
25
- color: "#4c78a8",
26
- opacity: 1.0,
27
- strokeWidth: 3,
28
- cornerRadius: 0.0,
29
-
30
- minWidth: 0.5, // Minimum width/height prevents annoying flickering when zooming
31
- minHeight: 0.5,
32
- minOpacity: 1.0,
33
-
34
- tessellationZoomThreshold: 10, // This works with genomes, but likely breaks with other data. TODO: Fix, TODO: log2
35
- tessellationTiles: 35, // TODO: Tiles per unit (bp)
36
- })
37
- );
38
- }
39
-
40
- getAttributes() {
41
- return [
42
- "uniqueId",
43
- "facetIndex",
44
- "x",
45
- "x2",
46
- "y",
47
- "y2",
48
- "fill",
49
- "stroke",
50
- "fillOpacity",
51
- "strokeOpacity",
52
- "strokeWidth",
53
- ];
54
- }
55
-
56
- /**
57
- * @returns {import("../spec/channel").Channel[]}
58
- */
59
- getSupportedChannels() {
60
- return [
61
- ...super.getSupportedChannels(),
62
- "x2",
63
- "y2",
64
- "fill",
65
- "stroke",
66
- "fillOpacity",
67
- "strokeOpacity",
68
- "strokeWidth",
69
- ];
70
- }
71
-
72
- get opaque() {
73
- return (
74
- getCachedOrCall(
75
- this,
76
- "opaque",
77
- () =>
78
- !this._isRoundedCorners() &&
79
- !this._isStroked() &&
80
- isValueDef(this.encoding.fillOpacity) &&
81
- this.encoding.fillOpacity.value == 1.0 &&
82
- this.properties.minOpacity == 1.0
83
- ) && this.unitView.getEffectiveOpacity() == 1
84
- );
85
- }
86
-
87
- /**
88
- * @param {import("../spec/channel").Encoding} encoding
89
- * @returns {import("../spec/channel").Encoding}
90
- */
91
- fixEncoding(encoding) {
92
- // TODO: Ensure that both the primary and secondary channel are either variables or constants (values)
93
- fixPositional(encoding, "x");
94
- fixPositional(encoding, "y");
95
-
96
- fixStroke(encoding, this.properties.filled);
97
- fixFill(encoding, this.properties.filled);
98
-
99
- // TODO: Function for getting rid of extras. Also should validate that all attributes are defined
100
- delete encoding.color;
101
- delete encoding.opacity;
102
-
103
- return encoding;
104
- }
105
-
106
- onBeforeSampleAnimation() {
107
- // TODO: Tessellate rects inside the viewport
108
- }
109
-
110
- onAfterSampleAnimation() {
111
- // TODO: Pop the previous buffers
112
- }
113
-
114
- _isRoundedCorners() {
115
- return ["", "TopLeft", "TopRight", "BottomLeft", "BottomRight"]
116
- .map(
117
- (c) =>
118
- /** @type {keyof import("../spec/mark").MarkConfig} */ (
119
- "cornerRadius" + c
120
- )
121
- )
122
- .some((c) => this.properties[c] > 0);
123
- }
124
-
125
- _isStroked() {
126
- const sw = this.encoding.strokeWidth;
127
- return !(isValueDef(sw) && !sw.value);
128
- }
129
-
130
- async initializeGraphics() {
131
- await super.initializeGraphics();
132
-
133
- /** @type {string[]} */
134
- const defines = [];
135
- if (this._isRoundedCorners()) {
136
- defines.push("ROUNDED_CORNERS");
137
- }
138
- if (this._isStroked()) {
139
- defines.push("STROKED");
140
- }
141
-
142
- this.createAndLinkShaders(
143
- VERTEX_SHADER,
144
- FRAGMENT_SHADER,
145
- defines.map((d) => "#define " + d)
146
- );
147
- }
148
-
149
- finalizeGraphicsInitialization() {
150
- super.finalizeGraphicsInitialization();
151
-
152
- this.gl.useProgram(this.programInfo.program);
153
-
154
- const props = this.properties;
155
-
156
- setUniforms(this.programInfo, {
157
- uMinSize: [props.minWidth, props.minHeight], // in pixels
158
- uMinOpacity: props.minOpacity,
159
- uCornerRadii: [
160
- props.cornerRadiusTopRight ?? props.cornerRadius,
161
- props.cornerRadiusBottomRight ?? props.cornerRadius,
162
- props.cornerRadiusTopLeft ?? props.cornerRadius,
163
- props.cornerRadiusBottomLeft ?? props.cornerRadius,
164
- ],
165
- });
166
- }
167
-
168
- updateGraphicsData() {
169
- const collector = this.unitView.getCollector();
170
- const numItems = collector.getItemCount();
171
-
172
- // TODO: Disable tessellation on SimpleTrack - no need for it
173
- const builder = new RectVertexBuilder({
174
- encoders: this.encoders,
175
- attributes: this.getAttributes(),
176
- numItems,
177
- });
178
-
179
- builder.addBatches(collector.facetBatches);
180
-
181
- const vertexData = builder.toArrays();
182
- this.rangeMap.migrateEntries(vertexData.rangeMap);
183
- this.updateBufferInfo(vertexData);
184
- }
185
-
186
- /**
187
- * @param {import("../view/rendering").GlobalRenderingOptions} options
188
- */
189
- prepareRender(options) {
190
- const ops = super.prepareRender(options);
191
-
192
- ops.push(() =>
193
- setBuffersAndAttributes(
194
- this.gl,
195
- this.programInfo,
196
- this.vertexArrayInfo
197
- )
198
- );
199
-
200
- return ops;
201
- }
202
-
203
- /**
204
- * @param {import("./Mark").MarkRenderingOptions} options
205
- */
206
- render(options) {
207
- const gl = this.gl;
208
-
209
- return this.createRenderCallback((offset, count) => {
210
- drawBufferInfo(
211
- gl,
212
- this.vertexArrayInfo,
213
- gl.TRIANGLE_STRIP,
214
- count,
215
- offset
216
- );
217
- }, options);
218
- }
219
-
220
- /**
221
- * Finds a datum that overlaps the given value on the x domain.
222
- * The result is unspecified if multiple data are found.
223
- *
224
- * This is highly specific to SampleView and its sorting/filtering functionality.
225
- *
226
- * @param {any} facetId
227
- * @param {number} x position on the x domain
228
- * @returns {any}
229
- */
230
- findDatumAt(facetId, x) {
231
- facetId = asArray(facetId); // TODO: Do at the call site
232
- const e = this.encoders;
233
- const data = this.unitView.getCollector().facetBatches.get(facetId);
234
- const a = e.x.accessor;
235
- const a2 = e.x2.accessor;
236
- if (data) {
237
- // TODO: Binary search
238
- return data.find((d) => x >= a(d) && x < a2(d));
239
- }
240
- }
241
- }