@diagrammo/dgmo 0.20.1 → 0.20.2

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/dist/index.cjs CHANGED
@@ -45910,7 +45910,7 @@ function resolveMap(parsed, data) {
45910
45910
  const lonSpan = extent2[1][0] - extent2[0][0];
45911
45911
  const latSpan = extent2[1][1] - extent2[0][1];
45912
45912
  const span = Math.max(lonSpan, latSpan);
45913
- const usDominant = (inferredCountry === "US" || subdivisions.includes("us-states")) && !regions.some((r) => r.layer === "country" && r.iso !== "US") && !anyNonUsPoi;
45913
+ const usDominant = (subdivisions.includes("us-states") || regions.some((r) => r.layer === "us-state")) && !regions.some((r) => r.layer === "country" && r.iso !== "US") && !anyNonUsPoi;
45914
45914
  let projection;
45915
45915
  const override = parsed.directives.projection;
45916
45916
  if (override === "equirectangular" || override === "natural-earth" || override === "albers-usa" || override === "mercator") {
@@ -46154,8 +46154,19 @@ function layoutMap(resolved, data, size, opts) {
46154
46154
  const { width, height } = size;
46155
46155
  const wantsUsStates = resolved.basemaps.subdivisions.includes("us-states");
46156
46156
  const usCrisp = resolved.projection === "albers-usa" && wantsUsStates && !!data.naLand;
46157
- const worldTopo = usCrisp ? data.naLand : resolved.basemaps.world === "detail" ? data.worldDetail : data.worldCoarse;
46157
+ const worldTopo = usCrisp ? data.worldDetail : resolved.basemaps.world === "detail" ? data.worldDetail : data.worldCoarse;
46158
46158
  const worldLayer = decodeLayer(worldTopo);
46159
+ if (usCrisp && data.naLand) {
46160
+ const [nbW, nbS, nbE, nbN] = [-140, 10, -52, 66];
46161
+ const crisp = decodeLayer(data.naLand);
46162
+ for (const [iso, cf] of crisp) {
46163
+ const base = worldLayer.get(iso);
46164
+ if (!base) continue;
46165
+ const [[bw, bs], [be, bn]] = (0, import_d3_geo2.geoBounds)(base);
46166
+ if (bw >= nbW && be <= nbE && bs >= nbS && bn <= nbN)
46167
+ worldLayer.set(iso, cf);
46168
+ }
46169
+ }
46159
46170
  const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
46160
46171
  const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
46161
46172
  const neutralFill = mix(palette.colors.green, palette.bg, landTint);
@@ -46301,6 +46312,10 @@ function layoutMap(resolved, data, size, opts) {
46301
46312
  return p ? stretch(p[0], p[1]) : null;
46302
46313
  };
46303
46314
  } else {
46315
+ projection.clipExtent([
46316
+ [0, 0],
46317
+ [width, height]
46318
+ ]);
46304
46319
  path = (0, import_d3_geo2.geoPath)(projection);
46305
46320
  project = (lon, lat) => projection([lon, lat]) ?? null;
46306
46321
  }
@@ -46445,18 +46460,11 @@ function layoutMap(resolved, data, size, opts) {
46445
46460
  placeInset("US-HI", hawaiiProjection(), akRight + 24, width * 0.1);
46446
46461
  }
46447
46462
  const conusFit = resolved.projection === "albers-usa" && !!usLayer;
46448
- const cullExtent = conusFit ? (0, import_d3_geo2.geoBounds)(fitTarget) : resolved.extent;
46449
- const [[exW, exS], [exE, exN]] = cullExtent;
46450
- const lonSpan = exE - exW;
46451
- const latSpan = exN - exS;
46452
- const isGlobalView = lonSpan >= 270 || latSpan >= 130;
46453
- const padLon = Math.max(8, lonSpan * 0.35);
46454
- const padLat = Math.max(8, latSpan * 0.35);
46455
- const vW = exW - padLon;
46456
- const vE = exE + padLon;
46457
- const vS = exS - padLat;
46458
- const vN = exN + padLat;
46459
- const vLonCenter = (exW + exE) / 2;
46463
+ const classifyExtent = conusFit ? (0, import_d3_geo2.geoBounds)(fitTarget) : resolved.extent;
46464
+ const dLonSpan = classifyExtent[1][0] - classifyExtent[0][0];
46465
+ const dLatSpan = classifyExtent[1][1] - classifyExtent[0][1];
46466
+ const isGlobalView = dLonSpan >= 270 || dLatSpan >= 130;
46467
+ const vLonCenter = (classifyExtent[0][0] + classifyExtent[1][0]) / 2;
46460
46468
  const normLon = (lon) => {
46461
46469
  let L = lon;
46462
46470
  while (L < vLonCenter - 180) L += 360;
@@ -46464,23 +46472,28 @@ function layoutMap(resolved, data, size, opts) {
46464
46472
  return L;
46465
46473
  };
46466
46474
  const ringOverlapsView = (ring) => {
46467
- let anyIn = false;
46468
- let loMin = Infinity, loMax = -Infinity, laMin = Infinity, laMax = -Infinity, rawMin = Infinity, rawMax = -Infinity;
46469
- for (const [rawLon, lat] of ring) {
46475
+ let loMin = Infinity, loMax = -Infinity, rawMin = Infinity, rawMax = -Infinity;
46476
+ for (const [rawLon] of ring) {
46470
46477
  const lon = normLon(rawLon);
46471
- if (lon >= vW && lon <= vE && lat >= vS && lat <= vN) anyIn = true;
46472
46478
  if (lon < loMin) loMin = lon;
46473
46479
  if (lon > loMax) loMax = lon;
46474
46480
  if (rawLon < rawMin) rawMin = rawLon;
46475
46481
  if (rawLon > rawMax) rawMax = rawLon;
46476
- if (lat < laMin) laMin = lat;
46477
- if (lat > laMax) laMax = lat;
46478
46482
  }
46479
46483
  if (loMax - loMin > 270) return false;
46480
46484
  if (rawMax - rawMin > 180 && loMax - loMin < 90) return false;
46481
- if (anyIn) return true;
46482
- if (loMax - loMin > 180) return false;
46483
- return !(loMax < vW || loMin > vE || laMax < vS || laMin > vN);
46485
+ let px0 = Infinity, py0 = Infinity, px1 = -Infinity, py1 = -Infinity, anyFinite = false;
46486
+ for (const [lon, lat] of ring) {
46487
+ const p = project(lon, lat);
46488
+ if (!p || !Number.isFinite(p[0]) || !Number.isFinite(p[1])) continue;
46489
+ anyFinite = true;
46490
+ if (p[0] < px0) px0 = p[0];
46491
+ if (p[0] > px1) px1 = p[0];
46492
+ if (p[1] < py0) py0 = p[1];
46493
+ if (p[1] > py1) py1 = p[1];
46494
+ }
46495
+ if (!anyFinite) return false;
46496
+ return !(px1 < 0 || px0 > width || py1 < 0 || py0 > height);
46484
46497
  };
46485
46498
  const cullFeatureToView = (f) => {
46486
46499
  if (isGlobalView) return f;
@@ -46871,19 +46884,39 @@ function layoutMap(resolved, data, size, opts) {
46871
46884
  const text = labelText(p);
46872
46885
  return { text, w: measureLegendText(text, FONT) };
46873
46886
  };
46887
+ const GAP = 3;
46888
+ const inlineRect = (p, w, side) => {
46889
+ switch (side) {
46890
+ case "right":
46891
+ return { x: p.cx + p.r + GAP, y: p.cy - poiLabH / 2, w, h: poiLabH };
46892
+ case "left":
46893
+ return {
46894
+ x: p.cx - p.r - GAP - w,
46895
+ y: p.cy - poiLabH / 2,
46896
+ w,
46897
+ h: poiLabH
46898
+ };
46899
+ case "above":
46900
+ return {
46901
+ x: p.cx - w / 2,
46902
+ y: p.cy - p.r - GAP - poiLabH,
46903
+ w,
46904
+ h: poiLabH
46905
+ };
46906
+ case "below":
46907
+ return { x: p.cx - w / 2, y: p.cy + p.r + GAP, w, h: poiLabH };
46908
+ }
46909
+ };
46874
46910
  const pushInline = (p, text, w, side) => {
46875
- const tx = side === "right" ? p.cx + p.r + 3 : p.cx - p.r - 3;
46876
- obstacles.push({
46877
- x: side === "right" ? tx : tx - w,
46878
- y: p.cy - poiLabH / 2,
46879
- w,
46880
- h: poiLabH
46881
- });
46911
+ const rect = inlineRect(p, w, side);
46912
+ obstacles.push(rect);
46913
+ const anchor = side === "right" ? "start" : side === "left" ? "end" : "middle";
46914
+ const x = side === "right" ? rect.x : side === "left" ? rect.x + w : p.cx;
46882
46915
  labels.push({
46883
- x: tx,
46884
- y: p.cy + FONT / 3,
46916
+ x,
46917
+ y: rect.y + poiLabH / 2 + FONT / 3,
46885
46918
  text,
46886
- anchor: side === "right" ? "start" : "end",
46919
+ anchor,
46887
46920
  color: palette.text,
46888
46921
  halo: true,
46889
46922
  haloColor: palette.bg,
@@ -46892,14 +46925,8 @@ function layoutMap(resolved, data, size, opts) {
46892
46925
  });
46893
46926
  };
46894
46927
  const inlineFits = (p, w, side) => {
46895
- const tx = side === "right" ? p.cx + p.r + 3 : p.cx - p.r - 3;
46896
- const rect = {
46897
- x: side === "right" ? tx : tx - w,
46898
- y: p.cy - poiLabH / 2,
46899
- w,
46900
- h: poiLabH
46901
- };
46902
- return rect.x >= 0 && rect.x + rect.w <= width && !collides(rect);
46928
+ const rect = inlineRect(p, w, side);
46929
+ return rect.x >= 0 && rect.x + rect.w <= width && rect.y >= 0 && rect.y + rect.h <= height && !collides(rect);
46903
46930
  };
46904
46931
  const GROUP_R = 30;
46905
46932
  const groups = [];
@@ -46956,12 +46983,11 @@ function layoutMap(resolved, data, size, opts) {
46956
46983
  if (g.length === 1) {
46957
46984
  const p = g[0];
46958
46985
  const { text, w } = labelInfo(p);
46959
- if (inlineFits(p, w, "right")) {
46960
- pushInline(p, text, w, "right");
46961
- continue;
46962
- }
46963
- if (inlineFits(p, w, "left")) {
46964
- pushInline(p, text, w, "left");
46986
+ const side = ["right", "left", "above", "below"].find(
46987
+ (s) => inlineFits(p, w, s)
46988
+ );
46989
+ if (side) {
46990
+ pushInline(p, text, w, side);
46965
46991
  continue;
46966
46992
  }
46967
46993
  }
package/dist/index.js CHANGED
@@ -45926,7 +45926,7 @@ function resolveMap(parsed, data) {
45926
45926
  const lonSpan = extent2[1][0] - extent2[0][0];
45927
45927
  const latSpan = extent2[1][1] - extent2[0][1];
45928
45928
  const span = Math.max(lonSpan, latSpan);
45929
- const usDominant = (inferredCountry === "US" || subdivisions.includes("us-states")) && !regions.some((r) => r.layer === "country" && r.iso !== "US") && !anyNonUsPoi;
45929
+ const usDominant = (subdivisions.includes("us-states") || regions.some((r) => r.layer === "us-state")) && !regions.some((r) => r.layer === "country" && r.iso !== "US") && !anyNonUsPoi;
45930
45930
  let projection;
45931
45931
  const override = parsed.directives.projection;
45932
45932
  if (override === "equirectangular" || override === "natural-earth" || override === "albers-usa" || override === "mercator") {
@@ -46179,8 +46179,19 @@ function layoutMap(resolved, data, size, opts) {
46179
46179
  const { width, height } = size;
46180
46180
  const wantsUsStates = resolved.basemaps.subdivisions.includes("us-states");
46181
46181
  const usCrisp = resolved.projection === "albers-usa" && wantsUsStates && !!data.naLand;
46182
- const worldTopo = usCrisp ? data.naLand : resolved.basemaps.world === "detail" ? data.worldDetail : data.worldCoarse;
46182
+ const worldTopo = usCrisp ? data.worldDetail : resolved.basemaps.world === "detail" ? data.worldDetail : data.worldCoarse;
46183
46183
  const worldLayer = decodeLayer(worldTopo);
46184
+ if (usCrisp && data.naLand) {
46185
+ const [nbW, nbS, nbE, nbN] = [-140, 10, -52, 66];
46186
+ const crisp = decodeLayer(data.naLand);
46187
+ for (const [iso, cf] of crisp) {
46188
+ const base = worldLayer.get(iso);
46189
+ if (!base) continue;
46190
+ const [[bw, bs], [be, bn]] = geoBounds2(base);
46191
+ if (bw >= nbW && be <= nbE && bs >= nbS && bn <= nbN)
46192
+ worldLayer.set(iso, cf);
46193
+ }
46194
+ }
46184
46195
  const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
46185
46196
  const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
46186
46197
  const neutralFill = mix(palette.colors.green, palette.bg, landTint);
@@ -46326,6 +46337,10 @@ function layoutMap(resolved, data, size, opts) {
46326
46337
  return p ? stretch(p[0], p[1]) : null;
46327
46338
  };
46328
46339
  } else {
46340
+ projection.clipExtent([
46341
+ [0, 0],
46342
+ [width, height]
46343
+ ]);
46329
46344
  path = geoPath(projection);
46330
46345
  project = (lon, lat) => projection([lon, lat]) ?? null;
46331
46346
  }
@@ -46470,18 +46485,11 @@ function layoutMap(resolved, data, size, opts) {
46470
46485
  placeInset("US-HI", hawaiiProjection(), akRight + 24, width * 0.1);
46471
46486
  }
46472
46487
  const conusFit = resolved.projection === "albers-usa" && !!usLayer;
46473
- const cullExtent = conusFit ? geoBounds2(fitTarget) : resolved.extent;
46474
- const [[exW, exS], [exE, exN]] = cullExtent;
46475
- const lonSpan = exE - exW;
46476
- const latSpan = exN - exS;
46477
- const isGlobalView = lonSpan >= 270 || latSpan >= 130;
46478
- const padLon = Math.max(8, lonSpan * 0.35);
46479
- const padLat = Math.max(8, latSpan * 0.35);
46480
- const vW = exW - padLon;
46481
- const vE = exE + padLon;
46482
- const vS = exS - padLat;
46483
- const vN = exN + padLat;
46484
- const vLonCenter = (exW + exE) / 2;
46488
+ const classifyExtent = conusFit ? geoBounds2(fitTarget) : resolved.extent;
46489
+ const dLonSpan = classifyExtent[1][0] - classifyExtent[0][0];
46490
+ const dLatSpan = classifyExtent[1][1] - classifyExtent[0][1];
46491
+ const isGlobalView = dLonSpan >= 270 || dLatSpan >= 130;
46492
+ const vLonCenter = (classifyExtent[0][0] + classifyExtent[1][0]) / 2;
46485
46493
  const normLon = (lon) => {
46486
46494
  let L = lon;
46487
46495
  while (L < vLonCenter - 180) L += 360;
@@ -46489,23 +46497,28 @@ function layoutMap(resolved, data, size, opts) {
46489
46497
  return L;
46490
46498
  };
46491
46499
  const ringOverlapsView = (ring) => {
46492
- let anyIn = false;
46493
- let loMin = Infinity, loMax = -Infinity, laMin = Infinity, laMax = -Infinity, rawMin = Infinity, rawMax = -Infinity;
46494
- for (const [rawLon, lat] of ring) {
46500
+ let loMin = Infinity, loMax = -Infinity, rawMin = Infinity, rawMax = -Infinity;
46501
+ for (const [rawLon] of ring) {
46495
46502
  const lon = normLon(rawLon);
46496
- if (lon >= vW && lon <= vE && lat >= vS && lat <= vN) anyIn = true;
46497
46503
  if (lon < loMin) loMin = lon;
46498
46504
  if (lon > loMax) loMax = lon;
46499
46505
  if (rawLon < rawMin) rawMin = rawLon;
46500
46506
  if (rawLon > rawMax) rawMax = rawLon;
46501
- if (lat < laMin) laMin = lat;
46502
- if (lat > laMax) laMax = lat;
46503
46507
  }
46504
46508
  if (loMax - loMin > 270) return false;
46505
46509
  if (rawMax - rawMin > 180 && loMax - loMin < 90) return false;
46506
- if (anyIn) return true;
46507
- if (loMax - loMin > 180) return false;
46508
- return !(loMax < vW || loMin > vE || laMax < vS || laMin > vN);
46510
+ let px0 = Infinity, py0 = Infinity, px1 = -Infinity, py1 = -Infinity, anyFinite = false;
46511
+ for (const [lon, lat] of ring) {
46512
+ const p = project(lon, lat);
46513
+ if (!p || !Number.isFinite(p[0]) || !Number.isFinite(p[1])) continue;
46514
+ anyFinite = true;
46515
+ if (p[0] < px0) px0 = p[0];
46516
+ if (p[0] > px1) px1 = p[0];
46517
+ if (p[1] < py0) py0 = p[1];
46518
+ if (p[1] > py1) py1 = p[1];
46519
+ }
46520
+ if (!anyFinite) return false;
46521
+ return !(px1 < 0 || px0 > width || py1 < 0 || py0 > height);
46509
46522
  };
46510
46523
  const cullFeatureToView = (f) => {
46511
46524
  if (isGlobalView) return f;
@@ -46896,19 +46909,39 @@ function layoutMap(resolved, data, size, opts) {
46896
46909
  const text = labelText(p);
46897
46910
  return { text, w: measureLegendText(text, FONT) };
46898
46911
  };
46912
+ const GAP = 3;
46913
+ const inlineRect = (p, w, side) => {
46914
+ switch (side) {
46915
+ case "right":
46916
+ return { x: p.cx + p.r + GAP, y: p.cy - poiLabH / 2, w, h: poiLabH };
46917
+ case "left":
46918
+ return {
46919
+ x: p.cx - p.r - GAP - w,
46920
+ y: p.cy - poiLabH / 2,
46921
+ w,
46922
+ h: poiLabH
46923
+ };
46924
+ case "above":
46925
+ return {
46926
+ x: p.cx - w / 2,
46927
+ y: p.cy - p.r - GAP - poiLabH,
46928
+ w,
46929
+ h: poiLabH
46930
+ };
46931
+ case "below":
46932
+ return { x: p.cx - w / 2, y: p.cy + p.r + GAP, w, h: poiLabH };
46933
+ }
46934
+ };
46899
46935
  const pushInline = (p, text, w, side) => {
46900
- const tx = side === "right" ? p.cx + p.r + 3 : p.cx - p.r - 3;
46901
- obstacles.push({
46902
- x: side === "right" ? tx : tx - w,
46903
- y: p.cy - poiLabH / 2,
46904
- w,
46905
- h: poiLabH
46906
- });
46936
+ const rect = inlineRect(p, w, side);
46937
+ obstacles.push(rect);
46938
+ const anchor = side === "right" ? "start" : side === "left" ? "end" : "middle";
46939
+ const x = side === "right" ? rect.x : side === "left" ? rect.x + w : p.cx;
46907
46940
  labels.push({
46908
- x: tx,
46909
- y: p.cy + FONT / 3,
46941
+ x,
46942
+ y: rect.y + poiLabH / 2 + FONT / 3,
46910
46943
  text,
46911
- anchor: side === "right" ? "start" : "end",
46944
+ anchor,
46912
46945
  color: palette.text,
46913
46946
  halo: true,
46914
46947
  haloColor: palette.bg,
@@ -46917,14 +46950,8 @@ function layoutMap(resolved, data, size, opts) {
46917
46950
  });
46918
46951
  };
46919
46952
  const inlineFits = (p, w, side) => {
46920
- const tx = side === "right" ? p.cx + p.r + 3 : p.cx - p.r - 3;
46921
- const rect = {
46922
- x: side === "right" ? tx : tx - w,
46923
- y: p.cy - poiLabH / 2,
46924
- w,
46925
- h: poiLabH
46926
- };
46927
- return rect.x >= 0 && rect.x + rect.w <= width && !collides(rect);
46953
+ const rect = inlineRect(p, w, side);
46954
+ return rect.x >= 0 && rect.x + rect.w <= width && rect.y >= 0 && rect.y + rect.h <= height && !collides(rect);
46928
46955
  };
46929
46956
  const GROUP_R = 30;
46930
46957
  const groups = [];
@@ -46981,12 +47008,11 @@ function layoutMap(resolved, data, size, opts) {
46981
47008
  if (g.length === 1) {
46982
47009
  const p = g[0];
46983
47010
  const { text, w } = labelInfo(p);
46984
- if (inlineFits(p, w, "right")) {
46985
- pushInline(p, text, w, "right");
46986
- continue;
46987
- }
46988
- if (inlineFits(p, w, "left")) {
46989
- pushInline(p, text, w, "left");
47011
+ const side = ["right", "left", "above", "below"].find(
47012
+ (s) => inlineFits(p, w, s)
47013
+ );
47014
+ if (side) {
47015
+ pushInline(p, text, w, side);
46990
47016
  continue;
46991
47017
  }
46992
47018
  }
package/dist/internal.cjs CHANGED
@@ -46197,7 +46197,7 @@ function resolveMap(parsed, data) {
46197
46197
  const lonSpan = extent2[1][0] - extent2[0][0];
46198
46198
  const latSpan = extent2[1][1] - extent2[0][1];
46199
46199
  const span = Math.max(lonSpan, latSpan);
46200
- const usDominant = (inferredCountry === "US" || subdivisions.includes("us-states")) && !regions.some((r) => r.layer === "country" && r.iso !== "US") && !anyNonUsPoi;
46200
+ const usDominant = (subdivisions.includes("us-states") || regions.some((r) => r.layer === "us-state")) && !regions.some((r) => r.layer === "country" && r.iso !== "US") && !anyNonUsPoi;
46201
46201
  let projection;
46202
46202
  const override = parsed.directives.projection;
46203
46203
  if (override === "equirectangular" || override === "natural-earth" || override === "albers-usa" || override === "mercator") {
@@ -46448,8 +46448,19 @@ function layoutMap(resolved, data, size, opts) {
46448
46448
  const { width, height } = size;
46449
46449
  const wantsUsStates = resolved.basemaps.subdivisions.includes("us-states");
46450
46450
  const usCrisp = resolved.projection === "albers-usa" && wantsUsStates && !!data.naLand;
46451
- const worldTopo = usCrisp ? data.naLand : resolved.basemaps.world === "detail" ? data.worldDetail : data.worldCoarse;
46451
+ const worldTopo = usCrisp ? data.worldDetail : resolved.basemaps.world === "detail" ? data.worldDetail : data.worldCoarse;
46452
46452
  const worldLayer = decodeLayer(worldTopo);
46453
+ if (usCrisp && data.naLand) {
46454
+ const [nbW, nbS, nbE, nbN] = [-140, 10, -52, 66];
46455
+ const crisp = decodeLayer(data.naLand);
46456
+ for (const [iso, cf] of crisp) {
46457
+ const base = worldLayer.get(iso);
46458
+ if (!base) continue;
46459
+ const [[bw, bs], [be, bn]] = (0, import_d3_geo2.geoBounds)(base);
46460
+ if (bw >= nbW && be <= nbE && bs >= nbS && bn <= nbN)
46461
+ worldLayer.set(iso, cf);
46462
+ }
46463
+ }
46453
46464
  const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
46454
46465
  const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
46455
46466
  const neutralFill = mix(palette.colors.green, palette.bg, landTint);
@@ -46595,6 +46606,10 @@ function layoutMap(resolved, data, size, opts) {
46595
46606
  return p ? stretch(p[0], p[1]) : null;
46596
46607
  };
46597
46608
  } else {
46609
+ projection.clipExtent([
46610
+ [0, 0],
46611
+ [width, height]
46612
+ ]);
46598
46613
  path = (0, import_d3_geo2.geoPath)(projection);
46599
46614
  project = (lon, lat) => projection([lon, lat]) ?? null;
46600
46615
  }
@@ -46739,18 +46754,11 @@ function layoutMap(resolved, data, size, opts) {
46739
46754
  placeInset("US-HI", hawaiiProjection(), akRight + 24, width * 0.1);
46740
46755
  }
46741
46756
  const conusFit = resolved.projection === "albers-usa" && !!usLayer;
46742
- const cullExtent = conusFit ? (0, import_d3_geo2.geoBounds)(fitTarget) : resolved.extent;
46743
- const [[exW, exS], [exE, exN]] = cullExtent;
46744
- const lonSpan = exE - exW;
46745
- const latSpan = exN - exS;
46746
- const isGlobalView = lonSpan >= 270 || latSpan >= 130;
46747
- const padLon = Math.max(8, lonSpan * 0.35);
46748
- const padLat = Math.max(8, latSpan * 0.35);
46749
- const vW = exW - padLon;
46750
- const vE = exE + padLon;
46751
- const vS = exS - padLat;
46752
- const vN = exN + padLat;
46753
- const vLonCenter = (exW + exE) / 2;
46757
+ const classifyExtent = conusFit ? (0, import_d3_geo2.geoBounds)(fitTarget) : resolved.extent;
46758
+ const dLonSpan = classifyExtent[1][0] - classifyExtent[0][0];
46759
+ const dLatSpan = classifyExtent[1][1] - classifyExtent[0][1];
46760
+ const isGlobalView = dLonSpan >= 270 || dLatSpan >= 130;
46761
+ const vLonCenter = (classifyExtent[0][0] + classifyExtent[1][0]) / 2;
46754
46762
  const normLon = (lon) => {
46755
46763
  let L = lon;
46756
46764
  while (L < vLonCenter - 180) L += 360;
@@ -46758,23 +46766,28 @@ function layoutMap(resolved, data, size, opts) {
46758
46766
  return L;
46759
46767
  };
46760
46768
  const ringOverlapsView = (ring) => {
46761
- let anyIn = false;
46762
- let loMin = Infinity, loMax = -Infinity, laMin = Infinity, laMax = -Infinity, rawMin = Infinity, rawMax = -Infinity;
46763
- for (const [rawLon, lat] of ring) {
46769
+ let loMin = Infinity, loMax = -Infinity, rawMin = Infinity, rawMax = -Infinity;
46770
+ for (const [rawLon] of ring) {
46764
46771
  const lon = normLon(rawLon);
46765
- if (lon >= vW && lon <= vE && lat >= vS && lat <= vN) anyIn = true;
46766
46772
  if (lon < loMin) loMin = lon;
46767
46773
  if (lon > loMax) loMax = lon;
46768
46774
  if (rawLon < rawMin) rawMin = rawLon;
46769
46775
  if (rawLon > rawMax) rawMax = rawLon;
46770
- if (lat < laMin) laMin = lat;
46771
- if (lat > laMax) laMax = lat;
46772
46776
  }
46773
46777
  if (loMax - loMin > 270) return false;
46774
46778
  if (rawMax - rawMin > 180 && loMax - loMin < 90) return false;
46775
- if (anyIn) return true;
46776
- if (loMax - loMin > 180) return false;
46777
- return !(loMax < vW || loMin > vE || laMax < vS || laMin > vN);
46779
+ let px0 = Infinity, py0 = Infinity, px1 = -Infinity, py1 = -Infinity, anyFinite = false;
46780
+ for (const [lon, lat] of ring) {
46781
+ const p = project(lon, lat);
46782
+ if (!p || !Number.isFinite(p[0]) || !Number.isFinite(p[1])) continue;
46783
+ anyFinite = true;
46784
+ if (p[0] < px0) px0 = p[0];
46785
+ if (p[0] > px1) px1 = p[0];
46786
+ if (p[1] < py0) py0 = p[1];
46787
+ if (p[1] > py1) py1 = p[1];
46788
+ }
46789
+ if (!anyFinite) return false;
46790
+ return !(px1 < 0 || px0 > width || py1 < 0 || py0 > height);
46778
46791
  };
46779
46792
  const cullFeatureToView = (f) => {
46780
46793
  if (isGlobalView) return f;
@@ -47165,19 +47178,39 @@ function layoutMap(resolved, data, size, opts) {
47165
47178
  const text = labelText(p);
47166
47179
  return { text, w: measureLegendText(text, FONT) };
47167
47180
  };
47181
+ const GAP = 3;
47182
+ const inlineRect = (p, w, side) => {
47183
+ switch (side) {
47184
+ case "right":
47185
+ return { x: p.cx + p.r + GAP, y: p.cy - poiLabH / 2, w, h: poiLabH };
47186
+ case "left":
47187
+ return {
47188
+ x: p.cx - p.r - GAP - w,
47189
+ y: p.cy - poiLabH / 2,
47190
+ w,
47191
+ h: poiLabH
47192
+ };
47193
+ case "above":
47194
+ return {
47195
+ x: p.cx - w / 2,
47196
+ y: p.cy - p.r - GAP - poiLabH,
47197
+ w,
47198
+ h: poiLabH
47199
+ };
47200
+ case "below":
47201
+ return { x: p.cx - w / 2, y: p.cy + p.r + GAP, w, h: poiLabH };
47202
+ }
47203
+ };
47168
47204
  const pushInline = (p, text, w, side) => {
47169
- const tx = side === "right" ? p.cx + p.r + 3 : p.cx - p.r - 3;
47170
- obstacles.push({
47171
- x: side === "right" ? tx : tx - w,
47172
- y: p.cy - poiLabH / 2,
47173
- w,
47174
- h: poiLabH
47175
- });
47205
+ const rect = inlineRect(p, w, side);
47206
+ obstacles.push(rect);
47207
+ const anchor = side === "right" ? "start" : side === "left" ? "end" : "middle";
47208
+ const x = side === "right" ? rect.x : side === "left" ? rect.x + w : p.cx;
47176
47209
  labels.push({
47177
- x: tx,
47178
- y: p.cy + FONT / 3,
47210
+ x,
47211
+ y: rect.y + poiLabH / 2 + FONT / 3,
47179
47212
  text,
47180
- anchor: side === "right" ? "start" : "end",
47213
+ anchor,
47181
47214
  color: palette.text,
47182
47215
  halo: true,
47183
47216
  haloColor: palette.bg,
@@ -47186,14 +47219,8 @@ function layoutMap(resolved, data, size, opts) {
47186
47219
  });
47187
47220
  };
47188
47221
  const inlineFits = (p, w, side) => {
47189
- const tx = side === "right" ? p.cx + p.r + 3 : p.cx - p.r - 3;
47190
- const rect = {
47191
- x: side === "right" ? tx : tx - w,
47192
- y: p.cy - poiLabH / 2,
47193
- w,
47194
- h: poiLabH
47195
- };
47196
- return rect.x >= 0 && rect.x + rect.w <= width && !collides(rect);
47222
+ const rect = inlineRect(p, w, side);
47223
+ return rect.x >= 0 && rect.x + rect.w <= width && rect.y >= 0 && rect.y + rect.h <= height && !collides(rect);
47197
47224
  };
47198
47225
  const GROUP_R = 30;
47199
47226
  const groups = [];
@@ -47250,12 +47277,11 @@ function layoutMap(resolved, data, size, opts) {
47250
47277
  if (g.length === 1) {
47251
47278
  const p = g[0];
47252
47279
  const { text, w } = labelInfo(p);
47253
- if (inlineFits(p, w, "right")) {
47254
- pushInline(p, text, w, "right");
47255
- continue;
47256
- }
47257
- if (inlineFits(p, w, "left")) {
47258
- pushInline(p, text, w, "left");
47280
+ const side = ["right", "left", "above", "below"].find(
47281
+ (s) => inlineFits(p, w, s)
47282
+ );
47283
+ if (side) {
47284
+ pushInline(p, text, w, side);
47259
47285
  continue;
47260
47286
  }
47261
47287
  }