sigma.canvas.edges.labels.curve.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. ;(function(undefined) {
  2. 'use strict';
  3. if (typeof sigma === 'undefined')
  4. throw 'sigma is not declared';
  5. // Initialize packages:
  6. sigma.utils.pkg('sigma.canvas.edges.labels');
  7. /**
  8. * This label renderer will just display the label on the curve of the edge.
  9. * The label is rendered at half distance of the edge extremities, and is
  10. * always oriented from left to right on the top side of the curve.
  11. *
  12. * @param {object} edge The edge object.
  13. * @param {object} source node The edge source node.
  14. * @param {object} target node The edge target node.
  15. * @param {CanvasRenderingContext2D} context The canvas context.
  16. * @param {configurable} settings The settings function.
  17. */
  18. sigma.canvas.edges.labels.curve =
  19. function(edge, source, target, context, settings) {
  20. if (typeof edge.label !== 'string')
  21. return;
  22. var prefix = settings('prefix') || '',
  23. size = edge[prefix + 'size'] || 1;
  24. if (size < settings('edgeLabelThreshold'))
  25. return;
  26. var fontSize,
  27. sSize = source[prefix + 'size'],
  28. sX = source[prefix + 'x'],
  29. sY = source[prefix + 'y'],
  30. tX = target[prefix + 'x'],
  31. tY = target[prefix + 'y'],
  32. count = edge.count || 0,
  33. dX = tX - sX,
  34. dY = tY - sY,
  35. sign = (sX < tX) ? 1 : -1,
  36. cp = {},
  37. c,
  38. angle,
  39. t = 0.5; //length of the curve
  40. if (source.id === target.id) {
  41. cp = sigma.utils.getSelfLoopControlPoints(sX, sY, sSize, count);
  42. c = sigma.utils.getPointOnBezierCurve(
  43. t, sX, sY, tX, tY, cp.x1, cp.y1, cp.x2, cp.y2
  44. );
  45. angle = Math.atan2(1, 1); // 45°
  46. } else {
  47. cp = sigma.utils.getQuadraticControlPoint(sX, sY, tX, tY, count);
  48. c = sigma.utils.getPointOnQuadraticCurve(t, sX, sY, tX, tY, cp.x, cp.y);
  49. angle = Math.atan2(dY * sign, dX * sign);
  50. }
  51. // The font size is sublineraly proportional to the edge size, in order to
  52. // avoid very large labels on screen.
  53. // This is achieved by f(x) = x * x^(-1/ a), where 'x' is the size and 'a'
  54. // is the edgeLabelSizePowRatio. Notice that f(1) = 1.
  55. // The final form is:
  56. // f'(x) = b * x * x^(-1 / a), thus f'(1) = b. Application:
  57. // fontSize = defaultEdgeLabelSize if edgeLabelSizePowRatio = 1
  58. fontSize = (settings('edgeLabelSize') === 'fixed') ?
  59. settings('defaultEdgeLabelSize') :
  60. settings('defaultEdgeLabelSize') *
  61. size *
  62. Math.pow(size, -1 / settings('edgeLabelSizePowRatio'));
  63. context.save();
  64. if (edge.active) {
  65. context.font = [
  66. settings('activeFontStyle'),
  67. fontSize + 'px',
  68. settings('activeFont') || settings('font')
  69. ].join(' ');
  70. context.fillStyle =
  71. settings('edgeActiveColor') === 'edge' ?
  72. (edge.active_color || settings('defaultEdgeActiveColor')) :
  73. settings('defaultEdgeLabelActiveColor');
  74. }
  75. else {
  76. context.font = [
  77. settings('fontStyle'),
  78. fontSize + 'px',
  79. settings('font')
  80. ].join(' ');
  81. context.fillStyle =
  82. (settings('edgeLabelColor') === 'edge') ?
  83. (edge.color || settings('defaultEdgeColor')) :
  84. settings('defaultEdgeLabelColor');
  85. }
  86. context.textAlign = 'center';
  87. context.textBaseline = 'alphabetic';
  88. context.translate(c.x, c.y);
  89. context.rotate(angle);
  90. context.fillText(
  91. edge.label,
  92. 0,
  93. (-size / 2) - 3
  94. );
  95. context.restore();
  96. };
  97. }).call(this);