1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
|
/**
* $Id: mxArrow.js,v 1.31 2012-05-23 19:09:22 gaudenz Exp $
* Copyright (c) 2006-2010, JGraph Ltd
*/
/**
* Class: mxArrow
*
* Extends <mxShape> to implement an arrow shape. (The shape
* is used to represent edges, not vertices.)
* This shape is registered under <mxConstants.SHAPE_ARROW>
* in <mxCellRenderer>.
*
* Constructor: mxArrow
*
* Constructs a new arrow shape.
*
* Parameters:
*
* points - Array of <mxPoints> that define the points. This is stored in
* <mxShape.points>.
* fill - String that defines the fill color. This is stored in <fill>.
* stroke - String that defines the stroke color. This is stored in <stroke>.
* strokewidth - Optional integer that defines the stroke width. Default is
* 1. This is stored in <strokewidth>.
* arrowWidth - Optional integer that defines the arrow width. Default is
* <mxConstants.ARROW_WIDTH>. This is stored in <arrowWidth>.
* spacing - Optional integer that defines the spacing between the arrow shape
* and its endpoints. Default is <mxConstants.ARROW_SPACING>. This is stored in
* <spacing>.
* endSize - Optional integer that defines the size of the arrowhead. Default
* is <mxConstants.ARROW_SIZE>. This is stored in <endSize>.
*/
function mxArrow(points, fill, stroke, strokewidth, arrowWidth, spacing, endSize)
{
this.points = points;
this.fill = fill;
this.stroke = stroke;
this.strokewidth = (strokewidth != null) ? strokewidth : 1;
this.arrowWidth = (arrowWidth != null) ? arrowWidth : mxConstants.ARROW_WIDTH;
this.spacing = (spacing != null) ? spacing : mxConstants.ARROW_SPACING;
this.endSize = (endSize != null) ? endSize : mxConstants.ARROW_SIZE;
};
/**
* Extends <mxActor>.
*/
mxArrow.prototype = new mxActor();
mxArrow.prototype.constructor = mxArrow;
/**
* Variable: addPipe
*
* Specifies if a SVG path should be created around any path to increase the
* tolerance for mouse events. Default is false since this shape is filled.
*/
mxArrow.prototype.addPipe = false;
/**
* Variable: enableFill
*
* Specifies if fill colors should be ignored. This must be set to true for
* shapes that are stroked only. Default is true since this shape is filled.
*/
mxArrow.prototype.enableFill = true;
/**
* Function: configureTransparentBackground
*
* Overidden to remove transparent background.
*/
mxArrow.prototype.configureTransparentBackground = function(node)
{
// do nothing
};
/**
* Function: updateBoundingBox
*
* Updates the <boundingBox> for this shape.
*/
mxArrow.prototype.augmentBoundingBox = function(bbox)
{
// FIXME: Fix precision, share math and cache results with painting code
bbox.grow(Math.max(this.arrowWidth / 2, this.endSize / 2) * this.scale);
mxShape.prototype.augmentBoundingBox.apply(this, arguments);
};
/**
* Function: createVml
*
* Extends <mxShape.createVml> to ignore fill if <enableFill> is false.
*/
mxArrow.prototype.createVml = function()
{
if (!this.enableFill)
{
this.fill = null;
}
return mxActor.prototype.createVml.apply(this, arguments);
};
/**
* Function: createSvg
*
* Extends <mxActor.createSvg> to ignore fill if <enableFill> is false and
* create an event handling shape if <this.addPipe> is true.
*/
mxArrow.prototype.createSvg = function()
{
if (!this.enableFill)
{
this.fill = null;
}
var g = mxActor.prototype.createSvg.apply(this, arguments);
// Creates an invisible shape around the path for easier
// selection with the mouse. Note: Firefox does not ignore
// the value of the stroke attribute for pointer-events: stroke,
// it does, however, ignore the visibility attribute.
if (this.addPipe)
{
this.pipe = this.createSvgPipe();
g.appendChild(this.pipe);
}
return g;
};
/**
* Function: reconfigure
*
* Extends <mxActor.reconfigure> to ignore fill if <enableFill> is false.
*/
mxArrow.prototype.reconfigure = function()
{
if (!this.enableFill)
{
this.fill = null;
}
mxActor.prototype.reconfigure.apply(this, arguments);
};
/**
* Function: redrawSvg
*
* Extends <mxActor.redrawSvg> to update the event handling shape if one
* exists.
*/
mxArrow.prototype.redrawSvg = function()
{
mxActor.prototype.redrawSvg.apply(this, arguments);
if (this.pipe != null)
{
var d = this.innerNode.getAttribute('d');
if (d != null)
{
this.pipe.setAttribute('d', this.innerNode.getAttribute('d'));
var strokeWidth = Math.round(this.strokewidth * this.scale);
this.pipe.setAttribute('stroke-width', strokeWidth + mxShape.prototype.SVG_STROKE_TOLERANCE);
}
}
};
/**
* Function: redrawPath
*
* Draws the path for this shape. This method uses the <mxPath>
* abstraction to paint the shape for VML and SVG.
*/
mxArrow.prototype.redrawPath = function(path, x, y, w, h)
{
// All points are offset
path.translate.x -= x;
path.translate.y -= y;
// Geometry of arrow
var spacing = this.spacing * this.scale;
var width = this.arrowWidth * this.scale;
var arrow = this.endSize * this.scale;
// Base vector (between end points)
var p0 = this.points[0];
var pe = this.points[this.points.length - 1];
var dx = pe.x - p0.x;
var dy = pe.y - p0.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var length = dist - 2 * spacing - arrow;
// Computes the norm and the inverse norm
var nx = dx / dist;
var ny = dy / dist;
var basex = length * nx;
var basey = length * ny;
var floorx = width * ny/3;
var floory = -width * nx/3;
// Computes points
var p0x = p0.x - floorx / 2 + spacing * nx;
var p0y = p0.y - floory / 2 + spacing * ny;
var p1x = p0x + floorx;
var p1y = p0y + floory;
var p2x = p1x + basex;
var p2y = p1y + basey;
var p3x = p2x + floorx;
var p3y = p2y + floory;
// p4 not necessary
var p5x = p3x - 3 * floorx;
var p5y = p3y - 3 * floory;
path.moveTo(p0x, p0y);
path.lineTo(p1x, p1y);
path.lineTo(p2x, p2y);
path.lineTo(p3x, p3y);
path.lineTo(pe.x - spacing * nx, pe.y - spacing * ny);
path.lineTo(p5x, p5y);
path.lineTo(p5x + floorx, p5y + floory);
path.lineTo(p0x, p0y);
path.close();
};
|