@genome-spy/core 0.59.0 → 0.60.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle/index.es.js +6170 -5616
- package/dist/bundle/index.js +144 -119
- package/dist/schema.json +304 -22
- package/dist/src/data/collector.d.ts.map +1 -1
- package/dist/src/data/collector.js +1 -0
- package/dist/src/data/sources/dataUtils.d.ts +2 -1
- package/dist/src/data/sources/dataUtils.d.ts.map +1 -1
- package/dist/src/data/sources/dataUtils.js +3 -4
- package/dist/src/data/sources/inlineSource.d.ts +8 -0
- package/dist/src/data/sources/inlineSource.d.ts.map +1 -1
- package/dist/src/data/sources/inlineSource.js +17 -1
- package/dist/src/data/sources/urlSource.d.ts +1 -0
- package/dist/src/data/sources/urlSource.d.ts.map +1 -1
- package/dist/src/data/sources/urlSource.js +33 -4
- package/dist/src/encoder/encoder.d.ts +1 -1
- package/dist/src/genomeSpy.d.ts.map +1 -1
- package/dist/src/genomeSpy.js +39 -6
- package/dist/src/gl/colorUtils.d.ts +4 -0
- package/dist/src/gl/colorUtils.d.ts.map +1 -1
- package/dist/src/gl/colorUtils.js +8 -0
- package/dist/src/gl/glslScaleGenerator.d.ts +1 -1
- package/dist/src/gl/glslScaleGenerator.d.ts.map +1 -1
- package/dist/src/gl/glslScaleGenerator.js +1 -9
- package/dist/src/gl/includes/common.glsl.js +1 -1
- package/dist/src/marks/link.d.ts.map +1 -1
- package/dist/src/marks/link.js +8 -0
- package/dist/src/marks/mark.d.ts +8 -0
- package/dist/src/marks/mark.d.ts.map +1 -1
- package/dist/src/marks/mark.js +101 -3
- package/dist/src/marks/point.fragment.glsl.js +1 -1
- package/dist/src/marks/point.vertex.glsl.js +1 -1
- package/dist/src/marks/rect.common.glsl.js +1 -1
- package/dist/src/marks/rect.d.ts.map +1 -1
- package/dist/src/marks/rect.fragment.glsl.js +1 -1
- package/dist/src/marks/rect.js +41 -0
- package/dist/src/marks/rect.vertex.glsl.js +1 -1
- package/dist/src/selection/selection.d.ts +27 -2
- package/dist/src/selection/selection.d.ts.map +1 -1
- package/dist/src/selection/selection.js +53 -3
- package/dist/src/spec/data.d.ts +18 -1
- package/dist/src/spec/mark.d.ts +58 -1
- package/dist/src/spec/parameter.d.ts +71 -31
- package/dist/src/spec/view.d.ts +9 -2
- package/dist/src/styles/genome-spy.css.d.ts +1 -1
- package/dist/src/styles/genome-spy.css.d.ts.map +1 -1
- package/dist/src/styles/genome-spy.css.js +12 -1
- package/dist/src/styles/genome-spy.scss +19 -1
- package/dist/src/types/selectionTypes.d.ts +4 -7
- package/dist/src/utils/expression.d.ts.map +1 -1
- package/dist/src/utils/expression.js +4 -0
- package/dist/src/utils/ui/tooltip.d.ts +6 -10
- package/dist/src/utils/ui/tooltip.d.ts.map +1 -1
- package/dist/src/utils/ui/tooltip.js +74 -42
- package/dist/src/view/concatView.d.ts +1 -1
- package/dist/src/view/concatView.d.ts.map +1 -1
- package/dist/src/view/concatView.js +1 -1
- package/dist/src/view/gridView/gridChild.d.ts +53 -0
- package/dist/src/view/gridView/gridChild.d.ts.map +1 -0
- package/dist/src/view/gridView/gridChild.js +753 -0
- package/dist/src/view/gridView/gridView.d.ts +64 -0
- package/dist/src/view/gridView/gridView.d.ts.map +1 -0
- package/dist/src/view/{gridView.js → gridView/gridView.js} +40 -595
- package/dist/src/view/gridView/scrollbar.d.ts +32 -0
- package/dist/src/view/gridView/scrollbar.d.ts.map +1 -0
- package/dist/src/view/gridView/scrollbar.js +186 -0
- package/dist/src/view/gridView/selectionRect.d.ts +10 -0
- package/dist/src/view/gridView/selectionRect.d.ts.map +1 -0
- package/dist/src/view/gridView/selectionRect.js +182 -0
- package/dist/src/view/layout/rectangle.d.ts +11 -1
- package/dist/src/view/layout/rectangle.d.ts.map +1 -1
- package/dist/src/view/layout/rectangle.js +22 -2
- package/dist/src/view/layout/rectangle.test.js +12 -0
- package/dist/src/view/paramMediator.d.ts.map +1 -1
- package/dist/src/view/paramMediator.js +9 -0
- package/dist/src/view/scaleResolution.d.ts +1 -0
- package/dist/src/view/scaleResolution.d.ts.map +1 -1
- package/dist/src/view/scaleResolution.js +43 -33
- package/dist/src/view/view.d.ts +6 -0
- package/dist/src/view/view.d.ts.map +1 -1
- package/dist/src/view/view.js +19 -0
- package/dist/src/view/viewFactory.d.ts.map +1 -1
- package/dist/src/view/viewFactory.js +13 -1
- package/package.json +2 -2
- package/dist/src/view/gridView.d.ts +0 -135
- package/dist/src/view/gridView.d.ts.map +0 -1
package/dist/src/genomeSpy.js
CHANGED
|
@@ -688,6 +688,8 @@ export default class GenomeSpy {
|
|
|
688
688
|
|
|
689
689
|
let lastWheelEvent = performance.now();
|
|
690
690
|
|
|
691
|
+
let longPressTriggered = false;
|
|
692
|
+
|
|
691
693
|
/** @param {Event} event */
|
|
692
694
|
const listener = (event) => {
|
|
693
695
|
const now = performance.now();
|
|
@@ -781,6 +783,10 @@ export default class GenomeSpy {
|
|
|
781
783
|
|
|
782
784
|
// TODO: Should be handled at the view level, not globally
|
|
783
785
|
if (event.type == "click") {
|
|
786
|
+
if (longPressTriggered) {
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
|
|
784
790
|
const e = this._currentHover
|
|
785
791
|
? {
|
|
786
792
|
type: event.type,
|
|
@@ -820,17 +826,44 @@ export default class GenomeSpy {
|
|
|
820
826
|
"mousemove",
|
|
821
827
|
"gesturechange",
|
|
822
828
|
"contextmenu",
|
|
829
|
+
"dblclick",
|
|
823
830
|
].forEach((type) => canvas.addEventListener(type, listener));
|
|
824
831
|
|
|
825
832
|
canvas.addEventListener("mousedown", (/** @type {MouseEvent} */ e) => {
|
|
826
833
|
this._mouseDownCoords = Point.fromMouseEvent(e);
|
|
834
|
+
if (this.tooltip.sticky) {
|
|
835
|
+
this.tooltip.sticky = false;
|
|
836
|
+
this.tooltip.clear();
|
|
837
|
+
// A hack to prevent selection if the tooltip is sticky.
|
|
838
|
+
// Let the tooltip be destickified first.
|
|
839
|
+
longPressTriggered = true;
|
|
840
|
+
} else {
|
|
841
|
+
longPressTriggered = false;
|
|
842
|
+
}
|
|
827
843
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
844
|
+
const disableTooltip = () => {
|
|
845
|
+
document.addEventListener(
|
|
846
|
+
"mouseup",
|
|
847
|
+
() => this.tooltip.popEnabledState(),
|
|
848
|
+
{ once: true }
|
|
849
|
+
);
|
|
850
|
+
this.tooltip.pushEnabledState(false);
|
|
851
|
+
};
|
|
852
|
+
|
|
853
|
+
// Opening context menu or using modifier keys disables the tooltip
|
|
854
|
+
if (e.button == 2 || e.shiftKey || e.ctrlKey || e.metaKey) {
|
|
855
|
+
disableTooltip();
|
|
856
|
+
} else if (this.tooltip.visible) {
|
|
857
|
+
// Make tooltip sticky if the user long-presses
|
|
858
|
+
const timeout = setTimeout(() => {
|
|
859
|
+
longPressTriggered = true;
|
|
860
|
+
this.tooltip.sticky = true;
|
|
861
|
+
}, 400);
|
|
862
|
+
|
|
863
|
+
const clear = () => clearTimeout(timeout);
|
|
864
|
+
document.addEventListener("mouseup", clear, { once: true });
|
|
865
|
+
document.addEventListener("mousemove", clear, { once: true });
|
|
866
|
+
}
|
|
834
867
|
});
|
|
835
868
|
|
|
836
869
|
// Prevent text selections etc while dragging
|
|
@@ -31,4 +31,8 @@ export function createDiscreteTexture(range: number[], gl: WebGL2RenderingContex
|
|
|
31
31
|
* @param {WebGLTexture} [existingTexture]
|
|
32
32
|
*/
|
|
33
33
|
export function createDiscreteColorTexture(colors: string[], gl: WebGL2RenderingContext, count?: number, existingTexture?: WebGLTexture): WebGLTexture;
|
|
34
|
+
/**
|
|
35
|
+
* @param {string} color
|
|
36
|
+
*/
|
|
37
|
+
export function cssColorToArray(color: string): number[];
|
|
34
38
|
//# sourceMappingURL=colorUtils.d.ts.map
|
|
@@ -1 +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"}
|
|
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;AAyDD;;GAEG;AACH,uCAFW,MAAM,YAKhB"}
|
|
@@ -189,3 +189,11 @@ function colorArrayToTextureData(scheme, count) {
|
|
|
189
189
|
}
|
|
190
190
|
return textureData;
|
|
191
191
|
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* @param {string} color
|
|
195
|
+
*/
|
|
196
|
+
export function cssColorToArray(color) {
|
|
197
|
+
const rgb = d3color(color).rgb();
|
|
198
|
+
return [rgb.r, rgb.g, rgb.b].map((x) => x / 255);
|
|
199
|
+
}
|
|
@@ -71,7 +71,7 @@ export function generateConditionalEncoderGlsl(channel: Channel, accessors: impo
|
|
|
71
71
|
/**
|
|
72
72
|
* @param {Channel} channel
|
|
73
73
|
*/
|
|
74
|
-
export function getScaledDataTypeForChannel(channel: Channel): "
|
|
74
|
+
export function getScaledDataTypeForChannel(channel: Channel): "vec3" | "uint" | "float";
|
|
75
75
|
/**
|
|
76
76
|
*
|
|
77
77
|
* @param {import("../types/encoder.js").VegaScale} scale
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":"AAsDA;;;;;GAKG;AACH,kDAJW,OAAO,mBACP,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,mDALW,OAAO,mBACP,MAAM,SACN,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,GAClC,aAAa,CA4CzB;AAED;;;;;;;GAOG;AACH,4DAJW,OAAO,mBACP,MAAM,GACJ,aAAa,CAkCzB;AAED;;;;;;GAMG;AACH,0CANW,OAAO,SACP,GAAG,mBACH,MAAM,+BACN,OAAO,EAAE,GACP,aAAa,CA+BzB;AACD;;;;;GAKG;AACH,qDALW,OAAO,SACP,GAAG,mBACH,MAAM,GACJ,aAAa,CAyBzB;AAED;;;;;GAKG;AAEH,2CALW,OAAO,SACP,GAAG,cACH,OAAO,oBAAoB,EAAE,UAAU;;;;;;EAwQjD;AAED;;;;GAIG;AACH,wDAHW,OAAO,aACP,OAAO,qBAAqB,EAAE,QAAQ,EAAE,UA+BlD;AAmED;;GAEG;AACH,qDAFW,OAAO,6BAQjB;
|
|
1
|
+
{"version":3,"file":"glslScaleGenerator.d.ts","sourceRoot":"","sources":["../../../src/gl/glslScaleGenerator.js"],"names":[],"mappings":"AAsDA;;;;;GAKG;AACH,kDAJW,OAAO,mBACP,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;;;;;;GAUG;AAEH;;;;;;;GAOG;AACH,mDALW,OAAO,mBACP,MAAM,SACN,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,OAAO,GAClC,aAAa,CA4CzB;AAED;;;;;;;GAOG;AACH,4DAJW,OAAO,mBACP,MAAM,GACJ,aAAa,CAkCzB;AAED;;;;;;GAMG;AACH,0CANW,OAAO,SACP,GAAG,mBACH,MAAM,+BACN,OAAO,EAAE,GACP,aAAa,CA+BzB;AACD;;;;;GAKG;AACH,qDALW,OAAO,SACP,GAAG,mBACH,MAAM,GACJ,aAAa,CAyBzB;AAED;;;;;GAKG;AAEH,2CALW,OAAO,SACP,GAAG,cACH,OAAO,oBAAoB,EAAE,UAAU;;;;;;EAwQjD;AAED;;;;GAIG;AACH,wDAHW,OAAO,aACP,OAAO,qBAAqB,EAAE,QAAQ,EAAE,UA+BlD;AAmED;;GAEG;AACH,qDAFW,OAAO,6BAQjB;AAuCD;;;;GAIG;AACH,iDAHW,OAAO,qBAAqB,EAAE,SAAS,WACvC,OAAO,oBAAoB,EAAE,OAAO;mBAQjB,MAAM;sBAAoB,sBAAsB,GAAG,sBAAsB,GAAG,uBAAuB;;;;;;EAkBhI;AAED;;;;GAIG;AACH,2CAFW,MAAM,6BAIhB;AAED;;;;GAIG;AACH,sCAFW,MAAM,EAAE,WAIlB;AAMD;;;GAGG;AACH,sCAHW,MAAM,QACN,MAAM,EAAE,YAYlB;AAED;;;GAGG;AACH,2CAHW,MAAM,QACN,MAAM,EAAE,YAUlB;AAYD;;GAEG;AACH,qDAFW,MAAM,EAAE,YAIlB;AAED;;GAEG;AAEH;;;;;GAKG;AACH,+CAFW,OAAO,CAAC,MAAM,CAAC,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;AAwBD;;;;GAIG;AACH,uCAJW,MAAM,EAAE,cACR,MAAM,EAAE,GACN,MAAM,CAgClB;AAt0BD,+BAAgC,OAAO,CAAC;AACxC,4BAA6B,UAAU,CAAC;AACxC,2BAA4B,QAAQ,CAAC;AACrC,uCAAwC,WAAW,CAAC;AACpD,oCAAqC,QAAQ,CAAC;AAC9C,qCAAsC,YAAY,CAAC;AACnD,mCAAoC,gBAAgB,CAAC;AACrD,2BAA4B,SAAS,CAAC;AACtC,uCAAwC,iBAAiB,CAAC;AAmxBnD,uCAJI,GAAG,WACH,OAAO,GACL,MAAM,EAAE,CAQA;sBAnxBR,OAAO,oBAAoB,EAAE,OAAO;;aA+BvC,OAAO;kBACP,MAAM;0BACN,MAAM;oBACN,MAAM;oBACN,MAAM;kBACN,MAAM;kBACN,MAAM;eACN,CAAC,CAAC,EAAE,GAAG,KAAK,GAAG;;;;;8BAqfZ,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE;;;;uBAwLhD,CAAC,MAAM,EAAE,OAAO,CAAC;0BAtuBJ,WAAW"}
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
isInterpolating,
|
|
6
6
|
} from "vega-scale";
|
|
7
7
|
import { isArray, isBoolean, isNumber, isString } from "vega-util";
|
|
8
|
-
import { color as d3color } from "d3-color";
|
|
9
8
|
|
|
10
9
|
import {
|
|
11
10
|
getDiscreteRangeMapper,
|
|
@@ -18,6 +17,7 @@ import { asArray, peek } from "../utils/arrayUtils.js";
|
|
|
18
17
|
import { InternMap } from "internmap";
|
|
19
18
|
import { isExprRef } from "../view/paramMediator.js";
|
|
20
19
|
import scaleNull from "../utils/scaleNull.js";
|
|
20
|
+
import { cssColorToArray } from "./colorUtils.js";
|
|
21
21
|
|
|
22
22
|
export const ATTRIBUTE_PREFIX = "attr_";
|
|
23
23
|
export const DOMAIN_PREFIX = "uDomain_";
|
|
@@ -618,14 +618,6 @@ export function getScaledDataTypeForChannel(channel) {
|
|
|
618
618
|
: "float";
|
|
619
619
|
}
|
|
620
620
|
|
|
621
|
-
/**
|
|
622
|
-
* @param {string} color
|
|
623
|
-
*/
|
|
624
|
-
function cssColorToArray(color) {
|
|
625
|
-
const rgb = d3color(color).rgb();
|
|
626
|
-
return [rgb.r, rgb.g, rgb.b].map((x) => x / 255);
|
|
627
|
-
}
|
|
628
|
-
|
|
629
621
|
/**
|
|
630
622
|
* @param {string} color
|
|
631
623
|
*/
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const shader = "#define PI 3.141593\nuniform View{mediump vec2 uViewOffset;mediump vec2 uViewScale;mediump vec2 uViewportSize;lowp float uDevicePixelRatio;lowp float uViewOpacity;bool uPickingEnabled;};/***Maps a coordinate on the unit scale to a normalized device coordinate.*(0,0)is at the bottom left corner.*/vec4 unitToNdc(vec2 coord){return vec4((coord*uViewScale+uViewOffset)*2.0-1.0,0.0,1.0);}vec4 unitToNdc(float x,float y){return unitToNdc(vec2(x,y));}vec4 pixelsToNdc(vec2 coord){return unitToNdc(coord/uViewportSize);}vec4 pixelsToNdc(float x,float y){return pixelsToNdc(vec2(x,y));}float linearstep(float edge0,float edge1,float x){return clamp((x-edge0)/(edge1-edge0),0.0,1.0);}bool isEmptyBinarySearchTexture(highp usampler2D s){return textureSize(s,0).x==1&&texelFetch(s,ivec2(0,0),0).r==0u;}bool binarySearchTexture(highp usampler2D s,uint value){int texSize=textureSize(s,0).x;int left=0;int right=texSize-1;while(left<=right){int mid=left+(right-left)/2;uint midValue=texelFetch(s,ivec2(mid,0),0).r;if(midValue==value){return true;}if(midValue<value){left=mid+1;}else{right=mid-1;}}return false;}/***Calculates a gamma for antialiasing opacity based on the color.*/float getGammaForColor(vec3 rgb){return mix(1.25,0.75,smoothstep(0.0,1.0,dot(rgb,vec3(0.299,0.587,0.114))));}/***Specialized linearstep for doing antialiasing*/float distanceToRatio(float d){return clamp(d*uDevicePixelRatio+0.5,0.0,1.0);}vec4 distanceToColor(float d,vec4 fill,vec4 stroke,float halfStrokeWidth){if(halfStrokeWidth>0.0){float sd=abs(d)-halfStrokeWidth;return mix(stroke,d<=0.0 ? fill :
|
|
1
|
+
const shader = "#define PI 3.141593\nuniform View{mediump vec2 uViewOffset;mediump vec2 uViewScale;mediump vec2 uViewportSize;lowp float uDevicePixelRatio;lowp float uViewOpacity;bool uPickingEnabled;};/***Maps a coordinate on the unit scale to a normalized device coordinate.*(0,0)is at the bottom left corner.*/vec4 unitToNdc(vec2 coord){return vec4((coord*uViewScale+uViewOffset)*2.0-1.0,0.0,1.0);}vec4 unitToNdc(float x,float y){return unitToNdc(vec2(x,y));}vec4 pixelsToNdc(vec2 coord){return unitToNdc(coord/uViewportSize);}vec4 pixelsToNdc(float x,float y){return pixelsToNdc(vec2(x,y));}float linearstep(float edge0,float edge1,float x){return clamp((x-edge0)/(edge1-edge0),0.0,1.0);}bool isEmptyBinarySearchTexture(highp usampler2D s){return textureSize(s,0).x==1&&texelFetch(s,ivec2(0,0),0).r==0u;}bool binarySearchTexture(highp usampler2D s,uint value){int texSize=textureSize(s,0).x;int left=0;int right=texSize-1;while(left<=right){int mid=left+(right-left)/2;uint midValue=texelFetch(s,ivec2(mid,0),0).r;if(midValue==value){return true;}if(midValue<value){left=mid+1;}else{right=mid-1;}}return false;}/***Calculates a gamma for antialiasing opacity based on the color.*/float getGammaForColor(vec3 rgb){return mix(1.25,0.75,smoothstep(0.0,1.0,dot(rgb,vec3(0.299,0.587,0.114))));}/***Specialized linearstep for doing antialiasing*/float distanceToRatio(float d){return clamp(d*uDevicePixelRatio+0.5,0.0,1.0);}vec4 distanceToColor(float d,vec4 fill,vec4 stroke,vec4 background,float halfStrokeWidth){if(halfStrokeWidth>0.0){float sd=abs(d)-halfStrokeWidth;return mix(stroke,d<=0.0 ? fill : background,distanceToRatio(sd));}else{return mix(background,fill,distanceToRatio(-d));}}";
|
|
2
2
|
export default shader;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/marks/link.js"],"names":[],"mappings":"AAYA;;GAEG;AACH;IACI;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,EAoC/C;IATG;;;;;OAKG;IACH,yBAEC;
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../src/marks/link.js"],"names":[],"mappings":"AAYA;;GAEG;AACH;IACI;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,EAoC/C;IATG;;;;;OAKG;IACH,yBAEC;IA8HD;;kBAGiC,GAAG;;;;MAEnC;CA4FR;iBA7QgB,WAAW"}
|
package/dist/src/marks/link.js
CHANGED
|
@@ -53,6 +53,14 @@ export default class LinkMark extends Mark {
|
|
|
53
53
|
);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Returns the default hit test mode for this mark.
|
|
58
|
+
* @returns {import("./mark.js").HitTestMode}
|
|
59
|
+
*/
|
|
60
|
+
get defaultHitTestMode() {
|
|
61
|
+
return "endpoints";
|
|
62
|
+
}
|
|
63
|
+
|
|
56
64
|
/**
|
|
57
65
|
* @returns {import("../spec/channel.js").Channel[]}
|
|
58
66
|
*/
|
package/dist/src/marks/mark.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export const SELECTION_TEXTURE_PREFIX: "uSelectionTexture_";
|
|
|
12
12
|
* @callback DrawFunction
|
|
13
13
|
* @param {number} offset
|
|
14
14
|
* @param {number} count
|
|
15
|
+
*
|
|
16
|
+
* @typedef {"intersects" | "encloses" | "endpoints"} HitTestMode
|
|
15
17
|
*/
|
|
16
18
|
/**
|
|
17
19
|
* @template {MarkProps} [P=MarkProps]
|
|
@@ -93,6 +95,11 @@ export default class Mark<P extends import("../spec/mark.js").MarkProps = import
|
|
|
93
95
|
*/
|
|
94
96
|
protected augmentDefaultProperties(props: Partial<P>): void;
|
|
95
97
|
get opaque(): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Returns the default hit test mode for this mark.
|
|
100
|
+
* @returns {HitTestMode}
|
|
101
|
+
*/
|
|
102
|
+
get defaultHitTestMode(): HitTestMode;
|
|
96
103
|
/**
|
|
97
104
|
* Returns attribute info for WebGL attributes that match visual channels.
|
|
98
105
|
*
|
|
@@ -277,6 +284,7 @@ export type _MarkRenderingOptions = {
|
|
|
277
284
|
};
|
|
278
285
|
export type MarkRenderingOptions = RenderingOptions & _MarkRenderingOptions;
|
|
279
286
|
export type DrawFunction = (offset: number, count: number) => any;
|
|
287
|
+
export type HitTestMode = "intersects" | "encloses" | "endpoints";
|
|
280
288
|
/**
|
|
281
289
|
* @augments {InternMap<K, import("../gl/dataToVertices.js").RangeEntry>}
|
|
282
290
|
* @template K
|
|
@@ -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
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from "twgl.js";
|
|
12
12
|
import { isContinuous, isDiscrete } from "vega-scale";
|
|
13
13
|
import createEncoders, {
|
|
14
|
+
getSecondaryChannel,
|
|
14
15
|
isChannelDefWithScale,
|
|
15
16
|
isChannelWithScale,
|
|
16
17
|
isDatumDef,
|
|
@@ -50,6 +51,7 @@ import ViewError from "../view/viewError.js";
|
|
|
50
51
|
import { isExprRef, validateParameterName } from "../view/paramMediator.js";
|
|
51
52
|
import { UNIQUE_ID_KEY } from "../data/transforms/identifier.js";
|
|
52
53
|
import {
|
|
54
|
+
isIntervalSelection,
|
|
53
55
|
isMultiPointSelection,
|
|
54
56
|
isSinglePointSelection,
|
|
55
57
|
} from "../selection/selection.js";
|
|
@@ -70,6 +72,8 @@ export const SELECTION_TEXTURE_PREFIX = "uSelectionTexture_";
|
|
|
70
72
|
* @callback DrawFunction
|
|
71
73
|
* @param {number} offset
|
|
72
74
|
* @param {number} count
|
|
75
|
+
*
|
|
76
|
+
* @typedef {"intersects" | "encloses" | "endpoints"} HitTestMode
|
|
73
77
|
*/
|
|
74
78
|
|
|
75
79
|
/**
|
|
@@ -217,6 +221,14 @@ export default class Mark {
|
|
|
217
221
|
return false;
|
|
218
222
|
}
|
|
219
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Returns the default hit test mode for this mark.
|
|
226
|
+
* @returns {HitTestMode}
|
|
227
|
+
*/
|
|
228
|
+
get defaultHitTestMode() {
|
|
229
|
+
return "intersects";
|
|
230
|
+
}
|
|
231
|
+
|
|
220
232
|
/**
|
|
221
233
|
* Returns attribute info for WebGL attributes that match visual channels.
|
|
222
234
|
*
|
|
@@ -464,14 +476,14 @@ export default class Mark {
|
|
|
464
476
|
|
|
465
477
|
/**
|
|
466
478
|
* Prevent duplicate registration.
|
|
467
|
-
* @type {Map<string, "single" | "multi" | "
|
|
479
|
+
* @type {Map<string, "single" | "multi" | "interval">}
|
|
468
480
|
*/
|
|
469
481
|
const selectionParameterUniforms = new Map();
|
|
470
482
|
|
|
471
483
|
for (const predicate of paramPredicates) {
|
|
472
484
|
const param = predicate.param;
|
|
473
485
|
const paramMediator = this.unitView.paramMediator;
|
|
474
|
-
const selection = paramMediator.
|
|
486
|
+
const selection = paramMediator.findValue(param);
|
|
475
487
|
|
|
476
488
|
// The selection is supposed to have an empty value at this point
|
|
477
489
|
// so that we can figure out the type of the selection.
|
|
@@ -487,9 +499,10 @@ export default class Mark {
|
|
|
487
499
|
// Register a mark uniform for each param. The uniform will have
|
|
488
500
|
// the value of uniqueId of the selected datum.
|
|
489
501
|
if (!selectionParameterUniforms.has(param)) {
|
|
502
|
+
selectionParameterUniforms.set(param, "single");
|
|
503
|
+
|
|
490
504
|
const uniformName =
|
|
491
505
|
PARAM_PREFIX + validateParameterName(param);
|
|
492
|
-
selectionParameterUniforms.set(param, "single");
|
|
493
506
|
|
|
494
507
|
dynamicMarkUniforms.push(` // Selection parameter`);
|
|
495
508
|
dynamicMarkUniforms.push(
|
|
@@ -561,6 +574,91 @@ export default class Mark {
|
|
|
561
574
|
this.getContext().animator.requestRender();
|
|
562
575
|
});
|
|
563
576
|
}
|
|
577
|
+
} else if (isIntervalSelection(selection)) {
|
|
578
|
+
if (!selectionParameterUniforms.has(param)) {
|
|
579
|
+
selectionParameterUniforms.set(param, "interval");
|
|
580
|
+
|
|
581
|
+
/** @type {string[]} */
|
|
582
|
+
const testSnippets = [];
|
|
583
|
+
|
|
584
|
+
/** @type {string[]} */
|
|
585
|
+
const emptySnippets = [];
|
|
586
|
+
|
|
587
|
+
// Handle both channels separately
|
|
588
|
+
for (const channel of Object.keys(selection.intervals)) {
|
|
589
|
+
if (!["x", "y"].includes(channel)) {
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
const uniformName =
|
|
594
|
+
PARAM_PREFIX +
|
|
595
|
+
validateParameterName(param) +
|
|
596
|
+
`_${channel}`;
|
|
597
|
+
|
|
598
|
+
// TODO: High precision scales
|
|
599
|
+
const { attributeType } = getAttributeAndArrayTypes(
|
|
600
|
+
this.unitView.getScaleResolution(channel).scale,
|
|
601
|
+
channel
|
|
602
|
+
);
|
|
603
|
+
|
|
604
|
+
dynamicMarkUniforms.push(` // Selection parameter`);
|
|
605
|
+
dynamicMarkUniforms.push(
|
|
606
|
+
` uniform highp ${attributeType}[2] ${uniformName};`
|
|
607
|
+
);
|
|
608
|
+
this.#callAfterShaderCompilation.push(() => {
|
|
609
|
+
this.registerMarkUniformValue(
|
|
610
|
+
uniformName,
|
|
611
|
+
{ expr: param },
|
|
612
|
+
(
|
|
613
|
+
/** @type {import("../types/selectionTypes.js").IntervalSelection} */ selection
|
|
614
|
+
) =>
|
|
615
|
+
selection.intervals[channel] ?? [
|
|
616
|
+
Infinity,
|
|
617
|
+
-Infinity,
|
|
618
|
+
]
|
|
619
|
+
);
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
const c = ATTRIBUTE_PREFIX + channel;
|
|
623
|
+
const u = uniformName + "[0]";
|
|
624
|
+
const u2 = uniformName + "[1]";
|
|
625
|
+
const secondaryChannel = getSecondaryChannel(channel);
|
|
626
|
+
if (this.encoding[secondaryChannel]) {
|
|
627
|
+
const c2 = ATTRIBUTE_PREFIX + secondaryChannel;
|
|
628
|
+
const mode = this.defaultHitTestMode;
|
|
629
|
+
if (mode == "endpoints") {
|
|
630
|
+
testSnippets.push(
|
|
631
|
+
`((${u} <= ${c} && ${c} <= ${u2}) || (${u} <= ${c2} && ${c2} <= ${u2}))`
|
|
632
|
+
);
|
|
633
|
+
} else if (mode == "encloses") {
|
|
634
|
+
testSnippets.push(
|
|
635
|
+
`(${u} <= ${c} && ${c2} <= ${u2})`
|
|
636
|
+
);
|
|
637
|
+
} else if (mode == "intersects") {
|
|
638
|
+
testSnippets.push(
|
|
639
|
+
`(${u} <= ${c2} && ${c} <= ${u2})`
|
|
640
|
+
);
|
|
641
|
+
} else {
|
|
642
|
+
throw new ViewError(
|
|
643
|
+
`Unsupported hit test mode "${mode}" for interval selection!`,
|
|
644
|
+
this.unitView
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
} else {
|
|
648
|
+
testSnippets.push(
|
|
649
|
+
`(${u} <= ${c} && ${c} <= ${u2})`
|
|
650
|
+
);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
emptySnippets.push(`${u} > ${u2}`);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
scaleCode.push(
|
|
657
|
+
`bool ${SELECTION_CHECKER_PREFIX}${param}(bool empty) {\n` +
|
|
658
|
+
` return ${testSnippets.join(" && ")} || (empty && (${emptySnippets.join(" || ")}));\n` +
|
|
659
|
+
`}`
|
|
660
|
+
);
|
|
661
|
+
}
|
|
564
662
|
}
|
|
565
663
|
}
|
|
566
664
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const shader = "const lowp vec4 white=vec4(1.0);const lowp vec4 black=vec4(0.0,0.0,0.0,1.0);in float vRadius;in float vRadiusWithPadding;in lowp vec4 vFillColor;in lowp vec4 vStrokeColor;in lowp float vShape;in lowp float vHalfStrokeWidth;in mat2 vRotationMatrix;out lowp vec4 fragColor;const float CIRCLE=0.0;const float SQUARE=1.0;const float CROSS=2.0;const float DIAMOND=3.0;const float TRIANGLE_UP=4.0;const float TICK_UP=8.0;float circle(vec2 p,float r){return length(p)-r;}float square(vec2 p,float r){p=abs(p);return max(p.x,p.y)-r;}float tickUp(vec2 p,float r){float halfR=r*0.5;p.y+=halfR;p=abs(p);return max(p.x-r*0.15,p.y-halfR);}float equilateralTriangle(vec2 p,float r){p.y=-p.y;float k=sqrt(3.0);float kr=k*r;p.y-=kr/2.0;return max((abs(p.x)*k+p.y)/2.0,-p.y-kr);}float crossShape(vec2 p,float r){p=abs(p);vec2 b=vec2(0.4,1.0)*r;vec2 v=abs(p)-b.xy;vec2 h=abs(p)-b.yx;return min(max(v.x,v.y),max(h.x,h.y));}float diamond(vec2 p,float r){p=abs(p);return(max(abs(p.x-p.y),abs(p.x+p.y))-r)/sqrt(2.0);}void main(){float d;vec2 p=vRotationMatrix*(2.0*gl_PointCoord-1.0)*vRadiusWithPadding;float r=vRadius;if(vShape==CIRCLE){d=circle(p,r);}else if(vShape==SQUARE){d=square(p,r);}else if(vShape==CROSS){d=crossShape(p,r);}else if(vShape==DIAMOND){d=diamond(p,r);}else if(vShape==TRIANGLE_UP){d=equilateralTriangle(p,r);}else if(vShape==TICK_UP){d=tickUp(p,r);}else{d=0.0;}if(!uPickingEnabled){lowp vec4 fillColor=mix(vFillColor,white,-d*uGradientStrength/vRadius);fragColor=distanceToColor(d+(uInwardStroke ? vHalfStrokeWidth : 0.0),fillColor,vStrokeColor,vHalfStrokeWidth);}else if(d-vHalfStrokeWidth<=0.0){fragColor=vPickingColor;}else{discard;}}";
|
|
1
|
+
const shader = "const lowp vec4 white=vec4(1.0);const lowp vec4 black=vec4(0.0,0.0,0.0,1.0);in float vRadius;in float vRadiusWithPadding;in lowp vec4 vFillColor;in lowp vec4 vStrokeColor;in lowp float vShape;in lowp float vHalfStrokeWidth;in mat2 vRotationMatrix;out lowp vec4 fragColor;const float CIRCLE=0.0;const float SQUARE=1.0;const float CROSS=2.0;const float DIAMOND=3.0;const float TRIANGLE_UP=4.0;const float TICK_UP=8.0;float circle(vec2 p,float r){return length(p)-r;}float square(vec2 p,float r){p=abs(p);return max(p.x,p.y)-r;}float tickUp(vec2 p,float r){float halfR=r*0.5;p.y+=halfR;p=abs(p);return max(p.x-r*0.15,p.y-halfR);}float equilateralTriangle(vec2 p,float r){p.y=-p.y;float k=sqrt(3.0);float kr=k*r;p.y-=kr/2.0;return max((abs(p.x)*k+p.y)/2.0,-p.y-kr);}float crossShape(vec2 p,float r){p=abs(p);vec2 b=vec2(0.4,1.0)*r;vec2 v=abs(p)-b.xy;vec2 h=abs(p)-b.yx;return min(max(v.x,v.y),max(h.x,h.y));}float diamond(vec2 p,float r){p=abs(p);return(max(abs(p.x-p.y),abs(p.x+p.y))-r)/sqrt(2.0);}void main(){float d;vec2 p=vRotationMatrix*(2.0*gl_PointCoord-1.0)*vRadiusWithPadding;float r=vRadius;if(vShape==CIRCLE){d=circle(p,r);}else if(vShape==SQUARE){d=square(p,r);}else if(vShape==CROSS){d=crossShape(p,r);}else if(vShape==DIAMOND){d=diamond(p,r);}else if(vShape==TRIANGLE_UP){d=equilateralTriangle(p,r);}else if(vShape==TICK_UP){d=tickUp(p,r);}else{d=0.0;}if(!uPickingEnabled){lowp vec4 fillColor=mix(vFillColor,white,-d*uGradientStrength/vRadius);fragColor=distanceToColor(d+(uInwardStroke ? vHalfStrokeWidth : 0.0),fillColor,vStrokeColor,vec4(0.0),vHalfStrokeWidth);}else if(d-vHalfStrokeWidth<=0.0){fragColor=vPickingColor;}else{discard;}}";
|
|
2
2
|
export default shader;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const shader = "out float vRadius;out float vRadiusWithPadding;out lowp vec4 vFillColor;out lowp vec4 vStrokeColor;out lowp float vShape;out lowp float vHalfStrokeWidth;out mat2 vRotationMatrix;const float CIRCLE=0.0;const float SQUARE=1.0;const float CROSS=2.0;const float DIAMOND=3.0;const float TRIANGLE_UP=4.0;const float TRIANGLE_RIGHT=5.0;const float TRIANGLE_DOWN=6.0;const float TRIANGLE_LEFT=7.0;const float TICK_UP=8.0;const float TICK_RIGHT=9.0;const float TICK_DOWN=10.0;const float TICK_LEFT=11.0;float computeSemanticThresholdFactor(){return getScaled_semanticScore()>=uSemanticThreshold ? 1.0 : 0.0;}vec2 getDxDy(){\n#if defined(dx_DEFINED) || defined(dy_DEFINED)\nreturn vec2(getScaled_dx(),getScaled_dy())/uViewportSize;\n#else\nreturn vec2(0.0,0.0);\n#endif\n}void main(void){float shapeAngle=0.0;float semanticThresholdFactor=computeSemanticThresholdFactor();if(semanticThresholdFactor<=0.0){gl_PointSize=0.0;gl_Position=vec4(100.0,0.0,0.0,0.0);return;}float size=getScaled_size();vec2 pos=vec2(getScaled_x(),getScaled_y())+getDxDy();gl_Position=unitToNdc(applySampleFacet(pos));float strokeWidth=getScaled_strokeWidth();float diameter=sqrt(size)*uScaleFactor*semanticThresholdFactor;float opacity=uViewOpacity;if(strokeWidth<=0.0||uInwardStroke){float minDiameter=1.0/uDevicePixelRatio;if(diameter<minDiameter){opacity*=pow(diameter/minDiameter,2.5);diameter=minDiameter;}}float fillOpa=getScaled_fillOpacity()*opacity;float strokeOpa=getScaled_strokeOpacity()*opacity;vShape=getScaled_shape();bool circle=vShape==0.0;if(vShape>TICK_UP&&vShape<=TICK_LEFT){shapeAngle=(vShape-TICK_UP)*90.0;vShape=TICK_UP;}else if(vShape>TRIANGLE_UP&&vShape<=TRIANGLE_LEFT){shapeAngle=(vShape-TRIANGLE_UP)*90.0;vShape=TRIANGLE_UP;}float angleInDegrees=getScaled_angle();float angle=-(shapeAngle+angleInDegrees)*PI/180.0;float sinTheta=sin(angle);float cosTheta=cos(angle);vRotationMatrix=mat2(cosTheta,sinTheta,-sinTheta,cosTheta);float roomForRotation=circle ? 1.0 : sin(mod(angle,PI/2.0)+PI/4.0)/sin(PI/4.0);float aaPadding=1.0/uDevicePixelRatio;float rotationPadding=(diameter*roomForRotation)-diameter;float strokePadding=uInwardStroke ? 0.0 : strokeWidth*(circle ? 1.0 : sqrt(3.0));float padding=rotationPadding+strokePadding+aaPadding;gl_PointSize=max((diameter+padding),uPickingEnabled ? uMinPickingSize : 0.0)*uDevicePixelRatio;vRadius=diameter/2.0;vRadiusWithPadding=vRadius+padding/2.0;vHalfStrokeWidth=strokeWidth/2.0;vFillColor=vec4(getScaled_fill()*fillOpa,fillOpa);vStrokeColor=vec4(getScaled_stroke()*strokeOpa,strokeOpa);setupPicking();}";
|
|
1
|
+
const shader = "out float vRadius;out float vRadiusWithPadding;out lowp vec4 vFillColor;out lowp vec4 vStrokeColor;out lowp float vShape;out lowp float vHalfStrokeWidth;out mat2 vRotationMatrix;const float CIRCLE=0.0;const float SQUARE=1.0;const float CROSS=2.0;const float DIAMOND=3.0;const float TRIANGLE_UP=4.0;const float TRIANGLE_RIGHT=5.0;const float TRIANGLE_DOWN=6.0;const float TRIANGLE_LEFT=7.0;const float TICK_UP=8.0;const float TICK_RIGHT=9.0;const float TICK_DOWN=10.0;const float TICK_LEFT=11.0;float computeSemanticThresholdFactor(){return getScaled_semanticScore()>=uSemanticThreshold ? 1.0 : 0.0;}vec2 getDxDy(){\n#if defined(dx_DEFINED) || defined(dy_DEFINED)\nreturn vec2(getScaled_dx(),getScaled_dy())/uViewportSize;\n#else\nreturn vec2(0.0,0.0);\n#endif\n}void main(void){float shapeAngle=0.0;float semanticThresholdFactor=isPointSelected()? 1.0: computeSemanticThresholdFactor();if(semanticThresholdFactor<=0.0){gl_PointSize=0.0;gl_Position=vec4(100.0,0.0,0.0,0.0);return;}float size=getScaled_size();vec2 pos=vec2(getScaled_x(),getScaled_y())+getDxDy();gl_Position=unitToNdc(applySampleFacet(pos));float strokeWidth=getScaled_strokeWidth();float diameter=sqrt(size)*uScaleFactor*semanticThresholdFactor;float opacity=uViewOpacity;if(strokeWidth<=0.0||uInwardStroke){float minDiameter=1.0/uDevicePixelRatio;if(diameter<minDiameter){opacity*=pow(diameter/minDiameter,2.5);diameter=minDiameter;}}float fillOpa=getScaled_fillOpacity()*opacity;float strokeOpa=getScaled_strokeOpacity()*opacity;vShape=getScaled_shape();bool circle=vShape==0.0;if(vShape>TICK_UP&&vShape<=TICK_LEFT){shapeAngle=(vShape-TICK_UP)*90.0;vShape=TICK_UP;}else if(vShape>TRIANGLE_UP&&vShape<=TRIANGLE_LEFT){shapeAngle=(vShape-TRIANGLE_UP)*90.0;vShape=TRIANGLE_UP;}float angleInDegrees=getScaled_angle();float angle=-(shapeAngle+angleInDegrees)*PI/180.0;float sinTheta=sin(angle);float cosTheta=cos(angle);vRotationMatrix=mat2(cosTheta,sinTheta,-sinTheta,cosTheta);float roomForRotation=circle ? 1.0 : sin(mod(angle,PI/2.0)+PI/4.0)/sin(PI/4.0);float aaPadding=1.0/uDevicePixelRatio;float rotationPadding=(diameter*roomForRotation)-diameter;float strokePadding=uInwardStroke ? 0.0 : strokeWidth*(circle ? 1.0 : sqrt(3.0));float padding=rotationPadding+strokePadding+aaPadding;gl_PointSize=max((diameter+padding),uPickingEnabled ? uMinPickingSize : 0.0)*uDevicePixelRatio;vRadius=diameter/2.0;vRadiusWithPadding=vRadius+padding/2.0;vHalfStrokeWidth=strokeWidth/2.0;vFillColor=vec4(getScaled_fill()*fillOpa,fillOpa);vStrokeColor=vec4(getScaled_stroke()*strokeOpa,strokeOpa);setupPicking();}";
|
|
2
2
|
export default shader;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const shader = "layout(std140)uniform Mark{uniform float uMinWidth;uniform float uMinHeight;uniform float uMinOpacity;uniform float uCornerRadiusTopRight;uniform float uCornerRadiusBottomRight;uniform float uCornerRadiusTopLeft;uniform float uCornerRadiusBottomLeft;\n#pragma markUniforms\n};";
|
|
1
|
+
const shader = "layout(std140)uniform Mark{uniform float uMinWidth;uniform float uMinHeight;uniform float uMinOpacity;uniform float uCornerRadiusTopRight;uniform float uCornerRadiusBottomRight;uniform float uCornerRadiusTopLeft;uniform float uCornerRadiusBottomLeft;uniform int uHatchPattern;uniform vec3 uShadowColor;uniform float uShadowOpacity;uniform float uShadowBlur;uniform float uShadowOffsetX;uniform float uShadowOffsetY;\n#pragma markUniforms\n};";
|
|
2
2
|
export default shader;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rect.d.ts","sourceRoot":"","sources":["../../../src/marks/rect.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rect.d.ts","sourceRoot":"","sources":["../../../src/marks/rect.js"],"names":[],"mappings":"AA2BA;;GAEG;AACH;IACI;;OAEG;IACH,sBAFW,OAAO,qBAAqB,EAAE,OAAO,EAkB/C;IAkOD;;;;;;;;;;OAUG;IACH,8BALW,GAAG,KACH,OAAO,oBAAoB,EAAE,MAAM,GACjC,GAAG,CAyBf;;CACJ;iBAhTgB,WAAW"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const shader = "#if defined(ROUNDED_CORNERS) || defined(STROKED)\nin vec2 vPosInPixels;\n#endif\nin vec2 vHalfSizeInPixels;in lowp vec4 vFillColor;in lowp vec4 vStrokeColor;in float vHalfStrokeWidth;in vec4 vCornerRadii;out lowp vec4 fragColor;float sdRoundedBox(vec2 p,vec2 b,vec4 r){r.xy=p.x>0.0 ? r.xy : r.zw;r.x=p.y>0.0 ? r.x : r.y;vec2 q=abs(p)-b+r.x;return min(max(q.x,q.y),0.0)+length(max(q,0.0))-r.x;}float sdSharpBox(vec2 p,vec2 b){vec2 q=abs(p)-b;return max(q.x,q.y);}void main(void){\n#if defined(ROUNDED_CORNERS) || defined(STROKED)\n#ifdef ROUNDED_CORNERS\nfloat d=sdRoundedBox(vPosInPixels,vHalfSizeInPixels,vCornerRadii);\n#else\nfloat d=sdSharpBox(vPosInPixels,vHalfSizeInPixels);\n#endif\
|
|
1
|
+
const shader = "#if defined(ROUNDED_CORNERS) || defined(STROKED) || defined(SHADOW)\nin vec2 vPosInPixels;\n#endif\nin vec2 vHalfSizeInPixels;in lowp vec4 vFillColor;in lowp vec4 vStrokeColor;in float vHalfStrokeWidth;in vec4 vCornerRadii;out lowp vec4 fragColor;\n#ifdef SHADOW\nfloat gaussian(float x,float sigma){const float pi=3.141592653589793;return exp(-(x*x)/(2.0*sigma*sigma))/(sqrt(2.0*pi)*sigma);}vec2 erf(vec2 x){vec2 s=sign(x),a=abs(x);x=1.0+(0.278393+(0.230389+0.078108*(a*a))*a)*a;x*=x;return s-s/(x*x);}float roundedBoxShadowX(float x,float y,float sigma,float corner,vec2 halfSize){float delta=min(halfSize.y-corner-abs(y),0.0);float curved=halfSize.x-corner+sqrt(max(0.0,corner*corner-delta*delta));vec2 integral=0.5+0.5*erf((x+vec2(-curved,curved))*(sqrt(0.5)/sigma));return integral.y-integral.x;}float roundedBoxShadow(vec2 lower,vec2 upper,vec2 point,float sigma,float corner){vec2 center=(lower+upper)*0.5;vec2 halfSize=(upper-lower)*0.5;point-=center;float low=point.y-halfSize.y;float high=point.y+halfSize.y;float start=clamp(-3.0*sigma,low,high);float end=clamp(3.0*sigma,low,high);float step=(end-start)/4.0;float y=start+step*0.5;float value=0.0;for(int i=0;i<4;i++){value+=roundedBoxShadowX(point.x,point.y-y,sigma,corner,halfSize)*gaussian(y,sigma)*step;y+=step;}return value;}\n#endif\nfloat sdRoundedBox(vec2 p,vec2 b,vec4 r){r.xy=p.x>0.0 ? r.xy : r.zw;r.x=p.y>0.0 ? r.x : r.y;vec2 q=abs(p)-b+r.x;return min(max(q.x,q.y),0.0)+length(max(q,0.0))-r.x;}float sdSharpBox(vec2 p,vec2 b){vec2 q=abs(p)-b;return max(q.x,q.y);}float diagonalPattern(vec2 uv,float spacing){float divisor=spacing*vHalfStrokeWidth*2.0*1.5;return abs(mod(uv.x-uv.y,divisor)-0.5*divisor)/1.5;}float verticalPattern(float x,float spacing){float divisor=spacing*vHalfStrokeWidth*2.0;return abs(mod(x,divisor))/2.0;}float circle(vec2 p,float r){return length(p)-r;}float masonryCirclePattern(vec2 uv,float spacing,float radius){float halfSpacing=0.5*spacing;float row=floor(uv.y/spacing);float shift=mod(row,2.0)*halfSpacing;vec2 shifted=vec2(uv.x+shift,uv.y+halfSpacing);vec2 cell=mod(shifted+0.5*spacing,spacing)-halfSpacing;return abs(circle(cell,radius));}/***Patterns:*0 none*1 diagonal(/)*2 antiDiagonal(\\)*3 cross(X)*4 vertical(|)*5 horizontal(-)*6 grid(+)*7 dots(.)*8 rings(o)*9 ringsLarge(O)*/float pattern(){\n#ifdef STROKED\nint patternType=uHatchPattern;vec2 uv=vPosInPixels;float spacing=4.0;switch(patternType){case 1:return diagonalPattern(vec2(uv.x,-uv.y),spacing);case 2:return diagonalPattern(uv,spacing);case 3:return min(diagonalPattern(uv,spacing),diagonalPattern(vec2(uv.x,-uv.y),spacing));case 4:return verticalPattern(uv.x,spacing);case 5:return verticalPattern(uv.y,spacing);case 6:return min(verticalPattern(uv.x,spacing),verticalPattern(uv.y,spacing));case 7:case 8:case 9:{float spacing=vHalfStrokeWidth*14.0;float radius=spacing*(patternType==8 ? 0.2 :patternType==9 ? 0.35 :0.07);return masonryCirclePattern(uv,spacing,radius);}default:break;}\n#endif\nreturn 1.0/0.0;}void main(void){\n#if defined(ROUNDED_CORNERS) || defined(STROKED) || defined(SHADOW)\n#ifdef ROUNDED_CORNERS\nfloat d=sdRoundedBox(vPosInPixels,vHalfSizeInPixels,vCornerRadii);\n#else\nfloat d=sdSharpBox(vPosInPixels,vHalfSizeInPixels);\n#endif\nvec4 backgroundColor=vec4(0.0,0.0,0.0,0.0);\n#ifdef SHADOW\nfloat maxCornerRadius=max(vCornerRadii.x,max(vCornerRadii.y,max(vCornerRadii.z,vCornerRadii.w)));float shadow=0.0;if(d>=vHalfStrokeWidth-1.0&&uShadowOpacity>0.0){shadow=roundedBoxShadow(-vHalfSizeInPixels-vHalfStrokeWidth,vHalfSizeInPixels+vHalfStrokeWidth,vPosInPixels-vec2(uShadowOffsetX,-uShadowOffsetY),max(uShadowBlur/2.5,0.25),maxCornerRadius+vHalfStrokeWidth)*uShadowOpacity*uViewOpacity;}backgroundColor=vec4(uShadowColor*shadow,shadow);\n#endif\nif(vHalfStrokeWidth>0.0&&uHatchPattern>0){d=max(d,-pattern());}fragColor=distanceToColor(d,vFillColor,vStrokeColor,backgroundColor,vHalfStrokeWidth);if(uPickingEnabled){if(d<vHalfStrokeWidth){fragColor=vPickingColor;}}else if(fragColor.a==0.0){discard;}\n#else\nfragColor=vFillColor;if(uPickingEnabled){fragColor=vPickingColor;}\n#endif\n}";
|
|
2
2
|
export default shader;
|
package/dist/src/marks/rect.js
CHANGED
|
@@ -10,6 +10,20 @@ import { asArray } from "../utils/arrayUtils.js";
|
|
|
10
10
|
import { isValueDef } from "../encoder/encoder.js";
|
|
11
11
|
import { getCachedOrCall } from "../utils/propertyCacher.js";
|
|
12
12
|
import { isDiscrete } from "vega-scale";
|
|
13
|
+
import { cssColorToArray } from "../gl/colorUtils.js";
|
|
14
|
+
|
|
15
|
+
const hatchPatterns = [
|
|
16
|
+
"none",
|
|
17
|
+
"diagonal",
|
|
18
|
+
"antiDiagonal",
|
|
19
|
+
"cross",
|
|
20
|
+
"vertical",
|
|
21
|
+
"horizontal",
|
|
22
|
+
"grid",
|
|
23
|
+
"dots",
|
|
24
|
+
"rings",
|
|
25
|
+
"ringsLarge",
|
|
26
|
+
];
|
|
13
27
|
|
|
14
28
|
/**
|
|
15
29
|
* @extends {Mark<import("../spec/mark.js").RectProps>}
|
|
@@ -79,6 +93,7 @@ export default class RectMark extends Mark {
|
|
|
79
93
|
() =>
|
|
80
94
|
!this.#isRoundedCorners() &&
|
|
81
95
|
!this.#isStroked() &&
|
|
96
|
+
!this.properties.shadowOpacity &&
|
|
82
97
|
isValueDef(this.encoding.fillOpacity) &&
|
|
83
98
|
this.encoding.fillOpacity.value == 1.0 &&
|
|
84
99
|
this.properties.minOpacity == 1.0
|
|
@@ -141,6 +156,9 @@ export default class RectMark extends Mark {
|
|
|
141
156
|
if (this.#isStroked()) {
|
|
142
157
|
defines.push("STROKED");
|
|
143
158
|
}
|
|
159
|
+
if (this.properties.shadowOpacity) {
|
|
160
|
+
defines.push("SHADOW");
|
|
161
|
+
}
|
|
144
162
|
|
|
145
163
|
this.createAndLinkShaders(VERTEX_SHADER, FRAGMENT_SHADER, [
|
|
146
164
|
COMMON_SHADER,
|
|
@@ -174,6 +192,29 @@ export default class RectMark extends Mark {
|
|
|
174
192
|
"uCornerRadiusBottomLeft",
|
|
175
193
|
props.cornerRadiusBottomLeft ?? props.cornerRadius ?? 0
|
|
176
194
|
);
|
|
195
|
+
|
|
196
|
+
this.registerMarkUniformValue("uHatchPattern", props.hatch, (x) =>
|
|
197
|
+
Math.max(0, hatchPatterns.indexOf(x ?? "none"))
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
this.registerMarkUniformValue("uShadowBlur", props.shadowBlur ?? 0);
|
|
201
|
+
this.registerMarkUniformValue(
|
|
202
|
+
"uShadowOpacity",
|
|
203
|
+
props.shadowOpacity ?? 0
|
|
204
|
+
);
|
|
205
|
+
this.registerMarkUniformValue(
|
|
206
|
+
"uShadowOffsetX",
|
|
207
|
+
props.shadowOffsetX ?? 0
|
|
208
|
+
);
|
|
209
|
+
this.registerMarkUniformValue(
|
|
210
|
+
"uShadowOffsetY",
|
|
211
|
+
props.shadowOffsetY ?? 0
|
|
212
|
+
);
|
|
213
|
+
this.registerMarkUniformValue(
|
|
214
|
+
"uShadowColor",
|
|
215
|
+
props.shadowColor ?? "black",
|
|
216
|
+
cssColorToArray
|
|
217
|
+
);
|
|
177
218
|
}
|
|
178
219
|
|
|
179
220
|
updateGraphicsData() {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const shader = "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,uCornerRadiusTopLeft,uCornerRadiusBottomLeft);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();}";
|
|
1
|
+
const shader = "out lowp vec4 vFillColor;out lowp vec4 vStrokeColor;out float vHalfStrokeWidth;out vec4 vCornerRadii;\n#if defined(ROUNDED_CORNERS) || defined(STROKED) || defined(SHADOW)\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,uCornerRadiusTopLeft,uCornerRadiusBottomLeft);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) || defined(SHADOW)\nfloat aaPadding=1.0/uDevicePixelRatio;float shadowPadding=uShadowBlur+max(abs(uShadowOffsetX),abs(uShadowOffsetY));float strokeWidth=getScaled_strokeWidth();float strokeOpacity=getScaled_strokeOpacity()*opaFactor;vec2 centeredFrac=frac-0.5;vec2 expand=centeredFrac*(strokeWidth+aaPadding+shadowPadding*2.0)/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
2
|
export default shader;
|
|
@@ -8,6 +8,12 @@ export function createSinglePointSelection(datum: import("../data/flowNode.js").
|
|
|
8
8
|
* @returns {import("../types/selectionTypes.js").MultiPointSelection}
|
|
9
9
|
*/
|
|
10
10
|
export function createMultiPointSelection(data?: import("../data/flowNode.js").Datum[]): import("../types/selectionTypes.js").MultiPointSelection;
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param {import("../spec/channel.js").ChannelWithScale[]} channels
|
|
14
|
+
* @returns {import("../types/selectionTypes.js").IntervalSelection}
|
|
15
|
+
*/
|
|
16
|
+
export function createIntervalSelection(channels: import("../spec/channel.js").ChannelWithScale[]): import("../types/selectionTypes.js").IntervalSelection;
|
|
11
17
|
/**
|
|
12
18
|
* Updates the backing data and returns a new instance of the selection object.
|
|
13
19
|
* A new instance is required to trigger reactivity in parameters.
|
|
@@ -32,9 +38,9 @@ export function makeSelectionTestExpression(params: {
|
|
|
32
38
|
}): string;
|
|
33
39
|
/**
|
|
34
40
|
* @param {import("../types/selectionTypes.js").Selection} selection
|
|
35
|
-
* @returns {selection is import("../types/selectionTypes.js").
|
|
41
|
+
* @returns {selection is import("../types/selectionTypes.js").IntervalSelection}
|
|
36
42
|
*/
|
|
37
|
-
export function
|
|
43
|
+
export function isIntervalSelection(selection: import("../types/selectionTypes.js").Selection): selection is import("../types/selectionTypes.js").IntervalSelection;
|
|
38
44
|
/**
|
|
39
45
|
* @param {import("../types/selectionTypes.js").Selection} selection
|
|
40
46
|
* @returns {selection is import("../types/selectionTypes.js").SinglePointSelection}
|
|
@@ -60,4 +66,23 @@ export function asSelectionConfig(typeOrConfig: import("../spec/parameter.js").S
|
|
|
60
66
|
* @returns {config is import("../spec/parameter.js").PointSelectionConfig}
|
|
61
67
|
*/
|
|
62
68
|
export function isPointSelectionConfig(config: import("../spec/parameter.js").SelectionConfig): config is import("../spec/parameter.js").PointSelectionConfig;
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
* @param {import("../spec/parameter.js").SelectionConfig} config
|
|
72
|
+
* @returns {config is import("../spec/parameter.js").IntervalSelectionConfig}
|
|
73
|
+
*/
|
|
74
|
+
export function isIntervalSelectionConfig(config: import("../spec/parameter.js").SelectionConfig): config is import("../spec/parameter.js").IntervalSelectionConfig;
|
|
75
|
+
/**
|
|
76
|
+
* @param {import("../types/selectionTypes.js").IntervalSelection} selection
|
|
77
|
+
*/
|
|
78
|
+
export function isActiveIntervalSelection(selection: import("../types/selectionTypes.js").IntervalSelection): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* @typedef {import("../types/selectionTypes.js").IntervalSelection} IntervalSelection
|
|
81
|
+
* @typedef {Partial<Record<keyof IntervalSelection["intervals"], number>>} IntervalPoint
|
|
82
|
+
* @param {IntervalSelection} selection
|
|
83
|
+
* @param {IntervalPoint} point
|
|
84
|
+
*/
|
|
85
|
+
export function selectionContainsPoint(selection: IntervalSelection, point: IntervalPoint): boolean;
|
|
86
|
+
export type IntervalSelection = import("../types/selectionTypes.js").IntervalSelection;
|
|
87
|
+
export type IntervalPoint = Partial<Record<keyof IntervalSelection["intervals"], number>>;
|
|
63
88
|
//# sourceMappingURL=selection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/selection/selection.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH,kDAHW,OAAO,qBAAqB,EAAE,KAAK,GACjC,OAAO,4BAA4B,EAAE,oBAAoB,CAQrE;AAED;;;GAGG;AACH,iDAHW,OAAO,qBAAqB,EAAE,KAAK,EAAE,GACnC,OAAO,4BAA4B,EAAE,mBAAmB,CAQpE;AAED;;;;;;;GAOG;AACH,qDAJW,OAAO,4BAA4B,EAAE,mBAAmB,2BACxD,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,QAAQ,GAAG,QAAQ,EAAE,QAAQ,CAAC,OAAO,qBAAqB,EAAE,KAAK,CAAC,CAAC,CAAC,GACzF,OAAO,4BAA4B,EAAE,mBAAmB,CA2BpE;AAED;;;;GAIG;AACH,yCAJW,OAAO,4BAA4B,EAAE,SAAS,SAC9C,OAAO,qBAAqB,EAAE,KAAK,UACnC,OAAO,
|
|
1
|
+
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/selection/selection.js"],"names":[],"mappings":"AAGA;;;GAGG;AACH,kDAHW,OAAO,qBAAqB,EAAE,KAAK,GACjC,OAAO,4BAA4B,EAAE,oBAAoB,CAQrE;AAED;;;GAGG;AACH,iDAHW,OAAO,qBAAqB,EAAE,KAAK,EAAE,GACnC,OAAO,4BAA4B,EAAE,mBAAmB,CAQpE;AAED;;;;GAIG;AACH,kDAHW,OAAO,oBAAoB,EAAE,gBAAgB,EAAE,GAC7C,OAAO,4BAA4B,EAAE,iBAAiB,CASlE;AAED;;;;;;;GAOG;AACH,qDAJW,OAAO,4BAA4B,EAAE,mBAAmB,2BACxD,OAAO,CAAC,MAAM,CAAC,KAAK,GAAG,QAAQ,GAAG,QAAQ,EAAE,QAAQ,CAAC,OAAO,qBAAqB,EAAE,KAAK,CAAC,CAAC,CAAC,GACzF,OAAO,4BAA4B,EAAE,mBAAmB,CA2BpE;AAED;;;;GAIG;AACH,yCAJW,OAAO,4BAA4B,EAAE,SAAS,SAC9C,OAAO,qBAAqB,EAAE,KAAK,UACnC,OAAO,WAoBjB;AAED;;GAEG;AACH,oDAFW;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAC,UAM1C;AAED;;;GAGG;AACH,+CAHW,OAAO,4BAA4B,EAAE,SAAS,GAC5C,SAAS,IAAI,OAAO,4BAA4B,EAAE,iBAAiB,CAI/E;AAED;;;GAGG;AACH,kDAHW,OAAO,4BAA4B,EAAE,SAAS,GAC5C,SAAS,IAAI,OAAO,4BAA4B,EAAE,oBAAoB,CAIlF;AAED;;;GAGG;AACH,iDAHW,OAAO,4BAA4B,EAAE,SAAS,GAC5C,SAAS,IAAI,OAAO,4BAA4B,EAAE,mBAAmB,CAIjF;AAED;;;GAGG;AACH,gDAHW,OAAO,4BAA4B,EAAE,SAAS,GAC5C,SAAS,IAAI,OAAO,4BAA4B,EAAE,kBAAkB,CAIhF;AAED;;;GAGG;AACH,gDAHW,OAAO,sBAAsB,EAAE,qBAAqB,GAClD,OAAO,sBAAsB,EAAE,eAAe,CAiB1D;AAED;;;GAGG;AACH,+CAHW,OAAO,sBAAsB,EAAE,eAAe,GAC5C,MAAM,IAAI,OAAO,sBAAsB,EAAE,oBAAoB,CAIzE;AAED;;;;GAIG;AACH,kDAHW,OAAO,sBAAsB,EAAE,eAAe,GAC5C,MAAM,IAAI,OAAO,sBAAsB,EAAE,uBAAuB,CAI5E;AAED;;GAEG;AACH,qDAFW,OAAO,4BAA4B,EAAE,iBAAiB,WAMhE;AAED;;;;;GAKG;AACH,kDAHW,iBAAiB,SACjB,aAAa,WAUvB;gCAbY,OAAO,4BAA4B,EAAE,iBAAiB;4BACtD,OAAO,CAAC,MAAM,CAAC,MAAM,iBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC"}
|