123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- /**
- * Class to generate polyline
- *
- * @author Dmitry Farafonov
- */
-
- var ANCHOR_TYPE= {
- main: "main",
- middle: "middle",
- first: "first",
- last: "last"
- };
- function Anchor(uuid, type, x, y) {
- this.uuid = uuid;
- this.x = x
- this.y = y
- this.type = (type == ANCHOR_TYPE.middle) ? ANCHOR_TYPE.middle : ANCHOR_TYPE.main;
- };
- Anchor.prototype = {
- uuid: null,
- x: 0,
- y: 0,
- type: ANCHOR_TYPE.main,
- isFirst: false,
- isLast: false,
- ndex: 0,
- typeIndex: 0
- };
- function Polyline(uuid, points, strokeWidth) {
- /* Array on coordinates:
- * points: [{x: 410, y: 110}, 1
- * {x: 570, y: 110}, 1 2
- * {x: 620, y: 240}, 2 3
- * {x: 750, y: 270}, 3 4
- * {x: 650, y: 370}]; 4
- */
- this.points = points;
-
- /*
- * path for graph
- * [["M", x1, y1], ["L", x2, y2], ["C", ax, ay, bx, by, x3, y3], ["L", x3, y3]]
- */
- this.path = [];
-
- this.anchors = [];
-
- if (strokeWidth) this.strokeWidth = strokeWidth;
-
- this.closePath = false;
-
- this.init();
- };
- Polyline.prototype = {
- id: null,
- points: [],
- path: [],
- anchors: [],
- strokeWidth: 1,
- radius: 15,
- showDetails: false,
- element: null,
- isDefaultConditionAvailable: false,
- closePath: false,
-
- init: function(points){
- var linesCount = this.getLinesCount();
- if (linesCount < 1)
- return;
-
- this.normalizeCoordinates();
-
- // create anchors
-
- this.pushAnchor(ANCHOR_TYPE.first, this.getLine(0).x1, this.getLine(0).y1);
-
- for(var i = 1; i < linesCount; i++){
- var line1 = this.getLine(i-1),
- line2 = this.getLine(i);
-
- //this.pushAnchor(ANCHOR_TYPE.middle, line1.x1 + line1.x2-line1.x1, line1.y1 + line1.y2-line1.y1);
- this.pushAnchor(ANCHOR_TYPE.main, line1.x2, line1.y2);
- //this.pushAnchor(ANCHOR_TYPE.middle, line2.x1 + line2.x2-line2.x1, line2.y1 + line2.y2-line2.y1);
- }
-
- this.pushAnchor(ANCHOR_TYPE.last, this.getLine(linesCount-1).x2, this.getLine(linesCount-1).y2);
-
- this.rebuildPath();
- },
-
- normalizeCoordinates: function(){
- for(var i=0; i < this.points.length; i++){
- this.points[i].x = parseFloat(this.points[i].x);
- this.points[i].y = parseFloat(this.points[i].y);
- }
- },
-
- getLinesCount: function(){
- return this.points.length-1;
- },
- _getLine: function(i){
- return {x1: this.points[i].x, y1: this.points[i].y, x2: this.points[i+1].x, y2: this.points[i+1].y};
- },
- getLine: function(i){
- var line = this._getLine(i);
- line.angle = this.getLineAngle(i) ;
- return line;
- },
- getLineAngle: function(i){
- var line = this._getLine(i);
- return Math.atan2(line.y2 - line.y1, line.x2 - line.x1);
- },
- getLineLengthX: function(i){
- var line = this.getLine(i);
- return (line.x2 - line.x1);
- },
- getLineLengthY: function(i){
- var line = this.getLine(i);
- return (line.y2 - line.y1);
- },
- getLineLength: function(i){
- var line = this.getLine(i);
- return Math.sqrt(Math.pow(this.getLineLengthX(i), 2) + Math.pow(this.getLineLengthY(i), 2));
- },
-
- getAnchors: function(){
- // ������� ��������������� ������
- // ????
- return this.anchors;
- },
- getAnchorsCount: function(type){
- if (!type)
- return this.anchors.length;
- else {
- var count = 0;
- for(var i=0; i < this.getAnchorsCount(); i++){
- var anchor = this.anchors[i];
- if (anchor.getType() == type) {
- count++;
- }
- }
- return count;
- }
- },
-
- pushAnchor: function(type, x, y, index){
- if (type == ANCHOR_TYPE.first) {
- index = 0;
- typeIndex = 0;
- } else if (type == ANCHOR_TYPE.last) {
- index = this.getAnchorsCount();
- typeIndex = 0;
- } else if (!index) {
- index = this.anchors.length;
- } else {
- // ��������� anchors, �������� ������� ��� �������, ������� � index
- //var anchor = this.getAnchor()
- for(var i=0; i < this.getAnchorsCount(); i++){
- var anchor = this.anchors[i];
- if (anchor.index > index) {
- anchor.index++;
- anchor.typeIndex++;
- }
- }
- }
-
- var anchor = new Anchor(this.id, ANCHOR_TYPE.main, x, y, index, typeIndex);
-
- this.anchors.push(anchor);
- },
-
- getAnchor: function(position){
- return this.anchors[position];
- },
-
- getAnchorByType: function(type, position){
- if (type == ANCHOR_TYPE.first)
- return this.anchors[0];
- if (type == ANCHOR_TYPE.last)
- return this.anchors[this.getAnchorsCount()-1];
-
- for(var i=0; i < this.getAnchorsCount(); i++){
- var anchor = this.anchors[i];
- if (anchor.type == type) {
- if( position == anchor.position)
- return anchor;
- }
- }
- return null;
- },
-
- addNewPoint: function(position, x, y){
- //
- for(var i = 0; i < this.getLinesCount(); i++){
- var line = this.getLine(i);
- if (x > line.x1 && x < line.x2 && y > line.y1 && y < line.y2) {
- this.points.splice(i+1,0,{x: x, y: y});
- break;
- }
- }
-
- this.rebuildPath();
- },
-
- rebuildPath: function(){
- var path = [];
-
- for(var i = 0; i < this.getAnchorsCount(); i++){
- var anchor = this.getAnchor(i);
-
- var pathType = ""
- if (i==0)
- pathType = "M";
- else
- pathType = "L";
-
- // TODO: save previous points and calculate new path just if points are updated, and then save currents values as previous
-
- var targetX = anchor.x, targetY = anchor.y;
- if (i>0 && i < this.getAnchorsCount()-1) {
- // get new x,y
- var cx = anchor.x, cy = anchor.y;
-
- // pivot point of prev line
- var AO = this.getLineLength(i-1);
- if (AO < this.radius) {
- AO = this.radius;
- }
-
- this.isDefaultConditionAvailable = (this.isDefaultConditionAvailable || (i == 1 && AO > 10));
- //console.log("isDefaultConditionAvailable", this.isDefaultConditionAvailable);
-
- var ED = this.getLineLengthY(i-1) * this.radius / AO;
- var OD = this.getLineLengthX(i-1) * this.radius / AO;
- targetX = anchor.x - OD;
- targetY = anchor.y - ED;
-
- if (AO < 2*this.radius && i>1) {
- targetX = anchor.x - this.getLineLengthX(i-1)/2;
- targetY = anchor.y - this.getLineLengthY(i-1)/2;;
- }
-
- // pivot point of next line
- var AO = this.getLineLength(i);
- if (AO < this.radius) {
- AO = this.radius;
- }
- var ED = this.getLineLengthY(i) * this.radius / AO;
- var OD = this.getLineLengthX(i) * this.radius / AO;
- var nextSrcX = anchor.x + OD;
- var nextSrcY = anchor.y + ED;
-
- if (AO < 2*this.radius && i<this.getAnchorsCount()-2) {
- nextSrcX = anchor.x + this.getLineLengthX(i)/2;
- nextSrcY = anchor.y + this.getLineLengthY(i)/2;;
- }
-
-
- var dx0 = (cx - targetX) / 3,
- dy0 = (cy - targetY) / 3,
- ax = cx - dx0,
- ay = cy - dy0,
-
- dx1 = (cx - nextSrcX) / 3,
- dy1 = (cy - nextSrcY) / 3,
- bx = cx - dx1,
- by = cy - dy1,
-
- zx=nextSrcX, zy=nextSrcY;
-
- if (this.showDetails) {
- var c = ProcessDiagramCanvas.g.path("M"+targetX+","+targetY+"L"+ax+","+ay).attr({stroke: Color.get(255, 153, 51), "stroke-dasharray": "- "});
- var c = ProcessDiagramCanvas.g.path("M"+nextSrcX+","+nextSrcY+"L"+bx+","+by).attr({stroke: Color.get(255, 153, 51), "stroke-dasharray": "- "});
- var c = ProcessDiagramCanvas.g.ellipse(ax, ay, 2, 2).attr({stroke: Color.SlateGrey});
- var c = ProcessDiagramCanvas.g.ellipse(bx, by, 2, 2).attr({stroke: Color.SlateGrey});
- var c = ProcessDiagramCanvas.g.ellipse(cx, cy, this.radius, this.radius).attr({stroke: Color.Gainsboro});
- var c = ProcessDiagramCanvas.g.ellipse(targetX, targetY, 2, 2).attr({fill: Color.red});
- var c = ProcessDiagramCanvas.g.ellipse(nextSrcX, nextSrcY, 2, 2).attr({fill: Color.red});
- }
- } else if (i==1 && this.getAnchorsCount() == 2){
- var AO = this.getLineLength(i-1);
- if (AO < this.radius) {
- AO = this.radius;
- }
- this.isDefaultConditionAvailable = (this.isDefaultConditionAvailable || (i == 1 && AO > 10));
- //console.log("-- isDefaultConditionAvailable", this.isDefaultConditionAvailable);
- }
- // anti smoothing
- if (this.strokeWidth%2 == 1) {
- targetX += 0.5;
- targetY += 0.5;
- }
-
- path.push([pathType, targetX, targetY]);
-
- if (i>0 && i < this.getAnchorsCount()-1) {
- path.push(["C", ax, ay, bx, by, zx, zy]);
- }
- }
-
- if (this.closePath) {
- console.log("closePath:", this.closePath);
- path.push(["Z"]);
- }
-
- this.path = path;
- },
-
- transform: function(transformation){
- this.element.transform(transformation);
- },
- attr: function(attrs){
- //console.log("attrs: " +attrs, "", this.element);
- // TODO: foreach and set each
- this.element.attr(attrs);
- }
- };
- function Polygone(points, strokeWidth) {
- /* Array on coordinates:
- * points: [{x: 410, y: 110}, 1
- * {x: 570, y: 110}, 1 2
- * {x: 620, y: 240}, 2 3
- * {x: 750, y: 270}, 3 4
- * {x: 650, y: 370}]; 4
- */
- this.points = points;
-
- /*
- * path for graph
- * [["M", x1, y1], ["L", x2, y2], ["C", ax, ay, bx, by, x3, y3], ["L", x3, y3]]
- */
- this.path = [];
-
- this.anchors = [];
-
- if (strokeWidth) this.strokeWidth = strokeWidth;
-
- this.closePath = true;
- this.init();
- };
- /*
- * Poligone is inherited from Poliline: draws closedPath of polyline
- */
- var Foo = function () { };
- Foo.prototype = Polyline.prototype;
- Polygone.prototype = new Foo();
- Polygone.prototype.rebuildPath = function(){
- var path = [];
- //console.log("Polygone rebuildPath");
- for(var i = 0; i < this.getAnchorsCount(); i++){
- var anchor = this.getAnchor(i);
-
- var pathType = ""
- if (i==0)
- pathType = "M";
- else
- pathType = "L";
-
- var targetX = anchor.x, targetY = anchor.y;
-
- // anti smoothing
- if (this.strokeWidth%2 == 1) {
- targetX += 0.5;
- targetY += 0.5;
- }
-
- path.push([pathType, targetX, targetY]);
- }
- if (this.closePath)
- path.push(["Z"]);
-
- this.path = path;
- };
- /*
- Polygone.prototype.transform = function(transformation){
- this.element.transform(transformation);
- };
- */
|