source: Dev/trunk/src/client/dojox/drawing/tools/custom/Axes.js

Last change on this file was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

  • Property svn:executable set to *
File size: 14.9 KB
Line 
1define(["dojo/_base/lang", "../../util/oo", "../../manager/_registry", "../../stencil/Path",
2        "../../annotations/Arrow", "../../annotations/Label", "../../tools/custom/Vector"],
3function(lang, oo, registry, StencilPath, Arrow, Label, Vector){
4
5var Axes = oo.declare(
6        StencilPath,
7        function(options){
8                this.closePath = false;
9
10                this.xArrow = new Arrow({stencil:this, idx1:0, idx2:1});
11                this.yArrow = new Arrow({stencil:this, idx1:2, idx2:1});
12                if(options.data){
13                        //Allows import of z-axis in non-enabled canvas and xy-axis in
14                        //enabled canvas
15                        this.style.zAxisEnabled = options.data.cosphi == 1 ? true : false;
16                        this.setData(options.data);
17                }
18                if(this.style.zAxisEnabled){
19                        // If the z-axis is enabled, all axes will be created with a z-axis on the canvas.
20                        // there is no switching back and forth for the axis, only for vectors.
21                        this.data.cosphi = 1;
22                        var ops = {};
23                        lang.mixin(ops,options);
24                        lang.mixin(ops,{
25                                container:this.container.createGroup(),
26                                style: this.style,
27                                showAngle: false,
28                                label: null
29                        });
30                        if(options.data && (!ops.data.radius || !ops.data.angle)){
31                                ops.data.x2 = ops.data.x4;
32                                ops.data.y2 = ops.data.y4;
33                        }
34                        ops.style.zAxis = true;
35                        this.zAxis = new Vector(ops);
36                        this.zAxis.minimumSize = 5;
37                        //console.log("-----constructing axes: ",this.zAxis);
38                        this.connectMult([
39                                [this, "onChangeStyle", this.zAxis, "onChangeStyle"],
40                                [this, "select", this.zAxis, "select"],
41                                [this, "deselect", this.zAxis, "deselect"],
42                                [this, "onDelete", this.zAxis, "destroy"],
43                                [this, "onDrag", this, "zSet"],
44                                [this, "onTransform", this, "zSet"],
45                                [this.zAxis, "onBeforeRender", this, "zSet"],
46                                [this, "_onPostRender", this.zAxis, "render"]
47                        ]);
48
49                }
50
51                if(this.points && this.points.length){
52                        this.setPoints = this._postSetPoints;
53                        // render isn't called yet because baseRender is false
54                        // instead it is called here
55                        this.render();
56                        options.label && this.setLabel(options.label);
57                        options.shadow && this.addShadow(options.shadow);
58                }
59        },
60        {
61                // summary:
62                //              Draws a right-angle Axes (shaped like an L, not a +)
63                // description:
64                //              This Stencil is created with a Path so that the L shape
65                //              is one continuous piece. Arrow heads are placed at the end
66                //              of each axis. The Axes can be rotated. There are custom
67                //              label methods.
68
69                draws:true,
70                type:"dojox.drawing.tools.custom.Axes",
71                minimumSize:30,
72                showAngle:true,
73                closePath:false,
74                baseRender:false,
75                zScale:.5,
76
77                zPoint: function(obj){
78                        // summary:
79                        //              Finds the point for the z axis.
80                        obj.radius = this.util.length(obj);
81                        var pt = this.util.pointOnCircle(obj.start.x, obj.start.y, obj.radius*this.zScale, this.style.zAngle);
82                        return {x:pt.x, y:pt.y, skip:true, noAnchor:true};
83                },
84
85                zSet: function(){
86                        if(!this.zAxis){ return; };
87                        var c = this.points[1];
88                        var z = this.points[3];
89                        var p = [
90                                {x:c.x, y:c.y},
91                                {x:z.x, y:z.y}
92                        ];
93                        var len = this.util.length({start:{x:c.x, y:c.y}, x:z.x, y:z.y});
94                        len > this.zAxis.minimumSize ? this.zAxis.setPoints(p) : false;
95                        this.zAxis.cosphi = 1;
96                },
97
98                createLabels: function(){
99                        // summary:
100                        //              Creates the label for each axis.
101
102                        // NOTE: Not passing style into text because it's changing it
103                        var props = {align:"middle", valign:"middle", util:this.util, annotation:true, container:this.container, mouse:this.mouse, stencil:this};
104                        this.labelX = new Label(lang.mixin(props,{
105                                labelPosition:this.setLabelX
106                        }));
107                        this.labelY = new Label(lang.mixin(props,{
108                                labelPosition:this.setLabelY
109                        }));
110                        if(this.style.zAxisEnabled){
111                                this.labelZ = new Label(lang.mixin(props,{
112                                        labelPosition:this.setLabelZ
113                                }));
114                        }
115
116                },
117
118                setLabelX: function(){
119                        // summary:
120                        //              Custom placement for x-axis label
121
122                        var ax = this.points[0];
123                        var c =  this.points[1];
124
125                        var dist = 40;
126                        var offdist = 20;
127                        var pt, px, py, pt2;
128
129                        pt = this.util.lineSub(c.x, c.y, ax.x, ax.y, dist);
130                        px = pt.x + (pt.y -ax.y);
131                        py = pt.y + (ax.x - pt.x);
132                        pt2 = this.util.lineSub(pt.x, pt.y, px, py, (dist-offdist));
133
134                        return {
135                                x:  pt2.x,
136                                y:  pt2.y,
137                                width:20
138                        };
139                },
140                setLabelY: function(){
141                        // summary:
142                        //              Custom placement for y-axis label
143
144                        var c =  this.points[1];
145                        var ay = this.points[2];
146
147                        var dist = 40;
148                        var offdist = 20;
149                        var pt, px, py, pt2;
150                        pt = this.util.lineSub(c.x, c.y, ay.x, ay.y, dist);
151                        px = pt.x + (ay.y - pt.y);
152                        py = pt.y + (pt.x - ay.x);
153                        pt2 = this.util.lineSub(pt.x, pt.y, px, py, (dist-offdist));
154                        return {
155                                x:  pt2.x,
156                                y:  pt2.y,
157                                width:20
158                        };
159                },
160                setLabelZ: function(){
161                        // summary:
162                        //              Custom placement for z-axis label
163
164                        var c = this.points[1];
165                        var z = this.points[3];
166
167                        var dist = 40;
168                        var offdist = 20;
169                        var pt, px, py, pt2;
170                        pt = this.util.lineSub(c.x, c.y, z.x, z.y, dist);
171                        px = pt.x + (pt.y - z.y);
172                        py = pt.y + (z.x - pt.x);
173                        pt2 = this.util.lineSub(pt.x, pt.y, px, py, (dist-offdist));
174
175                        return {
176                                x:pt2.x,
177                                y:pt2.y,
178                                width:20
179                        }
180                },
181                setLabel: function(/* ? String*/value){
182                        // summary:
183                        //              Set the text of the labels. The text would be
184                        //              broken up into the two labels.
185                        // value: [optional] String
186                        //              If no argument is passed, defaults to two labels
187                        //              'x' and 'y'. If an argument is passed, that
188                        //              text will be split on the word 'and' to determine
189                        //              the two labels.
190
191                        if(this._labelsCreated){ return; }
192                        !this.labelX && this.createLabels();
193                        var x = "x";
194                        var y = "y";
195                        var z = "z";
196                        if(value){
197                                // match first "and" or "&" and trim whitespace.
198                                // Non-greedy matches are not supported in older
199                                // browsers such as Netscape Navigator 4 or
200                                // Microsoft Internet Explorer 5.0.
201                                if(this.labelZ){
202                                        var lbls = value.match(/(.*?)(and|&)(.*?)(and|&)(.*)/i);
203                                        if(lbls.length>4){
204                                                x = lbls[1].replace(/^\s+/,"").replace(/\s+$/,"");
205                                                y = lbls[3].replace(/^\s+/,"").replace(/\s+$/,"");
206                                                z = lbls[5].replace(/^\s+/,"").replace(/\s+$/,"");
207                                        }
208                                }else{
209                                        var lbls = value.match(/(.*?)(and|&)(.*)/i);
210                                        if(lbls.length>2){
211                                                x = lbls[1].replace(/^\s+/,"").replace(/\s+$/,"");
212                                                y = lbls[3].replace(/^\s+/,"").replace(/\s+$/,"");
213                                        }
214                                }
215                        }
216                        this.labelX.setLabel(x);
217                        this.labelY.setLabel(y);
218                        if(this.labelZ){
219                                this.labelZ.setLabel(z);
220                        }
221                        this._labelsCreated = true;
222                },
223                getLabel: function(){
224                        // summary:
225                        //              Getter for the labels. returns an object.
226
227                        if(!this.labelX){ return null; }
228                        return {
229                                x:this.labelX.getText(),
230                                y:this.labelY.getText(),
231                                z:this.labelZ?this.labelZ.getText():null
232                        }; // Object
233                },
234
235                anchorPositionCheck: function(/*Number*/x, /*Number*/y, /*manager.Anchor*/anchor){
236                        // summary:
237                        //              Gets called from anchor to check if its current
238                        //              position is ok. If not, its x or y transform will
239                        //              be changed until this passes.
240
241                        var pm = this.container.getParent().getTransform();
242                        var am = anchor.shape.getTransform();
243
244                        // the xaxis point has changed and is not yet set as a point
245                        //      - but the center should be good (except for the transform).
246                        // Now check the yaxis point.
247
248                        var p = this.points;
249                        var o = {x:am.dx+anchor.org.x+pm.dx, y:am.dy+anchor.org.y+pm.dy};
250                        var c = {x:p[1].x+pm.dx, y:p[1].y+pm.dy};
251                        var ox = c.x - (c.y - o.y);
252                        var oy = c.y - (o.x - c.x);
253
254                        return {x:ox, y:oy};
255
256                },
257
258                onTransformBegin: function(/*manager.Anchor*/anchor){
259                        // summary:
260                        //              Overwrites _Base.onTransformBegin
261
262                        // called from anchor point up mouse down
263                        this._isBeingModified = true;
264                },
265
266                onTransformEnd: function(/*manager.Anchor*/anchor){
267                        // summary:
268                        //              Overwrites _Base.onTransformEnd
269
270                        // Gets called on anchor mouseup
271                        // also gets called by checkBounds - we don't want that.
272                        if(!anchor){ return; }
273
274                        // tell anchor to go to prev point if wrong
275                        // called from anchor point up mouse up
276
277                        this._isBeingModified = false;
278                        //this.deselect();
279                        this._toggleSelected();
280                        console.log("before:", Math.ceil(this.points[1].x), " x ", Math.ceil(this.points[1].y))
281
282                        var o = this.points[0];
283                        var c = this.points[1];
284                        var obj = {start:{x:c.x,y:c.y},x:o.x, y:o.y};
285                        var pt = this.util.constrainAngle(obj, 0, 89);
286                        var zpt = this.style.zAxisEnabled ? this.zPoint(obj) : null;
287
288                        if(pt.x==o.x && pt.y == o.y){
289                                // we're within the constraint, so now we snap
290                                pt = this.util.snapAngle(obj, this.angleSnap/180);
291
292                                obj.x = pt.x;
293                                obj.y = pt.y;
294                                var ox = obj.start.x - (obj.start.y - obj.y);
295                                var oy = obj.start.y - (obj.x - obj.start.x);
296
297                                if(ox<0 || oy<0){
298                                        console.warn("AXES ERROR LESS THAN ZERO - ABORT");
299                                        return;
300                                }
301                                this.points = [{x:obj.x, y:obj.y}, {x:obj.start.x, y:obj.start.y, noAnchor:true}];
302                                this.points.push({x:ox, y:oy, noAnchor:true});
303                                if(zpt){ this.points.push(zpt);}
304                                this.setPoints(this.points);
305
306                                //this.select();
307                                this.onModify(this);
308                                return;
309                        }
310
311                        // we're outside of the constraint. Set to the low or high.
312                        this.points[0].x = pt.x;
313                        this.points[0].y = pt.y;
314                        o = this.points[0];
315
316                        var ox = c.x - (c.y - o.y);
317                        var oy = c.y - (o.x - c.x);
318
319                        this.points[2] = {x:ox, y:oy, noAnchor:true};
320                        if(zpt){ this.points.push(zpt); }
321                        this.setPoints(this.points);
322
323                        // reset handles render
324                        //anchor.reset(this);
325
326                        this.labelX.setLabel();
327                        this.labelY.setLabel();
328                        if(this.labelZ){
329                                this.labelZ.setLabel();
330                        }
331
332                        //this.select();
333                        this.onModify(this);
334
335                },
336
337                getBounds: function(/*Boolean*/absolute){
338                        // summary:
339                        //              Custom getBounds overwrites _Base.getBounds
340
341                        var px = this.points[0],
342                            pc = this.points[1],
343                            py = this.points[2];
344                        if(this.style.zAxisEnabled){ var pz = this.points[3]; }
345
346                        if(absolute){
347                                var bounds = {
348                                        x:pc.x,
349                                        y:pc.y,
350                                        x1:pc.x,
351                                        y1:pc.y,
352                                        x2:px.x,
353                                        y2:px.y,
354                                        x3:py.x,
355                                        y3:py.y
356                                };
357                                if(this.style.zAxisEnabled){
358                                        bounds.x4 = pz.x;
359                                        bounds.y4 = pz.y;
360                                }
361                                return bounds;
362                        }
363
364                        var x1 = this.style.zAxisEnabled ? (py.x < pz.x ? py.x : pz.x) : py.x;
365                            y1 = py.y < px.y ? py.y : px.y,
366                            x2 = px.x,
367                            y2 = this.style.zAxisEnabled ? pz.y : pc.y;
368
369                        return {
370                                x1:x1,
371                                y1:y1,
372                                x2:x2,
373                                y2:y2,
374                                x:x1,
375                                y:y1,
376                                w:x2-x1,
377                                h:y2-y1
378                        };
379                },
380
381                _postSetPoints: function(/*Array*/pts){
382                        // summary:
383                        //              Because Axes only has one anchor,
384                        //              we substitute a special setPoints method
385
386                        this.points[0] = pts[0];
387                        if(this.pointsToData){
388                                this.data = this.pointsToData();
389                        }
390                },
391
392                onTransform: function(/*Number*/anchor){
393                        // summary:
394                        //              Overwrites _Base.onTransform
395
396                        // the xaxis point has changed - the center will not.
397                        // need to find the yaxis point.
398                        var o = this.points[0];
399                        var c = this.points[1];
400                        var ox = c.x - (c.y - o.y);
401                        var oy = c.y - (o.x - c.x);
402
403                        // 'noAnchor' on a point indicates an anchor should
404                        // not be rendered. This is the Y point being set.
405                        this.points[2] = {x:ox, y:oy, noAnchor:true};
406                        if(this.style.zAxisEnabled){
407                                this.points[3] = this.zPoint({start:{x:c.x, y:c.y}, x:o.x, y:o.y});
408                        }
409                        this.setPoints(this.points);
410                        if(!this._isBeingModified){
411                                this.onTransformBegin();
412                        }
413                        this.render();
414                },
415
416                pointsToData: function(){
417                        // summary:
418                        //              Converts points to data.
419                        var p = this.points;
420                        var d = {
421                                x1:p[1].x,
422                                y1:p[1].y,
423                                x2:p[0].x,
424                                y2:p[0].y,
425                                x3:p[2].x,
426                                y3:p[2].y
427                        }
428                        if(this.style.zAxisEnabled){
429                                d.x4 = p[3].x;
430                                d.y4 = p[3].y;
431                                d.cosphi = 1;
432                        }
433                        return d;
434
435                },
436
437                getRadius: function(){
438                        // summary:
439                        //              Possibility of z-axis makes bounds unreliable.
440                        //              Use these points instead.
441                        var p = this.points;
442                        var line = {start:{x:p[1].x, y:p[1].y}, x:p[0].x, y:p[0].y};
443                        return this.util.length(line);
444                },
445
446                dataToPoints: function(/* ? Object*/o){
447                        // summary:
448                        //              Converts data to points.
449                        o = o || this.data;
450                        if(o.radius || o.angle){
451                                // instead of using x1,x2,y1,y1,
452                                // it's been set as x,y,angle,radius
453                                var pt = this.util.pointOnCircle(o.x,o.y,o.radius,o.angle), zpt;
454                                var ox = o.x - (o.y - pt.y);
455                                var oy = o.y - (pt.x - o.x);
456                                if((o.cosphi && o.cosphi==1) || this.style.zAxisEnabled){
457                                        this.style.zAxisEnabled = true;
458                                        zpt = this.util.pointOnCircle(o.x, o.y, o.radius*this.zScale, this.style.zAngle);
459                                }
460                                this.data = o = {
461                                        x1:o.x,
462                                        y1:o.y,
463                                        x2:pt.x,
464                                        y2:pt.y,
465                                        x3:ox,
466                                        y3:oy
467                                }
468                                if(this.style.zAxisEnabled){
469                                        this.data.x4 = o.x4 = zpt.x;
470                                        this.data.y4 = o.y4 = zpt.y;
471                                        this.data.cosphi = 1;
472                                }
473
474                        }
475                        this.points = [
476                                {x:o.x2, y:o.y2},
477                                {x:o.x1, y:o.y1, noAnchor:true},
478                                {x:o.x3, y:o.y3, noAnchor:true}
479                        ];
480                        if(this.style.zAxisEnabled){ this.points.push({x:o.x4, y:o.y4, skip:true, noAnchor:true}); }
481                        return this.points;
482                },
483
484                onDrag: function(/*EventObject*/obj){
485                        // summary:
486                        //              See stencil._Base.onDrag
487
488                        var pt = this.util.constrainAngle(obj, 0, 89);
489                        obj.x = pt.x;
490                        obj.y = pt.y;
491                        var ox = obj.start.x - (obj.start.y - obj.y);
492                        var oy = obj.start.y - (obj.x - obj.start.x);
493
494                        if(ox<0 || oy<0){
495                                return;
496                        }
497                        this.points = [{x:obj.x, y:obj.y}, {x:obj.start.x, y:obj.start.y, noAnchor:true}];
498
499                        this.points.push({x:ox, y:oy, noAnchor:true});
500                        if(this.style.zAxisEnabled){
501                                var zpt = this.zPoint(obj);
502                                this.points.push(zpt);
503                        }
504                        this.render();
505                },
506
507                onUp: function(/*EventObject*/obj){
508                        // summary:
509                        //              See stencil._Base.onUp
510
511                        if(!this._downOnCanvas){ return; }
512                        this._downOnCanvas = false;
513                        var p = this.points;
514                        if(!p.length){
515                                var s = obj.start, d = 100;
516                                this.points = [
517                                        {x:s.x+d, y:s.y+d},
518                                        {x:s.x, y:s.y+d, noAnchor:true},
519                                        {x:s.x, y:s.y, noAnchor:true}
520                                ];
521                                if(this.style.zAxisEnabled){
522                                        var zpt = this.zPoint({start:{x:s.x, y:s.y+d}, x:s.x+d, y:s.y+d});
523                                        this.points.push(zpt);
524                                }
525                                this.setPoints = this._postSetPoints;
526                                this.pointsToData();
527                                this.render();
528                                this.onRender(this);
529                                return;
530                        }
531
532                        var len = this.util.distance(p[1].x ,p[1].y ,p[0].x ,p[0].y );
533                        if(!p || !p.length){
534                                return;
535                        }else if(len < this.minimumSize){
536                                this.remove(this.shape, this.hit);
537                                this.xArrow.remove(this.xArrow.shape, this.xArrow.hit);
538                                this.yArrow.remove(this.yArrow.shape, this.yArrow.hit);
539                                if(this.zArrow){
540                                  this.zArrow.remove(this.zArrow.shape, this.zArrow.hit);
541                                }
542                                return;
543                        }
544
545                        var o = p[0];
546                        var c = p[1];
547                        obj = {start:{x:c.x,y:c.y},x:o.x,y:o.y};
548                        var pt = this.util.snapAngle(obj, this.angleSnap/180);
549                        obj.x = pt.x;
550                        obj.y = pt.y;
551                        var ox = obj.start.x - (obj.start.y - obj.y);
552                        var oy = obj.start.y - (obj.x - obj.start.x);
553
554                        if(ox<0 || oy<0){
555                                return;
556                        }
557                        this.points = [{x:obj.x, y:obj.y}, {x:obj.start.x, y:obj.start.y, noAnchor:true}];
558
559                        this.points.push({x:ox, y:oy, noAnchor:true});
560                        if(this.style.zAxisEnabled){ this.points.push(this.zPoint(obj)); }
561                        this.onRender(this);
562                        this.setPoints = this._postSetPoints;
563                }
564        }
565);
566
567lang.setObject("dojox.drawing.tools.custom.Axes", Axes);
568Axes.setup = {
569        // summary:
570        //              See stencil._Base ToolsSetup
571
572        name:"dojox.drawing.tools.custom.Axes",
573        tooltip:"Axes Tool",
574        iconClass:"iconAxes"
575};
576registry.register(Axes.setup, "tool");
577
578return Axes;
579});
Note: See TracBrowser for help on using the repository browser.