Hypertrack map library

Framework for rendering dynamic data on the map of your choice.

Items on the map are synced with the data provided to the library. When the data gets updated, the library takes care of updating markers of same id and clearing markers which are no more part of the provided data set.

The library is written in typescript but can be used with vanilla javascript.

This library supports both google maps and leaflet.js. It acts as a wrapper which handles cross map api's. The choice of map can be easily switched without any effort.

Installation

npm install ht-maps
Prerequesites

Install HyperTrack library internally used by ht-client.

npm i ht-data
npm i ht-utility
npm i ht-models //if used in typescript

Install other helper libraries

npm i rxjs
npm i underscore
npm i date-fns

Usage

Library exposes htMaps as a global variable when used as es5. Otherwise can be used with es6+ by directly importing the relevent class/functions of the library

Example

javascript

var mapClass = new htMaps.HtMapClass(mapType);

typescript

import {HtMapClass} from "ht-js-map"

var mapClass = new HtMapClass(mapType);

References

Setup

HtMapClass needs to be initalized before any functionality of the library is used. It takes mapType: 'google' | 'leaflet' as argument.

Usage

library exposes htMaps as a global variable when used as es5. Otherwise can be used with es6+ by directly importing HtMapClass

javascript

var mapType = 'google'; //or 'leaflet'
var mapClass = new htMaps.HtMapClass(mapType);

typescript

import {HtMapClass} from "ht-js-map"

var mapType: HtMapTypes = 'google'; //or 'leaflet'
var mapClass = new HtMapClass(mapType);

Initialize map

HtMapClass.initMap(elem: Element, options: MapOptions = {})

Initializes the map. Requires a map DOM element. As a second argument, map options can be passed to customize the map. This will be map type dependent and refer google-maps/leaflet docs for details.

var elem = document.getElementById('map-id');
var options = {
  center: {lat: 0, lng: 0}, zoom: 2,
  fullscreenControl: false,
}; //example google map options

var map = mapClass.initMap(elem, options);

console.log(map) // map object

Get map object

HtMapClass.map: HtMap | undefined

Current Map object. May be undefined if the map is not yet initialized. Recommended that map$ is used. Checkout tutorial explaining this feature in detail here

HtMapClass.map$: Observable<HtMap>

Observable which return map object whenever map in initialized. Can emit value more than once.

mapClass.map$.subscribe((map) => {
  console.log(map) // map object;
})

//Following emits value only once
mapClass.map$.take(1).subscribe((map) => {
  console.log(map) 
})

Render user placeline

HtMapClass.placeline

Class which renders user placeline on the map.

HtMapClass.placeline.trace(user: IUserData)

Traces the placeline on the map. Takes placeline user data as an argument. Pass null to remove existing placeline items from the map.

HtMapClass.placeline.setCompoundData$(user$: Observable<IUserData | null>, config: CompoundSetDataConfig = {})

Traces the placeline on the map, This is a more reactive approach of rendering placeline. Takes an observable which emits user placeline as first argument, takes config object as seconds argument. Config object can be used to intercept the user$ observable. Config object has the following interface.

export interface CompoundSetDataConfig {
  filter$?: Observable<string | null>,
  roots?: string[],
  resetMap$?: Observable<any>
}

filter$: This is an observable which emits id of an entity which will be rendered and rest will be hidden from placeline map view. This needs to be used with roots which will affect the properties of placeline on which filter will be applies. e.g. passing filters$ = Observable.of('#4') and roots: ['segments'] will filter segments properties of placeline data which has id === '#4'. Passing roots: ['segments', 'actions'] will apply the filter on both segments actions properties of placeline data.

resetMap$: When this observable emits a non null value, the map reset function will be triggered.

Intilize new instance of placeline

PlacelineTrace

If multiple placelines needs to be rendered on the map, new instance of placeline class can be initialized from class PlacelineTrace

var placeline1 = new PlacelineTrace();
var placeline2 = new PlacelineTrace();
placeline1.trace(userData1)
placeline2.trace(userData2)

Render users clusters

HtMapClass.usersCluster

Class which renders users clusters on the map.

HtMapClass.usersCluster.trace(users: IUser[])

Traces the list of users on the map. Pass null of empty array to remove existing users cluster from the map.

HtMapClass.usersCluster.setData$(data$: Observable<any[] | null>, config: SetDataConfig = {})

Reactive approach of rendering list of users on the map. Pass an observable emitting list of users as the first argument. Pass config object to intercept the user list data.

export interface SetDataConfig {
  hide$?: Observable<any>,
}

hide$: The users cluster on map will be hidden whenever this observable emits non null value. Example use-case will be when you need to automatically hide users clusters when placeline of a user is selected. Pass an observable which emits selected user id for placeline.

HtMapClass.usersCluster.setPageData$(data$: Observable<Page<any> | null>, config: SetDataConfig = {})

Reactive approach of rendering page of users on the map. Pass an observable emitting list of users as the first argument. Pass config object to intercept the user list data. Page data should have the following interface. This is a standard data format Hypertrack use for sending Paginated list data through api.

export interface Page<T> {
  count: number,
  next: string | null,
  previous: string | null,
  results: T[]
}

Render custom data on map

itemsFactory({renderConfig, typeConfig, styleObj}: ItemClassFactoryConfig): ItemsTrace

This is a factory function which is used for rendering any generic (HyperTrack independent) data set on the map. This is used internally to render HyperTrack entity. ItemsTrace class returned by this factory function exposes methods which needs to be called with the custom data to render them on the map.

ItemClassFactoryConfig

Configuration object that is passed to itemsFactory for instantiating a class which handles rendering of map items.

It is of the following interface

export interface ItemClassFactoryConfig {
  renderConfig: DataConfig<any>,
  typeConfig?: Partial<MapItemsFactoryConfig>,
  styleObj?: StyleObj,
  name?: string
}

[info] Interfaces

Interface is typescript specific feature. But this interface also reflect the structure of object expected in vanilla javascript (non-typescript) environment.

Passing rendering info

renderConfig: DataConfig<any>

export interface MarkerDataConfig<T> {
  getPosition(data: T): HtPosition,
  getInfoContent?(data: T): string,
}

export interface DivMarkerDataConfig<T> extends MarkerDataConfig<T>{
  // getPosition?(data: T): HtPosition,
  // getInfoContent?(data: T): string,
  getDivContent(data: T): string
}

export interface PolylineDataConfig<T> {
  getEncodedPath?(data: T): string,
  getEncodedPositionTime?(data: any): string
}

export type DataConfig<T> = MarkerDataConfig<T>
  | DivMarkerDataConfig<any>
  | PolylineDataConfig<any>

This object contains function which are required to render the entity on the map

  • getPosition(data): HtPosition | null required to render markers/circles etc which needs position. Marker will not be rendered if this functions return null
  • getInfoContent(data): string required for popup info content
  • getDivContent(data): string required for Div Markers for custom html of markers
  • getEncodedPath(data): string required for polyline

Passing style info

styleObj

Contains styling information of the map entities. Has 2 keys google and leaflet which contains map specific styling information. This object must contain a default style object.

Example
var styleObj = {
  google: {
    default: {
      ...
    }
  },
  leaflet: {
    default: {
      ...
    }
  }
}

default style object is required. This will be the default style of the marker. If the marker has a popup, it can be styled by adding popup style object as a sibling to default.

Passing map item type info

typeConfig: MapItemsFactoryConfig

Type of map item entity which needs to be rendered can be configured using typeConfig. It has following interface

export interface MapItemsFactoryConfig {
  isCluster: boolean,
  hasPopup: boolean,
  isDiv: boolean,
  isCircle: boolean,
  isSingleItem: boolean,
  hasDataObservable: boolean,
  isPolyline: boolean
};
  • isCluster : Set to true to render markers as clusters
  • isCircle : Set to true to render markers as circles,
  • isPolyline : Set to true to render markers as Polyline,
  • isSingleItem : Set to true if a single item needs to be rendered on the map. In trace function just pass the item which needs to be rendered instead of array of items.
  • hasPopup : Set to true to add popup on hover on the markers. Pass getInfoContent function in renderConfig to configure the text shown in the popup. Popup style can be configured by adding popup key (as a sibling of default) in styleObj argument.
  • isDiv : Set to true to render markers as custom html element. Also pass getDivContent function in renderConfig to configure the custom html which needs to be rendered as markers,
  • hasDataObservable : This added setData(data$: Observable<any>, config: SetDataConfig) functionality to the class. This enables more reactive approach of rendering data on map. Instead of calling trace(data) function every time new data needs to be rendered and calling resetMap function, by passing observable emitting data, it will internally call trace(data) every time new data is emitted by the observable and reset map accordingly.

ItemsTrace.trace(data)

Pass custom data to render them on the map.

ItemsTrace.setData(data$: Observable<any>, config: SetDataConfig)

Pass observable which emits custom data as the first argument.

Reset map bounds

HtMapClass.resetBounds(bounds?: HtBounds)

Sets the bounds of the map to contain all HyperTrack map items. Additional bounds can be passed which will be included while extending the bounds. By default only HyperTrack entities like usersClusters and placeline are included. If custom data is rendered, this function will not work on those unless they are explicitly added using HtMapClass.addEntities(entity).

mapClass.resetBounds()

HtMapClass.addEntities(entity)

Add custom map entities to the list of entities to be included in the bounds when resetBounds() function is called.

var customMapEntities = mapItemsFactory({renderConfig, typeConfig, styleObj});
mapClass.addEntities(customMapEntities);
mapClass.resetBounds() //this will now set bounds with custom map entities also in view.

results matching ""

    No results matching ""