@vitessce/neuroglancer 3.9.6 → 3.9.8

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.
@@ -88,7 +88,7 @@ export function toNgLayerName(dataType, layerScope, channelScope = null) {
88
88
  /**
89
89
  * @returns [viewerState]
90
90
  */
91
- export function useNeuroglancerViewerState(theme, segmentationLayerScopes, segmentationChannelScopesByLayer, segmentationLayerCoordination, segmentationChannelCoordination, obsSegmentationsUrls, obsSegmentationsData, pointLayerScopes, pointLayerCoordination, obsPointsUrls, obsPointsData, pointMultiIndicesData) {
91
+ export function useNeuroglancerViewerState(theme, showAxisLines, segmentationLayerScopes, segmentationChannelScopesByLayer, segmentationLayerCoordination, segmentationChannelCoordination, obsSegmentationsUrls, obsSegmentationsData, pointLayerScopes, pointLayerCoordination, obsPointsUrls, obsPointsData, pointMultiIndicesData) {
92
92
  const viewerState = useMemoCustomComparison(() => {
93
93
  let result = cloneDeep(DEFAULT_NG_PROPS);
94
94
  // ======= SEGMENTATIONS =======
@@ -103,20 +103,32 @@ export function useNeuroglancerViewerState(theme, segmentationLayerScopes, segme
103
103
  channelScopes.forEach((channelScope) => {
104
104
  const channelCoordination = segmentationChannelCoordination[0]?.[layerScope]?.[channelScope];
105
105
  const { spatialChannelVisible, } = channelCoordination || {};
106
+ const { source: ngSource, ...otherNgOptions } = layerData.neuroglancerOptions ?? {};
107
+ // Build source: if neuroglancerOptions has subsources
108
+ const hasNgSourceOptions = layerData.neuroglancerOptions?.subsources
109
+ || layerData.neuroglancerOptions?.enableDefaultSubsources !== undefined;
110
+ const source = hasNgSourceOptions
111
+ ? {
112
+ url: toPrecomputedSource(layerUrl),
113
+ subsources: layerData.neuroglancerOptions.subsources,
114
+ enableDefaultSubsources: layerData.neuroglancerOptions.enableDefaultSubsources
115
+ ?? false,
116
+ }
117
+ : toPrecomputedSource(layerUrl);
106
118
  result = {
107
119
  ...result,
108
120
  layers: [
109
121
  ...result.layers,
110
122
  {
111
123
  type: 'segmentation',
112
- source: toPrecomputedSource(layerUrl),
124
+ source,
113
125
  segments: [],
114
126
  name: toNgLayerName(DataType.OBS_SEGMENTATIONS, layerScope, channelScope),
115
127
  visible: spatialLayerVisible && spatialChannelVisible, // Both layer and channel
116
128
  // visibility must be true for the layer to be visible.
117
129
  // TODO: update this to extract specific properties from
118
130
  // neuroglancerOptions as needed.
119
- ...(layerData.neuroglancerOptions ?? {}),
131
+ ...otherNgOptions,
120
132
  },
121
133
  ],
122
134
  };
@@ -131,7 +143,7 @@ export function useNeuroglancerViewerState(theme, segmentationLayerScopes, segme
131
143
  const layerUrl = obsPointsUrls[layerScope]?.[0]?.url;
132
144
  const featureIndex = pointMultiIndicesData[layerScope]?.featureIndex;
133
145
  if (layerUrl && layerData) {
134
- const { spatialLayerVisible, spatialLayerOpacity, obsColorEncoding, spatialLayerColor, featureSelection, featureFilterMode, featureColor, } = layerCoordination || {};
146
+ const { spatialLayerVisible, spatialLayerOpacity, obsColorEncoding, spatialLayerColor, featureSelection, featureFilterMode, featureColor, spatialPointStrokeWidth, } = layerCoordination || {};
135
147
  // Dynamically construct the shader based on the color encoding
136
148
  // and other coordination values.
137
149
  const shader = getPointsShader({
@@ -145,6 +157,7 @@ export function useNeuroglancerViewerState(theme, segmentationLayerScopes, segme
145
157
  featureColor,
146
158
  featureIndexProp: layerData.neuroglancerOptions?.featureIndexProp,
147
159
  pointIndexProp: layerData.neuroglancerOptions?.pointIndexProp,
160
+ pointMarkerBorderWidth: spatialPointStrokeWidth ?? 0.0,
148
161
  });
149
162
  result = {
150
163
  ...result,
@@ -182,6 +195,7 @@ export function useNeuroglancerViewerState(theme, segmentationLayerScopes, segme
182
195
  return result;
183
196
  }, {
184
197
  theme,
198
+ showAxisLines,
185
199
  segmentationLayerScopes,
186
200
  segmentationChannelScopesByLayer,
187
201
  segmentationLayerCoordination,
@@ -5,7 +5,7 @@
5
5
  * @param {number} opacity Opacity (0-1).
6
6
  * @returns {string} A GLSL shader string.
7
7
  */
8
- export function getSpatialLayerColorShader(staticColor: [number, number, number], opacity: number): string;
8
+ export function getSpatialLayerColorShader(staticColor: [number, number, number], opacity: number, borderWidth?: number): string;
9
9
  /**
10
10
  * Generate a shader for spatialLayerColor encoding with feature selection.
11
11
  * Selected features get the static color; unselected get the default color.
@@ -16,7 +16,7 @@ export function getSpatialLayerColorShader(staticColor: [number, number, number]
16
16
  * @param {string} featureIndexProp The property name for the feature index in the shader.
17
17
  * @returns {string} A GLSL shader string.
18
18
  */
19
- export function getSpatialLayerColorWithSelectionShader(staticColor: [number, number, number], opacity: number, featureIndices: number[], defaultColor: [number, number, number], featureIndexProp: string): string;
19
+ export function getSpatialLayerColorWithSelectionShader(staticColor: [number, number, number], opacity: number, featureIndices: number[], defaultColor: [number, number, number], featureIndexProp: string, borderWidth?: number): string;
20
20
  /**
21
21
  * Generate a shader for spatialLayerColor encoding with feature selection
22
22
  * and featureFilterMode='featureSelection' (hide unselected points).
@@ -26,7 +26,7 @@ export function getSpatialLayerColorWithSelectionShader(staticColor: [number, nu
26
26
  * @param {string} featureIndexProp The property name for the feature index in the shader.
27
27
  * @returns {string} A GLSL shader string.
28
28
  */
29
- export function getSpatialLayerColorFilteredShader(staticColor: [number, number, number], opacity: number, featureIndices: number[], featureIndexProp: string): string;
29
+ export function getSpatialLayerColorFilteredShader(staticColor: [number, number, number], opacity: number, featureIndices: number[], featureIndexProp: string, borderWidth?: number): string;
30
30
  /**
31
31
  * Generate a shader for geneSelection encoding with no feature selection.
32
32
  * All points get the static color (since no features are selected to
@@ -35,7 +35,7 @@ export function getSpatialLayerColorFilteredShader(staticColor: [number, number,
35
35
  * @param {number} opacity Opacity (0-1).
36
36
  * @returns {string} A GLSL shader string.
37
37
  */
38
- export function getGeneSelectionNoSelectionShader(staticColor: [number, number, number], opacity: number): string;
38
+ export function getGeneSelectionNoSelectionShader(staticColor: [number, number, number], opacity: number, borderWidth?: number): string;
39
39
  /**
40
40
  * Generate a shader for geneSelection encoding with feature selection.
41
41
  * Each selected feature gets its color from featureColor; unselected
@@ -51,7 +51,7 @@ export function getGeneSelectionNoSelectionShader(staticColor: [number, number,
51
51
  * @param {string} featureIndexProp The property name for the feature index in the shader.
52
52
  * @returns {string} A GLSL shader string.
53
53
  */
54
- export function getGeneSelectionWithSelectionShader(featureIndices: number[], featureColors: [number, number, number][], staticColor: [number, number, number], defaultColor: [number, number, number], opacity: number, featureIndexProp: string): string;
54
+ export function getGeneSelectionWithSelectionShader(featureIndices: number[], featureColors: [number, number, number][], staticColor: [number, number, number], defaultColor: [number, number, number], opacity: number, featureIndexProp: string, borderWidth?: number): string;
55
55
  /**
56
56
  * Generate a shader for geneSelection encoding with feature selection
57
57
  * and featureFilterMode='featureSelection' (hide unselected points).
@@ -63,7 +63,7 @@ export function getGeneSelectionWithSelectionShader(featureIndices: number[], fe
63
63
  * @param {string} featureIndexProp The property name for the feature index in the shader.
64
64
  * @returns {string} A GLSL shader string.
65
65
  */
66
- export function getGeneSelectionFilteredShader(featureIndices: number[], featureColors: [number, number, number][], staticColor: [number, number, number], opacity: number, featureIndexProp: string): string;
66
+ export function getGeneSelectionFilteredShader(featureIndices: number[], featureColors: [number, number, number][], staticColor: [number, number, number], opacity: number, featureIndexProp: string, borderWidth?: number): string;
67
67
  /**
68
68
  * Generate a shader for randomByFeature encoding with no feature selection.
69
69
  * Each feature gets a deterministic color from PALETTE based on its index.
@@ -71,7 +71,7 @@ export function getGeneSelectionFilteredShader(featureIndices: number[], feature
71
71
  * @param {string} featureIndexProp The property name for the feature index in the shader.
72
72
  * @returns {string} A GLSL shader string.
73
73
  */
74
- export function getRandomByFeatureShader(opacity: number, featureIndexProp: string): string;
74
+ export function getRandomByFeatureShader(opacity: number, featureIndexProp: string, borderWidth?: number): string;
75
75
  /**
76
76
  * Generate a shader for randomByFeature encoding with feature selection.
77
77
  * Selected features get their deterministic palette color; unselected
@@ -82,7 +82,7 @@ export function getRandomByFeatureShader(opacity: number, featureIndexProp: stri
82
82
  * @param {string} featureIndexProp The property name for the feature index in the shader.
83
83
  * @returns {string} A GLSL shader string.
84
84
  */
85
- export function getRandomByFeatureWithSelectionShader(featureIndices: number[], defaultColor: [number, number, number], opacity: number, featureIndexProp: string): string;
85
+ export function getRandomByFeatureWithSelectionShader(featureIndices: number[], defaultColor: [number, number, number], opacity: number, featureIndexProp: string, borderWidth?: number): string;
86
86
  /**
87
87
  * Generate a shader for randomByFeature encoding with feature selection
88
88
  * and featureFilterMode='featureSelection' (hide unselected points).
@@ -91,7 +91,7 @@ export function getRandomByFeatureWithSelectionShader(featureIndices: number[],
91
91
  * @param {string} featureIndexProp The property name for the feature index in the shader.
92
92
  * @returns {string} A GLSL shader string.
93
93
  */
94
- export function getRandomByFeatureFilteredShader(featureIndices: number[], opacity: number, featureIndexProp: string): string;
94
+ export function getRandomByFeatureFilteredShader(featureIndices: number[], opacity: number, featureIndexProp: string, borderWidth?: number): string;
95
95
  /**
96
96
  * Generate a shader for random-per-point encoding with no feature selection.
97
97
  * Each point gets a pseudo-random color based on its index.
@@ -100,7 +100,7 @@ export function getRandomByFeatureFilteredShader(featureIndices: number[], opaci
100
100
  * @param {string} pointIndexProp The property name for the point index in the shader.
101
101
  * @returns {string} A GLSL shader string.
102
102
  */
103
- export function getRandomPerPointShader(opacity: number, featureIndexProp: string, pointIndexProp: string): string;
103
+ export function getRandomPerPointShader(opacity: number, featureIndexProp: string, pointIndexProp: string, borderWidth?: number): string;
104
104
  /**
105
105
  * Generate a shader for random-per-point encoding with feature selection.
106
106
  * Selected points get a pseudo-random color; unselected get the default color.
@@ -111,7 +111,7 @@ export function getRandomPerPointShader(opacity: number, featureIndexProp: strin
111
111
  * @param {string} pointIndexProp The property name for the point index in the shader.
112
112
  * @returns {string} A GLSL shader string.
113
113
  */
114
- export function getRandomPerPointWithSelectionShader(featureIndices: number[], defaultColor: [number, number, number], opacity: number, featureIndexProp: string, pointIndexProp: string): string;
114
+ export function getRandomPerPointWithSelectionShader(featureIndices: number[], defaultColor: [number, number, number], opacity: number, featureIndexProp: string, pointIndexProp: string, borderWidth?: number): string;
115
115
  /**
116
116
  * Generate a shader for random-per-point encoding with feature selection
117
117
  * and featureFilterMode='featureSelection' (hide unselected points).
@@ -121,6 +121,6 @@ export function getRandomPerPointWithSelectionShader(featureIndices: number[], d
121
121
  * @param {string} pointIndexProp The property name for the point index in the shader.
122
122
  * @returns {string} A GLSL shader string.
123
123
  */
124
- export function getRandomPerPointFilteredShader(featureIndices: number[], opacity: number, featureIndexProp: string, pointIndexProp: string): string;
124
+ export function getRandomPerPointFilteredShader(featureIndices: number[], opacity: number, featureIndexProp: string, pointIndexProp: string, borderWidth?: number): string;
125
125
  export function getPointsShader(layerCoordination: any): string;
126
126
  //# sourceMappingURL=shader-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shader-utils.d.ts","sourceRoot":"","sources":["../src/shader-utils.js"],"names":[],"mappings":"AAwCA;;;;;;GAMG;AACH,wDAJW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,GACJ,MAAM,CAUlB;AAGD;;;;;;;;;GASG;AACH,qEAPW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,kBACN,MAAM,EAAE,gBACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,oBACxB,MAAM,GACJ,MAAM,CA4BlB;AAGD;;;;;;;;GAQG;AACH,gEANW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,kBACN,MAAM,EAAE,oBACR,MAAM,GACJ,MAAM,CA0BlB;AAMD;;;;;;;GAOG;AACH,+DAJW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;;;;;;;;;GAcG;AACH,oEAXW,MAAM,EAAE,iBACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAE1B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,gBAExB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WAExB,MAAM,oBACN,MAAM,GACJ,MAAM,CA+BlB;AAED;;;;;;;;;;GAUG;AACH,+DARW,MAAM,EAAE,iBACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAE1B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,oBACN,MAAM,GACJ,MAAM,CAoClB;AAMD;;;;;;GAMG;AACH,kDAJW,MAAM,oBACN,MAAM,GACJ,MAAM,CAkBlB;AAED;;;;;;;;;GASG;AACH,sEANW,MAAM,EAAE,gBACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,oBACN,MAAM,GACJ,MAAM,CAkClB;AAED;;;;;;;GAOG;AACH,iEALW,MAAM,EAAE,WACR,MAAM,oBACN,MAAM,GACJ,MAAM,CA8BlB;AAuBD;;;;;;;GAOG;AACH,iDALW,MAAM,oBACN,MAAM,kBACN,MAAM,GACJ,MAAM,CAelB;AAED;;;;;;;;;GASG;AACH,qEAPW,MAAM,EAAE,gBACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,oBACN,MAAM,kBACN,MAAM,GACJ,MAAM,CAgClB;AAED;;;;;;;;GAQG;AACH,gEANW,MAAM,EAAE,WACR,MAAM,oBACN,MAAM,kBACN,MAAM,GACJ,MAAM,CA8BlB;AAGD,gEAwKC"}
1
+ {"version":3,"file":"shader-utils.d.ts","sourceRoot":"","sources":["../src/shader-utils.js"],"names":[],"mappings":"AAoDA;;;;;;GAMG;AACH,wDAJW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,yBACJ,MAAM,CAWlB;AAGD;;;;;;;;;GASG;AACH,qEAPW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,kBACN,MAAM,EAAE,gBACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,oBACxB,MAAM,yBACJ,MAAM,CA8BlB;AAGD;;;;;;;;GAQG;AACH,gEANW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,kBACN,MAAM,EAAE,oBACR,MAAM,yBACJ,MAAM,CA2BlB;AAMD;;;;;;;GAOG;AACH,+DAJW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,yBACJ,MAAM,CAWlB;AAED;;;;;;;;;;;;;;GAcG;AACH,oEAXW,MAAM,EAAE,iBACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAE1B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,gBAExB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WAExB,MAAM,oBACN,MAAM,yBACJ,MAAM,CAsClB;AAED;;;;;;;;;;GAUG;AACH,+DARW,MAAM,EAAE,iBACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,eAE1B,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,oBACN,MAAM,yBACJ,MAAM,CAqClB;AAMD;;;;;;GAMG;AACH,kDAJW,MAAM,oBACN,MAAM,yBACJ,MAAM,CAmBlB;AAED;;;;;;;;;GASG;AACH,sEANW,MAAM,EAAE,gBACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,oBACN,MAAM,yBACJ,MAAM,CAoClB;AAED;;;;;;;GAOG;AACH,iEALW,MAAM,EAAE,WACR,MAAM,oBACN,MAAM,yBACJ,MAAM,CAoClB;AAuBD;;;;;;;GAOG;AACH,iDALW,MAAM,oBACN,MAAM,kBACN,MAAM,yBACJ,MAAM,CAqBlB;AAED;;;;;;;;;GASG;AACH,qEAPW,MAAM,EAAE,gBACR,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,WACxB,MAAM,oBACN,MAAM,kBACN,MAAM,yBACJ,MAAM,CAkClB;AAED;;;;;;;;GAQG;AACH,gEANW,MAAM,EAAE,WACR,MAAM,oBACN,MAAM,kBACN,MAAM,yBACJ,MAAM,CA+BlB;AAGD,gEAkLC"}
@@ -12,6 +12,16 @@ import { PALETTE, getDefaultColor } from '@vitessce/utils';
12
12
  function normalizeColor(rgbColor) {
13
13
  return rgbColor.map(c => c / 255);
14
14
  }
15
+ /**
16
+ * GLSL call to set point marker border width.
17
+ * Set to 0.0 to remove the outline.
18
+ * @param {number} borderWidth
19
+ * @returns {string}
20
+ */
21
+ function borderWidthGlsl(borderWidth = 0.0) {
22
+ // must be decimal/float value
23
+ return `setPointMarkerBorderWidth(${borderWidth.toFixed(1)});`;
24
+ }
15
25
  /**
16
26
  * Format a normalized color as a GLSL vec3 literal.
17
27
  * @param {[number, number, number]} normalizedColor
@@ -39,12 +49,13 @@ function toVec4(normalizedColor, alpha) {
39
49
  * @param {number} opacity Opacity (0-1).
40
50
  * @returns {string} A GLSL shader string.
41
51
  */
42
- export function getSpatialLayerColorShader(staticColor, opacity) {
52
+ export function getSpatialLayerColorShader(staticColor, opacity, borderWidth = 0.0) {
43
53
  const norm = normalizeColor(staticColor);
44
54
  // lang: glsl
45
55
  return `
46
56
  void main() {
47
57
  setColor(${toVec4(norm, opacity)});
58
+ ${borderWidthGlsl(borderWidth)}
48
59
  }
49
60
  `;
50
61
  }
@@ -58,7 +69,7 @@ export function getSpatialLayerColorShader(staticColor, opacity) {
58
69
  * @param {string} featureIndexProp The property name for the feature index in the shader.
59
70
  * @returns {string} A GLSL shader string.
60
71
  */
61
- export function getSpatialLayerColorWithSelectionShader(staticColor, opacity, featureIndices, defaultColor, featureIndexProp) {
72
+ export function getSpatialLayerColorWithSelectionShader(staticColor, opacity, featureIndices, defaultColor, featureIndexProp, borderWidth = 0.0) {
62
73
  const normStatic = normalizeColor(staticColor);
63
74
  const normDefault = normalizeColor(defaultColor);
64
75
  const numFeatures = featureIndices.length;
@@ -76,8 +87,10 @@ export function getSpatialLayerColorWithSelectionShader(staticColor, opacity, fe
76
87
  }
77
88
  if (isSelected) {
78
89
  setColor(${toVec4(normStatic, opacity)});
90
+ ${borderWidthGlsl(borderWidth)}
79
91
  } else {
80
92
  setColor(${toVec4(normDefault, opacity)});
93
+ ${borderWidthGlsl(borderWidth)}
81
94
  }
82
95
  }
83
96
  `;
@@ -91,7 +104,7 @@ export function getSpatialLayerColorWithSelectionShader(staticColor, opacity, fe
91
104
  * @param {string} featureIndexProp The property name for the feature index in the shader.
92
105
  * @returns {string} A GLSL shader string.
93
106
  */
94
- export function getSpatialLayerColorFilteredShader(staticColor, opacity, featureIndices, featureIndexProp) {
107
+ export function getSpatialLayerColorFilteredShader(staticColor, opacity, featureIndices, featureIndexProp, borderWidth = 0.0) {
95
108
  const normStatic = normalizeColor(staticColor);
96
109
  const numFeatures = featureIndices.length;
97
110
  const indicesArr = `int selectedIndices[${numFeatures}] = int[${numFeatures}](${featureIndices.join(', ')});`;
@@ -110,6 +123,7 @@ export function getSpatialLayerColorFilteredShader(staticColor, opacity, feature
110
123
  discard;
111
124
  }
112
125
  setColor(${toVec4(normStatic, opacity)});
126
+ ${borderWidthGlsl(borderWidth)}
113
127
  }
114
128
  `;
115
129
  }
@@ -124,12 +138,13 @@ export function getSpatialLayerColorFilteredShader(staticColor, opacity, feature
124
138
  * @param {number} opacity Opacity (0-1).
125
139
  * @returns {string} A GLSL shader string.
126
140
  */
127
- export function getGeneSelectionNoSelectionShader(staticColor, opacity) {
141
+ export function getGeneSelectionNoSelectionShader(staticColor, opacity, borderWidth = 0.0) {
128
142
  const norm = normalizeColor(staticColor);
129
143
  // lang: glsl
130
144
  return `
131
145
  void main() {
132
146
  setColor(${toVec4(norm, opacity)});
147
+ ${borderWidthGlsl(borderWidth)}
133
148
  }
134
149
  `;
135
150
  }
@@ -148,7 +163,7 @@ export function getGeneSelectionNoSelectionShader(staticColor, opacity) {
148
163
  * @param {string} featureIndexProp The property name for the feature index in the shader.
149
164
  * @returns {string} A GLSL shader string.
150
165
  */
151
- export function getGeneSelectionWithSelectionShader(featureIndices, featureColors, staticColor, defaultColor, opacity, featureIndexProp) {
166
+ export function getGeneSelectionWithSelectionShader(featureIndices, featureColors, staticColor, defaultColor, opacity, featureIndexProp, borderWidth = 0.0) {
152
167
  const numFeatures = featureIndices.length;
153
168
  const normDefault = normalizeColor(defaultColor);
154
169
  const normColors = featureColors.map(c => normalizeColor(c));
@@ -169,6 +184,7 @@ export function getGeneSelectionWithSelectionShader(featureIndices, featureColor
169
184
  }
170
185
  }
171
186
  setColor(color);
187
+ ${borderWidthGlsl(borderWidth)}
172
188
  }
173
189
  `;
174
190
  }
@@ -183,7 +199,7 @@ export function getGeneSelectionWithSelectionShader(featureIndices, featureColor
183
199
  * @param {string} featureIndexProp The property name for the feature index in the shader.
184
200
  * @returns {string} A GLSL shader string.
185
201
  */
186
- export function getGeneSelectionFilteredShader(featureIndices, featureColors, staticColor, opacity, featureIndexProp) {
202
+ export function getGeneSelectionFilteredShader(featureIndices, featureColors, staticColor, opacity, featureIndexProp, borderWidth = 0.0) {
187
203
  const numFeatures = featureIndices.length;
188
204
  const normColors = featureColors.map(c => normalizeColor(c));
189
205
  const normStatic = normalizeColor(staticColor);
@@ -208,6 +224,7 @@ export function getGeneSelectionFilteredShader(featureIndices, featureColors, st
208
224
  discard;
209
225
  }
210
226
  setColor(vec4(matchedColor, ${opacity}));
227
+ ${borderWidthGlsl(borderWidth)}
211
228
  }
212
229
  `;
213
230
  }
@@ -221,7 +238,7 @@ export function getGeneSelectionFilteredShader(featureIndices, featureColors, st
221
238
  * @param {string} featureIndexProp The property name for the feature index in the shader.
222
239
  * @returns {string} A GLSL shader string.
223
240
  */
224
- export function getRandomByFeatureShader(opacity, featureIndexProp) {
241
+ export function getRandomByFeatureShader(opacity, featureIndexProp, borderWidth = 0.0) {
225
242
  const paletteSize = PALETTE.length;
226
243
  const normPalette = PALETTE.map(c => normalizeColor(c));
227
244
  const paletteDecl = `vec3 palette[${paletteSize}] = vec3[${paletteSize}](${normPalette.map(c => toVec3(c)).join(', ')});`;
@@ -234,6 +251,7 @@ export function getRandomByFeatureShader(opacity, featureIndexProp) {
234
251
  if (colorIdx < 0) { colorIdx = -colorIdx; }
235
252
  vec3 color = palette[colorIdx];
236
253
  setColor(vec4(color, ${opacity}));
254
+ ${borderWidthGlsl(borderWidth)}
237
255
  }
238
256
  `;
239
257
  }
@@ -247,7 +265,7 @@ export function getRandomByFeatureShader(opacity, featureIndexProp) {
247
265
  * @param {string} featureIndexProp The property name for the feature index in the shader.
248
266
  * @returns {string} A GLSL shader string.
249
267
  */
250
- export function getRandomByFeatureWithSelectionShader(featureIndices, defaultColor, opacity, featureIndexProp) {
268
+ export function getRandomByFeatureWithSelectionShader(featureIndices, defaultColor, opacity, featureIndexProp, borderWidth = 0.0) {
251
269
  const paletteSize = PALETTE.length;
252
270
  const normPalette = PALETTE.map(c => normalizeColor(c));
253
271
  const normDefault = normalizeColor(defaultColor);
@@ -270,8 +288,10 @@ export function getRandomByFeatureWithSelectionShader(featureIndices, defaultCol
270
288
  int colorIdx = geneIndex - (geneIndex / ${paletteSize}) * ${paletteSize};
271
289
  if (colorIdx < 0) { colorIdx = -colorIdx; }
272
290
  setColor(vec4(palette[colorIdx], ${opacity}));
291
+ ${borderWidthGlsl(borderWidth)}
273
292
  } else {
274
293
  setColor(${toVec4(normDefault, opacity)});
294
+ ${borderWidthGlsl(borderWidth)}
275
295
  }
276
296
  }
277
297
  `;
@@ -284,7 +304,7 @@ export function getRandomByFeatureWithSelectionShader(featureIndices, defaultCol
284
304
  * @param {string} featureIndexProp The property name for the feature index in the shader.
285
305
  * @returns {string} A GLSL shader string.
286
306
  */
287
- export function getRandomByFeatureFilteredShader(featureIndices, opacity, featureIndexProp) {
307
+ export function getRandomByFeatureFilteredShader(featureIndices, opacity, featureIndexProp, borderWidth = 0.0) {
288
308
  const paletteSize = PALETTE.length;
289
309
  const normPalette = PALETTE.map(c => normalizeColor(c));
290
310
  const numFeatures = featureIndices.length;
@@ -308,6 +328,7 @@ export function getRandomByFeatureFilteredShader(featureIndices, opacity, featur
308
328
  int colorIdx = geneIndex - (geneIndex / ${paletteSize}) * ${paletteSize};
309
329
  if (colorIdx < 0) { colorIdx = -colorIdx; }
310
330
  setColor(vec4(palette[colorIdx], ${opacity}));
331
+ ${borderWidthGlsl(borderWidth)}
311
332
  }
312
333
  `;
313
334
  }
@@ -338,7 +359,7 @@ function hashToFloatGlsl() {
338
359
  * @param {string} pointIndexProp The property name for the point index in the shader.
339
360
  * @returns {string} A GLSL shader string.
340
361
  */
341
- export function getRandomPerPointShader(opacity, featureIndexProp, pointIndexProp) {
362
+ export function getRandomPerPointShader(opacity, featureIndexProp, pointIndexProp, borderWidth = 0.0) {
342
363
  // lang: glsl
343
364
  return `
344
365
  ${hashToFloatGlsl()}
@@ -349,6 +370,7 @@ export function getRandomPerPointShader(opacity, featureIndexProp, pointIndexPro
349
370
  float g = hashToFloat(pointIndex, 1);
350
371
  float b = hashToFloat(pointIndex, 2);
351
372
  setColor(vec4(r, g, b, ${opacity}));
373
+ ${borderWidthGlsl(borderWidth)}
352
374
  }
353
375
  `;
354
376
  }
@@ -362,7 +384,7 @@ export function getRandomPerPointShader(opacity, featureIndexProp, pointIndexPro
362
384
  * @param {string} pointIndexProp The property name for the point index in the shader.
363
385
  * @returns {string} A GLSL shader string.
364
386
  */
365
- export function getRandomPerPointWithSelectionShader(featureIndices, defaultColor, opacity, featureIndexProp, pointIndexProp) {
387
+ export function getRandomPerPointWithSelectionShader(featureIndices, defaultColor, opacity, featureIndexProp, pointIndexProp, borderWidth = 0.0) {
366
388
  const normDefault = normalizeColor(defaultColor);
367
389
  const numFeatures = featureIndices.length;
368
390
  const indicesDecl = `int selectedIndices[${numFeatures}] = int[${numFeatures}](${featureIndices.join(', ')});`;
@@ -384,8 +406,10 @@ export function getRandomPerPointWithSelectionShader(featureIndices, defaultColo
384
406
  float g = hashToFloat(pointIndex, 1);
385
407
  float b = hashToFloat(pointIndex, 2);
386
408
  setColor(vec4(r, g, b, ${opacity}));
409
+ ${borderWidthGlsl(borderWidth)}
387
410
  } else {
388
411
  setColor(${toVec4(normDefault, opacity)});
412
+ ${borderWidthGlsl(borderWidth)}
389
413
  }
390
414
  }
391
415
  `;
@@ -399,7 +423,7 @@ export function getRandomPerPointWithSelectionShader(featureIndices, defaultColo
399
423
  * @param {string} pointIndexProp The property name for the point index in the shader.
400
424
  * @returns {string} A GLSL shader string.
401
425
  */
402
- export function getRandomPerPointFilteredShader(featureIndices, opacity, featureIndexProp, pointIndexProp) {
426
+ export function getRandomPerPointFilteredShader(featureIndices, opacity, featureIndexProp, pointIndexProp, borderWidth = 0.0) {
403
427
  const numFeatures = featureIndices.length;
404
428
  const indicesDecl = `int selectedIndices[${numFeatures}] = int[${numFeatures}](${featureIndices.join(', ')});`;
405
429
  // lang: glsl
@@ -422,11 +446,12 @@ export function getRandomPerPointFilteredShader(featureIndices, opacity, feature
422
446
  float g = hashToFloat(pointIndex, 1);
423
447
  float b = hashToFloat(pointIndex, 2);
424
448
  setColor(vec4(r, g, b, ${opacity}));
449
+ ${borderWidthGlsl(borderWidth)}
425
450
  }
426
451
  `;
427
452
  }
428
453
  export function getPointsShader(layerCoordination) {
429
- const { theme, featureIndex, spatialLayerOpacity, obsColorEncoding, spatialLayerColor, featureSelection, featureFilterMode, featureColor, featureIndexProp, pointIndexProp, } = layerCoordination;
454
+ const { theme, featureIndex, spatialLayerOpacity, obsColorEncoding, spatialLayerColor, featureSelection, featureFilterMode, featureColor, pointMarkerBorderWidth = 0.0, featureIndexProp, pointIndexProp, } = layerCoordination;
430
455
  const defaultColor = getDefaultColor(theme);
431
456
  const opacity = spatialLayerOpacity ?? 1.0;
432
457
  const staticColor = (Array.isArray(spatialLayerColor) && spatialLayerColor.length === 3
@@ -496,12 +521,12 @@ export function getPointsShader(layerCoordination) {
496
521
  // ---- spatialLayerColor ----
497
522
  if (obsColorEncoding === 'spatialLayerColor') {
498
523
  if (!hasFeatureSelection || !hasResolvedIndices) {
499
- return getSpatialLayerColorShader(staticColor, opacity);
524
+ return getSpatialLayerColorShader(staticColor, opacity, pointMarkerBorderWidth);
500
525
  }
501
526
  if (isFiltered) {
502
- return getSpatialLayerColorFilteredShader(staticColor, opacity, featureIndices, featureIndexProp);
527
+ return getSpatialLayerColorFilteredShader(staticColor, opacity, featureIndices, featureIndexProp, pointMarkerBorderWidth);
503
528
  }
504
- return getSpatialLayerColorWithSelectionShader(staticColor, opacity, featureIndices, defaultColor, featureIndexProp);
529
+ return getSpatialLayerColorWithSelectionShader(staticColor, opacity, featureIndices, defaultColor, featureIndexProp, pointMarkerBorderWidth);
505
530
  }
506
531
  // ---- geneSelection ----
507
532
  if (obsColorEncoding === 'geneSelection') {
@@ -509,12 +534,12 @@ export function getPointsShader(layerCoordination) {
509
534
  throw new Error('In order to use gene-based color encoding for Neuroglancer Points, options.featureIndexProp must be specified for the obsPoints.ng-annotations fileType in the Vitessce configuration.');
510
535
  }
511
536
  if (!hasFeatureSelection || !hasResolvedIndices) {
512
- return getGeneSelectionNoSelectionShader(staticColor, opacity);
537
+ return getGeneSelectionNoSelectionShader(staticColor, opacity, pointMarkerBorderWidth);
513
538
  }
514
539
  if (isFiltered) {
515
- return getGeneSelectionFilteredShader(featureIndices, resolvedFeatureColors, staticColor, opacity, featureIndexProp);
540
+ return getGeneSelectionFilteredShader(featureIndices, resolvedFeatureColors, staticColor, opacity, featureIndexProp, pointMarkerBorderWidth);
516
541
  }
517
- return getGeneSelectionWithSelectionShader(featureIndices, resolvedFeatureColors, staticColor, defaultColor, opacity, featureIndexProp);
542
+ return getGeneSelectionWithSelectionShader(featureIndices, resolvedFeatureColors, staticColor, defaultColor, opacity, featureIndexProp, pointMarkerBorderWidth);
518
543
  }
519
544
  // ---- randomByFeature ----
520
545
  if (obsColorEncoding === 'randomByFeature') {
@@ -522,12 +547,12 @@ export function getPointsShader(layerCoordination) {
522
547
  throw new Error('In order to use gene-based color encoding for Neuroglancer Points, options.featureIndexProp must be specified for the obsPoints.ng-annotations fileType in the Vitessce configuration.');
523
548
  }
524
549
  if (!hasFeatureSelection || !hasResolvedIndices) {
525
- return getRandomByFeatureShader(opacity, featureIndexProp);
550
+ return getRandomByFeatureShader(opacity, featureIndexProp, pointMarkerBorderWidth);
526
551
  }
527
552
  if (isFiltered) {
528
- return getRandomByFeatureFilteredShader(featureIndices, opacity, featureIndexProp);
553
+ return getRandomByFeatureFilteredShader(featureIndices, opacity, featureIndexProp, pointMarkerBorderWidth);
529
554
  }
530
- return getRandomByFeatureWithSelectionShader(featureIndices, defaultColor, opacity, featureIndexProp);
555
+ return getRandomByFeatureWithSelectionShader(featureIndices, defaultColor, opacity, featureIndexProp, pointMarkerBorderWidth);
531
556
  }
532
557
  // ---- random (per point) ----
533
558
  if (obsColorEncoding === 'random') {
@@ -535,13 +560,13 @@ export function getPointsShader(layerCoordination) {
535
560
  throw new Error('In order to use per-point color encoding for Neuroglancer Points, options.pointIndexProp must be specified for the obsPoints.ng-annotations fileType in the Vitessce configuration.');
536
561
  }
537
562
  if (!hasFeatureSelection || !hasResolvedIndices) {
538
- return getRandomPerPointShader(opacity, featureIndexProp, pointIndexProp);
563
+ return getRandomPerPointShader(opacity, featureIndexProp, pointIndexProp, pointMarkerBorderWidth);
539
564
  }
540
565
  if (isFiltered) {
541
- return getRandomPerPointFilteredShader(featureIndices, opacity, featureIndexProp, pointIndexProp);
566
+ return getRandomPerPointFilteredShader(featureIndices, opacity, featureIndexProp, pointIndexProp, pointMarkerBorderWidth);
542
567
  }
543
- return getRandomPerPointWithSelectionShader(featureIndices, defaultColor, opacity, featureIndexProp, pointIndexProp);
568
+ return getRandomPerPointWithSelectionShader(featureIndices, defaultColor, opacity, featureIndexProp, pointIndexProp, pointMarkerBorderWidth);
544
569
  }
545
570
  // Fallback: static color.
546
- return getSpatialLayerColorShader(staticColor, opacity);
571
+ return getSpatialLayerColorShader(staticColor, opacity, pointMarkerBorderWidth);
547
572
  }
@@ -29,6 +29,7 @@ describe('getSpatialLayerColorShader', () => {
29
29
  const expected = `
30
30
  void main() {
31
31
  setColor(vec4(1, 0.5019607843137255, 0, 0.8));
32
+ setPointMarkerBorderWidth(0.0);
32
33
  }
33
34
  `;
34
35
  expectShaderEqual(result, expected);
@@ -38,6 +39,7 @@ void main() {
38
39
  const expected = `
39
40
  void main() {
40
41
  setColor(vec4(0, 0, 0, 0));
42
+ setPointMarkerBorderWidth(0.0);
41
43
  }
42
44
  `;
43
45
  expectShaderEqual(result, expected);
@@ -47,6 +49,7 @@ void main() {
47
49
  const expected = `
48
50
  void main() {
49
51
  setColor(vec4(1, 1, 1, 1));
52
+ setPointMarkerBorderWidth(0.0);
50
53
  }
51
54
  `;
52
55
  expectShaderEqual(result, expected);
@@ -67,8 +70,10 @@ void main() {
67
70
  }
68
71
  if (isSelected) {
69
72
  setColor(vec4(1, 0, 0, 0.5));
73
+ setPointMarkerBorderWidth(0.0);
70
74
  } else {
71
75
  setColor(vec4(0.5019607843137255, 0.5019607843137255, 0.5019607843137255, 0.5));
76
+ setPointMarkerBorderWidth(0.0);
72
77
  }
73
78
  }
74
79
  `;
@@ -88,8 +93,10 @@ void main() {
88
93
  }
89
94
  if (isSelected) {
90
95
  setColor(vec4(0, 1, 0, 1));
96
+ setPointMarkerBorderWidth(0.0);
91
97
  } else {
92
98
  setColor(vec4(0, 0, 0, 1));
99
+ setPointMarkerBorderWidth(0.0);
93
100
  }
94
101
  }
95
102
  `;
@@ -113,6 +120,7 @@ void main() {
113
120
  discard;
114
121
  }
115
122
  setColor(vec4(0, 0, 1, 0.9));
123
+ setPointMarkerBorderWidth(0.0);
116
124
  }
117
125
  `;
118
126
  expectShaderEqual(result, expected);
@@ -127,6 +135,7 @@ describe('getGeneSelectionNoSelectionShader', () => {
127
135
  const expected = `
128
136
  void main() {
129
137
  setColor(vec4(0.39215686274509803, 0.7843137254901961, 0.19607843137254902, 0.7));
138
+ setPointMarkerBorderWidth(0.0);
130
139
  }
131
140
  `;
132
141
  expectShaderEqual(result, expected);
@@ -147,6 +156,7 @@ void main() {
147
156
  }
148
157
  }
149
158
  setColor(color);
159
+ setPointMarkerBorderWidth(0.0);
150
160
  }
151
161
  `;
152
162
  expectShaderEqual(result, expected);
@@ -169,6 +179,7 @@ void main() {
169
179
  }
170
180
  }
171
181
  setColor(color);
182
+ setPointMarkerBorderWidth(0.0);
172
183
  }
173
184
  `;
174
185
  expectShaderEqual(result, expected);
@@ -194,6 +205,7 @@ void main() {
194
205
  discard;
195
206
  }
196
207
  setColor(vec4(matchedColor, 0.75));
208
+ setPointMarkerBorderWidth(0.0);
197
209
  }
198
210
  `;
199
211
  expectShaderEqual(result, expected);
@@ -213,6 +225,7 @@ void main() {
213
225
  if (colorIdx < 0) { colorIdx = -colorIdx; }
214
226
  vec3 color = palette[colorIdx];
215
227
  setColor(vec4(color, 0.5));
228
+ setPointMarkerBorderWidth(0.0);
216
229
  }
217
230
  `;
218
231
  expectShaderEqual(result, expected);
@@ -236,8 +249,10 @@ void main() {
236
249
  int colorIdx = geneIndex - (geneIndex / 3) * 3;
237
250
  if (colorIdx < 0) { colorIdx = -colorIdx; }
238
251
  setColor(vec4(palette[colorIdx], 0.8));
252
+ setPointMarkerBorderWidth(0.0);
239
253
  } else {
240
254
  setColor(vec4(0.19607843137254902, 0.19607843137254902, 0.19607843137254902, 0.8));
255
+ setPointMarkerBorderWidth(0.0);
241
256
  }
242
257
  }
243
258
  `;
@@ -264,6 +279,7 @@ void main() {
264
279
  int colorIdx = geneIndex - (geneIndex / 3) * 3;
265
280
  if (colorIdx < 0) { colorIdx = -colorIdx; }
266
281
  setColor(vec4(palette[colorIdx], 1));
282
+ setPointMarkerBorderWidth(0.0);
267
283
  }
268
284
  `;
269
285
  expectShaderEqual(result, expected);
@@ -290,6 +306,7 @@ void main() {
290
306
  float g = hashToFloat(pointIndex, 1);
291
307
  float b = hashToFloat(pointIndex, 2);
292
308
  setColor(vec4(r, g, b, 0.9));
309
+ setPointMarkerBorderWidth(0.0);
293
310
  }
294
311
  `;
295
312
  expectShaderEqual(result, expected);
@@ -321,8 +338,10 @@ void main() {
321
338
  float g = hashToFloat(pointIndex, 1);
322
339
  float b = hashToFloat(pointIndex, 2);
323
340
  setColor(vec4(r, g, b, 0.5));
341
+ setPointMarkerBorderWidth(0.0);
324
342
  } else {
325
343
  setColor(vec4(0.39215686274509803, 0.39215686274509803, 0.39215686274509803, 0.5));
344
+ setPointMarkerBorderWidth(0.0);
326
345
  }
327
346
  }
328
347
  `;
@@ -357,6 +376,7 @@ void main() {
357
376
  float g = hashToFloat(pointIndex, 1);
358
377
  float b = hashToFloat(pointIndex, 2);
359
378
  setColor(vec4(r, g, b, 1));
379
+ setPointMarkerBorderWidth(0.0);
360
380
  }
361
381
  `;
362
382
  expectShaderEqual(result, expected);
@@ -1 +1 @@
1
- {"version":3,"file":"use-memo-custom-comparison.d.ts","sourceRoot":"","sources":["../src/use-memo-custom-comparison.js"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,wCAPa,CAAC,WACH,MAAM,CAAC,gBACP,GAAG,iBACH,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,OAAO,GAEvC,CAAC,CAUb;AA6CD,kFA8CC;AAED,0FAyEC"}
1
+ {"version":3,"file":"use-memo-custom-comparison.d.ts","sourceRoot":"","sources":["../src/use-memo-custom-comparison.js"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,wCAPa,CAAC,WACH,MAAM,CAAC,gBACP,GAAG,iBACH,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,OAAO,GAEvC,CAAC,CAUb;AA6CD,kFAgDC;AAED,0FA8EC"}
@@ -73,6 +73,8 @@ export function customIsEqualForCellColors(prevDeps, nextDeps) {
73
73
  'obsColorEncoding',
74
74
  'obsSetSelection',
75
75
  'additionalObsSets',
76
+ 'spatialChannelColor',
77
+ 'spatialChannelOpacity',
76
78
  ])) {
77
79
  forceUpdate = true;
78
80
  }
@@ -95,6 +97,9 @@ export function customIsEqualForInitialViewerState(prevDeps, nextDeps) {
95
97
  const curriedShallowDiffByLayerCoordinationWithKeys = (depName, layerScope, keys) => shallowDiffByLayerCoordinationWithKeys(prevDeps, nextDeps, depName, layerScope, keys);
96
98
  const curriedShallowDiffByChannelCoordination = (depName, layerScope, channelScope) => shallowDiffByChannelCoordination(prevDeps, nextDeps, depName, layerScope, channelScope);
97
99
  const curriedShallowDiffByChannelCoordinationWithKeys = (depName, layerScope, channelScope, keys) => shallowDiffByChannelCoordinationWithKeys(prevDeps, nextDeps, depName, layerScope, channelScope, keys);
100
+ if (['theme', 'showAxisLines'].some(curriedShallowDiff)) {
101
+ forceUpdate = true;
102
+ }
98
103
  // Segmentation layers/channels.
99
104
  if (['segmentationLayerScopes', 'segmentationChannelScopesByLayer'].some(curriedShallowDiff)) {
100
105
  // Force update for all layers since the layerScopes array changed.
@@ -135,6 +140,7 @@ export function customIsEqualForInitialViewerState(prevDeps, nextDeps) {
135
140
  'featureSelection',
136
141
  'featureFilterMode',
137
142
  'featureColor',
143
+ 'spatialPointStrokeWidth',
138
144
  ])
139
145
  // For opacity, use an epsilon comparison to avoid too many re-renders, as it affects performance.
140
146
  || (Math.abs(prevDeps?.pointLayerCoordination?.[0]?.[layerScope]?.spatialLayerOpacity - nextDeps?.pointLayerCoordination?.[0]?.[layerScope]?.spatialLayerOpacity)