vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

324 lines
9.0 KiB

8 years ago
  1. /**
  2. * Canvas shapes used by Network
  3. */
  4. if (typeof CanvasRenderingContext2D !== 'undefined') {
  5. /**
  6. * Draw a circle shape
  7. *
  8. * @param {Number} x
  9. * @param {Number} y
  10. * @param {Number} r
  11. */
  12. CanvasRenderingContext2D.prototype.circle = function (x, y, r) {
  13. this.beginPath();
  14. this.arc(x, y, r, 0, 2 * Math.PI, false);
  15. this.closePath();
  16. };
  17. /**
  18. * Draw a square shape
  19. * @param {Number} x horizontal center
  20. * @param {Number} y vertical center
  21. * @param {Number} r size, width and height of the square
  22. */
  23. CanvasRenderingContext2D.prototype.square = function (x, y, r) {
  24. this.beginPath();
  25. this.rect(x - r, y - r, r * 2, r * 2);
  26. this.closePath();
  27. };
  28. /**
  29. * Draw a triangle shape
  30. * @param {Number} x horizontal center
  31. * @param {Number} y vertical center
  32. * @param {Number} r radius, half the length of the sides of the triangle
  33. */
  34. CanvasRenderingContext2D.prototype.triangle = function (x, y, r) {
  35. // http://en.wikipedia.org/wiki/Equilateral_triangle
  36. this.beginPath();
  37. // the change in radius and the offset is here to center the shape
  38. r *= 1.15;
  39. y += 0.275 * r;
  40. var s = r * 2;
  41. var s2 = s / 2;
  42. var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
  43. var h = Math.sqrt(s * s - s2 * s2); // height
  44. this.moveTo(x, y - (h - ir));
  45. this.lineTo(x + s2, y + ir);
  46. this.lineTo(x - s2, y + ir);
  47. this.lineTo(x, y - (h - ir));
  48. this.closePath();
  49. };
  50. /**
  51. * Draw a triangle shape in downward orientation
  52. * @param {Number} x horizontal center
  53. * @param {Number} y vertical center
  54. * @param {Number} r radius
  55. */
  56. CanvasRenderingContext2D.prototype.triangleDown = function (x, y, r) {
  57. // http://en.wikipedia.org/wiki/Equilateral_triangle
  58. this.beginPath();
  59. // the change in radius and the offset is here to center the shape
  60. r *= 1.15;
  61. y -= 0.275 * r;
  62. var s = r * 2;
  63. var s2 = s / 2;
  64. var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
  65. var h = Math.sqrt(s * s - s2 * s2); // height
  66. this.moveTo(x, y + (h - ir));
  67. this.lineTo(x + s2, y - ir);
  68. this.lineTo(x - s2, y - ir);
  69. this.lineTo(x, y + (h - ir));
  70. this.closePath();
  71. };
  72. /**
  73. * Draw a star shape, a star with 5 points
  74. * @param {Number} x horizontal center
  75. * @param {Number} y vertical center
  76. * @param {Number} r radius, half the length of the sides of the triangle
  77. */
  78. CanvasRenderingContext2D.prototype.star = function (x, y, r) {
  79. // http://www.html5canvastutorials.com/labs/html5-canvas-star-spinner/
  80. this.beginPath();
  81. // the change in radius and the offset is here to center the shape
  82. r *= 0.82;
  83. y += 0.1 * r;
  84. for (var n = 0; n < 10; n++) {
  85. var radius = (n % 2 === 0) ? r * 1.3 : r * 0.5;
  86. this.lineTo(
  87. x + radius * Math.sin(n * 2 * Math.PI / 10),
  88. y - radius * Math.cos(n * 2 * Math.PI / 10)
  89. );
  90. }
  91. this.closePath();
  92. };
  93. /**
  94. * Draw a Diamond shape
  95. * @param {Number} x horizontal center
  96. * @param {Number} y vertical center
  97. * @param {Number} r radius, half the length of the sides of the triangle
  98. */
  99. CanvasRenderingContext2D.prototype.diamond = function (x, y, r) {
  100. // http://www.html5canvastutorials.com/labs/html5-canvas-star-spinner/
  101. this.beginPath();
  102. this.lineTo(x, y + r);
  103. this.lineTo(x + r, y);
  104. this.lineTo(x, y - r);
  105. this.lineTo(x - r, y);
  106. this.closePath();
  107. };
  108. /**
  109. * http://stackoverflow.com/questions/1255512/how-to-draw-a-rounded-rectangle-on-html-canvas
  110. *
  111. * @param {Number} x
  112. * @param {Number} y
  113. * @param {Number} w
  114. * @param {Number} h
  115. * @param {Number} r
  116. */
  117. CanvasRenderingContext2D.prototype.roundRect = function (x, y, w, h, r) {
  118. var r2d = Math.PI / 180;
  119. if (w - ( 2 * r ) < 0) {
  120. r = ( w / 2 );
  121. } //ensure that the radius isn't too large for x
  122. if (h - ( 2 * r ) < 0) {
  123. r = ( h / 2 );
  124. } //ensure that the radius isn't too large for y
  125. this.beginPath();
  126. this.moveTo(x + r, y);
  127. this.lineTo(x + w - r, y);
  128. this.arc(x + w - r, y + r, r, r2d * 270, r2d * 360, false);
  129. this.lineTo(x + w, y + h - r);
  130. this.arc(x + w - r, y + h - r, r, 0, r2d * 90, false);
  131. this.lineTo(x + r, y + h);
  132. this.arc(x + r, y + h - r, r, r2d * 90, r2d * 180, false);
  133. this.lineTo(x, y + r);
  134. this.arc(x + r, y + r, r, r2d * 180, r2d * 270, false);
  135. this.closePath();
  136. };
  137. /**
  138. * http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
  139. *
  140. * Postfix '_vis' added to discern it from standard method ellipse().
  141. *
  142. * @param {Number} x
  143. * @param {Number} y
  144. * @param {Number} w
  145. * @param {Number} h
  146. */
  147. CanvasRenderingContext2D.prototype.ellipse_vis = function (x, y, w, h) {
  148. var kappa = .5522848,
  149. ox = (w / 2) * kappa, // control point offset horizontal
  150. oy = (h / 2) * kappa, // control point offset vertical
  151. xe = x + w, // x-end
  152. ye = y + h, // y-end
  153. xm = x + w / 2, // x-middle
  154. ym = y + h / 2; // y-middle
  155. this.beginPath();
  156. this.moveTo(x, ym);
  157. this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
  158. this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
  159. this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
  160. this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
  161. this.closePath();
  162. };
  163. /**
  164. * http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
  165. *
  166. * @param {Number} x
  167. * @param {Number} y
  168. * @param {Number} w
  169. * @param {Number} h
  170. */
  171. CanvasRenderingContext2D.prototype.database = function (x, y, w, h) {
  172. var f = 1 / 3;
  173. var wEllipse = w;
  174. var hEllipse = h * f;
  175. var kappa = .5522848,
  176. ox = (wEllipse / 2) * kappa, // control point offset horizontal
  177. oy = (hEllipse / 2) * kappa, // control point offset vertical
  178. xe = x + wEllipse, // x-end
  179. ye = y + hEllipse, // y-end
  180. xm = x + wEllipse / 2, // x-middle
  181. ym = y + hEllipse / 2, // y-middle
  182. ymb = y + (h - hEllipse / 2), // y-midlle, bottom ellipse
  183. yeb = y + h; // y-end, bottom ellipse
  184. this.beginPath();
  185. this.moveTo(xe, ym);
  186. this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
  187. this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
  188. this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
  189. this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
  190. this.lineTo(xe, ymb);
  191. this.bezierCurveTo(xe, ymb + oy, xm + ox, yeb, xm, yeb);
  192. this.bezierCurveTo(xm - ox, yeb, x, ymb + oy, x, ymb);
  193. this.lineTo(x, ym);
  194. };
  195. /**
  196. * Draw an arrow at the end of a line with the given angle.
  197. *
  198. * @param {Number} x
  199. * @param {Number} y
  200. * @param {Number} angle
  201. * @param {Number} length
  202. */
  203. CanvasRenderingContext2D.prototype.arrowEndpoint = function (x, y, angle, length) {
  204. // tail
  205. var xt = x - length * Math.cos(angle);
  206. var yt = y - length * Math.sin(angle);
  207. // inner tail
  208. var xi = x - length * 0.9 * Math.cos(angle);
  209. var yi = y - length * 0.9 * Math.sin(angle);
  210. // left
  211. var xl = xt + length / 3 * Math.cos(angle + 0.5 * Math.PI);
  212. var yl = yt + length / 3 * Math.sin(angle + 0.5 * Math.PI);
  213. // right
  214. var xr = xt + length / 3 * Math.cos(angle - 0.5 * Math.PI);
  215. var yr = yt + length / 3 * Math.sin(angle - 0.5 * Math.PI);
  216. this.beginPath();
  217. this.moveTo(x, y);
  218. this.lineTo(xl, yl);
  219. this.lineTo(xi, yi);
  220. this.lineTo(xr, yr);
  221. this.closePath();
  222. };
  223. /**
  224. * Draw an circle an the end of an line with the given angle.
  225. *
  226. * @param {Number} x
  227. * @param {Number} y
  228. * @param {Number} angle
  229. * @param {Number} length
  230. */
  231. CanvasRenderingContext2D.prototype.circleEndpoint = function (x, y, angle, length) {
  232. var radius = length * 0.4;
  233. var xc = x - radius * Math.cos(angle);
  234. var yc = y - radius * Math.sin(angle);
  235. this.circle(xc, yc, radius);
  236. };
  237. /**
  238. * Sets up the dashedLine functionality for drawing
  239. * Original code came from http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas
  240. * @author David Jordan
  241. * @date 2012-08-08
  242. *
  243. * @param {Number} x
  244. * @param {Number} y
  245. * @param {Number} x2
  246. * @param {Number} y2
  247. * @param {String} pattern
  248. */
  249. CanvasRenderingContext2D.prototype.dashedLine = function (x, y, x2, y2, pattern) {
  250. this.beginPath();
  251. this.moveTo(x, y);
  252. var patternLength = pattern.length;
  253. var dx = (x2 - x);
  254. var dy = (y2 - y);
  255. var slope = dy / dx;
  256. var distRemaining = Math.sqrt(dx * dx + dy * dy);
  257. var patternIndex = 0;
  258. var draw = true;
  259. var xStep = 0;
  260. var dashLength = pattern[0];
  261. while (distRemaining >= 0.1) {
  262. dashLength = pattern[patternIndex++ % patternLength];
  263. if (dashLength > distRemaining) {
  264. dashLength = distRemaining;
  265. }
  266. xStep = Math.sqrt(dashLength * dashLength / (1 + slope * slope));
  267. xStep = dx < 0 ? -xStep : xStep;
  268. x += xStep;
  269. y += slope * xStep;
  270. if (draw === true) {this.lineTo(x,y);}
  271. else {this.moveTo(x,y);}
  272. distRemaining -= dashLength;
  273. draw = !draw;
  274. }
  275. };
  276. }