gridviz 3.0.40 → 3.0.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gridviz",
3
- "version": "3.0.40",
3
+ "version": "3.0.41",
4
4
  "description": "Visualization tool for gridded statistics",
5
5
  "keywords": [
6
6
  "statistics",
@@ -10,6 +10,17 @@ import { Dataset } from '../core/Dataset.js'
10
10
  // external
11
11
  import { json, csv } from 'd3-fetch'
12
12
 
13
+ // The tiles that are loaded are kept, so that going back to a place needs no new request. They are kept as lists of cell objects, which
14
+ // take a lot of memory (the education grid of the Statistical Atlas reached 1.5 GB after some minutes of panning and zooming), so the
15
+ // number of cells kept by all the TiledGrid together is limited (TiledGrid.maxCachedCells): when there are more, the tiles that were used
16
+ // the longest time ago are dropped, and loaded again if the map needs them. The tiles of the view on the screen, and those used in the
17
+ // last KEEP_MS ms, are never dropped.
18
+ const KEEP_MS = 3000
19
+ /** All the tiles kept, of every dataset. */
20
+ const keptTiles = new Set()
21
+ let keptCells = 0
22
+ const now = () => (typeof performance !== 'undefined' ? performance.now() : Date.now())
23
+
13
24
  /**
14
25
  * A tiled dataset, composed of CSV tiles.
15
26
  *
@@ -152,6 +163,8 @@ export class TiledGrid extends Dataset {
152
163
 
153
164
  // Skip already loaded tiles or retry failed ones
154
165
  if (this.cache[xT][yT] && this.cache[xT][yT] !== 'failed') {
166
+ // in the view: not to be dropped
167
+ if (typeof this.cache[xT][yT] === 'object') this.cache[xT][yT].lastUsed = now()
155
168
  ++processedTiles
156
169
  continue
157
170
  }
@@ -163,6 +176,7 @@ export class TiledGrid extends Dataset {
163
176
  this.loadTile(xT, yT, signal)
164
177
  .then((tile) => {
165
178
  this.cache[xT][yT] = tile
179
+ this._keep(tile)
166
180
 
167
181
  // Check if this is the last tile
168
182
  const isLastTile = ++processedTiles === totalTiles
@@ -235,6 +249,45 @@ export class TiledGrid extends Dataset {
235
249
  }
236
250
  }
237
251
 
252
+ /**
253
+ * Counts a tile that was loaded in the cells kept, and drops the tiles used the longest time ago when there are too many.
254
+ *
255
+ * @param {any} tile
256
+ * @private
257
+ */
258
+ _keep(tile) {
259
+ // a failed tile is the string 'failed', not a tile
260
+ if (!tile || typeof tile !== 'object' || !tile.cells) return
261
+ tile.lastUsed = now()
262
+ tile.owner = this
263
+ keptTiles.add(tile)
264
+ keptCells += tile.cells.length
265
+ if (keptCells <= TiledGrid.maxCachedCells) return
266
+ const limit = now() - KEEP_MS
267
+ const unused = [...keptTiles].filter((t) => t.lastUsed < limit).sort((a, b) => a.lastUsed - b.lastUsed)
268
+ for (const t of unused) {
269
+ if (keptCells <= TiledGrid.maxCachedCells) break
270
+ t.owner._drop(t)
271
+ }
272
+ }
273
+
274
+ /**
275
+ * Forgets a tile: it is loaded again when the map needs it.
276
+ *
277
+ * @param {any} tile
278
+ * @private
279
+ */
280
+ _drop(tile) {
281
+ const column = this.cache[tile.x]
282
+ if (column && column[tile.y] === tile) {
283
+ delete column[tile.y]
284
+ if (!Object.keys(column).length) delete this.cache[tile.x]
285
+ }
286
+ if (keptTiles.delete(tile)) keptCells -= tile.cells.length
287
+ tile.owner = undefined
288
+ tile.cells = []
289
+ }
290
+
238
291
  /**
239
292
  * Fill the view cache with all cells which are within a geographical envelope.
240
293
  * @abstract
@@ -264,6 +317,7 @@ export class TiledGrid extends Dataset {
264
317
  /** @type {object} */
265
318
  const tile = this.cache[xT][yT]
266
319
  if (!tile || typeof tile === 'string') continue
320
+ tile.lastUsed = now()
267
321
 
268
322
  //get cells
269
323
  //this.cellsViewCache = this.cellsViewCache.concat(tile.cells)
@@ -280,6 +334,14 @@ export class TiledGrid extends Dataset {
280
334
  }
281
335
  }
282
336
 
337
+ /**
338
+ * The most cells kept in memory by the tiles of all the TiledGrid together (a cell is an object of the values of a place, some hundred
339
+ * bytes: about 250 MB for a million). It can be changed at any time.
340
+ *
341
+ * @type {number}
342
+ */
343
+ TiledGrid.maxCachedCells = 1500000
344
+
283
345
  function getGridTile(cells, xT, yT, gridInfo) {
284
346
  const tile = {}
285
347