Skip to content

Frontend Angular en

aneahgi edited this page May 22, 2018 · 17 revisions

Installation

  • Download Node.js. Download and installation from: https://nodejs.org/en/
  • npm - Package Manager (is available after the installation of node on the command line)
  • Angular/cli. Installation from command line: npm install -g @angular/cli
  • Json-server. From command line: npm install -g json-server
  • IDE's, that work with Angular: Visual Studio Code Atom Webstorm

Test your environment

  • ng new test-app
  • cd test-app
  • ng serve

Use the Angular/cli

  • The Angular client is a practical tool to create new components, services etc. easily.

  • You can install the Angular client globally on the computer with:

  • npm install -g @angular/cli

  • These are some examples for the most important classes in Angular:

  • Create a service ng generate service hospital

  • Create a component ng generate component hospital

  • Create a model ng generate class hospital --type=model

  • Create a module ng genarate module hospital

General information Angular

  • This documentation shows a good overview: https://angular.io/docs

Modules

The basic blocks of an Angular application are the NgModules, which contain the complication context for the components. The NgModules merge related code into functional sets. The complete application is then a combination of NgModules. Every Angular application has at least one module, the root module, which enables bootstrapping. Typically there are many more modules available.

  • In spite we don't have a lot of different components and services we just need the app-module and didn't create more modules. But we have also predefined modules, which we use in the project.
  • Our app-module is set up like this:
import {environment} from "../environments/environment";

import {HttpClientModule} from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, ApplicationRef } from '@angular/core';
import { FormsModule} from '@angular/forms';
import { CommonModule } from '@angular/common';
import {AppRoutingModule} from "./app-routing.module";

import { AppComponent } from './app.component';
import { MapsComponent } from './components/maps/maps.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { HospitalComponent } from './components/hospital/hospital.component';
import { DropdownComponent } from './components/dropdown/dropdown.component';
import { CharacteristicsComponent } from './components/characteristics/characteristics.component';

import {CharacteristicsService} from './services/characteristics.service';
import {HospitalService} from "./services/hospital.service";

@NgModule({
  declarations: [
    AppComponent,
    MapsComponent,
    NavbarComponent,
    HospitalComponent,
    DropdownComponent,
    CharacteristicsComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    CommonModule,
    FormsModule,
    AppRoutingModule,

  ],
  providers: [
    CharacteristicsService,
    HospitalService,
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Get the data from the Backend and use it

  • The data is loaded with services and is used after that in the associated components

Services

  • The services are used to provide program logic that is used in different components
  • All the logic that is not in direct context with the view is outsourced in services
  • To retrieve the data in the service from the backend, the HttpClient is used, which accesses the desired URL's, where the JSONs are located
import { HttpClient, HttpHeaders } from '@angular/common/http';
constructor(private http: HttpClient) {
}

Hospital Service

  • In the hospital services we get the hospitals with all corresponding data (addresses, coordinates, attributes)
  /**
   * Gets all hospitals with all corresponding data (address, coordinates, attributes)
   * @returns {Observable<Hospital[]>} data in form of the defined model Hospital
   */
  getAll(): Observable<Hospital[]> {
    return this.http.get<Hospital[]>('https://geopital.herokuapp.com/' + 'api/hospitals')
    .map(res => {
      return res as Hospital[]
    })
  }

Characteristics Service

  • In the characteristics service we load the numeric and the categorical attributes separated, to use them for the attribute selection
  • The numerical attributes determine the size of the points
  • The categorical attribues determine the shape
  • Further processing is happening in the dropdown component
  /**
   * Gets all attributes which a hospital can have
   * @returns {Observable<Attributes[]>} data in form of the defined model Attributes
   */
  getCategoricalAttributes(): Observable<Attributes[]> {
    return this.http.get<Attributes[]>('https://geopital.herokuapp.com/' + 'api/attributeTypes')
      .map(res => {
        return res['attribute_types_string'] as Attributes[];
      })
  }

  getNumericalAttributes(): Observable<Attributes[]> {
    return this.http.get<Attributes[]>('https://geopital.herokuapp.com/' + 'api/attributeTypes')
      .map(res => {
        return res['attribute_types_number'] as Attributes[];
      })
  }

Components

  • In the components we have all logic implemented, which is in direct context to the view
  • A component includes a typescript, a HTML and a CSS file
  • TypeScript: For the logic
  • HTML: For the view
  • CSS: For the design

Dropdown Component

  • The dropdown component is the middle part of the menu on the right side
  • Im Dropdown Component werden die numerischen und kategoriellen Variablen weiterverarbeitet und in das Auswählfeld auf der rechten Seite des Bildschirmes geladen
  /**
   * Is called on init and loads the attribute-array from the backend.
   * The attributes are stored in two arrays, one that contains all the
   * numerical and the other that contains all categorical attributes
   * The attributes are then displayed in the html.
   */
  ngOnInit() {
    this.hospitalService.getCategoricalAttributes()
      .subscribe(attributes => {
        this.categoricalAttributes = attributes;
      });

      this.hospitalService.getNumericalAttributes()
      .subscribe(attributes => {
        this.numericalAttributes = attributes;
      });
  }
  • Im HTML werden dann die Daten auf diese Weise geladen (Beispiel für die kategoriellen Attribute
<!-- first dropdown with categorical attributes -->
  <div id="numAttr" class="dropdown" style="padding:5px;">
    <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
      1. Attribut:
    </button>
    <div class="dropdown-menu">
      <a class="dropdown-item" href="#" *ngFor="let attribute of categoricalAttributes" 
         (click)="selectedNumAttribute(attribute)">{{ attribute.nameDE }}</a>
    </div>
  </div>

Navbar Component

  • Der Navbarkomponent ist der oberste Teil des Menus auf der rechten Seite
  • Hier können die Spitaltypen ausgewählt werden
  • Diese Navbar fungiert gleichzeitig als Legende, welche Farbe für welchen Spitaltyp gilt
  • Das folgende Beispiel zeigt den Code für die Auswahl des Universitätsspital (die weitere Logik geschieht im MapInitializer, Dokumentation für d3)
/** NavbarComponent.ts */
  if (hospitalType == 'K111') {
    this.numUniSp = this.numUniSp+1;
    updateMap(this.numUniSp, this.numZentSp, this.numGrundVers, this.numPsychKl, this.numRehaKl, this.numSpezKl);
  }
<!-- NavbarComponent.html -->
  <label class="container">Universitätsspitäler
     <input type="checkbox" checked="checked" (change)="selectHospitalType('K111')">
     <span class="checkmark1"></span>
  </label>
/* NavbarComponent.css */
.checkmark1 {
  position: absolute;
  top: 0;
  left: 0;
  height: 25px;
  width: 25px;
  background-color:#a82a2a;
}

Map Component

  • Im Map Component wird die getAll() Funktion des Hospital Servies aufgerufen um die Spitäler mit allen Attributen zu laden
  • Zusätzlich werden aus dem Characteristics Service die numerischen Attribute geladen um die Grösse der Punkte auf der Karte zu bestimmen. Als Default Wert nehmen wir den Ertrag aus medizinischen Leistungen der jeweiligen Spitäler
  /**
   * Loads all hospital data from backend with the help of hospitalService
   * and the Characteristics Service (for the attributes) and gives 
   * it to the mapDrawer() and setNumAttributes() functions in mapInitializer.js
   */
  ngOnInit() {
    this.characteristicsService.getNumericalAttributes()
      .subscribe(attributes => {
        this.numericalAttributes = attributes;
        for (let i of this.numericalAttributes) {
          if(this.numericalAttributes.code!=null){
            if(this.numericalAttributes[i].code=="EtMedL"){
              setNumAttribute(this.numericalAttributes[i]);
            }
          }
        }
      });

    this.hospitalService.getAll()
      .subscribe(hospitals => {
        this.hospitalsList = hospitals;
        mapDrawer(this.hospitalsList);
      });
  }
  • Im MapComponent.html wird die Karte initialisiert, welche im MapInitializer.js erstellt wird
<!-- show map defined in mapInitializer.js on screen -->
<div id="mapid" style="width: 100%; height: 100%; position: absolute"></div>
  • Zusätzlich werden im MapComponent.html noch alle Components aufgerufen, welche danach auf der Karte angezeigt werden
  <!-- shows navbar on the map -->
  <app-navbar></app-navbar>
  <!-- shows dropdown on the map -->
  <app-dropdown></app-dropdown>
  <!-- shows the characteristics on the map -->
  <app-characteristics></app-characteristics>

Visualisierung

  • Der Visualisierungs Teil wird in der Frontend D3 Dokumentation erläutert
Clone this wiki locally