Digital Office Automation System Backend
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

il y a 1 jour
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /**
  2. * Class to generate polyline
  3. *
  4. * @author Dmitry Farafonov
  5. */
  6. var ANCHOR_TYPE= {
  7. main: "main",
  8. middle: "middle",
  9. first: "first",
  10. last: "last"
  11. };
  12. function Anchor(uuid, type, x, y) {
  13. this.uuid = uuid;
  14. this.x = x
  15. this.y = y
  16. this.type = (type == ANCHOR_TYPE.middle) ? ANCHOR_TYPE.middle : ANCHOR_TYPE.main;
  17. };
  18. Anchor.prototype = {
  19. uuid: null,
  20. x: 0,
  21. y: 0,
  22. type: ANCHOR_TYPE.main,
  23. isFirst: false,
  24. isLast: false,
  25. ndex: 0,
  26. typeIndex: 0
  27. };
  28. function Polyline(uuid, points, strokeWidth) {
  29. /* Array on coordinates:
  30. * points: [{x: 410, y: 110}, 1
  31. * {x: 570, y: 110}, 1 2
  32. * {x: 620, y: 240}, 2 3
  33. * {x: 750, y: 270}, 3 4
  34. * {x: 650, y: 370}]; 4
  35. */
  36. this.points = points;
  37. /*
  38. * path for graph
  39. * [["M", x1, y1], ["L", x2, y2], ["C", ax, ay, bx, by, x3, y3], ["L", x3, y3]]
  40. */
  41. this.path = [];
  42. this.anchors = [];
  43. if (strokeWidth) this.strokeWidth = strokeWidth;
  44. this.closePath = false;
  45. this.init();
  46. };
  47. Polyline.prototype = {
  48. id: null,
  49. points: [],
  50. path: [],
  51. anchors: [],
  52. strokeWidth: 1,
  53. radius: 15,
  54. showDetails: false,
  55. element: null,
  56. isDefaultConditionAvailable: false,
  57. closePath: false,
  58. init: function(points){
  59. var linesCount = this.getLinesCount();
  60. if (linesCount < 1)
  61. return;
  62. this.normalizeCoordinates();
  63. // create anchors
  64. this.pushAnchor(ANCHOR_TYPE.first, this.getLine(0).x1, this.getLine(0).y1);
  65. for(var i = 1; i < linesCount; i++){
  66. var line1 = this.getLine(i-1),
  67. line2 = this.getLine(i);
  68. //this.pushAnchor(ANCHOR_TYPE.middle, line1.x1 + line1.x2-line1.x1, line1.y1 + line1.y2-line1.y1);
  69. this.pushAnchor(ANCHOR_TYPE.main, line1.x2, line1.y2);
  70. //this.pushAnchor(ANCHOR_TYPE.middle, line2.x1 + line2.x2-line2.x1, line2.y1 + line2.y2-line2.y1);
  71. }
  72. this.pushAnchor(ANCHOR_TYPE.last, this.getLine(linesCount-1).x2, this.getLine(linesCount-1).y2);
  73. this.rebuildPath();
  74. },
  75. normalizeCoordinates: function(){
  76. for(var i=0; i < this.points.length; i++){
  77. this.points[i].x = parseFloat(this.points[i].x);
  78. this.points[i].y = parseFloat(this.points[i].y);
  79. }
  80. },
  81. getLinesCount: function(){
  82. return this.points.length-1;
  83. },
  84. _getLine: function(i){
  85. return {x1: this.points[i].x, y1: this.points[i].y, x2: this.points[i+1].x, y2: this.points[i+1].y};
  86. },
  87. getLine: function(i){
  88. var line = this._getLine(i);
  89. line.angle = this.getLineAngle(i) ;
  90. return line;
  91. },
  92. getLineAngle: function(i){
  93. var line = this._getLine(i);
  94. return Math.atan2(line.y2 - line.y1, line.x2 - line.x1);
  95. },
  96. getLineLengthX: function(i){
  97. var line = this.getLine(i);
  98. return (line.x2 - line.x1);
  99. },
  100. getLineLengthY: function(i){
  101. var line = this.getLine(i);
  102. return (line.y2 - line.y1);
  103. },
  104. getLineLength: function(i){
  105. var line = this.getLine(i);
  106. return Math.sqrt(Math.pow(this.getLineLengthX(i), 2) + Math.pow(this.getLineLengthY(i), 2));
  107. },
  108. getAnchors: function(){
  109. //
  110. // ????
  111. return this.anchors;
  112. },
  113. getAnchorsCount: function(type){
  114. if (!type)
  115. return this.anchors.length;
  116. else {
  117. var count = 0;
  118. for(var i=0; i < this.getAnchorsCount(); i++){
  119. var anchor = this.anchors[i];
  120. if (anchor.getType() == type) {
  121. count++;
  122. }
  123. }
  124. return count;
  125. }
  126. },
  127. pushAnchor: function(type, x, y, index){
  128. if (type == ANCHOR_TYPE.first) {
  129. index = 0;
  130. typeIndex = 0;
  131. } else if (type == ANCHOR_TYPE.last) {
  132. index = this.getAnchorsCount();
  133. typeIndex = 0;
  134. } else if (!index) {
  135. index = this.anchors.length;
  136. } else {
  137. // anchors, , index
  138. //var anchor = this.getAnchor()
  139. for(var i=0; i < this.getAnchorsCount(); i++){
  140. var anchor = this.anchors[i];
  141. if (anchor.index > index) {
  142. anchor.index++;
  143. anchor.typeIndex++;
  144. }
  145. }
  146. }
  147. var anchor = new Anchor(this.id, ANCHOR_TYPE.main, x, y, index, typeIndex);
  148. this.anchors.push(anchor);
  149. },
  150. getAnchor: function(position){
  151. return this.anchors[position];
  152. },
  153. getAnchorByType: function(type, position){
  154. if (type == ANCHOR_TYPE.first)
  155. return this.anchors[0];
  156. if (type == ANCHOR_TYPE.last)
  157. return this.anchors[this.getAnchorsCount()-1];
  158. for(var i=0; i < this.getAnchorsCount(); i++){
  159. var anchor = this.anchors[i];
  160. if (anchor.type == type) {
  161. if( position == anchor.position)
  162. return anchor;
  163. }
  164. }
  165. return null;
  166. },
  167. addNewPoint: function(position, x, y){
  168. //
  169. for(var i = 0; i < this.getLinesCount(); i++){
  170. var line = this.getLine(i);
  171. if (x > line.x1 && x < line.x2 && y > line.y1 && y < line.y2) {
  172. this.points.splice(i+1,0,{x: x, y: y});
  173. break;
  174. }
  175. }
  176. this.rebuildPath();
  177. },
  178. rebuildPath: function(){
  179. var path = [];
  180. for(var i = 0; i < this.getAnchorsCount(); i++){
  181. var anchor = this.getAnchor(i);
  182. var pathType = ""
  183. if (i==0)
  184. pathType = "M";
  185. else
  186. pathType = "L";
  187. // TODO: save previous points and calculate new path just if points are updated, and then save currents values as previous
  188. var targetX = anchor.x, targetY = anchor.y;
  189. if (i>0 && i < this.getAnchorsCount()-1) {
  190. // get new x,y
  191. var cx = anchor.x, cy = anchor.y;
  192. // pivot point of prev line
  193. var AO = this.getLineLength(i-1);
  194. if (AO < this.radius) {
  195. AO = this.radius;
  196. }
  197. this.isDefaultConditionAvailable = (this.isDefaultConditionAvailable || (i == 1 && AO > 10));
  198. //console.log("isDefaultConditionAvailable", this.isDefaultConditionAvailable);
  199. var ED = this.getLineLengthY(i-1) * this.radius / AO;
  200. var OD = this.getLineLengthX(i-1) * this.radius / AO;
  201. targetX = anchor.x - OD;
  202. targetY = anchor.y - ED;
  203. if (AO < 2*this.radius && i>1) {
  204. targetX = anchor.x - this.getLineLengthX(i-1)/2;
  205. targetY = anchor.y - this.getLineLengthY(i-1)/2;;
  206. }
  207. // pivot point of next line
  208. var AO = this.getLineLength(i);
  209. if (AO < this.radius) {
  210. AO = this.radius;
  211. }
  212. var ED = this.getLineLengthY(i) * this.radius / AO;
  213. var OD = this.getLineLengthX(i) * this.radius / AO;
  214. var nextSrcX = anchor.x + OD;
  215. var nextSrcY = anchor.y + ED;
  216. if (AO < 2*this.radius && i<this.getAnchorsCount()-2) {
  217. nextSrcX = anchor.x + this.getLineLengthX(i)/2;
  218. nextSrcY = anchor.y + this.getLineLengthY(i)/2;;
  219. }
  220. var dx0 = (cx - targetX) / 3,
  221. dy0 = (cy - targetY) / 3,
  222. ax = cx - dx0,
  223. ay = cy - dy0,
  224. dx1 = (cx - nextSrcX) / 3,
  225. dy1 = (cy - nextSrcY) / 3,
  226. bx = cx - dx1,
  227. by = cy - dy1,
  228. zx=nextSrcX, zy=nextSrcY;
  229. if (this.showDetails) {
  230. var c = ProcessDiagramCanvas.g.path("M"+targetX+","+targetY+"L"+ax+","+ay).attr({stroke: Color.get(255, 153, 51), "stroke-dasharray": "- "});
  231. var c = ProcessDiagramCanvas.g.path("M"+nextSrcX+","+nextSrcY+"L"+bx+","+by).attr({stroke: Color.get(255, 153, 51), "stroke-dasharray": "- "});
  232. var c = ProcessDiagramCanvas.g.ellipse(ax, ay, 2, 2).attr({stroke: Color.SlateGrey});
  233. var c = ProcessDiagramCanvas.g.ellipse(bx, by, 2, 2).attr({stroke: Color.SlateGrey});
  234. var c = ProcessDiagramCanvas.g.ellipse(cx, cy, this.radius, this.radius).attr({stroke: Color.Gainsboro});
  235. var c = ProcessDiagramCanvas.g.ellipse(targetX, targetY, 2, 2).attr({fill: Color.red});
  236. var c = ProcessDiagramCanvas.g.ellipse(nextSrcX, nextSrcY, 2, 2).attr({fill: Color.red});
  237. }
  238. } else if (i==1 && this.getAnchorsCount() == 2){
  239. var AO = this.getLineLength(i-1);
  240. if (AO < this.radius) {
  241. AO = this.radius;
  242. }
  243. this.isDefaultConditionAvailable = (this.isDefaultConditionAvailable || (i == 1 && AO > 10));
  244. //console.log("-- isDefaultConditionAvailable", this.isDefaultConditionAvailable);
  245. }
  246. // anti smoothing
  247. if (this.strokeWidth%2 == 1) {
  248. targetX += 0.5;
  249. targetY += 0.5;
  250. }
  251. path.push([pathType, targetX, targetY]);
  252. if (i>0 && i < this.getAnchorsCount()-1) {
  253. path.push(["C", ax, ay, bx, by, zx, zy]);
  254. }
  255. }
  256. if (this.closePath) {
  257. console.log("closePath:", this.closePath);
  258. path.push(["Z"]);
  259. }
  260. this.path = path;
  261. },
  262. transform: function(transformation){
  263. this.element.transform(transformation);
  264. },
  265. attr: function(attrs){
  266. //console.log("attrs: " +attrs, "", this.element);
  267. // TODO: foreach and set each
  268. this.element.attr(attrs);
  269. }
  270. };
  271. function Polygone(points, strokeWidth) {
  272. /* Array on coordinates:
  273. * points: [{x: 410, y: 110}, 1
  274. * {x: 570, y: 110}, 1 2
  275. * {x: 620, y: 240}, 2 3
  276. * {x: 750, y: 270}, 3 4
  277. * {x: 650, y: 370}]; 4
  278. */
  279. this.points = points;
  280. /*
  281. * path for graph
  282. * [["M", x1, y1], ["L", x2, y2], ["C", ax, ay, bx, by, x3, y3], ["L", x3, y3]]
  283. */
  284. this.path = [];
  285. this.anchors = [];
  286. if (strokeWidth) this.strokeWidth = strokeWidth;
  287. this.closePath = true;
  288. this.init();
  289. };
  290. /*
  291. * Poligone is inherited from Poliline: draws closedPath of polyline
  292. */
  293. var Foo = function () { };
  294. Foo.prototype = Polyline.prototype;
  295. Polygone.prototype = new Foo();
  296. Polygone.prototype.rebuildPath = function(){
  297. var path = [];
  298. //console.log("Polygone rebuildPath");
  299. for(var i = 0; i < this.getAnchorsCount(); i++){
  300. var anchor = this.getAnchor(i);
  301. var pathType = ""
  302. if (i==0)
  303. pathType = "M";
  304. else
  305. pathType = "L";
  306. var targetX = anchor.x, targetY = anchor.y;
  307. // anti smoothing
  308. if (this.strokeWidth%2 == 1) {
  309. targetX += 0.5;
  310. targetY += 0.5;
  311. }
  312. path.push([pathType, targetX, targetY]);
  313. }
  314. if (this.closePath)
  315. path.push(["Z"]);
  316. this.path = path;
  317. };
  318. /*
  319. Polygone.prototype.transform = function(transformation){
  320. this.element.transform(transformation);
  321. };
  322. */