@@ -184,8 +184,14 @@ function updateMembersList() {
184184 // アクティブな地域を追跡
185185 let activeCard = null ;
186186
187- // 地域ごとにカードを作成
188- Object . entries ( groupedMembers ) . forEach ( ( [ area , areaMembers ] ) => {
187+ // エリアをアルファベット順にソート
188+ const sortedAreas = Object . keys ( groupedMembers ) . sort ( ( a , b ) => {
189+ return a . toLowerCase ( ) . localeCompare ( b . toLowerCase ( ) ) ;
190+ } ) ;
191+
192+ // 地域ごとにカードを作成(ソートされた順序で)
193+ sortedAreas . forEach ( area => {
194+ const areaMembers = groupedMembers [ area ] ;
189195 const regionCard = document . createElement ( 'div' ) ;
190196 regionCard . className = 'region-card' ;
191197
@@ -212,12 +218,35 @@ function updateMembersList() {
212218 regionCard . setAttribute ( 'data-area' , area ) ;
213219 regionCard . setAttribute ( 'data-country-code' , countryCode ) ;
214220 regionCard . id = `region-${ countryCode } ` ;
221+
222+ // メンバーを役職でソート
223+ const sortedMembers = areaMembers . sort ( ( a , b ) => {
224+ // 役職の優先順位を定義
225+ const rolePriority = {
226+ 'President' : 1 ,
227+ 'Vice President' : 2 ,
228+ 'Secretary' : 3 ,
229+ 'Assistant Secretary' : 4 ,
230+ 'Treasurer' : 5 ,
231+ 'Assistant Treasurer' : 6 ,
232+ 'Executive Director' : 7 ,
233+ 'Board Member' : 8 ,
234+ 'Member' : 9
235+ } ;
236+
237+ // 役職が同じ場合は名前でソート
238+ if ( rolePriority [ a . role ] === rolePriority [ b . role ] ) {
239+ return a . name . localeCompare ( b . name ) ;
240+ }
241+
242+ return rolePriority [ a . role ] - rolePriority [ b . role ] ;
243+ } ) ;
215244
216245 regionCard . innerHTML = `
217246 <h3>${ areaData . name || area } </h3>
218- <div class="member-count">${ areaMembers . length } member(s)</div>
247+ <div class="member-count">${ sortedMembers . length } member(s)</div>
219248 <div class="member-list">
220- ${ areaMembers . map ( member => `
249+ ${ sortedMembers . map ( member => `
221250 <div class="member-item">
222251 <div class="member-name">${ member . name } </div>
223252 <div class="member-role">${ member . role } </div>
@@ -252,13 +281,32 @@ function updateMembersList() {
252281async function initGlobe ( ) {
253282 console . log ( 'Initializing globe...' ) ; // デバッグ用ログ
254283 const container = document . getElementById ( 'globe-container' ) ;
284+ const membersPanel = document . getElementById ( 'members-panel' ) ;
255285
256286 try {
257287 console . log ( 'Loading world data...' ) ; // デバッグ用ログ
258288 // 世界地図データの読み込み
259289 const worldData = await fetch ( 'https://unpkg.com/world-atlas/countries-110m.json' ) . then ( res => res . json ( ) ) ;
260290 const worldCountries = topojson . feature ( worldData , worldData . objects . countries ) ;
261291
292+ // 右ペインの幅を考慮してコンテナの位置を調整
293+ function updateGlobePosition ( ) {
294+ const panelWidth = membersPanel ? membersPanel . offsetWidth : 0 ;
295+ const windowWidth = window . innerWidth ;
296+ const windowHeight = window . innerHeight ;
297+
298+ // 地球儀の表示領域を計算(右ペインを除いた領域の中央)
299+ const globeAreaWidth = windowWidth - panelWidth ;
300+ container . style . width = `${ globeAreaWidth } px` ;
301+ container . style . height = `${ windowHeight } px` ;
302+ container . style . position = 'absolute' ;
303+ container . style . left = '0' ;
304+ container . style . top = '0' ;
305+ }
306+
307+ // 初期位置の設定
308+ updateGlobePosition ( ) ;
309+
262310 globe = Globe ( ) ( container )
263311 . globeImageUrl ( 'https://unpkg.com/three-globe/example/img/earth-night.jpg' )
264312 . backgroundImageUrl ( 'https://unpkg.com/three-globe/example/img/night-sky.png' )
@@ -384,8 +432,9 @@ async function initGlobe() {
384432
385433 // ウィンドウリサイズ時の処理
386434 window . addEventListener ( 'resize' , ( ) => {
387- globe . width ( [ window . innerWidth ] ) ;
388- globe . height ( [ window . innerHeight ] ) ;
435+ updateGlobePosition ( ) ;
436+ globe . width ( [ container . offsetWidth ] ) ;
437+ globe . height ( [ container . offsetHeight ] ) ;
389438 } ) ;
390439
391440 } catch ( error ) {
@@ -403,25 +452,25 @@ function getAreaNameFromCountryCode(countryCode) {
403452}
404453
405454// 地球儀のハイライトを更新
406- function updateGlobeHighlight ( location , states = null ) {
455+ function updateGlobeHighlight ( area , states = null ) {
407456 globe . polygonLabel ( ( { properties : d , id } ) => {
408- if ( location === 'USA' ) {
457+ if ( area === 'USA' ) {
409458 // USAの場合、選択された州のみラベル表示
410459 const stateFips = properties ?. STATEFP ;
411- const stateLocation = states ?. find ( state =>
412- AREA_DATA [ members . find ( m => m . location === state ) . area ] . center [ 1 ] === properties ?. INTPTLAT
413- && AREA_DATA [ members . find ( m => m . location === state ) . area ] . center [ 0 ] === properties ?. INTPTLON
460+ const stateArea = states ?. find ( state =>
461+ AREA_DATA [ members . find ( m => m . area === state ) . area ] . center [ 1 ] === properties ?. INTPTLAT
462+ && AREA_DATA [ members . find ( m => m . area === state ) . area ] . center [ 0 ] === properties ?. INTPTLON
414463 ) ;
415464
416- if ( stateLocation ) {
417- const stateMembers = members . filter ( m => m . location === stateLocation ) ;
418- return createLabel ( stateLocation , stateMembers ) ;
465+ if ( stateArea ) {
466+ const stateMembers = members . filter ( m => m . area === stateArea ) ;
467+ return createLabel ( stateArea , stateMembers ) ;
419468 }
420469 } else {
421- const memberArea = members . find ( m => m . location === location ) ?. area ;
470+ const memberArea = members . find ( m => m . area === area ) ?. area ;
422471 const areaData = AREA_DATA [ memberArea ] ;
423472 if ( areaData && d . ISO_A3 === getCountryAlpha3 ( areaData . countryCode ) ) {
424- return createLabel ( location , members . filter ( m => m . location === location ) ) ;
473+ return createLabel ( area , members . filter ( m => m . area === area ) ) ;
425474 }
426475 }
427476 return null ;
@@ -433,16 +482,16 @@ function updateGlobeHighlight(location, states = null) {
433482 return ;
434483 }
435484
436- if ( location === 'USA' ) {
485+ if ( area === 'USA' ) {
437486 const stateFips = hoverD . properties ?. STATEFP ;
438487 if ( stateFips && states ?. some ( state =>
439- AREA_DATA [ members . find ( m => m . location === state ) . area ] . center [ 1 ] === hoverD . properties ?. INTPTLAT
440- && AREA_DATA [ members . find ( m => m . location === state ) . area ] . center [ 0 ] === hoverD . properties ?. INTPTLON
488+ AREA_DATA [ members . find ( m => m . area === state ) . area ] . center [ 1 ] === hoverD . properties ?. INTPTLAT
489+ && AREA_DATA [ members . find ( m => m . area === state ) . area ] . center [ 0 ] === hoverD . properties ?. INTPTLON
441490 ) ) {
442491 globe . polygonAltitude ( d => d === hoverD ? 0.12 : 0.01 ) ;
443492 }
444493 } else {
445- const memberArea = members . find ( m => m . location === location ) ?. area ;
494+ const memberArea = members . find ( m => m . area === area ) ?. area ;
446495 const areaData = AREA_DATA [ memberArea ] ;
447496 if ( areaData && hoverD . properties ?. ISO_A3 === getCountryAlpha3 ( areaData . countryCode ) ) {
448497 globe . polygonAltitude ( d => d === hoverD ? 0.12 : 0.01 ) ;
@@ -452,12 +501,12 @@ function updateGlobeHighlight(location, states = null) {
452501}
453502
454503// ラベルのHTML生成
455- function createLabel ( location , locationMembers ) {
504+ function createLabel ( area , areaMembers ) {
456505 return `
457506 <div style="background: white; padding: 10px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.2);">
458- <div style="font-weight: bold; color: #2c3e50;">${ location } </div>
459- <div style="color: #7f8c8d; margin-top: 5px;">Members: ${ locationMembers . length } </div>
460- ${ locationMembers . map ( member => `
507+ <div style="font-weight: bold; color: #2c3e50;">${ area } </div>
508+ <div style="color: #7f8c8d; margin-top: 5px;">Members: ${ areaMembers . length } </div>
509+ ${ areaMembers . map ( member => `
461510 <div style="color: #7f8c8d; margin-top: 3px;">
462511 ${ member . name } (${ member . role } )
463512 </div>
0 commit comments