@pirireis/webglobeplugins 0.3.6 → 0.3.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.
@@ -160,7 +160,7 @@ export default class Plugin {
160
160
  };
161
161
 
162
162
  this.lineVao = this.lineProgram.createVAO(
163
- ...['centerCoords', 'targetCoords', 'dashRatio', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
163
+ ...['centerCoords', 'targetCoords', 'dashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
164
164
  this.ringVao = this.ringProgram.createVAO(
165
165
  ...['centerCoords', 'startAngle', 'tailAngle', 'rgba', 'radius', 'rgbaMode'].map(key => obj(this.bufferManagersCompMap.get(key))));
166
166
  {
@@ -174,7 +174,7 @@ export default class Plugin {
174
174
  }
175
175
  // centerObj, startAngleObj, radiusObj, colorObj, dashRatioObj, dashOpacityObj
176
176
  this.circleVao = this.circleProgram.createVAO(
177
- ...["centerCoords", "startAngle", "bigRadius", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key))));
177
+ ...["centerCoords", "bigRadius", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key))));
178
178
  }
179
179
 
180
180
 
@@ -216,17 +216,21 @@ export default class Plugin {
216
216
  * @property {number} dashOpacity 0-1
217
217
  * @property {number} circleDashAngle 0-360
218
218
  * @param {Array<item>} items
219
- * @param {Array<string>} injectionsSubSetIDs | textContextInjectionMap keys to be used for writing text.
219
+ * @param {Array<string>} textWriterInjectionSubSetIDs | textContextInjectionMap keys to be used for writing text.
220
220
  */
221
- insertBulk(items, injectionsSubSetIDs = []) {
221
+ insertBulk(items, textWriterInjectionSubSetIDs = []) {
222
222
  const { globe, bufferOrchestrator, bufferManagersCompMap } = this;// angleTextContext, distanceTextContext,
223
- const injectionsSubSet = injectionsSubSetIDs.map((id) => this._textContextInjectionMap.get(id));
223
+ const textWriterInjectionSubSets = textWriterInjectionSubSetIDs.map((id) => this._textContextInjectionMap.get(id));
224
224
  const data = []
225
225
  for (let item of items) {
226
- this._insertTexts(item, injectionsSubSet);
226
+ this._insertTexts(item, textWriterInjectionSubSets);
227
227
  data.push(this.__insertAdaptor(item));
228
228
  }
229
229
  bufferOrchestrator.insertBulk(data, bufferManagersCompMap);
230
+ this._textContextInjectionMap.forEach((v) => {
231
+ const { writer } = v;
232
+ writer.updateOpacityBulk(items, (e) => e.key, (e) => e.rgba[3]);
233
+ })
230
234
  globe.DrawRender();
231
235
  }
232
236
 
@@ -251,7 +255,7 @@ export default class Plugin {
251
255
  */
252
256
  updateCoordinatesBulk(items, textWriterInjectionSubSetIDs = []) { //TODO
253
257
  const injectionsSubSet = textWriterInjectionSubSetIDs.map((id) => this._textContextInjectionMap.get(id));
254
- const { globe, bufferOrchestrator, bufferManagersCompMap, angleTextContext, distanceTextContext } = this;
258
+ const { globe, bufferOrchestrator, bufferManagersCompMap, } = this;
255
259
  const data = []
256
260
  for (let item of items) {
257
261
  this._insertTexts(item, injectionsSubSet);
@@ -270,12 +274,22 @@ export default class Plugin {
270
274
  * @param {*} textWriterInjectionSubSetIDs
271
275
  * Do NOT send empty data if property ID of this data is entered or NaN is loaded to the buffer, resulting in an unwanted behaviour.
272
276
  */
273
- updatePartial(items, propertyIDs = [], textWriterInjectionSubSetIDs = []) {
277
+ updatePartial(items, propertyIDs = [], textWriterInjectionSubSetIDs = []) { // textWriterInjectionSubSetIDs = []
274
278
  if (propertyIDs.length === 0) console.warn("updatePartial is called with no target propertyIDs");
275
279
  const { _textContextInjectionMap, bufferOrchestrator, bufferManagersCompMap } = this;
276
280
  const writers = textWriterInjectionSubSetIDs.map((x) => _textContextInjectionMap.get(x));
277
281
  for (let item of items) { this._insertTexts(item, writers) }
278
282
  bufferOrchestrator.updateBulk(items, bufferManagersCompMap, propertyIDs);
283
+ // patch to update text opacity
284
+ for (const property of propertyIDs) {
285
+ if (property === "rgba") {
286
+ this._textContextInjectionMap.forEach((v) => {
287
+ const { writer } = v;
288
+ writer.updateOpacityBulk(items, (e) => e.key, (e) => e.rgba[3]);
289
+ })
290
+
291
+ }
292
+ }
279
293
  }
280
294
 
281
295
 
@@ -359,6 +373,7 @@ export default class Plugin {
359
373
 
360
374
 
361
375
 
376
+
362
377
  _insertTexts(item, textWriterInjectionSubSet) {
363
378
  //TODO This method can be more performant if it works horizontally, tabular
364
379
  textWriterInjectionSubSet.forEach((v) => {
@@ -369,6 +384,7 @@ export default class Plugin {
369
384
  });
370
385
  }
371
386
 
387
+
372
388
  _deleteTexts(keys) {
373
389
  this._textContextInjectionMap.forEach((e) => {
374
390
  e.writer.deleteTextBulk(keys);
@@ -0,0 +1,336 @@
1
+
2
+ ## insertBulk
3
+ ```json
4
+ [
5
+ {
6
+ "chainID": "Mağrib",
7
+ "points": [
8
+ {
9
+ "id": "Fas",
10
+ "long": 0,
11
+ "lat": 0,
12
+ },
13
+ {
14
+ "id":"Cezayir",
15
+ "long": 10,
16
+ "lat": 20,
17
+ },
18
+ {
19
+ "id":"Tunus",
20
+ "long": 10,
21
+ "lat": 15
22
+ }
23
+ ],
24
+ "rgba": [1,0,0,1],
25
+ "dashRatio": 0.1,
26
+ "dashOpacity": 0.5,
27
+ "circleDashAngle": 15,
28
+ },
29
+ ]
30
+ ```
31
+
32
+ ```js
33
+ // ["distance"]
34
+ updateCoordinatesBulk( items, contextTextWriterIDs=[]) {
35
+ for ( const item of items){
36
+ this._updateCoordsChain(item.chainID, item.points);
37
+ }
38
+ }
39
+
40
+ _updateCoordsChain(chainID, nodes){
41
+ const chain = this._chainMap(chainID); // chain is a `list`
42
+ const updateIDs = [];
43
+ for ( let i = 0; i< chain.length; i++){
44
+ if ( )
45
+ }
46
+ }
47
+ ```
48
+
49
+
50
+ ```js
51
+ // text
52
+ const textContextMap = new Map(
53
+ [
54
+ [
55
+ "distance",
56
+ {
57
+ writer: new ContextTextWriter(globe,),
58
+ coordsAdaptor: (item, index, array) => { //
59
+ const { long, lat } = globe.Math.GetMidPoint(item.long, item.lat, item.endLong, item.endLat);
60
+ return {
61
+ long,
62
+ lat,
63
+ }
64
+ },
65
+ textAdaptor: (item) => {
66
+ const distance = globe.Math.GetDist2D(item.long, item.lat, item.endLong, item.endLat);
67
+ return distance.toFixed(2) + "m";
68
+ },
69
+
70
+ }
71
+ ]
72
+ ]
73
+ )
74
+
75
+ // ["distance"]
76
+ updateCoordinatesBulk(items, textWriterInjectionSubSetIDs = []) {
77
+
78
+ }
79
+
80
+ _updateChainCoords(chainID, points){
81
+ this._updateCoordsBuffer();
82
+ }
83
+
84
+ ```
85
+
86
+
87
+ ---
88
+
89
+ ```js
90
+ const connectNaive = (p1, p2) => {p1.set("to",p2);p2.set("from":p1)};
91
+ const Tanca = new Map([["long", 0],[ "lat",0], ["from", null], ["to":null]]);
92
+ const Cebelitarik = new Map([["long", 0],[ "lat",0], ["from", null], ["to":null]]);
93
+ const Cezayir = new Map([["long", 0],[ "lat",0], ["from", null], ["to":null]]);
94
+ const Tunus = new Map([["long", 0],[ "lat",0], ["from", null], ["to":null]]);
95
+ const Tanca = {id, long,lat, toID}
96
+
97
+ plugin.insertBulk([
98
+ {
99
+ chainID: "Mağrib",
100
+ points: [
101
+ {Tanca, to: Cebelitarik}
102
+ {Cebelitarik, to:"Cezayir"},
103
+ {Cezayir, to: "Tunus"}, // implicitly connects to Tunus
104
+ {Tunus, to:null}
105
+ ]),
106
+ rgba: [1.0, 0.0, 0.0, 1.0],
107
+ dashRatio: 0.1,
108
+ dashOpacity: 0.5,
109
+ circleDashAngle: 15,
110
+ }
111
+ ]);
112
+ ```
113
+ Advantage: User knows patterns of position data.
114
+ Disadventage: Not json.
115
+ Bug: How to insert into middle?
116
+
117
+
118
+ coordinateAdaptor => (v, i, array) => {
119
+ return {
120
+ (v.long + array[i+1].long) / 2.0,
121
+ }
122
+ }
123
+
124
+ ```js
125
+ const connect = (chainMap, chainID, node) => {
126
+ const chain = chainMap.get(chainID);
127
+
128
+ }
129
+
130
+ ```
131
+ ---
132
+
133
+ ## updateCoordinatesBulk
134
+
135
+ updates pointMap;
136
+ then updates buffers from updated version of pointMap;
137
+
138
+ imparatively open next or prev
139
+
140
+ ```json
141
+ [
142
+ {
143
+ "chainID": "Mağrib",
144
+ "points": [
145
+ {
146
+ ""Fas"": {
147
+ " "l"ong": 100,
148
+ "lat": 30
149
+ }
150
+ }
151
+ ]
152
+ }
153
+ ]
154
+ ```
155
+
156
+
157
+ ## deleteBulk
158
+
159
+ ```json
160
+ [
161
+ {
162
+ "chainID": "Mağrib",
163
+ "all": false,
164
+ "points": [
165
+ "Fas"
166
+ ]
167
+ }
168
+ ]
169
+ ```
170
+
171
+
172
+ ## ContextTextWriter
173
+
174
+ ```js
175
+ {
176
+
177
+ writer: new ContextTextWriter(globe),
178
+ coordsAdaptor: (item) =>
179
+ if (item.get("next") === null) return false;
180
+ const goe = {
181
+ long: point.get("long"),
182
+ lat: point.get("lat"),
183
+ endLong: point.get("next")?.get("long"),
184
+ endLat: point.get("next")?.get("lat")
185
+ }
186
+ return globe.getMidPoint(geo.long,geo.lat, geo.endLong, geo.endLat)
187
+ }
188
+ },
189
+ textAdaptor: (item) => {
190
+ const angle = item.long, item.lat, item.endLong, item.endLat
191
+ );
192
+ if (angle < 0) {
193
+ return (angle + 360).toFixed(2) + "°";
194
+ }
195
+ return angle.toFixed(2) + "°";
196
+ },
197
+ }
198
+ ```
199
+
200
+ ---
201
+
202
+ ```js
203
+ class Chain{
204
+ constractor(id, {rgba = [1,0,0,1], dashOpacity = 1, dashRatio = 0.1, circleDashAngle = 30 } = []){
205
+ this.id = 0;
206
+ this.idMap = new Map();
207
+ this.list = [];
208
+ this._rgba = rgba;
209
+ this._dashOpacity = dashOpacity;
210
+ this._dashRatio = dashRatio;
211
+ this._circleDashAngle = this.circleDashAngle;
212
+ }
213
+
214
+ add(item, fromID = null){
215
+ this.idMap.set(item.id, item);
216
+ let drawIndex;
217
+ if (from === null) {
218
+ this.list.push(item);
219
+ drawIndex = this.list.length - 1;
220
+ }
221
+
222
+ for ( let i = 0 ; i < this.list.length ; i++){
223
+ if ( fromID === this.list[i].id) {
224
+ drawIndex = i;
225
+ this.list.splice(i, 0, item);
226
+ }
227
+ }
228
+
229
+ this._update( [i, i-1]);
230
+ }
231
+
232
+ nextID(id){
233
+ // for loop if data source is a list. not performand.
234
+ // pointer if data rouce is a node. Clunky
235
+ // reconstract the map on (!append) operation.
236
+ }
237
+ }
238
+
239
+ ```
240
+
241
+ ---
242
+ ## Design Priorities
243
+
244
+ user interaction. insert, update, get data
245
+ some processies are callback. callbacks uses the pattern user insert the data
246
+
247
+ ContextTextWriter Plugin interaction I provided was imparative. I fit to that context because item had required data.
248
+ Current context has uses next objects data in the chain.
249
+
250
+ What is the imparative way to get next data?
251
+ A `function` - A `pointer`
252
+ If I go with a `pointer` I need to get the data with a `pointer`
253
+ How to I provide a `function` to get the next data?
254
+ ```js
255
+ getNodeData(chainID, id){
256
+ return this.chainMap.get(chainID).get(id)
257
+ }
258
+ // Problem to use this function the object of getNodeData must be created before creating contextTextWriterMap.
259
+ ```
260
+
261
+ how minimally hold the data
262
+
263
+ how to render
264
+
265
+
266
+
267
+ Edit mod. user asks chain data and bind placeholders.
268
+
269
+
270
+
271
+ ## API
272
+
273
+
274
+
275
+ getChain(chainID) => {pointID, long, lat}
276
+
277
+
278
+
279
+ ## explore pattern
280
+
281
+ (x, index, array ) doesnt fit.
282
+
283
+
284
+
285
+
286
+ ## insertBulk
287
+ ```json
288
+ [
289
+ {
290
+ "chainID": "Mağrib",
291
+ "points": [
292
+ {
293
+ "id": "Fas",
294
+ "long": 0,
295
+ "lat": 0,
296
+ "to": "Cezayir"
297
+ },
298
+ {
299
+ "id":"Cezayir",
300
+ "long": 10,
301
+ "lat": 20,
302
+ "to": "Tunus"
303
+ },
304
+ {
305
+ "id":"Tunus",
306
+ "long": 10,
307
+ "lat": 15
308
+ }
309
+ ],
310
+ "rgba": [1,0,0,1],
311
+ "dashRatio": 0.1,
312
+ "dashOpacity": 0.5,
313
+ "circleDashAngle": 15,
314
+ },
315
+ ]
316
+ ```
317
+
318
+ ```js
319
+ // ["distance"]
320
+ updateCoordinatesBulk( items, contextTextWriterIDs=[]) {
321
+ for ( const item of items){
322
+ this._updateCoordsChain(item.chainID, item.points);
323
+ }
324
+ }
325
+
326
+ _updateCoordsChain(chainID, nodes){
327
+ const chain = this._chainMap(chainID); // chain is a `list`
328
+
329
+
330
+ }
331
+ ```
332
+
333
+
334
+ ##
335
+ Get data from user with `to` keyword. implicitly add from keyword
336
+
@@ -0,0 +1,203 @@
1
+ import { keyMethod } from "./util";
2
+ /**
3
+ * set and get node data
4
+ * node indexes;
5
+ */
6
+ export class ChainListMap {
7
+
8
+ constructor() {
9
+ this._chainMap = new Map();
10
+ this._chainSideProperties = new Map();
11
+ this._indexMap = new Map(); // hold list index of lastly updated nodes. on add delete goes empty
12
+ }
13
+
14
+ getChain(chainKey) {
15
+ if (!this._chainMap.has(chainKey)) this._chainMap.set(chainKey, []);
16
+ return this._chainMap.get(chainKey);
17
+ }
18
+
19
+ /**
20
+ *
21
+ * @param {*} node
22
+ * @param {*} chainKey
23
+ * @param {string|null} theNodeKeyFront
24
+ */
25
+ addNode(node, chainKey, theNodeKeyFront = null) {
26
+ const chain = this.getChain(chainKey);
27
+
28
+ if (theNodeKeyFront == null) {
29
+ chain.push(node);
30
+ return;
31
+ }
32
+
33
+ for (let i = 0; i < chain.length; i++) {
34
+ const n_ode = chain[i];
35
+ if (n_ode == theNodeKeyFront) {
36
+ chain.splice(i, 0, node);
37
+ return;
38
+ }
39
+ }
40
+ this._resetIndexChain(chainKey);
41
+ }
42
+
43
+ deleteNode(chainKey, nodeKey) {
44
+ const index = this.getIndexOfNode(chainKey, nodeKey);
45
+ const chain = this._chainMap.get(chainKey);
46
+ chain.splice(index, 1);
47
+ this._resetIndexChain(chainKey);
48
+ }
49
+
50
+ deleteNodesBelongToAChain(chainKey, nodeKeys) {
51
+ const chain = this._chainMap.get(chainKey);
52
+ const compKeys = [];
53
+ const removeSet = new Set(nodeKeys);
54
+ const newChain = []
55
+ for (const node of chain) {
56
+ const dKey = keyMethod(chainKey, node.key);
57
+ this._indexMap.delete(dKey);
58
+ if (removeSet.has(node.key)) {
59
+ compKeys.push(dKey);
60
+ } else {
61
+ newChain.push(node);
62
+ }
63
+ }
64
+ this._chainMap.set(chainKey, newChain);
65
+ return compKeys;
66
+ }
67
+
68
+ deleteChainAndReturnChainKeys(chainKey) {
69
+ const keys = this.getNodeKeysOfChain(chainKey);
70
+ this._chainMap.delete(chainKey);
71
+ for (const key of keys) this._indexMap.delete(key);
72
+ return keys;
73
+ }
74
+
75
+ updateNode(node, chainKey) {
76
+ const index = this.getIndexOfNode(chainKey, node.key)
77
+ const chain = this._chainMap.getChain(chainKey);
78
+ chain[index] = node;
79
+ }
80
+
81
+
82
+ setChain(chainKey, list) {
83
+ if (this._chainMap.has(chain)) this._flushIndexMap();
84
+ this._chainMap.set(chainKey, list);
85
+ }
86
+
87
+
88
+ setChainProperties(chainKey, properties) {
89
+ this._chainSideProperties.set(chainKey, properties);
90
+ }
91
+
92
+
93
+ /**
94
+ *
95
+ * @param {string} chainKey
96
+ * @param {Map} properties
97
+ * // after this method update text and buffer data of the chain
98
+ */
99
+ updateChainProperties(chainKey, properties) {
100
+
101
+ const memoryProperties = this._chainSideProperties.get(chainKey);
102
+ properties.forEach((value, key, m) => {
103
+ memoryProperties[key] = value;
104
+ })
105
+
106
+ }
107
+
108
+ getChainProperties(chainKey) {
109
+ this._chainSideProperties.get(chainKey);
110
+ }
111
+
112
+ /**
113
+ *
114
+ * @param {*} chainKey
115
+ * @param {*} callback | (value, index, array) => expexted output
116
+ */
117
+ calculateBufferPropertiesChain(chainKey, callback, result, nodeIndexes = null) {
118
+ const nodes = this._chainMap(chainKey);
119
+ const props = this._chainSideProperties(chainKey);
120
+ const iterator = nodeIndexes !== null ? nodeIndexes : nodes.keys();
121
+ for (const i of iterator) {
122
+
123
+ result.push(callback(chain[i], i, chain, probs));
124
+ }
125
+ }
126
+
127
+
128
+ /**
129
+ *
130
+ * @param {*} chainKey
131
+ * @param {*} textWriterObjs
132
+ * @param {*} nodeKeys use nodeKeys on updateCoordinatesOnly
133
+ */
134
+ textUpdate(chainKey, textWriterObjs, nodeIndexes = null) {
135
+ const chain = this.getChain(chainKey);
136
+
137
+ if (nodeKeys) {
138
+ textWriterObjs.forEach((v) => {
139
+ const { coordsAdaptor, textAdaptor, writer } = v;
140
+ for (const i in nodeIndexes) {
141
+ const value = chain[i];
142
+ const { long, lat } = coordsAdaptor(value, i, chain);
143
+ const text = textAdaptor(value, i, chain);
144
+ const opacity = opacityAdaptor(value, i, array);
145
+
146
+ writer.insertText(
147
+ keyMethod(chainKey, value.key),
148
+ lat,
149
+ long,
150
+ text,
151
+ opacity
152
+ );
153
+ }
154
+ });
155
+ return;
156
+ }
157
+
158
+ textWriterObjs.forEach((v) => {
159
+ const { coordsAdaptor, textAdaptor, opacityAdaptor, writer } = v;
160
+ chain.forEach((value, i, array) => {
161
+ const { lat, long } = coordsAdaptor(value, i, array);
162
+ const text = textAdaptor(value, i, array);
163
+ const opacity = opacityAdaptor(value, i, array);
164
+ writer.insertText(item.key, lat, long, text);
165
+ });
166
+ });
167
+
168
+ }
169
+
170
+
171
+ getIndexOfNode(chainKey, nodeKey) {
172
+ const key = keyMethod(chainKey, nodeKey);
173
+ if (this._indexMap.has(key)) return this._indexMap.get(key);
174
+
175
+ const chain = this._chainMap.get(chainKey);
176
+ for (let i = 0; i < chain.length; i++) {
177
+ const node = chain[i];
178
+ this._indexMap.set(key, i);
179
+ if (node.key === nodeKey) {
180
+ return i
181
+ }
182
+ }
183
+ }
184
+
185
+ _flushIndexMap() {
186
+ this._indexMap.clear();
187
+ }
188
+
189
+ _resetIndexChain(chainKey) {
190
+ const chain = this._chainMap.get(chain);
191
+ for (let i = 0; i < chain.length; i++) {
192
+ const node = chain[i]
193
+ this._indexMap.set(keyMethod(chainKey, node.key), i);
194
+ }
195
+ }
196
+
197
+ getNodeKeysOfChain(chainKey) {
198
+ const chain = this._chainMap(chainKey);
199
+ return chain.map((v) => keyMethod(chainKey, v.key));
200
+ }
201
+
202
+
203
+ }
File without changes
File without changes