Search code examples
angularmapbox-gl

Mapbox-gl only displaying half the container


I'm trying to get ngx-mapbox-gl to display a map in an angular app, but the map is only displaying in half the div. Have played with multiple settings and html tweaks, but cannot get more than half a map to display. Here is the map.component.html file:

    <div class="map" ng-view flex layout-fill style="height: 100%;border: solid 1px">
      <mgl-map
           [style]="'mapbox://styles/mapbox/streets-v9'"
           [zoom]="9"
           [center]="_center"
           (load)="loadMap($event)"
       >
       </mgl-map> 
     </div>

and the map.component.scss:

     @import 'mapbox-gl/dist/mapbox-gl.css';

     .mapboxgl-canvas {
       position: fixed !important;
       height: 100% !important;
}

map.component.ts:

 import { Component, OnInit, Input, Output, EventEmitter, OnChanges } from      '@angular/core';

 import { LngLat, Map } from 'mapbox-gl';

 @Component({
   selector: 'app-map',
   templateUrl: './map.component.html',
   styleUrls: ['./map.component.scss'],
 })

 export class DisplayMapComponent implements OnInit, OnChanges {
   map: Map;

   _center: LngLat;

   //refs
   _mapRef: Map;

   @Output()
   centerChange: EventEmitter<LngLat> =  new EventEmitter;

   @Input()
   set zoom(z: number) {
     this._zoom = z;
     if(this.index === 0) {
       this.zoomChange.emit(this._zoom);
     }
   }
   @Output()
   zoomChange : EventEmitter<number> = new EventEmitter;
   _zoom: number;

   @Input()
   index: number;

   constructor() { }

   ngOnInit() {
     this.zoom = 11;
     this._center = new LngLat( -121.31209, 37.449904  );
     console.log('this._center: ', this._center);
   }

   ngOnChanges(changes) {
     console.log('changes: ', changes);
     if (!changes) {
       return;
     }

   }

   loadMap( map: Map) {
     console.log("Initializing map, _center: ", this._center);
     console.log("map: ", map);
     this._mapRef = map;
     console.log("Loading map data");
     this._center = map.getCenter();
     console.log('this._center from map: ', this._center);
   }

 }

app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LocalStorageService } from './services/local-storage.service';
import { MatToolbarModule, MatMenuModule, MatIconModule, MatListModule, MatGridListModule, MatButtonModule, MatCardModule } from '@angular/material'; 
import { MatSidenavModule } from '@angular/material/sidenav';
import { FlexLayoutModule } from '@angular/flex-layout';
import { StorageServiceModule } from 'angular-webstorage-service';

//mapbox imports
import { NgxMapboxGLModule } from 'ngx-mapbox-gl';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/header/header.component';
import { DisplayMapComponent } from './components/map/map.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { LayoutModule } from '@angular/cdk/layout';
import { SettingsContainerComponent } from './components/settings-    container/settings-container.component';

@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    DisplayMapComponent,
    NavbarComponent,
    SettingsContainerComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatToolbarModule,
    MatSidenavModule,
    MatMenuModule,
    MatButtonModule,
    MatIconModule,
    FlexLayoutModule,
    LayoutModule,
    MatListModule,
    StorageServiceModule,
    NgxMapboxGLModule.withConfig({
      accessToken: '<token>', 
    }),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Here's a screenshot of what I'm seeing:

enter image description here If I remove the map,the border of the div it taking the entire window as it should. But I can't get the map to use up the entire window. Is it css or html or ts I'm doing wrong?

Thanks....


Solution

  • You can do the same as it is shown in the ngx-mapbox-gl documentation sample. There is a getting started section that explains all in detail. Here is also a summary of what you need to do.

    Instead of using your .mapboxgl-canvas style override you just need to specify this style in the map.component.scss file:

     mgl-map {
          height: 100%;
          width: 100%;
        }
    

    Put the import of the mapbox css file @import 'mapbox-gl/dist/mapbox-gl.css'; in the main styles.scss file of the application instead in the component file. Then it should work ok.

    Also another tip. Since you are using the @angular/flex-layout library you can use the fxFlexFill directive on your div to make it fill all the content instead off all what you have there. Then you component html is much more clean.

    <div fxFlexFill style="border: solid 1px">
      <mgl-map
          [style]="'mapbox://styles/mapbox/streets-v9'"
          [zoom]="9"
          [center]="_center"
          (load)="loadMap($event)"
      >
      </mgl-map> 
    </div>
    

    I have created also a StackBlitz sample where you can see it working. If you want to see the map you need to edit the sample and add your token in the app.module.ts.