@guardian/interactive-component-library 0.7.10 → 0.7.12

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.
@@ -1,4 +1,4 @@
1
- import { Extent } from './util';
1
+ import { GeoBounds, Extent } from './util';
2
2
  import { ZoomTransform } from 'd3-zoom';
3
3
  /**
4
4
  * @typedef ViewConfig
@@ -64,7 +64,7 @@ export class View {
64
64
  fitWidth(width: any, object: any): any;
65
65
  fitHeight(height: any, object: any): any;
66
66
  };
67
- bounds: Extent;
67
+ bounds: GeoBounds;
68
68
  extent: Extent;
69
69
  minZoom: number;
70
70
  maxZoom: number;
@@ -75,10 +75,15 @@ export class View {
75
75
  bottom: number;
76
76
  left: number;
77
77
  };
78
- _viewPortSize: number[];
78
+ /** @type { [number, number] } */
79
+ _viewPortSize: [number, number];
79
80
  pixelRatio: number;
80
- set viewPortSize(size: number[]);
81
- get viewPortSize(): number[];
81
+ readonly set viewPortSize(size: [number, number]);
82
+ /**
83
+ * @returns {[number, number]} - The size of the viewport in pixels
84
+ * @readonly
85
+ */
86
+ readonly get viewPortSize(): [number, number];
82
87
  set transform(transform: ZoomTransform);
83
88
  get transform(): ZoomTransform;
84
89
  get mapSize(): any;
@@ -135,9 +140,9 @@ export class View {
135
140
  * @function getBounds
136
141
  * @param {ZoomTransform} transform
137
142
  * @param {*} projection
138
- * @returns {import("./util").GeoBoundsLike}
143
+ * @returns {import("./util").GeoBounds}
139
144
  */
140
- getVisibleBounds(transform: ZoomTransform, projection: any): import('./util').GeoBoundsLike;
145
+ getVisibleBounds(transform: ZoomTransform, projection: any): import('./util').GeoBounds;
141
146
  getState(): {
142
147
  transform: ZoomTransform;
143
148
  projection: {
@@ -164,9 +169,9 @@ export class View {
164
169
  bottom: number;
165
170
  left: number;
166
171
  };
167
- viewPortSize: number[];
172
+ viewPortSize: [number, number];
168
173
  sizeInPixels: any;
169
- visibleExtent: import('./util').GeoBoundsLike;
174
+ visibleExtent: Extent;
170
175
  };
171
176
  }
172
177
  export type ViewConfig = {
@@ -4,7 +4,7 @@ import { zoomLevelToZoomScale, zoomLevelForResolution } from "./util/zoomLevel.j
4
4
  import { GeoBounds } from "./util/bounds.js";
5
5
  import { Extent } from "./util/extent.js";
6
6
  import { bboxFeature } from "./util/bboxFeature.js";
7
- import { resolutionForExtent } from "./util/resolution.js";
7
+ import { resolutionForBounds } from "./util/resolution.js";
8
8
  import { Projection } from "./projection/index.js";
9
9
  import { generateDebugUrl } from "./util/debug.js";
10
10
  class View {
@@ -23,7 +23,8 @@ class View {
23
23
  this.debug = debug;
24
24
  projection.revision = 0;
25
25
  this.projection = projection;
26
- this.bounds = this.extent = Extent.convert(extent) || GeoBounds.convert(bounds).toExtent();
26
+ this.bounds = bounds && GeoBounds.convert(bounds);
27
+ this.extent = Extent.convert(extent) || GeoBounds.convert(bounds).toExtent();
27
28
  this.minZoom = minZoom;
28
29
  this.maxZoom = maxZoom;
29
30
  this._transform = zoomIdentity;
@@ -40,6 +41,10 @@ class View {
40
41
  }
41
42
  }
42
43
  }
44
+ /**
45
+ * @returns {[number, number]} - The size of the viewport in pixels
46
+ * @readonly
47
+ */
43
48
  get viewPortSize() {
44
49
  return this._viewPortSize;
45
50
  }
@@ -66,8 +71,8 @@ class View {
66
71
  return scalePadding(scaledPadding, this.pixelRatio);
67
72
  }
68
73
  get baseResolution() {
69
- const baseExtent = this.getVisibleBounds(zoomIdentity, this.projection);
70
- const baseResolution = resolutionForExtent(baseExtent, this.viewPortSize);
74
+ const bounds = this.bounds ?? this.getVisibleBounds(zoomIdentity, this.projection);
75
+ const baseResolution = resolutionForBounds(bounds, this.viewPortSize);
71
76
  return baseResolution;
72
77
  }
73
78
  /**
@@ -139,7 +144,7 @@ class View {
139
144
  }
140
145
  // map resolution (meters per pixel)
141
146
  getResolution() {
142
- return resolutionForExtent(
147
+ return resolutionForBounds(
143
148
  this.getVisibleBounds(this.transform, this.projection),
144
149
  this.viewPortSize
145
150
  );
@@ -173,20 +178,13 @@ class View {
173
178
  * @function getBounds
174
179
  * @param {ZoomTransform} transform
175
180
  * @param {*} projection
176
- * @returns {import("./util").GeoBoundsLike}
181
+ * @returns {import("./util").GeoBounds}
177
182
  */
178
183
  getVisibleBounds(transform, projection) {
179
184
  const [width, height] = this.mapSize;
180
185
  const southWest = projection.invert(transform.invert([0, height]));
181
186
  const northEast = projection.invert(transform.invert([width, 0]));
182
- const southWestLatitude = southWest[1];
183
- const northEastLatitude = northEast[1];
184
- const flippedY = southWestLatitude < northEastLatitude;
185
- if (flippedY) {
186
- return [southWest[0], southWest[1], northEast[0], northEast[1]];
187
- } else {
188
- return [southWest[0], northEast[1], northEast[0], southWest[1]];
189
- }
187
+ return GeoBounds.convert({ sw: southWest, ne: northEast });
190
188
  }
191
189
  getState() {
192
190
  const transform = this.transform;
@@ -199,7 +197,7 @@ class View {
199
197
  padding: this.padding,
200
198
  viewPortSize: this.viewPortSize,
201
199
  sizeInPixels: scaleSize(this.viewPortSize, this.pixelRatio),
202
- visibleExtent: this.getVisibleBounds(transform, projection)
200
+ visibleExtent: this.getVisibleBounds(transform, projection).toExtent()
203
201
  };
204
202
  }
205
203
  }
@@ -21,10 +21,10 @@ export class VectorSource {
21
21
  */
22
22
  getFeaturesAtCoordinate(coordinate: [number, number]): import('../Feature').Feature[];
23
23
  /**
24
- * @param {[number, number, number, number]} extent TODO: should this be an `Extent`?
24
+ * @param {import("../util/extent").Extent} extent
25
25
  * @returns {import("../Feature").Feature[]}
26
26
  */
27
- getFeaturesInExtent(extent: [number, number, number, number]): import('../Feature').Feature[];
27
+ getFeaturesInExtent(extent: import('../util/extent').Extent): import('../Feature').Feature[];
28
28
  /**
29
29
  * @param {import("../Feature").Feature[]} features
30
30
  */
@@ -39,11 +39,11 @@ class VectorSource {
39
39
  return items.map((d) => d.feature);
40
40
  }
41
41
  /**
42
- * @param {[number, number, number, number]} extent TODO: should this be an `Extent`?
42
+ * @param {import("../util/extent").Extent} extent
43
43
  * @returns {import("../Feature").Feature[]}
44
44
  */
45
45
  getFeaturesInExtent(extent) {
46
- const [minX, minY, maxX, maxY] = extent;
46
+ const { minX, minY, maxX, maxY } = extent;
47
47
  const features = this._featuresRtree.search({ minX, minY, maxX, maxY }).map((d) => d.feature);
48
48
  return features;
49
49
  }
@@ -41,6 +41,12 @@ class HashPattern {
41
41
  */
42
42
  _createPattern(ctx, scale) {
43
43
  const size = this.tileSize * scale;
44
+ if (size <= 0) {
45
+ console.error(
46
+ `HashPattern: size (${size}) is too small to draw a pattern. Pattern width and height must be > 0`
47
+ );
48
+ return;
49
+ }
44
50
  this.offscreenCanvas.width = size;
45
51
  this.offscreenCanvas.height = size;
46
52
  const offCtx = this.offscreenCanvas.getContext("2d");
@@ -23,12 +23,24 @@ class GeoBounds {
23
23
  ];
24
24
  }
25
25
  toExtent() {
26
- return new Extent(
27
- this.southWest.lng,
28
- this.southWest.lat,
29
- this.northEast.lng,
30
- this.northEast.lat
31
- );
26
+ const southWestLatitude = this.southWest.lat;
27
+ const northEastLatitude = this.northEast.lat;
28
+ const flippedY = southWestLatitude < northEastLatitude;
29
+ if (flippedY) {
30
+ return new Extent(
31
+ this.southWest.lng,
32
+ this.southWest.lat,
33
+ this.northEast.lng,
34
+ this.northEast.lat
35
+ );
36
+ } else {
37
+ return new Extent(
38
+ this.southWest.lng,
39
+ this.northEast.lat,
40
+ this.northEast.lng,
41
+ this.southWest.lat
42
+ );
43
+ }
32
44
  }
33
45
  /**
34
46
  * Converts an array to a `GeoBounds` object.
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Get map resolution
3
3
  *
4
- * @param {Extent} extent Geographical extent: [ lonMin, latMin, lonMax, latMax ]
5
- * @param {size} viewportSize Viewport size: [ width, height ]
4
+ * @param {import("./bounds").GeoBounds} bounds
5
+ * @param {[Number, Number]} viewportSize
6
6
  * @return {number} Map resolution (horizontal)
7
7
  * @api
8
8
  */
9
- export function resolutionForExtent(extent: Extent, viewportSize: size): number;
9
+ export function resolutionForBounds(bounds: import('./bounds').GeoBounds, viewportSize: [number, number]): number;
@@ -1,11 +1,16 @@
1
1
  import { haversineDistance } from "./distance.js";
2
- function resolutionForExtent(extent, viewportSize) {
3
- const [lonMin, latMin, lonMax, latMax] = extent;
4
- const latMid = (latMin + latMax) / 2;
5
- const distance = haversineDistance(latMid, lonMin, latMid, lonMax);
2
+ function resolutionForBounds(bounds, viewportSize) {
3
+ const { southWest, northEast } = bounds;
4
+ const latMid = (southWest.lat + northEast.lat) / 2;
5
+ const distance = haversineDistance(
6
+ latMid,
7
+ southWest.lng,
8
+ latMid,
9
+ northEast.lng
10
+ );
6
11
  const resolution = distance / viewportSize[0];
7
12
  return resolution;
8
13
  }
9
14
  export {
10
- resolutionForExtent
15
+ resolutionForBounds
11
16
  };
@@ -1,7 +1,7 @@
1
- const refreshIndicator = "_refreshIndicator_3z0ji_9";
2
- const icon = "_icon_3z0ji_17";
3
- const liveText = "_liveText_3z0ji_26";
4
- const refreshText = "_refreshText_3z0ji_27";
1
+ const refreshIndicator = "_refreshIndicator_1ikk9_9";
2
+ const icon = "_icon_1ikk9_17";
3
+ const liveText = "_liveText_1ikk9_26";
4
+ const refreshText = "_refreshText_1ikk9_27";
5
5
  const defaultStyles = {
6
6
  refreshIndicator,
7
7
  icon,
package/dist/index.js CHANGED
@@ -51,7 +51,7 @@ import { GeoCoordinate } from "./components/molecules/canvas-map/lib/util/coordi
51
51
  import { GeoBounds } from "./components/molecules/canvas-map/lib/util/bounds.js";
52
52
  import { Extent, combineExtents, containsCoordinate, containsXY, extentForCoordinates } from "./components/molecules/canvas-map/lib/util/extent.js";
53
53
  import { bboxFeature } from "./components/molecules/canvas-map/lib/util/bboxFeature.js";
54
- import { resolutionForExtent } from "./components/molecules/canvas-map/lib/util/resolution.js";
54
+ import { resolutionForBounds } from "./components/molecules/canvas-map/lib/util/resolution.js";
55
55
  import { zoomLevelForResolution, zoomLevelToZoomScale } from "./components/molecules/canvas-map/lib/util/zoomLevel.js";
56
56
  import { interpolateFeatures } from "./components/molecules/canvas-map/lib/interpolators/interpolateFeatures.js";
57
57
  import { interpolateFill, interpolateStroke, interpolateStyles } from "./components/molecules/canvas-map/lib/interpolators/interpolateStyles.js";
@@ -141,7 +141,7 @@ export {
141
141
  interpolateFill,
142
142
  interpolateStroke,
143
143
  interpolateStyles,
144
- resolutionForExtent,
144
+ resolutionForBounds,
145
145
  saveSVG,
146
146
  useContainerSize,
147
147
  useTouchOrHover,
package/dist/style.css CHANGED
@@ -2674,15 +2674,15 @@ body.android {
2674
2674
  --top-inset: 58px;
2675
2675
  }
2676
2676
 
2677
- ._refreshIndicator_3z0ji_9 {
2677
+ ._refreshIndicator_1ikk9_9 {
2678
2678
  display: flex;
2679
2679
  flex-direction: row;
2680
2680
  column-gap: var(--space-0);
2681
- align-items: stretch;
2681
+ align-items: center;
2682
2682
  flex-wrap: wrap;
2683
2683
  }
2684
2684
 
2685
- ._icon_3z0ji_17 {
2685
+ ._icon_1ikk9_17 {
2686
2686
  display: flex;
2687
2687
  flex-direction: column;
2688
2688
  justify-content: center;
@@ -2691,23 +2691,23 @@ body.android {
2691
2691
  line-height: var(--sans-line-height);
2692
2692
  }
2693
2693
 
2694
- ._liveText_3z0ji_26,
2695
- ._refreshText_3z0ji_27 {
2694
+ ._liveText_1ikk9_26,
2695
+ ._refreshText_1ikk9_27 {
2696
2696
  font-family: var(--text-sans);
2697
2697
  color: var(--secondary-text-color);
2698
2698
  line-height: var(--sans-line-height);
2699
2699
  font-size: var(--sans-small);
2700
2700
  }
2701
2701
 
2702
- ._liveText_3z0ji_26 {
2702
+ ._liveText_1ikk9_26 {
2703
2703
  font-weight: 700;
2704
2704
  }
2705
2705
 
2706
- ._refreshText_3z0ji_27 {
2706
+ ._refreshText_1ikk9_27 {
2707
2707
  margin-left: var(--space-0);
2708
2708
  }
2709
2709
  @media (min-width: 71.25em) and (max-width: 81.24em) {
2710
- ._refreshText_3z0ji_27 {
2710
+ ._refreshText_1ikk9_27 {
2711
2711
  flex-basis: 100%;
2712
2712
  }
2713
2713
  }body {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@guardian/interactive-component-library",
3
3
  "private": false,
4
- "version": "0.7.10",
4
+ "version": "0.7.12",
5
5
  "packageManager": "pnpm@8.4.0",
6
6
  "repository": {
7
7
  "type": "git",