@abi-software/flatmap-viewer 2.3.0-b.2 → 2.3.2-b.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.
@@ -0,0 +1,143 @@
1
+ /******************************************************************************
2
+
3
+ Flatmap viewer and annotation tool
4
+
5
+ Copyright (c) 2019 - 2023 David Brooks
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
18
+
19
+ ******************************************************************************/
20
+
21
+ export class PathControl
22
+ {
23
+ constructor(flatmap, pathTypes)
24
+ {
25
+ this._flatmap = flatmap;
26
+ this._map = undefined;
27
+ this.__pathTypes = pathTypes;
28
+ }
29
+
30
+ getDefaultPosition()
31
+ //==================
32
+ {
33
+ return 'top-right';
34
+ }
35
+
36
+ onAdd(map)
37
+ //========
38
+ {
39
+ this._map = map;
40
+ this._container = document.createElement('div');
41
+ this._container.className = 'maplibregl-ctrl';
42
+ this._container.id = 'flatmap-nerve-key';
43
+
44
+ this._legend = document.createElement('div');
45
+ this._legend.id = 'nerve-key-text';
46
+ this._legend.className = 'flatmap-nerve-grid';
47
+
48
+ const innerHTML = [];
49
+ innerHTML.push(`<label for="path-all-paths">ALL PATHS:</label><div class="nerve-line"></div><input id="path-all-paths" type="checkbox" checked/>`);
50
+ this.__checkedCount = 0;
51
+ for (const path of this.__pathTypes) {
52
+ const checked = !('enabled' in path) || path.enabled ? 'checked' : '';
53
+ if (checked != '') {
54
+ this.__checkedCount += 1;
55
+ }
56
+ const colour = path.colour || '#440';
57
+ const style = path.dashed ? `background: repeating-linear-gradient(to right,${colour} 0,${colour} 6px,transparent 6px,transparent 9px);`
58
+ : `background: ${colour};`;
59
+
60
+ innerHTML.push(`<label for="path-${path.type}">${path.label}</label><div class="nerve-line" style="${style}"></div><input id="path-${path.type}" type="checkbox" ${checked}/>`);
61
+ }
62
+ this._legend.innerHTML = innerHTML.join('\n');
63
+ this.__halfCount = Math.trunc(this.__pathTypes.length/2);
64
+
65
+ this._button = document.createElement('button');
66
+ this._button.id = 'nerve-key-button';
67
+ this._button.className = 'control-button text-button';
68
+ this._button.setAttribute('type', 'button');
69
+ this._button.setAttribute('aria-label', 'Nerve paths legend');
70
+ this._button.setAttribute('control-visible', 'false');
71
+ this._button.textContent = 'PATHS';
72
+ this._button.title = 'Show/hide neuron paths';
73
+ this._container.appendChild(this._button);
74
+
75
+ this._container.addEventListener('click', this.onClick_.bind(this));
76
+ return this._container;
77
+ }
78
+
79
+ onRemove()
80
+ //========
81
+ {
82
+ this._container.parentNode.removeChild(this._container);
83
+ this._map = undefined;
84
+ }
85
+
86
+ onClick_(event)
87
+ //=============
88
+ {
89
+ if (event.target.id === 'nerve-key-button') {
90
+ if (this._button.getAttribute('control-visible') === 'false') {
91
+ this._container.appendChild(this._legend);
92
+ this._button.setAttribute('control-visible', 'true');
93
+ const allPathsCheckbox = document.getElementById('path-all-paths');
94
+ allPathsCheckbox.indeterminate = this.__checkedCount < this.__pathTypes.length
95
+ && this.__checkedCount > 0;
96
+ this._legend.focus();
97
+ } else {
98
+ this._legend = this._container.removeChild(this._legend);
99
+ this._button.setAttribute('control-visible', 'false');
100
+ }
101
+ } else if (event.target.tagName === 'INPUT') {
102
+ if (event.target.id === 'path-all-paths') {
103
+ if (event.target.indeterminate) {
104
+ event.target.checked = (this.__checkedCount >= this.__halfCount);
105
+ event.target.indeterminate = false;
106
+ }
107
+ if (event.target.checked) {
108
+ this.__checkedCount = this.__pathTypes.length;
109
+ } else {
110
+ this.__checkedCount = 0;
111
+ }
112
+ for (const path of this.__pathTypes) {
113
+ const pathCheckbox = document.getElementById(`path-${path.type}`);
114
+ if (pathCheckbox) {
115
+ pathCheckbox.checked = event.target.checked;
116
+ this._flatmap.enablePath(path.type, event.target.checked);
117
+ }
118
+ }
119
+ } else if (event.target.id.startsWith('path-')) {
120
+ const pathType = event.target.id.substring(5);
121
+ this._flatmap.enablePath(pathType, event.target.checked);
122
+ if (event.target.checked) {
123
+ this.__checkedCount += 1;
124
+ } else {
125
+ this.__checkedCount -= 1;
126
+ }
127
+ const allPathsCheckbox = document.getElementById('path-all-paths');
128
+ if (this.__checkedCount === 0) {
129
+ allPathsCheckbox.checked = false;
130
+ allPathsCheckbox.indeterminate = false;
131
+ } else if (this.__checkedCount === this.__pathTypes.length) {
132
+ allPathsCheckbox.checked = true;
133
+ allPathsCheckbox.indeterminate = false;
134
+ } else {
135
+ allPathsCheckbox.indeterminate = true;
136
+ }
137
+ }
138
+ }
139
+ event.stopPropagation();
140
+ }
141
+ }
142
+
143
+ //==============================================================================
@@ -31,24 +31,33 @@ export class SystemsControl extends Control
31
31
  this.__systems = systems;
32
32
  }
33
33
 
34
- __innerLinesHTML()
35
- //================
34
+ _addControlDetails()
35
+ //===============
36
36
  {
37
- const html = [];
37
+ let lines = 0;
38
+ let enabled = 0;
38
39
  for (const system of this.__systems) {
39
- html.push(`<label for="${this.__prefix}${system.id}" style="background: ${system.colour};">${system.name}</label><input id="${this.__prefix}${system.id}" type="checkbox" checked/>`);
40
+ const input = this._addControlLine(`${this.__prefix}${system.id}`, system.name, `background: ${system.colour};`);
41
+ if (system.enabled) {
42
+ input.checked = true;
43
+ enabled += 1;
44
+ }
45
+ lines += 1;
40
46
  }
41
- return html;
47
+ return {
48
+ enabled: enabled,
49
+ total: lines
50
+ };
42
51
  }
43
52
 
44
- __enableAll(enable)
45
- //=================
53
+ _enableAll(enable)
54
+ //================
46
55
  {
47
56
  for (const system of this.__systems) {
48
57
  const checkbox = document.getElementById(`${this.__prefix}${system.id}`);
49
58
  if (checkbox) {
50
59
  checkbox.checked = enable;
51
- this.__flatmap.enableSystem(system.name, enable);
60
+ this.__flatmap.enableSystem(system.id, enable);
52
61
  }
53
62
  }
54
63
  }
@@ -58,7 +67,7 @@ export class SystemsControl extends Control
58
67
  {
59
68
  for (const system of this.__systems) {
60
69
  if (id === system.id) {
61
- this.__flatmap.enableSystem(system.name, enable);
70
+ this.__flatmap.enableSystem(system.id, enable);
62
71
  }
63
72
  }
64
73
  }
@@ -180,10 +180,13 @@ class FlatMap
180
180
  if (this._userInteractions === null) {
181
181
  this.setupUserInteractions_();
182
182
  } else if (this._initialState === null) {
183
+ this._map.setMinZoom(3.0);
184
+ this._map.setMaxBounds(null);
185
+ this._map.setRenderWorldCopies(true);
183
186
  this._bounds = this._map.getBounds();
184
- this._map.setMaxBounds(this._bounds);
185
- const sw = maplibregl.MercatorCoordinate.fromLngLat(this._bounds.toArray()[0]);
186
- const ne = maplibregl.MercatorCoordinate.fromLngLat(this._bounds.toArray()[1]);
187
+ const bounds = this._bounds.toArray();
188
+ const sw = maplibregl.MercatorCoordinate.fromLngLat(bounds[0]);
189
+ const ne = maplibregl.MercatorCoordinate.fromLngLat(bounds[1]);
187
190
  this.__normalised_origin = [sw.x, ne.y];
188
191
  this.__normalised_size = [ne.x - sw.x, sw.y - ne.y];
189
192
  if ('state' in this._options) {
@@ -260,20 +263,6 @@ class FlatMap
260
263
  this._map.zoomOut();
261
264
  }
262
265
 
263
- /**
264
- * Toggle the visibility of paths on the map.zoomIn
265
- *
266
- * * If some paths are hidden then all paths are made visible.
267
- * * If all paths are visible then they are all hidden.
268
- */
269
- togglePaths()
270
- //===========
271
- {
272
- if (this._userInteractions !== null) {
273
- this._userInteractions.togglePaths();
274
- }
275
- }
276
-
277
266
  /**
278
267
  * @returns {Array.<{type: string, label: string, colour: string}>} an array of objects giving the path types
279
268
  * present in the map along with their
@@ -283,7 +272,7 @@ class FlatMap
283
272
  //=========
284
273
  {
285
274
  if (this._userInteractions !== null) {
286
- return this._userInteractions.pathways.pathTypes();
275
+ return this._userInteractions.pathManager.pathTypes();
287
276
  }
288
277
  }
289
278
 
@@ -298,7 +287,7 @@ class FlatMap
298
287
  //===============================
299
288
  {
300
289
  if (this._userInteractions !== null) {
301
- this._userInteractions.enablePath(pathType, enable);
290
+ this._userInteractions.enablePathsByType(pathType, enable);
302
291
  }
303
292
  }
304
293
 
@@ -313,7 +302,7 @@ class FlatMap
313
302
  //======================================
314
303
  {
315
304
  if (this._userInteractions !== null) {
316
- this._userInteractions.enableSckanPath(sckanState, enable);
305
+ this._userInteractions.enableSckanPaths(sckanState, enable);
317
306
  }
318
307
  }
319
308
 
@@ -535,7 +524,7 @@ class FlatMap
535
524
  }
536
525
  if (featureIds.length == 0 && this._userInteractions !== null) {
537
526
  // We still haven't found a feature, so check connectivity
538
- featureIds.extend(this._userInteractions.pathwaysFeatureIds(anatomicalIds));
527
+ featureIds.extend(this._userInteractions.pathFeatureIds(anatomicalIds));
539
528
  }
540
529
  return featureIds;
541
530
  }
@@ -819,7 +808,7 @@ class FlatMap
819
808
  /**
820
809
  * Get a list of a FC flatmap's systems.
821
810
  *
822
- * @return {Array.Object.<{name: string, colour: string}>} An array with system details
811
+ * @return {Array.Object.<{id: string, name: string, colour: string, enabled: boolean}>} An array with system details
823
812
  */
824
813
  getSystems()
825
814
  //==========
@@ -830,15 +819,15 @@ class FlatMap
830
819
  }
831
820
 
832
821
  /**
833
- * @param {string} systemName The name of the system to enable
822
+ * @param {string} systemId The identifier of the system to enable
834
823
  * @param {boolean} enable Show or hide the system. Defaults to ``true`` (show)
835
824
  *
836
825
  */
837
- enableSystem(systemName, enable=true)
826
+ enableSystem(systemId, enable=true)
838
827
  //===================================
839
828
  {
840
829
  if (this._userInteractions !== null) {
841
- return this._userInteractions.enableSystem(systemName, enable);
830
+ return this._userInteractions.enableSystem(systemId, enable);
842
831
  }
843
832
  }
844
833