@ngroznykh/papirus 0.3.1 → 0.3.2
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 +92 -44
- package/dist/papirus.js.map +1 -1
- package/dist/utils/SvgExporter.d.ts +2 -3
- package/dist/utils/SvgExporter.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/papirus.js
CHANGED
|
@@ -8124,17 +8124,15 @@ class SvgExporter {
|
|
|
8124
8124
|
this.renderer.nodes.values()
|
|
8125
8125
|
);
|
|
8126
8126
|
const parts = [];
|
|
8127
|
-
const markerDefs = /* @__PURE__ */ new Map();
|
|
8128
8127
|
const renderedEdges = [];
|
|
8129
8128
|
parts.push(
|
|
8130
8129
|
`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">`
|
|
8131
8130
|
);
|
|
8132
8131
|
for (const edge of this.renderer.edges.values()) {
|
|
8133
8132
|
if (edge.visible) {
|
|
8134
|
-
renderedEdges.push(this.renderEdge(edge,
|
|
8133
|
+
renderedEdges.push(this.renderEdge(edge, edgeLabelOffset));
|
|
8135
8134
|
}
|
|
8136
8135
|
}
|
|
8137
|
-
parts.push(this.buildDefs(markerDefs));
|
|
8138
8136
|
if (includeBackground) {
|
|
8139
8137
|
parts.push(`<rect width="100%" height="100%" fill="${backgroundColor}"/>`);
|
|
8140
8138
|
}
|
|
@@ -8222,7 +8220,7 @@ class SvgExporter {
|
|
|
8222
8220
|
label
|
|
8223
8221
|
].join("");
|
|
8224
8222
|
}
|
|
8225
|
-
renderEdge(edge,
|
|
8223
|
+
renderEdge(edge, edgeLabelOffset) {
|
|
8226
8224
|
const path = edge.path;
|
|
8227
8225
|
if (path.length < 2) {
|
|
8228
8226
|
return "";
|
|
@@ -8235,12 +8233,9 @@ class SvgExporter {
|
|
|
8235
8233
|
const dash = dashValues ? ` stroke-dasharray="${dashValues.join(" ")}"` : "";
|
|
8236
8234
|
const dashOffset = style.lineDashOffset !== void 0 ? ` stroke-dashoffset="${style.lineDashOffset}"` : "";
|
|
8237
8235
|
const d = this.buildPath(edge);
|
|
8238
|
-
const
|
|
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)})"` : "";
|
|
8236
|
+
const markerShapes = this.renderEdgeMarkers(edge, stroke);
|
|
8242
8237
|
const label = edge.label ? this.renderTextLabel(edge.label.text, this.getEdgeLabelPoint(edge, edgeLabelOffset), edge.label.style) : "";
|
|
8243
|
-
return `<path d="${d}" fill="none" stroke="${stroke}" stroke-width="${strokeWidth}" opacity="${opacity}" color="${stroke}"${dash}${dashOffset}
|
|
8238
|
+
return `<path d="${d}" fill="none" stroke="${stroke}" stroke-width="${strokeWidth}" opacity="${opacity}" color="${stroke}"${dash}${dashOffset}/>${markerShapes}${label}`;
|
|
8244
8239
|
}
|
|
8245
8240
|
resolveMarkerConfig(edge, side) {
|
|
8246
8241
|
const marker = side === "start" ? edge.startMarker : edge.endMarker;
|
|
@@ -8252,40 +8247,99 @@ class SvgExporter {
|
|
|
8252
8247
|
}
|
|
8253
8248
|
return edge.arrowType === "double" ? { type: "arrow" } : null;
|
|
8254
8249
|
}
|
|
8255
|
-
|
|
8256
|
-
const
|
|
8257
|
-
const
|
|
8258
|
-
const
|
|
8259
|
-
|
|
8260
|
-
|
|
8261
|
-
|
|
8262
|
-
|
|
8263
|
-
|
|
8264
|
-
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
);
|
|
8250
|
+
renderEdgeMarkers(edge, edgeStroke) {
|
|
8251
|
+
const startMarker = this.resolveMarkerConfig(edge, "start");
|
|
8252
|
+
const endMarker = this.resolveMarkerConfig(edge, "end");
|
|
8253
|
+
const parts = [];
|
|
8254
|
+
if (endMarker) {
|
|
8255
|
+
const points = this.getMarkerPoints(edge, "end");
|
|
8256
|
+
if (points) {
|
|
8257
|
+
parts.push(this.renderMarkerShape(endMarker, points.from, points.to, edgeStroke));
|
|
8258
|
+
}
|
|
8259
|
+
}
|
|
8260
|
+
if (startMarker) {
|
|
8261
|
+
const points = this.getMarkerPoints(edge, "start");
|
|
8262
|
+
if (points) {
|
|
8263
|
+
parts.push(this.renderMarkerShape(startMarker, points.from, points.to, edgeStroke));
|
|
8264
|
+
}
|
|
8271
8265
|
}
|
|
8272
|
-
return
|
|
8266
|
+
return parts.join("");
|
|
8273
8267
|
}
|
|
8274
|
-
|
|
8275
|
-
const
|
|
8276
|
-
|
|
8268
|
+
getMarkerPoints(edge, position) {
|
|
8269
|
+
const path = edge.path;
|
|
8270
|
+
if (path.length < 2) {
|
|
8271
|
+
return null;
|
|
8272
|
+
}
|
|
8273
|
+
if (edge.type === "bezier" && path.length >= 4) {
|
|
8274
|
+
const epsilon = 1e-3;
|
|
8275
|
+
const isSame = (a, b) => Math.abs(a.x - b.x) < epsilon && Math.abs(a.y - b.y) < epsilon;
|
|
8276
|
+
if (position === "end") {
|
|
8277
|
+
const endIndex = path.length - 1;
|
|
8278
|
+
const endPoint = path[endIndex];
|
|
8279
|
+
let from = path[endIndex - 1];
|
|
8280
|
+
if (isSame(from, endPoint)) {
|
|
8281
|
+
from = path[endIndex - 2];
|
|
8282
|
+
if (isSame(from, endPoint)) {
|
|
8283
|
+
from = path[0];
|
|
8284
|
+
}
|
|
8285
|
+
}
|
|
8286
|
+
return { from, to: endPoint };
|
|
8287
|
+
}
|
|
8288
|
+
const start = path[0];
|
|
8289
|
+
let next = path[1];
|
|
8290
|
+
if (isSame(next, start)) {
|
|
8291
|
+
next = path[2];
|
|
8292
|
+
if (isSame(next, start)) {
|
|
8293
|
+
next = path[path.length - 1];
|
|
8294
|
+
}
|
|
8295
|
+
}
|
|
8296
|
+
return { from: next, to: start };
|
|
8297
|
+
}
|
|
8298
|
+
if (position === "end") {
|
|
8299
|
+
return { from: path[path.length - 2], to: path[path.length - 1] };
|
|
8300
|
+
}
|
|
8301
|
+
return { from: path[1], to: path[0] };
|
|
8277
8302
|
}
|
|
8278
|
-
renderMarkerShape(marker,
|
|
8303
|
+
renderMarkerShape(marker, from, to, edgeStroke) {
|
|
8304
|
+
const angle2 = Math.atan2(to.y - from.y, to.x - from.x);
|
|
8305
|
+
const size = marker.size ?? 12;
|
|
8306
|
+
const stroke = marker.strokeColor ?? edgeStroke;
|
|
8307
|
+
const fill = marker.fillColor ?? stroke;
|
|
8308
|
+
const fillOpacity = marker.fillOpacity ?? 1;
|
|
8279
8309
|
switch (marker.type) {
|
|
8280
|
-
case "open":
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
|
|
8284
|
-
|
|
8285
|
-
return `<
|
|
8310
|
+
case "open": {
|
|
8311
|
+
const x1 = to.x - size * Math.cos(angle2 - ARROW_ANGLE);
|
|
8312
|
+
const y1 = to.y - size * Math.sin(angle2 - ARROW_ANGLE);
|
|
8313
|
+
const x2 = to.x - size * Math.cos(angle2 + ARROW_ANGLE);
|
|
8314
|
+
const y2 = to.y - size * Math.sin(angle2 + ARROW_ANGLE);
|
|
8315
|
+
return `<path d="M ${to.x} ${to.y} L ${x1} ${y1} M ${to.x} ${to.y} L ${x2} ${y2}" fill="none" stroke="${stroke}" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>`;
|
|
8316
|
+
}
|
|
8317
|
+
case "diamond": {
|
|
8318
|
+
const halfLength = size / 2;
|
|
8319
|
+
const halfWidth = size * 0.3;
|
|
8320
|
+
const cos = Math.cos(angle2);
|
|
8321
|
+
const sin = Math.sin(angle2);
|
|
8322
|
+
const p1x = to.x - halfLength * cos + halfWidth * sin;
|
|
8323
|
+
const p1y = to.y - halfLength * sin - halfWidth * cos;
|
|
8324
|
+
const backX = to.x - size * cos;
|
|
8325
|
+
const backY = to.y - size * sin;
|
|
8326
|
+
const p2x = to.x - halfLength * cos - halfWidth * sin;
|
|
8327
|
+
const p2y = to.y - halfLength * sin + halfWidth * cos;
|
|
8328
|
+
return `<path d="M ${to.x} ${to.y} L ${p1x} ${p1y} L ${backX} ${backY} L ${p2x} ${p2y} Z" fill="${fill}" fill-opacity="${fillOpacity}" stroke="${stroke}" stroke-width="1"/>`;
|
|
8329
|
+
}
|
|
8330
|
+
case "circle": {
|
|
8331
|
+
const cx = to.x - size * Math.cos(angle2);
|
|
8332
|
+
const cy = to.y - size * Math.sin(angle2);
|
|
8333
|
+
return `<circle cx="${cx}" cy="${cy}" r="${size}" fill="${fill}" fill-opacity="${fillOpacity}" stroke="${stroke}" stroke-width="1"/>`;
|
|
8334
|
+
}
|
|
8286
8335
|
case "arrow":
|
|
8287
|
-
default:
|
|
8288
|
-
|
|
8336
|
+
default: {
|
|
8337
|
+
const x1 = to.x - size * Math.cos(angle2 - ARROW_ANGLE);
|
|
8338
|
+
const y1 = to.y - size * Math.sin(angle2 - ARROW_ANGLE);
|
|
8339
|
+
const x2 = to.x - size * Math.cos(angle2 + ARROW_ANGLE);
|
|
8340
|
+
const y2 = to.y - size * Math.sin(angle2 + ARROW_ANGLE);
|
|
8341
|
+
return `<path d="M ${to.x} ${to.y} L ${x1} ${y1} L ${x2} ${y2} Z" fill="${fill}" fill-opacity="${fillOpacity}" stroke="${stroke}" stroke-width="1"/>`;
|
|
8342
|
+
}
|
|
8289
8343
|
}
|
|
8290
8344
|
}
|
|
8291
8345
|
buildPath(edge) {
|
|
@@ -8354,12 +8408,6 @@ class SvgExporter {
|
|
|
8354
8408
|
text
|
|
8355
8409
|
)}</text>`;
|
|
8356
8410
|
}
|
|
8357
|
-
buildDefs(markerDefs) {
|
|
8358
|
-
if (markerDefs.size === 0) {
|
|
8359
|
-
return "<defs></defs>";
|
|
8360
|
-
}
|
|
8361
|
-
return `<defs>${Array.from(markerDefs.values()).join("")}</defs>`;
|
|
8362
|
-
}
|
|
8363
8411
|
createEmptySvg(width, height, backgroundColor, includeBackground) {
|
|
8364
8412
|
return [
|
|
8365
8413
|
`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">`,
|