1
+ import { useEffect , useMemo , useRef , useState } from "react" ;
2
+ import ReactECharts from "echarts-for-react" ;
3
+ import 'echarts-extension-gmap' ;
4
+ import { findIndex } from "lodash" ;
5
+
6
+ const googleMapsApiUrl = "https://maps.googleapis.com/maps/api/js" ;
7
+
8
+ function loadGoogleMapsScript ( apiKey : string ) {
9
+ const mapsUrl = `${ googleMapsApiUrl } ?key=${ apiKey } ` ;
10
+ const scripts = document . getElementsByTagName ( 'script' ) ;
11
+ // is script already loaded
12
+ let scriptIndex = findIndex ( scripts , ( script ) => script . src . endsWith ( mapsUrl ) ) ;
13
+ if ( scriptIndex > - 1 ) {
14
+ return scripts [ scriptIndex ] ;
15
+ }
16
+ // is script loaded with diff api_key, remove the script and load again
17
+ scriptIndex = findIndex ( scripts , ( script ) => script . src . startsWith ( googleMapsApiUrl ) ) ;
18
+ if ( scriptIndex > - 1 ) {
19
+ scripts [ scriptIndex ] . remove ( ) ;
20
+ }
21
+
22
+ const script = document . createElement ( "script" ) ;
23
+ script . type = "text/javascript" ;
24
+ script . src = mapsUrl ;
25
+ script . async = true ;
26
+ script . defer = true ;
27
+ window . document . body . appendChild ( script ) ;
28
+
29
+ return script ;
30
+ }
31
+
32
+ interface Props {
33
+ data : Array < any > ;
34
+ }
35
+
36
+ function getRandomLatLng ( minLat : number , maxLat : number , minLng : number , maxLng : number ) {
37
+ const lat = Math . random ( ) * ( maxLat - minLat ) + minLat
38
+ const lng = Math . random ( ) * ( maxLng - minLng ) + minLng
39
+ return [ lat , lng ]
40
+ }
41
+
42
+ const UserEngagementByRegionChart = ( { data } : Props ) => {
43
+ const chartRef = useRef < any > ( null ) ;
44
+ const [ mapScriptLoaded , setMapScriptLoaded ] = useState ( false ) ;
45
+
46
+ const isMapScriptLoaded = useMemo ( ( ) => {
47
+ return mapScriptLoaded || ( window as any ) ?. google ;
48
+ } , [ mapScriptLoaded ] )
49
+
50
+ const handleOnMapScriptLoad = ( ) => {
51
+ setMapScriptLoaded ( true ) ;
52
+ }
53
+
54
+ useEffect ( ( ) => {
55
+ const gMapScript = loadGoogleMapsScript ( '' ) ;
56
+ if ( isMapScriptLoaded ) {
57
+ handleOnMapScriptLoad ( ) ;
58
+ return ;
59
+ }
60
+ gMapScript . addEventListener ( 'load' , handleOnMapScriptLoad ) ;
61
+ return ( ) => {
62
+ gMapScript . removeEventListener ( 'load' , handleOnMapScriptLoad ) ;
63
+ }
64
+ } , [ ] )
65
+
66
+ const series = useMemo ( ( ) => {
67
+ return [
68
+ {
69
+ "name" : "Company Size" ,
70
+ "type" : "scatter" ,
71
+ "coordinateSystem" : "gmap" ,
72
+ "itemStyle" : {
73
+ "color" : "#ff00ff"
74
+ } ,
75
+ "data" : data
76
+ // .filter(item => {
77
+ // if (!item.geolocationDataJsonb) return false;
78
+ // return item.geolocationDataJsonb.longitude !== null &&
79
+ // item.geolocationDataJsonb.latitude !== null
80
+ // })
81
+ . map ( item => ( {
82
+ name : item . details ?. applicationName ,
83
+ value : [
84
+ ...getRandomLatLng ( 35 , 72 , 25 , 65 ) ,
85
+ 1 ,
86
+ ]
87
+ // value: [
88
+ // geoLocation.location.longitude, // item.longitude,
89
+ // geoLocation.location.latitude, // item.latitude,
90
+ // 1
91
+ // ]
92
+ } ) )
93
+ ,
94
+ "encode" : {
95
+ "value" : 2 ,
96
+ "lng" : 0 ,
97
+ "lat" : 1
98
+ }
99
+ }
100
+ ]
101
+ } , [ data ] ) ;
102
+
103
+ return (
104
+ < >
105
+ { isMapScriptLoaded && (
106
+ < ReactECharts
107
+ ref = { chartRef }
108
+ option = { {
109
+ gmap : {
110
+ center : [ 15 , 55 ] ,
111
+ zoom : 3 ,
112
+ renderOnMoving : true ,
113
+ echartsLayerZIndex : 2019 ,
114
+ roam : true
115
+ } ,
116
+ tooltip : {
117
+ trigger : "item" ,
118
+ formatter : "{b}"
119
+ } ,
120
+ animation : true ,
121
+ series : series ,
122
+ } }
123
+ style = { { height : "400px" } }
124
+ />
125
+ ) }
126
+ </ >
127
+ )
128
+ }
129
+
130
+ export default UserEngagementByRegionChart ;
0 commit comments