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.

180 lines
5.0 KiB

  1. import NodeBase from './NodeBase';
  2. import CachedImage from '../../../../CachedImage';
  3. /**
  4. * NOTE: This is a bad base class
  5. *
  6. * Child classes are:
  7. *
  8. * Image - uses *only* image methods
  9. * Circle - uses *only* _drawRawCircle
  10. * CircleImage - uses all
  11. *
  12. * TODO: Refactor, move _drawRawCircle to different module, derive Circle from NodeBase
  13. * Rename this to ImageBase
  14. * Consolidate common code in Image and CircleImage to base class
  15. */
  16. class CircleImageBase extends NodeBase {
  17. constructor(options, body, labelModule) {
  18. super(options, body, labelModule);
  19. this.labelOffset = 0;
  20. this.selected = false;
  21. }
  22. setOptions(options, imageObj, imageObjAlt) {
  23. this.options = options;
  24. if (!(imageObj === undefined && imageObjAlt === undefined)) {
  25. this.setImages(imageObj, imageObjAlt);
  26. }
  27. }
  28. /**
  29. * Set the images for this node.
  30. *
  31. * The images can be updated after the initial setting of options;
  32. * therefore, this method needs to be reentrant.
  33. *
  34. * For correct working in error cases, it is necessary to properly set
  35. * field 'nodes.brokenImage' in the options.
  36. *
  37. * @param {Image} imageObj required; main image to show for this node
  38. * @param {Image|undefined} optional; image to show when node is selected
  39. */
  40. setImages(imageObj, imageObjAlt) {
  41. if (imageObjAlt && this.selected) {
  42. this.imageObj = imageObjAlt;
  43. this.imageObjAlt = imageObj;
  44. } else {
  45. this.imageObj = imageObj;
  46. this.imageObjAlt = imageObjAlt;
  47. }
  48. }
  49. /**
  50. * Set selection and switch between the base and the selected image.
  51. *
  52. * Do the switch only if imageObjAlt exists.
  53. *
  54. * @param {true|false} selected value of new selected state for current node
  55. */
  56. switchImages(selected) {
  57. var selection_changed = ((selected && !this.selected) || (!selected && this.selected));
  58. this.selected = selected; // Remember new selection
  59. if (this.imageObjAlt !== undefined && selection_changed) {
  60. let imageTmp = this.imageObj;
  61. this.imageObj = this.imageObjAlt;
  62. this.imageObjAlt = imageTmp;
  63. }
  64. }
  65. /**
  66. * Adjust the node dimensions for a loaded image.
  67. *
  68. * Pre: this.imageObj is valid
  69. */
  70. _resizeImage() {
  71. var width, height;
  72. if (this.options.shapeProperties.useImageSize === false) {
  73. // Use the size property
  74. var ratio_width = 1;
  75. var ratio_height = 1;
  76. // Only calculate the proper ratio if both width and height not zero
  77. if (this.imageObj.width && this.imageObj.height) {
  78. if (this.imageObj.width > this.imageObj.height) {
  79. ratio_width = this.imageObj.width / this.imageObj.height;
  80. }
  81. else {
  82. ratio_height = this.imageObj.height / this.imageObj.width;
  83. }
  84. }
  85. width = this.options.size * 2 * ratio_width;
  86. height = this.options.size * 2 * ratio_height;
  87. }
  88. else {
  89. // Use the image size
  90. width = this.imageObj.width;
  91. height = this.imageObj.height;
  92. }
  93. this.width = width;
  94. this.height = height;
  95. this.radius = 0.5 * this.width;
  96. }
  97. _drawRawCircle(ctx, x, y, values) {
  98. var borderWidth = values.borderWidth / this.body.view.scale;
  99. ctx.lineWidth = Math.min(this.width, borderWidth);
  100. ctx.strokeStyle = values.borderColor;
  101. ctx.fillStyle = values.color;
  102. ctx.circle(x, y, values.size);
  103. // draw shadow if enabled
  104. this.enableShadow(ctx, values);
  105. // draw the background
  106. ctx.fill();
  107. // disable shadows for other elements.
  108. this.disableShadow(ctx, values);
  109. //draw dashed border if enabled, save and restore is required for firefox not to crash on unix.
  110. ctx.save();
  111. // if borders are zero width, they will be drawn with width 1 by default. This prevents that
  112. if (borderWidth > 0) {
  113. this.enableBorderDashes(ctx, values);
  114. //draw the border
  115. ctx.stroke();
  116. //disable dashed border for other elements
  117. this.disableBorderDashes(ctx, values);
  118. }
  119. ctx.restore();
  120. }
  121. _drawImageAtPosition(ctx, values) {
  122. if (this.imageObj.width != 0) {
  123. // draw the image
  124. ctx.globalAlpha = 1.0;
  125. // draw shadow if enabled
  126. this.enableShadow(ctx, values);
  127. let factor = 1;
  128. if (this.options.shapeProperties.interpolation === true) {
  129. factor = (this.imageObj.width / this.width) / this.body.view.scale;
  130. }
  131. this.imageObj.drawImageAtPosition(ctx, factor, this.left, this.top, this.width, this.height);
  132. // disable shadows for other elements.
  133. this.disableShadow(ctx, values);
  134. }
  135. }
  136. _drawImageLabel(ctx, x, y, selected, hover) {
  137. var yLabel;
  138. var offset = 0;
  139. if (this.height !== undefined) {
  140. offset = this.height * 0.5;
  141. var labelDimensions = this.labelModule.getTextSize(ctx, selected, hover);
  142. if (labelDimensions.lineCount >= 1) {
  143. offset += labelDimensions.height / 2;
  144. }
  145. }
  146. yLabel = y + offset;
  147. if (this.options.label) {
  148. this.labelOffset = offset;
  149. }
  150. this.labelModule.draw(ctx, x, yLabel, selected, hover, 'hanging');
  151. }
  152. }
  153. export default CircleImageBase;