1 | import RRElement from './rrelement';
|
2 | import RRDiagramToSVG from './rrdiagramtosvg';
|
3 | import LayoutInfo from './layoutinfo';
|
4 | import { escapeXml, getFontInfo } from '../utils/utils';
|
5 |
|
6 | const Type = {
|
7 | LITERAL: 1,
|
8 | RULE: 2,
|
9 | SPECIAL_SEQUENCE: 3,
|
10 | };
|
11 |
|
12 | export default class RRText extends RRElement {
|
13 |
|
14 | static get Type() {
|
15 | return Type;
|
16 | }
|
17 |
|
18 | |
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | constructor(type, text, link) {
|
25 | super();
|
26 | this.type = type;
|
27 | this.text = text;
|
28 | this.link = link;
|
29 | this.fontInfo = null;
|
30 | }
|
31 |
|
32 | getType() {
|
33 | return this.type;
|
34 | }
|
35 |
|
36 | getText() {
|
37 | return this.text;
|
38 | }
|
39 |
|
40 | getLink() {
|
41 | return this.link;
|
42 | }
|
43 |
|
44 | computeLayoutInfo(rrDiagramToSVG) {
|
45 | const insets = {
|
46 | top: 5,
|
47 | left: 10,
|
48 | bottom: 5,
|
49 | right: 10,
|
50 | };
|
51 | let cssTextClass;
|
52 | if (this.type == Type.RULE) {
|
53 | cssTextClass = rrDiagramToSVG.cssRuleTextClass;
|
54 | } else if (this.type == Type.LITERAL) {
|
55 | cssTextClass = rrDiagramToSVG.cssLiteralTextClass;
|
56 | } else if (this.type == Type.SPECIAL_SEQUENCE) {
|
57 | cssTextClass = rrDiagramToSVG.cssSpecialSequenceTextClass;
|
58 | } else {
|
59 | throw 'Unknown type: type';
|
60 | }
|
61 | this.fontInfo = getFontInfo(this.text, cssTextClass);
|
62 | let width = this.fontInfo.textWidth;
|
63 | let height = this.fontInfo.height;
|
64 | const fontYOffset = this.fontInfo.descent;
|
65 | const connectorOffset = insets.top + height - fontYOffset;
|
66 | width += insets.left + insets.right;
|
67 | height += insets.top + insets.bottom;
|
68 | this.setLayoutInfo(new LayoutInfo(width, height, connectorOffset));
|
69 | }
|
70 |
|
71 | toSVG(rrDiagramToSVG, xOffset, yOffset, svgContent) {
|
72 | const insets = {
|
73 | top: 5,
|
74 | left: 10,
|
75 | bottom: 5,
|
76 | right: 10,
|
77 | };
|
78 | const layoutInfo = this.getLayoutInfo();
|
79 | const width = layoutInfo.getWidth();
|
80 | const height = layoutInfo.getHeight();
|
81 | if (this.link != null) {
|
82 | svgContent.addElement("<a xlink:href=\"" + escapeXml(this.link) + "\">");
|
83 | }
|
84 | let cssClass;
|
85 | let cssTextClass;
|
86 | let shape;
|
87 | if (this.type == Type.RULE) {
|
88 | cssClass = rrDiagramToSVG.cssRuleClass;
|
89 | cssTextClass = rrDiagramToSVG.cssRuleTextClass;
|
90 | shape = rrDiagramToSVG.ruleShape;
|
91 | } else if (this.type == Type.LITERAL) {
|
92 | cssClass = rrDiagramToSVG.cssLiteralClass;
|
93 | cssTextClass = rrDiagramToSVG.cssLiteralTextClass;
|
94 | shape = rrDiagramToSVG.literalShape;
|
95 | } else if (this.type == Type.SPECIAL_SEQUENCE) {
|
96 | cssClass = rrDiagramToSVG.cssSpecialSequenceClass;
|
97 | cssTextClass = rrDiagramToSVG.cssSpecialSequenceTextClass;
|
98 | shape = rrDiagramToSVG.specialSequenceShape;
|
99 | } else {
|
100 | throw 'Unknown type: type';
|
101 | }
|
102 | if (shape == RRDiagramToSVG.BoxShape.RECTANGLE) {
|
103 | svgContent.addElement("<rect class=\"" + cssClass + "\" x=\"" + xOffset + "\" y=\"" + yOffset + "\" width=\"" + width + "\" height=\"" + height + "\"/>");
|
104 | } else if (shape == RRDiagramToSVG.BoxShape.ROUNDED_RECTANGLE) {
|
105 | const rx = Math.floor((insets.left + insets.right + insets.top + insets.bottom) / 4);
|
106 | svgContent.addElement("<rect class=\"" + cssClass + "\" x=\"" + xOffset + "\" y=\"" + yOffset + "\" width=\"" + width + "\" height=\"" + height + "\" rx=\"" + rx + "\"/>");
|
107 | } else if (shape == RRDiagramToSVG.BoxShape.HEXAGON) {
|
108 |
|
109 |
|
110 | const connectorOffset = layoutInfo.getConnectorOffset();
|
111 | svgContent.addLineConnector(xOffset, yOffset + connectorOffset, xOffset + insets.left, yOffset + connectorOffset);
|
112 | svgContent.addElement("<polygon class=\"" + escapeXml(cssClass) + "\" points=\"" + xOffset + " " + (yOffset + Math.floor(height / 2)) + " " + (xOffset + insets.left) + " " + yOffset + " " + (xOffset + width - insets.right) + " " + yOffset + " " + (xOffset + width) + " " + (yOffset + Math.floor(height / 2)) + " " + (xOffset + width - insets.right) + " " + (yOffset + height) + " " + (xOffset + insets.left) + " " + (yOffset + height) + "\"/>");
|
113 | svgContent.addLineConnector(xOffset + width, yOffset + connectorOffset, xOffset + width - insets.right, yOffset + connectorOffset);
|
114 | }
|
115 | const fontYOffset = this.fontInfo.descent;
|
116 | const textHeight = this.fontInfo.textHeight;
|
117 | const textXOffset = xOffset + insets.left;
|
118 | const textYOffset = yOffset + insets.top + textHeight - fontYOffset;
|
119 | svgContent.addElement("<text class=\"" + escapeXml(cssTextClass) + "\" x=\"" + textXOffset + "\" y=\"" + textYOffset + "\">" + escapeXml(this.text) + "</text>");
|
120 | if (this.link != null) {
|
121 | svgContent.addElement("</a>");
|
122 | }
|
123 | }
|
124 |
|
125 | }
|