@ngroznykh/papirus 0.3.0 → 0.3.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/dist/papirus.js +74 -18
- package/dist/papirus.js.map +1 -1
- package/dist/utils/SvgExporter.d.ts +11 -1
- package/dist/utils/SvgExporter.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/papirus.js
CHANGED
|
@@ -8104,6 +8104,7 @@ class SvgExporter {
|
|
|
8104
8104
|
const padding = options.padding ?? 20;
|
|
8105
8105
|
const includeBackground = options.includeBackground ?? true;
|
|
8106
8106
|
const backgroundColor = options.backgroundColor ?? "#ffffff";
|
|
8107
|
+
const edgeLabelOffset = options.edgeLabelOffset ?? 0;
|
|
8107
8108
|
const bounds = getContentBounds({
|
|
8108
8109
|
nodes: this.renderer.nodes.values(),
|
|
8109
8110
|
edges: this.renderer.edges.values(),
|
|
@@ -8123,10 +8124,17 @@ class SvgExporter {
|
|
|
8123
8124
|
this.renderer.nodes.values()
|
|
8124
8125
|
);
|
|
8125
8126
|
const parts = [];
|
|
8127
|
+
const markerDefs = /* @__PURE__ */ new Map();
|
|
8128
|
+
const renderedEdges = [];
|
|
8126
8129
|
parts.push(
|
|
8127
8130
|
`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">`
|
|
8128
8131
|
);
|
|
8129
|
-
|
|
8132
|
+
for (const edge of this.renderer.edges.values()) {
|
|
8133
|
+
if (edge.visible) {
|
|
8134
|
+
renderedEdges.push(this.renderEdge(edge, markerDefs, edgeLabelOffset));
|
|
8135
|
+
}
|
|
8136
|
+
}
|
|
8137
|
+
parts.push(this.buildDefs(markerDefs));
|
|
8130
8138
|
if (includeBackground) {
|
|
8131
8139
|
parts.push(`<rect width="100%" height="100%" fill="${backgroundColor}"/>`);
|
|
8132
8140
|
}
|
|
@@ -8136,11 +8144,7 @@ class SvgExporter {
|
|
|
8136
8144
|
parts.push(this.renderGroup(group));
|
|
8137
8145
|
}
|
|
8138
8146
|
}
|
|
8139
|
-
|
|
8140
|
-
if (edge.visible) {
|
|
8141
|
-
parts.push(this.renderEdge(edge));
|
|
8142
|
-
}
|
|
8143
|
-
}
|
|
8147
|
+
parts.push(...renderedEdges);
|
|
8144
8148
|
for (const node of this.renderer.nodes.values()) {
|
|
8145
8149
|
if (node.visible) {
|
|
8146
8150
|
parts.push(this.renderNode(node));
|
|
@@ -8218,7 +8222,7 @@ class SvgExporter {
|
|
|
8218
8222
|
label
|
|
8219
8223
|
].join("");
|
|
8220
8224
|
}
|
|
8221
|
-
renderEdge(edge) {
|
|
8225
|
+
renderEdge(edge, markerDefs, edgeLabelOffset) {
|
|
8222
8226
|
const path = edge.path;
|
|
8223
8227
|
if (path.length < 2) {
|
|
8224
8228
|
return "";
|
|
@@ -8231,11 +8235,59 @@ class SvgExporter {
|
|
|
8231
8235
|
const dash = dashValues ? ` stroke-dasharray="${dashValues.join(" ")}"` : "";
|
|
8232
8236
|
const dashOffset = style.lineDashOffset !== void 0 ? ` stroke-dashoffset="${style.lineDashOffset}"` : "";
|
|
8233
8237
|
const d = this.buildPath(edge);
|
|
8234
|
-
const
|
|
8235
|
-
const
|
|
8236
|
-
const
|
|
8238
|
+
const startMarkerConfig = this.resolveMarkerConfig(edge, "start");
|
|
8239
|
+
const endMarkerConfig = this.resolveMarkerConfig(edge, "end");
|
|
8240
|
+
const markerStart = startMarkerConfig ? ` marker-start="url(#${this.ensureMarkerDef(markerDefs, startMarkerConfig, "start", stroke)})"` : "";
|
|
8241
|
+
const markerEnd = endMarkerConfig ? ` marker-end="url(#${this.ensureMarkerDef(markerDefs, endMarkerConfig, "end", stroke)})"` : "";
|
|
8242
|
+
const label = edge.label ? this.renderTextLabel(edge.label.text, this.getEdgeLabelPoint(edge, edgeLabelOffset), edge.label.style) : "";
|
|
8237
8243
|
return `<path d="${d}" fill="none" stroke="${stroke}" stroke-width="${strokeWidth}" opacity="${opacity}" color="${stroke}"${dash}${dashOffset}${markerStart}${markerEnd}/>${label}`;
|
|
8238
8244
|
}
|
|
8245
|
+
resolveMarkerConfig(edge, side) {
|
|
8246
|
+
const marker = side === "start" ? edge.startMarker : edge.endMarker;
|
|
8247
|
+
if (marker && marker.type !== "none") {
|
|
8248
|
+
return marker;
|
|
8249
|
+
}
|
|
8250
|
+
if (side === "end") {
|
|
8251
|
+
return edge.arrowType === "none" ? null : { type: "arrow" };
|
|
8252
|
+
}
|
|
8253
|
+
return edge.arrowType === "double" ? { type: "arrow" } : null;
|
|
8254
|
+
}
|
|
8255
|
+
ensureMarkerDef(markerDefs, marker, side, stroke) {
|
|
8256
|
+
const size = marker.size ?? 12;
|
|
8257
|
+
const markerStroke = marker.strokeColor ?? stroke;
|
|
8258
|
+
const markerFill = marker.fillColor ?? markerStroke;
|
|
8259
|
+
const fillOpacity = marker.fillOpacity ?? 1;
|
|
8260
|
+
const markerId = this.buildMarkerId(side, marker.type, size, markerFill, markerStroke, fillOpacity);
|
|
8261
|
+
if (!markerDefs.has(markerId)) {
|
|
8262
|
+
const refX = marker.type === "circle" ? 5 : 10;
|
|
8263
|
+
markerDefs.set(
|
|
8264
|
+
markerId,
|
|
8265
|
+
[
|
|
8266
|
+
`<marker id="${markerId}" viewBox="0 0 10 10" refX="${refX}" refY="5" markerWidth="${size}" markerHeight="${size}" orient="auto-start-reverse" markerUnits="userSpaceOnUse">`,
|
|
8267
|
+
this.renderMarkerShape(marker, markerFill, markerStroke, fillOpacity),
|
|
8268
|
+
`</marker>`
|
|
8269
|
+
].join("")
|
|
8270
|
+
);
|
|
8271
|
+
}
|
|
8272
|
+
return markerId;
|
|
8273
|
+
}
|
|
8274
|
+
buildMarkerId(side, type, size, fill, stroke, fillOpacity) {
|
|
8275
|
+
const token = `${side}-${type}-${size}-${fill}-${stroke}-${fillOpacity}`.toLowerCase().replace(/[^a-z0-9_-]+/g, "-");
|
|
8276
|
+
return `marker-${token}`;
|
|
8277
|
+
}
|
|
8278
|
+
renderMarkerShape(marker, fill, stroke, fillOpacity) {
|
|
8279
|
+
switch (marker.type) {
|
|
8280
|
+
case "open":
|
|
8281
|
+
return `<path d="M 10 0 L 0 5 L 10 10" fill="none" stroke="${stroke}" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>`;
|
|
8282
|
+
case "diamond":
|
|
8283
|
+
return `<path d="M 10 5 L 5 0 L 0 5 L 5 10 z" fill="${fill}" fill-opacity="${fillOpacity}" stroke="${stroke}" stroke-width="1"/>`;
|
|
8284
|
+
case "circle":
|
|
8285
|
+
return `<circle cx="5" cy="5" r="4" fill="${fill}" fill-opacity="${fillOpacity}" stroke="${stroke}" stroke-width="1"/>`;
|
|
8286
|
+
case "arrow":
|
|
8287
|
+
default:
|
|
8288
|
+
return `<path d="M 0 0 L 10 5 L 0 10 z" fill="${fill}" fill-opacity="${fillOpacity}" stroke="${stroke}" stroke-width="1"/>`;
|
|
8289
|
+
}
|
|
8290
|
+
}
|
|
8239
8291
|
buildPath(edge) {
|
|
8240
8292
|
const path = edge.path;
|
|
8241
8293
|
if (edge.type === "bezier" && path.length >= 4) {
|
|
@@ -8284,6 +8336,13 @@ class SvgExporter {
|
|
|
8284
8336
|
}
|
|
8285
8337
|
return path[0];
|
|
8286
8338
|
}
|
|
8339
|
+
getEdgeLabelPoint(edge, edgeLabelOffset) {
|
|
8340
|
+
const midpoint = this.getPathMidpoint(edge);
|
|
8341
|
+
return {
|
|
8342
|
+
x: midpoint.x,
|
|
8343
|
+
y: midpoint.y + edgeLabelOffset
|
|
8344
|
+
};
|
|
8345
|
+
}
|
|
8287
8346
|
renderTextLabel(text, point, style = {}) {
|
|
8288
8347
|
const fill = style.color ?? "#000000";
|
|
8289
8348
|
const fontSize = style.fontSize ?? 14;
|
|
@@ -8295,14 +8354,11 @@ class SvgExporter {
|
|
|
8295
8354
|
text
|
|
8296
8355
|
)}</text>`;
|
|
8297
8356
|
}
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
"<defs>"
|
|
8301
|
-
|
|
8302
|
-
|
|
8303
|
-
"</marker>",
|
|
8304
|
-
"</defs>"
|
|
8305
|
-
].join("");
|
|
8357
|
+
buildDefs(markerDefs) {
|
|
8358
|
+
if (markerDefs.size === 0) {
|
|
8359
|
+
return "<defs></defs>";
|
|
8360
|
+
}
|
|
8361
|
+
return `<defs>${Array.from(markerDefs.values()).join("")}</defs>`;
|
|
8306
8362
|
}
|
|
8307
8363
|
createEmptySvg(width, height, backgroundColor, includeBackground) {
|
|
8308
8364
|
return [
|