datastake-daf 0.6.265 β 0.6.267
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/components/index.js +235 -16
- package/package.json +1 -1
- package/src/@daf/core/components/Dashboard/Globe/Globe.stories.js +30 -5
- package/src/@daf/core/components/Dashboard/Globe/README.md +106 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobe.jsx +214 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobe.stories.js +174 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobeDebug.jsx +85 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobeExample.jsx +75 -0
- package/src/@daf/core/components/Dashboard/Globe/SimpleGlobeTest.jsx +48 -0
- package/src/@daf/core/components/Dashboard/Globe/hook.js +63 -7
- package/src/@daf/core/components/Dashboard/Globe/index.jsx +24 -6
- package/src/@daf/core/components/Dashboard/Globe/storyConfig.js +243 -0
- package/src/@daf/core/components/Dashboard/Globe/storyConfig1.js +354 -0
- package/src/@daf/core/components/Dashboard/Map/helper.js +1 -1
- package/src/index.js +1 -0
- package/.env +0 -8
- package/.vscode/settings.json +0 -13
package/dist/components/index.js
CHANGED
|
@@ -18246,7 +18246,6 @@ function useMapHelper$1({
|
|
|
18246
18246
|
|
|
18247
18247
|
// Actions to do when active marker is changed
|
|
18248
18248
|
React.useEffect(() => {
|
|
18249
|
-
console.log("RERENDER");
|
|
18250
18249
|
if (mapRef) {
|
|
18251
18250
|
if (activeMarker) {
|
|
18252
18251
|
mapRef.eachLayer(layer => {
|
|
@@ -19929,14 +19928,26 @@ const useGlobe = ({
|
|
|
19929
19928
|
const addedSources = React.useRef(new Set());
|
|
19930
19929
|
const isMounted = React.useRef(true);
|
|
19931
19930
|
const addAllDataToMap = React.useCallback(() => {
|
|
19932
|
-
|
|
19931
|
+
console.log('π [GLOBE HOOK] addAllDataToMap called');
|
|
19932
|
+
console.log('π [GLOBE HOOK] data:', data);
|
|
19933
|
+
console.log('π [GLOBE HOOK] mapRef exists:', !!mapRef);
|
|
19934
|
+
console.log('π [GLOBE HOOK] style loaded:', mapRef?.isStyleLoaded());
|
|
19935
|
+
if (!data || !mapRef) {
|
|
19936
|
+
console.log('β [GLOBE HOOK] addAllDataToMap early return - missing data or mapRef');
|
|
19937
|
+
return;
|
|
19938
|
+
}
|
|
19939
|
+
if (!mapRef.isStyleLoaded()) {
|
|
19940
|
+
console.log('β³ [GLOBE HOOK] Style not loaded yet, retrying in 100ms...');
|
|
19941
|
+
setTimeout(() => {
|
|
19942
|
+
addAllDataToMap();
|
|
19943
|
+
}, 100);
|
|
19933
19944
|
return;
|
|
19934
19945
|
}
|
|
19935
|
-
|
|
19936
|
-
// Prevent multiple calls with empty data
|
|
19937
19946
|
if (data.length === 0) {
|
|
19947
|
+
console.log('β [GLOBE HOOK] addAllDataToMap early return - no data');
|
|
19938
19948
|
return;
|
|
19939
19949
|
}
|
|
19950
|
+
console.log('β
[GLOBE HOOK] Starting to add markers to map...');
|
|
19940
19951
|
|
|
19941
19952
|
// Clear existing markers using functional update to avoid dependency issues
|
|
19942
19953
|
setMapMarkers(currentMarkers => {
|
|
@@ -19988,8 +19999,13 @@ const useGlobe = ({
|
|
|
19988
19999
|
if (data && mapRef) {
|
|
19989
20000
|
const newMarkers = [];
|
|
19990
20001
|
const maxTotal = Math.max(...(data || []).map(d => d.total || 0));
|
|
20002
|
+
console.log('π― [GLOBE HOOK] Processing data items:', data.length);
|
|
19991
20003
|
data.forEach((d, i) => {
|
|
20004
|
+
console.log(`π― [GLOBE HOOK] Processing item ${i}:`, d);
|
|
20005
|
+
console.log(`π― [GLOBE HOOK] Item ${i} marker:`, d?.marker);
|
|
20006
|
+
console.log(`π― [GLOBE HOOK] Item ${i} lat/lng:`, d?.marker?.lat, d?.marker?.lng);
|
|
19992
20007
|
if (d?.marker?.lat && d?.marker?.lng) {
|
|
20008
|
+
console.log(`β
[GLOBE HOOK] Item ${i} has valid coordinates, creating marker...`);
|
|
19993
20009
|
let marker;
|
|
19994
20010
|
let iconClassName = "";
|
|
19995
20011
|
let iconSize = [25, 25];
|
|
@@ -20069,6 +20085,7 @@ const useGlobe = ({
|
|
|
20069
20085
|
el.style.fontWeight = 'bold';
|
|
20070
20086
|
el.innerHTML = `<span>${d.total || 0}</span>`;
|
|
20071
20087
|
marker = new mapboxgl.Marker(el).setLngLat([d.marker.lng, d.marker.lat]).setPopup(new mapboxgl.Popup().setDOMContent(div)).addTo(mapRef);
|
|
20088
|
+
console.log(`π [GLOBE HOOK] Marker ${i} added to map at:`, [d.marker.lng, d.marker.lat]);
|
|
20072
20089
|
} else if (type === "territory") {
|
|
20073
20090
|
// Handle territory polygons
|
|
20074
20091
|
if (d.area && Array.isArray(d.area)) {
|
|
@@ -20138,6 +20155,7 @@ const useGlobe = ({
|
|
|
20138
20155
|
}));
|
|
20139
20156
|
roots.current.push(root);
|
|
20140
20157
|
marker = new mapboxgl.Marker(el).setLngLat([d.marker.lng, d.marker.lat]).setPopup(new mapboxgl.Popup().setDOMContent(div)).addTo(mapRef);
|
|
20158
|
+
console.log(`π [GLOBE HOOK] Default marker ${i} added to map at:`, [d.marker.lng, d.marker.lat]);
|
|
20141
20159
|
}
|
|
20142
20160
|
|
|
20143
20161
|
// Add click handler
|
|
@@ -20171,6 +20189,7 @@ const useGlobe = ({
|
|
|
20171
20189
|
mapboxgl.accessToken = MAP_TOKEN;
|
|
20172
20190
|
|
|
20173
20191
|
// Create the map with Mapbox GL JS - 3D globe
|
|
20192
|
+
console.log('πΊοΈ [GLOBE HOOK] Creating map with style:', STYLE_URL);
|
|
20174
20193
|
const map = new mapboxgl.Map({
|
|
20175
20194
|
container: container.current,
|
|
20176
20195
|
style: STYLE_URL,
|
|
@@ -20189,8 +20208,13 @@ const useGlobe = ({
|
|
|
20189
20208
|
|
|
20190
20209
|
// Configure the map when style loads
|
|
20191
20210
|
map.on('style.load', () => {
|
|
20211
|
+
console.log('π¨ [GLOBE HOOK] Style loaded event triggered');
|
|
20212
|
+
console.log('π¨ [GLOBE HOOK] Map style loaded:', map.isStyleLoaded());
|
|
20213
|
+
|
|
20192
20214
|
// Wait a bit for the style to fully load
|
|
20193
20215
|
setTimeout(() => {
|
|
20216
|
+
console.log('π¨ [GLOBE HOOK] After timeout - Map style loaded:', map.isStyleLoaded());
|
|
20217
|
+
|
|
20194
20218
|
// Set fog for the space background effect with stars - simplified to avoid errors
|
|
20195
20219
|
try {
|
|
20196
20220
|
map.setFog({
|
|
@@ -20286,9 +20310,10 @@ const useGlobe = ({
|
|
|
20286
20310
|
|
|
20287
20311
|
// Add navigation controls
|
|
20288
20312
|
map.addControl(new mapboxgl.NavigationControl(), 'top-right');
|
|
20313
|
+
console.log('πΊοΈ [GLOBE HOOK] Map created successfully');
|
|
20289
20314
|
return map;
|
|
20290
20315
|
} catch (error) {
|
|
20291
|
-
console.error('Error creating Mapbox GL JS globe:', error);
|
|
20316
|
+
console.error('β [GLOBE HOOK] Error creating Mapbox GL JS globe:', error);
|
|
20292
20317
|
return null;
|
|
20293
20318
|
}
|
|
20294
20319
|
}, []);
|
|
@@ -20301,9 +20326,12 @@ const useGlobe = ({
|
|
|
20301
20326
|
// }, [initialMarkerSetIsDone]);
|
|
20302
20327
|
|
|
20303
20328
|
React.useEffect(() => {
|
|
20329
|
+
console.log('π [GLOBE HOOK] useEffect for map creation - mapRef:', !!mapRef);
|
|
20304
20330
|
if (!mapRef) {
|
|
20331
|
+
console.log('π [GLOBE HOOK] Creating map instance...');
|
|
20305
20332
|
const instance = createInstance();
|
|
20306
20333
|
if (instance) {
|
|
20334
|
+
console.log('π [GLOBE HOOK] Map instance created, setting mapRef');
|
|
20307
20335
|
setMapRef(instance);
|
|
20308
20336
|
|
|
20309
20337
|
// Add comprehensive resize detection for Mapbox GL JS responsiveness
|
|
@@ -20384,14 +20412,22 @@ const useGlobe = ({
|
|
|
20384
20412
|
}
|
|
20385
20413
|
}, [polygon, mapRef]);
|
|
20386
20414
|
React.useEffect(() => {
|
|
20415
|
+
console.log('π₯ [GLOBE HOOK] allData received:', allData);
|
|
20416
|
+
console.log('π₯ [GLOBE HOOK] allData length:', allData?.length);
|
|
20387
20417
|
if (allData) {
|
|
20388
20418
|
if (allData.length === 0) {
|
|
20419
|
+
console.log('β οΈ [GLOBE HOOK] Empty data array');
|
|
20389
20420
|
setEmptyStateIsVisible(true);
|
|
20390
20421
|
} else if (emptyStateIsVisible) {
|
|
20391
20422
|
setEmptyStateIsVisible(false);
|
|
20392
20423
|
}
|
|
20393
|
-
|
|
20424
|
+
console.log('π [GLOBE HOOK] Filtering data with filterValidGPS...');
|
|
20425
|
+
const filteredData = filterValidGPS(allData);
|
|
20426
|
+
console.log('π [GLOBE HOOK] filtered data result:', filteredData);
|
|
20427
|
+
console.log('π [GLOBE HOOK] filtered data length:', filteredData.length);
|
|
20428
|
+
setData(filteredData);
|
|
20394
20429
|
} else {
|
|
20430
|
+
console.log('β [GLOBE HOOK] No allData provided');
|
|
20395
20431
|
setData(null);
|
|
20396
20432
|
}
|
|
20397
20433
|
}, [allData, emptyStateIsVisible]);
|
|
@@ -20421,7 +20457,19 @@ const useGlobe = ({
|
|
|
20421
20457
|
}
|
|
20422
20458
|
}, [user, mapRef, allData]);
|
|
20423
20459
|
React.useEffect(() => {
|
|
20424
|
-
|
|
20460
|
+
console.log('π [GLOBE HOOK] useEffect triggered:', {
|
|
20461
|
+
mapRef: !!mapRef,
|
|
20462
|
+
data: !!data,
|
|
20463
|
+
dataLength: data?.length,
|
|
20464
|
+
initialMarkerSetIsDone,
|
|
20465
|
+
styleLoaded: mapRef?.isStyleLoaded()
|
|
20466
|
+
});
|
|
20467
|
+
if (mapRef && data && !initialMarkerSetIsDone) {
|
|
20468
|
+
console.log('π [GLOBE HOOK] Attempting to add markers...');
|
|
20469
|
+
console.log('π [GLOBE HOOK] Style loaded check:', mapRef.isStyleLoaded());
|
|
20470
|
+
|
|
20471
|
+
// Try to add markers immediately, and if style isn't loaded,
|
|
20472
|
+
// the addAllDataToMap function will handle it
|
|
20425
20473
|
setInitialMarkerSetIsDone(true);
|
|
20426
20474
|
addAllDataToMap();
|
|
20427
20475
|
}
|
|
@@ -20634,7 +20682,7 @@ function Globe(_ref) {
|
|
|
20634
20682
|
renderSider = null,
|
|
20635
20683
|
renderMarker = null,
|
|
20636
20684
|
type = "default",
|
|
20637
|
-
showSider =
|
|
20685
|
+
showSider = false,
|
|
20638
20686
|
filtersConfig,
|
|
20639
20687
|
onFilterChange = () => {},
|
|
20640
20688
|
isSatellite = false,
|
|
@@ -20644,15 +20692,29 @@ function Globe(_ref) {
|
|
|
20644
20692
|
onUnmount
|
|
20645
20693
|
} = _ref;
|
|
20646
20694
|
// Map data to include marker coordinates
|
|
20647
|
-
const mappedData = React.useMemo(() =>
|
|
20648
|
-
|
|
20649
|
-
|
|
20650
|
-
|
|
20651
|
-
|
|
20652
|
-
|
|
20653
|
-
|
|
20695
|
+
const mappedData = React.useMemo(() => {
|
|
20696
|
+
console.log('π [GLOBE COMPONENT] Original data received:', data);
|
|
20697
|
+
console.log('π [GLOBE COMPONENT] Data length:', data === null || data === void 0 ? void 0 : data.length);
|
|
20698
|
+
if (!data || data.length === 0) {
|
|
20699
|
+
console.log('β [GLOBE COMPONENT] No data to map');
|
|
20700
|
+
return [];
|
|
20701
|
+
}
|
|
20702
|
+
const mapped = data.map((d, i) => {
|
|
20703
|
+
var _d$gps, _d$gps2;
|
|
20704
|
+
console.log("\uD83D\uDCCA [GLOBE COMPONENT] Mapping item ".concat(i, ":"), d);
|
|
20705
|
+
console.log("\uD83D\uDCCA [GLOBE COMPONENT] Item ".concat(i, " GPS:"), d === null || d === void 0 ? void 0 : d.gps);
|
|
20706
|
+
const result = _objectSpread2(_objectSpread2({}, d), {}, {
|
|
20707
|
+
marker: {
|
|
20708
|
+
lat: d === null || d === void 0 || (_d$gps = d.gps) === null || _d$gps === void 0 ? void 0 : _d$gps.latitude,
|
|
20709
|
+
lng: d === null || d === void 0 || (_d$gps2 = d.gps) === null || _d$gps2 === void 0 ? void 0 : _d$gps2.longitude
|
|
20710
|
+
}
|
|
20711
|
+
});
|
|
20712
|
+
console.log("\uD83D\uDCCA [GLOBE COMPONENT] Item ".concat(i, " mapped result:"), result);
|
|
20713
|
+
return result;
|
|
20654
20714
|
});
|
|
20655
|
-
|
|
20715
|
+
console.log('π [GLOBE COMPONENT] Final mapped data:', mapped);
|
|
20716
|
+
return mapped;
|
|
20717
|
+
}, [data]);
|
|
20656
20718
|
|
|
20657
20719
|
// Get resize context for sidebar state changes
|
|
20658
20720
|
const {
|
|
@@ -20836,6 +20898,162 @@ Globe.propTypes = {
|
|
|
20836
20898
|
nameAsSiderTitle: PropTypes__default["default"].bool
|
|
20837
20899
|
};
|
|
20838
20900
|
|
|
20901
|
+
const SimpleGlobe = _ref => {
|
|
20902
|
+
let {
|
|
20903
|
+
projects = [],
|
|
20904
|
+
mapConfig = {},
|
|
20905
|
+
showSider = false,
|
|
20906
|
+
onProjectClick = () => {}
|
|
20907
|
+
} = _ref;
|
|
20908
|
+
const mapContainer = React.useRef(null);
|
|
20909
|
+
const map = React.useRef(null);
|
|
20910
|
+
React.useEffect(() => {
|
|
20911
|
+
if (map.current) return; // Initialize map only once
|
|
20912
|
+
|
|
20913
|
+
console.log('πΊοΈ [SIMPLE GLOBE] Creating map...');
|
|
20914
|
+
|
|
20915
|
+
// Set Mapbox access token
|
|
20916
|
+
mapboxgl.accessToken = 'pk.eyJ1IjoicmVkaXM5OTkiLCJhIjoiY2x4YWV5MzA5MmtuZzJpcXM5Y201Z2E2YiJ9.m5bwPg-Tj4Akesl1yQUa3w';
|
|
20917
|
+
|
|
20918
|
+
// Create map with custom Straatos style
|
|
20919
|
+
map.current = new mapboxgl.Map({
|
|
20920
|
+
container: mapContainer.current,
|
|
20921
|
+
style: 'mapbox://styles/pietragottardo/cm9tt9zfi00d101pg1vdx26si',
|
|
20922
|
+
center: [0, 0],
|
|
20923
|
+
zoom: mapConfig.maxZoom || 3,
|
|
20924
|
+
projection: 'globe',
|
|
20925
|
+
attributionControl: false
|
|
20926
|
+
});
|
|
20927
|
+
|
|
20928
|
+
// Add markers when map loads
|
|
20929
|
+
map.current.on('load', () => {
|
|
20930
|
+
console.log('πΊοΈ [SIMPLE GLOBE] Map loaded, adding markers...');
|
|
20931
|
+
|
|
20932
|
+
// Hide Mapbox logo and attribution completely
|
|
20933
|
+
map.current.getContainer();
|
|
20934
|
+
const style = document.createElement('style');
|
|
20935
|
+
style.textContent = "\n .mapboxgl-ctrl-logo,\n .mapboxgl-ctrl-attrib,\n .mapboxgl-ctrl-bottom-left,\n .mapboxgl-ctrl-bottom-right {\n display: none !important;\n }\n ";
|
|
20936
|
+
document.head.appendChild(style);
|
|
20937
|
+
|
|
20938
|
+
// Set the space background with stars
|
|
20939
|
+
try {
|
|
20940
|
+
map.current.setFog({
|
|
20941
|
+
'color': 'rgb(0, 0, 0)',
|
|
20942
|
+
'high-color': 'rgb(0, 0, 0)',
|
|
20943
|
+
'horizon-blend': 0.1,
|
|
20944
|
+
'space-color': 'rgb(0, 0, 0)',
|
|
20945
|
+
'star-intensity': 0.6
|
|
20946
|
+
});
|
|
20947
|
+
console.log('β¨ [SIMPLE GLOBE] Space background with stars set');
|
|
20948
|
+
} catch (e) {
|
|
20949
|
+
console.log('β οΈ [SIMPLE GLOBE] Could not set fog, trying alternative...');
|
|
20950
|
+
// Fallback: try simpler fog configuration
|
|
20951
|
+
try {
|
|
20952
|
+
map.current.setFog({
|
|
20953
|
+
'color': 'rgb(0, 0, 0)',
|
|
20954
|
+
'high-color': 'rgb(0, 0, 0)',
|
|
20955
|
+
'horizon-blend': 0.1
|
|
20956
|
+
});
|
|
20957
|
+
console.log('β¨ [SIMPLE GLOBE] Alternative space background set');
|
|
20958
|
+
} catch (e2) {
|
|
20959
|
+
console.log('β οΈ [SIMPLE GLOBE] Could not set any fog configuration');
|
|
20960
|
+
}
|
|
20961
|
+
}
|
|
20962
|
+
|
|
20963
|
+
// Calculate bounds to fit all markers
|
|
20964
|
+
const bounds = new mapboxgl.LngLatBounds();
|
|
20965
|
+
let hasValidCoordinates = false;
|
|
20966
|
+
projects.forEach((project, index) => {
|
|
20967
|
+
var _project$author;
|
|
20968
|
+
console.log("\uD83D\uDCCD [SIMPLE GLOBE] Adding marker ".concat(index, ":"), project);
|
|
20969
|
+
|
|
20970
|
+
// Create marker element
|
|
20971
|
+
const el = document.createElement('div');
|
|
20972
|
+
el.className = 'mapboxgl-marker';
|
|
20973
|
+
el.style.width = '25px';
|
|
20974
|
+
el.style.height = '25px';
|
|
20975
|
+
el.style.backgroundColor = '#00809E';
|
|
20976
|
+
el.style.borderRadius = '50%';
|
|
20977
|
+
el.style.border = '2px solid white';
|
|
20978
|
+
el.style.cursor = 'pointer';
|
|
20979
|
+
el.style.boxShadow = '0px 3.45px 3.45px 0px #00000029';
|
|
20980
|
+
el.style.display = 'flex';
|
|
20981
|
+
el.style.alignItems = 'center';
|
|
20982
|
+
el.style.justifyContent = 'center';
|
|
20983
|
+
el.style.color = 'white';
|
|
20984
|
+
el.style.fontWeight = 'bold';
|
|
20985
|
+
el.style.fontSize = '12px';
|
|
20986
|
+
el.innerHTML = "<span>".concat(project.percentageCompletion || 0, "</span>");
|
|
20987
|
+
|
|
20988
|
+
// Create popup content using the same structure as minesitemap
|
|
20989
|
+
const popupContent = "\n <div class=\"daf-tooltip-cont\">\n <div class=\"daf-tooltip-head\">\n <div class=\"daf-tooltip-title\">\n <div>\n <h4>".concat(project.name, "</h4>\n <h5>").concat(project.sectoralScope || 'Project', "</h5>\n </div>\n </div>\n </div>\n <div class=\"daf-tooltip-list\">\n <div class=\"daf-tooltip-list-item\">\n <span class=\"daf-tooltip-name\">Country</span>\n <span class=\"daf-tooltip-value\">").concat(project.country || 'N/A', "</span>\n </div>\n <div class=\"daf-tooltip-list-item\">\n <span class=\"daf-tooltip-name\">Completion</span>\n <span class=\"daf-tooltip-value\">").concat(project.percentageCompletion || 0, "%</span>\n </div>\n <div class=\"daf-tooltip-list-item\">\n <span class=\"daf-tooltip-name\">Author</span>\n <span class=\"daf-tooltip-value\">").concat(((_project$author = project.author) === null || _project$author === void 0 ? void 0 : _project$author.name) || 'N/A', "</span>\n </div>\n <div class=\"daf-tooltip-list-item\">\n <span class=\"daf-tooltip-name\">ID</span>\n <span class=\"daf-tooltip-value\">").concat(project.datastakeId || 'N/A', "</span>\n </div>\n </div>\n </div>\n ");
|
|
20990
|
+
|
|
20991
|
+
// Create popup
|
|
20992
|
+
const popup = new mapboxgl.Popup({
|
|
20993
|
+
offset: 25,
|
|
20994
|
+
closeButton: true,
|
|
20995
|
+
closeOnClick: false
|
|
20996
|
+
}).setHTML(popupContent);
|
|
20997
|
+
|
|
20998
|
+
// Ensure coordinates are valid numbers
|
|
20999
|
+
const lng = Number(project.longitude);
|
|
21000
|
+
const lat = Number(project.latitude);
|
|
21001
|
+
console.log("\uD83D\uDCCD [SIMPLE GLOBE] Marker ".concat(index, " coordinates:"), {
|
|
21002
|
+
lng,
|
|
21003
|
+
lat
|
|
21004
|
+
});
|
|
21005
|
+
|
|
21006
|
+
// Validate coordinates
|
|
21007
|
+
if (isNaN(lng) || isNaN(lat) || lng < -180 || lng > 180 || lat < -90 || lat > 90) {
|
|
21008
|
+
console.error("\u274C [SIMPLE GLOBE] Invalid coordinates for project ".concat(index, ":"), {
|
|
21009
|
+
lng,
|
|
21010
|
+
lat
|
|
21011
|
+
});
|
|
21012
|
+
return;
|
|
21013
|
+
}
|
|
21014
|
+
|
|
21015
|
+
// Add coordinates to bounds
|
|
21016
|
+
bounds.extend([lng, lat]);
|
|
21017
|
+
hasValidCoordinates = true;
|
|
21018
|
+
|
|
21019
|
+
// Add marker to map with proper coordinate order [lng, lat]
|
|
21020
|
+
new mapboxgl.Marker(el).setLngLat([lng, lat]).setPopup(popup).addTo(map.current);
|
|
21021
|
+
|
|
21022
|
+
// Add click handler
|
|
21023
|
+
el.addEventListener('click', () => {
|
|
21024
|
+
console.log('π [SIMPLE GLOBE] Marker clicked:', project);
|
|
21025
|
+
onProjectClick(project);
|
|
21026
|
+
});
|
|
21027
|
+
console.log("\u2705 [SIMPLE GLOBE] Marker ".concat(index, " added at:"), [lng, lat]);
|
|
21028
|
+
});
|
|
21029
|
+
|
|
21030
|
+
// Fit map to show all markers if we have valid coordinates
|
|
21031
|
+
if (hasValidCoordinates && !bounds.isEmpty()) {
|
|
21032
|
+
console.log('πΊοΈ [SIMPLE GLOBE] Fitting map to bounds:', bounds);
|
|
21033
|
+
map.current.fitBounds(bounds, {
|
|
21034
|
+
padding: 50,
|
|
21035
|
+
maxZoom: 8
|
|
21036
|
+
});
|
|
21037
|
+
}
|
|
21038
|
+
});
|
|
21039
|
+
return () => {
|
|
21040
|
+
if (map.current) {
|
|
21041
|
+
map.current.remove();
|
|
21042
|
+
map.current = null;
|
|
21043
|
+
}
|
|
21044
|
+
};
|
|
21045
|
+
}, [projects, onProjectClick, mapConfig]);
|
|
21046
|
+
return /*#__PURE__*/jsxRuntime.jsx(Style$A, {
|
|
21047
|
+
children: /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
21048
|
+
ref: mapContainer,
|
|
21049
|
+
style: {
|
|
21050
|
+
width: '100%',
|
|
21051
|
+
height: '100%'
|
|
21052
|
+
}
|
|
21053
|
+
})
|
|
21054
|
+
});
|
|
21055
|
+
};
|
|
21056
|
+
|
|
20839
21057
|
function WidgetPlaceholder(_ref) {
|
|
20840
21058
|
let {
|
|
20841
21059
|
icon = "",
|
|
@@ -61609,6 +61827,7 @@ exports.SelectFiltersTimeFrame = Timeframe;
|
|
|
61609
61827
|
exports.SettingsPopover = SettingsPopover;
|
|
61610
61828
|
exports.Sidenav = Sidenav;
|
|
61611
61829
|
exports.SidenavMenu = SidenavMenu;
|
|
61830
|
+
exports.SimpleGlobe = SimpleGlobe;
|
|
61612
61831
|
exports.StackChart = StackChart;
|
|
61613
61832
|
exports.StakeholderMappings = index$1;
|
|
61614
61833
|
exports.Steps = DAFSteps;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@ import Globe from "./index";
|
|
|
2
2
|
import ThemeLayout from "../../ThemeLayout";
|
|
3
3
|
import Widget from "../Widget";
|
|
4
4
|
|
|
5
|
-
import * as configs from "
|
|
5
|
+
import * as configs from "./storyConfig";
|
|
6
6
|
|
|
7
7
|
export default {
|
|
8
8
|
title: "Dashboard/Globe",
|
|
@@ -29,14 +29,14 @@ export default {
|
|
|
29
29
|
export const DefaultGlobe = {
|
|
30
30
|
name: "Default Globe",
|
|
31
31
|
args: {
|
|
32
|
-
...configs.
|
|
32
|
+
...configs.DefaultGlobeConfig,
|
|
33
33
|
},
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export const SatelliteGlobe = {
|
|
37
37
|
name: "Satellite Globe",
|
|
38
38
|
args: {
|
|
39
|
-
...configs.
|
|
39
|
+
...configs.DefaultGlobeConfig,
|
|
40
40
|
isSatellite: true,
|
|
41
41
|
},
|
|
42
42
|
};
|
|
@@ -44,11 +44,19 @@ export const SatelliteGlobe = {
|
|
|
44
44
|
export const TerritoryGlobe = {
|
|
45
45
|
name: "Territory Globe",
|
|
46
46
|
args: {
|
|
47
|
-
...configs.
|
|
47
|
+
...configs.TerritoryGlobeConfig,
|
|
48
48
|
type: "territory",
|
|
49
49
|
},
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
+
export const StakeholderGlobe = {
|
|
53
|
+
name: "Stakeholder Globe",
|
|
54
|
+
args: {
|
|
55
|
+
...configs.StakeholderGlobeConfig,
|
|
56
|
+
type: "stakeholder",
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
52
60
|
export const EventGlobe = {
|
|
53
61
|
name: "Event Globe",
|
|
54
62
|
args: {
|
|
@@ -57,10 +65,27 @@ export const EventGlobe = {
|
|
|
57
65
|
},
|
|
58
66
|
};
|
|
59
67
|
|
|
68
|
+
export const ChainGlobe = {
|
|
69
|
+
name: "Supply Chain Globe",
|
|
70
|
+
args: {
|
|
71
|
+
...configs.ChainGlobeConfig,
|
|
72
|
+
type: "chain",
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
60
76
|
export const LocationGlobe = {
|
|
61
77
|
name: "Location Globe",
|
|
62
78
|
args: {
|
|
63
|
-
...configs.
|
|
79
|
+
...configs.DefaultGlobeConfig,
|
|
64
80
|
type: "location",
|
|
65
81
|
},
|
|
66
82
|
};
|
|
83
|
+
|
|
84
|
+
export const ProjectGlobe = {
|
|
85
|
+
name: "Project Globe",
|
|
86
|
+
args: {
|
|
87
|
+
...configs.ProjectGlobeConfig,
|
|
88
|
+
type: "project",
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# SimpleGlobe Component
|
|
2
|
+
|
|
3
|
+
A simplified wrapper for the Globe component that makes it easy to display project data as pins on a 3D globe.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- πΊοΈ **3D Globe Visualization**: Interactive 3D globe using Mapbox GL JS
|
|
8
|
+
- π **Pin-based Display**: Projects are displayed as clickable pins on the globe
|
|
9
|
+
- π― **Simple Integration**: Just pass your project data and it works
|
|
10
|
+
- π **Rich Tooltips**: Hover over pins to see project details
|
|
11
|
+
- π¨ **Customizable**: Support for custom map configurations
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```jsx
|
|
16
|
+
import SimpleGlobe from './SimpleGlobe';
|
|
17
|
+
|
|
18
|
+
const MyComponent = () => {
|
|
19
|
+
const projects = [
|
|
20
|
+
{
|
|
21
|
+
name: "Solar Project",
|
|
22
|
+
latitude: 14.7167,
|
|
23
|
+
longitude: -17.4677,
|
|
24
|
+
percentageCompletion: 75,
|
|
25
|
+
projectDescription: "Large-scale solar energy project"
|
|
26
|
+
}
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<div style={{ width: '100%', height: '600px' }}>
|
|
31
|
+
<SimpleGlobe
|
|
32
|
+
projects={projects}
|
|
33
|
+
onProjectClick={(project) => console.log('Clicked:', project)}
|
|
34
|
+
/>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Props
|
|
41
|
+
|
|
42
|
+
| Prop | Type | Default | Description |
|
|
43
|
+
|------|------|---------|-------------|
|
|
44
|
+
| `projects` | `Array` | `[]` | Array of project objects |
|
|
45
|
+
| `mapConfig` | `Object` | `{}` | Map configuration options |
|
|
46
|
+
| `showSider` | `boolean` | `false` | Whether to show the sidebar |
|
|
47
|
+
| `onProjectClick` | `Function` | `() => {}` | Callback when a project pin is clicked |
|
|
48
|
+
|
|
49
|
+
## Project Data Format
|
|
50
|
+
|
|
51
|
+
Your project objects should have the following structure:
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
{
|
|
55
|
+
_id: "unique-id", // Optional: Unique identifier
|
|
56
|
+
name: "Project Name", // Required: Project name
|
|
57
|
+
latitude: 14.7167, // Required: Latitude coordinate
|
|
58
|
+
longitude: -17.4677, // Required: Longitude coordinate
|
|
59
|
+
projectDescription: "Description", // Optional: Project description
|
|
60
|
+
country: "SN", // Optional: Country code
|
|
61
|
+
sectoralScope: "energy", // Optional: Project sector
|
|
62
|
+
percentageCompletion: 75, // Optional: Completion percentage
|
|
63
|
+
author: { name: "Author Name" } // Optional: Author information
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Examples
|
|
68
|
+
|
|
69
|
+
### Basic Usage
|
|
70
|
+
```jsx
|
|
71
|
+
<SimpleGlobe projects={myProjects} />
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### With Sidebar
|
|
75
|
+
```jsx
|
|
76
|
+
<SimpleGlobe
|
|
77
|
+
projects={myProjects}
|
|
78
|
+
showSider={true}
|
|
79
|
+
/>
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### With Custom Configuration
|
|
83
|
+
```jsx
|
|
84
|
+
<SimpleGlobe
|
|
85
|
+
projects={myProjects}
|
|
86
|
+
mapConfig={{
|
|
87
|
+
maxZoom: 8,
|
|
88
|
+
minZoom: 2
|
|
89
|
+
}}
|
|
90
|
+
onProjectClick={(project) => {
|
|
91
|
+
// Handle project click
|
|
92
|
+
console.log('Project clicked:', project);
|
|
93
|
+
}}
|
|
94
|
+
/>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Storybook
|
|
98
|
+
|
|
99
|
+
You can see all examples in Storybook under "Dashboard/Globe/SimpleGlobe".
|
|
100
|
+
|
|
101
|
+
## Notes
|
|
102
|
+
|
|
103
|
+
- The component automatically transforms your project data to the format expected by the underlying Globe component
|
|
104
|
+
- Pins are displayed as circular markers with project completion percentage
|
|
105
|
+
- Tooltips show project details when hovering over pins
|
|
106
|
+
- The globe is fully interactive - you can zoom, pan, and rotate
|