fredmo commited on
Commit
46933c1
·
verified ·
1 Parent(s): 763e7aa

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +287 -255
index.html CHANGED
@@ -3,320 +3,352 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>GCP Accelerator Map</title>
7
- <script src="https://cesium.com/downloads/cesiumjs/releases/1.117/Build/Cesium/Cesium.js"></script>
8
- <link href="https://cesium.com/downloads/cesiumjs/releases/1.117/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
9
  <style>
10
- html, body, #cesiumContainer {
11
- width: 100%;
12
- height: 100%;
13
- margin: 0;
14
- padding: 0;
15
- overflow: hidden;
16
- font-family: sans-serif;
17
- }
18
  #controls {
19
  position: absolute;
20
  top: 10px;
21
  left: 10px;
22
- background: rgba(40, 40, 40, 0.8);
23
  padding: 15px;
24
- border-radius: 8px;
25
- color: white;
26
  max-height: 90vh;
27
  overflow-y: auto;
28
  z-index: 10;
29
  }
30
- #controls h3 {
31
- margin-top: 0;
32
- }
33
  #controls label {
34
  display: block;
35
  margin-bottom: 8px;
36
  cursor: pointer;
 
37
  }
38
  #controls input[type="checkbox"] {
39
- margin-right: 8px;
40
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  </style>
 
 
 
42
  </head>
43
  <body>
44
- <div id="cesiumContainer"></div>
 
45
  <div id="controls">
46
- <h3>Filter by Accelerator</h3>
47
- <div id="acceleratorFilters">
48
- </div>
 
 
 
 
 
 
49
  </div>
50
 
51
  <script>
52
- // --- Cesium Ion Access Token (Replace with your own) ---
53
- Cesium.Ion.defaultAccessToken = 'YOUR_CESIUM_ION_ACCESS_TOKEN'; // Optional
54
 
55
- // --- Datacenter Data ---
56
- // (Latitude and Longitude are approximate and need to be verified/corrected)
 
57
  const rawData = [
58
- { accelerator: "TPU v2", regionId: "us-central1", zones: "b, c, f", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514 },
59
- { accelerator: "TPU v2", regionId: "europe-west4", zones: "a", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442 },
60
- { accelerator: "TPU v2", regionId: "asia-east1", zones: "c", location: "Changhua County, Taiwan", lat: 24.0716, lon: 120.5469 },
61
- // ... (Duplicate TPU v2 entries were present, consolidated by location for mapping)
62
- { accelerator: "TPU v3", regionId: "us-central1", zones: "a, b, f", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514 },
63
- { accelerator: "TPU v3", regionId: "europe-west4", zones: "a", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442 },
64
- // ... (Duplicate TPU v3 entries)
65
- { accelerator: "TPU v4", regionId: "us-central2", zones: "b", location: "Council Bluffs, Iowa, USA (?)", lat: 41.2619, lon: -95.8514 }, // Note: Location was marked with (?)
66
- { accelerator: "TPU v5e", regionId: "us-central1", zones: "a", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514 },
67
- { accelerator: "TPU v5e", regionId: "us-east5", zones: "a, b, c", location: "Columbus, Ohio, USA", lat: 39.9612, lon: -82.9988 },
68
- { accelerator: "TPU v5e", regionId: "us-south1", zones: "a", location: "Dallas, Texas, USA", lat: 32.7767, lon: -96.7970 },
69
- { accelerator: "TPU v5e", regionId: "us-west1", zones: "c", location: "The Dalles, Oregon, USA", lat: 45.5946, lon: -121.1787 },
70
- { accelerator: "TPU v5e", regionId: "us-west4", zones: "a", location: "Las Vegas, Nevada, USA", lat: 36.1699, lon: -115.1398 },
71
- { accelerator: "TPU v5e", regionId: "europe-west1", zones: "b", location: "St. Ghislain, Belgium", lat: 50.4377, lon: 3.8203 },
72
- { accelerator: "TPU v5e", regionId: "asia-southeast1", zones: "b", location: "Jurong West, Singapore", lat: 1.3521, lon: 103.8198 }, // Using general Singapore coords
73
- { accelerator: "TPU v5p", regionId: "us-east5", zones: "a", location: "Columbus, Ohio, USA", lat: 39.9612, lon: -82.9988 },
74
- { accelerator: "TPU v5p", regionId: "europe-west4", zones: "b", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442 },
75
- { accelerator: "TPU v6e", regionId: "us-east1", zones: "d", location: "Moncks Corner, South Carolina, USA", lat: 33.1957, lon: -79.9906 },
76
- { accelerator: "TPU v6e", regionId: "us-east5", zones: "b", location: "Columbus, Ohio, USA", lat: 39.9612, lon: -82.9988 },
77
- { accelerator: "TPU v6e", regionId: "europe-west4", zones: "a", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442 },
78
- { accelerator: "TPU v6e", regionId: "asia-northeast1", zones: "b", location: "Tokyo, Japan", lat: 35.6895, lon: 139.6917 },
79
- { accelerator: "H100 A3 Mega", regionId: "us-central1", zones: "a, b*, c", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514, notes: "b: Limited capacity, contact TAM" },
80
- { accelerator: "H100 A3 Mega", regionId: "us-east4", zones: "a, b, c", location: "Ashburn, Virginia, USA", lat: 39.0438, lon: -77.4874 },
81
- { accelerator: "H100 A3 Mega", regionId: "us-west1", zones: "a, b", location: "The Dalles, Oregon, USA", lat: 45.5946, lon: -121.1787 },
82
- { accelerator: "H100 A3 Mega", regionId: "us-west4", zones: "a", location: "Las Vegas, Nevada, USA", lat: 36.1699, lon: -115.1398 },
83
- { accelerator: "H100 A3 Mega", regionId: "asia-northeast1", zones: "b", location: "Tokyo, Japan", lat: 35.6895, lon: 139.6917 },
84
- { accelerator: "H100 A3 Mega", regionId: "asia-southeast1", zones: "b, c", location: "Jurong West, Singapore", lat: 1.3521, lon: 103.8198 },
85
- { accelerator: "H100 A3 Mega", regionId: "australia-southeast1", zones: "c*", location: "Sydney, Australia", lat: -33.8688, lon: 151.2093, notes: "Limited capacity, contact TAM" },
86
- { accelerator: "H100 A3 Mega", regionId: "europe-west1", zones: "b*, c*", location: "St. Ghislain, Belgium", lat: 50.4377, lon: 3.8203, notes: "Limited capacity, contact TAM" },
87
- { accelerator: "H100 A3 Mega", regionId: "europe-west4", zones: "b, c", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442 },
88
- { accelerator: "H100 A3 High", regionId: "us-central1", zones: "a, c", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514 },
89
- { accelerator: "H100 A3 High", regionId: "us-east4", zones: "a, b", location: "Ashburn, Virginia, USA", lat: 39.0438, lon: -77.4874 },
90
- { accelerator: "H100 A3 High", regionId: "us-east5", zones: "a", location: "Columbus, Ohio, USA", lat: 39.9612, lon: -82.9988 },
91
- { accelerator: "H100 A3 High", regionId: "us-west1", zones: "a, b", location: "The Dalles, Oregon, USA", lat: 45.5946, lon: -121.1787 },
92
- { accelerator: "H100 A3 High", regionId: "us-west4", zones: "a", location: "Las Vegas, Nevada, USA", lat: 36.1699, lon: -115.1398 },
93
- { accelerator: "H100 A3 High", regionId: "asia-northeast1", zones: "b", location: "Tokyo, Japan", lat: 35.6895, lon: 139.6917 },
94
- { accelerator: "H100 A3 High", regionId: "asia-southeast1", zones: "b, c", location: "Jurong West, Singapore", lat: 1.3521, lon: 103.8198 },
95
- { accelerator: "H100 A3 High", regionId: "europe-west1", zones: "b*", location: "St. Ghislain, Belgium", lat: 50.4377, lon: 3.8203, notes: "Limited capacity, contact TAM" },
96
- { accelerator: "H100 A3 Edge", regionId: "northamerica-northeast2", zones: "c", location: "Toronto, Ontario, Canada", lat: 43.6532, lon: -79.3832 },
97
- { accelerator: "H100 A3 Edge", regionId: "asia-northeast1", zones: "b", location: "Tokyo, Japan", lat: 35.6895, lon: 139.6917 },
98
- { accelerator: "H100 A3 Edge", regionId: "asia-northeast3", zones: "a, c", location: "Seoul, South Korea", lat: 37.5665, lon: 126.9780 },
99
- { accelerator: "H100 A3 Edge", regionId: "asia-south1", zones: "c", location: "Mumbai, India", lat: 19.0760, lon: 72.8777 },
100
- { accelerator: "H100 A3 Edge", regionId: "europe-west2", zones: "b", location: "London, UK", lat: 51.5074, lon: -0.1278 },
101
- { accelerator: "H100 A3 Edge", regionId: "europe-west3", zones: "a", location: "Frankfurt, Germany", lat: 50.1109, lon: 8.6821 },
102
- { accelerator: "A100 A2 Ultra", regionId: "us-central1", zones: "a, c", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514 },
103
- { accelerator: "A100 A2 Ultra", regionId: "us-east4", zones: "c", location: "Ashburn, Virginia, USA", lat: 39.0438, lon: -77.4874 },
104
- { accelerator: "A100 A2 Ultra", regionId: "us-east5", zones: "b", location: "Columbus, Ohio, USA", lat: 39.9612, lon: -82.9988 },
105
- { accelerator: "A100 A2 Ultra", regionId: "asia-southeast1", zones: "c", location: "Jurong West, Singapore", lat: 1.3521, lon: 103.8198 },
106
- { accelerator: "A100 A2 Ultra", regionId: "europe-west4", zones: "a, b, c", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442 },
107
- { accelerator: "A100 40GB A2 Standard", regionId: "us-central1", zones: "a*, b*, c*, f*", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514, notes: "a2-megagpu-16g only" },
108
- { accelerator: "A100 40GB A2 Standard", regionId: "us-east1", zones: "b", location: "Moncks Corner, South Carolina, USA", lat: 33.1957, lon: -79.9906 },
109
- { accelerator: "A100 40GB A2 Standard", regionId: "us-west1", zones: "b", location: "The Dalles, Oregon, USA", lat: 45.5946, lon: -121.1787 },
110
- { accelerator: "A100 40GB A2 Standard", regionId: "us-west3", zones: "b", location: "Salt Lake City, Utah, USA", lat: 40.7608, lon: -111.8910 },
111
- { accelerator: "A100 40GB A2 Standard", regionId: "us-west4", zones: "b", location: "Las Vegas, Nevada, USA", lat: 36.1699, lon: -115.1398 },
112
- { accelerator: "A100 40GB A2 Standard", regionId: "asia-northeast1", zones: "a, c", location: "Tokyo, Japan", lat: 35.6895, lon: 139.6917 },
113
- { accelerator: "A100 40GB A2 Standard", regionId: "asia-northeast3", zones: "a, b", location: "Seoul, South Korea", lat: 37.5665, lon: 126.9780 },
114
- { accelerator: "A100 40GB A2 Standard", regionId: "asia-southeast1", zones: "b, c*", location: "Jurong West, Singapore", lat: 1.3521, lon: 103.8198, notes: "c: a2-megagpu-16g only" },
115
- { accelerator: "A100 40GB A2 Standard", regionId: "me-west1", zones: "a, c", location: "Tel Aviv, Israel", lat: 32.0853, lon: 34.7818 },
116
- { accelerator: "A100 40GB A2 Standard", regionId: "europe-west4", zones: "a*, b*", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442, notes: "a2-megagpu-16g only" },
117
- { accelerator: "G2 (L4)", regionId: "us-central1", zones: "a, b, c", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514 },
118
- { accelerator: "G2 (L4)", regionId: "us-east1", zones: "b, c, d", location: "Moncks Corner, South Carolina, USA", lat: 33.1957, lon: -79.9906 },
119
- { accelerator: "G2 (L4)", regionId: "us-east4", zones: "a", location: "Ashburn, Virginia, USA", lat: 39.0438, lon: -77.4874 },
120
- { accelerator: "G2 (L4)", regionId: "us-west1", zones: "a, b, c", location: "The Dalles, Oregon, USA", lat: 45.5946, lon: -121.1787 },
121
- { accelerator: "G2 (L4)", regionId: "us-west4", zones: "a, c", location: "Las Vegas, Nevada, USA", lat: 36.1699, lon: -115.1398 },
122
- { accelerator: "G2 (L4)", regionId: "northamerica-northeast2", zones: "a", location: "Toronto, Ontario, Canada", lat: 43.6532, lon: -79.3832 },
123
- { accelerator: "G2 (L4)", regionId: "asia-east1", zones: "a, b, c", location: "Changhua County, Taiwan", lat: 24.0716, lon: 120.5469 },
124
- { accelerator: "G2 (L4)", regionId: "asia-northeast1", zones: "a, b, c", location: "Tokyo, Japan", lat: 35.6895, lon: 139.6917 },
125
- { accelerator: "G2 (L4)", regionId: "asia-northeast3", zones: "a, b", location: "Seoul, South Korea", lat: 37.5665, lon: 126.9780 },
126
- { accelerator: "G2 (L4)", regionId: "asia-south1", zones: "a, b, c", location: "Mumbai, India", lat: 19.0760, lon: 72.8777 },
127
- { accelerator: "G2 (L4)", regionId: "asia-southeast1", zones: "a, b, c", location: "Jurong West, Singapore", lat: 1.3521, lon: 103.8198 },
128
- { accelerator: "G2 (L4)", regionId: "australia-southeast1", zones: "a", location: "Sydney, Australia", lat: -33.8688, lon: 151.2093 },
129
- { accelerator: "G2 (L4)", regionId: "europe-west1", zones: "b, c", location: "St. Ghislain, Belgium", lat: 50.4377, lon: 3.8203 },
130
- { accelerator: "G2 (L4)", regionId: "europe-west2", zones: "a, b", location: "London, UK", lat: 51.5074, lon: -0.1278 },
131
- { accelerator: "G2 (L4)", regionId: "europe-west3", zones: "a, b", location: "Frankfurt, Germany", lat: 50.1109, lon: 8.6821 },
132
- { accelerator: "G2 (L4)", regionId: "europe-west4", zones: "a, b, c", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442 },
133
- { accelerator: "G2 (L4)", regionId: "europe-west6", zones: "b, c", location: "Zurich, Switzerland", lat: 47.3769, lon: 8.5417 },
134
- { accelerator: "G2 (L4)", regionId: "me-central2", zones: "a", location: "Dammam, Saudi Arabia", lat: 26.4207, lon: 50.0888 },
135
- { accelerator: "N1+T4", regionId: "us-central1", zones: "a, b, f", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514 },
136
- { accelerator: "N1+T4", regionId: "us-east1", zones: "c, d", location: "Moncks Corner, South Carolina, USA", lat: 33.1957, lon: -79.9906 },
137
- { accelerator: "N1+T4", regionId: "us-east4", zones: "a, b", location: "Ashburn, Virginia, USA", lat: 39.0438, lon: -77.4874 },
138
- { accelerator: "N1+T4", regionId: "us-west1", zones: "a, b", location: "The Dalles, Oregon, USA", lat: 45.5946, lon: -121.1787 },
139
- { accelerator: "N1+T4", regionId: "us-west3", zones: "b", location: "Salt Lake City, Utah, USA", lat: 40.7608, lon: -111.8910 },
140
- { accelerator: "N1+T4", regionId: "us-west4", zones: "a, b", location: "Las Vegas, Nevada, USA", lat: 36.1699, lon: -115.1398 },
141
- { accelerator: "N1+T4", regionId: "northamerica-northeast1", zones: "c", location: "Montréal, Québec, Canada", lat: 45.5017, lon: -73.5673 },
142
- { accelerator: "N1+T4", regionId: "asia-east1", zones: "a, c", location: "Changhua County, Taiwan", lat: 24.0716, lon: 120.5469 },
143
- { accelerator: "N1+T4", regionId: "asia-east2", zones: "a, c", location: "Hong Kong", lat: 22.3193, lon: 114.1694 },
144
- { accelerator: "N1+T4", regionId: "asia-northeast1", zones: "a, c", location: "Tokyo, Japan", lat: 35.6895, lon: 139.6917 },
145
- { accelerator: "N1+T4", regionId: "asia-northeast3", zones: "b, c", location: "Seoul, South Korea", lat: 37.5665, lon: 126.9780 },
146
- { accelerator: "N1+T4", regionId: "asia-south1", zones: "a, b", location: "Mumbai, India", lat: 19.0760, lon: 72.8777 },
147
- { accelerator: "N1+T4", regionId: "asia-southeast1", zones: "a, b, c", location: "Jurong West, Singapore", lat: 1.3521, lon: 103.8198 },
148
- { accelerator: "N1+T4", regionId: "asia-southeast2", zones: "a", location: "Jakarta, Indonesia", lat: -6.2088, lon: 106.8456 },
149
- { accelerator: "N1+T4", regionId: "australia-southeast1", zones: "a, c", location: "Sydney, Australia", lat: -33.8688, lon: 151.2093 },
150
- { accelerator: "N1+T4", regionId: "europe-central2", zones: "b, c", location: "Warsaw, Poland", lat: 52.2297, lon: 21.0122 },
151
- { accelerator: "N1+T4", regionId: "europe-west1", zones: "b, c, d", location: "St. Ghislain, Belgium", lat: 50.4377, lon: 3.8203 },
152
- { accelerator: "N1+T4", regionId: "europe-west2", zones: "a, b", location: "London, UK", lat: 51.5074, lon: -0.1278 },
153
- { accelerator: "N1+T4", regionId: "europe-west3", zones: "b", location: "Frankfurt, Germany", lat: 50.1109, lon: 8.6821 },
154
- { accelerator: "N1+T4", regionId: "europe-west4", zones: "a, b, c", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442 },
155
- { accelerator: "N1+T4", regionId: "me-west1", zones: "b, c", location: "Tel Aviv, Israel", lat: 32.0853, lon: 34.7818 },
156
- { accelerator: "N1+T4", regionId: "southamerica-east1", zones: "a, c", location: "Osasco, São Paulo, Brazil", lat: -23.5329, lon: -46.7920 },
157
- { accelerator: "N1+V100", regionId: "us-central1", zones: "a, b, c, f", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514 },
158
- { accelerator: "N1+V100", regionId: "us-east1", zones: "c", location: "Moncks Corner, South Carolina, USA", lat: 33.1957, lon: -79.9906 },
159
- { accelerator: "N1+V100", regionId: "us-west1", zones: "a, b", location: "The Dalles, Oregon, USA", lat: 45.5946, lon: -121.1787 },
160
- { accelerator: "N1+V100", regionId: "asia-east1", zones: "c", location: "Changhua County, Taiwan", lat: 24.0716, lon: 120.5469 },
161
- { accelerator: "N1+V100", regionId: "europe-west4", zones: "a, b, c", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442 },
162
- { accelerator: "N1+P100", regionId: "us-central1", zones: "c, f", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514 },
163
- { accelerator: "N1+P100", regionId: "us-east1", zones: "b, c", location: "Moncks Corner, South Carolina, USA", lat: 33.1957, lon: -79.9906 },
164
- { accelerator: "N1+P100", regionId: "us-west1", zones: "a, b", location: "The Dalles, Oregon, USA", lat: 45.5946, lon: -121.1787 },
165
- { accelerator: "N1+P100", regionId: "asia-east1", zones: "a, c", location: "Changhua County, Taiwan", lat: 24.0716, lon: 120.5469 },
166
- { accelerator: "N1+P100", regionId: "australia-southeast1", zones: "c", location: "Sydney, Australia", lat: -33.8688, lon: 151.2093 },
167
- { accelerator: "N1+P100", regionId: "europe-west1", zones: "b, d", location: "St. Ghislain, Belgium", lat: 50.4377, lon: 3.8203 },
168
- { accelerator: "N1+P100", regionId: "europe-west4", zones: "a", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442 },
169
- { accelerator: "N1+P4", regionId: "us-central1", zones: "a, c", location: "Council Bluffs, Iowa, USA", lat: 41.2619, lon: -95.8514 },
170
- { accelerator: "N1+P4", regionId: "us-east4", zones: "a, b, c", location: "Ashburn, Virginia, USA", lat: 39.0438, lon: -77.4874 },
171
- { accelerator: "N1+P4", regionId: "northamerica-northeast1", zones: "a, b, c", location: "Montréal, Québec, Canada", lat: 45.5017, lon: -73.5673 },
172
- { accelerator: "N1+P4", regionId: "us-west2", zones: "b, c", location: "Los Angeles, California, USA", lat: 34.0522, lon: -118.2437 },
173
- { accelerator: "N1+P4", regionId: "asia-southeast1", zones: "b, c", location: "Jurong West, Singapore", lat: 1.3521, lon: 103.8198 },
174
- { accelerator: "N1+P4", regionId: "australia-southeast1", zones: "a, b", location: "Sydney, Australia", lat: -33.8688, lon: 151.2093 },
175
- { accelerator: "N1+P4", regionId: "europe-west4", zones: "b, c", location: "Eemshaven, Netherlands", lat: 53.4427, lon: 6.8442 }
176
  ];
177
 
178
- // --- Process Data ---
179
- const locationsMap = new Map(); // Key: location string, Value: { lat, lon, accelerators: Set<string>, details: [] }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
  rawData.forEach(item => {
182
- const locationKey = `${item.location}_${item.lat}_${item.lon}`; // Unique key for location
183
- if (!locationsMap.has(locationKey)) {
184
- locationsMap.set(locationKey, {
185
- name: item.location,
186
- lat: item.lat,
187
- lon: item.lon,
188
- accelerators: new Set(),
189
- details: []
190
- });
191
  }
192
- const locData = locationsMap.get(locationKey);
193
- locData.accelerators.add(item.accelerator);
194
- locData.details.push({
195
- accelerator: item.accelerator,
196
- regionId: item.regionId,
197
- zones: item.zones,
198
- notes: item.notes || ''
199
- });
200
- });
201
 
202
- const uniqueAccelerators = [...new Set(rawData.map(item => item.accelerator))].sort();
 
 
 
 
 
 
 
203
 
204
- // --- Initialize Cesium Viewer ---
205
- const viewer = new Cesium.Viewer('cesiumContainer', {
206
- terrainProvider: Cesium.createWorldTerrain(), // Optional: Needs Ion account or self-hosted terrain
207
- // imageryProvider: new Cesium.IonImageryProvider({ assetId: YOUR_IMAGERY_ASSET_ID }), // Optional
208
- animation: false,
209
- baseLayerPicker: true,
210
- fullscreenButton: false,
211
- geocoder: false,
212
- homeButton: false,
213
- infoBox: true, // Enable InfoBox for entity details
214
- sceneModePicker: true,
215
- selectionIndicator: true,
216
- timeline: false,
217
- navigationHelpButton: false,
218
- scene3DOnly: true,
219
  });
220
 
221
- // Optional: Improve visual quality
222
- viewer.scene.globe.enableLighting = true;
223
- viewer.scene.fog.enabled = true;
224
- viewer.scene.skyAtmosphere.show = true;
225
 
 
 
226
 
227
- // --- Create Filters and Entities ---
228
- const filtersContainer = document.getElementById('acceleratorFilters');
229
- const entities = []; // To store references to Cesium entities
 
230
 
231
- function createEntity(locationData) {
232
- let description = `<h3>${locationData.name}</h3><hr><ul>`;
233
- locationData.details.forEach(detail => {
234
- description += `<li><b>${detail.accelerator}</b>
235
- <br/>Region: ${detail.regionId} (Zones: ${detail.zones})
236
- ${detail.notes ? `<br/><em>Note: ${detail.notes}</em>` : ''}
237
- </li>`;
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  });
239
- description += '</ul>';
240
 
241
- const entity = viewer.entities.add({
242
- name: locationData.name,
243
- position: Cesium.Cartesian3.fromDegrees(locationData.lon, locationData.lat),
244
- billboard: {
245
- image: 'data:image/svg+xml;base64,' + btoa(`
246
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="48" height="48">
247
- <circle cx="12" cy="12" r="10" fill="#007bff" stroke="white" stroke-width="1.5"/>
248
- <circle cx="12" cy="12" r="4" fill="white"/>
249
- </svg>
250
- `), // Simple blue dot SVG marker
251
- width: 24,
252
- height: 24,
253
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
254
- },
255
- description: description,
256
- label: {
257
- text: locationData.name,
258
- font: '12pt sans-serif',
259
- style: Cesium.LabelStyle.FILL_AND_OUTLINE,
260
- outlineWidth: 2,
261
- outlineColor: Cesium.Color.BLACK,
262
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
263
- pixelOffset: new Cesium.Cartesian2(0, -26), // Offset label above billboard
264
- showBackground: true,
265
- backgroundColor: new Cesium.Color(0.1, 0.1, 0.1, 0.7),
266
- backgroundPadding: new Cesium.Cartesian2(7,5)
267
- },
268
- _accelerators: locationData.accelerators // Store accelerators for filtering
269
- });
270
- entities.push(entity);
271
- }
272
 
273
- locationsMap.forEach(createEntity);
 
 
 
274
 
275
- // --- Filtering Logic ---
276
- uniqueAccelerators.forEach(accel => {
277
- const checkboxId = `filter-${accel.replace(/\s+|\(|\)|\+/g, '-')}`; // Create valid ID
278
 
 
279
  const label = document.createElement('label');
280
- label.htmlFor = checkboxId;
281
-
282
  const checkbox = document.createElement('input');
283
  checkbox.type = 'checkbox';
284
- checkbox.id = checkboxId;
285
  checkbox.value = accel;
286
- checkbox.checked = true; // Default to show all
287
- checkbox.addEventListener('change', updateEntityVisibility);
288
 
289
  label.appendChild(checkbox);
290
- label.appendChild(document.createTextNode(accel));
291
  filtersContainer.appendChild(label);
 
292
  });
293
 
294
- function updateEntityVisibility() {
295
- const selectedAccelerators = [];
296
- filtersContainer.querySelectorAll('input[type="checkbox"]:checked').forEach(cb => {
297
- selectedAccelerators.push(cb.value);
298
- });
299
 
300
- entities.forEach(entity => {
301
- if (selectedAccelerators.length === 0) {
302
- entity.show = false; // Hide if no filters selected
303
- } else {
304
- // Show if the entity has AT LEAST ONE of the selected accelerators
305
- const hasSelectedAccelerator = Array.from(entity._accelerators).some(accel => selectedAccelerators.includes(accel));
306
- entity.show = hasSelectedAccelerator;
307
- }
308
  });
 
 
309
  }
310
 
311
- // Initial call to set visibility based on default checked states
312
- updateEntityVisibility();
 
 
 
 
 
 
 
 
 
 
 
 
313
 
314
- // Fly to a general overview
315
- viewer.camera.flyTo({
316
- destination: Cesium.Cartesian3.fromDegrees(-30, 20, 25000000), // Adjust as needed
317
- duration: 3
318
  });
319
 
320
  </script>
 
321
  </body>
322
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>GCP Accelerator Availability Map</title>
 
 
7
  <style>
8
+ body { margin: 0; font-family: sans-serif; background-color: #111; color: #eee; }
9
+ #globeViz { width: 100vw; height: 100vh; }
 
 
 
 
 
 
10
  #controls {
11
  position: absolute;
12
  top: 10px;
13
  left: 10px;
14
+ background: rgba(0, 0, 0, 0.7);
15
  padding: 15px;
16
+ border-radius: 5px;
 
17
  max-height: 90vh;
18
  overflow-y: auto;
19
  z-index: 10;
20
  }
21
+ #controls h3 { margin-top: 0; border-bottom: 1px solid #555; padding-bottom: 5px; }
 
 
22
  #controls label {
23
  display: block;
24
  margin-bottom: 8px;
25
  cursor: pointer;
26
+ font-size: 0.9em;
27
  }
28
  #controls input[type="checkbox"] {
29
+ margin-right: 5px;
30
  }
31
+ #info-panel {
32
+ position: absolute;
33
+ bottom: 10px;
34
+ left: 10px;
35
+ background: rgba(0, 0, 0, 0.8);
36
+ padding: 10px;
37
+ border-radius: 5px;
38
+ max-width: 300px;
39
+ font-size: 0.85em;
40
+ z-index: 10;
41
+ display: none; /* Hidden by default */
42
+ }
43
+ #info-panel h4 { margin: 0 0 5px 0; }
44
+ #info-panel ul { margin: 0; padding-left: 15px; }
45
+ #info-panel li { margin-bottom: 3px; }
46
  </style>
47
+ <!-- Import globe.gl library -->
48
+ <script src="//unpkg.com/three"></script>
49
+ <script src="//unpkg.com/globe.gl"></script>
50
  </head>
51
  <body>
52
+
53
+ <div id="globeViz"></div>
54
  <div id="controls">
55
+ <h3>Filter by Accelerator:</h3>
56
+ <div id="accelerator-filters">
57
+ <!-- Filters will be populated by JavaScript -->
58
+ </div>
59
+ <button id="show-all" style="margin-top: 10px; padding: 5px 10px;">Show All</button>
60
+ <button id="hide-all" style="margin-top: 10px; padding: 5px 10px;">Hide All</button>
61
+ </div>
62
+ <div id="info-panel">
63
+ <!-- Info about hovered location -->
64
  </div>
65
 
66
  <script>
67
+ // --- 1. Data Processing ---
 
68
 
69
+ // Raw data based on the provided table
70
+ // Note: Some locations might be slightly approximated. Need exact coordinates for higher precision.
71
+ // Note: Handling duplicates and summarizing zones/notes.
72
  const rawData = [
73
+ { accel: "TPU v2", region: "us-central1", zones: "b, c, f", location: "Council Bluffs, Iowa, USA" },
74
+ { accel: "TPU v2", region: "europe-west4", zones: "a", location: "Eemshaven, Netherlands" },
75
+ { accel: "TPU v2", region: "asia-east1", zones: "c", location: "Changhua County, Taiwan" },
76
+ // Some TPU v2/v3 entries seem redundant in the input, consolidating them by location
77
+ { accel: "TPU v3", region: "us-central1", zones: "a, b, f", location: "Council Bluffs, Iowa, USA" },
78
+ { accel: "TPU v3", region: "europe-west4", zones: "a", location: "Eemshaven, Netherlands" },
79
+ { accel: "TPU v4", region: "us-central2", zones: "b", location: "Council Bluffs, Iowa, USA", notes: "Location assumed near us-central1" }, // Added note about assumption
80
+ { accel: "TPU v5e", region: "us-central1", zones: "a", location: "Council Bluffs, Iowa, USA" },
81
+ { accel: "TPU v5e", region: "us-east5", zones: "a, b, c", location: "Columbus, Ohio, USA" },
82
+ { accel: "TPU v5e", region: "us-south1", zones: "a", location: "Dallas, Texas, USA" },
83
+ { accel: "TPU v5e", region: "us-west1", zones: "c", location: "The Dalles, Oregon, USA" },
84
+ { accel: "TPU v5e", region: "us-west4", zones: "a", location: "Las Vegas, Nevada, USA" },
85
+ { accel: "TPU v5e", region: "europe-west1", zones: "b", location: "St. Ghislain, Belgium" },
86
+ { accel: "TPU v5e", region: "asia-southeast1", zones: "b", location: "Jurong West, Singapore" },
87
+ { accel: "TPU v5p", region: "us-east5", zones: "a", location: "Columbus, Ohio, USA" },
88
+ { accel: "TPU v5p", region: "europe-west4", zones: "b", location: "Eemshaven, Netherlands" },
89
+ { accel: "TPU v6e", region: "us-east1", zones: "d", location: "Moncks Corner, South Carolina, USA" },
90
+ { accel: "TPU v6e", region: "us-east5", zones: "b", location: "Columbus, Ohio, USA" },
91
+ { accel: "TPU v6e", region: "europe-west4", zones: "a", location: "Eemshaven, Netherlands" },
92
+ { accel: "TPU v6e", region: "asia-northeast1", zones: "b", location: "Tokyo, Japan" },
93
+ { accel: "H100 A3 Mega", region: "us-central1", zones: "a, b*, c", location: "Council Bluffs, Iowa, USA", notes: "b: Limited capacity" },
94
+ { accel: "H100 A3 Mega", region: "us-east4", zones: "a, b, c", location: "Ashburn, Virginia, USA" },
95
+ { accel: "H100 A3 Mega", region: "us-west1", zones: "a, b", location: "The Dalles, Oregon, USA" },
96
+ { accel: "H100 A3 Mega", region: "us-west4", zones: "a", location: "Las Vegas, Nevada, USA" },
97
+ { accel: "H100 A3 Mega", region: "asia-northeast1", zones: "b", location: "Tokyo, Japan" },
98
+ { accel: "H100 A3 Mega", region: "asia-southeast1", zones: "b, c", location: "Jurong West, Singapore" },
99
+ { accel: "H100 A3 Mega", region: "australia-southeast1", zones: "c*", location: "Sydney, Australia", notes: "Limited capacity" },
100
+ { accel: "H100 A3 Mega", region: "europe-west1", zones: "b*, c*", location: "St. Ghislain, Belgium", notes: "Limited capacity" },
101
+ { accel: "H100 A3 Mega", region: "europe-west4", zones: "b, c", location: "Eemshaven, Netherlands" },
102
+ { accel: "H100 A3 High", region: "us-central1", zones: "a, c", location: "Council Bluffs, Iowa, USA" },
103
+ { accel: "H100 A3 High", region: "us-east4", zones: "a, b", location: "Ashburn, Virginia, USA" },
104
+ { accel: "H100 A3 High", region: "us-east5", zones: "a", location: "Columbus, Ohio, USA" },
105
+ { accel: "H100 A3 High", region: "us-west1", zones: "a, b", location: "The Dalles, Oregon, USA" },
106
+ { accel: "H100 A3 High", region: "us-west4", zones: "a", location: "Las Vegas, Nevada, USA" },
107
+ { accel: "H100 A3 High", region: "asia-northeast1", zones: "b", location: "Tokyo, Japan" },
108
+ { accel: "H100 A3 High", region: "asia-southeast1", zones: "b, c", location: "Jurong West, Singapore" },
109
+ { accel: "H100 A3 High", region: "europe-west1", zones: "b*", location: "St. Ghislain, Belgium", notes: "Limited capacity" },
110
+ { accel: "H100 A3 Edge", region: "northamerica-northeast2", zones: "c", location: "Toronto, Ontario, Canada" },
111
+ { accel: "H100 A3 Edge", region: "asia-northeast1", zones: "b", location: "Tokyo, Japan" },
112
+ { accel: "H100 A3 Edge", region: "asia-northeast3", zones: "a, c", location: "Seoul, South Korea" },
113
+ { accel: "H100 A3 Edge", region: "asia-south1", zones: "c", location: "Mumbai, India" },
114
+ { accel: "H100 A3 Edge", region: "europe-west2", zones: "b", location: "London, UK" },
115
+ { accel: "H100 A3 Edge", region: "europe-west3", zones: "a", location: "Frankfurt, Germany" },
116
+ { accel: "A100 A2 Ultra", region: "us-central1", zones: "a, c", location: "Council Bluffs, Iowa, USA" },
117
+ { accel: "A100 A2 Ultra", region: "us-east4", zones: "c", location: "Ashburn, Virginia, USA" },
118
+ { accel: "A100 A2 Ultra", region: "us-east5", zones: "b", location: "Columbus, Ohio, USA" },
119
+ { accel: "A100 A2 Ultra", region: "asia-southeast1", zones: "c", location: "Jurong West, Singapore" },
120
+ { accel: "A100 A2 Ultra", region: "europe-west4", zones: "a, b, c", location: "Eemshaven, Netherlands" },
121
+ { accel: "A100 40GB A2 Standard", region: "us-central1", zones: "a*, b*, c*, f*", location: "Council Bluffs, Iowa, USA", notes: "a2-megagpu-16g only" },
122
+ { accel: "A100 40GB A2 Standard", region: "us-east1", zones: "b", location: "Moncks Corner, South Carolina, USA" },
123
+ { accel: "A100 40GB A2 Standard", region: "us-west1", zones: "b", location: "The Dalles, Oregon, USA" },
124
+ { accel: "A100 40GB A2 Standard", region: "us-west3", zones: "b", location: "Salt Lake City, Utah, USA" },
125
+ { accel: "A100 40GB A2 Standard", region: "us-west4", zones: "b", location: "Las Vegas, Nevada, USA" },
126
+ { accel: "A100 40GB A2 Standard", region: "asia-northeast1", zones: "a, c", location: "Tokyo, Japan" },
127
+ { accel: "A100 40GB A2 Standard", region: "asia-northeast3", zones: "a, b", location: "Seoul, South Korea" },
128
+ { accel: "A100 40GB A2 Standard", region: "asia-southeast1", zones: "b, c*", location: "Jurong West, Singapore", notes: "c: a2-megagpu-16g only" },
129
+ { accel: "A100 40GB A2 Standard", region: "me-west1", zones: "a, c", location: "Tel Aviv, Israel" },
130
+ { accel: "A100 40GB A2 Standard", region: "europe-west4", zones: "a*, b*", location: "Eemshaven, Netherlands", notes: "a2-megagpu-16g only" },
131
+ { accel: "G2 (L4)", region: "us-central1", zones: "a, b, c", location: "Council Bluffs, Iowa, USA" },
132
+ { accel: "G2 (L4)", region: "us-east1", zones: "b, c, d", location: "Moncks Corner, South Carolina, USA" },
133
+ { accel: "G2 (L4)", region: "us-east4", zones: "a", location: "Ashburn, Virginia, USA" },
134
+ { accel: "G2 (L4)", region: "us-west1", zones: "a, b, c", location: "The Dalles, Oregon, USA" },
135
+ { accel: "G2 (L4)", region: "us-west4", zones: "a, c", location: "Las Vegas, Nevada, USA" },
136
+ { accel: "G2 (L4)", region: "northamerica-northeast2", zones: "a", location: "Toronto, Ontario, Canada" },
137
+ { accel: "G2 (L4)", region: "asia-east1", zones: "a, b, c", location: "Changhua County, Taiwan" },
138
+ { accel: "G2 (L4)", region: "asia-northeast1", zones: "a, b, c", location: "Tokyo, Japan" },
139
+ { accel: "G2 (L4)", region: "asia-northeast3", zones: "a, b", location: "Seoul, South Korea" },
140
+ { accel: "G2 (L4)", region: "asia-south1", zones: "a, b, c", location: "Mumbai, India" },
141
+ { accel: "G2 (L4)", region: "asia-southeast1", zones: "a, b, c", location: "Jurong West, Singapore" },
142
+ { accel: "G2 (L4)", region: "australia-southeast1", zones: "a", location: "Sydney, Australia" },
143
+ { accel: "G2 (L4)", region: "europe-west1", zones: "b, c", location: "St. Ghislain, Belgium" },
144
+ { accel: "G2 (L4)", region: "europe-west2", zones: "a, b", location: "London, UK" },
145
+ { accel: "G2 (L4)", region: "europe-west3", zones: "a, b", location: "Frankfurt, Germany" },
146
+ { accel: "G2 (L4)", region: "europe-west4", zones: "a, b, c", location: "Eemshaven, Netherlands" },
147
+ { accel: "G2 (L4)", region: "europe-west6", zones: "b, c", location: "Zurich, Switzerland" },
148
+ { accel: "G2 (L4)", region: "me-central2", zones: "a", location: "Dammam, Saudi Arabia" },
149
+ { accel: "N1+T4", region: "us-central1", zones: "a, b, f", location: "Council Bluffs, Iowa, USA" },
150
+ { accel: "N1+T4", region: "us-east1", zones: "c, d", location: "Moncks Corner, South Carolina, USA" },
151
+ { accel: "N1+T4", region: "us-east4", zones: "a, b", location: "Ashburn, Virginia, USA" },
152
+ { accel: "N1+T4", region: "us-west1", zones: "a, b", location: "The Dalles, Oregon, USA" },
153
+ { accel: "N1+T4", region: "us-west3", zones: "b", location: "Salt Lake City, Utah, USA" },
154
+ { accel: "N1+T4", region: "us-west4", zones: "a, b", location: "Las Vegas, Nevada, USA" },
155
+ { accel: "N1+T4", region: "northamerica-northeast1", zones: "c", location: "Montréal, Québec, Canada" },
156
+ { accel: "N1+T4", region: "asia-east1", zones: "a, c", location: "Changhua County, Taiwan" },
157
+ { accel: "N1+T4", region: "asia-east2", zones: "a, c", location: "Hong Kong" },
158
+ { accel: "N1+T4", region: "asia-northeast1", zones: "a, c", location: "Tokyo, Japan" },
159
+ { accel: "N1+T4", region: "asia-northeast3", zones: "b, c", location: "Seoul, South Korea" },
160
+ { accel: "N1+T4", region: "asia-south1", zones: "a, b", location: "Mumbai, India" },
161
+ { accel: "N1+T4", region: "asia-southeast1", zones: "a, b, c", location: "Jurong West, Singapore" },
162
+ { accel: "N1+T4", region: "asia-southeast2", zones: "a", location: "Jakarta, Indonesia" },
163
+ { accel: "N1+T4", region: "australia-southeast1", zones: "a, c", location: "Sydney, Australia" },
164
+ { accel: "N1+T4", region: "europe-central2", zones: "b, c", location: "Warsaw, Poland" },
165
+ { accel: "N1+T4", region: "europe-west1", zones: "b, c, d", location: "St. Ghislain, Belgium" },
166
+ { accel: "N1+T4", region: "europe-west2", zones: "a, b", location: "London, UK" },
167
+ { accel: "N1+T4", region: "europe-west3", zones: "b", location: "Frankfurt, Germany" },
168
+ { accel: "N1+T4", region: "europe-west4", zones: "a, b, c", location: "Eemshaven, Netherlands" },
169
+ { accel: "N1+T4", region: "me-west1", zones: "b, c", location: "Tel Aviv, Israel" },
170
+ { accel: "N1+T4", region: "southamerica-east1", zones: "a, c", location: "Osasco, São Paulo, Brazil" },
171
+ { accel: "N1+V100", region: "us-central1", zones: "a, b, c, f", location: "Council Bluffs, Iowa, USA" },
172
+ { accel: "N1+V100", region: "us-east1", zones: "c", location: "Moncks Corner, South Carolina, USA" },
173
+ { accel: "N1+V100", region: "us-west1", zones: "a, b", location: "The Dalles, Oregon, USA" },
174
+ { accel: "N1+V100", region: "asia-east1", zones: "c", location: "Changhua County, Taiwan" },
175
+ { accel: "N1+V100", region: "europe-west4", zones: "a, b, c", location: "Eemshaven, Netherlands" },
176
+ { accel: "N1+P100", region: "us-central1", zones: "c, f", location: "Council Bluffs, Iowa, USA" },
177
+ { accel: "N1+P100", region: "us-east1", zones: "b, c", location: "Moncks Corner, South Carolina, USA" },
178
+ { accel: "N1+P100", region: "us-west1", zones: "a, b", location: "The Dalles, Oregon, USA" },
179
+ { accel: "N1+P100", region: "asia-east1", zones: "a, c", location: "Changhua County, Taiwan" },
180
+ { accel: "N1+P100", region: "australia-southeast1", zones: "c", location: "Sydney, Australia" },
181
+ { accel: "N1+P100", region: "europe-west1", zones: "b, d", location: "St. Ghislain, Belgium" },
182
+ { accel: "N1+P100", region: "europe-west4", zones: "a", location: "Eemshaven, Netherlands" },
183
+ { accel: "N1+P4", region: "us-central1", zones: "a, c", location: "Council Bluffs, Iowa, USA" },
184
+ { accel: "N1+P4", region: "us-east4", zones: "a, b, c", location: "Ashburn, Virginia, USA" },
185
+ { accel: "N1+P4", region: "northamerica-northeast1", zones: "a, b, c", location: "Montréal, Québec, Canada" },
186
+ { accel: "N1+P4", region: "us-west2", zones: "b, c", location: "Los Angeles, California, USA" },
187
+ { accel: "N1+P4", region: "asia-southeast1", zones: "b, c", location: "Jurong West, Singapore" },
188
+ { accel: "N1+P4", region: "australia-southeast1", zones: "a, b", location: "Sydney, Australia" },
189
+ { accel: "N1+P4", region: "europe-west4", zones: "b, c", location: "Eemshaven, Netherlands" }
 
190
  ];
191
 
192
+ // Geocode locations (Approximate coordinates)
193
+ const locationsCoords = {
194
+ "Council Bluffs, Iowa, USA": { lat: 41.2619, lng: -95.8513 },
195
+ "Eemshaven, Netherlands": { lat: 53.4421, lng: 6.8349 },
196
+ "Changhua County, Taiwan": { lat: 24.0729, lng: 120.5446 },
197
+ "Columbus, Ohio, USA": { lat: 39.9612, lng: -82.9988 },
198
+ "Dallas, Texas, USA": { lat: 32.7767, lng: -96.7970 },
199
+ "The Dalles, Oregon, USA": { lat: 45.5946, lng: -121.1787 },
200
+ "Las Vegas, Nevada, USA": { lat: 36.1699, lng: -115.1398 },
201
+ "St. Ghislain, Belgium": { lat: 50.4430, lng: 3.8181 },
202
+ "Jurong West, Singapore": { lat: 1.3392, lng: 103.7062 },
203
+ "Moncks Corner, South Carolina, USA": { lat: 33.1918, lng: -80.0173 },
204
+ "Tokyo, Japan": { lat: 35.6895, lng: 139.6917 },
205
+ "Ashburn, Virginia, USA": { lat: 39.0438, lng: -77.4874 },
206
+ "Sydney, Australia": { lat: -33.8688, lng: 151.2093 },
207
+ "Toronto, Ontario, Canada": { lat: 43.6532, lng: -79.3832 },
208
+ "Seoul, South Korea": { lat: 37.5665, lng: 126.9780 },
209
+ "Mumbai, India": { lat: 19.0760, lng: 72.8777 },
210
+ "London, UK": { lat: 51.5074, lng: -0.1278 },
211
+ "Frankfurt, Germany": { lat: 50.1109, lng: 8.6821 },
212
+ "Salt Lake City, Utah, USA": { lat: 40.7608, lng: -111.8910 },
213
+ "Tel Aviv, Israel": { lat: 32.0853, lng: 34.7818 },
214
+ "Zurich, Switzerland": { lat: 47.3769, lng: 8.5417 },
215
+ "Dammam, Saudi Arabia": { lat: 26.4207, lng: 50.0888 },
216
+ "Montréal, Québec, Canada": { lat: 45.5017, lng: -73.5673 },
217
+ "Hong Kong": { lat: 22.3193, lng: 114.1694 },
218
+ "Jakarta, Indonesia": { lat: -6.2088, lng: 106.8456 },
219
+ "Warsaw, Poland": { lat: 52.2297, lng: 21.0122 },
220
+ "Osasco, São Paulo, Brazil": { lat: -23.5329, lng: -46.7919 },
221
+ "Los Angeles, California, USA": { lat: 34.0522, lng: -118.2437 }
222
+ };
223
+
224
+ // Aggregate data by location
225
+ const locationsData = {};
226
+ const uniqueAccelerators = new Set();
227
 
228
  rawData.forEach(item => {
229
+ const locName = item.location;
230
+ if (!locationsCoords[locName]) {
231
+ console.warn(`Coordinates not found for: ${locName}`);
232
+ return; // Skip if no coordinates
 
 
 
 
 
233
  }
 
 
 
 
 
 
 
 
 
234
 
235
+ if (!locationsData[locName]) {
236
+ locationsData[locName] = {
237
+ name: locName,
238
+ lat: locationsCoords[locName].lat,
239
+ lng: locationsCoords[locName].lng,
240
+ accelerators: []
241
+ };
242
+ }
243
 
244
+ // Add accelerator details if not already present for this location
245
+ // (Simple check based on accel name only for this example)
246
+ if (!locationsData[locName].accelerators.some(a => a.name === item.accel)) {
247
+ locationsData[locName].accelerators.push({
248
+ name: item.accel,
249
+ region: item.region,
250
+ zones: item.zones,
251
+ notes: item.notes || '' // Include notes if available
252
+ });
253
+ }
254
+ uniqueAccelerators.add(item.accel);
 
 
 
 
255
  });
256
 
257
+ // Convert aggregated data to array format for globe.gl
258
+ const pointsData = Object.values(locationsData);
 
 
259
 
260
+ // Sort accelerator names for consistent filter order
261
+ const sortedAccelerators = Array.from(uniqueAccelerators).sort();
262
 
263
+ // --- 2. Globe Initialization & Configuration ---
264
+ const myGlobe = Globe();
265
+ const globeVizElement = document.getElementById('globeViz');
266
+ const infoPanel = document.getElementById('info-panel');
267
 
268
+ myGlobe(globeVizElement)
269
+ .globeImageUrl('//unpkg.com/three-globe/example/img/earth-night.jpg')
270
+ .backgroundImageUrl('//unpkg.com/three-globe/example/img/night-sky.png')
271
+ .pointsData(pointsData) // Initial data
272
+ .pointColor(() => '#67ff94') // Nice bright green color for markers
273
+ .pointAltitude(0.01) // Slightly raise points off the surface
274
+ .pointRadius(0.25) // Adjust size as needed
275
+ .pointLabel(d => d.name)
276
+ .onPointHover(d => { // Show info panel on hover
277
+ if (d) {
278
+ infoPanel.style.display = 'block';
279
+ let accelHtml = '<ul>';
280
+ d.accelerators.forEach(accel => {
281
+ accelHtml += `<li><b>${accel.name}</b> (${accel.region}: ${accel.zones})${accel.notes ? ` <i>(${accel.notes})</i>` : ''}</li>`;
282
+ });
283
+ accelHtml += '</ul>';
284
+ infoPanel.innerHTML = `<h4>${d.name}</h4>${accelHtml}`;
285
+ } else {
286
+ infoPanel.style.display = 'none'; // Hide if not hovering over a point
287
+ }
288
  });
 
289
 
290
+ // Auto-rotate globe initially
291
+ myGlobe.controls().autoRotate = true;
292
+ myGlobe.controls().autoRotateSpeed = 0.2;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293
 
294
+ // Stop auto-rotate on user interaction
295
+ myGlobe.controls().addEventListener('start', () => {
296
+ myGlobe.controls().autoRotate = false;
297
+ });
298
 
299
+ // --- 3. Filter Implementation ---
300
+ const filtersContainer = document.getElementById('accelerator-filters');
301
+ const filterCheckboxes = [];
302
 
303
+ sortedAccelerators.forEach(accel => {
304
  const label = document.createElement('label');
 
 
305
  const checkbox = document.createElement('input');
306
  checkbox.type = 'checkbox';
 
307
  checkbox.value = accel;
308
+ checkbox.checked = true; // Start with all checked
309
+ checkbox.addEventListener('change', updateFilters);
310
 
311
  label.appendChild(checkbox);
312
+ label.appendChild(document.createTextNode(` ${accel}`));
313
  filtersContainer.appendChild(label);
314
+ filterCheckboxes.push(checkbox);
315
  });
316
 
317
+ function updateFilters() {
318
+ const selectedAccelerators = filterCheckboxes
319
+ .filter(cb => cb.checked)
320
+ .map(cb => cb.value);
 
321
 
322
+ const filteredPoints = pointsData.filter(location => {
323
+ // Keep location if it has at least one of the selected accelerators
324
+ return location.accelerators.some(accel => selectedAccelerators.includes(accel.name));
 
 
 
 
 
325
  });
326
+
327
+ myGlobe.pointsData(filteredPoints); // Update the globe
328
  }
329
 
330
+ // Show/Hide All buttons
331
+ document.getElementById('show-all').addEventListener('click', () => {
332
+ filterCheckboxes.forEach(cb => cb.checked = true);
333
+ updateFilters();
334
+ });
335
+
336
+ document.getElementById('hide-all').addEventListener('click', () => {
337
+ filterCheckboxes.forEach(cb => cb.checked = false);
338
+ updateFilters();
339
+ });
340
+
341
+ // --- 4. Initial Setup ---
342
+ // Optional: Center the view on a specific point initially
343
+ // myGlobe.pointOfView({ lat: 30, lng: -20, altitude: 2.5 });
344
 
345
+ // Handle window resize
346
+ window.addEventListener('resize', () => {
347
+ myGlobe.width(window.innerWidth);
348
+ myGlobe.height(window.innerHeight);
349
  });
350
 
351
  </script>
352
+
353
  </body>
354
  </html>