ixmaps-gl 0.2.1 → 0.2.3
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/README.md +7 -6
- package/ixmaps-gl.js +83 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -72,7 +72,7 @@ circle/square/diamond/triangle. See the top-of-file comment in
|
|
|
72
72
|
A page's `.require(url)` scripts (page code, e.g. a user chart function) load in order before the
|
|
73
73
|
layers are built. `ixmaps.map()` is the map handle as in flat — its calls wait until the map is ready —
|
|
74
74
|
with `add(theme, flags)` / `replace` / `replaceTheme` / `remove`, `changeThemeStyle` for any style key,
|
|
75
|
-
`getZoom()` (flat's zoom), `resize()` and `
|
|
75
|
+
`getZoom()` (flat's zoom), `resize()`, `setBasemapOpacity` and `setMapType(id)` (also `setMapTypeId`, `mapType`: a basemap name reading dark/black/night/matter loads CARTO Dark Matter, any other name CARTO Positron, a color a plain background — the same rule the `mapType` option follows at start); the page's `htmlgui_onNewTheme(id)` and
|
|
76
76
|
`htmlgui_onZoomAndPan()` (also once on load) are called (as in flat, a theme swapped in with `replace` comes last
|
|
77
77
|
in the legend, while FEATURE and CHOROPLETH shapes always draw under the charts), and `map`, `getZoom` and flat's
|
|
78
78
|
`formatValue` exist as globals. `.data({name})` without a URL waits for data of that name: from
|
|
@@ -155,8 +155,9 @@ ones, `replace` swaps themes by `style.name`/`meta.name`, `themeonly`/`maponly`/
|
|
|
155
155
|
work as in flat. Themes in flat's older shape (data source in `style.dbtable*`, value field at
|
|
156
156
|
the top level) are translated first. It resolves to `{ themes, skipped, notes }`: a theme
|
|
157
157
|
that can't load is skipped with a warning, the rest still load. **Code a project names is not
|
|
158
|
-
run by default** — `required` scripts, `ext` data scripts and a project's `process`
|
|
159
|
-
reported, not executed (only a page's own
|
|
158
|
+
run by default** — `required` scripts, `ext` data scripts and a project's `process` and `query`
|
|
159
|
+
functions and function-string `colorscheme`s are reported, not executed (only a page's own
|
|
160
|
+
`.data({process, query})` and colorscheme functions run) — and the basemap isn't switched.
|
|
160
161
|
|
|
161
162
|
A page can opt in to a project's **scripts** (`data.ext`) for script URLs under prefixes it lists —
|
|
162
163
|
no built-in prefixes, and a project file's own `options.trustedscripts` is ignored. Both of flat's
|
|
@@ -192,7 +193,7 @@ of your own project files gl can render.
|
|
|
192
193
|
Load the engine from jsDelivr, pinned to a release tag (or `@main` for the latest commit):
|
|
193
194
|
|
|
194
195
|
```html
|
|
195
|
-
<script src="https://cdn.jsdelivr.net/gh/gjrichter/ixmaps-gl@v0.2.
|
|
196
|
+
<script src="https://cdn.jsdelivr.net/gh/gjrichter/ixmaps-gl@v0.2.3/ixmaps-gl.js"></script>
|
|
196
197
|
```
|
|
197
198
|
|
|
198
199
|
or from unpkg, the npm package [`ixmaps-gl`](https://www.npmjs.com/package/ixmaps-gl)
|
|
@@ -200,13 +201,13 @@ or from unpkg, the npm package [`ixmaps-gl`](https://www.npmjs.com/package/ixmap
|
|
|
200
201
|
browser script, which defines the global `ixmaps`):
|
|
201
202
|
|
|
202
203
|
```html
|
|
203
|
-
<script src="https://unpkg.com/ixmaps-gl@0.2.
|
|
204
|
+
<script src="https://unpkg.com/ixmaps-gl@0.2.3/ixmaps-gl.js"></script>
|
|
204
205
|
```
|
|
205
206
|
|
|
206
207
|
or use a local copy (`<script src="ixmaps-gl.js"></script>`). A minimal page:
|
|
207
208
|
|
|
208
209
|
```html
|
|
209
|
-
<script src="https://cdn.jsdelivr.net/gh/gjrichter/ixmaps-gl@v0.2.
|
|
210
|
+
<script src="https://cdn.jsdelivr.net/gh/gjrichter/ixmaps-gl@v0.2.3/ixmaps-gl.js"></script>
|
|
210
211
|
<div id="map_div" style="position:absolute;inset:0;"></div>
|
|
211
212
|
|
|
212
213
|
<script>
|
package/ixmaps-gl.js
CHANGED
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
// ---------------------------------------------------------------
|
|
81
81
|
// this engine's release (= package.json "version", checked by
|
|
82
82
|
// test/unit/version.test.mjs); ixmaps.glVersion, and logged once at start
|
|
83
|
-
const IXMAPS_GL_VERSION = '0.2.
|
|
83
|
+
const IXMAPS_GL_VERSION = '0.2.3';
|
|
84
84
|
|
|
85
85
|
const LIB_URLS = {
|
|
86
86
|
// Bumped 3.6.2 -> 5.x (2026-09-21, globe-projection compat fix): native
|
|
@@ -1720,7 +1720,7 @@
|
|
|
1720
1720
|
// htmlgui_flat.js). Its methods act on the last built map; called while
|
|
1721
1721
|
// the map is still building, they run once it is ready.
|
|
1722
1722
|
const MAP_HANDLE_METHODS = ['replace', 'add', 'remove', 'removeTheme', 'replaceTheme', 'changeThemeStyle', 'setThemeStyle',
|
|
1723
|
-
'refreshTheme', 'setBasemapOpacity', 'resize', 'view', 'options', 'layer', 'loadProject', 'require', 'setThemeVisible'];
|
|
1723
|
+
'refreshTheme', 'setBasemapOpacity', 'setMapType', 'setMapTypeId', 'mapType', 'resize', 'view', 'options', 'layer', 'loadProject', 'require', 'setThemeVisible'];
|
|
1724
1724
|
const _mapHandle = {};
|
|
1725
1725
|
for (const m of MAP_HANDLE_METHODS) {
|
|
1726
1726
|
_mapHandle[m] = (...args) => {
|
|
@@ -2148,6 +2148,36 @@
|
|
|
2148
2148
|
dbtable: 'name', dbtableUrl: 'url', dbtableType: 'type', dbtableExt: 'ext',
|
|
2149
2149
|
dbtableProcess: 'process', dbtableQuery: 'query', dbtableObj: 'obj', datacache: 'cache',
|
|
2150
2150
|
};
|
|
2151
|
+
// Every project key the engine would turn into code (new Function)
|
|
2152
|
+
// is kept out, never run — a page's own .data({process, query}) and
|
|
2153
|
+
// .style({colorscheme: fn.toString()}) still run. Project keys of
|
|
2154
|
+
// that kind: the data processing function (data.process /
|
|
2155
|
+
// style.dbtableProcess), the broker query (data.query /
|
|
2156
|
+
// style.dbtableQuery — without it a data.name still reaches a
|
|
2157
|
+
// provider the PAGE defined as ixmaps[name]) and a colorscheme given
|
|
2158
|
+
// as a string, which resolveColorScheme evaluates as a function
|
|
2159
|
+
// (an array colorscheme is data and stays).
|
|
2160
|
+
const PROJECT_CODE_KEYS = [
|
|
2161
|
+
['data', 'process', 'data.process function'],
|
|
2162
|
+
['style', 'dbtableProcess', 'data.process function'],
|
|
2163
|
+
['data', 'query', 'data.query function'],
|
|
2164
|
+
['style', 'dbtableQuery', 'data.query function'],
|
|
2165
|
+
['style', 'colorscheme', 'colorscheme function', v => typeof v === 'string'],
|
|
2166
|
+
];
|
|
2167
|
+
function withoutProjectCode(t, report) {
|
|
2168
|
+
const found = PROJECT_CODE_KEYS.filter(([part, key, , isCode]) =>
|
|
2169
|
+
t[part] && t[part][key] != null && (!isCode || isCode(t[part][key])));
|
|
2170
|
+
if (!found.length) return t;
|
|
2171
|
+
const copy = Object.assign({}, t);
|
|
2172
|
+
found.forEach(([part, key]) => {
|
|
2173
|
+
if (copy[part] === t[part]) copy[part] = Object.assign({}, t[part]);
|
|
2174
|
+
delete copy[part][key];
|
|
2175
|
+
});
|
|
2176
|
+
const what = [...new Set(found.map(f => f[2]))].join(', ');
|
|
2177
|
+
report.notes.push(`theme "${t.layer}": the project's ${what} is never run by ixmaps-gl`);
|
|
2178
|
+
return copy;
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2151
2181
|
function projectThemeToDefinition(theme) {
|
|
2152
2182
|
const t = theme || {};
|
|
2153
2183
|
const style = Object.assign({}, t.style);
|
|
@@ -2418,6 +2448,19 @@
|
|
|
2418
2448
|
const named = NAMED_MAPTYPE_COLORS[t.toLowerCase()];
|
|
2419
2449
|
return named || null;
|
|
2420
2450
|
}
|
|
2451
|
+
// A basemap NAME (flat's mapType: "VT_TONER_LITE", "VT_DATAVIZ_DARK",
|
|
2452
|
+
// "CartoDB - Dark matter", ...) picks one of two keyless CARTO vector
|
|
2453
|
+
// styles: dark for a name reading dark/black/night/matter, otherwise
|
|
2454
|
+
// light (Positron, gl's default). A color mapType (resolveMapTypeColor)
|
|
2455
|
+
// is a plain background instead and wins, so "dark" alone stays the
|
|
2456
|
+
// #1a1a1a background it always was.
|
|
2457
|
+
const BASEMAP_STYLE_URLS = {
|
|
2458
|
+
light: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
|
|
2459
|
+
dark: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',
|
|
2460
|
+
};
|
|
2461
|
+
function resolveBasemapStyleUrl(mapType) {
|
|
2462
|
+
return typeof mapType === 'string' && /dark|black|night|matter/i.test(mapType) ? BASEMAP_STYLE_URLS.dark : BASEMAP_STYLE_URLS.light;
|
|
2463
|
+
}
|
|
2421
2464
|
// Real ixmaps-flat's legend look (tools/legend.js 3773-3845, via
|
|
2422
2465
|
// tools/background_theme.js): DARK when the basemap is more than half
|
|
2423
2466
|
// opaque and the map background reads as dark — a map type naming
|
|
@@ -2688,7 +2731,7 @@
|
|
|
2688
2731
|
const map = new maplibregl.Map({
|
|
2689
2732
|
container: this.containerId,
|
|
2690
2733
|
style: mapTypeColor ? buildBlankBackgroundStyle(mapTypeColor)
|
|
2691
|
-
:
|
|
2734
|
+
: resolveBasemapStyleUrl(this.mapOptions.mapType),
|
|
2692
2735
|
center: [lon, lat],
|
|
2693
2736
|
zoom: this._viewZoom != null && this._viewZoom !== '' ? flatToMapLibreZoom(Number(this._viewZoom)) : 8,
|
|
2694
2737
|
// .attribution(a) (MapBuilder, above) was stored but never read —
|
|
@@ -3140,6 +3183,31 @@
|
|
|
3140
3183
|
},
|
|
3141
3184
|
replaceTheme: (id, layerBuilder, flag) => engineApi.replace(id, layerBuilder, flag),
|
|
3142
3185
|
remove: (id) => { removeThemeById(id); return engineApi; },
|
|
3186
|
+
// flat's map.setMapType(id) / setMapTypeId / mapType (htmlgui_flat.js
|
|
3187
|
+
// mapApi): swap the basemap at runtime. MapLibre's setStyle replaces
|
|
3188
|
+
// the whole style; deck.gl's interleaved overlay re-adds its own
|
|
3189
|
+
// layers on 'styledata' by itself. What the new style resets is put
|
|
3190
|
+
// back once it has loaded: the projection (globe), the basemap
|
|
3191
|
+
// opacity (it is written into the style's paint properties).
|
|
3192
|
+
setMapType: (id) => {
|
|
3193
|
+
const color = resolveMapTypeColor(id);
|
|
3194
|
+
const style = color ? buildBlankBackgroundStyle(color) : resolveBasemapStyleUrl(id);
|
|
3195
|
+
const current = color ? null : resolveBasemapStyleUrl(builder.mapOptions.mapType);
|
|
3196
|
+
const wasColor = !!resolveMapTypeColor(builder.mapOptions.mapType);
|
|
3197
|
+
builder.mapOptions.mapType = id;
|
|
3198
|
+
if (!color && !wasColor && style === current) return engineApi; // same style: nothing to reload
|
|
3199
|
+
const projection = typeof map.getProjection === 'function' ? map.getProjection() : null;
|
|
3200
|
+
map.once('style.load', () => {
|
|
3201
|
+
if (projection && projection.type && typeof map.setProjection === 'function') {
|
|
3202
|
+
try { map.setProjection({ type: projection.type }); } catch (e) { /* projection unsupported by this build */ }
|
|
3203
|
+
}
|
|
3204
|
+
applyBasemapOpacity();
|
|
3205
|
+
});
|
|
3206
|
+
map.setStyle(style);
|
|
3207
|
+
return engineApi;
|
|
3208
|
+
},
|
|
3209
|
+
setMapTypeId: (id) => engineApi.setMapType(id),
|
|
3210
|
+
mapType: (id) => engineApi.setMapType(id),
|
|
3143
3211
|
setBasemapOpacity: (delta, mode) => {
|
|
3144
3212
|
_basemapOpacity = mode === 'relative'
|
|
3145
3213
|
? Math.max(0, Math.min(1, _basemapOpacity + (parseFloat(delta) || 0)))
|
|
@@ -3611,19 +3679,6 @@
|
|
|
3611
3679
|
return report;
|
|
3612
3680
|
}
|
|
3613
3681
|
|
|
3614
|
-
// a project file's data processing function is code the project
|
|
3615
|
-
// names — kept out, never run (a page's own .data({process}) runs)
|
|
3616
|
-
function withoutProjectCode(t, report) {
|
|
3617
|
-
const hasData = t.data && t.data.process != null;
|
|
3618
|
-
const hasStyle = t.style && t.style.dbtableProcess != null;
|
|
3619
|
-
if (!hasData && !hasStyle) return t;
|
|
3620
|
-
report.notes.push(`theme "${t.layer}": the project's data.process function is never run by ixmaps-gl`);
|
|
3621
|
-
const copy = Object.assign({}, t);
|
|
3622
|
-
if (hasData) { copy.data = Object.assign({}, t.data); delete copy.data.process; }
|
|
3623
|
-
if (hasStyle) { copy.style = Object.assign({}, t.style); delete copy.style.dbtableProcess; }
|
|
3624
|
-
return copy;
|
|
3625
|
-
}
|
|
3626
|
-
|
|
3627
3682
|
function applyProjectMap(m, f, report) {
|
|
3628
3683
|
const svg = String(m.map || '');
|
|
3629
3684
|
if (svg && !/generic\/(mercator|orthographic)\.svg$/i.test(svg)) report.notes.push(`flat SVG map "${svg.split('/').pop()}" is not available in ixmaps-gl — mercator used`);
|
|
@@ -5266,6 +5321,16 @@
|
|
|
5266
5321
|
return text;
|
|
5267
5322
|
}
|
|
5268
5323
|
|
|
5324
|
+
// Records behind one drawn chart item: a group's per-category record
|
|
5325
|
+
// counts summed, else a Supercluster cluster's point_count, else 1.
|
|
5326
|
+
// recordCounts only exists on RELOCATE groups (groupCoLocated); a plain
|
|
5327
|
+
// grid group (no RELOCATE) carries counts only — read unguarded, BOX|TITLE
|
|
5328
|
+
// without RELOCATE threw on the first cluster and the theme stopped drawing.
|
|
5329
|
+
function groupRecordCount(props) {
|
|
5330
|
+
const perCat = props.recordCounts || props.counts;
|
|
5331
|
+
return perCat ? perCat.reduce((x, c) => x + c, 0) : (props.point_count || 1);
|
|
5332
|
+
}
|
|
5333
|
+
|
|
5269
5334
|
function valuesFontSizePx(radiusPx, text, valueScale) {
|
|
5270
5335
|
return Math.min(radiusPx * 0.8, radiusPx * (3.3 / Math.max(1, text.length))) * (valueScale || 1);
|
|
5271
5336
|
}
|
|
@@ -9364,7 +9429,7 @@
|
|
|
9364
9429
|
let title = null;
|
|
9365
9430
|
if (titleShown) {
|
|
9366
9431
|
const raw = d.properties.raw;
|
|
9367
|
-
const n =
|
|
9432
|
+
const n = groupRecordCount(d.properties);
|
|
9368
9433
|
const text = n > 3 ? '(' + n + ')' : (raw && raw[this.binding.title] != null ? String(raw[this.binding.title]) : '');
|
|
9369
9434
|
if (text) {
|
|
9370
9435
|
const f = titleFontPx;
|
|
@@ -9987,7 +10052,7 @@
|
|
|
9987
10052
|
// engine runs in a Node vm there); deliberately NOT on the ixmaps object
|
|
9988
10053
|
global.__ixmapsGlInternals = {
|
|
9989
10054
|
IXMAPS_GL_VERSION,
|
|
9990
|
-
normalizeTheme, projectThemeToDefinition, LayerBuilder, LayerRuntime, typeStyleNumbers, styleNum,
|
|
10055
|
+
normalizeTheme, projectThemeToDefinition, withoutProjectCode, groupRecordCount, resolveBasemapStyleUrl, resolveMapTypeColor, LayerBuilder, LayerRuntime, typeStyleNumbers, styleNum,
|
|
9991
10056
|
resolveScriptUrl, isTrustedScriptUrl, loadProcessingScript, loadBrokerData, applyBrokerThemePatch, makeBrokerTheme,
|
|
9992
10057
|
equalIntervalBreaks, quantileBreaks, naturalBreaks, evenStrideSample, jenksBreakValues, partsFromBreakValues, resolvePartsClass,
|
|
9993
10058
|
computeAlphaStats, computeMultiFieldClasses, computeDominantStats, resolveDominantClass, computeComposeColorStats,
|