{"_id":"@bravobit/ng-org-chart","_rev":"3-af53ed3b9780281bbb81198cd0135786","name":"@bravobit/ng-org-chart","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"@bravobit/ng-org-chart","version":"1.0.0","author":{"url":"https://bravobit.nl","name":"Stan van Heumen","email":"stan@bravobit.nl"},"license":"SEE LICENSE IN LICENSE","_id":"@bravobit/ng-org-chart@1.0.0","maintainers":[{"name":"stanvanheumen","email":"stanvanheumen@gmail.com"}],"dist":{"shasum":"9e0ab57ceeeb3f1392519fe52ab665c0141edc7a","tarball":"https://registry.npmjs.org/@bravobit/ng-org-chart/-/ng-org-chart-1.0.0.tgz","fileCount":6,"integrity":"sha512-6a9jguQP2bWWbwOaMY095MSo/RDUCGlbTHLnd1uV7K+gknRaQqSlK049qfVR03bgsf0qFHqyiiKmVPCx62txww==","signatures":[{"sig":"MEQCIBfwqQyF6woFK3SzrFIGJOBCvbmWjyfzGS9FUT2qK+4HAiB9a12n0t1sowS5BtPVLWgUIpnxkl5yN2WGlGX7eTANcw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57027},"type":"module","module":"fesm2022/bravobit-ng-org-chart.mjs","exports":{".":{"types":"./types/bravobit-ng-org-chart.d.ts","default":"./fesm2022/bravobit-ng-org-chart.mjs"},"./package.json":{"default":"./package.json"}},"typings":"types/bravobit-ng-org-chart.d.ts","_npmUser":{"name":"stanvanheumen","email":"stanvanheumen@gmail.com"},"_npmVersion":"11.18.0","description":"Angular wrapper around @bravobit/org-chart: declarative org/ownership charts with template-based nodes.","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","dependencies":{"tslib":"^2.3.0","@bravobit/org-chart":"^1.0.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":"^22.0.0","@angular/common":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-org-chart_1.0.0_1783358963520_0.5218749154704208","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@bravobit/ng-org-chart","version":"1.0.1","author":{"url":"https://bravobit.nl","name":"Stan van Heumen","email":"stan@bravobit.nl"},"license":"SEE LICENSE IN LICENSE","_id":"@bravobit/ng-org-chart@1.0.1","maintainers":[{"name":"stanvanheumen","email":"stanvanheumen@gmail.com"}],"dist":{"shasum":"b600b3d9e35a56bce22f20afb8434fd7db628a66","tarball":"https://registry.npmjs.org/@bravobit/ng-org-chart/-/ng-org-chart-1.0.1.tgz","fileCount":6,"integrity":"sha512-FKGqTlrr1RSmENGXu+IjilFhd3xQkPaiUod3R8BTN8fLD2/lUmK0nha6W1LwQIkGIZWdLgDZv2Y/MzL03mbtAw==","signatures":[{"sig":"MEQCIF9QOAzDE9fEQhu8gHyvNQOhDJCSSWRp5Of2DumR9ZdQAiBG7+i8+n6YkEogjneoW/IfZ+wLk4+/vpAxpVWdfHt4RA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57027},"type":"module","module":"fesm2022/bravobit-ng-org-chart.mjs","exports":{".":{"types":"./types/bravobit-ng-org-chart.d.ts","default":"./fesm2022/bravobit-ng-org-chart.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"9db595c0401651f31869fb47b3a79713f67c8489","typings":"types/bravobit-ng-org-chart.d.ts","_npmUser":{"name":"stanvanheumen","email":"stanvanheumen@gmail.com"},"_npmVersion":"11.18.0","description":"Angular wrapper around @bravobit/org-chart: declarative org/ownership charts with template-based nodes.","directories":{},"sideEffects":false,"_nodeVersion":"24.16.0","dependencies":{"tslib":"^2.3.0","@bravobit/org-chart":"^1.0.1"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":"^22.0.0","@angular/common":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-org-chart_1.0.1_1783362103428_0.3704510553173266","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@bravobit/ng-org-chart","version":"1.0.2","author":{"name":"Stan van Heumen","email":"stan@bravobit.nl","url":"https://bravobit.nl"},"license":"SEE LICENSE IN LICENSE","description":"Angular wrapper around @bravobit/org-chart: declarative org/ownership charts with template-based nodes.","peerDependencies":{"@angular/common":"^22.0.0","@angular/core":"^22.0.0"},"dependencies":{"@bravobit/org-chart":"^1.0.2","tslib":"^2.3.0"},"sideEffects":false,"module":"fesm2022/bravobit-ng-org-chart.mjs","typings":"types/bravobit-ng-org-chart.d.ts","exports":{"./package.json":{"default":"./package.json"},".":{"types":"./types/bravobit-ng-org-chart.d.ts","default":"./fesm2022/bravobit-ng-org-chart.mjs"}},"type":"module","gitHead":"848d4779fc14c4afc56fb33437985a97245fd360","_id":"@bravobit/ng-org-chart@1.0.2","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-jUm0qx4IbHZSBy+H5c+zVK1Sd3ehPnU7MpProrKK0oZiv2Gb5InNP4qTAP6pHDGxnQyIvQfOFNQZZjtNpJWIaw==","shasum":"dbb32a51965dfbb937b07b1ea680beef7204fd5e","tarball":"https://registry.npmjs.org/@bravobit/ng-org-chart/-/ng-org-chart-1.0.2.tgz","fileCount":6,"unpackedSize":57027,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDZgPMYi/jA6YQuvL3lyPm2olFgatEiKyNPLqamhSkHIwIgXylx0eCdneZWZMtqk9PkF+XTBCh98RPZG8zUikWQIrk="}]},"_npmUser":{"name":"stanvanheumen","email":"stanvanheumen@gmail.com"},"directories":{},"maintainers":[{"name":"stanvanheumen","email":"stanvanheumen@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ng-org-chart_1.0.2_1783599082146_0.42504283013928523"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-06T17:29:23.374Z","modified":"2026-07-09T12:11:22.432Z","1.0.0":"2026-07-06T17:29:23.667Z","1.0.1":"2026-07-06T18:21:43.636Z","1.0.2":"2026-07-09T12:11:22.283Z"},"author":{"name":"Stan van Heumen","email":"stan@bravobit.nl","url":"https://bravobit.nl"},"license":"SEE LICENSE IN LICENSE","description":"Angular wrapper around @bravobit/org-chart: declarative org/ownership charts with template-based nodes.","maintainers":[{"name":"stanvanheumen","email":"stanvanheumen@gmail.com"}],"readme":"# @bravobit/ng-org-chart\n\nAngular wrapper around [`@bravobit/org-chart`](https://www.npmjs.com/package/@bravobit/org-chart): declarative organization/ownership charts where every node is an Angular template.\n\n- `<ng-org-chart>` is the chart: it receives the `nodes` and `edges` and hosts the viewport (pan, zoom, hover highlighting, keyboard navigation)\n- `*ngOrgChartNode` declares — per `node.type` — the template and dimensions of that node type\n- Signal-based and zoneless-ready; re-renders automatically when `nodes`, `edges` or `options` change\n- Full SSR support: on the server the chart renders through a `Renderer2`-backed DOM adapter, so the SVG is part of the HTML response (scaled via `viewBox`); the browser then rebuilds it interactively (`ngSkipHydration`)\n\n## Installation\n\n```bash\nnpm install @bravobit/ng-org-chart\n```\n\nThe core engine [`@bravobit/org-chart`](https://www.npmjs.com/package/@bravobit/org-chart) is a regular dependency and is installed automatically; its types are re-exported by this package.\n\nAdd the chart stylesheet (shipped with this package) to your global styles, e.g. in `angular.json`:\n\n```json\n\"styles\": [\n  \"src/styles.scss\",\n  \"node_modules/@bravobit/ng-org-chart/org-chart.css\"\n]\n```\n\n## Quick start\n\n```ts\nimport { Component, signal } from '@angular/core';\nimport { NgOrgChart, NgOrgChartNode, type OrgChartEdge, type OrgChartNode } from '@bravobit/ng-org-chart';\n\ninterface EntityData {\n  label: string;\n}\n\n@Component({\n  selector: 'app-structure',\n  imports: [NgOrgChart, NgOrgChartNode],\n  template: `\n    <ng-org-chart [nodes]=\"nodes()\" [edges]=\"edges()\" style=\"height: 600px\">\n      <div *ngOrgChartNode=\"'company'; typedBy: nodes(); width: 220; height: 72; let node\" class=\"card\">\n        {{ node.data.label }}\n      </div>\n      <div *ngOrgChartNode=\"'person'; typedBy: nodes(); width: 180; height: 56; let node\" class=\"card card--person\">\n        {{ node.data.label }}\n      </div>\n    </ng-org-chart>\n  `,\n})\nexport class Structure {\n  protected readonly nodes = signal<OrgChartNode<EntityData>[]>([\n    { id: 'bv', type: 'company', data: { label: 'Meridiaan B.V.' } },\n    { id: 'holding', type: 'company', data: { label: 'Holding B.V.' } },\n    { id: 'ubo', type: 'person', data: { label: 'A. de Groot' } },\n  ]);\n  // Edges point from the owned entity up to its owner ('up' is the default).\n  protected readonly edges = signal<OrgChartEdge[]>([\n    { from: 'bv', to: 'holding', label: '100%', arrow: 'from' },\n    { from: 'holding', to: 'ubo', label: '100%', arrow: 'from' },\n  ]);\n}\n```\n\nEvery `type` that appears in `nodes` needs exactly one `*ngOrgChartNode` template. The template receives the placed node as `$implicit` (`let node`) and its payload as `data` (`let data = data`).\n\n## `<ng-org-chart>` (NgOrgChart)\n\n| Input | Type | Description |\n| --- | --- | --- |\n| `nodes` | `OrgChartNode<TData>[]` | Required. The chart's nodes. |\n| `edges` | `OrgChartEdge[]` | The edges; `direction` defaults to `'up'` (toward the owner/parent). |\n| `options` | `DeepPartial<OrgChartOptions>` | Options patch (orientation, gaps, zoom, hover, `ariaLabel`, …). |\n| `autoFit` | `'first' \\| 'always' \\| 'none'` | When to scale/center automatically. Default `'first'`. |\n| `highlight` | `HighlightResolver<TData>` | Custom hover highlighting (default: direct neighbors). |\n\n| Output | Payload | Description |\n| --- | --- | --- |\n| `nodeClick` | `{ node, event }` | Click or Enter/Space on a node. |\n| `nodeHover` | `{ node \\| null, event }` | Hovered/focused node changed. |\n| `edgeClick` | `{ edge, event }` | Click on an edge or its label. |\n| `edgeHover` | `{ edge \\| null, event }` | Hovered edge changed. |\n\nMethods (via `viewChild(NgOrgChart)`): `fit(padding?)`, `zoomIn()`, `zoomOut()`, and the `chartInstance` getter as escape hatch to the underlying `OrgChart`.\n\nThe host element is the chart container — give it a size (`height`, flex, …).\n\n## `*ngOrgChartNode` (NgOrgChartNode)\n\n```html\n<div *ngOrgChartNode=\"'company'; width: 220; height: 72; typedBy: nodes(); let node; let data = data\">\n  …\n</div>\n```\n\n| Key | Description |\n| --- | --- |\n| (expression) | The `node.type` this template renders. |\n| `width` / `height` | Required. Dimensions in px of nodes of this type — the layout needs sizes up front; nothing is measured. |\n| `typedBy` | Optional, type-inference only: pass your `nodes` array to type `node.data` in the template. |\n\nContext: `$implicit` is the `PlacedNode` (id, type, data, position, `placement`, `hasParent`, …); `data` is a shortcut for `node.data`.\n\n## SSR\n\nThe chart renders on the server too — no extra setup needed. All DOM mutations go through a `DomAdapter` backed by Angular's `Renderer2`, so the same code path works on every Angular platform. Because the server cannot measure layout, the static SVG is scaled and centered with a `viewBox` capped at `fitMaxZoom` — the SSR equivalent of `fit()`. The component is marked `ngSkipHydration`: the server-rendered chart serves as the first paint, after which the browser rebuilds it interactively with real pan/zoom fitting.\n\n## Styling\n\nNodes are your own markup — style them however you want; a node's root element best fills its box (`height: 100%`). Chart colors (edges, labels, focus ring, fade) are tuned with CSS variables on the container, see the [core documentation](https://www.npmjs.com/package/@bravobit/org-chart#styling). Type-specific hooks are also available on the SVG side as `.ogc-node--<type>`.\n\n## Playground\n\nThis repository contains a playground application demonstrating everything (owners, percentages, side branches, cross links, floating nodes, dynamic data, orientation switching):\n\n```bash\nnpm start\n```\n","readmeFilename":"README.md"}