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.

262 lines
7.8 KiB

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