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

@d3-polytree/core

v0.5.1

Published

Core diagram engine for the d3-polytree v2 ecosystem (draw/features/modelling) — carved from core-v2beta in B3

Readme

@d3-polytree/core

The diagram engine for the d3-polytree v2 ecosystem. It wires the base canvas (@d3-polytree/canvas) and the PFDN model (@d3-polytree/pfdn-moddle) into the didi module stack the components build on, running on slim, modular D3 v7 peer dependencies.

Most applications consume the engine through a component (viewer, interactive-viewer, editor) rather than directly — but every drawer and feature is a didi module you can compose à la carte.

Install

pnpm add @d3-polytree/core \
  d3-selection d3-zoom d3-transition d3-scale d3-axis d3-drag

The six D3 v7 slices are peer dependencies — the engine imports only the functions it needs and lets the host own the D3 version. @d3-polytree/canvas, @d3-polytree/layout, and @d3-polytree/pfdn-moddle come along as bundled workspace dependencies.

What's inside

  • draw/ — the drawers (nodes, links, labels, zones), the icon loader + base icon set, markers, <defs>, and the DrawingRegistry. A node draws as a <use> of an SVG symbol keyed by its type (iconLoader.symbolHref(type)) and sized by its size attribute.
  • model/ — the model provider and settings normalisation (loadModel, loadModelFromJson, emptyModel, ModelHost).
  • modelling/ — the four element handlers and the create/save/delete orchestrator.
  • features/* — pan/zoom, grid/axes, background, mouse events, selection, outline, drag, export, localStorage, upload, the palette (toolbar + add-handlers + link tool), resize, tooltip, and notifications — each a standalone didi module.

Usage

Boot the engine directly

import { Diagram, loadModel, nodesModule, linksModule, labelsModule, zonesModule } from '@d3-polytree/core';

const host = await loadModel(pfdnXml);                 // { definitions, moddle }
const diagram = new Diagram({
  container: document.getElementById('app')!,
  modules: [
    labelsModule, zonesModule, linksModule, nodesModule,
    { d3polytree: ['value', host] }                    // drawers resolve the model off this token
  ]
});

const eventBus = diagram.get('eventBus');
eventBus.on('selection.changed', (prev, next) => console.log(next));

Load from typed JSON

import { loadModelFromJson } from '@d3-polytree/core';
import { validate } from '@d3-polytree/pfdn-moddle';

if (validate(doc).ok) {
  const host = await loadModelFromJson(doc); // JSON twin of loadModel — throws on invalid input
}

Dependency injection (didi)

The engine is a module list, not a monolith. A module is a plain object — { __init__: ['svc'], __depends__: [otherModule], svc: ['type'|'factory'|'value', X] } — and two invariants govern composition:

  1. Last definition of a token wins. Composing a module after the core modules overrides that token. This is the single extension seam: caller modules are appended after the component's own, and icon packs rely on it.
  2. Boot order = event-subscription order. Drawers emit <class>.created (node.created, link.created, …) during boot; any feature that must see those initial elements (selection, outline, search) has to be registered before the drawer modules.

Key exports

Diagram, coreModules, loadModel, loadModelFromJson, emptyModel, ModelHost; the drawer modules (nodesModule, linksModule, labelsModule, zonesModule); the feature modules (zoomModule, zoomScrollModule, axesModule, backgroundColorModule, mouseEventsModule, selectionModule, outlineModule, dragModule, exportingModule, localStorageModule, uploadModule, paletteModule, resizeElementModule, autoLayoutModule, …); createIcons and the icon-pack convention; plus a broad set of TypeScript types (DiagramModule, DiagramEventMap, CreateParameters, CommandStack, Selection, DrawingRegistry, LayoutOptions, …).

Links

License

MIT © David Castillo