@genome-spy/core 0.29.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 -784
  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 -489
  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 -488
  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 -791
  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,636 +0,0 @@
1
- import { InternMap } from "internmap";
2
- import { format } from "d3-format";
3
- import { isString } from "vega-util";
4
- import ArrayBuilder from "./arrayBuilder";
5
- import { SDF_PADDING } from "../fonts/bmFontMetrics";
6
- import { createBinningRangeIndexer } from "../utils/binnedIndex";
7
- import { isValueDef } from "../encoder/encoder";
8
- import {
9
- isHighPrecisionScale,
10
- splitHighPrecision,
11
- } from "../scale/glslScaleGenerator";
12
- import { isContinuous } from "vega-scale";
13
-
14
- /**
15
- * @typedef {object} RangeEntry Represents a location of a vertex subset
16
- * @prop {number} offset in vertices
17
- * @prop {number} count in vertices
18
- * @prop {import("../utils/binnedIndex").Lookup} xIndex
19
- *
20
- * @typedef {import("./arraybuilder").ConverterMetadata} Converter
21
- * @typedef {import("../encoder/encoder").Encoder} Encoder
22
- */
23
- export class GeometryBuilder {
24
- /**
25
- *
26
- * @param {object} object
27
- * @param {Record<string, Encoder>} object.encoders
28
- * @param {string[]} [object.attributes]
29
- * @param {number} [object.numVertices] If the number of data items is known, a
30
- * preallocated TypedArray is used
31
- */
32
- constructor({ encoders, numVertices = undefined, attributes = [] }) {
33
- this.encoders = encoders;
34
-
35
- // Encoders for variable channels
36
- this.variableEncoders = Object.fromEntries(
37
- Object.entries(encoders).filter(
38
- ([channel, e]) =>
39
- attributes.includes(channel) && e && e.scale && !e.constant
40
- )
41
- );
42
-
43
- this.allocatedVertices = numVertices;
44
-
45
- this.variableBuilder = new ArrayBuilder(numVertices);
46
-
47
- // Create converters and updaters for all variable channels.
48
- // TODO: If more than one channels use the same field with the same data type, convert the field only once.
49
-
50
- for (const [channel, ce] of Object.entries(this.variableEncoders)) {
51
- const accessor = ce.accessor;
52
-
53
- const doubleArray = [0, 0];
54
- const hp = isHighPrecisionScale(ce.scale.type);
55
-
56
- const indexer = ce.indexer;
57
-
58
- /**
59
- * Discrete variables both numeric and strings must be "indexed",
60
- * 64 bit floats must be converted to vec2.
61
- * 32 bit continuous variables go to GPU as is.
62
- *
63
- * @type {function(any):(number | number[])}
64
- */
65
- const f = indexer
66
- ? (d) => indexer(accessor(d))
67
- : hp
68
- ? (d) => splitHighPrecision(accessor(d), doubleArray)
69
- : accessor;
70
-
71
- this.variableBuilder.addConverter(channel, {
72
- f,
73
- numComponents: hp ? 2 : 1,
74
- arrayReference: hp ? doubleArray : undefined,
75
- });
76
- }
77
-
78
- this.lastOffset = 0;
79
-
80
- /** @type {Map<any, RangeEntry>} keep track of facet locations within the vertex array */
81
- this.rangeMap = new InternMap([], JSON.stringify);
82
- }
83
-
84
- /**
85
- * Must be called at the end of `addBatch`
86
- *
87
- * @param {any} key
88
- */
89
- registerBatch(key) {
90
- const offset = this.lastOffset;
91
- const index = this.variableBuilder.vertexCount;
92
- const size = index - offset;
93
- if (size) {
94
- this.rangeMap.set(key, {
95
- offset,
96
- count: size,
97
- xIndex: this.xIndexer?.getIndex(),
98
- });
99
- }
100
- this.lastOffset = index;
101
- }
102
-
103
- /**
104
- * @param {Map<any, object[]>} batches
105
- */
106
- addBatches(batches) {
107
- for (const [key, data] of batches) {
108
- this.addBatch(key, data);
109
- }
110
- }
111
-
112
- /**
113
- * @param {any} key The facet id, for example
114
- * @param {object[]} data
115
- */
116
- addBatch(key, data, lo = 0, hi = data.length) {
117
- this.prepareXIndexer(data, lo, hi);
118
-
119
- for (let i = lo; i < hi; i++) {
120
- const d = data[i];
121
- this.variableBuilder.pushFromDatum(d);
122
- this.addToXIndex(d);
123
- }
124
-
125
- this.registerBatch(key);
126
- }
127
-
128
- /**
129
- * @param {import("../data/flowNode").Data} data Domain, but specified using datums
130
- * @param {number} [lo]
131
- * @param {number} [hi]
132
- */
133
- prepareXIndexer(data, lo = 0, hi = lo + data.length) {
134
- const disable = () => {
135
- /**
136
- * @param {import("../data/flowNode").Datum} datum
137
- */
138
- this.addToXIndex = (datum) => {
139
- // nop
140
- };
141
- this.xIndexer = undefined;
142
- };
143
-
144
- if (!data.length || hi - lo < 0) {
145
- disable();
146
- return;
147
- }
148
-
149
- /** @param {Encoder} encoder */
150
- const getContinuousEncoder = (encoder) =>
151
- encoder && isContinuous(encoder.scale?.type) && encoder;
152
-
153
- const xe = getContinuousEncoder(this.variableEncoders.x);
154
- const x2e = getContinuousEncoder(this.variableEncoders.x2);
155
-
156
- if (xe) {
157
- const xa = xe.accessor;
158
- const x2a = x2e ? x2e.accessor : xa;
159
-
160
- /** @type {[number, number]} */
161
- const dataDomain = [xa(data[lo]), x2a(data[hi - 1])];
162
-
163
- // No indexer for point domains that have zero extent
164
- if (dataDomain[1] > dataDomain[0]) {
165
- this.xIndexer = createBinningRangeIndexer(
166
- 50,
167
- dataDomain,
168
- xa,
169
- x2a
170
- );
171
-
172
- let lastVertexCount = this.variableBuilder.vertexCount;
173
-
174
- /**
175
- * @param {any} datum
176
- */
177
- this.addToXIndex = (datum) => {
178
- let currentVertexCount = this.variableBuilder.vertexCount;
179
- this.xIndexer(datum, lastVertexCount, currentVertexCount);
180
- lastVertexCount = currentVertexCount;
181
- };
182
- } else {
183
- disable();
184
- }
185
- } else {
186
- disable();
187
- }
188
- }
189
-
190
- /**
191
- * Add the datum to an index, which allows for efficient rendering of ranges
192
- * on the x axis. Must be called after a datum has been pushed to the ArrayBuilder.
193
- *
194
- * @param {import("../data/flowNode").Datum} datum
195
- */
196
- addToXIndex(datum) {
197
- //
198
- }
199
-
200
- toArrays() {
201
- return {
202
- /** @type {Record<string, {data: number[] | Float32Array, numComponents: number, divisor?: number}>} */
203
- arrays: this.variableBuilder.arrays,
204
- /** Number of vertices used */
205
- vertexCount: this.variableBuilder.vertexCount,
206
- /** Number of vertices allocated in buffers */
207
- allocatedVertices: this.allocatedVertices,
208
- rangeMap: this.rangeMap,
209
- };
210
- }
211
- }
212
-
213
- export class RectVertexBuilder extends GeometryBuilder {
214
- /**
215
- *
216
- * @param {Object} object
217
- * @param {Record<string, Encoder>} object.encoders
218
- * @param {string[]} object.attributes
219
- * @param {number} [object.tessellationThreshold]
220
- * If the rect is wider than the threshold, tessellate it into pieces
221
- * @param {number[]} [object.visibleRange]
222
- * @param {number} [object.numItems] Number of data items
223
- */
224
- constructor({
225
- encoders,
226
- attributes,
227
- tessellationThreshold = Infinity,
228
- visibleRange = [-Infinity, Infinity],
229
- numItems,
230
- }) {
231
- super({
232
- encoders,
233
- attributes,
234
- numVertices:
235
- tessellationThreshold == Infinity ? numItems * 6 : undefined,
236
- });
237
-
238
- this.visibleRange = visibleRange;
239
-
240
- this.tessellationThreshold = tessellationThreshold || Infinity;
241
-
242
- this.updateFrac = this.variableBuilder.createUpdater("frac", 2);
243
- }
244
-
245
- /**
246
- *
247
- * @param {any} key
248
- * @param {object[]} data
249
- */
250
- addBatch(key, data, lo = 0, hi = data.length) {
251
- if (hi <= lo) {
252
- return;
253
- }
254
-
255
- const e =
256
- /** @type {Object.<string, import("../encoder/encoder").NumberEncoder>} */ (
257
- this.encoders
258
- );
259
- const [lower, upper] = this.visibleRange;
260
-
261
- /**
262
- * @param {import("../encoder/encoder").Encoder} encoder
263
- */
264
- const a = (encoder) => encoder.accessor || ((x) => 0);
265
-
266
- const xAccessor = a(e.x);
267
- const x2Accessor = a(e.x2);
268
-
269
- this.prepareXIndexer(data, lo, hi);
270
-
271
- const frac = [0, 0];
272
- this.updateFrac(frac);
273
-
274
- for (let i = lo; i < hi; i++) {
275
- const d = data[i];
276
-
277
- let x = xAccessor(d),
278
- x2 = x2Accessor(d);
279
-
280
- if (x > x2) {
281
- [x, x2] = [x2, x];
282
- }
283
-
284
- // Skip rects that fall outside the visible range. TODO: Optimize by using binary search / interval tree
285
- if (x2 < lower || x > upper) {
286
- continue;
287
- }
288
-
289
- // Truncate to prevent tessellation of parts that are outside the viewport
290
- if (x < lower) x = lower;
291
- if (x2 > upper) x2 = upper;
292
-
293
- // Start a new segment.
294
- this.variableBuilder.updateFromDatum(d);
295
-
296
- frac[0] = 0;
297
- frac[1] = 0;
298
-
299
- // Tessellate segments
300
- const tileCount = 1;
301
- // width < Infinity
302
- // ? Math.ceil(width / this.tessellationThreshold)
303
- // : 1;
304
-
305
- // Duplicate the first vertex to produce degenerate triangles
306
- this.variableBuilder.pushAll();
307
-
308
- for (let i = 0; i <= tileCount; i++) {
309
- frac[0] = i / tileCount;
310
- frac[1] = 0;
311
- this.variableBuilder.pushAll();
312
- frac[1] = 1;
313
- this.variableBuilder.pushAll();
314
- }
315
-
316
- // Duplicate the last vertex to produce a degenerate triangle between the segments
317
- this.variableBuilder.pushAll();
318
- this.addToXIndex(d);
319
- }
320
-
321
- this.registerBatch(key);
322
- }
323
- }
324
-
325
- export class RuleVertexBuilder extends GeometryBuilder {
326
- /**
327
- *
328
- * @param {Object} object
329
- * @param {Record<string, Encoder>} object.encoders
330
- * @param {string[]} object.attributes
331
- * @param {number} [object.tessellationThreshold]
332
- * If the rule is wider than the threshold, tessellate it into pieces
333
- * @param {number[]} [object.visibleRange]
334
- * @param {number} [object.numItems] Number of data items
335
- */
336
- constructor({
337
- encoders,
338
- attributes,
339
- tessellationThreshold = Infinity,
340
- visibleRange = [-Infinity, Infinity],
341
- numItems,
342
- }) {
343
- super({
344
- encoders,
345
- attributes,
346
- numVertices:
347
- tessellationThreshold == Infinity ? numItems * 6 : undefined,
348
- });
349
-
350
- this.visibleRange = visibleRange;
351
-
352
- this.tessellationThreshold = tessellationThreshold || Infinity;
353
-
354
- this.updateSide = this.variableBuilder.createUpdater("side", 1);
355
- this.updatePos = this.variableBuilder.createUpdater("pos", 1);
356
- }
357
-
358
- /* eslint-disable complexity */
359
- /**
360
- *
361
- * @param {any} key
362
- * @param {object[]} data
363
- */
364
- addBatch(key, data, lo = 0, hi = data.length) {
365
- //const [lower, upper] = this.visibleRange; // TODO
366
-
367
- this.prepareXIndexer(data, lo, hi);
368
-
369
- for (let i = lo; i < hi; i++) {
370
- const d = data[i];
371
-
372
- // Start a new rule. Duplicate the first vertex to produce degenerate triangles
373
- this.variableBuilder.updateFromDatum(d);
374
- this.updateSide(-0.5);
375
- this.updatePos(0);
376
- this.variableBuilder.pushAll();
377
-
378
- // Tesselate segments
379
- const tileCount = 1;
380
- // width < Infinity
381
- // ? Math.ceil(width / this.tessellationThreshold)
382
- // : 1;
383
- for (let i = 0; i <= tileCount; i++) {
384
- this.updatePos(i / tileCount);
385
- this.updateSide(-0.5);
386
- this.variableBuilder.pushAll();
387
- this.updateSide(0.5);
388
- this.variableBuilder.pushAll();
389
- }
390
-
391
- // Duplicate the last vertex to produce a degenerate triangle between the rules
392
- this.variableBuilder.pushAll();
393
- this.addToXIndex(d);
394
- }
395
-
396
- this.registerBatch(key);
397
- }
398
- }
399
-
400
- export class PointVertexBuilder extends GeometryBuilder {
401
- /**
402
- *
403
- * @param {object} object
404
- * @param {Record<string, Encoder>} object.encoders
405
- * @param {string[]} object.attributes
406
- * @param {number} [object.numItems] Number of points if known, uses TypedArray
407
- */
408
- constructor({ encoders, attributes, numItems = undefined }) {
409
- super({
410
- encoders,
411
- attributes,
412
- numVertices: numItems,
413
- });
414
- }
415
- }
416
-
417
- export class ConnectionVertexBuilder extends GeometryBuilder {
418
- /**
419
- * @param {object} object
420
- * @param {Record<string, Encoder>} object.encoders
421
- * @param {string[]} object.attributes
422
- * @param {number} [object.numItems ] Number of points if known, uses TypedArray
423
- */
424
- constructor({ encoders, attributes, numItems = undefined }) {
425
- super({
426
- encoders,
427
- attributes,
428
- numVertices: numItems,
429
- });
430
- }
431
-
432
- toArrays() {
433
- const arrays = this.variableBuilder.arrays;
434
-
435
- // Prepare for instanced rendering
436
- for (let a of Object.values(arrays)) {
437
- a.divisor = 1;
438
- }
439
-
440
- return super.toArrays();
441
- }
442
- }
443
-
444
- export class TextVertexBuilder extends GeometryBuilder {
445
- /**
446
- *
447
- * @param {object} object
448
- * @param {Record<string, Encoder>} object.encoders
449
- * @param {string[]} object.attributes
450
- * @param {import("../fonts/bmFontMetrics").BMFontMetrics} object.fontMetrics
451
- * @param {Record<string, any>} object.properties
452
- * @param {number} [object.numCharacters] number of characters
453
- * @param {boolean} [object.logoLetters]
454
- */
455
- constructor({
456
- encoders,
457
- attributes,
458
- fontMetrics,
459
- properties,
460
- numCharacters = undefined,
461
- }) {
462
- super({
463
- encoders,
464
- attributes,
465
- numVertices: numCharacters * 6, // six vertices per quad (character)
466
- });
467
-
468
- this.metadata = fontMetrics;
469
- this.metrics = fontMetrics;
470
-
471
- this.properties = properties;
472
-
473
- const e = encoders;
474
-
475
- const channelDef =
476
- /** @type {import("../spec/channel").TextDef<string>} */ (
477
- e.text.channelDef
478
- );
479
- /** @type {(value: any) => string} */
480
- this.numberFormat =
481
- !isValueDef(channelDef) && channelDef.format
482
- ? format(channelDef.format)
483
- : (d) => d;
484
-
485
- this.updateVertexCoord = this.variableBuilder.createUpdater(
486
- "vertexCoord",
487
- 2
488
- );
489
- this.updateTextureCoord = this.variableBuilder.createUpdater(
490
- "textureCoord",
491
- 2
492
- );
493
-
494
- this.updateWidth = this.variableBuilder.createUpdater("width", 1);
495
- }
496
-
497
- /**
498
- *
499
- * @param {any} key
500
- * @param {object[]} data
501
- */
502
- addBatch(key, data, lo = 0, hi = data.length) {
503
- const align = this.properties.align || "left";
504
- const logoLetters = this.properties.logoLetters ?? false;
505
-
506
- const base = this.metadata.common.base;
507
- const scale = this.metadata.common.scaleH; // Assume square textures
508
-
509
- let baseline = -SDF_PADDING;
510
- switch (this.properties.baseline) {
511
- case "top":
512
- baseline += this.metrics.capHeight;
513
- break;
514
- case "middle":
515
- baseline += this.metrics.capHeight / 2;
516
- break;
517
- case "bottom":
518
- baseline -= this.metrics.descent;
519
- break;
520
- default:
521
- // alphabetic
522
- }
523
-
524
- const accessor = this.encoders.text.accessor || this.encoders.text; // accessor or constant value
525
-
526
- const vertexCoord = [0, 0];
527
- this.updateVertexCoord(vertexCoord);
528
- const textureCoord = [0, 0];
529
- this.updateTextureCoord(textureCoord);
530
-
531
- this.prepareXIndexer(data, lo, hi);
532
-
533
- for (let i = lo; i < hi; i++) {
534
- const d = data[i];
535
-
536
- const value = this.numberFormat(accessor(d));
537
- const str = isString(value)
538
- ? value
539
- : value === null
540
- ? ""
541
- : "" + value;
542
- if (str.length == 0) continue;
543
-
544
- this.variableBuilder.updateFromDatum(d);
545
-
546
- const textWidth = logoLetters
547
- ? str.length
548
- : this.metrics.measureWidth(str);
549
-
550
- this.updateWidth(textWidth); // TODO: Check if one letter space should be reduced
551
-
552
- let x =
553
- align == "right"
554
- ? -textWidth
555
- : align == "center"
556
- ? -textWidth / 2
557
- : 0;
558
-
559
- if (!logoLetters) {
560
- const firstChar = this.metrics.getCharByCode(str.charCodeAt(0));
561
- x -= (firstChar.width - firstChar.xadvance) / base / 2; // TODO: Fix, this is a bit off..
562
- }
563
-
564
- let bottom = -0.5,
565
- height = 1,
566
- normalWidth = 1;
567
-
568
- for (let i = 0; i < str.length; i++) {
569
- const c = this.metrics.getCharByCode(str.charCodeAt(i));
570
-
571
- const advance = logoLetters ? 1 : c.xadvance / base;
572
-
573
- if (c.id == 32) {
574
- x += advance;
575
- continue;
576
- }
577
-
578
- if (!logoLetters) {
579
- height = c.height / base;
580
- bottom = -(c.height + c.yoffset + baseline) / base;
581
- normalWidth = c.width / base;
582
- } else {
583
- normalWidth = (c.width + SDF_PADDING * 2) / c.width;
584
- x = -normalWidth / 2;
585
- height = (c.height + SDF_PADDING * 2) / c.height;
586
- bottom = -0.5 - SDF_PADDING / c.height;
587
- }
588
-
589
- const tx = c.x;
590
- const ty = c.y;
591
-
592
- vertexCoord[0] = x;
593
- vertexCoord[1] = bottom + height;
594
- textureCoord[0] = tx / scale;
595
- textureCoord[1] = ty / scale;
596
- this.variableBuilder.pushAll();
597
-
598
- vertexCoord[0] = x + normalWidth;
599
- vertexCoord[1] = bottom + height;
600
- textureCoord[0] = (tx + c.width) / scale;
601
- textureCoord[1] = ty / scale;
602
- this.variableBuilder.pushAll();
603
-
604
- vertexCoord[0] = x;
605
- vertexCoord[1] = bottom;
606
- textureCoord[0] = tx / scale;
607
- textureCoord[1] = (ty + c.height) / scale;
608
- this.variableBuilder.pushAll();
609
-
610
- vertexCoord[0] = x + normalWidth;
611
- vertexCoord[1] = bottom + height;
612
- textureCoord[0] = (tx + c.width) / scale;
613
- textureCoord[1] = ty / scale;
614
- this.variableBuilder.pushAll();
615
-
616
- vertexCoord[0] = x;
617
- vertexCoord[1] = bottom;
618
- textureCoord[0] = tx / scale;
619
- textureCoord[1] = (ty + c.height) / scale;
620
- this.variableBuilder.pushAll();
621
-
622
- vertexCoord[0] = x + normalWidth;
623
- vertexCoord[1] = bottom;
624
- textureCoord[0] = (tx + c.width) / scale;
625
- textureCoord[1] = (ty + c.height) / scale;
626
- this.variableBuilder.pushAll();
627
-
628
- x += advance;
629
- }
630
-
631
- this.addToXIndex(d);
632
- }
633
-
634
- this.registerBatch(key);
635
- }
636
- }
@@ -1,63 +0,0 @@
1
- #define PI 3.141593
2
-
3
- uniform View {
4
- /** Offset in "unit" units */
5
- mediump vec2 uViewOffset;
6
- mediump vec2 uViewScale;
7
- /** Size of the logical viewport in pixels, i.e., the view */
8
- mediump vec2 uViewportSize;
9
- lowp float uDevicePixelRatio;
10
- // TODO: Views with opacity less than 1.0 should be rendered into a texture
11
- // that is rendered with the specified opacity.
12
- lowp float uViewOpacity;
13
- bool uPickingEnabled;
14
- };
15
-
16
-
17
- /**
18
- * Maps a coordinate on the unit scale to a normalized device coordinate.
19
- * (0, 0) is at the bottom left corner.
20
- */
21
- vec4 unitToNdc(vec2 coord) {
22
- return vec4((coord * uViewScale + uViewOffset) * 2.0 - 1.0, 0.0, 1.0);
23
- }
24
-
25
- vec4 unitToNdc(float x, float y) {
26
- return unitToNdc(vec2(x, y));
27
- }
28
-
29
- vec4 pixelsToNdc(vec2 coord) {
30
- return unitToNdc(coord / uViewportSize);
31
- }
32
-
33
- vec4 pixelsToNdc(float x, float y) {
34
- return pixelsToNdc(vec2(x, y));
35
- }
36
-
37
- float linearstep(float edge0, float edge1, float x) {
38
- return clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
39
- }
40
-
41
- // Fragment shader stuff ////////////////////////////////////////////////////////
42
-
43
- // TODO: include the following only in fragment shaders
44
-
45
- /**
46
- * Specialized linearstep for doing antialiasing
47
- */
48
- float distanceToRatio(float d) {
49
- return clamp(d * uDevicePixelRatio + 0.5, 0.0, 1.0);
50
- }
51
-
52
- vec4 distanceToColor(float d, vec4 fill, vec4 stroke, float halfStrokeWidth) {
53
- if (halfStrokeWidth > 0.0) {
54
- // Distance to stroke's edge. Negative inside the stroke.
55
- float sd = abs(d) - halfStrokeWidth;
56
- return mix(
57
- stroke,
58
- d <= 0.0 ? fill : vec4(0.0),
59
- distanceToRatio(sd));
60
- } else {
61
- return fill * distanceToRatio(-d);
62
- }
63
- }
@@ -1 +0,0 @@
1
- in highp vec4 vPickingColor;