@genome-spy/core 0.42.0 → 0.42.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.
- package/dist/bundle/index.es.js +2575 -2567
- package/dist/bundle/index.js +75 -74
- package/dist/src/encoder/encoder.d.ts +6 -1
- package/dist/src/encoder/encoder.d.ts.map +1 -1
- package/dist/src/encoder/encoder.js +10 -0
- package/dist/src/gl/arrayBuilder.js +1 -1
- package/dist/src/gl/colorUtils.d.ts.map +1 -0
- package/dist/src/{scale → gl}/colorUtils.js +1 -1
- package/dist/src/gl/dataToVertices.d.ts +1 -9
- package/dist/src/gl/dataToVertices.d.ts.map +1 -1
- package/dist/src/gl/dataToVertices.js +33 -73
- package/dist/src/{scale → gl}/glslScaleGenerator.d.ts +23 -1
- package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -0
- package/dist/src/{scale → gl}/glslScaleGenerator.js +61 -8
- package/dist/src/gl/webGLHelper.js +1 -1
- package/dist/src/marks/link.js +2 -2
- package/dist/src/marks/mark.d.ts +2 -1
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +30 -2
- package/dist/src/marks/{pointMark.d.ts → point.d.ts} +1 -1
- package/dist/src/marks/point.d.ts.map +1 -0
- package/dist/src/marks/{pointMark.js → point.js} +3 -3
- package/dist/src/marks/{rectMark.d.ts → rect.d.ts} +1 -1
- package/dist/src/marks/rect.d.ts.map +1 -0
- package/dist/src/marks/{rectMark.js → rect.js} +2 -3
- package/dist/src/marks/rect.vertex.glsl.js +2 -0
- package/dist/src/marks/rule.js +3 -3
- package/dist/src/marks/text.js +3 -3
- package/dist/src/utils/indexer.d.ts.map +1 -1
- package/dist/src/utils/indexer.js +10 -1
- package/dist/src/utils/indexer.test.js +2 -0
- package/dist/src/view/unitView.d.ts +1 -1
- package/dist/src/view/unitView.js +2 -2
- package/dist/src/view/view.test.js +1 -1
- package/package.json +2 -2
- package/dist/src/gl/rect.vertex.glsl.js +0 -2
- package/dist/src/marks/pointMark.d.ts.map +0 -1
- package/dist/src/marks/rectMark.d.ts.map +0 -1
- package/dist/src/scale/colorUtils.d.ts.map +0 -1
- package/dist/src/scale/glslScaleGenerator.d.ts.map +0 -1
- /package/dist/src/{scale → gl}/colorUtils.d.ts +0 -0
- /package/dist/src/{gl → marks}/link.fragment.glsl.js +0 -0
- /package/dist/src/{gl → marks}/link.vertex.glsl.js +0 -0
- /package/dist/src/{gl → marks}/point.common.glsl.js +0 -0
- /package/dist/src/{gl → marks}/point.fragment.glsl.js +0 -0
- /package/dist/src/{gl → marks}/point.vertex.glsl.js +0 -0
- /package/dist/src/{gl → marks}/rect.fragment.glsl.js +0 -0
- /package/dist/src/{gl → marks}/rule.common.glsl.js +0 -0
- /package/dist/src/{gl → marks}/rule.fragment.glsl.js +0 -0
- /package/dist/src/{gl → marks}/rule.vertex.glsl.js +0 -0
- /package/dist/src/{gl → marks}/text.common.glsl.js +0 -0
- /package/dist/src/{gl → marks}/text.fragment.glsl.js +0 -0
- /package/dist/src/{gl → marks}/text.vertex.glsl.js +0 -0
|
@@ -45,7 +45,12 @@ export function isChannelDefWithScale(channelDef: import("../spec/channel.js").C
|
|
|
45
45
|
* @param {import("../view/unitView.js").default} view
|
|
46
46
|
* @param {import("../spec/channel.js").Channel} channel
|
|
47
47
|
*/
|
|
48
|
-
export function getChannelDefWithScale(view: import("../view/unitView.js").default, channel: import("../spec/channel.js").Channel): import("../spec/channel.js").
|
|
48
|
+
export function getChannelDefWithScale(view: import("../view/unitView.js").default, channel: import("../spec/channel.js").Channel): import("../spec/channel.js").MarkPropExprDef<import("../spec/channel.js").Type> | import("../spec/channel.js").MarkPropDatumDef<import("../spec/channel.js").Type> | import("../spec/channel.js").ChromPosDef | import("../spec/channel.js").PositionDatumDef | import("../spec/channel.js").MarkPropDatumDef<import("../spec/channel.js").TypeForShape> | import("../spec/channel.js").MarkPropFieldDef<string, import("../spec/channel.js").Type> | import("../spec/channel.js").PositionFieldDef<string> | import("../spec/channel.js").MarkPropFieldDef<string, import("../spec/channel.js").TypeForShape>;
|
|
49
|
+
/**
|
|
50
|
+
* @param {import("../spec/channel.js").ChannelDef} channelDef
|
|
51
|
+
* @returns {channelDef is import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>}
|
|
52
|
+
*/
|
|
53
|
+
export function isChannelDefWithType(channelDef: import("../spec/channel.js").ChannelDef): channelDef is import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>;
|
|
49
54
|
/**
|
|
50
55
|
* @param {import("../spec/channel.js").ChannelDef} channelDef
|
|
51
56
|
* @returns {channelDef is import("../spec/channel.js").ChromPosDef}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/encoder/encoder.js"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,6CAJW,OAAO,kBAAkB,EAAE,OAAO,aAClC,OAAO,oBAAoB,EAAE,QAAQ,gGAsC/C;AAED;;;;;;;GAOG;AACH,0CANW,OAAO,oBAAoB,EAAE,UAAU,SACvC,GAAG,
|
|
1
|
+
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../src/encoder/encoder.js"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,6CAJW,OAAO,kBAAkB,EAAE,OAAO,aAClC,OAAO,oBAAoB,EAAE,QAAQ,gGAsC/C;AAED;;;;;;;GAOG;AACH,0CANW,OAAO,oBAAoB,EAAE,UAAU,SACvC,GAAG,0IA2Fb;AAED;;;;;GAKG;AACH,uCAHW,OAAO,oBAAoB,EAAE,UAAU,4FAKjD;AAED;;;GAGG;AACH,uCAHW,OAAO,oBAAoB,EAAE,UAAU,mEAKjD;AAED;;;GAGG;AACH,uCAHW,OAAO,oBAAoB,EAAE,UAAU,uDAKjD;AAED;;;GAGG;AACH,kDAHW,OAAO,oBAAoB,EAAE,UAAU,kEAWjD;AAED;;;GAGG;AACH,6CAHW,OAAO,qBAAqB,EAAE,OAAO,WACrC,OAAO,oBAAoB,EAAE,OAAO,klBAS9C;AAED;;;GAGG;AACH,iDAHW,OAAO,oBAAoB,EAAE,UAAU,4FAKjD;AAED;;;GAGG;AACH,0CAHW,OAAO,oBAAoB,EAAE,UAAU,0DAKjD;AAED;;;GAGG;AACH,sCAHW,OAAO,oBAAoB,EAAE,UAAU,sDAKjD;AAoBD;;;GAGG;AACH,oDAHW,OAAO,oBAAoB,EAAE,OAAO,oEAM9C;AAED;;;GAGG;AACH,6CAHW,OAAO,oBAAoB,EAAE,OAAO,6DAM9C;AAqBD;;;GAGG;AACH,4CAFW,MAAM,WAIhB;AAED;;;;GAIG;AACH,oDAFW,OAAO,oBAAoB,EAAE,OAAO,2DAS9C;AAED;;;;;GAKG;AACH,2CAFW,OAAO,oBAAoB,EAAE,OAAO,wCAI9C;AAED;;;;GAIG;AACH,kDAFW,OAAO,oBAAoB,EAAE,OAAO,0CAM9C;AAED;;GAEG;AACH,wCAFW,OAAO,oBAAoB,EAAE,OAAO,WAI9C;AAED;;;;GAIG;AACH,2CAFW,OAAO,oBAAoB,EAAE,OAAO,WAI9C;AAED;;;GAGG;AACH,4CAHW,OAAO,oBAAoB,EAAE,OAAO,4DAuB9C;AAED;;;;;GAKG;AACH,0CAHW,OAAO,oBAAoB,EAAE,OAAO,GAClC,GAAG,EAAE,CAsBjB;AAED;;;GAGG;AACH,gDAHW,OAAO,oBAAoB,EAAE,OAAO,UACzB,GAAG,KAAE,MAAM,CAmBhC;AA7LD;;GAEG;AACH,wCAFU,OAAO,oBAAoB,EAAE,wBAAwB,EAAE,CAEb;AAEpD;;GAEG;AACH,0CAFU,OAAO,oBAAoB,EAAE,0BAA0B,EAAE,CAEX;AAExD;;GAEG;AACH,iCAFU,OAAO,oBAAoB,EAAE,iBAAiB,EAAE,CAKxD;AAoBF;;;;GAIG;AACH,gCAFU,QAAQ,OAAO,OAAO,oBAAoB,EAAE,OAAO,EAAE,OAAO,oBAAoB,EAAE,0BAA0B,CAAC,CAAC,CAKtH;AAEF;;;;GAIG;AACH,8BAFU,QAAQ,OAAO,OAAO,oBAAoB,EAAE,OAAO,EAAE,OAAO,oBAAoB,EAAE,OAAO,CAAC,CAAC,CAInG"}
|
|
@@ -101,6 +101,8 @@ export function createEncoder(channelDef, scale, accessor, channel) {
|
|
|
101
101
|
if (isDiscrete(scale.type)) {
|
|
102
102
|
// TODO: pass the found values back to the scale/resolution
|
|
103
103
|
const indexer = createIndexer();
|
|
104
|
+
// Warning: There's a chance that the domain and indexer get out of sync.
|
|
105
|
+
// TODO: Make this more robust
|
|
104
106
|
indexer.addAll(scale.domain());
|
|
105
107
|
encoder.indexer = indexer;
|
|
106
108
|
}
|
|
@@ -197,6 +199,14 @@ export function getChannelDefWithScale(view, channel) {
|
|
|
197
199
|
}
|
|
198
200
|
}
|
|
199
201
|
|
|
202
|
+
/**
|
|
203
|
+
* @param {import("../spec/channel.js").ChannelDef} channelDef
|
|
204
|
+
* @returns {channelDef is import("../spec/channel.js").TypeMixins<import("../spec/channel.js").Type>}
|
|
205
|
+
*/
|
|
206
|
+
export function isChannelDefWithType(channelDef) {
|
|
207
|
+
return channelDef && "type" in channelDef;
|
|
208
|
+
}
|
|
209
|
+
|
|
200
210
|
/**
|
|
201
211
|
* @param {import("../spec/channel.js").ChannelDef} channelDef
|
|
202
212
|
* @returns {channelDef is import("../spec/channel.js").ChromPosDef}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorUtils.d.ts","sourceRoot":"","sources":["../../../src/gl/colorUtils.js"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,kDALW,MAAM,GAAG,OAAO,kBAAkB,EAAE,YAAY,MAChD,sBAAsB,UACtB,MAAM,oBACN,YAAY,gBAqCtB;AAED;;;;;GAKG;AACH,uDALW,MAAM,EAAE,qBACR,OAAO,kBAAkB,EAAE,gBAAgB,GAAG,OAAO,kBAAkB,EAAE,sBAAsB,MAC/F,sBAAsB,oBACtB,YAAY,gBA6BtB;AAED;;;;;;;;GAQG;AACH,6CALW,MAAM,EAAE,MACR,sBAAsB,UACtB,MAAM,oBACN,YAAY,gBAqBtB;AAED;;;;;;;GAOG;AACH,mDALW,MAAM,EAAE,MACR,sBAAsB,UACtB,MAAM,oBACN,YAAY,gBActB"}
|
|
@@ -3,7 +3,7 @@ import { range } from "d3-array";
|
|
|
3
3
|
import { scheme as vegaScheme, interpolateColors } from "vega-scale";
|
|
4
4
|
import { isString, isArray, isFunction } from "vega-util";
|
|
5
5
|
import { peek } from "../utils/arrayUtils.js";
|
|
6
|
-
import { createOrUpdateTexture } from "
|
|
6
|
+
import { createOrUpdateTexture } from "./webGLHelper.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @param {string | import("../spec/scale.js").SchemeParams} schemeParams
|
|
@@ -82,21 +82,13 @@ export class RectVertexBuilder extends GeometryBuilder {
|
|
|
82
82
|
* @param {Object} object
|
|
83
83
|
* @param {Record<string, Encoder>} object.encoders
|
|
84
84
|
* @param {string[]} object.attributes
|
|
85
|
-
* @param {number} [object.tessellationThreshold]
|
|
86
|
-
* If the rect is wider than the threshold, tessellate it into pieces
|
|
87
|
-
* @param {number[]} [object.visibleRange]
|
|
88
85
|
* @param {number} [object.numItems] Number of data items
|
|
89
86
|
*/
|
|
90
|
-
constructor({ encoders, attributes,
|
|
87
|
+
constructor({ encoders, attributes, numItems }: {
|
|
91
88
|
encoders: Record<string, import("../types/encoder.js").Encoder>;
|
|
92
89
|
attributes: string[];
|
|
93
|
-
tessellationThreshold?: number;
|
|
94
|
-
visibleRange?: number[];
|
|
95
90
|
numItems?: number;
|
|
96
91
|
});
|
|
97
|
-
visibleRange: number[];
|
|
98
|
-
tessellationThreshold: number;
|
|
99
|
-
updateFrac: (arg0: number | number[]) => any;
|
|
100
92
|
}
|
|
101
93
|
export class RuleVertexBuilder extends GeometryBuilder {
|
|
102
94
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dataToVertices.d.ts","sourceRoot":"","sources":["../../../src/gl/dataToVertices.js"],"names":[],"mappings":"AAeA;;;;;GAKG;AACH;IACI;;;OAGG;IAEH;;;;;;OAMG;IACH;;qBAJW,MAAM,EAAE;sBACR,MAAM;OAyEhB;IArEG,gEAAwB;IAGxB;;MAKC;IAQD,0BAAoC;IAEpC,8BAAoD;IA+CpD,mBAAmB;IAEnB,yFAAyF;IACzF,UADW,IAAI,GAAG,EAAE,UAAU,CAAC,CACkB;IAGrD;;;;OAIG;IACH,mBAFW,GAAG,QAcb;IAED;;OAEG;IACH,oBAFW,IAAI,GAAG,EAAE,MAAM,EAAE,CAAC,QAM5B;IAED;;;OAGG;IACH,cAHW,GAAG,QACH,MAAM,EAAE,kCAYlB;IAED;;;;OAIG;IACH,sBAJW,OAAO,qBAAqB,EAAE,IAAI,OAClC,MAAM,OACN,MAAM,QAyDhB;IAED;;;;;OAKG;IACH,mBAFW,OAAO,qBAAqB,EAAE,KAAK,QAI7C;IAzDO;;;MAAyB;IA2DjC;QAEQ,uGAAuG;gBAA5F,OAAO,MAAM,EAAE;YAAC,IAAI,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC;YAAC,aAAa,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAC,CAAC;QAEnG,8BAA8B;;QAE9B,8CAA8C;;;MAIrD;CACJ;AAED;IACI;;;;;;OAMG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAQhB;CAkCJ;AAED;IACI;;;;;;;;;OASG;IACH;;oBANW,MAAM,EAAE;gCACR,MAAM;uBAEN,MAAM,EAAE;mBACR,MAAM;OAsBhB;IANG,uBAAgC;IAEhC,8BAA8D;IAE9D,6CAA+D;IAC/D,4CAA6D;CA2CpE;AAED;IACI;;;;;;OAMG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAQhB;CACJ;AAED;IACI;;;;;OAKG;IACH;;oBAHW,MAAM,EAAE;mBACR,MAAM;OAQhB;CAYJ;AAED;IACI;;;;;;;;;OASG;IACH;;oBANW,MAAM,EAAE;qBACR,OAAO,2BAA2B,EAAE,aAAa;oBACjD,OAAO,MAAM,EAAE,GAAG,CAAC;wBACnB,MAAM;sBACN,OAAO;OA4CjB;IA7BG,4DAA2B;IAC3B,2DAA0B;IAE1B,gCAA4B;IAQ5B,qCAAqC;IACrC,sBADmB,GAAG,KAAK,MAAM,CAMf;IAElB,oDAGC;IACD,qDAGC;IAED,8CAAiE;CA8IxE;;;;;;;;YArkBS,MAAM;;;;WACN,MAAM;YACN,OAAO,yBAAyB,EAAE,MAAM;;yBAhBzB,mBAAmB"}
|
|
@@ -6,9 +6,11 @@ import { SDF_PADDING } from "../fonts/bmFontMetrics.js";
|
|
|
6
6
|
import { createBinningRangeIndexer } from "../utils/binnedIndex.js";
|
|
7
7
|
import { isValueDef } from "../encoder/encoder.js";
|
|
8
8
|
import {
|
|
9
|
+
dedupeEncodingFields,
|
|
9
10
|
isHighPrecisionScale,
|
|
11
|
+
makeAttributeName,
|
|
10
12
|
splitHighPrecision,
|
|
11
|
-
} from "
|
|
13
|
+
} from "./glslScaleGenerator.js";
|
|
12
14
|
import { isContinuous } from "vega-scale";
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -41,6 +43,12 @@ export class GeometryBuilder {
|
|
|
41
43
|
)
|
|
42
44
|
);
|
|
43
45
|
|
|
46
|
+
const dedupedEncodingFields = [
|
|
47
|
+
...dedupeEncodingFields(encoders).entries(),
|
|
48
|
+
]
|
|
49
|
+
.filter(([key, channels]) => key[1] && channels.length > 1)
|
|
50
|
+
.map(([_key, channels]) => channels);
|
|
51
|
+
|
|
44
52
|
this.allocatedVertices = numVertices;
|
|
45
53
|
|
|
46
54
|
this.variableBuilder = new ArrayBuilder(numVertices);
|
|
@@ -49,6 +57,16 @@ export class GeometryBuilder {
|
|
|
49
57
|
// TODO: If more than one channels use the same field with the same data type, convert the field only once.
|
|
50
58
|
|
|
51
59
|
for (const [channel, ce] of Object.entries(this.variableEncoders)) {
|
|
60
|
+
// Only add the first of the shared channels as all the rest are same
|
|
61
|
+
// For example, if both x and x2 are using the same field, only x is
|
|
62
|
+
// added to the array builder with the name "x_x2".
|
|
63
|
+
const sharedChannels = dedupedEncodingFields.find((channels) =>
|
|
64
|
+
channels.find((c) => c == channel)
|
|
65
|
+
);
|
|
66
|
+
if (sharedChannels && channel != sharedChannels[0]) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
52
70
|
const accessor = ce.accessor;
|
|
53
71
|
|
|
54
72
|
const doubleArray = [0, 0];
|
|
@@ -69,7 +87,11 @@ export class GeometryBuilder {
|
|
|
69
87
|
? (d) => splitHighPrecision(accessor(d), doubleArray)
|
|
70
88
|
: accessor;
|
|
71
89
|
|
|
72
|
-
|
|
90
|
+
const attributeName = sharedChannels
|
|
91
|
+
? makeAttributeName(sharedChannels)
|
|
92
|
+
: channel;
|
|
93
|
+
|
|
94
|
+
this.variableBuilder.addConverter(attributeName, {
|
|
73
95
|
f,
|
|
74
96
|
numComponents: hp ? 2 : 1,
|
|
75
97
|
arrayReference: hp ? doubleArray : undefined,
|
|
@@ -217,30 +239,14 @@ export class RectVertexBuilder extends GeometryBuilder {
|
|
|
217
239
|
* @param {Object} object
|
|
218
240
|
* @param {Record<string, Encoder>} object.encoders
|
|
219
241
|
* @param {string[]} object.attributes
|
|
220
|
-
* @param {number} [object.tessellationThreshold]
|
|
221
|
-
* If the rect is wider than the threshold, tessellate it into pieces
|
|
222
|
-
* @param {number[]} [object.visibleRange]
|
|
223
242
|
* @param {number} [object.numItems] Number of data items
|
|
224
243
|
*/
|
|
225
|
-
constructor({
|
|
226
|
-
encoders,
|
|
227
|
-
attributes,
|
|
228
|
-
tessellationThreshold = Infinity,
|
|
229
|
-
visibleRange = [-Infinity, Infinity],
|
|
230
|
-
numItems,
|
|
231
|
-
}) {
|
|
244
|
+
constructor({ encoders, attributes, numItems }) {
|
|
232
245
|
super({
|
|
233
246
|
encoders,
|
|
234
247
|
attributes,
|
|
235
|
-
numVertices:
|
|
236
|
-
tessellationThreshold == Infinity ? numItems * 6 : undefined,
|
|
248
|
+
numVertices: numItems * 6,
|
|
237
249
|
});
|
|
238
|
-
|
|
239
|
-
this.visibleRange = visibleRange;
|
|
240
|
-
|
|
241
|
-
this.tessellationThreshold = tessellationThreshold || Infinity;
|
|
242
|
-
|
|
243
|
-
this.updateFrac = this.variableBuilder.createUpdater("frac", 2);
|
|
244
250
|
}
|
|
245
251
|
|
|
246
252
|
/**
|
|
@@ -253,69 +259,23 @@ export class RectVertexBuilder extends GeometryBuilder {
|
|
|
253
259
|
return;
|
|
254
260
|
}
|
|
255
261
|
|
|
256
|
-
const e =
|
|
257
|
-
/** @type {Object.<string, import("../types/encoder.js").NumberEncoder>} */ (
|
|
258
|
-
this.encoders
|
|
259
|
-
);
|
|
260
|
-
const [lower, upper] = this.visibleRange;
|
|
261
|
-
|
|
262
|
-
/**
|
|
263
|
-
* @param {import("../types/encoder.js").Encoder} encoder
|
|
264
|
-
*/
|
|
265
|
-
const a = (encoder) => encoder.accessor || ((x) => 0);
|
|
266
|
-
|
|
267
|
-
const xAccessor = a(e.x);
|
|
268
|
-
const x2Accessor = a(e.x2);
|
|
269
|
-
|
|
270
262
|
this.prepareXIndexer(data, lo, hi);
|
|
271
263
|
|
|
272
|
-
const frac = [0, 0];
|
|
273
|
-
this.updateFrac(frac);
|
|
274
|
-
|
|
275
264
|
for (let i = lo; i < hi; i++) {
|
|
276
265
|
const d = data[i];
|
|
277
266
|
|
|
278
|
-
let x = xAccessor(d),
|
|
279
|
-
x2 = x2Accessor(d);
|
|
280
|
-
|
|
281
|
-
if (x > x2) {
|
|
282
|
-
[x, x2] = [x2, x];
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// Skip rects that fall outside the visible range. TODO: Optimize by using binary search / interval tree
|
|
286
|
-
if (x2 < lower || x > upper) {
|
|
287
|
-
continue;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// Truncate to prevent tessellation of parts that are outside the viewport
|
|
291
|
-
if (x < lower) x = lower;
|
|
292
|
-
if (x2 > upper) x2 = upper;
|
|
293
|
-
|
|
294
267
|
// Start a new segment.
|
|
295
268
|
this.variableBuilder.updateFromDatum(d);
|
|
296
269
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
const tileCount = 1;
|
|
302
|
-
// width < Infinity
|
|
303
|
-
// ? Math.ceil(width / this.tessellationThreshold)
|
|
304
|
-
// : 1;
|
|
305
|
-
|
|
306
|
-
// Duplicate the first vertex to produce degenerate triangles
|
|
270
|
+
// Six vertices per rect. The vertex shader is using gl_VertexID to
|
|
271
|
+
// determine the vertex position within the rect.
|
|
272
|
+
this.variableBuilder.pushAll();
|
|
273
|
+
this.variableBuilder.pushAll();
|
|
307
274
|
this.variableBuilder.pushAll();
|
|
308
|
-
|
|
309
|
-
for (let i = 0; i <= tileCount; i++) {
|
|
310
|
-
frac[0] = i / tileCount;
|
|
311
|
-
frac[1] = 0;
|
|
312
|
-
this.variableBuilder.pushAll();
|
|
313
|
-
frac[1] = 1;
|
|
314
|
-
this.variableBuilder.pushAll();
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Duplicate the last vertex to produce a degenerate triangle between the segments
|
|
318
275
|
this.variableBuilder.pushAll();
|
|
276
|
+
this.variableBuilder.pushAll();
|
|
277
|
+
this.variableBuilder.pushAll();
|
|
278
|
+
|
|
319
279
|
this.addToXIndex(d);
|
|
320
280
|
}
|
|
321
281
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="external-typings/internmap.js" />
|
|
1
2
|
/**
|
|
2
3
|
*
|
|
3
4
|
* @param {Channel} channel
|
|
@@ -9,8 +10,10 @@ export function generateValueGlsl(channel: Channel, value: number | number[] | s
|
|
|
9
10
|
* @param {Channel} channel
|
|
10
11
|
* @param {any} scale TODO: typing
|
|
11
12
|
* @param {import("../spec/channel.js").ChannelDef} channelDef
|
|
13
|
+
* @param {Channel[]} [sharedQuantitativeChannels] Channels that share the same quantitative field
|
|
12
14
|
*/
|
|
13
|
-
export function generateScaleGlsl(channel: Channel, scale: any, channelDef: import("../spec/channel.js").ChannelDef): {
|
|
15
|
+
export function generateScaleGlsl(channel: Channel, scale: any, channelDef: import("../spec/channel.js").ChannelDef, sharedQuantitativeChannels?: Channel[]): {
|
|
16
|
+
attributeGlsl: string;
|
|
14
17
|
glsl: string;
|
|
15
18
|
domainUniform: string;
|
|
16
19
|
};
|
|
@@ -28,6 +31,20 @@ export function splitHighPrecision(x: number, arr?: number[]): number[];
|
|
|
28
31
|
* @param {number[]} domain
|
|
29
32
|
*/
|
|
30
33
|
export function toHighPrecisionDomainUniform(domain: number[]): number[];
|
|
34
|
+
/**
|
|
35
|
+
* @typedef {[string, boolean]} FieldKey Tuple: [channel, isQuantitative]]
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Finds duplicated quantitative fields in the encoding block.
|
|
39
|
+
* They need to be uploaded to the GPU only once.
|
|
40
|
+
*
|
|
41
|
+
* @param {Partial<Record<import("../spec/channel.js").Channel, import("../types/encoder.js").Encoder>>} encoders
|
|
42
|
+
*/
|
|
43
|
+
export function dedupeEncodingFields(encoders: Partial<Record<import("../spec/channel.js").Channel, import("../types/encoder.js").Encoder>>): InternMap<FieldKey, import("../spec/channel.js").Channel[]>;
|
|
44
|
+
/**
|
|
45
|
+
* @param {import("../spec/channel.js").Channel | import("../spec/channel.js").Channel[]} channel
|
|
46
|
+
*/
|
|
47
|
+
export function makeAttributeName(channel: import("../spec/channel.js").Channel | import("../spec/channel.js").Channel[]): string;
|
|
31
48
|
export const ATTRIBUTE_PREFIX: "attr_";
|
|
32
49
|
export const DOMAIN_PREFIX: "uDomain_";
|
|
33
50
|
export const RANGE_PREFIX: "range_";
|
|
@@ -42,4 +59,9 @@ export type VectorizedValue = string & {
|
|
|
42
59
|
type: string;
|
|
43
60
|
numComponents: number;
|
|
44
61
|
};
|
|
62
|
+
/**
|
|
63
|
+
* Tuple: [channel, isQuantitative]]
|
|
64
|
+
*/
|
|
65
|
+
export type FieldKey = [string, boolean];
|
|
66
|
+
import { InternMap } from "internmap";
|
|
45
67
|
//# sourceMappingURL=glslScaleGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":";AAmDA;;;;GAIG;AACH,2CAHW,OAAO,SACP,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,UAsC9C;AAED;;;;;;GAMG;AAEH,2CANW,OAAO,SACP,GAAG,cACH,OAAO,oBAAoB,EAAE,UAAU,+BACvC,OAAO,EAAE;;;;EAmRnB;AA+FD;;;GAGG;AACH,2CAFW,MAAM,WAIhB;AAOD;;;GAGG;AACH,sCAHW,MAAM,QACN,MAAM,EAAE,YAYlB;AAYD;;GAEG;AACH,qDAFW,MAAM,EAAE,YAIlB;AAED;;GAEG;AAEH;;;;;GAKG;AACH,+CAFW,QAAQ,OAAO,OAAO,oBAAoB,EAAE,OAAO,EAAE,OAAO,qBAAqB,EAAE,OAAO,CAAC,CAAC,+DA4BtG;AAED;;GAEG;AACH,2CAFW,OAAO,oBAAoB,EAAE,OAAO,GAAG,OAAO,oBAAoB,EAAE,OAAO,EAAE,UAIvF;AAzhBD,uCAAwC;AACxC,uCAAwC;AACxC,oCAAqC;AACrC,6CAA8C;AAC9C,kDAAmD;AACnD,oDAAqD;sBAMxC,OAAO,oBAAoB,EAAE,OAAO;;;;8BAsXpC,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;;;;uBA8GhD,CAAC,MAAM,EAAE,OAAO,CAAC;0BAjfJ,WAAW"}
|
|
@@ -14,8 +14,10 @@ import {
|
|
|
14
14
|
isDiscreteChannel,
|
|
15
15
|
getPrimaryChannel,
|
|
16
16
|
isValueDef,
|
|
17
|
+
isFieldDef,
|
|
17
18
|
} from "../encoder/encoder.js";
|
|
18
|
-
import { peek } from "../utils/arrayUtils.js";
|
|
19
|
+
import { asArray, peek } from "../utils/arrayUtils.js";
|
|
20
|
+
import { InternMap } from "internmap";
|
|
19
21
|
|
|
20
22
|
export const ATTRIBUTE_PREFIX = "attr_";
|
|
21
23
|
export const DOMAIN_PREFIX = "uDomain_";
|
|
@@ -95,9 +97,15 @@ ${vec.type} ${SCALED_FUNCTION_PREFIX}${channel}() {
|
|
|
95
97
|
* @param {Channel} channel
|
|
96
98
|
* @param {any} scale TODO: typing
|
|
97
99
|
* @param {import("../spec/channel.js").ChannelDef} channelDef
|
|
100
|
+
* @param {Channel[]} [sharedQuantitativeChannels] Channels that share the same quantitative field
|
|
98
101
|
*/
|
|
99
102
|
// eslint-disable-next-line complexity
|
|
100
|
-
export function generateScaleGlsl(
|
|
103
|
+
export function generateScaleGlsl(
|
|
104
|
+
channel,
|
|
105
|
+
scale,
|
|
106
|
+
channelDef,
|
|
107
|
+
sharedQuantitativeChannels = [channel]
|
|
108
|
+
) {
|
|
101
109
|
if (isValueDef(channelDef)) {
|
|
102
110
|
throw new Error(
|
|
103
111
|
`Cannot create scale for "value": ${JSON.stringify(channelDef)}`
|
|
@@ -109,7 +117,8 @@ export function generateScaleGlsl(channel, scale, channelDef) {
|
|
|
109
117
|
}
|
|
110
118
|
|
|
111
119
|
const primary = getPrimaryChannel(channel);
|
|
112
|
-
const attributeName =
|
|
120
|
+
const attributeName =
|
|
121
|
+
ATTRIBUTE_PREFIX + makeAttributeName(sharedQuantitativeChannels);
|
|
113
122
|
const domainUniformName = DOMAIN_PREFIX + primary;
|
|
114
123
|
const rangeName = RANGE_PREFIX + primary;
|
|
115
124
|
|
|
@@ -270,11 +279,9 @@ export function generateScaleGlsl(channel, scale, channelDef) {
|
|
|
270
279
|
interpolate = `getDiscreteColor(${textureUniformName}, int(transformed)).r`;
|
|
271
280
|
}
|
|
272
281
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
glsl.push(`in highp ${attributeType} ${attributeName};`);
|
|
277
|
-
}
|
|
282
|
+
const attributeGlsl = isDatumDef(channelDef)
|
|
283
|
+
? `uniform highp ${attributeType} ${attributeName};`
|
|
284
|
+
: `in highp ${attributeType} ${attributeName};`;
|
|
278
285
|
|
|
279
286
|
/** @type {string[]} Channel's scale function*/
|
|
280
287
|
const scaleBody = [];
|
|
@@ -361,6 +368,7 @@ ${returnType} ${SCALED_FUNCTION_PREFIX}${channel}() {
|
|
|
361
368
|
}
|
|
362
369
|
|
|
363
370
|
return {
|
|
371
|
+
attributeGlsl,
|
|
364
372
|
glsl: concatenated,
|
|
365
373
|
domainUniform,
|
|
366
374
|
};
|
|
@@ -504,3 +512,48 @@ function exactSplitHighPrecision(x) {
|
|
|
504
512
|
export function toHighPrecisionDomainUniform(domain) {
|
|
505
513
|
return [...exactSplitHighPrecision(domain[0]), domain[1] - domain[0]];
|
|
506
514
|
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* @typedef {[string, boolean]} FieldKey Tuple: [channel, isQuantitative]]
|
|
518
|
+
*/
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Finds duplicated quantitative fields in the encoding block.
|
|
522
|
+
* They need to be uploaded to the GPU only once.
|
|
523
|
+
*
|
|
524
|
+
* @param {Partial<Record<import("../spec/channel.js").Channel, import("../types/encoder.js").Encoder>>} encoders
|
|
525
|
+
*/
|
|
526
|
+
export function dedupeEncodingFields(encoders) {
|
|
527
|
+
/**
|
|
528
|
+
* Value: an array of channels
|
|
529
|
+
* @type {InternMap<FieldKey, import("../spec/channel.js").Channel[]>}
|
|
530
|
+
*/
|
|
531
|
+
const deduped = new InternMap([], JSON.stringify);
|
|
532
|
+
|
|
533
|
+
for (const [channel, encoder] of Object.entries(encoders)) {
|
|
534
|
+
const channelDef = encoder.channelDef;
|
|
535
|
+
if (isFieldDef(channelDef)) {
|
|
536
|
+
const field = channelDef.field;
|
|
537
|
+
|
|
538
|
+
/** @type {[string, boolean]} */
|
|
539
|
+
const key = [
|
|
540
|
+
field,
|
|
541
|
+
encoder.scale
|
|
542
|
+
? (isContinuous(encoder.scale.type) ||
|
|
543
|
+
isDiscretizing(encoder.scale.type)) ??
|
|
544
|
+
false
|
|
545
|
+
: false,
|
|
546
|
+
];
|
|
547
|
+
|
|
548
|
+
deduped.set(key, [...(deduped.get(key) ?? []), channel]);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return deduped;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* @param {import("../spec/channel.js").Channel | import("../spec/channel.js").Channel[]} channel
|
|
556
|
+
*/
|
|
557
|
+
export function makeAttributeName(channel) {
|
|
558
|
+
return asArray(channel).join("_");
|
|
559
|
+
}
|
package/dist/src/marks/link.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { setBuffersAndAttributes } from "twgl.js";
|
|
2
|
-
import VERTEX_SHADER from "
|
|
3
|
-
import FRAGMENT_SHADER from "
|
|
2
|
+
import VERTEX_SHADER from "./link.vertex.glsl.js";
|
|
3
|
+
import FRAGMENT_SHADER from "./link.fragment.glsl.js";
|
|
4
4
|
import { LinkVertexBuilder } from "../gl/dataToVertices.js";
|
|
5
5
|
|
|
6
6
|
import Mark from "./mark.js";
|
package/dist/src/marks/mark.d.ts
CHANGED
|
@@ -125,8 +125,9 @@ export default class Mark {
|
|
|
125
125
|
* @param {string} vertexShader
|
|
126
126
|
* @param {string} fragmentShader
|
|
127
127
|
* @param {string[]} [extraHeaders]
|
|
128
|
+
* @protected
|
|
128
129
|
*/
|
|
129
|
-
createAndLinkShaders(vertexShader: string, fragmentShader: string, extraHeaders?: string[]): void;
|
|
130
|
+
protected createAndLinkShaders(vertexShader: string, fragmentShader: string, extraHeaders?: string[]): void;
|
|
130
131
|
/** @type {string[]} */
|
|
131
132
|
domainUniforms: string[];
|
|
132
133
|
programStatus: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"mark.d.ts","sourceRoot":"","sources":["../../../src/marks/mark.js"],"names":[],"mappings":"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"}
|
package/dist/src/marks/mark.js
CHANGED
|
@@ -14,6 +14,7 @@ import createEncoders, {
|
|
|
14
14
|
isChannelDefWithScale,
|
|
15
15
|
isChannelWithScale,
|
|
16
16
|
isDatumDef,
|
|
17
|
+
isFieldDef,
|
|
17
18
|
isValueDef,
|
|
18
19
|
} from "../encoder/encoder.js";
|
|
19
20
|
import {
|
|
@@ -25,7 +26,8 @@ import {
|
|
|
25
26
|
isHighPrecisionScale,
|
|
26
27
|
toHighPrecisionDomainUniform,
|
|
27
28
|
splitHighPrecision,
|
|
28
|
-
|
|
29
|
+
dedupeEncodingFields,
|
|
30
|
+
} from "../gl/glslScaleGenerator.js";
|
|
29
31
|
import GLSL_COMMON from "../gl/includes/common.glsl.js";
|
|
30
32
|
import GLSL_SCALES from "../gl/includes/scales.glsl.js";
|
|
31
33
|
import GLSL_SAMPLE_FACET from "../gl/includes/sampleFacet.glsl.js";
|
|
@@ -316,6 +318,7 @@ export default class Mark {
|
|
|
316
318
|
* @param {string} vertexShader
|
|
317
319
|
* @param {string} fragmentShader
|
|
318
320
|
* @param {string[]} [extraHeaders]
|
|
321
|
+
* @protected
|
|
319
322
|
*/
|
|
320
323
|
createAndLinkShaders(vertexShader, fragmentShader, extraHeaders = []) {
|
|
321
324
|
const attributes = this.getAttributes();
|
|
@@ -330,6 +333,15 @@ export default class Mark {
|
|
|
330
333
|
/** @type {string[]} */
|
|
331
334
|
let scaleCode = [];
|
|
332
335
|
|
|
336
|
+
/**
|
|
337
|
+
* Attribute definitions. Using set to prevent duplicates caused by
|
|
338
|
+
* multiple channels using the same shared quantitative field.
|
|
339
|
+
* @type {Set<string>}
|
|
340
|
+
*/
|
|
341
|
+
const attributeCode = new Set();
|
|
342
|
+
|
|
343
|
+
const dedupedEncodingFields = dedupeEncodingFields(this.encoders);
|
|
344
|
+
|
|
333
345
|
const sampleFacetMode = this.getSampleFacetMode();
|
|
334
346
|
if (sampleFacetMode) {
|
|
335
347
|
extraHeaders.push(`#define ${sampleFacetMode}`);
|
|
@@ -364,12 +376,27 @@ export default class Mark {
|
|
|
364
376
|
.getScale()
|
|
365
377
|
: scaleNull();
|
|
366
378
|
|
|
367
|
-
|
|
379
|
+
// Channels that share the same quantitative field
|
|
380
|
+
// TODO: It should be ok to share a categorical field if the channels
|
|
381
|
+
// share the same scale, e.g., primary and secondary positional channels
|
|
382
|
+
const sharedChannels = isFieldDef(channelDef)
|
|
383
|
+
? dedupedEncodingFields.get([channelDef.field, true])
|
|
384
|
+
: [channel];
|
|
385
|
+
|
|
386
|
+
const generated = generateScaleGlsl(
|
|
387
|
+
channel,
|
|
388
|
+
scale,
|
|
389
|
+
channelDef,
|
|
390
|
+
sharedChannels
|
|
391
|
+
);
|
|
368
392
|
|
|
369
393
|
scaleCode.push(generated.glsl);
|
|
370
394
|
if (generated.domainUniform) {
|
|
371
395
|
this.domainUniforms.push(generated.domainUniform);
|
|
372
396
|
}
|
|
397
|
+
if (generated.attributeGlsl) {
|
|
398
|
+
attributeCode.add(generated.attributeGlsl);
|
|
399
|
+
}
|
|
373
400
|
}
|
|
374
401
|
}
|
|
375
402
|
|
|
@@ -388,6 +415,7 @@ export default class Mark {
|
|
|
388
415
|
GLSL_COMMON,
|
|
389
416
|
GLSL_SCALES,
|
|
390
417
|
domainUniformBlock,
|
|
418
|
+
[...attributeCode].join("\n"),
|
|
391
419
|
...scaleCode,
|
|
392
420
|
GLSL_SAMPLE_FACET,
|
|
393
421
|
GLSL_PICKING_VERTEX,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"point.d.ts","sourceRoot":"","sources":["../../../src/marks/point.js"],"names":[],"mappings":"AAkBA;IAsGY,oCAMC;IA2CT,mCAQC;IAED;;OAEG;IACH,wDASC;IAED,+BAoBC;CAiDJ;iBA3PgB,WAAW"}
|
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
} from "twgl.js";
|
|
6
6
|
import { quantileSorted } from "d3-array";
|
|
7
7
|
import { PointVertexBuilder } from "../gl/dataToVertices.js";
|
|
8
|
-
import VERTEX_SHADER from "
|
|
9
|
-
import FRAGMENT_SHADER from "
|
|
10
|
-
import COMMON_SHADER from "
|
|
8
|
+
import VERTEX_SHADER from "./point.vertex.glsl.js";
|
|
9
|
+
import FRAGMENT_SHADER from "./point.fragment.glsl.js";
|
|
10
|
+
import COMMON_SHADER from "./point.common.glsl.js";
|
|
11
11
|
|
|
12
12
|
import Mark from "./mark.js";
|
|
13
13
|
import { sampleIterable } from "../data/transforms/sample.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rect.d.ts","sourceRoot":"","sources":["../../../src/marks/rect.js"],"names":[],"mappings":"AAYA;IA0NI;;;;;;;;;;OAUG;IACH,8BALW,GAAG,KACH,OAAO,oBAAoB,EAAE,MAAM,GACjC,GAAG,CAyBf;;CACJ;iBAnQgB,WAAW"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { drawBufferInfo, setBuffersAndAttributes } from "twgl.js";
|
|
2
|
-
import VERTEX_SHADER from "
|
|
3
|
-
import FRAGMENT_SHADER from "
|
|
2
|
+
import VERTEX_SHADER from "./rect.vertex.glsl.js";
|
|
3
|
+
import FRAGMENT_SHADER from "./rect.fragment.glsl.js";
|
|
4
4
|
import { RectVertexBuilder } from "../gl/dataToVertices.js";
|
|
5
5
|
|
|
6
6
|
import Mark from "./mark.js";
|
|
@@ -179,7 +179,6 @@ export default class RectMark extends Mark {
|
|
|
179
179
|
const collector = this.unitView.getCollector();
|
|
180
180
|
const numItems = collector.getItemCount();
|
|
181
181
|
|
|
182
|
-
// TODO: Disable tessellation on SimpleTrack - no need for it
|
|
183
182
|
const builder = new RectVertexBuilder({
|
|
184
183
|
encoders: this.encoders,
|
|
185
184
|
attributes: this.getAttributes(),
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const shader = "uniform Mark{uniform float uMinWidth;uniform float uMinHeight;uniform float uMinOpacity;uniform float uCornerRadiusTopRight;uniform float uCornerRadiusBottomRight;uniform float uCornerRadiusTopLeft;uniform float uCornerRadiusBottomLeft;};out lowp vec4 vFillColor;out lowp vec4 vStrokeColor;out float vHalfStrokeWidth;out vec4 vCornerRadii;\n#if defined(ROUNDED_CORNERS) || defined(STROKED)\nout vec2 vPosInPixels;\n#endif\nout vec2 vHalfSizeInPixels;/***Clamps the minimumSize and returns an opacity that reflects the amount of clamping.*/float clampMinSize(inout float pos,float frac,float size,float minSize){if(minSize>0.0&&abs(size)<minSize){pos+=(frac-0.5)*(minSize*sign(size)-size);return abs(size)/minSize;}return 1.0;}void sort(inout float a,inout float b){if(a>b){float tmp=b;b=a;a=tmp;}}/***The vertex position wrt the rectangle specified by(x,x2,y,y2).*[0,0]=[x,y],[1,1]=[x2,y2].*The x or y component may contain fractional values if the rectangle*have been tessellated.*/vec2 getVertexPos(){int index=gl_VertexID % 6;return vec2(index==0||index==1||index==3 ? 0.0 : 1.0,index==0||index==1||index==2 ? 0.0 : 1.0);}void main(void){vec2 frac=getVertexPos();vec2 normalizedMinSize=vec2(uMinWidth,uMinHeight)/uViewportSize;vec4 cornerRadii=vec4(uCornerRadiusTopRight,uCornerRadiusBottomRight,uCornerRadiusBottomLeft,uCornerRadiusTopLeft);float x=getScaled_x();float x2=getScaled_x2();float y=getScaled_y();float y2=getScaled_y2();sort(x,x2);sort(y,y2);float clampMargin=1.0;vec2 pos1=vec2(clamp(x,0.0-clampMargin,1.0+clampMargin),y);vec2 pos2=vec2(clamp(x2,0.0-clampMargin,1.0+clampMargin),y2);vec2 size=pos2-pos1;if(size.x<=0.0||size.y<=0.0){gl_Position=vec4(0.0,0.0,0.0,1.0);return;}vec2 pos=pos1+frac*size;size.y*=getSampleFacetHeight(pos);float opaFactor=uViewOpacity*max(uMinOpacity,clampMinSize(pos.x,frac.x,size.x,normalizedMinSize.x)*clampMinSize(pos.y,frac.y,size.y,normalizedMinSize.y));pos=applySampleFacet(pos);\n#if defined(ROUNDED_CORNERS) || defined(STROKED)\nfloat aaPadding=1.0/uDevicePixelRatio;float strokeWidth=getScaled_strokeWidth();float strokeOpacity=getScaled_strokeOpacity()*opaFactor;vec2 centeredFrac=frac-0.5;vec2 expand=centeredFrac*(strokeWidth+aaPadding)/uViewportSize;pos+=expand;vec2 sizeInPixels=size*uViewportSize;vPosInPixels=(centeredFrac+expand/size)*sizeInPixels;vHalfSizeInPixels=sizeInPixels/2.0;vCornerRadii=min(cornerRadii,min(vHalfSizeInPixels.x,vHalfSizeInPixels.y));vHalfStrokeWidth=strokeWidth/2.0;vStrokeColor=vec4(getScaled_stroke()*strokeOpacity,strokeOpacity);\n#endif\ngl_Position=unitToNdc(pos);float fillOpacity=getScaled_fillOpacity()*opaFactor;vFillColor=vec4(getScaled_fill()*fillOpacity,fillOpacity);setupPicking();}";
|
|
2
|
+
export default shader;
|
package/dist/src/marks/rule.js
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
setBuffersAndAttributes,
|
|
7
7
|
setUniforms,
|
|
8
8
|
} from "twgl.js";
|
|
9
|
-
import VERTEX_SHADER from "
|
|
10
|
-
import FRAGMENT_SHADER from "
|
|
11
|
-
import COMMON_SHADER from "
|
|
9
|
+
import VERTEX_SHADER from "./rule.vertex.glsl.js";
|
|
10
|
+
import FRAGMENT_SHADER from "./rule.fragment.glsl.js";
|
|
11
|
+
import COMMON_SHADER from "./rule.common.glsl.js";
|
|
12
12
|
import { RuleVertexBuilder } from "../gl/dataToVertices.js";
|
|
13
13
|
import { isChannelDefWithScale } from "../encoder/encoder.js";
|
|
14
14
|
|