@ngx-km/path-drawing 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # @ngx-km/path-drawing
2
+
3
+ SVG path rendering component for Angular graph visualization.
4
+
5
+ ## Features
6
+
7
+ - SVG path rendering from waypoints
8
+ - Support for orthogonal, bezier, and straight paths
9
+ - Configurable stroke color, width, and dash patterns
10
+ - Arrow head markers (multiple styles)
11
+ - Arrow rotation based on path direction
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @ngx-km/path-drawing
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```typescript
22
+ import { PathComponent } from '@ngx-km/path-drawing';
23
+
24
+ @Component({
25
+ imports: [PathComponent],
26
+ template: `
27
+ <ngx-path
28
+ [waypoints]="waypoints"
29
+ [style]="pathStyle">
30
+ </ngx-path>
31
+ `
32
+ })
33
+ export class MyComponent {}
34
+ ```
35
+
36
+ ## Running unit tests
37
+
38
+ ```bash
39
+ nx test ngx-path-drawing
40
+ ```
@@ -0,0 +1,276 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, computed, NO_ERRORS_SCHEMA, Component } from '@angular/core';
3
+
4
+ /**
5
+ * Path Drawing Models
6
+ *
7
+ * Types and interfaces for SVG path rendering with arrows and styling.
8
+ */
9
+ /**
10
+ * Default path style
11
+ */
12
+ const DEFAULT_PATH_STYLE = {
13
+ strokeColor: '#6366f1',
14
+ strokeWidth: 2,
15
+ strokePattern: 'solid',
16
+ strokeDasharray: '',
17
+ strokeOpacity: 1,
18
+ };
19
+ /**
20
+ * Default arrow configuration
21
+ */
22
+ const DEFAULT_ARROW_CONFIG = {
23
+ style: 'filled',
24
+ size: 10,
25
+ position: 'end',
26
+ color: '',
27
+ };
28
+
29
+ /**
30
+ * SVG Path Component
31
+ *
32
+ * Renders an SVG path from waypoints with configurable styling and arrows.
33
+ * Supports orthogonal (right-angle), bezier (curved), and straight paths.
34
+ *
35
+ * @example
36
+ * ```html
37
+ * <svg>
38
+ * <g ngx-path [config]="pathConfig"></g>
39
+ * </svg>
40
+ * ```
41
+ */
42
+ class PathComponent {
43
+ /** Path configuration */
44
+ config = input.required(...(ngDevMode ? [{ debugName: "config" }] : []));
45
+ /** Computed path ID */
46
+ pathId = computed(() => this.config().id, ...(ngDevMode ? [{ debugName: "pathId" }] : []));
47
+ /** Unique marker ID for this path */
48
+ markerId = computed(() => `arrow-${this.pathId()}`, ...(ngDevMode ? [{ debugName: "markerId" }] : []));
49
+ /** Merged style with defaults */
50
+ style = computed(() => ({
51
+ ...DEFAULT_PATH_STYLE,
52
+ ...this.config().style,
53
+ }), ...(ngDevMode ? [{ debugName: "style" }] : []));
54
+ /** Merged arrow config with defaults */
55
+ arrow = computed(() => ({
56
+ ...DEFAULT_ARROW_CONFIG,
57
+ ...this.config().arrow,
58
+ }), ...(ngDevMode ? [{ debugName: "arrow" }] : []));
59
+ /** Whether to show arrow markers */
60
+ showArrow = computed(() => {
61
+ const arrow = this.arrow();
62
+ return arrow.style !== 'none' && arrow.position !== 'none';
63
+ }, ...(ngDevMode ? [{ debugName: "showArrow" }] : []));
64
+ /** Arrow style */
65
+ arrowStyle = computed(() => this.arrow().style, ...(ngDevMode ? [{ debugName: "arrowStyle" }] : []));
66
+ /** Arrow color (defaults to stroke color) */
67
+ arrowColor = computed(() => this.arrow().color || this.style().strokeColor, ...(ngDevMode ? [{ debugName: "arrowColor" }] : []));
68
+ /** Arrow refX based on size */
69
+ arrowRefX = computed(() => this.arrow().size, ...(ngDevMode ? [{ debugName: "arrowRefX" }] : []));
70
+ /** Stroke color */
71
+ strokeColor = computed(() => this.style().strokeColor, ...(ngDevMode ? [{ debugName: "strokeColor" }] : []));
72
+ /** Stroke width */
73
+ strokeWidth = computed(() => this.style().strokeWidth, ...(ngDevMode ? [{ debugName: "strokeWidth" }] : []));
74
+ /** Stroke opacity */
75
+ strokeOpacity = computed(() => this.style().strokeOpacity, ...(ngDevMode ? [{ debugName: "strokeOpacity" }] : []));
76
+ /** Stroke dasharray pattern */
77
+ strokeDasharray = computed(() => {
78
+ const style = this.style();
79
+ if (style.strokeDasharray) {
80
+ return style.strokeDasharray;
81
+ }
82
+ switch (style.strokePattern) {
83
+ case 'dashed':
84
+ return '8,4';
85
+ case 'dotted':
86
+ return '2,4';
87
+ case 'solid':
88
+ default:
89
+ return '';
90
+ }
91
+ }, ...(ngDevMode ? [{ debugName: "strokeDasharray" }] : []));
92
+ /** Marker end URL */
93
+ markerEnd = computed(() => {
94
+ const arrow = this.arrow();
95
+ if (arrow.style === 'none' || arrow.position === 'none')
96
+ return '';
97
+ if (arrow.position === 'end' || arrow.position === 'both') {
98
+ return `url(#${this.markerId()})`;
99
+ }
100
+ return '';
101
+ }, ...(ngDevMode ? [{ debugName: "markerEnd" }] : []));
102
+ /** Marker start URL */
103
+ markerStart = computed(() => {
104
+ const arrow = this.arrow();
105
+ if (arrow.style === 'none' || arrow.position === 'none')
106
+ return '';
107
+ if (arrow.position === 'start' || arrow.position === 'both') {
108
+ return `url(#${this.markerId()})`;
109
+ }
110
+ return '';
111
+ }, ...(ngDevMode ? [{ debugName: "markerStart" }] : []));
112
+ /** SVG path 'd' attribute */
113
+ pathD = computed(() => {
114
+ const config = this.config();
115
+ const waypoints = config.waypoints;
116
+ if (!waypoints || waypoints.length === 0) {
117
+ return '';
118
+ }
119
+ switch (config.pathType) {
120
+ case 'bezier':
121
+ return this.generateBezierPath(waypoints);
122
+ case 'straight':
123
+ return this.generateStraightPath(waypoints);
124
+ case 'orthogonal':
125
+ default:
126
+ return this.generateOrthogonalPath(waypoints);
127
+ }
128
+ }, ...(ngDevMode ? [{ debugName: "pathD" }] : []));
129
+ /**
130
+ * Generate SVG path for orthogonal (polyline) paths
131
+ */
132
+ generateOrthogonalPath(waypoints) {
133
+ const nonControlPoints = waypoints.filter(w => !w.isControlPoint);
134
+ if (nonControlPoints.length === 0)
135
+ return '';
136
+ return nonControlPoints
137
+ .map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x} ${p.y}`)
138
+ .join(' ');
139
+ }
140
+ /**
141
+ * Generate SVG path for bezier curves
142
+ */
143
+ generateBezierPath(waypoints) {
144
+ if (waypoints.length < 2)
145
+ return '';
146
+ // For bezier, expect: [start, controlPoint1, controlPoint2, end]
147
+ if (waypoints.length === 4) {
148
+ const [start, cp1, cp2, end] = waypoints;
149
+ return `M ${start.x} ${start.y} C ${cp1.x} ${cp1.y}, ${cp2.x} ${cp2.y}, ${end.x} ${end.y}`;
150
+ }
151
+ // For quadratic bezier: [start, controlPoint, end]
152
+ if (waypoints.length === 3) {
153
+ const [start, cp, end] = waypoints;
154
+ return `M ${start.x} ${start.y} Q ${cp.x} ${cp.y}, ${end.x} ${end.y}`;
155
+ }
156
+ // Fallback to straight line if not enough points
157
+ return this.generateStraightPath(waypoints);
158
+ }
159
+ /**
160
+ * Generate SVG path for straight lines
161
+ */
162
+ generateStraightPath(waypoints) {
163
+ const nonControlPoints = waypoints.filter(w => !w.isControlPoint);
164
+ if (nonControlPoints.length < 2)
165
+ return '';
166
+ const start = nonControlPoints[0];
167
+ const end = nonControlPoints[nonControlPoints.length - 1];
168
+ return `M ${start.x} ${start.y} L ${end.x} ${end.y}`;
169
+ }
170
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PathComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
171
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: PathComponent, isStandalone: true, selector: "g[ngx-path]", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: `
172
+ <!-- Arrow marker definition -->
173
+ @if (showArrow()) {
174
+ <defs>
175
+ <marker
176
+ [id]="markerId()"
177
+ markerWidth="10"
178
+ markerHeight="10"
179
+ [attr.refX]="arrowRefX()"
180
+ refY="5"
181
+ orient="auto-start-reverse"
182
+ markerUnits="userSpaceOnUse"
183
+ >
184
+ @if (arrowStyle() === 'filled') {
185
+ <polygon
186
+ points="0,0 10,5 0,10"
187
+ [attr.fill]="arrowColor()"
188
+ />
189
+ } @else if (arrowStyle() === 'outline') {
190
+ <polyline
191
+ points="0,0 10,5 0,10"
192
+ fill="none"
193
+ [attr.stroke]="arrowColor()"
194
+ stroke-width="1.5"
195
+ />
196
+ }
197
+ </marker>
198
+ </defs>
199
+ }
200
+
201
+ <!-- Main path -->
202
+ <path
203
+ [attr.d]="pathD()"
204
+ fill="none"
205
+ [attr.stroke]="strokeColor()"
206
+ [attr.stroke-width]="strokeWidth()"
207
+ [attr.stroke-dasharray]="strokeDasharray()"
208
+ [attr.stroke-opacity]="strokeOpacity()"
209
+ [attr.marker-end]="markerEnd()"
210
+ [attr.marker-start]="markerStart()"
211
+ stroke-linecap="round"
212
+ stroke-linejoin="round"
213
+ />
214
+ `, isInline: true });
215
+ }
216
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PathComponent, decorators: [{
217
+ type: Component,
218
+ args: [{
219
+ selector: 'g[ngx-path]',
220
+ standalone: true,
221
+ schemas: [NO_ERRORS_SCHEMA],
222
+ template: `
223
+ <!-- Arrow marker definition -->
224
+ @if (showArrow()) {
225
+ <defs>
226
+ <marker
227
+ [id]="markerId()"
228
+ markerWidth="10"
229
+ markerHeight="10"
230
+ [attr.refX]="arrowRefX()"
231
+ refY="5"
232
+ orient="auto-start-reverse"
233
+ markerUnits="userSpaceOnUse"
234
+ >
235
+ @if (arrowStyle() === 'filled') {
236
+ <polygon
237
+ points="0,0 10,5 0,10"
238
+ [attr.fill]="arrowColor()"
239
+ />
240
+ } @else if (arrowStyle() === 'outline') {
241
+ <polyline
242
+ points="0,0 10,5 0,10"
243
+ fill="none"
244
+ [attr.stroke]="arrowColor()"
245
+ stroke-width="1.5"
246
+ />
247
+ }
248
+ </marker>
249
+ </defs>
250
+ }
251
+
252
+ <!-- Main path -->
253
+ <path
254
+ [attr.d]="pathD()"
255
+ fill="none"
256
+ [attr.stroke]="strokeColor()"
257
+ [attr.stroke-width]="strokeWidth()"
258
+ [attr.stroke-dasharray]="strokeDasharray()"
259
+ [attr.stroke-opacity]="strokeOpacity()"
260
+ [attr.marker-end]="markerEnd()"
261
+ [attr.marker-start]="markerStart()"
262
+ stroke-linecap="round"
263
+ stroke-linejoin="round"
264
+ />
265
+ `,
266
+ }]
267
+ }], propDecorators: { config: [{ type: i0.Input, args: [{ isSignal: true, alias: "config", required: true }] }] } });
268
+
269
+ // Models - Values
270
+
271
+ /**
272
+ * Generated bundle index. Do not edit.
273
+ */
274
+
275
+ export { DEFAULT_ARROW_CONFIG, DEFAULT_PATH_STYLE, PathComponent };
276
+ //# sourceMappingURL=ngx-km-path-drawing.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-km-path-drawing.mjs","sources":["../../../../libs/ngx-km-path-drawing/src/lib/models/path-drawing.models.ts","../../../../libs/ngx-km-path-drawing/src/lib/components/path.component.ts","../../../../libs/ngx-km-path-drawing/src/index.ts","../../../../libs/ngx-km-path-drawing/src/ngx-km-path-drawing.ts"],"sourcesContent":["/**\n * Path Drawing Models\n *\n * Types and interfaces for SVG path rendering with arrows and styling.\n */\n\n/**\n * Type of path to render\n */\nexport type PathType = 'orthogonal' | 'bezier' | 'straight';\n\n/**\n * Stroke dash pattern for paths\n */\nexport type StrokePattern = 'solid' | 'dashed' | 'dotted';\n\n/**\n * Arrow style for path endpoints\n */\nexport type ArrowStyle = 'filled' | 'outline' | 'none';\n\n/**\n * Position where arrow should be placed\n */\nexport type ArrowPosition = 'start' | 'end' | 'both' | 'none';\n\n/**\n * A point in 2D space\n */\nexport interface Point {\n x: number;\n y: number;\n}\n\n/**\n * A waypoint along a path (can be a control point for bezier curves)\n */\nexport interface PathWaypoint extends Point {\n /** Indicates if this is a bezier control point */\n isControlPoint?: boolean;\n}\n\n/**\n * Styling options for a path\n */\nexport interface PathStyle {\n /** Stroke color (CSS color string) */\n strokeColor?: string;\n /** Stroke width in pixels */\n strokeWidth?: number;\n /** Stroke dash pattern */\n strokePattern?: StrokePattern;\n /** Custom dash array (overrides strokePattern) */\n strokeDasharray?: string;\n /** Stroke opacity (0-1) */\n strokeOpacity?: number;\n}\n\n/**\n * Arrow configuration\n */\nexport interface ArrowConfig {\n /** Arrow style */\n style?: ArrowStyle;\n /** Arrow size (length) */\n size?: number;\n /** Where to place arrows */\n position?: ArrowPosition;\n /** Arrow fill color (defaults to stroke color) */\n color?: string;\n}\n\n/**\n * Configuration for rendering a path\n */\nexport interface PathConfig {\n /** Unique identifier for this path */\n id: string;\n /** Type of path to render */\n pathType: PathType;\n /** Waypoints forming the path */\n waypoints: PathWaypoint[];\n /** Path styling */\n style?: PathStyle;\n /** Arrow configuration */\n arrow?: ArrowConfig;\n}\n\n/**\n * Default path style\n */\nexport const DEFAULT_PATH_STYLE: Required<PathStyle> = {\n strokeColor: '#6366f1',\n strokeWidth: 2,\n strokePattern: 'solid',\n strokeDasharray: '',\n strokeOpacity: 1,\n};\n\n/**\n * Default arrow configuration\n */\nexport const DEFAULT_ARROW_CONFIG: Required<ArrowConfig> = {\n style: 'filled',\n size: 10,\n position: 'end',\n color: '',\n};\n\n/**\n * SVG path data result\n */\nexport interface PathData {\n /** The SVG path 'd' attribute value */\n d: string;\n /** The path type used */\n pathType: PathType;\n}\n","import { Component, input, computed, NO_ERRORS_SCHEMA } from '@angular/core';\nimport {\n PathConfig,\n PathWaypoint,\n PathStyle,\n ArrowConfig,\n DEFAULT_PATH_STYLE,\n DEFAULT_ARROW_CONFIG,\n} from '../models/path-drawing.models';\n\n/**\n * SVG Path Component\n *\n * Renders an SVG path from waypoints with configurable styling and arrows.\n * Supports orthogonal (right-angle), bezier (curved), and straight paths.\n *\n * @example\n * ```html\n * <svg>\n * <g ngx-path [config]=\"pathConfig\"></g>\n * </svg>\n * ```\n */\n@Component({\n selector: 'g[ngx-path]',\n standalone: true,\n schemas: [NO_ERRORS_SCHEMA],\n template: `\n <!-- Arrow marker definition -->\n @if (showArrow()) {\n <defs>\n <marker\n [id]=\"markerId()\"\n markerWidth=\"10\"\n markerHeight=\"10\"\n [attr.refX]=\"arrowRefX()\"\n refY=\"5\"\n orient=\"auto-start-reverse\"\n markerUnits=\"userSpaceOnUse\"\n >\n @if (arrowStyle() === 'filled') {\n <polygon\n points=\"0,0 10,5 0,10\"\n [attr.fill]=\"arrowColor()\"\n />\n } @else if (arrowStyle() === 'outline') {\n <polyline\n points=\"0,0 10,5 0,10\"\n fill=\"none\"\n [attr.stroke]=\"arrowColor()\"\n stroke-width=\"1.5\"\n />\n }\n </marker>\n </defs>\n }\n\n <!-- Main path -->\n <path\n [attr.d]=\"pathD()\"\n fill=\"none\"\n [attr.stroke]=\"strokeColor()\"\n [attr.stroke-width]=\"strokeWidth()\"\n [attr.stroke-dasharray]=\"strokeDasharray()\"\n [attr.stroke-opacity]=\"strokeOpacity()\"\n [attr.marker-end]=\"markerEnd()\"\n [attr.marker-start]=\"markerStart()\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n `,\n})\nexport class PathComponent {\n /** Path configuration */\n config = input.required<PathConfig>();\n\n /** Computed path ID */\n protected pathId = computed(() => this.config().id);\n\n /** Unique marker ID for this path */\n protected markerId = computed(() => `arrow-${this.pathId()}`);\n\n /** Merged style with defaults */\n protected style = computed((): Required<PathStyle> => ({\n ...DEFAULT_PATH_STYLE,\n ...this.config().style,\n }));\n\n /** Merged arrow config with defaults */\n protected arrow = computed((): Required<ArrowConfig> => ({\n ...DEFAULT_ARROW_CONFIG,\n ...this.config().arrow,\n }));\n\n /** Whether to show arrow markers */\n protected showArrow = computed(() => {\n const arrow = this.arrow();\n return arrow.style !== 'none' && arrow.position !== 'none';\n });\n\n /** Arrow style */\n protected arrowStyle = computed(() => this.arrow().style);\n\n /** Arrow color (defaults to stroke color) */\n protected arrowColor = computed(() =>\n this.arrow().color || this.style().strokeColor\n );\n\n /** Arrow refX based on size */\n protected arrowRefX = computed(() => this.arrow().size);\n\n /** Stroke color */\n protected strokeColor = computed(() => this.style().strokeColor);\n\n /** Stroke width */\n protected strokeWidth = computed(() => this.style().strokeWidth);\n\n /** Stroke opacity */\n protected strokeOpacity = computed(() => this.style().strokeOpacity);\n\n /** Stroke dasharray pattern */\n protected strokeDasharray = computed(() => {\n const style = this.style();\n if (style.strokeDasharray) {\n return style.strokeDasharray;\n }\n switch (style.strokePattern) {\n case 'dashed':\n return '8,4';\n case 'dotted':\n return '2,4';\n case 'solid':\n default:\n return '';\n }\n });\n\n /** Marker end URL */\n protected markerEnd = computed(() => {\n const arrow = this.arrow();\n if (arrow.style === 'none' || arrow.position === 'none') return '';\n if (arrow.position === 'end' || arrow.position === 'both') {\n return `url(#${this.markerId()})`;\n }\n return '';\n });\n\n /** Marker start URL */\n protected markerStart = computed(() => {\n const arrow = this.arrow();\n if (arrow.style === 'none' || arrow.position === 'none') return '';\n if (arrow.position === 'start' || arrow.position === 'both') {\n return `url(#${this.markerId()})`;\n }\n return '';\n });\n\n /** SVG path 'd' attribute */\n protected pathD = computed(() => {\n const config = this.config();\n const waypoints = config.waypoints;\n\n if (!waypoints || waypoints.length === 0) {\n return '';\n }\n\n switch (config.pathType) {\n case 'bezier':\n return this.generateBezierPath(waypoints);\n case 'straight':\n return this.generateStraightPath(waypoints);\n case 'orthogonal':\n default:\n return this.generateOrthogonalPath(waypoints);\n }\n });\n\n /**\n * Generate SVG path for orthogonal (polyline) paths\n */\n private generateOrthogonalPath(waypoints: PathWaypoint[]): string {\n const nonControlPoints = waypoints.filter(w => !w.isControlPoint);\n if (nonControlPoints.length === 0) return '';\n\n return nonControlPoints\n .map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x} ${p.y}`)\n .join(' ');\n }\n\n /**\n * Generate SVG path for bezier curves\n */\n private generateBezierPath(waypoints: PathWaypoint[]): string {\n if (waypoints.length < 2) return '';\n\n // For bezier, expect: [start, controlPoint1, controlPoint2, end]\n if (waypoints.length === 4) {\n const [start, cp1, cp2, end] = waypoints;\n return `M ${start.x} ${start.y} C ${cp1.x} ${cp1.y}, ${cp2.x} ${cp2.y}, ${end.x} ${end.y}`;\n }\n\n // For quadratic bezier: [start, controlPoint, end]\n if (waypoints.length === 3) {\n const [start, cp, end] = waypoints;\n return `M ${start.x} ${start.y} Q ${cp.x} ${cp.y}, ${end.x} ${end.y}`;\n }\n\n // Fallback to straight line if not enough points\n return this.generateStraightPath(waypoints);\n }\n\n /**\n * Generate SVG path for straight lines\n */\n private generateStraightPath(waypoints: PathWaypoint[]): string {\n const nonControlPoints = waypoints.filter(w => !w.isControlPoint);\n if (nonControlPoints.length < 2) return '';\n\n const start = nonControlPoints[0];\n const end = nonControlPoints[nonControlPoints.length - 1];\n\n return `M ${start.x} ${start.y} L ${end.x} ${end.y}`;\n }\n}\n","// Models - Types\nexport type {\n PathType,\n StrokePattern,\n ArrowStyle,\n ArrowPosition,\n Point,\n PathWaypoint,\n PathStyle,\n ArrowConfig,\n PathConfig,\n PathData,\n} from './lib/models/path-drawing.models';\n\n// Models - Values\nexport {\n DEFAULT_PATH_STYLE,\n DEFAULT_ARROW_CONFIG,\n} from './lib/models/path-drawing.models';\n\n// Components\nexport { PathComponent } from './lib/components/path.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,163 @@
1
+ import * as _ngx_km_path_drawing from '@ngx-km/path-drawing';
2
+ import * as _angular_core from '@angular/core';
3
+
4
+ /**
5
+ * Path Drawing Models
6
+ *
7
+ * Types and interfaces for SVG path rendering with arrows and styling.
8
+ */
9
+ /**
10
+ * Type of path to render
11
+ */
12
+ type PathType = 'orthogonal' | 'bezier' | 'straight';
13
+ /**
14
+ * Stroke dash pattern for paths
15
+ */
16
+ type StrokePattern = 'solid' | 'dashed' | 'dotted';
17
+ /**
18
+ * Arrow style for path endpoints
19
+ */
20
+ type ArrowStyle = 'filled' | 'outline' | 'none';
21
+ /**
22
+ * Position where arrow should be placed
23
+ */
24
+ type ArrowPosition = 'start' | 'end' | 'both' | 'none';
25
+ /**
26
+ * A point in 2D space
27
+ */
28
+ interface Point {
29
+ x: number;
30
+ y: number;
31
+ }
32
+ /**
33
+ * A waypoint along a path (can be a control point for bezier curves)
34
+ */
35
+ interface PathWaypoint extends Point {
36
+ /** Indicates if this is a bezier control point */
37
+ isControlPoint?: boolean;
38
+ }
39
+ /**
40
+ * Styling options for a path
41
+ */
42
+ interface PathStyle {
43
+ /** Stroke color (CSS color string) */
44
+ strokeColor?: string;
45
+ /** Stroke width in pixels */
46
+ strokeWidth?: number;
47
+ /** Stroke dash pattern */
48
+ strokePattern?: StrokePattern;
49
+ /** Custom dash array (overrides strokePattern) */
50
+ strokeDasharray?: string;
51
+ /** Stroke opacity (0-1) */
52
+ strokeOpacity?: number;
53
+ }
54
+ /**
55
+ * Arrow configuration
56
+ */
57
+ interface ArrowConfig {
58
+ /** Arrow style */
59
+ style?: ArrowStyle;
60
+ /** Arrow size (length) */
61
+ size?: number;
62
+ /** Where to place arrows */
63
+ position?: ArrowPosition;
64
+ /** Arrow fill color (defaults to stroke color) */
65
+ color?: string;
66
+ }
67
+ /**
68
+ * Configuration for rendering a path
69
+ */
70
+ interface PathConfig {
71
+ /** Unique identifier for this path */
72
+ id: string;
73
+ /** Type of path to render */
74
+ pathType: PathType;
75
+ /** Waypoints forming the path */
76
+ waypoints: PathWaypoint[];
77
+ /** Path styling */
78
+ style?: PathStyle;
79
+ /** Arrow configuration */
80
+ arrow?: ArrowConfig;
81
+ }
82
+ /**
83
+ * Default path style
84
+ */
85
+ declare const DEFAULT_PATH_STYLE: Required<PathStyle>;
86
+ /**
87
+ * Default arrow configuration
88
+ */
89
+ declare const DEFAULT_ARROW_CONFIG: Required<ArrowConfig>;
90
+ /**
91
+ * SVG path data result
92
+ */
93
+ interface PathData {
94
+ /** The SVG path 'd' attribute value */
95
+ d: string;
96
+ /** The path type used */
97
+ pathType: PathType;
98
+ }
99
+
100
+ /**
101
+ * SVG Path Component
102
+ *
103
+ * Renders an SVG path from waypoints with configurable styling and arrows.
104
+ * Supports orthogonal (right-angle), bezier (curved), and straight paths.
105
+ *
106
+ * @example
107
+ * ```html
108
+ * <svg>
109
+ * <g ngx-path [config]="pathConfig"></g>
110
+ * </svg>
111
+ * ```
112
+ */
113
+ declare class PathComponent {
114
+ /** Path configuration */
115
+ config: _angular_core.InputSignal<PathConfig>;
116
+ /** Computed path ID */
117
+ protected pathId: _angular_core.Signal<string>;
118
+ /** Unique marker ID for this path */
119
+ protected markerId: _angular_core.Signal<string>;
120
+ /** Merged style with defaults */
121
+ protected style: _angular_core.Signal<Required<PathStyle>>;
122
+ /** Merged arrow config with defaults */
123
+ protected arrow: _angular_core.Signal<Required<ArrowConfig>>;
124
+ /** Whether to show arrow markers */
125
+ protected showArrow: _angular_core.Signal<boolean>;
126
+ /** Arrow style */
127
+ protected arrowStyle: _angular_core.Signal<_ngx_km_path_drawing.ArrowStyle>;
128
+ /** Arrow color (defaults to stroke color) */
129
+ protected arrowColor: _angular_core.Signal<string>;
130
+ /** Arrow refX based on size */
131
+ protected arrowRefX: _angular_core.Signal<number>;
132
+ /** Stroke color */
133
+ protected strokeColor: _angular_core.Signal<string>;
134
+ /** Stroke width */
135
+ protected strokeWidth: _angular_core.Signal<number>;
136
+ /** Stroke opacity */
137
+ protected strokeOpacity: _angular_core.Signal<number>;
138
+ /** Stroke dasharray pattern */
139
+ protected strokeDasharray: _angular_core.Signal<string>;
140
+ /** Marker end URL */
141
+ protected markerEnd: _angular_core.Signal<string>;
142
+ /** Marker start URL */
143
+ protected markerStart: _angular_core.Signal<string>;
144
+ /** SVG path 'd' attribute */
145
+ protected pathD: _angular_core.Signal<string>;
146
+ /**
147
+ * Generate SVG path for orthogonal (polyline) paths
148
+ */
149
+ private generateOrthogonalPath;
150
+ /**
151
+ * Generate SVG path for bezier curves
152
+ */
153
+ private generateBezierPath;
154
+ /**
155
+ * Generate SVG path for straight lines
156
+ */
157
+ private generateStraightPath;
158
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<PathComponent, never>;
159
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<PathComponent, "g[ngx-path]", never, { "config": { "alias": "config"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
160
+ }
161
+
162
+ export { DEFAULT_ARROW_CONFIG, DEFAULT_PATH_STYLE, PathComponent };
163
+ export type { ArrowConfig, ArrowPosition, ArrowStyle, PathConfig, PathData, PathStyle, PathType, PathWaypoint, Point, StrokePattern };
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@ngx-km/path-drawing",
3
+ "version": "0.0.1",
4
+ "peerDependencies": {
5
+ "@angular/common": ">=19.0.0",
6
+ "@angular/core": ">=19.0.0"
7
+ },
8
+ "sideEffects": false,
9
+ "module": "fesm2022/ngx-km-path-drawing.mjs",
10
+ "typings": "index.d.ts",
11
+ "exports": {
12
+ "./package.json": {
13
+ "default": "./package.json"
14
+ },
15
+ ".": {
16
+ "types": "./index.d.ts",
17
+ "default": "./fesm2022/ngx-km-path-drawing.mjs"
18
+ }
19
+ },
20
+ "dependencies": {
21
+ "tslib": "^2.3.0"
22
+ }
23
+ }