@geode/opengeodeweb-front 10.41.0 → 10.42.0-rc.1

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.
@@ -11,5 +11,9 @@ const { itemProps } = defineProps<Props>();
11
11
  </script>
12
12
 
13
13
  <template>
14
- <ViewerGenericMeshEdgesOptions :itemProps="itemProps" :btnImage="Grid2D_Edges" />
14
+ <ViewerGenericMeshEdgesOptions
15
+ :itemProps="itemProps"
16
+ :btnImage="Grid2D_Edges"
17
+ :capabilities="{ edge: { available: false } }"
18
+ />
15
19
  </template>
@@ -11,5 +11,9 @@ const { itemProps } = defineProps<Props>();
11
11
  </script>
12
12
 
13
13
  <template>
14
- <ViewerGenericMeshEdgesOptions :itemProps="itemProps" :btnImage="Grid3D_Edges" />
14
+ <ViewerGenericMeshEdgesOptions
15
+ :itemProps="itemProps"
16
+ :btnImage="Grid3D_Edges"
17
+ :capabilities="{ edge: { available: false } }"
18
+ />
15
19
  </template>
@@ -11,5 +11,9 @@ const { itemProps } = defineProps<Props>();
11
11
  </script>
12
12
 
13
13
  <template>
14
- <ViewerGenericMeshEdgesOptions :itemProps="itemProps" :btnImage="SolidEdges" />
14
+ <ViewerGenericMeshEdgesOptions
15
+ :itemProps="itemProps"
16
+ :btnImage="SolidEdges"
17
+ :capabilities="{ edge: { available: false } }"
18
+ />
15
19
  </template>
@@ -11,5 +11,9 @@ const { itemProps } = defineProps<Props>();
11
11
  </script>
12
12
 
13
13
  <template>
14
- <ViewerGenericMeshEdgesOptions :itemProps="itemProps" :btnImage="SurfaceEdges" />
14
+ <ViewerGenericMeshEdgesOptions
15
+ :itemProps="itemProps"
16
+ :btnImage="SurfaceEdges"
17
+ :capabilities="{ edge: { available: false } }"
18
+ />
15
19
  </template>
@@ -0,0 +1,51 @@
1
+ import {
2
+ type ModelComponentEdgesStyle,
3
+ useModelComponentEdgesStyle,
4
+ } from "@ogw_internal/stores/data_style/model/edges/component";
5
+
6
+ interface UseModelBlocksEdgesStyleReturn {
7
+ modelBlockEdgesVisibility: ModelComponentEdgesStyle["visibility"];
8
+ modelBlockEdgesWidth: ModelComponentEdgesStyle["width"];
9
+ modelBlockEdgesColor: ModelComponentEdgesStyle["color"];
10
+ modelBlockEdgesActiveColoring: ModelComponentEdgesStyle["activeColoring"];
11
+ modelBlockEdgesVertexAttributeName: ModelComponentEdgesStyle["vertexAttributeName"];
12
+ modelBlockEdgesVertexAttributeItem: ModelComponentEdgesStyle["vertexAttributeItem"];
13
+ modelBlockEdgesVertexAttributeRange: ModelComponentEdgesStyle["vertexAttributeRange"];
14
+ modelBlockEdgesVertexAttributeColorMap: ModelComponentEdgesStyle["vertexAttributeColorMap"];
15
+ modelBlockEdgesVertexAttributeNoDataColor: ModelComponentEdgesStyle["vertexAttributeNoDataColor"];
16
+ setModelBlocksEdgesVisibility: ModelComponentEdgesStyle["setVisibility"];
17
+ setModelBlocksEdgesWidth: ModelComponentEdgesStyle["setWidth"];
18
+ setModelBlocksEdgesColor: ModelComponentEdgesStyle["setColor"];
19
+ setModelBlocksEdgesActiveColoring: ModelComponentEdgesStyle["setActiveColoring"];
20
+ setModelBlocksEdgesVertexAttributeName: ModelComponentEdgesStyle["setVertexAttributeName"];
21
+ setModelBlocksEdgesVertexAttributeItem: ModelComponentEdgesStyle["setVertexAttributeItem"];
22
+ setModelBlocksEdgesVertexAttributeRange: ModelComponentEdgesStyle["setVertexAttributeRange"];
23
+ setModelBlocksEdgesVertexAttributeColorMap: ModelComponentEdgesStyle["setVertexAttributeColorMap"];
24
+ setModelBlocksEdgesVertexAttributeNoDataColor: ModelComponentEdgesStyle["setVertexAttributeNoDataColor"];
25
+ applyModelBlocksEdgesStyle: ModelComponentEdgesStyle["applyEdgesStyle"];
26
+ }
27
+
28
+ export function useModelBlocksEdgesStyle(): UseModelBlocksEdgesStyleReturn {
29
+ const edges = useModelComponentEdgesStyle("Block");
30
+ return {
31
+ modelBlockEdgesVisibility: edges.visibility,
32
+ modelBlockEdgesWidth: edges.width,
33
+ modelBlockEdgesColor: edges.color,
34
+ modelBlockEdgesActiveColoring: edges.activeColoring,
35
+ modelBlockEdgesVertexAttributeName: edges.vertexAttributeName,
36
+ modelBlockEdgesVertexAttributeItem: edges.vertexAttributeItem,
37
+ modelBlockEdgesVertexAttributeRange: edges.vertexAttributeRange,
38
+ modelBlockEdgesVertexAttributeColorMap: edges.vertexAttributeColorMap,
39
+ modelBlockEdgesVertexAttributeNoDataColor: edges.vertexAttributeNoDataColor,
40
+ setModelBlocksEdgesVisibility: edges.setVisibility,
41
+ setModelBlocksEdgesWidth: edges.setWidth,
42
+ setModelBlocksEdgesColor: edges.setColor,
43
+ setModelBlocksEdgesActiveColoring: edges.setActiveColoring,
44
+ setModelBlocksEdgesVertexAttributeName: edges.setVertexAttributeName,
45
+ setModelBlocksEdgesVertexAttributeItem: edges.setVertexAttributeItem,
46
+ setModelBlocksEdgesVertexAttributeRange: edges.setVertexAttributeRange,
47
+ setModelBlocksEdgesVertexAttributeColorMap: edges.setVertexAttributeColorMap,
48
+ setModelBlocksEdgesVertexAttributeNoDataColor: edges.setVertexAttributeNoDataColor,
49
+ applyModelBlocksEdgesStyle: edges.applyEdgesStyle,
50
+ };
51
+ }
@@ -7,6 +7,7 @@ import type { RGBAColor } from "@ogw_front/utils/default_styles/constants";
7
7
  import { useDataStore } from "@ogw_front/stores/data";
8
8
  import { useModelBlocksColor } from "./color";
9
9
  import { useModelBlocksCommonStyle } from "./common";
10
+ import { useModelBlocksEdgesStyle } from "./edges";
10
11
  import { useModelBlocksPointsStyle } from "./points";
11
12
  import { useModelBlocksVisibility } from "./visibility";
12
13
 
@@ -36,6 +37,7 @@ type UseModelBlocksStyleReturn = {
36
37
  ReturnType<typeof useModelBlocksVisibility> &
37
38
  ReturnType<typeof useModelBlocksColor> &
38
39
  ReturnType<typeof useModelBlocksPointsStyle> &
40
+ ReturnType<typeof useModelBlocksEdgesStyle> &
39
41
  ReturnType<typeof useModelBlocksVertexAttribute> &
40
42
  ReturnType<typeof useModelBlocksPolyhedronAttribute>;
41
43
 
@@ -48,6 +50,7 @@ export function useModelBlocksStyle(): UseModelBlocksStyleReturn {
48
50
  const modelBlocksVertexAttribute = useModelBlocksVertexAttribute();
49
51
  const modelBlocksPolyhedronAttribute = useModelBlocksPolyhedronAttribute();
50
52
  const modelBlocksPointsStyle = useModelBlocksPointsStyle();
53
+ const modelBlocksEdgesStyle = useModelBlocksEdgesStyle();
51
54
 
52
55
  async function applyModelBlocksVisibilityStyle(
53
56
  modelId: string,
@@ -249,5 +252,6 @@ export function useModelBlocksStyle(): UseModelBlocksStyleReturn {
249
252
  ...modelBlocksVertexAttribute,
250
253
  ...modelBlocksPolyhedronAttribute,
251
254
  ...modelBlocksPointsStyle,
255
+ ...modelBlocksEdgesStyle,
252
256
  };
253
257
  }
@@ -0,0 +1,27 @@
1
+ import type { RGBAColor } from "@ogw_front/utils/default_styles/constants";
2
+
3
+ function groupBy(componentIds: string[], key: (componentId: string) => string): string[][] {
4
+ const groups: Record<string, string[]> = {};
5
+ for (const componentId of componentIds) {
6
+ const groupKey = key(componentId);
7
+ groups[groupKey] ??= [];
8
+ groups[groupKey].push(componentId);
9
+ }
10
+ return Object.values(groups);
11
+ }
12
+
13
+ interface AttributeStoredConfig {
14
+ minimum: number | undefined;
15
+ maximum: number | undefined;
16
+ colorMap: string | undefined;
17
+ no_data_color: RGBAColor;
18
+ }
19
+
20
+ interface AttributeState {
21
+ name?: string;
22
+ item?: number;
23
+ storedConfigs?: Record<string, { lastItem: number } & Record<string, AttributeStoredConfig>>;
24
+ }
25
+
26
+ export { groupBy };
27
+ export type { AttributeState, AttributeStoredConfig };
@@ -0,0 +1,406 @@
1
+ // oxlint-disable eslint/max-lines
2
+ import {
3
+ type AttributeState,
4
+ type AttributeStoredConfig,
5
+ groupBy,
6
+ } from "@ogw_internal/stores/data_style/model/component_style";
7
+ import {
8
+ DEFAULT_NO_DATA_COLOR,
9
+ EDGES_DEFAULT_COLOR,
10
+ EDGES_DEFAULT_VISIBILITY,
11
+ EDGES_DEFAULT_WIDTH,
12
+ type RGBAColor,
13
+ } from "@ogw_front/utils/default_styles/constants";
14
+ import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap";
15
+ import merge from "lodash/merge";
16
+ import { useAttributeTimeStepStyle } from "@ogw_internal/stores/data_style/time_step";
17
+ import { useDataStore } from "@ogw_front/stores/data";
18
+ import { useDataStyleState } from "@ogw_internal/stores/data_style/state";
19
+ import { useModelCommonStyle } from "@ogw_internal/stores/data_style/model/common";
20
+ import { useViewerStore } from "@ogw_front/stores/viewer";
21
+ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
22
+
23
+ // Lines are edges themselves and corners have none, so only these components get their own edges style
24
+ const EDGES_COMPONENT_TYPES = ["Surface", "Block"] as const;
25
+ type EdgesComponentType = (typeof EDGES_COMPONENT_TYPES)[number];
26
+
27
+ const modelSchemas = viewer_schemas.opengeodeweb_viewer.model;
28
+ const COMPONENT_TYPE_KEYS = {
29
+ Surface: "surfaces",
30
+ Block: "blocks",
31
+ } as const;
32
+
33
+ type EdgesSchemas =
34
+ (typeof modelSchemas)[(typeof COMPONENT_TYPE_KEYS)[EdgesComponentType]]["edges"];
35
+ type EdgesRequestSchema =
36
+ | EdgesSchemas["visibility"]
37
+ | EdgesSchemas["width"]
38
+ | EdgesSchemas["color"]
39
+ | EdgesSchemas["attribute"]["vertex"]["attribute"];
40
+
41
+ interface EdgesStyle {
42
+ visibility?: boolean;
43
+ width?: number;
44
+ coloring?: {
45
+ active?: string;
46
+ constant?: RGBAColor;
47
+ vertex?: AttributeState;
48
+ };
49
+ }
50
+
51
+ // Return type is inferred, see ModelComponentEdgesStyle: signatures live on the functions only
52
+ // oxlint-disable-next-line max-lines-per-function, max-statements, typescript/explicit-function-return-type, typescript/explicit-module-boundary-types
53
+ function useModelComponentEdgesStyle(type: EdgesComponentType) {
54
+ const dataStore = useDataStore();
55
+ const dataStyleState = useDataStyleState();
56
+ const modelCommonStyle = useModelCommonStyle();
57
+ const viewerStore = useViewerStore();
58
+ const { seriesArrayName } = useAttributeTimeStepStyle();
59
+ const schemas = modelSchemas[COMPONENT_TYPE_KEYS[type]].edges;
60
+
61
+ // Without an explicit edges style, components follow the model edges style
62
+ function edgesStyle(modelId: string, componentId?: string): EdgesStyle {
63
+ // oxlint-disable-next-line no-unsafe-type-assertion -- edges shape is defined by the data style schema.
64
+ const modelEdges = (dataStyleState.getStyle(modelId).edges ?? {}) as EdgesStyle;
65
+ // oxlint-disable-next-line no-unsafe-type-assertion -- edges shape is defined by the data style schema.
66
+ const typeEdges = dataStyleState.getModelComponentTypeStyle(modelId, type).edges as
67
+ | EdgesStyle
68
+ | undefined;
69
+ const componentEdges =
70
+ componentId === undefined
71
+ ? undefined
72
+ : // oxlint-disable-next-line no-unsafe-type-assertion -- edges shape is defined by the data style schema.
73
+ (dataStyleState.getComponentStyle(modelId, componentId).edges as EdgesStyle | undefined);
74
+ return merge(
75
+ {
76
+ visibility: modelEdges.visibility ?? EDGES_DEFAULT_VISIBILITY,
77
+ width: modelEdges.width ?? EDGES_DEFAULT_WIDTH,
78
+ coloring: { active: "constant", constant: EDGES_DEFAULT_COLOR },
79
+ },
80
+ typeEdges,
81
+ componentEdges,
82
+ );
83
+ }
84
+
85
+ function vertexAttribute(modelId: string, componentId?: string): AttributeState {
86
+ return edgesStyle(modelId, componentId).coloring?.vertex ?? {};
87
+ }
88
+
89
+ function edgesVisibility(modelId: string, componentId?: string): boolean {
90
+ return edgesStyle(modelId, componentId).visibility ?? EDGES_DEFAULT_VISIBILITY;
91
+ }
92
+
93
+ function edgesWidth(modelId: string, componentId?: string): number {
94
+ return edgesStyle(modelId, componentId).width ?? EDGES_DEFAULT_WIDTH;
95
+ }
96
+
97
+ function edgesColor(modelId: string, componentId?: string): RGBAColor {
98
+ return edgesStyle(modelId, componentId).coloring?.constant ?? EDGES_DEFAULT_COLOR;
99
+ }
100
+
101
+ function activeColoring(modelId: string, componentId?: string): string {
102
+ return edgesStyle(modelId, componentId).coloring?.active ?? "constant";
103
+ }
104
+
105
+ function vertexAttributeName(modelId: string, componentId?: string): string | undefined {
106
+ return vertexAttribute(modelId, componentId).name;
107
+ }
108
+
109
+ function lastItem(modelId: string, componentId: string | undefined, name?: string): number {
110
+ const { storedConfigs } = vertexAttribute(modelId, componentId);
111
+ return name === undefined ? 0 : (storedConfigs?.[name]?.lastItem ?? 0);
112
+ }
113
+
114
+ function vertexAttributeItem(modelId: string, componentId?: string): number {
115
+ const { name, item } = vertexAttribute(modelId, componentId);
116
+ return item ?? lastItem(modelId, componentId, name);
117
+ }
118
+
119
+ function storedConfig(modelId: string, componentId: string | undefined): AttributeStoredConfig {
120
+ const { name, storedConfigs } = vertexAttribute(modelId, componentId);
121
+ const item = vertexAttributeItem(modelId, componentId);
122
+ const config = name === undefined ? undefined : storedConfigs?.[name]?.[item];
123
+ // A stored config may be partial, missing fields fall back to the defaults
124
+ return {
125
+ minimum: undefined,
126
+ maximum: undefined,
127
+ colorMap: undefined,
128
+ no_data_color: DEFAULT_NO_DATA_COLOR,
129
+ ...config,
130
+ };
131
+ }
132
+
133
+ function vertexAttributeRange(
134
+ modelId: string,
135
+ componentId?: string,
136
+ ): [number | undefined, number | undefined] {
137
+ const { minimum, maximum } = storedConfig(modelId, componentId);
138
+ return [minimum, maximum];
139
+ }
140
+
141
+ function vertexAttributeColorMap(modelId: string, componentId?: string): string | undefined {
142
+ return storedConfig(modelId, componentId).colorMap;
143
+ }
144
+
145
+ function vertexAttributeNoDataColor(modelId: string, componentId?: string): RGBAColor {
146
+ return storedConfig(modelId, componentId).no_data_color;
147
+ }
148
+
149
+ // The type style is updated too when every component of the type is targeted
150
+ async function mutateEdges(
151
+ modelId: string,
152
+ componentIds: string[],
153
+ values: EdgesStyle,
154
+ ): Promise<void> {
155
+ const tasks = [
156
+ modelCommonStyle.mutateComponentStyles(modelId, componentIds, { edges: values }),
157
+ ];
158
+ const totalIds = await dataStore.getMeshComponentGeodeIds(modelId, type);
159
+ if (componentIds.length === totalIds.length) {
160
+ tasks.push(modelCommonStyle.mutateModelComponentTypeStyle(modelId, type, { edges: values }));
161
+ }
162
+ await Promise.all(tasks);
163
+ }
164
+
165
+ async function requestEdges(
166
+ modelId: string,
167
+ componentIds: string[],
168
+ schema: EdgesRequestSchema,
169
+ values: Record<string, unknown> & { style: EdgesStyle },
170
+ ): Promise<unknown> {
171
+ if (componentIds.length === 0) {
172
+ return undefined;
173
+ }
174
+ const block_ids = await dataStore.getMeshComponentsViewerIds(modelId, componentIds);
175
+ if (!block_ids?.length) {
176
+ return undefined;
177
+ }
178
+ const { style, ...params } = values;
179
+ const result = await viewerStore.request(
180
+ // oxlint-disable-next-line no-unsafe-type-assertion, no-unnecessary-type-assertion -- params match the edges schema of every component type.
181
+ { schema, params: { id: modelId, block_ids, ...params } } as Parameters<
182
+ typeof viewerStore.request
183
+ >[0],
184
+ {
185
+ response_function: async () => {
186
+ await mutateEdges(modelId, componentIds, style);
187
+ },
188
+ },
189
+ );
190
+ return result;
191
+ }
192
+
193
+ async function setVisibility(
194
+ modelId: string,
195
+ componentIds: string[],
196
+ visibility: boolean,
197
+ ): Promise<unknown> {
198
+ const result = await requestEdges(modelId, componentIds, schemas.visibility, {
199
+ visibility,
200
+ style: { visibility },
201
+ });
202
+ return result;
203
+ }
204
+
205
+ async function setWidth(
206
+ modelId: string,
207
+ componentIds: string[],
208
+ width: number,
209
+ ): Promise<unknown> {
210
+ const result = await requestEdges(modelId, componentIds, schemas.width, {
211
+ width,
212
+ style: { width },
213
+ });
214
+ return result;
215
+ }
216
+
217
+ async function setColor(
218
+ modelId: string,
219
+ componentIds: string[],
220
+ color: RGBAColor,
221
+ ): Promise<unknown> {
222
+ const result = await requestEdges(modelId, componentIds, schemas.color, {
223
+ color,
224
+ style: { coloring: { active: "constant", constant: color } },
225
+ });
226
+ return result;
227
+ }
228
+
229
+ async function applyVertexAttribute(modelId: string, componentIds: string[]): Promise<unknown> {
230
+ const [referenceId] = componentIds;
231
+ const name = vertexAttributeName(modelId, referenceId);
232
+ const item = vertexAttributeItem(modelId, referenceId);
233
+ const { minimum, maximum, colorMap, no_data_color } = storedConfig(modelId, referenceId);
234
+ if (
235
+ name === undefined ||
236
+ minimum === undefined ||
237
+ maximum === undefined ||
238
+ colorMap === undefined
239
+ ) {
240
+ return undefined;
241
+ }
242
+ const schema = schemas.attribute.vertex.attribute;
243
+ const result = await requestEdges(modelId, componentIds, schema, {
244
+ name: seriesArrayName(modelId, schema.$id, name),
245
+ item,
246
+ points: [...getRGBPointsFromPreset(colorMap)],
247
+ minimum,
248
+ maximum,
249
+ no_data_color,
250
+ style: { coloring: { active: "vertex" } },
251
+ });
252
+ return result;
253
+ }
254
+
255
+ async function mutateVertexAttribute(
256
+ modelId: string,
257
+ componentIds: string[],
258
+ values: AttributeState,
259
+ ): Promise<void> {
260
+ await mutateEdges(modelId, componentIds, { coloring: { vertex: values } });
261
+ }
262
+
263
+ async function mutateStoredConfig(
264
+ modelId: string,
265
+ componentIds: string[],
266
+ config: Partial<AttributeStoredConfig>,
267
+ ): Promise<void> {
268
+ const name = vertexAttributeName(modelId, componentIds[0]);
269
+ const item = vertexAttributeItem(modelId, componentIds[0]);
270
+ const itemConfigs = { lastItem: item, [item]: config };
271
+ // oxlint-disable-next-line no-unsafe-type-assertion -- partial stored config is merged into the existing one.
272
+ const storedConfigs = { [name ?? ""]: itemConfigs } as AttributeState["storedConfigs"];
273
+ await mutateVertexAttribute(modelId, componentIds, { storedConfigs });
274
+ }
275
+
276
+ async function setActiveColoring(
277
+ modelId: string,
278
+ componentIds: string[],
279
+ activeColoringType: string,
280
+ ): Promise<unknown> {
281
+ await mutateEdges(modelId, componentIds, { coloring: { active: activeColoringType } });
282
+ if (activeColoringType === "vertex") {
283
+ const result = await applyVertexAttribute(modelId, componentIds);
284
+ return result;
285
+ }
286
+ const result = await setColor(modelId, componentIds, edgesColor(modelId, componentIds[0]));
287
+ return result;
288
+ }
289
+
290
+ async function setVertexAttributeName(
291
+ modelId: string,
292
+ componentIds: string[],
293
+ name: string,
294
+ ): Promise<unknown> {
295
+ const item = lastItem(modelId, componentIds[0], name);
296
+ await mutateVertexAttribute(modelId, componentIds, { name, item });
297
+ const result = await applyVertexAttribute(modelId, componentIds);
298
+ return result;
299
+ }
300
+
301
+ async function setVertexAttributeItem(
302
+ modelId: string,
303
+ componentIds: string[],
304
+ item: number,
305
+ ): Promise<unknown> {
306
+ await mutateVertexAttribute(modelId, componentIds, { item });
307
+ const result = await applyVertexAttribute(modelId, componentIds);
308
+ return result;
309
+ }
310
+
311
+ async function setVertexAttributeRange(
312
+ modelId: string,
313
+ componentIds: string[],
314
+ minimum: number,
315
+ maximum: number,
316
+ ): Promise<unknown> {
317
+ await mutateStoredConfig(modelId, componentIds, { minimum, maximum });
318
+ const result = await applyVertexAttribute(modelId, componentIds);
319
+ return result;
320
+ }
321
+
322
+ async function setVertexAttributeColorMap(
323
+ modelId: string,
324
+ componentIds: string[],
325
+ colorMap: string | undefined,
326
+ ): Promise<unknown> {
327
+ await mutateStoredConfig(modelId, componentIds, { colorMap });
328
+ const result = await applyVertexAttribute(modelId, componentIds);
329
+ return result;
330
+ }
331
+
332
+ async function setVertexAttributeNoDataColor(
333
+ modelId: string,
334
+ componentIds: string[],
335
+ no_data_color: RGBAColor,
336
+ ): Promise<unknown> {
337
+ await mutateStoredConfig(modelId, componentIds, { no_data_color });
338
+ const result = await applyVertexAttribute(modelId, componentIds);
339
+ return result;
340
+ }
341
+
342
+ async function styledComponentIds(modelId: string): Promise<string[]> {
343
+ const componentIds = await dataStore.getMeshComponentGeodeIds(modelId, type);
344
+ if (dataStyleState.getModelComponentTypeStyle(modelId, type).edges !== undefined) {
345
+ return componentIds;
346
+ }
347
+ return componentIds.filter(
348
+ (componentId) => dataStyleState.getComponentStyle(modelId, componentId).edges !== undefined,
349
+ );
350
+ }
351
+
352
+ // The model edges routes override every component, so the explicit edges styles follow
353
+ async function mutateStyledEdges(modelId: string, values: EdgesStyle): Promise<void> {
354
+ const componentIds = await styledComponentIds(modelId);
355
+ if (componentIds.length > 0) {
356
+ await mutateEdges(modelId, componentIds, values);
357
+ }
358
+ }
359
+
360
+ // Only components with an explicit edges style are sent, the others follow the model edges
361
+ async function applyEdgesStyle(modelId: string): Promise<void> {
362
+ const componentIds = await styledComponentIds(modelId);
363
+ function style(componentId?: string): EdgesStyle {
364
+ return edgesStyle(modelId, componentId);
365
+ }
366
+ await Promise.all([
367
+ ...groupBy(componentIds, (id) => String(style(id).visibility)).map(async (ids) => {
368
+ await setVisibility(modelId, ids, edgesVisibility(modelId, ids[0]));
369
+ }),
370
+ ...groupBy(componentIds, (id) => String(style(id).width)).map(async (ids) => {
371
+ await setWidth(modelId, ids, edgesWidth(modelId, ids[0]));
372
+ }),
373
+ ...groupBy(componentIds, (id) => JSON.stringify(style(id).coloring)).map(async (ids) => {
374
+ await setActiveColoring(modelId, ids, activeColoring(modelId, ids[0]));
375
+ }),
376
+ ]);
377
+ }
378
+
379
+ return {
380
+ visibility: edgesVisibility,
381
+ width: edgesWidth,
382
+ color: edgesColor,
383
+ activeColoring,
384
+ vertexAttributeName,
385
+ vertexAttributeItem,
386
+ vertexAttributeRange,
387
+ vertexAttributeColorMap,
388
+ vertexAttributeNoDataColor,
389
+ setVisibility,
390
+ setWidth,
391
+ setColor,
392
+ setActiveColoring,
393
+ setVertexAttributeName,
394
+ setVertexAttributeItem,
395
+ setVertexAttributeRange,
396
+ setVertexAttributeColorMap,
397
+ setVertexAttributeNoDataColor,
398
+ mutateStyledEdges,
399
+ applyEdgesStyle,
400
+ };
401
+ }
402
+
403
+ type ModelComponentEdgesStyle = ReturnType<typeof useModelComponentEdgesStyle>;
404
+
405
+ export { EDGES_COMPONENT_TYPES, useModelComponentEdgesStyle };
406
+ export type { ModelComponentEdgesStyle };
@@ -1,13 +1,17 @@
1
1
  import { useModelEdgesCommonStyle } from "./common";
2
2
  import { useModelEdgesVisibilityStyle } from "./visibility";
3
+ import { useModelEdgesWidthStyle } from "./width";
3
4
 
4
5
  export function useModelEdgesStyle(): ReturnType<typeof useModelEdgesCommonStyle> &
5
- ReturnType<typeof useModelEdgesVisibilityStyle> {
6
+ ReturnType<typeof useModelEdgesVisibilityStyle> &
7
+ ReturnType<typeof useModelEdgesWidthStyle> {
6
8
  const modelEdgesCommonStyle = useModelEdgesCommonStyle();
7
9
  const modelEdgesVisibilityStyle = useModelEdgesVisibilityStyle();
10
+ const modelEdgesWidthStyle = useModelEdgesWidthStyle();
8
11
 
9
12
  return {
10
13
  ...modelEdgesCommonStyle,
11
14
  ...modelEdgesVisibilityStyle,
15
+ ...modelEdgesWidthStyle,
12
16
  };
13
17
  }
@@ -1,7 +1,12 @@
1
1
  // Third party imports
2
2
  import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_typed_schemas.js";
3
3
 
4
+ import {
5
+ EDGES_COMPONENT_TYPES,
6
+ useModelComponentEdgesStyle,
7
+ } from "@ogw_internal/stores/data_style/model/edges/component";
4
8
  import { useModelEdgesCommonStyle } from "./common";
9
+ import { useModelEdgesWidthStyle } from "./width";
5
10
  import { useViewerStore } from "@ogw_front/stores/viewer";
6
11
  import { whenDefined } from "@ogw_internal/stores/data_style/when_defined";
7
12
 
@@ -17,6 +22,10 @@ interface ModelEdgesVisibilityStyleApi {
17
22
  export function useModelEdgesVisibilityStyle(): ModelEdgesVisibilityStyleApi {
18
23
  const viewerStore = useViewerStore();
19
24
  const modelEdgesCommonStyle = useModelEdgesCommonStyle();
25
+ const modelEdgesWidthStyle = useModelEdgesWidthStyle();
26
+ const componentsEdgesStyles = EDGES_COMPONENT_TYPES.map((type) =>
27
+ useModelComponentEdgesStyle(type),
28
+ );
20
29
 
21
30
  function modelEdgesVisibility(id: string): boolean | undefined {
22
31
  const { visibility } = modelEdgesCommonStyle.modelEdgesStyle(id);
@@ -32,7 +41,12 @@ export function useModelEdgesVisibilityStyle(): ModelEdgesVisibilityStyleApi {
32
41
  { schema, params },
33
42
  {
34
43
  response_function: async () => {
35
- await modelEdgesCommonStyle.mutateModelEdgesStyle(id, { visibility });
44
+ await Promise.all([
45
+ modelEdgesCommonStyle.mutateModelEdgesStyle(id, { visibility }),
46
+ ...componentsEdgesStyles.map(async (edgesStyle) => {
47
+ await edgesStyle.mutateStyledEdges(id, { visibility });
48
+ }),
49
+ ]);
36
50
  },
37
51
  },
38
52
  );
@@ -40,11 +54,18 @@ export function useModelEdgesVisibilityStyle(): ModelEdgesVisibilityStyleApi {
40
54
  }
41
55
 
42
56
  async function applyModelEdgesStyle(id: string): Promise<unknown[]> {
43
- const result = await whenDefined(modelEdgesVisibility(id), async (visibility) => {
57
+ const visibilityResult = await whenDefined(modelEdgesVisibility(id), async (visibility) => {
44
58
  const applied = await setModelEdgesVisibility(id, visibility);
45
59
  return applied;
46
60
  });
47
- return [result];
61
+ const widthResult = await whenDefined(
62
+ modelEdgesWidthStyle.modelEdgesWidth(id),
63
+ async (width) => {
64
+ const applied = await modelEdgesWidthStyle.setModelEdgesWidth(id, width);
65
+ return applied;
66
+ },
67
+ );
68
+ return [visibilityResult, widthResult];
48
69
  }
49
70
 
50
71
  return {