npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ngx-apexmaps

v0.3.0

Published

Angular component for ApexMaps

Readme

ngx-apexmaps

Angular component for ApexMaps.

npm install apexmaps ngx-apexmaps

apexmaps and @angular/core (>= 20) are peer dependencies. Nothing else: no @angular/common, no rxjs requirement of its own, no zone.js requirement, no NgModule.

Quick start

import { Component, signal } from '@angular/core'
import { ApexMapsComponent } from 'ngx-apexmaps'
import 'apexmaps/apexmaps.css'

@Component({
  standalone: true,
  imports: [ApexMapsComponent],
  template: `
    <apx-map
      [options]="options"
      [series]="series()"
      [height]="480"
      (featureClick)="selected.set($event.key)"
    />
  `,
})
export class CoverageComponent {
  readonly options = { geo: { map: 'world' } }
  readonly series = signal([
    {
      type: 'choropleth',
      name: 'Coverage',
      data: [{ key: 'IND', value: 42 }],
      scale: { palette: 'blues', classes: 5 },
    },
  ])
  readonly selected = signal<string | null>(null)
}

Inputs and outputs

| Input | Type | Notes | | --- | --- | --- | | options | ApexMapsOptions | Required. The same options object the core takes. | | series | Series[] | Optional shorthand for options.series. Takes precedence over it. | | width / height | number \| string | Shorthand for options.chart.width / .height. See sizing. |

One output per core event, under the core's own name: rendered, updated, resized, featureClick, featureHover, featureFocus, markClick, markHover, clusterClick, drilldown, drillup, selectionChange, legendToggle, zoom, panEnd. Each receives the payload the core emits, fully typed.

The zone contract

The reason this wrapper exists rather than "just call the library from Angular":

  • The map runs outside the Angular zone. A map attaches pointer listeners to everything it draws, and zone-patched listeners run change detection on every event: with zone.js, every pointermove over every feature would tick your whole application. Construction, rendering and updates all happen outside the zone, and re-attached listeners stay unpatched.
  • Outputs are emitted back inside the zone. Events originate from unpatched listeners, which zone-based change detection cannot see. The component re-enters the zone to emit, so a (featureClick) handler that sets component state repaints, in zoned and zoneless applications alike.

Measured in Chromium against the built package: 30 pointermoves over the map, zero change detection passes; one click, one repaint.

The imperative API

Camera moves, drilldown, export and diagnostics are methods rather than options. The component exposes the live instance as a signal:

@Component({
  template: `<apx-map #map [options]="options" />
    <button (click)="map.map()?.frameFeature('IND')">Zoom to India</button>`,
  imports: [ApexMapsComponent],
  standalone: true,
})

map() is null until the first render completes and after destroy, so an effect() on it is the way to run something once the map exists.

What it does with your inputs

Bindings are compared deeply, not by reference, because a template expression like [options]="build()" hands over a brand new object on every change detection cycle. A fresh but equal tree is not a redraw; an inline formatter is compared by source rather than identity; geo.map is compared by identity and never walked (pass a stable reference or a pack id). A series-only change routes to updateSeries, which tweens; everything else to updateOptions.

Signal inputs do not fire on in-place mutation, so prefer replacing objects. If something else later changes any input, an earlier in-place mutation is picked up with it rather than lost.

Sizing

Use the width and height inputs, not CSS. The map's height comes from options.chart.height, which defaults to 400, and an explicit number wins over the container; width defaults to '100%' and follows the container. height="100%" hands the height to the container:

<apx-map [options]="options" height="100%" style="height: 60vh" />

The <apx-map> element is yours: class and style bindings land there (it is display: block by default). The element inside it belongs to the map.

SSR

Safe under Angular SSR and hydration: the component renders its container on the server and builds the map in afterNextRender, which only ever runs in the browser. There is no server-rendered map markup yet, because the core has no HTML output path.