@gooddata/sdk-ui-geo 11.6.0-alpha.5 → 11.6.0-alpha.7
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/esm/next/GeoPushpinChartNext.d.ts +12 -0
- package/esm/next/GeoPushpinChartNext.d.ts.map +1 -0
- package/esm/next/GeoPushpinChartNext.js +42 -0
- package/esm/next/GeoPushpinChartNext.js.map +1 -0
- package/esm/next/RenderGeoPushpinChart.d.ts +15 -0
- package/esm/next/RenderGeoPushpinChart.d.ts.map +1 -0
- package/esm/next/RenderGeoPushpinChart.js +97 -0
- package/esm/next/RenderGeoPushpinChart.js.map +1 -0
- package/esm/next/components/ErrorComponent.d.ts +13 -0
- package/esm/next/components/ErrorComponent.d.ts.map +1 -0
- package/esm/next/components/ErrorComponent.js +19 -0
- package/esm/next/components/ErrorComponent.js.map +1 -0
- package/esm/next/components/LoadingComponent.d.ts +5 -0
- package/esm/next/components/LoadingComponent.d.ts.map +1 -0
- package/esm/next/components/LoadingComponent.js +13 -0
- package/esm/next/components/LoadingComponent.js.map +1 -0
- package/esm/next/components/legends/Legend.d.ts +28 -0
- package/esm/next/components/legends/Legend.d.ts.map +1 -0
- package/esm/next/components/legends/Legend.js +54 -0
- package/esm/next/components/legends/Legend.js.map +1 -0
- package/esm/next/components/legends/LegendBody.d.ts +12 -0
- package/esm/next/components/legends/LegendBody.d.ts.map +1 -0
- package/esm/next/components/legends/LegendBody.js +30 -0
- package/esm/next/components/legends/LegendBody.js.map +1 -0
- package/esm/next/components/legends/legendPropsAdapter.d.ts +14 -0
- package/esm/next/components/legends/legendPropsAdapter.d.ts.map +1 -0
- package/esm/next/components/legends/legendPropsAdapter.js +34 -0
- package/esm/next/components/legends/legendPropsAdapter.js.map +1 -0
- package/esm/next/components/legends/types.d.ts +16 -0
- package/esm/next/components/legends/types.d.ts.map +1 -0
- package/esm/next/components/legends/types.js +3 -0
- package/esm/next/components/legends/types.js.map +1 -0
- package/esm/next/constants/geoChart.d.ts +108 -0
- package/esm/next/constants/geoChart.d.ts.map +1 -0
- package/esm/next/constants/geoChart.js +130 -0
- package/esm/next/constants/geoChart.js.map +1 -0
- package/esm/next/constants/internal.d.ts +19 -0
- package/esm/next/constants/internal.d.ts.map +1 -0
- package/esm/next/constants/internal.js +20 -0
- package/esm/next/constants/internal.js.map +1 -0
- package/esm/next/context/GeoDataContext.d.ts +69 -0
- package/esm/next/context/GeoDataContext.d.ts.map +1 -0
- package/esm/next/context/GeoDataContext.js +80 -0
- package/esm/next/context/GeoDataContext.js.map +1 -0
- package/esm/next/context/GeoLegendContext.d.ts +78 -0
- package/esm/next/context/GeoLegendContext.d.ts.map +1 -0
- package/esm/next/context/GeoLegendContext.js +74 -0
- package/esm/next/context/GeoLegendContext.js.map +1 -0
- package/esm/next/context/GeoPushpinPropsContext.d.ts +47 -0
- package/esm/next/context/GeoPushpinPropsContext.d.ts.map +1 -0
- package/esm/next/context/GeoPushpinPropsContext.js +81 -0
- package/esm/next/context/GeoPushpinPropsContext.js.map +1 -0
- package/esm/next/context/InitialExecutionContext.d.ts +43 -0
- package/esm/next/context/InitialExecutionContext.d.ts.map +1 -0
- package/esm/next/context/InitialExecutionContext.js +45 -0
- package/esm/next/context/InitialExecutionContext.js.map +1 -0
- package/esm/next/context/MapInstanceContext.d.ts +42 -0
- package/esm/next/context/MapInstanceContext.d.ts.map +1 -0
- package/esm/next/context/MapInstanceContext.js +62 -0
- package/esm/next/context/MapInstanceContext.js.map +1 -0
- package/esm/next/features/clustering/clustering.d.ts +23 -0
- package/esm/next/features/clustering/clustering.d.ts.map +1 -0
- package/esm/next/features/clustering/clustering.js +26 -0
- package/esm/next/features/clustering/clustering.js.map +1 -0
- package/esm/next/features/coloring/colorStrategy.d.ts +22 -0
- package/esm/next/features/coloring/colorStrategy.d.ts.map +1 -0
- package/esm/next/features/coloring/colorStrategy.js +83 -0
- package/esm/next/features/coloring/colorStrategy.js.map +1 -0
- package/esm/next/features/coloring/palette.d.ts +81 -0
- package/esm/next/features/coloring/palette.d.ts.map +1 -0
- package/esm/next/features/coloring/palette.js +233 -0
- package/esm/next/features/coloring/palette.js.map +1 -0
- package/esm/next/features/data/dataSourceManagement.d.ts +20 -0
- package/esm/next/features/data/dataSourceManagement.d.ts.map +1 -0
- package/esm/next/features/data/dataSourceManagement.js +30 -0
- package/esm/next/features/data/dataSourceManagement.js.map +1 -0
- package/esm/next/features/data/transformation.d.ts +99 -0
- package/esm/next/features/data/transformation.d.ts.map +1 -0
- package/esm/next/features/data/transformation.js +369 -0
- package/esm/next/features/data/transformation.js.map +1 -0
- package/esm/next/features/map/initializeMap.d.ts +30 -0
- package/esm/next/features/map/initializeMap.d.ts.map +1 -0
- package/esm/next/features/map/initializeMap.js +58 -0
- package/esm/next/features/map/initializeMap.js.map +1 -0
- package/esm/next/features/map/layerManagement.d.ts +51 -0
- package/esm/next/features/map/layerManagement.d.ts.map +1 -0
- package/esm/next/features/map/layerManagement.js +95 -0
- package/esm/next/features/map/layerManagement.js.map +1 -0
- package/esm/next/features/map/viewportManagement.d.ts +76 -0
- package/esm/next/features/map/viewportManagement.d.ts.map +1 -0
- package/esm/next/features/map/viewportManagement.js +193 -0
- package/esm/next/features/map/viewportManagement.js.map +1 -0
- package/esm/next/features/size/calculations.d.ts +32 -0
- package/esm/next/features/size/calculations.d.ts.map +1 -0
- package/esm/next/features/size/calculations.js +37 -0
- package/esm/next/features/size/calculations.js.map +1 -0
- package/esm/next/features/tooltip/formatting.d.ts +28 -0
- package/esm/next/features/tooltip/formatting.d.ts.map +1 -0
- package/esm/next/features/tooltip/formatting.js +51 -0
- package/esm/next/features/tooltip/formatting.js.map +1 -0
- package/esm/next/features/tooltip/tooltipManagement.d.ts +47 -0
- package/esm/next/features/tooltip/tooltipManagement.d.ts.map +1 -0
- package/esm/next/features/tooltip/tooltipManagement.js +73 -0
- package/esm/next/features/tooltip/tooltipManagement.js.map +1 -0
- package/esm/next/hooks/init/useInitExecution.d.ts +29 -0
- package/esm/next/hooks/init/useInitExecution.d.ts.map +1 -0
- package/esm/next/hooks/init/useInitExecution.js +91 -0
- package/esm/next/hooks/init/useInitExecution.js.map +1 -0
- package/esm/next/hooks/init/useInitExecutionResult.d.ts +17 -0
- package/esm/next/hooks/init/useInitExecutionResult.d.ts.map +1 -0
- package/esm/next/hooks/init/useInitExecutionResult.js +44 -0
- package/esm/next/hooks/init/useInitExecutionResult.js.map +1 -0
- package/esm/next/hooks/legend/useLegendConfig.d.ts +35 -0
- package/esm/next/hooks/legend/useLegendConfig.d.ts.map +1 -0
- package/esm/next/hooks/legend/useLegendConfig.js +25 -0
- package/esm/next/hooks/legend/useLegendConfig.js.map +1 -0
- package/esm/next/hooks/legend/useLegendDetails.d.ts +27 -0
- package/esm/next/hooks/legend/useLegendDetails.d.ts.map +1 -0
- package/esm/next/hooks/legend/useLegendDetails.js +39 -0
- package/esm/next/hooks/legend/useLegendDetails.js.map +1 -0
- package/esm/next/hooks/legend/useLegendItemClick.d.ts +16 -0
- package/esm/next/hooks/legend/useLegendItemClick.d.ts.map +1 -0
- package/esm/next/hooks/legend/useLegendItemClick.js +23 -0
- package/esm/next/hooks/legend/useLegendItemClick.js.map +1 -0
- package/esm/next/hooks/legend/useLegendItems.d.ts +27 -0
- package/esm/next/hooks/legend/useLegendItems.d.ts.map +1 -0
- package/esm/next/hooks/legend/useLegendItems.js +54 -0
- package/esm/next/hooks/legend/useLegendItems.js.map +1 -0
- package/esm/next/hooks/legend/useLegendItemsWithState.d.ts +21 -0
- package/esm/next/hooks/legend/useLegendItemsWithState.d.ts.map +1 -0
- package/esm/next/hooks/legend/useLegendItemsWithState.js +42 -0
- package/esm/next/hooks/legend/useLegendItemsWithState.js.map +1 -0
- package/esm/next/hooks/legend/useLegendProps.d.ts +53 -0
- package/esm/next/hooks/legend/useLegendProps.d.ts.map +1 -0
- package/esm/next/hooks/legend/useLegendProps.js +38 -0
- package/esm/next/hooks/legend/useLegendProps.js.map +1 -0
- package/esm/next/hooks/legend/useSelectedSegments.d.ts +17 -0
- package/esm/next/hooks/legend/useSelectedSegments.d.ts.map +1 -0
- package/esm/next/hooks/legend/useSelectedSegments.js +32 -0
- package/esm/next/hooks/legend/useSelectedSegments.js.map +1 -0
- package/esm/next/hooks/map/useAfterRender.d.ts +19 -0
- package/esm/next/hooks/map/useAfterRender.d.ts.map +1 -0
- package/esm/next/hooks/map/useAfterRender.js +99 -0
- package/esm/next/hooks/map/useAfterRender.js.map +1 -0
- package/esm/next/hooks/map/useMapCallbacks.d.ts +20 -0
- package/esm/next/hooks/map/useMapCallbacks.d.ts.map +1 -0
- package/esm/next/hooks/map/useMapCallbacks.js +44 -0
- package/esm/next/hooks/map/useMapCallbacks.js.map +1 -0
- package/esm/next/hooks/map/useMapDataSync.d.ts +44 -0
- package/esm/next/hooks/map/useMapDataSync.d.ts.map +1 -0
- package/esm/next/hooks/map/useMapDataSync.js +87 -0
- package/esm/next/hooks/map/useMapDataSync.js.map +1 -0
- package/esm/next/hooks/map/useMapInitialization.d.ts +56 -0
- package/esm/next/hooks/map/useMapInitialization.d.ts.map +1 -0
- package/esm/next/hooks/map/useMapInitialization.js +121 -0
- package/esm/next/hooks/map/useMapInitialization.js.map +1 -0
- package/esm/next/hooks/map/useTooltipHandlers.d.ts +22 -0
- package/esm/next/hooks/map/useTooltipHandlers.d.ts.map +1 -0
- package/esm/next/hooks/map/useTooltipHandlers.js +28 -0
- package/esm/next/hooks/map/useTooltipHandlers.js.map +1 -0
- package/esm/next/hooks/shared/useGeoDataTransformation.d.ts +23 -0
- package/esm/next/hooks/shared/useGeoDataTransformation.d.ts.map +1 -0
- package/esm/next/hooks/shared/useGeoDataTransformation.js +37 -0
- package/esm/next/hooks/shared/useGeoDataTransformation.js.map +1 -0
- package/esm/next/hooks/shared/usePushData.d.ts +8 -0
- package/esm/next/hooks/shared/usePushData.d.ts.map +1 -0
- package/esm/next/hooks/shared/usePushData.js +36 -0
- package/esm/next/hooks/shared/usePushData.js.map +1 -0
- package/esm/next/hooks/shared/useResolvedProps.d.ts +16 -0
- package/esm/next/hooks/shared/useResolvedProps.d.ts.map +1 -0
- package/esm/next/hooks/shared/useResolvedProps.js +40 -0
- package/esm/next/hooks/shared/useResolvedProps.js.map +1 -0
- package/esm/next/index.d.ts +5 -0
- package/esm/next/index.d.ts.map +1 -0
- package/esm/next/index.js +3 -0
- package/esm/next/index.js.map +1 -0
- package/esm/next/providers/maplibre/maplibreConfig.d.ts +68 -0
- package/esm/next/providers/maplibre/maplibreConfig.d.ts.map +1 -0
- package/esm/next/providers/maplibre/maplibreConfig.js +104 -0
- package/esm/next/providers/maplibre/maplibreConfig.js.map +1 -0
- package/esm/next/providers/maplibre/maplibreDataLayers.d.ts +51 -0
- package/esm/next/providers/maplibre/maplibreDataLayers.d.ts.map +1 -0
- package/esm/next/providers/maplibre/maplibreDataLayers.js +195 -0
- package/esm/next/providers/maplibre/maplibreDataLayers.js.map +1 -0
- package/esm/next/providers/maplibre/maplibreDataSource.d.ts +28 -0
- package/esm/next/providers/maplibre/maplibreDataSource.d.ts.map +1 -0
- package/esm/next/providers/maplibre/maplibreDataSource.js +117 -0
- package/esm/next/providers/maplibre/maplibreDataSource.js.map +1 -0
- package/esm/next/providers/maplibre/maplibreTooltip.d.ts +54 -0
- package/esm/next/providers/maplibre/maplibreTooltip.d.ts.map +1 -0
- package/esm/next/providers/maplibre/maplibreTooltip.js +158 -0
- package/esm/next/providers/maplibre/maplibreTooltip.js.map +1 -0
- package/esm/next/providers/maplibre/maplibreViewport.d.ts +45 -0
- package/esm/next/providers/maplibre/maplibreViewport.d.ts.map +1 -0
- package/esm/next/providers/maplibre/maplibreViewport.js +92 -0
- package/esm/next/providers/maplibre/maplibreViewport.js.map +1 -0
- package/esm/next/providers/maplibre/style.d.ts +3 -0
- package/esm/next/providers/maplibre/style.d.ts.map +1 -0
- package/esm/next/providers/maplibre/style.js +8361 -0
- package/esm/next/providers/maplibre/style.js.map +1 -0
- package/esm/next/types/config.d.ts +89 -0
- package/esm/next/types/config.d.ts.map +1 -0
- package/esm/next/types/config.js +3 -0
- package/esm/next/types/config.js.map +1 -0
- package/esm/next/types/internal.d.ts +17 -0
- package/esm/next/types/internal.d.ts.map +1 -0
- package/esm/next/types/internal.js +3 -0
- package/esm/next/types/internal.js.map +1 -0
- package/esm/next/types/mapProvider.d.ts +122 -0
- package/esm/next/types/mapProvider.d.ts.map +1 -0
- package/esm/next/types/mapProvider.js +3 -0
- package/esm/next/types/mapProvider.js.map +1 -0
- package/esm/next/types/public.d.ts +84 -0
- package/esm/next/types/public.d.ts.map +1 -0
- package/esm/next/types/public.js +15 -0
- package/esm/next/types/public.js.map +1 -0
- package/esm/next/types/shared.d.ts +209 -0
- package/esm/next/types/shared.d.ts.map +1 -0
- package/esm/next/types/shared.js +3 -0
- package/esm/next/types/shared.js.map +1 -0
- package/esm/next/utils/mapLocale.d.ts +26 -0
- package/esm/next/utils/mapLocale.d.ts.map +1 -0
- package/esm/next/utils/mapLocale.js +22 -0
- package/esm/next/utils/mapLocale.js.map +1 -0
- package/package.json +13 -10
- package/styles/css/main.css +925 -0
- package/styles/css/main.css.map +1 -1
- package/styles/scss/_geo-pushpin-next-legend.scss +166 -0
- package/styles/scss/_maplibre-overrides.scss +64 -0
- package/styles/scss/geo-pushpin-next.scss +58 -0
- package/styles/scss/main.scss +1 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { Map as MapLibreMap } from "maplibre-gl";
|
|
2
|
+
import { IMapConfig, IMapViewport } from "../../types/mapProvider.js";
|
|
3
|
+
import { IGeoLngLat } from "../../types/shared.js";
|
|
4
|
+
/**
|
|
5
|
+
* Calculate optimal viewport for data points
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* This function determines the best viewport (center/zoom or bounds) based on
|
|
9
|
+
* the provided location data and configuration. It considers:
|
|
10
|
+
* - Explicit center/zoom from config
|
|
11
|
+
* - Viewport area presets (continents, world, etc.)
|
|
12
|
+
* - Calculated bounds from data points
|
|
13
|
+
* - Default fallback values
|
|
14
|
+
*
|
|
15
|
+
* @param locations - Array of location coordinates
|
|
16
|
+
* @param config - Map configuration
|
|
17
|
+
* @returns Viewport configuration with center/zoom or bounds
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export declare function calculateViewport(locations: IGeoLngLat[], config: IMapConfig): Partial<IMapViewport>;
|
|
22
|
+
/**
|
|
23
|
+
* Apply viewport to map instance
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* This function applies a viewport configuration to the map. It can:
|
|
27
|
+
* - Fit the map to bounds with padding
|
|
28
|
+
* - Set center and zoom together
|
|
29
|
+
* - Pan to a new center
|
|
30
|
+
* - Zoom to a specific level
|
|
31
|
+
*
|
|
32
|
+
* The animate parameter controls whether transitions are animated.
|
|
33
|
+
*
|
|
34
|
+
* @param map - MapLibre map instance
|
|
35
|
+
* @param viewport - Viewport configuration to apply
|
|
36
|
+
* @param animate - Whether to animate the transition
|
|
37
|
+
*
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
export declare function applyViewport(map: MapLibreMap, viewport: Partial<IMapViewport>, animate?: boolean): void;
|
|
41
|
+
/**
|
|
42
|
+
* Apply viewport with manual center/zoom calculation for bounds
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* This is a specialized version that manually calculates center and zoom
|
|
46
|
+
* from bounds to avoid fitBounds wrapping issues with continental-scale data.
|
|
47
|
+
* Used primarily during initial map setup.
|
|
48
|
+
*
|
|
49
|
+
* @param map - MapLibre map instance
|
|
50
|
+
* @param viewport - Viewport configuration to apply
|
|
51
|
+
*
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
export declare function applyViewportWithManualCalculation(map: MapLibreMap, viewport: Partial<IMapViewport>): void;
|
|
55
|
+
/**
|
|
56
|
+
* Apply viewport with graceful error handling
|
|
57
|
+
*
|
|
58
|
+
* @remarks
|
|
59
|
+
* This function applies a viewport with automatic fallback strategies:
|
|
60
|
+
* 1. Try standard applyViewport (respects animations and constraints)
|
|
61
|
+
* 2. If that fails and we're still loading, retry once on "idle"
|
|
62
|
+
* 3. If still failing, use manual calculation as last resort
|
|
63
|
+
*
|
|
64
|
+
* This handles edge cases like:
|
|
65
|
+
* - Map not fully loaded yet
|
|
66
|
+
* - Invalid bounds that cause fitBounds to throw
|
|
67
|
+
* - Continental-scale data that causes wrapping issues
|
|
68
|
+
*
|
|
69
|
+
* @param map - MapLibre map instance
|
|
70
|
+
* @param viewport - Viewport configuration to apply
|
|
71
|
+
* @returns Cleanup function to remove event listeners
|
|
72
|
+
*
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
export declare function applyViewportSafely(map: MapLibreMap, viewport: Partial<IMapViewport>): (() => void) | undefined;
|
|
76
|
+
//# sourceMappingURL=viewportManagement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewportManagement.d.ts","sourceRoot":"","sources":["../../../../src/next/features/map/viewportManagement.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAwC,GAAG,IAAI,WAAW,EAAE,MAAM,aAAa,CAAC;AAG5F,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AA2DnD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAQpG;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CACzB,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,EAC/B,OAAO,GAAE,OAAc,GACxB,IAAI,CAoBN;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAa1G;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CAC/B,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,GAChC,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAkC1B"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// (C) 2025 GoodData Corporation
|
|
2
|
+
import { getViewportOptions } from "../../providers/maplibre/maplibreViewport.js";
|
|
3
|
+
function toTuple(lngLat) {
|
|
4
|
+
if (Array.isArray(lngLat)) {
|
|
5
|
+
const [lng = 0, lat = 0] = lngLat;
|
|
6
|
+
return [lng, lat];
|
|
7
|
+
}
|
|
8
|
+
if (typeof lngLat === "object" && lngLat) {
|
|
9
|
+
const candidate = lngLat;
|
|
10
|
+
const lng = typeof candidate.lng === "function" ? candidate.lng() : (candidate.lng ?? candidate.lon ?? 0);
|
|
11
|
+
const lat = typeof candidate.lat === "function" ? candidate.lat() : (candidate.lat ?? 0);
|
|
12
|
+
return [lng, lat];
|
|
13
|
+
}
|
|
14
|
+
return [0, 0];
|
|
15
|
+
}
|
|
16
|
+
function normalizeBounds(bounds) {
|
|
17
|
+
if (!bounds) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
if (typeof bounds.getSouthWest ===
|
|
21
|
+
"function") {
|
|
22
|
+
const sw = bounds.getSouthWest();
|
|
23
|
+
const ne = bounds.getNorthEast();
|
|
24
|
+
const [swLng, swLat] = toTuple(sw);
|
|
25
|
+
const [neLng, neLat] = toTuple(ne);
|
|
26
|
+
return {
|
|
27
|
+
southWest: { lng: Math.min(swLng, neLng), lat: Math.min(swLat, neLat) },
|
|
28
|
+
northEast: { lng: Math.max(swLng, neLng), lat: Math.max(swLat, neLat) },
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (Array.isArray(bounds)) {
|
|
32
|
+
const [first, second] = bounds;
|
|
33
|
+
if (!first || !second) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
const [lng1, lat1] = toTuple(first);
|
|
37
|
+
const [lng2, lat2] = toTuple(second);
|
|
38
|
+
return {
|
|
39
|
+
southWest: { lng: Math.min(lng1, lng2), lat: Math.min(lat1, lat2) },
|
|
40
|
+
northEast: { lng: Math.max(lng1, lng2), lat: Math.max(lat1, lat2) },
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Calculate optimal viewport for data points
|
|
47
|
+
*
|
|
48
|
+
* @remarks
|
|
49
|
+
* This function determines the best viewport (center/zoom or bounds) based on
|
|
50
|
+
* the provided location data and configuration. It considers:
|
|
51
|
+
* - Explicit center/zoom from config
|
|
52
|
+
* - Viewport area presets (continents, world, etc.)
|
|
53
|
+
* - Calculated bounds from data points
|
|
54
|
+
* - Default fallback values
|
|
55
|
+
*
|
|
56
|
+
* @param locations - Array of location coordinates
|
|
57
|
+
* @param config - Map configuration
|
|
58
|
+
* @returns Viewport configuration with center/zoom or bounds
|
|
59
|
+
*
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
export function calculateViewport(locations, config) {
|
|
63
|
+
const viewportOptions = getViewportOptions(locations, config);
|
|
64
|
+
return {
|
|
65
|
+
center: viewportOptions.center,
|
|
66
|
+
zoom: viewportOptions.zoom,
|
|
67
|
+
bounds: normalizeBounds(viewportOptions.bounds),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Apply viewport to map instance
|
|
72
|
+
*
|
|
73
|
+
* @remarks
|
|
74
|
+
* This function applies a viewport configuration to the map. It can:
|
|
75
|
+
* - Fit the map to bounds with padding
|
|
76
|
+
* - Set center and zoom together
|
|
77
|
+
* - Pan to a new center
|
|
78
|
+
* - Zoom to a specific level
|
|
79
|
+
*
|
|
80
|
+
* The animate parameter controls whether transitions are animated.
|
|
81
|
+
*
|
|
82
|
+
* @param map - MapLibre map instance
|
|
83
|
+
* @param viewport - Viewport configuration to apply
|
|
84
|
+
* @param animate - Whether to animate the transition
|
|
85
|
+
*
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
export function applyViewport(map, viewport, animate = true) {
|
|
89
|
+
const options = { animate };
|
|
90
|
+
if (viewport.bounds) {
|
|
91
|
+
const bounds = [
|
|
92
|
+
[viewport.bounds.southWest.lng, viewport.bounds.southWest.lat],
|
|
93
|
+
[viewport.bounds.northEast.lng, viewport.bounds.northEast.lat],
|
|
94
|
+
];
|
|
95
|
+
map.fitBounds(bounds, { ...options, padding: 45 });
|
|
96
|
+
}
|
|
97
|
+
else if (viewport.center && viewport.zoom !== undefined) {
|
|
98
|
+
map.flyTo({
|
|
99
|
+
center: [viewport.center.lng, viewport.center.lat],
|
|
100
|
+
zoom: viewport.zoom,
|
|
101
|
+
...options,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
else if (viewport.center) {
|
|
105
|
+
map.panTo([viewport.center.lng, viewport.center.lat], options);
|
|
106
|
+
}
|
|
107
|
+
else if (viewport.zoom !== undefined) {
|
|
108
|
+
map.zoomTo(viewport.zoom, options);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Apply viewport with manual center/zoom calculation for bounds
|
|
113
|
+
*
|
|
114
|
+
* @remarks
|
|
115
|
+
* This is a specialized version that manually calculates center and zoom
|
|
116
|
+
* from bounds to avoid fitBounds wrapping issues with continental-scale data.
|
|
117
|
+
* Used primarily during initial map setup.
|
|
118
|
+
*
|
|
119
|
+
* @param map - MapLibre map instance
|
|
120
|
+
* @param viewport - Viewport configuration to apply
|
|
121
|
+
*
|
|
122
|
+
* @internal
|
|
123
|
+
*/
|
|
124
|
+
export function applyViewportWithManualCalculation(map, viewport) {
|
|
125
|
+
if (viewport.bounds) {
|
|
126
|
+
// Calculate center manually to avoid fitBounds wrapping issues
|
|
127
|
+
const { southWest, northEast } = viewport.bounds;
|
|
128
|
+
const centerLng = (southWest.lng + northEast.lng) / 2;
|
|
129
|
+
const centerLat = (southWest.lat + northEast.lat) / 2;
|
|
130
|
+
const zoom = 3; // Conservative zoom for continental-scale data
|
|
131
|
+
map.setCenter([centerLng, centerLat]);
|
|
132
|
+
map.setZoom(zoom);
|
|
133
|
+
}
|
|
134
|
+
else if (viewport.center && viewport.zoom !== undefined) {
|
|
135
|
+
map.setCenter([viewport.center.lng, viewport.center.lat]);
|
|
136
|
+
map.setZoom(viewport.zoom);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Apply viewport with graceful error handling
|
|
141
|
+
*
|
|
142
|
+
* @remarks
|
|
143
|
+
* This function applies a viewport with automatic fallback strategies:
|
|
144
|
+
* 1. Try standard applyViewport (respects animations and constraints)
|
|
145
|
+
* 2. If that fails and we're still loading, retry once on "idle"
|
|
146
|
+
* 3. If still failing, use manual calculation as last resort
|
|
147
|
+
*
|
|
148
|
+
* This handles edge cases like:
|
|
149
|
+
* - Map not fully loaded yet
|
|
150
|
+
* - Invalid bounds that cause fitBounds to throw
|
|
151
|
+
* - Continental-scale data that causes wrapping issues
|
|
152
|
+
*
|
|
153
|
+
* @param map - MapLibre map instance
|
|
154
|
+
* @param viewport - Viewport configuration to apply
|
|
155
|
+
* @returns Cleanup function to remove event listeners
|
|
156
|
+
*
|
|
157
|
+
* @internal
|
|
158
|
+
*/
|
|
159
|
+
export function applyViewportSafely(map, viewport) {
|
|
160
|
+
try {
|
|
161
|
+
// Try standard application first
|
|
162
|
+
applyViewport(map, viewport, false);
|
|
163
|
+
return undefined;
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// Only retry if we have bounds (most common failure case)
|
|
167
|
+
if (!viewport.bounds) {
|
|
168
|
+
applyViewportWithManualCalculation(map, viewport);
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
// Create retry handler
|
|
172
|
+
const retryOnce = () => {
|
|
173
|
+
try {
|
|
174
|
+
applyViewport(map, viewport, false);
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// Final fallback: manual calculation
|
|
178
|
+
applyViewportWithManualCalculation(map, viewport);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
// If map is loaded, retry immediately
|
|
182
|
+
if (map.loaded()) {
|
|
183
|
+
retryOnce();
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
// Otherwise, wait for map to be idle
|
|
187
|
+
void map.once("idle", retryOnce);
|
|
188
|
+
return () => {
|
|
189
|
+
map.off("idle", retryOnce);
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=viewportManagement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"viewportManagement.js","sourceRoot":"","sources":["../../../../src/next/features/map/viewportManagement.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Size calculation functions for GeoPushpinChartNext
|
|
3
|
+
*
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Interface for min/max value pair
|
|
8
|
+
*/
|
|
9
|
+
interface IMinMax {
|
|
10
|
+
min?: number;
|
|
11
|
+
max?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Calculates the average of an array of numbers
|
|
15
|
+
*
|
|
16
|
+
* @param values - Array of numbers to average
|
|
17
|
+
* @returns Average value, or 0 if array is empty
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export declare function calculateAverage(values?: number[]): number;
|
|
22
|
+
/**
|
|
23
|
+
* Gets minimum and maximum values from a number array, ignoring non-finite values
|
|
24
|
+
*
|
|
25
|
+
* @param data - Array of numbers
|
|
26
|
+
* @returns Object containing min and max values (may be undefined if no finite values exist)
|
|
27
|
+
*
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export declare function getMinMax(data: number[]): IMinMax;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=calculations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calculations.d.ts","sourceRoot":"","sources":["../../../../src/next/features/size/calculations.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH;;GAEG;AACH,UAAU,OAAO;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,MAAM,EAAO,GAAG,MAAM,CAK9D;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAiBjD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// (C) 2025 GoodData Corporation
|
|
2
|
+
/**
|
|
3
|
+
* Calculates the average of an array of numbers
|
|
4
|
+
*
|
|
5
|
+
* @param values - Array of numbers to average
|
|
6
|
+
* @returns Average value, or 0 if array is empty
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export function calculateAverage(values = []) {
|
|
11
|
+
if (values.length === 0) {
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
return values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Gets minimum and maximum values from a number array, ignoring non-finite values
|
|
18
|
+
*
|
|
19
|
+
* @param data - Array of numbers
|
|
20
|
+
* @returns Object containing min and max values (may be undefined if no finite values exist)
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export function getMinMax(data) {
|
|
25
|
+
return data.reduce((result, value) => {
|
|
26
|
+
if (!isFinite(value)) {
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
const min = result.min !== undefined && isFinite(result.min) ? Math.min(value, result.min) : value;
|
|
30
|
+
const max = result.max !== undefined && isFinite(result.max) ? Math.max(value, result.max) : value;
|
|
31
|
+
return { min, max };
|
|
32
|
+
}, {
|
|
33
|
+
min: undefined,
|
|
34
|
+
max: undefined,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=calculations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calculations.js","sourceRoot":"","sources":["../../../../src/next/features/size/calculations.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAgBhC;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAmB,EAAE;IAClD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,CAAC;IACb,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;AACzE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,IAAc;IACpC,OAAO,IAAI,CAAC,MAAM,CACd,CAAC,MAAe,EAAE,KAAa,EAAW,EAAE;QACxC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,GACL,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAC3F,MAAM,GAAG,GACL,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAC3F,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACxB,CAAC,EACD;QACI,GAAG,EAAE,SAAS;QACd,GAAG,EAAE,SAAS;KACjB,CACJ,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ISeparators } from "@gooddata/sdk-model";
|
|
2
|
+
/**
|
|
3
|
+
* Formats a value for display in tooltips
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Uses GoodData's number formatter to format values according to the provided format string.
|
|
7
|
+
* The formatted value is escaped for safe HTML rendering.
|
|
8
|
+
*
|
|
9
|
+
* @param val - Value to format (string or number)
|
|
10
|
+
* @param format - Format string (e.g., "#,##0.00")
|
|
11
|
+
* @param separators - Optional separators configuration for thousands and decimals
|
|
12
|
+
* @returns Formatted and escaped string
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export declare function formatValueForTooltip(val: string | number, format: string | undefined, separators?: ISeparators): string;
|
|
17
|
+
/**
|
|
18
|
+
* Calculates tooltip content width based on chart dimensions
|
|
19
|
+
*
|
|
20
|
+
* @param isFullScreenTooltip - Whether tooltip should take full width
|
|
21
|
+
* @param chartWidth - Width of the chart container
|
|
22
|
+
* @param tooltipMaxWidth - Maximum allowed tooltip width
|
|
23
|
+
* @returns Calculated tooltip width
|
|
24
|
+
*
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export declare function getTooltipContentWidth(isFullScreenTooltip: boolean, chartWidth: number, tooltipMaxWidth: number): number;
|
|
28
|
+
//# sourceMappingURL=formatting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting.d.ts","sourceRoot":"","sources":["../../../../src/next/features/tooltip/formatting.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAgBlD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CACjC,GAAG,EAAE,MAAM,GAAG,MAAM,EACpB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,UAAU,CAAC,EAAE,WAAW,GACzB,MAAM,CASR;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAClC,mBAAmB,EAAE,OAAO,EAC5B,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GACxB,MAAM,CAER"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// (C) 2025 GoodData Corporation
|
|
2
|
+
import { escape, unescape } from "lodash-es";
|
|
3
|
+
import { ClientFormatterFacade } from "@gooddata/number-formatter";
|
|
4
|
+
/**
|
|
5
|
+
* Formatting functions for GeoPushpinChartNext tooltips
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Custom escape function that first unescapes then escapes a string
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* Ensures consistent escaping by removing any existing escape sequences first
|
|
14
|
+
*/
|
|
15
|
+
const customEscape = (str) => str && escape(unescape(str));
|
|
16
|
+
/**
|
|
17
|
+
* Formats a value for display in tooltips
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* Uses GoodData's number formatter to format values according to the provided format string.
|
|
21
|
+
* The formatted value is escaped for safe HTML rendering.
|
|
22
|
+
*
|
|
23
|
+
* @param val - Value to format (string or number)
|
|
24
|
+
* @param format - Format string (e.g., "#,##0.00")
|
|
25
|
+
* @param separators - Optional separators configuration for thousands and decimals
|
|
26
|
+
* @returns Formatted and escaped string
|
|
27
|
+
*
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export function formatValueForTooltip(val, format, separators) {
|
|
31
|
+
if (!format) {
|
|
32
|
+
return `${val}`;
|
|
33
|
+
}
|
|
34
|
+
const convertedValue = ClientFormatterFacade.convertValue(val);
|
|
35
|
+
const { formattedValue } = ClientFormatterFacade.formatValue(convertedValue, format, separators);
|
|
36
|
+
return customEscape(formattedValue);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Calculates tooltip content width based on chart dimensions
|
|
40
|
+
*
|
|
41
|
+
* @param isFullScreenTooltip - Whether tooltip should take full width
|
|
42
|
+
* @param chartWidth - Width of the chart container
|
|
43
|
+
* @param tooltipMaxWidth - Maximum allowed tooltip width
|
|
44
|
+
* @returns Calculated tooltip width
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
export function getTooltipContentWidth(isFullScreenTooltip, chartWidth, tooltipMaxWidth) {
|
|
49
|
+
return isFullScreenTooltip ? chartWidth : Math.min(chartWidth, tooltipMaxWidth);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=formatting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting.js","sourceRoot":"","sources":["../../../../src/next/features/tooltip/formatting.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAGnE;;;;GAIG;AAEH;;;;;GAKG;AACH,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AAEnE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,qBAAqB,CACjC,GAAoB,EACpB,MAA0B,EAC1B,UAAwB;IAExB,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,OAAO,GAAG,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,MAAM,cAAc,GAAG,qBAAqB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAC/D,MAAM,EAAE,cAAc,EAAE,GAAG,qBAAqB,CAAC,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;IAEjG,OAAO,YAAY,CAAC,cAAc,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,sBAAsB,CAClC,mBAA4B,EAC5B,UAAkB,EAClB,eAAuB;IAEvB,OAAO,mBAAmB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;AACpF,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { Map as MapLibreMap, Popup } from "maplibre-gl";
|
|
2
|
+
import { IntlShape } from "react-intl";
|
|
3
|
+
import { IHeaderPredicate } from "@gooddata/sdk-ui";
|
|
4
|
+
import { IMapConfig } from "../../types/mapProvider.js";
|
|
5
|
+
/**
|
|
6
|
+
* Set up tooltip event handlers for pushpins
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* This function sets up mousemove listeners to show/hide tooltips when hovering
|
|
10
|
+
* over pushpins. It queries rendered features at the mouse position and delegates
|
|
11
|
+
* to the existing tooltip handlers.
|
|
12
|
+
*
|
|
13
|
+
* @param map - MapLibre map instance
|
|
14
|
+
* @param tooltip - Popup instance for displaying tooltips
|
|
15
|
+
* @param config - Map configuration
|
|
16
|
+
* @param drillableItems - Array of drillable item predicates
|
|
17
|
+
* @param intl - Internationalization configuration
|
|
18
|
+
* @returns Cleanup function to remove event listeners
|
|
19
|
+
*
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export declare function setupTooltipHandlers(map: MapLibreMap, tooltip: Popup, config: IMapConfig, drillableItems?: IHeaderPredicate[], intl?: IntlShape): () => void;
|
|
23
|
+
/**
|
|
24
|
+
* Show tooltip at specified location
|
|
25
|
+
*
|
|
26
|
+
* @param map - MapLibre map instance
|
|
27
|
+
* @param tooltip - Popup instance
|
|
28
|
+
* @param lngLat - Location to show tooltip
|
|
29
|
+
* @param html - HTML content for tooltip
|
|
30
|
+
* @param className - Optional CSS class name
|
|
31
|
+
* @param offset - Optional pixel offset
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export declare function showTooltip(map: MapLibreMap, tooltip: Popup, lngLat: {
|
|
36
|
+
lng: number;
|
|
37
|
+
lat: number;
|
|
38
|
+
}, html: string, className?: string, offset?: [number, number]): void;
|
|
39
|
+
/**
|
|
40
|
+
* Hide the currently displayed tooltip
|
|
41
|
+
*
|
|
42
|
+
* @param tooltip - Popup instance
|
|
43
|
+
*
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
46
|
+
export declare function hideTooltip(tooltip: Popup): void;
|
|
47
|
+
//# sourceMappingURL=tooltipManagement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltipManagement.d.ts","sourceRoot":"","sources":["../../../../src/next/features/tooltip/tooltipManagement.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,IAAI,WAAW,EAAiB,KAAK,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAOpD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAChC,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,KAAK,EACd,MAAM,EAAE,UAAU,EAClB,cAAc,CAAC,EAAE,gBAAgB,EAAE,EACnC,IAAI,CAAC,EAAE,SAAS,GACjB,MAAM,IAAI,CAuBZ;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACvB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,KAAK,EACd,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EACpC,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,IAAI,CAUN;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,KAAK,GAAG,IAAI,CAEhD"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// (C) 2025 GoodData Corporation
|
|
2
|
+
import { DEFAULT_LAYER_NAME } from "../../constants/geoChart.js";
|
|
3
|
+
import { handlePushpinMouseEnter, handlePushpinMouseLeave, } from "../../providers/maplibre/maplibreTooltip.js";
|
|
4
|
+
/**
|
|
5
|
+
* Set up tooltip event handlers for pushpins
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* This function sets up mousemove listeners to show/hide tooltips when hovering
|
|
9
|
+
* over pushpins. It queries rendered features at the mouse position and delegates
|
|
10
|
+
* to the existing tooltip handlers.
|
|
11
|
+
*
|
|
12
|
+
* @param map - MapLibre map instance
|
|
13
|
+
* @param tooltip - Popup instance for displaying tooltips
|
|
14
|
+
* @param config - Map configuration
|
|
15
|
+
* @param drillableItems - Array of drillable item predicates
|
|
16
|
+
* @param intl - Internationalization configuration
|
|
17
|
+
* @returns Cleanup function to remove event listeners
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export function setupTooltipHandlers(map, tooltip, config, drillableItems, intl) {
|
|
22
|
+
const layerId = DEFAULT_LAYER_NAME;
|
|
23
|
+
const handleMouseMove = (e) => {
|
|
24
|
+
const features = map.queryRenderedFeatures(e.point, {
|
|
25
|
+
layers: [layerId],
|
|
26
|
+
});
|
|
27
|
+
if (features && features.length > 0) {
|
|
28
|
+
handlePushpinMouseEnter(e, map, tooltip, config, drillableItems, intl);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Mouse not over any pushpin, hide tooltip if showing
|
|
32
|
+
if (tooltip.isOpen()) {
|
|
33
|
+
handlePushpinMouseLeave(e, map, tooltip, config);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
map.on("mousemove", handleMouseMove);
|
|
38
|
+
return () => {
|
|
39
|
+
map.off("mousemove", handleMouseMove);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Show tooltip at specified location
|
|
44
|
+
*
|
|
45
|
+
* @param map - MapLibre map instance
|
|
46
|
+
* @param tooltip - Popup instance
|
|
47
|
+
* @param lngLat - Location to show tooltip
|
|
48
|
+
* @param html - HTML content for tooltip
|
|
49
|
+
* @param className - Optional CSS class name
|
|
50
|
+
* @param offset - Optional pixel offset
|
|
51
|
+
*
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
export function showTooltip(map, tooltip, lngLat, html, className, offset) {
|
|
55
|
+
tooltip.setLngLat([lngLat.lng, lngLat.lat]).setHTML(html).addTo(map);
|
|
56
|
+
if (className) {
|
|
57
|
+
tooltip.addClassName(className);
|
|
58
|
+
}
|
|
59
|
+
if (offset) {
|
|
60
|
+
tooltip.setOffset(offset);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Hide the currently displayed tooltip
|
|
65
|
+
*
|
|
66
|
+
* @param tooltip - Popup instance
|
|
67
|
+
*
|
|
68
|
+
* @internal
|
|
69
|
+
*/
|
|
70
|
+
export function hideTooltip(tooltip) {
|
|
71
|
+
tooltip.remove();
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=tooltipManagement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltipManagement.js","sourceRoot":"","sources":["../../../../src/next/features/tooltip/tooltipManagement.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAOhC,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EACH,uBAAuB,EACvB,uBAAuB,GAC1B,MAAM,6CAA6C,CAAC;AAGrD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,oBAAoB,CAChC,GAAgB,EAChB,OAAc,EACd,MAAkB,EAClB,cAAmC,EACnC,IAAgB;IAEhB,MAAM,OAAO,GAAG,kBAAkB,CAAC;IAEnC,MAAM,eAAe,GAAG,CAAC,CAAgB,EAAE,EAAE;QACzC,MAAM,QAAQ,GAAG,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC,KAAK,EAAE;YAChD,MAAM,EAAE,CAAC,OAAO,CAAC;SACpB,CAAC,CAAC;QAEH,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,uBAAuB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC;QAC3E,CAAC;aAAM,CAAC;YACJ,sDAAsD;YACtD,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;gBACnB,uBAAuB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YACrD,CAAC;QACL,CAAC;IACL,CAAC,CAAC;IAEF,GAAG,CAAC,EAAE,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IAErC,OAAO,GAAG,EAAE;QACR,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;IAC1C,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CACvB,GAAgB,EAChB,OAAc,EACd,MAAoC,EACpC,IAAY,EACZ,SAAkB,EAClB,MAAyB;IAEzB,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAErE,IAAI,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACT,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,OAAc;IACtC,OAAO,CAAC,MAAM,EAAE,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { IPreparedExecution } from "@gooddata/sdk-backend-spi";
|
|
2
|
+
import { IDimension, IExecutionDefinition } from "@gooddata/sdk-model";
|
|
3
|
+
import { IGeoPushpinChartNextResolvedProps } from "../../types/internal.js";
|
|
4
|
+
/**
|
|
5
|
+
* Creates dimensions for geo chart execution.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export declare function getGeoChartDimensions(def: IExecutionDefinition): IDimension[];
|
|
9
|
+
/**
|
|
10
|
+
* Creates an execution for GeoPushpinChartNext with proper bucket configuration.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* This hook creates a prepared execution with the appropriate buckets based on whether
|
|
14
|
+
* the chart is using location mode (single attribute) or lat/lng mode (two attributes).
|
|
15
|
+
*
|
|
16
|
+
* Buckets created:
|
|
17
|
+
* - LOCATION: Contains either location attribute or lat/lng attributes
|
|
18
|
+
* - SIZE: Contains size measure/attribute
|
|
19
|
+
* - COLOR: Contains color measure/attribute
|
|
20
|
+
* - SEGMENT: Contains segmentBy attribute
|
|
21
|
+
* - TOOLTIP_TEXT: Contains tooltipText attribute
|
|
22
|
+
*
|
|
23
|
+
* @param config - Execution configuration
|
|
24
|
+
* @returns Prepared execution ready to be executed
|
|
25
|
+
*
|
|
26
|
+
* @alpha
|
|
27
|
+
*/
|
|
28
|
+
export declare function useInitExecution(props: IGeoPushpinChartNextResolvedProps): IPreparedExecution;
|
|
29
|
+
//# sourceMappingURL=useInitExecution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useInitExecution.d.ts","sourceRoot":"","sources":["../../../../src/next/hooks/init/useInitExecution.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EACH,UAAU,EACV,oBAAoB,EAMvB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,iCAAiC,EAAE,MAAM,yBAAyB,CAAC;AAE5E;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,oBAAoB,GAAG,UAAU,EAAE,CAM7E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iCAAiC,GAAG,kBAAkB,CA4E7F"}
|