Merge lp:~makyo/juju-gui/add-rel-improvements into lp:juju-gui/experimental
- add-rel-improvements
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 233 |
Proposed branch: | lp:~makyo/juju-gui/add-rel-improvements |
Merge into: | lp:juju-gui/experimental |
Diff against target: |
183 lines (+55/-37) 2 files modified
app/views/environment.js (+52/-37) test/test_environment_view.js (+3/-0) |
To merge this branch: | bzr merge lp:~makyo/juju-gui/add-rel-improvements |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju GUI Hackers | Pending | ||
Review via email: mp+131542@code.launchpad.net |
Commit message
Description of the change
Add-relation improvements
UX improvements per Jovan: draglines should start with the long-click as an indicator that the user will be dragging a line; draglines should be on top of all services/lines, as they are currently the most important thing the user is working with; and draglines should be used when adding a relation from the service menu as well, showing that a relation will be created.
Madison Scott-Clary (makyo) wrote : | # |
- 208. By Madison Scott-Clary
-
Add-relation improvements
- 209. By Madison Scott-Clary
-
Add-relation improvements
- 210. By Madison Scott-Clary
-
Add-relation improvements
Madison Scott-Clary (makyo) wrote : | # |
Please take a look.
Gary Poster (gary) wrote : | # |
Hi Matt. This looks like it will be a step in a good direction. I just went for a cruise around the UX for a second before I looked at the code, and I saw a few things that you might want to address, or at least run past Jovan, before a more thorough review.
- the two experiences of starting from long-click and starting from the service menu are different in ways that surprise me, and in at least one case seems like at error. In general I prefer the long-click behavior.
* lines started from the service menu can go crazy when you hover over things that are not a target service. For example, try hovering over a relationship name. For me, the line then goes from the service start point to [0, 0]. I see other similar issues that I won't clarify now, but if you can't dupe I'll be happy to provide more details and screenshots. (This does not happen with long-click.)
* lines started from the service menu cannot go over the service, unlike the change you made for long-click. I think they ought to be the same.
Also, unrelatedly but concerningly, I discovered bug 1072433. That looks pretty critical, but it is in the trunk. I put that in the kanban board.
I'm going to stop the review for now until I hear back from you on how you want to handle my UX observations.
Thanks,
Gary
Madison Scott-Clary (makyo) wrote : | # |
On 10/28/2012 08:53 PM, Gary Poster wrote:
> Hi Matt. This looks like it will be a step in a good direction. I just went for a cruise around the UX for a second before I looked at the code, and I saw a few things that you might want to address, or at least run past Jovan, before a more thorough review.
>
> - the two experiences of starting from long-click and starting from the service menu are different in ways that surprise me, and in at least one case seems like at error. In general I prefer the long-click behavior.
> * lines started from the service menu can go crazy when you hover over things that are not a target service. For example, try hovering over a relationship name. For me, the line then goes from the service start point to [0, 0]. I see other similar issues that I won't clarify now, but if you can't dupe I'll be happy to provide more details and screenshots. (This does not happen with long-click.)
> * lines started from the service menu cannot go over the service, unlike the change you made for long-click. I think they ought to be the same.
>
> Also, unrelatedly but concerningly, I discovered bug 1072433. That looks pretty critical, but it is in the trunk. I put that in the kanban board.
>
> I'm going to stop the review for now until I hear back from you on how you want to handle my UX observations.
>
> Thanks,
>
> Gary
Thanks for the catch - looks like mousemove events aren't bubbling how I
thought they would, and I was working on a mostly empty environment.
I'll investigate all these points.
- 211. By Madison Scott-Clary
-
Add-relation improvements
Preview Diff
1 | === modified file 'app/views/environment.js' | |||
2 | --- app/views/environment.js 2012-10-29 10:01:29 +0000 | |||
3 | +++ app/views/environment.js 2012-10-30 08:16:22 +0000 | |||
4 | @@ -33,6 +33,8 @@ | |||
5 | 33 | var box = this.get('active_service'), | 33 | var box = this.get('active_service'), |
6 | 34 | service = this.serviceForBox(box), | 34 | service = this.serviceForBox(box), |
7 | 35 | context = this.get('active_context'); | 35 | context = this.get('active_context'); |
8 | 36 | this.addRelationDragStart.call(this, box, context); | ||
9 | 37 | this.clickAddRelation = true; | ||
10 | 36 | this.service_click_actions | 38 | this.service_click_actions |
11 | 37 | .toggleControlPanel(box, this, context); | 39 | .toggleControlPanel(box, this, context); |
12 | 38 | this.service_click_actions | 40 | this.service_click_actions |
13 | @@ -81,6 +83,12 @@ | |||
14 | 81 | if (!d.containsPoint(mouse_coords, self.zoom)) { | 83 | if (!d.containsPoint(mouse_coords, self.zoom)) { |
15 | 82 | return; | 84 | return; |
16 | 83 | } | 85 | } |
17 | 86 | |||
18 | 87 | // Do not fire if we're on the same service. | ||
19 | 88 | if (d === self.get('addRelationStart_service')) { | ||
20 | 89 | return; | ||
21 | 90 | } | ||
22 | 91 | |||
23 | 84 | self.set('potential_drop_point_service', d); | 92 | self.set('potential_drop_point_service', d); |
24 | 85 | self.set('potential_drop_point_rect', rect); | 93 | self.set('potential_drop_point_rect', rect); |
25 | 86 | self.addSVGClass(rect, 'hover'); | 94 | self.addSVGClass(rect, 'hover'); |
26 | @@ -121,6 +129,13 @@ | |||
27 | 121 | self.dragline.attr('class', | 129 | self.dragline.attr('class', |
28 | 122 | 'relation pending-relation dragline dragging'); | 130 | 'relation pending-relation dragline dragging'); |
29 | 123 | } | 131 | } |
30 | 132 | }, | ||
31 | 133 | mousemove: function(d, self) { | ||
32 | 134 | if (self.clickAddRelation) { | ||
33 | 135 | var container = self.get('container'), | ||
34 | 136 | node = container.one('#canvas rect:first-child'); | ||
35 | 137 | self.rectMousemove.call(node.getDOMNode(), d, self); | ||
36 | 138 | } | ||
37 | 124 | } | 139 | } |
38 | 125 | }, | 140 | }, |
39 | 126 | '.sub-rel-block': { | 141 | '.sub-rel-block': { |
40 | @@ -152,7 +167,14 @@ | |||
41 | 152 | 167 | ||
42 | 153 | // Relation Related | 168 | // Relation Related |
43 | 154 | '.rel-label': { | 169 | '.rel-label': { |
45 | 155 | click: 'relationClick' | 170 | click: 'relationClick', |
46 | 171 | mousemove: function(d, self) { | ||
47 | 172 | if (self.clickAddRelation) { | ||
48 | 173 | var container = self.get('container'), | ||
49 | 174 | node = container.one('#canvas rect:first-child'); | ||
50 | 175 | self.rectMousemove.call(node.getDOMNode(), d, self); | ||
51 | 176 | } | ||
52 | 177 | } | ||
53 | 156 | }, | 178 | }, |
54 | 157 | 179 | ||
55 | 158 | // Canvas related | 180 | // Canvas related |
56 | @@ -162,7 +184,8 @@ | |||
57 | 162 | container.all('.environment-menu.active').removeClass('active'); | 184 | container.all('.environment-menu.active').removeClass('active'); |
58 | 163 | self.service_click_actions.toggleControlPanel(null, self); | 185 | self.service_click_actions.toggleControlPanel(null, self); |
59 | 164 | self.cancelRelationBuild(); | 186 | self.cancelRelationBuild(); |
61 | 165 | } | 187 | }, |
62 | 188 | mousemove: 'rectMousemove' | ||
63 | 166 | } | 189 | } |
64 | 167 | }, | 190 | }, |
65 | 168 | 191 | ||
66 | @@ -184,19 +207,6 @@ | |||
67 | 184 | // we have the correct event in d3.event for d3.mouse(). | 207 | // we have the correct event in d3.event for d3.mouse(). |
68 | 185 | d3.event = e; | 208 | d3.event = e; |
69 | 186 | 209 | ||
70 | 187 | // Flash an indicator around the center of the service block. | ||
71 | 188 | var center = d.getCenter(); | ||
72 | 189 | self.vis.append('circle') | ||
73 | 190 | .attr('cx', center[0]) | ||
74 | 191 | .attr('cy', center[1]) | ||
75 | 192 | .attr('r', 100) | ||
76 | 193 | .attr('class', 'mouse-down-indicator') | ||
77 | 194 | .transition() | ||
78 | 195 | .duration(750) | ||
79 | 196 | .ease('bounce') | ||
80 | 197 | .attr('r', 0) | ||
81 | 198 | .remove(); | ||
82 | 199 | |||
83 | 200 | // Start the process of adding a relation | 210 | // Start the process of adding a relation |
84 | 201 | self.addRelationDragStart.call(self, d, this); | 211 | self.addRelationDragStart.call(self, d, this); |
85 | 202 | }, [d, evt], false); | 212 | }, [d, evt], false); |
86 | @@ -409,6 +419,18 @@ | |||
87 | 409 | self.removeRelationConfirm(d, this, self); | 419 | self.removeRelationConfirm(d, this, self); |
88 | 410 | }, | 420 | }, |
89 | 411 | 421 | ||
90 | 422 | rectMousemove: function(d, self) { | ||
91 | 423 | // If we're clicking to add a relation, make sure a dragline | ||
92 | 424 | // follows the mouse cursor. | ||
93 | 425 | if (self.clickAddRelation) { | ||
94 | 426 | var mouse = d3.mouse(this); | ||
95 | 427 | d3.event.x = mouse[0]; | ||
96 | 428 | d3.event.y = mouse[1]; | ||
97 | 429 | self.addRelationDrag | ||
98 | 430 | .call(self, self.get('addRelationStart_service'), this); | ||
99 | 431 | } | ||
100 | 432 | }, | ||
101 | 433 | |||
102 | 412 | /* | 434 | /* |
103 | 413 | * Sync view models with current db.models. | 435 | * Sync view models with current db.models. |
104 | 414 | */ | 436 | */ |
105 | @@ -1030,22 +1052,25 @@ | |||
106 | 1030 | 1052 | ||
107 | 1031 | addRelationDragStart: function(d, context) { | 1053 | addRelationDragStart: function(d, context) { |
108 | 1032 | // Create a pending drag-line behind services. | 1054 | // Create a pending drag-line behind services. |
110 | 1033 | var dragline = this.vis.insert('line', '.service') | 1055 | var dragline = this.vis.append('line') |
111 | 1034 | .attr('class', 'relation pending-relation dragline dragging'), | 1056 | .attr('class', 'relation pending-relation dragline dragging'), |
112 | 1035 | self = this; | 1057 | self = this; |
113 | 1036 | 1058 | ||
120 | 1037 | // Start the line in the middle of the service. | 1059 | // Start the line between the cursor and the nearest connector |
121 | 1038 | var point = d.getCenter(); | 1060 | // point on the service. |
122 | 1039 | dragline.attr('x1', point[0]) | 1061 | var mouse = d3.mouse(Y.one('svg').getDOMNode()); |
123 | 1040 | .attr('y1', point[1]) | 1062 | self.cursorBox = views.BoundingBox(); |
124 | 1041 | .attr('x2', point[0]) | 1063 | self.cursorBox.pos = {x: mouse[0], y: mouse[1], w: 0, h: 0}; |
125 | 1042 | .attr('y2', point[1]); | 1064 | var point = self.cursorBox.getConnectorPair(d); |
126 | 1065 | dragline.attr('x1', point[0][0]) | ||
127 | 1066 | .attr('y1', point[0][1]) | ||
128 | 1067 | .attr('x2', point[1][0]) | ||
129 | 1068 | .attr('y2', point[1][1]); | ||
130 | 1043 | self.dragline = dragline; | 1069 | self.dragline = dragline; |
131 | 1044 | self.cursorBox = views.BoundingBox(); | ||
132 | 1045 | 1070 | ||
133 | 1046 | // Start the add-relation process. | 1071 | // Start the add-relation process. |
134 | 1047 | self.service_click_actions | 1072 | self.service_click_actions |
136 | 1048 | .addRelationStart(d, self, context); | 1073 | .addRelationStart(d, self, context); |
137 | 1049 | }, | 1074 | }, |
138 | 1050 | 1075 | ||
139 | 1051 | addRelationDrag: function(d, context) { | 1076 | addRelationDrag: function(d, context) { |
140 | @@ -1142,6 +1167,7 @@ | |||
141 | 1142 | this.dragline.remove(); | 1167 | this.dragline.remove(); |
142 | 1143 | this.dragline = null; | 1168 | this.dragline = null; |
143 | 1144 | } | 1169 | } |
144 | 1170 | this.clickAddRelation = null; | ||
145 | 1145 | this.set('currentServiceClickAction', 'toggleControlPanel'); | 1171 | this.set('currentServiceClickAction', 'toggleControlPanel'); |
146 | 1146 | this.show(this.vis.selectAll('.service')) | 1172 | this.show(this.vis.selectAll('.service')) |
147 | 1147 | .classed('selectable-service', false); | 1173 | .classed('selectable-service', false); |
148 | @@ -1500,19 +1526,8 @@ | |||
149 | 1500 | return a[0].name + a[1].name < b[0].name + b[1].name; | 1526 | return a[0].name + a[1].name < b[0].name + b[1].name; |
150 | 1501 | }); | 1527 | }); |
151 | 1502 | 1528 | ||
165 | 1503 | // Create a pending line if it doesn't exist, as in the case of | 1529 | // Stop rubberbanding on mousemove. |
166 | 1504 | // clicking to add relation. | 1530 | view.clickAddRelation = null; |
154 | 1505 | if (!view.dragline) { | ||
155 | 1506 | var dragline = view.vis.insert('line', '.service') | ||
156 | 1507 | .attr('class', 'relation pending-relation dragline'), | ||
157 | 1508 | points = m.getConnectorPair( | ||
158 | 1509 | view.get('addRelationStart_service')); | ||
159 | 1510 | dragline.attr('x1', points[0][0]) | ||
160 | 1511 | .attr('y1', points[0][1]) | ||
161 | 1512 | .attr('x2', points[1][0]) | ||
162 | 1513 | .attr('y2', points[1][1]); | ||
163 | 1514 | view.dragline = dragline; | ||
164 | 1515 | } | ||
167 | 1516 | 1531 | ||
168 | 1517 | // Display menu with available endpoints. | 1532 | // Display menu with available endpoints. |
169 | 1518 | var menu = container.one('#ambiguous-relation-menu'); | 1533 | var menu = container.one('#ambiguous-relation-menu'); |
170 | 1519 | 1534 | ||
171 | === modified file 'test/test_environment_view.js' | |||
172 | --- test/test_environment_view.js 2012-10-25 09:52:10 +0000 | |||
173 | +++ test/test_environment_view.js 2012-10-30 08:16:22 +0000 | |||
174 | @@ -339,6 +339,9 @@ | |||
175 | 339 | container.all('.selectable-service') | 339 | container.all('.selectable-service') |
176 | 340 | .size() | 340 | .size() |
177 | 341 | .should.equal(2); | 341 | .should.equal(2); |
178 | 342 | container.all('.dragline') | ||
179 | 343 | .size() | ||
180 | 344 | .should.equal(1); | ||
181 | 342 | service.next().simulate('click'); | 345 | service.next().simulate('click'); |
182 | 343 | container.all('.selectable-service').size() | 346 | container.all('.selectable-service').size() |
183 | 344 | .should.equal(0); | 347 | .should.equal(0); |
Reviewers: mp+131542_ code.launchpad. net,
Message:
Please take a look.
Description:
Add-relation improvements
UX improvements per Jovan: draglines should start with the long-click as
an indicator that the user will be dragging a line; draglines should be
on top of all services/lines, as they are currently the most important
thing the user is working with; and draglines should be used when adding
a relation from the service menu as well, showing that a relation will
be created.
https:/ /code.launchpad .net/~makyo/ juju-gui/ add-rel- improvements/ +merge/ 131542
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/6786050/
Affected files: environment. js environment_ view.js
A [revision details]
M app/views/
M test/test_
Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: <email address hidden>
+New revision: <email address hidden>
Index: test/test_ environment_ view.js environment_ view.js' environment_ view.js 2012-10-20 18:16:19 +0000 environment_ view.js 2012-10-26 07:54:00 +0000
container. all('.selectabl e-service' )
.size( )
.should. equal(2) ; all('.dragline' )
service. next(). simulate( 'click' );
container. all('.selectabl e-service' ).size( )
.should. equal(0) ;
=== modified file 'test/test_
--- test/test_
+++ test/test_
@@ -339,6 +339,9 @@
+ container.
+ .size()
+ .should.equal(1);
Index: app/views/ environment. js environment. js' environment. js 2012-10-26 06:35:16 +0000 environment. js 2012-10-26 07:48:26 +0000 'active_ service' ),
service = this.serviceFor Box(box) ,
context = this.get( 'active_ context' ); nDragStart. call(this, box, context); lation = true;
this. service_ click_actions
.toggleCon trolPanel( box, this, context);
this. service_ click_actions nt(mouse_ coords, self.zoom)) {
return; 'addRelationSta rt_service' )) {
self. set('potential_ drop_point_ service' , d);
self. set('potential_ drop_point_ rect', rect);
self. addSVGClass( rect, 'hover');
=== modified file 'app/views/
--- app/views/
+++ app/views/
@@ -33,6 +33,8 @@
var box = this.get(
+ this.addRelatio
+ this.clickAddRe
@@ -81,6 +83,12 @@
if (!d.containsPoi
}
+
+ // Do not fire if we're on the same service.
+ if (d === self.get(
+ return;
+ }
+
@@ -162,6 +170,17 @@
container. all('.environme nt-menu. active' ).removeClass( 'active' );
self. service_ click_actions. toggleControlPa nel(null, self);
self. cancelRelationB uild();
+ },
+ mousemove: function(d, self) {
+ // If we're clicking to add a relation, make sure a dragline
+ // follows the mouse cursor.
+ ...