pageflow-sitemap 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (184) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +25 -0
  3. data/.jshintrc +18 -0
  4. data/Gemfile +24 -0
  5. data/LICENSE.md +20 -0
  6. data/README.md +47 -0
  7. data/Rakefile +32 -0
  8. data/app/assets/images/pageflow/sitemap/.keep +0 -0
  9. data/app/assets/javascripts/pageflow/sitemap/.keep +0 -0
  10. data/app/assets/javascripts/pageflow/sitemap/editor/controllers/abstract_controller.js +68 -0
  11. data/app/assets/javascripts/pageflow/sitemap/editor/controllers/editor_mode_controller.js +301 -0
  12. data/app/assets/javascripts/pageflow/sitemap/editor/controllers/fragment_parser.js +31 -0
  13. data/app/assets/javascripts/pageflow/sitemap/editor/controllers/selection_mode_controller.js +37 -0
  14. data/app/assets/javascripts/pageflow/sitemap/editor/controllers/selection_navigator.js +43 -0
  15. data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/mouse_wheel.js +43 -0
  16. data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/multi_drag.js +73 -0
  17. data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/scroll_and_zoom.js +286 -0
  18. data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/selection_rect.js +104 -0
  19. data/app/assets/javascripts/pageflow/sitemap/editor/d3/behaviors/tooltip_target.js +24 -0
  20. data/app/assets/javascripts/pageflow/sitemap/editor/d3/graph_view.js +277 -0
  21. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/chapter_collision.js +33 -0
  22. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/collision.js +116 -0
  23. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/dragging_decorator.js +58 -0
  24. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/grid.js +238 -0
  25. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout/link_dragging_decorator.js +42 -0
  26. data/app/assets/javascripts/pageflow/sitemap/editor/d3/layout.js +94 -0
  27. data/app/assets/javascripts/pageflow/sitemap/editor/d3/options.js +25 -0
  28. data/app/assets/javascripts/pageflow/sitemap/editor/d3/paths/follow_path.js +36 -0
  29. data/app/assets/javascripts/pageflow/sitemap/editor/d3/paths/linkpath.js +64 -0
  30. data/app/assets/javascripts/pageflow/sitemap/editor/d3/paths/successor_path.js +49 -0
  31. data/app/assets/javascripts/pageflow/sitemap/editor/d3/utils.js +33 -0
  32. data/app/assets/javascripts/pageflow/sitemap/editor/d3/view_model.js +202 -0
  33. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/add_button_view.js +28 -0
  34. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/chapter_placeholders_view.js +22 -0
  35. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/chapters_view.js +89 -0
  36. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/group_view.js +104 -0
  37. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/page_links_view.js +7 -0
  38. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/pages_view.js +112 -0
  39. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/selectable_links_view.js +104 -0
  40. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/storylines_view.js +86 -0
  41. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/successor_links_view.js +7 -0
  42. data/app/assets/javascripts/pageflow/sitemap/editor/d3/views/text_label_view.js +45 -0
  43. data/app/assets/javascripts/pageflow/sitemap/editor/d3.js +20 -0
  44. data/app/assets/javascripts/pageflow/sitemap/editor/feature.js +126 -0
  45. data/app/assets/javascripts/pageflow/sitemap/editor/models/selection.js +41 -0
  46. data/app/assets/javascripts/pageflow/sitemap/editor/templates/scroll_bar.jst.ejs +2 -0
  47. data/app/assets/javascripts/pageflow/sitemap/editor/templates/sitemap.jst.ejs +85 -0
  48. data/app/assets/javascripts/pageflow/sitemap/editor/views/scroll_bar_view.js +130 -0
  49. data/app/assets/javascripts/pageflow/sitemap/editor/views/scroll_pane_view.js +73 -0
  50. data/app/assets/javascripts/pageflow/sitemap/editor/views/sitemap_view.js +137 -0
  51. data/app/assets/javascripts/pageflow/sitemap/editor.js +14 -0
  52. data/app/assets/javascripts/pageflow/sitemap/feature.js +3 -0
  53. data/app/assets/javascripts/pageflow/sitemap/scroll_navigator.js +112 -0
  54. data/app/assets/javascripts/pageflow/sitemap.js +5 -0
  55. data/app/assets/stylesheets/pageflow/sitemap/.keep +0 -0
  56. data/app/assets/stylesheets/pageflow/sitemap/editor/add_button.scss +29 -0
  57. data/app/assets/stylesheets/pageflow/sitemap/editor/chapter_placeholders.scss +14 -0
  58. data/app/assets/stylesheets/pageflow/sitemap/editor/chapters.scss +62 -0
  59. data/app/assets/stylesheets/pageflow/sitemap/editor/page_links.scss +19 -0
  60. data/app/assets/stylesheets/pageflow/sitemap/editor/pages.scss +78 -0
  61. data/app/assets/stylesheets/pageflow/sitemap/editor/scroll_bar.css.scss +33 -0
  62. data/app/assets/stylesheets/pageflow/sitemap/editor/scroll_pane.scss +15 -0
  63. data/app/assets/stylesheets/pageflow/sitemap/editor/selectable_links.scss +88 -0
  64. data/app/assets/stylesheets/pageflow/sitemap/editor/selection_rect.scss +12 -0
  65. data/app/assets/stylesheets/pageflow/sitemap/editor/storylines.scss +59 -0
  66. data/app/assets/stylesheets/pageflow/sitemap/editor/successor_links.scss +42 -0
  67. data/app/assets/stylesheets/pageflow/sitemap/editor/text_label.scss +23 -0
  68. data/app/assets/stylesheets/pageflow/sitemap/editor/toolbar.css.scss +45 -0
  69. data/app/assets/stylesheets/pageflow/sitemap/editor.css.scss +96 -0
  70. data/config/locales/de.yml +16 -0
  71. data/config/locales/en.yml +48 -0
  72. data/config/locales/new/help_button.de.yml +7 -0
  73. data/config/locales/new/help_button.en.yml +7 -0
  74. data/config/locales/new/tooltips.de.yml +11 -0
  75. data/config/locales/new/tooltips.en.yml +11 -0
  76. data/config/routes.rb +7 -0
  77. data/config/spring.rb +1 -0
  78. data/exec/rails +12 -0
  79. data/exec/spring +18 -0
  80. data/exec/teaspoon +17 -0
  81. data/lib/pageflow/sitemap/engine.rb +10 -0
  82. data/lib/pageflow/sitemap/plugin.rb +11 -0
  83. data/lib/pageflow/sitemap/version.rb +5 -0
  84. data/lib/pageflow-sitemap.rb +9 -0
  85. data/pageflow-sitemap.gemspec +29 -0
  86. data/spec/d/r/.gitignore +16 -0
  87. data/spec/d/r/README.rdoc +28 -0
  88. data/spec/d/r/Rakefile +6 -0
  89. data/spec/d/r/app/admin/dashboard.rb +33 -0
  90. data/spec/d/r/app/assets/images/.keep +0 -0
  91. data/spec/d/r/app/assets/javascripts/active_admin.js.coffee +2 -0
  92. data/spec/d/r/app/assets/javascripts/application.js +16 -0
  93. data/spec/d/r/app/assets/javascripts/pageflow/application.js +1 -0
  94. data/spec/d/r/app/assets/javascripts/pageflow/editor.js +4 -0
  95. data/spec/d/r/app/assets/stylesheets/active_admin.css.scss +18 -0
  96. data/spec/d/r/app/assets/stylesheets/application.css +13 -0
  97. data/spec/d/r/app/assets/stylesheets/pageflow/application.css.scss +1 -0
  98. data/spec/d/r/app/assets/stylesheets/pageflow/editor.css.scss +1 -0
  99. data/spec/d/r/app/controllers/application_controller.rb +5 -0
  100. data/spec/d/r/app/controllers/concerns/.keep +0 -0
  101. data/spec/d/r/app/helpers/application_helper.rb +2 -0
  102. data/spec/d/r/app/mailers/.keep +0 -0
  103. data/spec/d/r/app/models/.keep +0 -0
  104. data/spec/d/r/app/models/ability.rb +12 -0
  105. data/spec/d/r/app/models/concerns/.keep +0 -0
  106. data/spec/d/r/app/models/user.rb +9 -0
  107. data/spec/d/r/app/views/layouts/application.html.erb +14 -0
  108. data/spec/d/r/bin/bundle +3 -0
  109. data/spec/d/r/bin/rails +4 -0
  110. data/spec/d/r/bin/rake +4 -0
  111. data/spec/d/r/config/application.rb +31 -0
  112. data/spec/d/r/config/boot.rb +4 -0
  113. data/spec/d/r/config/database.yml +39 -0
  114. data/spec/d/r/config/environment.rb +5 -0
  115. data/spec/d/r/config/environments/development.rb +29 -0
  116. data/spec/d/r/config/environments/production.rb +80 -0
  117. data/spec/d/r/config/environments/test.rb +37 -0
  118. data/spec/d/r/config/initializers/active_admin.rb +225 -0
  119. data/spec/d/r/config/initializers/backtrace_silencers.rb +7 -0
  120. data/spec/d/r/config/initializers/devise.rb +252 -0
  121. data/spec/d/r/config/initializers/devise_async.rb +6 -0
  122. data/spec/d/r/config/initializers/filter_parameter_logging.rb +4 -0
  123. data/spec/d/r/config/initializers/friendly_id.rb +88 -0
  124. data/spec/d/r/config/initializers/inflections.rb +16 -0
  125. data/spec/d/r/config/initializers/mime_types.rb +5 -0
  126. data/spec/d/r/config/initializers/pageflow.rb +76 -0
  127. data/spec/d/r/config/initializers/resque.rb +4 -0
  128. data/spec/d/r/config/initializers/resque_enqueue_after_commit_patch.rb +25 -0
  129. data/spec/d/r/config/initializers/resque_logger.rb +16 -0
  130. data/spec/d/r/config/initializers/resque_mailer.rb +4 -0
  131. data/spec/d/r/config/initializers/secret_token.rb +12 -0
  132. data/spec/d/r/config/initializers/session_store.rb +3 -0
  133. data/spec/d/r/config/initializers/wrap_parameters.rb +14 -0
  134. data/spec/d/r/config/locales/devise.en.yml +59 -0
  135. data/spec/d/r/config/locales/en.yml +23 -0
  136. data/spec/d/r/config/routes.rb +59 -0
  137. data/spec/d/r/config.ru +4 -0
  138. data/spec/d/r/db/migrate/00000000000000_create_test_hosted_file.rb +7 -0
  139. data/spec/d/r/db/migrate/00000000000001_create_test_revision_component.rb +10 -0
  140. data/spec/d/r/db/migrate/20150209101518_create_active_admin_comments.rb +19 -0
  141. data/spec/d/r/db/migrate/20150209101524_devise_create_users.rb +46 -0
  142. data/spec/d/r/db/migrate/20150209101530_create_friendly_id_slugs.rb +15 -0
  143. data/spec/d/r/db/migrate/20150209101540_setup_schema.pageflow.rb +208 -0
  144. data/spec/d/r/db/migrate/20150209101541_add_attributes_to_users.pageflow.rb +16 -0
  145. data/spec/d/r/db/migrate/20150209101542_create_themings.pageflow.rb +16 -0
  146. data/spec/d/r/db/migrate/20150209101543_create_themings_for_existing_accounts.pageflow.rb +27 -0
  147. data/spec/d/r/db/migrate/20150209101544_change_theme_references_to_theming_references.pageflow.rb +46 -0
  148. data/spec/d/r/db/migrate/20150209101545_remove_attributes_from_themes.pageflow.rb +11 -0
  149. data/spec/d/r/db/migrate/20150209101546_create_accounts_themes_join_table.pageflow.rb +9 -0
  150. data/spec/d/r/db/migrate/20150209101547_move_cname_from_account_to_theming.pageflow.rb +22 -0
  151. data/spec/d/r/db/migrate/20150209101548_drop_themes.pageflow.rb +15 -0
  152. data/spec/d/r/db/migrate/20150209101549_add_confirmed_by_to_encoded_files.pageflow.rb +7 -0
  153. data/spec/d/r/db/migrate/20150209101550_add_home_url_attributes_to_themings_and_revisions.pageflow.rb +10 -0
  154. data/spec/d/r/db/migrate/20150209101551_create_widgets.pageflow.rb +12 -0
  155. data/spec/d/r/db/migrate/20150209101552_add_emphasize_chapter_beginning_to_revisions.pageflow.rb +6 -0
  156. data/spec/d/r/db/migrate/20150209101553_add_emphasize_new_pages_to_revisions.pageflow.rb +6 -0
  157. data/spec/d/r/db/migrate/20150209101554_add_sharing_image_to_revisions.pageflow.rb +8 -0
  158. data/spec/d/r/db/schema.rb +316 -0
  159. data/spec/d/r/db/seeds.rb +30 -0
  160. data/spec/d/r/lib/assets/.keep +0 -0
  161. data/spec/d/r/lib/tasks/.keep +0 -0
  162. data/spec/d/r/lib/tasks/resque.rake +7 -0
  163. data/spec/d/r/public/404.html +58 -0
  164. data/spec/d/r/public/422.html +58 -0
  165. data/spec/d/r/public/500.html +57 -0
  166. data/spec/d/r/public/favicon.ico +0 -0
  167. data/spec/d/r/public/javascripts/translations.js +2 -0
  168. data/spec/d/r/public/robots.txt +5 -0
  169. data/spec/d/r/vendor/assets/javascripts/.keep +0 -0
  170. data/spec/d/r/vendor/assets/stylesheets/.keep +0 -0
  171. data/spec/javascripts/.jshintrc +26 -0
  172. data/spec/javascripts/pageflow/sitemap/editor/controllers/selection_navigator_spec.js +52 -0
  173. data/spec/javascripts/pageflow/sitemap/editor/d3/layout/collision_spec.js +99 -0
  174. data/spec/javascripts/pageflow/sitemap/editor/d3/layout/dragging_decorator_spec.js +114 -0
  175. data/spec/javascripts/pageflow/sitemap/editor/d3/layout/grid_spec.js +183 -0
  176. data/spec/javascripts/pageflow/sitemap/editor/d3/layout_spec.js +31 -0
  177. data/spec/javascripts/pageflow/sitemap/editor/d3/view_model_spec.js +56 -0
  178. data/spec/javascripts/pageflow/sitemap/editor/models/selection_spec.js +62 -0
  179. data/spec/javascripts/pageflow/sitemap/scroll_navigator_spec.js +5 -0
  180. data/spec/javascripts/spec_helper.js +13 -0
  181. data/spec/javascripts/support/factories.js +81 -0
  182. data/spec/teaspoon_env.rb +182 -0
  183. data/vendor/assets/javascripts/d3.v3.js +9215 -0
  184. metadata +379 -0
@@ -0,0 +1,43 @@
1
+ sitemap.behavior = sitemap.behavior || {};
2
+
3
+ sitemap.behavior.mouseWheel = function() {
4
+ var delta, eventName;
5
+ var dispatch = d3.dispatch("wheel");
6
+
7
+ function behavior(g) {
8
+ g.on(eventName + ".mouseWheelBehavior", onWheel);
9
+ }
10
+
11
+ function onWheel() {
12
+ d3.event.preventDefault();
13
+
14
+ dispatch.wheel({
15
+ delta: delta(),
16
+ point: d3.mouse(this),
17
+ ctrlKey: d3.event.ctrlKey,
18
+ shiftKey: d3.event.shiftKey,
19
+ altKey: d3.event.altKey
20
+ });
21
+ }
22
+
23
+ if ('onwheel' in window.document) {
24
+ delta = function() {
25
+ return -(d3.event.deltaY || d3.event.deltaX) * (d3.event.deltaMode ? 120 : 1);
26
+ };
27
+ eventName = 'wheel';
28
+ }
29
+ else if ('onmousewheel' in window.document) {
30
+ delta = function() {
31
+ return d3.event.wheelDelta;
32
+ };
33
+ eventName = 'mousewheel';
34
+ }
35
+ else {
36
+ delta = function() {
37
+ return -d3.event.detail;
38
+ };
39
+ eventName = 'MozMousePixelScroll';
40
+ }
41
+
42
+ return d3.rebind(behavior, dispatch, 'on');
43
+ };
@@ -0,0 +1,73 @@
1
+ sitemap.behavior.multiDrag = function(options) {
2
+ options = options || {};
3
+
4
+ var dragstart = 'dragstart.multiDrag';
5
+ var dragmove = 'drag.multiDrag';
6
+ var dragend = 'dragend.multiDrag';
7
+
8
+ function behavior(g) {
9
+ var handles = options.handle ? g.selectAll(options.handle) : g;
10
+ var dx, dy, x, y, isDragging, gotDragMove;
11
+
12
+ var xxx;
13
+
14
+ var drag = d3.behavior.drag()
15
+ .on(dragstart, function(data) {
16
+ dx = 0;
17
+ dy = 0;
18
+
19
+ isDragging = options.enabled ? options.enabled(data) : true;
20
+ gotDragMove = false;
21
+
22
+ xxx = window.options.duration;
23
+ window.options.duration = 0;
24
+ })
25
+ .on(dragmove, function() {
26
+ if (!isDragging) {
27
+ return;
28
+ }
29
+
30
+ gotDragMove = true;
31
+
32
+ dx += d3.event.dx;
33
+ dy += d3.event.dy;
34
+
35
+ x = d3.event.x;
36
+ y = d3.event.y;
37
+
38
+ options.drag({
39
+ dx: dx,
40
+ dy: dy,
41
+ position: {
42
+ x: x,
43
+ y: y
44
+ }
45
+ });
46
+ })
47
+ .on(dragend, function(data) {
48
+ window.options.duration = xxx;
49
+
50
+ if (!isDragging) {
51
+ return;
52
+ }
53
+
54
+ isDragging = false;
55
+
56
+ if (gotDragMove) {
57
+ options.dragend({
58
+ data: data,
59
+ dx: dx,
60
+ dy: dy,
61
+ position: {
62
+ x: x,
63
+ y: y
64
+ }
65
+ });
66
+ }
67
+ });
68
+
69
+ handles.call(drag);
70
+ }
71
+
72
+ return behavior;
73
+ };
@@ -0,0 +1,286 @@
1
+ sitemap.behavior = sitemap.behavior || {};
2
+
3
+ sitemap.behavior.scrollAndZoom = function(options) {
4
+ options = options || {};
5
+
6
+ var view = {x: 0, y: 0, k: 1};
7
+ var dispatch = d3.dispatch('change');
8
+
9
+ var minScale = options.minScale || 0.1;
10
+ var maxScale = options.maxScale || 1;
11
+ var margin = options.margin || 0;
12
+ var minX = -100;
13
+ var minY = -100;
14
+ var maxX = 100;
15
+ var maxY = 100;
16
+ var size = {x: 0, y: 0};
17
+
18
+ var sizeAvailable = new $.Deferred();
19
+ var constraintsAvaiable = new $.Deferred();
20
+ var viewportInitialized = false;
21
+
22
+ function behavior(g) {
23
+ g.call(sitemap.behavior.mouseWheel()
24
+ .on('wheel', onWheel))
25
+ .on('mousedown', onMouseDown);
26
+ }
27
+
28
+ if (options.change) {
29
+ dispatch.on('change.option', options.change);
30
+ }
31
+
32
+ behavior.updateConstraints = function(options) {
33
+ minX = options.minX;
34
+ minY = options.minY;
35
+ maxX = options.maxX;
36
+ maxY = options.maxY;
37
+
38
+ constraintsAvaiable.resolve();
39
+
40
+ normalize();
41
+ dispatchChange();
42
+ };
43
+
44
+ behavior.updateSize = function(x, y) {
45
+ size.x = x;
46
+ size.y = y;
47
+
48
+ sizeAvailable.resolve();
49
+
50
+ normalize();
51
+ dispatchChange();
52
+ };
53
+
54
+ behavior.ensureViewport = function(options) {
55
+ if (viewportInitialized) {
56
+ return;
57
+ }
58
+
59
+ viewportInitialized = true;
60
+
61
+ $.when(sizeAvailable, constraintsAvaiable).then(function() {
62
+ behavior.setViewport(options.defaultViewport);
63
+
64
+ if (options.centerAt) {
65
+ behavior.centerAt(options.centerAt);
66
+ }
67
+ });
68
+ };
69
+
70
+ behavior.centerAt = function(pos) {
71
+ var k = view.k;
72
+
73
+ view = {
74
+ x: size.x / 2 - pos.x * k,
75
+ y: size.y / 2 - pos.y * k,
76
+ k: k
77
+ };
78
+
79
+ normalize();
80
+ dispatchChange();
81
+ };
82
+
83
+ behavior.getViewport = function() {
84
+ return _.clone(view);
85
+ };
86
+
87
+ behavior.setViewport = function(viewport) {
88
+ view = _.extend({
89
+ x: Infinity,
90
+ y: Infinity,
91
+ k: view.k
92
+ }, viewport || {});
93
+
94
+ normalize();
95
+ dispatchChange();
96
+ };
97
+
98
+ behavior.scrollBy = function(x, y) {
99
+ var k = view.k;
100
+
101
+ view = {
102
+ x: view.x + x,
103
+ y: view.y + y,
104
+ k: k
105
+ };
106
+
107
+ normalize();
108
+ dispatchChange();
109
+ };
110
+
111
+ behavior.getScale = function() {
112
+ return (view.k - minScale) / (maxScale - minScale) * 100;
113
+ };
114
+
115
+ behavior.setScale = function(percent) {
116
+ var r = percent / 100;
117
+ scaleTo(minScale * (1 - r) + maxScale * r);
118
+
119
+ normalize();
120
+ dispatchChange();
121
+ };
122
+
123
+ behavior.getScrollX = function() {
124
+ var _maxX = maxX * view.k + margin;
125
+ var _minX = Math.min(_maxX, minX * view.k + size.x - margin);
126
+
127
+ return (view.x - _maxX) / (_minX - _maxX) * 100;
128
+ };
129
+
130
+ behavior.setScrollX = function(percent) {
131
+ var _maxX = maxX * view.k + margin;
132
+ var _minX = Math.min(_maxX, minX * view.k + size.x - margin);
133
+ var r = percent / 100;
134
+
135
+ view.x = _minX * r + _maxX * (1 - r);
136
+ dispatchChange();
137
+ };
138
+
139
+ behavior.getScrollY = function() {
140
+ var _maxY = maxY * view.k + margin;
141
+ var _minY = Math.min(_maxY, minY * view.k + size.y - margin);
142
+
143
+ return (view.y - _minY) / (_maxY - _minY) * 100;
144
+ };
145
+
146
+ behavior.setScrollY = function(percent) {
147
+ var _maxY = maxY * view.k + margin;
148
+ var _minY = Math.min(_maxY, minY * view.k + size.y - margin);
149
+ var r = percent / 100;
150
+
151
+ view.y = _minY * (1 - r) + _maxY * r;
152
+ dispatchChange();
153
+ };
154
+
155
+ behavior.getScrollWindowProportionX = function() {
156
+ var _maxX = maxX * view.k + margin;
157
+ var _minX = Math.min(_maxX, minX * view.k - margin);
158
+
159
+ return Math.min(1, size.x / (_maxX - _minX));
160
+ };
161
+
162
+ behavior.getScrollWindowProportionY = function() {
163
+ var _maxY = maxY * view.k + margin;
164
+ var _minY = Math.min(_maxY, minY * view.k - margin);
165
+
166
+ return Math.min(1, size.y / (_maxY - _minY));
167
+ };
168
+
169
+ behavior.pointTo = function(coords) {
170
+ var p = [coords.x, coords.y];
171
+ var l = location(p);
172
+
173
+ return {x: l[0], y: l[1]};
174
+ };
175
+
176
+ function dispatchChange() {
177
+ dispatch.change({
178
+ scale: view.k,
179
+ translate: [view.x, view.y]
180
+ });
181
+ }
182
+
183
+ function location(p) {
184
+ return [(p[0] - view.x) / view.k, (p[1] - view.y) / view.k];
185
+ }
186
+
187
+ function point(l) {
188
+ return [l[0] * view.k + view.x, l[1] * view.k + view.y];
189
+ }
190
+
191
+ function scaleTo(s) {
192
+ view.k = restrict(s, minScale, maxScale);
193
+ }
194
+
195
+ function translateTo(p, l) {
196
+ l = point(l);
197
+
198
+ view.x += p[0] - l[0];
199
+ view.y += p[1] - l[1];
200
+
201
+ normalize();
202
+ }
203
+
204
+ function normalize() {
205
+ var _maxX = maxX * view.k + margin;
206
+ var _maxY = maxY * view.k + margin;
207
+ var _minX = Math.min(_maxX, minX * view.k + size.x - margin);
208
+ var _minY = Math.min(_maxY, minY * view.k + size.y - margin);
209
+
210
+ view.x = restrict(view.x, _minX, _maxX);
211
+ view.y = restrict(view.y, _minY, _maxY);
212
+ }
213
+
214
+ function ensureInsideMargin(p) {
215
+ view.x -= Math.max(0, p[0] - size.x + margin);
216
+ view.x -= Math.min(0, p[0] - margin);
217
+ view.y -= Math.max(0, p[1] - size.y + margin);
218
+ view.y -= Math.min(0, p[1] - margin);
219
+
220
+ normalize();
221
+ dispatchChange();
222
+ }
223
+
224
+ function restrict(value, min, max) {
225
+ return Math.max(min, Math.min(max, value));
226
+ }
227
+
228
+ function onWheel(event) {
229
+ var center0 = event.point;
230
+ var translate0 = location(event.point);
231
+
232
+ if (event.altKey) {
233
+ scaleTo(Math.pow(2, event.delta * 0.002) * view.k);
234
+ translateTo(center0, translate0);
235
+ }
236
+ else if (event.shiftKey) {
237
+ center0[0] += sign(event.delta) * 50;
238
+ }
239
+ else {
240
+ center0[1] += sign(event.delta) * 50;
241
+ }
242
+
243
+ translateTo(center0, translate0);
244
+ dispatchChange();
245
+ }
246
+
247
+ function onMouseDown() {
248
+ if (d3.event.which !== 1) {
249
+ return;
250
+ }
251
+
252
+ var that = this,
253
+ timeout,
254
+ mousemove = 'mousemove.zoomAndScroll',
255
+ mouseup = 'mouseup.zoomAndScroll',
256
+ subject = d3.select(window).on(mousemove, moved).on(mouseup, ended);
257
+
258
+ function moved() {
259
+ var p = d3.mouse(that);
260
+
261
+ function tick() {
262
+ ensureInsideMargin(p);
263
+
264
+ clearTimeout(timeout);
265
+ timeout = setTimeout(tick, 20);
266
+ }
267
+
268
+ tick();
269
+ }
270
+
271
+ function ended() {
272
+ clearTimeout(timeout);
273
+ subject.on(mousemove, null).on(mouseup, null);
274
+ }
275
+ }
276
+
277
+ function sign(x) {
278
+ x = +x; // convert to a number
279
+ if (x === 0 || isNaN(x)) {
280
+ return x;
281
+ }
282
+ return x > 0 ? 1 : -1;
283
+ }
284
+
285
+ return d3.rebind(behavior, dispatch, 'on');
286
+ };
@@ -0,0 +1,104 @@
1
+ pageflow.sitemap.behavior.selectionRect = function(options) {
2
+ options = options || {};
3
+
4
+ var mousedown = 'mousedown.selectionRect';
5
+ var mousemove = 'mousemove.selectionRect';
6
+ var mouseup = 'mouseup.selectionRect';
7
+
8
+ var eventTarget = d3.select(window);
9
+
10
+ function behavior(g) {
11
+ var rect = g
12
+ .append('svg:rect')
13
+ .attr('class', 'selection')
14
+ .style('visibility', 'hidden');
15
+
16
+ g.on(mousedown, function() {
17
+ if (d3.event.which !== 1) {
18
+ return;
19
+ }
20
+
21
+ if (d3.event.target !== g.node()) {
22
+ return;
23
+ }
24
+
25
+ var startPoint = d3.mouse(this);
26
+ var container = g.select(options.container);
27
+ var r0 = container.node().getBoundingClientRect();
28
+ var timeout;
29
+
30
+ g.on(mousemove, onMouseMove);
31
+ eventTarget.on(mouseup, onMouseUp);
32
+
33
+ dispatchSelectEvent([]);
34
+
35
+ rect
36
+ .attr('width', 0)
37
+ .attr('height', 0);
38
+
39
+ function onMouseMove() {
40
+ var point = d3.mouse(this);
41
+
42
+ function tick() {
43
+ var r1 = container.node().getBoundingClientRect();
44
+ var translatedStartPoint = [
45
+ startPoint[0] + r1.left - r0.left,
46
+ startPoint[1] + r1.top - r0.top
47
+ ];
48
+
49
+ rect
50
+ .attr('x', Math.min(point[0], translatedStartPoint[0]))
51
+ .attr('y', Math.min(point[1], translatedStartPoint[1]))
52
+ .attr('width', Math.abs(point[0] - translatedStartPoint[0]))
53
+ .attr('height', Math.abs(point[1] - translatedStartPoint[1]))
54
+ .style('visibility', 'visible');
55
+
56
+ clearTimeout(timeout);
57
+ timeout = setTimeout(tick, 20);
58
+ }
59
+
60
+ tick();
61
+ }
62
+
63
+ function onMouseUp() {
64
+ clearTimeout(timeout);
65
+
66
+ g.on(mousemove, null);
67
+ eventTarget.on(mouseup, null);
68
+
69
+ rect
70
+ .style('visibility', 'hidden');
71
+
72
+ dispatchSelectEvent(selectedTargets().data());
73
+ }
74
+
75
+ function dispatchSelectEvent(targets) {
76
+ if (options.selected) {
77
+ options.selected(targets);
78
+ }
79
+ }
80
+
81
+ function selectedTargets() {
82
+ return targets().filter(function() {
83
+ return intersect(rect.node(), this);
84
+ });
85
+ }
86
+
87
+ function targets() {
88
+ return g.selectAll(options.targets);
89
+ }
90
+ });
91
+ }
92
+
93
+ function intersect(node1, node2) {
94
+ var rect1 = node1.getBoundingClientRect();
95
+ var rect2 = node2.getBoundingClientRect();
96
+
97
+ return rect1.right > rect2.left &&
98
+ rect1.left < rect2.right &&
99
+ rect1.bottom > rect2.top &&
100
+ rect1.top < rect2.bottom;
101
+ }
102
+
103
+ return behavior;
104
+ };
@@ -0,0 +1,24 @@
1
+ sitemap.behavior = sitemap.behavior || {};
2
+
3
+ sitemap.behavior.tooltipTarget = function(translationKey) {
4
+ function behavior(g) {
5
+ g
6
+ .on('mouseover.tooltipTarget', function() {
7
+ var rect = d3.event.target.getBoundingClientRect();
8
+
9
+ $(d3.event.target).trigger('requesttooltip', [{
10
+ translationKey: translationKey,
11
+ position: {
12
+ left: rect.right,
13
+ top: rect.top + rect.height / 2
14
+ }
15
+ }]);
16
+ })
17
+ .on('mouseout.tooltipTarget', function() {
18
+ $(d3.event.target).trigger('resettooltip');
19
+ })
20
+ ;
21
+ }
22
+
23
+ return behavior;
24
+ };