decidim-assemblies 0.27.9 → 0.28.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (198) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/assemblies/assemblies/show.erb +16 -0
  3. data/app/cells/decidim/assemblies/assemblies_cell.rb +24 -0
  4. data/app/cells/decidim/assemblies/assembly_cell.rb +7 -2
  5. data/app/cells/decidim/assemblies/assembly_dropdown_metadata_cell.rb +19 -0
  6. data/app/cells/decidim/assemblies/assembly_g_cell.rb +23 -0
  7. data/app/cells/decidim/assemblies/assembly_member/data.erb +19 -0
  8. data/app/cells/decidim/assemblies/assembly_member/name_and_position.erb +11 -0
  9. data/app/cells/decidim/assemblies/assembly_member/show.erb +8 -52
  10. data/app/cells/decidim/assemblies/assembly_metadata_g_cell.rb +46 -0
  11. data/app/cells/decidim/assemblies/assembly_s_cell.rb +15 -0
  12. data/app/cells/decidim/assemblies/content_block_cell.rb +21 -0
  13. data/app/cells/decidim/assemblies/content_blocks/children_assemblies_cell.rb +27 -0
  14. data/app/cells/decidim/assemblies/content_blocks/dates_metadata_cell.rb +23 -0
  15. data/app/cells/decidim/assemblies/content_blocks/extra_data_cell.rb +39 -0
  16. data/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies_cell.rb +15 -23
  17. data/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies_settings_form/show.erb +1 -1
  18. data/app/cells/decidim/assemblies/content_blocks/main_data_cell.rb +52 -0
  19. data/app/cells/decidim/assemblies/content_blocks/metadata_cell.rb +23 -0
  20. data/app/cells/decidim/assemblies/content_blocks/related_assemblies/content.erb +1 -0
  21. data/app/cells/decidim/assemblies/content_blocks/related_assemblies_cell.rb +34 -0
  22. data/app/cells/decidim/assemblies/content_blocks/stats_cell.rb +15 -0
  23. data/app/commands/decidim/assemblies/admin/copy_assembly.rb +2 -2
  24. data/app/commands/decidim/assemblies/admin/create_assemblies_type.rb +1 -1
  25. data/app/commands/decidim/assemblies/admin/create_assembly.rb +2 -1
  26. data/app/commands/decidim/assemblies/admin/create_assembly_member.rb +3 -3
  27. data/app/commands/decidim/assemblies/admin/destroy_assemblies_type.rb +1 -1
  28. data/app/commands/decidim/assemblies/admin/destroy_assembly_member.rb +1 -1
  29. data/app/commands/decidim/assemblies/admin/import_assembly.rb +1 -1
  30. data/app/commands/decidim/assemblies/admin/update_assemblies_type.rb +1 -1
  31. data/app/commands/decidim/assemblies/admin/update_assembly.rb +1 -1
  32. data/app/commands/decidim/assemblies/admin/update_assembly_member.rb +1 -1
  33. data/app/constraints/decidim/assemblies/current_assembly.rb +1 -1
  34. data/app/controllers/concerns/decidim/assemblies/admin/assembly_context.rb +1 -1
  35. data/app/controllers/concerns/decidim/assemblies/admin/assembly_members/filterable.rb +39 -0
  36. data/app/controllers/concerns/decidim/assemblies/assembly_breadcrumb.rb +36 -0
  37. data/app/controllers/decidim/assemblies/admin/assemblies_controller.rb +1 -0
  38. data/app/controllers/decidim/assemblies/admin/assemblies_types_controller.rb +1 -1
  39. data/app/controllers/decidim/assemblies/admin/assembly_attachment_collections_controller.rb +5 -0
  40. data/app/controllers/decidim/assemblies/admin/assembly_attachments_controller.rb +5 -0
  41. data/app/controllers/decidim/assemblies/admin/assembly_imports_controller.rb +2 -0
  42. data/app/controllers/decidim/assemblies/admin/assembly_landing_page_content_blocks_controller.rb +35 -0
  43. data/app/controllers/decidim/assemblies/admin/assembly_landing_page_controller.rb +37 -0
  44. data/app/controllers/decidim/assemblies/admin/assembly_members_controller.rb +2 -6
  45. data/app/controllers/decidim/assemblies/admin/assembly_publications_controller.rb +9 -29
  46. data/app/controllers/decidim/assemblies/admin/assembly_user_roles_controller.rb +8 -91
  47. data/app/controllers/decidim/assemblies/admin/concerns/assembly_admin.rb +1 -1
  48. data/app/controllers/decidim/assemblies/assemblies_controller.rb +12 -7
  49. data/app/controllers/decidim/assemblies/assembly_members_controller.rb +2 -0
  50. data/app/events/decidim/assemblies/create_assembly_member_event.rb +1 -1
  51. data/app/events/decidim/role_assigned_to_assembly_event.rb +11 -6
  52. data/app/forms/decidim/assemblies/admin/assembly_copy_form.rb +1 -1
  53. data/app/forms/decidim/assemblies/admin/assembly_form.rb +1 -1
  54. data/app/forms/decidim/assemblies/admin/assembly_import_form.rb +1 -1
  55. data/app/forms/decidim/assemblies/admin/assembly_user_role_form.rb +2 -18
  56. data/app/helpers/decidim/assemblies/admin/assembly_members_helper.rb +11 -0
  57. data/app/helpers/decidim/assemblies/application_helper.rb +12 -0
  58. data/app/helpers/decidim/assemblies/assemblies_helper.rb +21 -19
  59. data/app/helpers/decidim/assemblies/filter_assemblies_helper.rb +15 -30
  60. data/app/models/decidim/assembly.rb +6 -5
  61. data/app/models/decidim/assembly_user_role.rb +5 -33
  62. data/app/packs/entrypoints/decidim_assemblies.js +0 -1
  63. data/app/packs/src/decidim/assemblies/admin/assemblies.js +2 -2
  64. data/app/packs/src/decidim/assemblies/orgchart.js +0 -701
  65. data/app/permissions/decidim/assemblies/permissions.rb +14 -27
  66. data/app/presenters/decidim/assemblies/admin_log/assemblies_setting_presenter.rb +2 -2
  67. data/app/presenters/decidim/assemblies/admin_log/assemblies_type_presenter.rb +2 -2
  68. data/app/presenters/decidim/assemblies/admin_log/assembly_member_presenter.rb +2 -2
  69. data/app/presenters/decidim/assemblies/admin_log/assembly_presenter.rb +2 -2
  70. data/app/presenters/decidim/assemblies/admin_log/assembly_user_role_presenter.rb +2 -2
  71. data/app/presenters/decidim/assemblies/assembly_presenter.rb +38 -0
  72. data/app/presenters/decidim/assemblies/assembly_stats_presenter.rb +2 -41
  73. data/app/presenters/decidim/assembly_member_presenter.rb +18 -4
  74. data/app/queries/decidim/assemblies/admin/admin_users.rb +1 -1
  75. data/app/queries/decidim/assemblies/assemblies_with_user_role.rb +2 -2
  76. data/app/serializers/decidim/assemblies/assembly_importer.rb +3 -3
  77. data/app/serializers/decidim/assemblies/assembly_serializer.rb +1 -1
  78. data/app/views/decidim/assemblies/admin/assemblies/_form.html.erb +218 -176
  79. data/app/views/decidim/assemblies/admin/assemblies/edit.html.erb +25 -11
  80. data/app/views/decidim/assemblies/admin/assemblies/index.html.erb +105 -115
  81. data/app/views/decidim/assemblies/admin/assemblies/new.html.erb +16 -9
  82. data/app/views/decidim/assemblies/admin/assemblies_types/_form.html.erb +6 -8
  83. data/app/views/decidim/assemblies/admin/assemblies_types/edit.html.erb +11 -5
  84. data/app/views/decidim/assemblies/admin/assemblies_types/index.html.erb +34 -35
  85. data/app/views/decidim/assemblies/admin/assemblies_types/new.html.erb +16 -6
  86. data/app/views/decidim/assemblies/admin/assembly_copies/_form.html.erb +12 -20
  87. data/app/views/decidim/assemblies/admin/assembly_copies/new.html.erb +17 -5
  88. data/app/views/decidim/assemblies/admin/assembly_imports/_form.html.erb +28 -37
  89. data/app/views/decidim/assemblies/admin/assembly_imports/new.html.erb +17 -5
  90. data/app/views/decidim/assemblies/admin/assembly_members/_form.html.erb +45 -49
  91. data/app/views/decidim/assemblies/admin/assembly_members/edit.html.erb +17 -6
  92. data/app/views/decidim/assemblies/admin/assembly_members/index.html.erb +51 -88
  93. data/app/views/decidim/assemblies/admin/assembly_members/new.html.erb +17 -6
  94. data/app/views/decidim/assemblies/admin/assembly_user_roles/_form.html.erb +14 -18
  95. data/app/views/decidim/assemblies/admin/assembly_user_roles/edit.html.erb +17 -6
  96. data/app/views/decidim/assemblies/admin/assembly_user_roles/index.html.erb +54 -55
  97. data/app/views/decidim/assemblies/admin/assembly_user_roles/new.html.erb +17 -6
  98. data/app/views/decidim/assemblies/assemblies/_collection.html.erb +7 -0
  99. data/app/views/decidim/assemblies/assemblies/index.html.erb +20 -19
  100. data/app/views/decidim/assemblies/assemblies/index.js.erb +1 -8
  101. data/app/views/decidim/assemblies/assemblies/show.html.erb +17 -207
  102. data/app/views/decidim/assemblies/assembly_members/index.html.erb +7 -5
  103. data/app/views/decidim/assemblies/pages/user_profile/_member_of.html.erb +6 -9
  104. data/app/views/layouts/decidim/admin/_manage_assemblies.html.erb +36 -0
  105. data/app/views/layouts/decidim/admin/assemblies.html.erb +13 -11
  106. data/app/views/layouts/decidim/admin/assemblies_imports.html.erb +9 -0
  107. data/app/views/layouts/decidim/admin/assemblies_types.html.erb +17 -0
  108. data/app/views/layouts/decidim/admin/assembly.html.erb +12 -13
  109. data/app/views/layouts/decidim/assembly.html.erb +7 -14
  110. data/config/locales/ar.yml +7 -68
  111. data/config/locales/bg.yml +0 -466
  112. data/config/locales/ca.yml +62 -71
  113. data/config/locales/cs.yml +59 -66
  114. data/config/locales/de.yml +60 -69
  115. data/config/locales/el.yml +11 -61
  116. data/config/locales/en.yml +57 -66
  117. data/config/locales/es-MX.yml +57 -66
  118. data/config/locales/es-PY.yml +57 -66
  119. data/config/locales/es.yml +63 -72
  120. data/config/locales/eu.yml +57 -70
  121. data/config/locales/fi-plain.yml +58 -67
  122. data/config/locales/fi.yml +57 -66
  123. data/config/locales/fr-CA.yml +57 -66
  124. data/config/locales/fr.yml +57 -66
  125. data/config/locales/ga-IE.yml +4 -15
  126. data/config/locales/gl.yml +4 -62
  127. data/config/locales/hu.yml +33 -65
  128. data/config/locales/id-ID.yml +6 -47
  129. data/config/locales/is-IS.yml +5 -40
  130. data/config/locales/it.yml +5 -62
  131. data/config/locales/ja.yml +51 -66
  132. data/config/locales/kaa.yml +0 -8
  133. data/config/locales/ko.yml +0 -92
  134. data/config/locales/lb.yml +5 -61
  135. data/config/locales/lt.yml +40 -63
  136. data/config/locales/lv.yml +5 -57
  137. data/config/locales/nl.yml +4 -62
  138. data/config/locales/no.yml +5 -62
  139. data/config/locales/pl.yml +3 -93
  140. data/config/locales/pt-BR.yml +77 -132
  141. data/config/locales/pt.yml +5 -62
  142. data/config/locales/ro-RO.yml +20 -63
  143. data/config/locales/ru.yml +4 -44
  144. data/config/locales/sk.yml +0 -26
  145. data/config/locales/sl.yml +5 -48
  146. data/config/locales/sq-AL.yml +0 -364
  147. data/config/locales/sr-CS.yml +0 -5
  148. data/config/locales/sv.yml +132 -193
  149. data/config/locales/tr-TR.yml +8 -69
  150. data/config/locales/uk.yml +4 -44
  151. data/config/locales/zh-CN.yml +5 -60
  152. data/config/locales/zh-TW.yml +7 -63
  153. data/db/migrate/20200108123050_migrate_decidim_assembly_types.rb +1 -1
  154. data/lib/decidim/api/assemblies_type_type.rb +1 -1
  155. data/lib/decidim/api/assembly_member_type.rb +1 -1
  156. data/lib/decidim/api/assembly_type.rb +1 -1
  157. data/lib/decidim/assemblies/admin_engine.rb +21 -126
  158. data/lib/decidim/assemblies/content_blocks/registry_manager.rb +184 -0
  159. data/lib/decidim/assemblies/engine.rb +15 -21
  160. data/lib/decidim/assemblies/menu.rb +161 -0
  161. data/lib/decidim/assemblies/participatory_space.rb +7 -229
  162. data/lib/decidim/assemblies/query_extensions.rb +6 -6
  163. data/lib/decidim/assemblies/seeds.rb +161 -0
  164. data/lib/decidim/assemblies/test/factories.rb +47 -55
  165. data/lib/decidim/assemblies/version.rb +1 -1
  166. metadata +54 -51
  167. data/app/cells/decidim/assemblies/assembly_m/footer.erb +0 -15
  168. data/app/cells/decidim/assemblies/assembly_m/tags.erb +0 -1
  169. data/app/cells/decidim/assemblies/assembly_m_cell.rb +0 -77
  170. data/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies/show.erb +0 -30
  171. data/app/commands/decidim/assemblies/admin/create_assembly_admin.rb +0 -54
  172. data/app/commands/decidim/assemblies/admin/destroy_assembly_admin.rb +0 -58
  173. data/app/commands/decidim/assemblies/admin/notify_role_assigned_to_assembly.rb +0 -22
  174. data/app/commands/decidim/assemblies/admin/publish_assembly.rb +0 -39
  175. data/app/commands/decidim/assemblies/admin/unpublish_assembly.rb +0 -39
  176. data/app/commands/decidim/assemblies/admin/update_assemblies_setting.rb +0 -46
  177. data/app/commands/decidim/assemblies/admin/update_assembly_admin.rb +0 -53
  178. data/app/controllers/decidim/assemblies/admin/assemblies_settings_controller.rb +0 -49
  179. data/app/controllers/decidim/assemblies/widgets_controller.rb +0 -33
  180. data/app/forms/decidim/assemblies/admin/assemblies_setting_form.rb +0 -14
  181. data/app/models/decidim/assemblies_setting.rb +0 -17
  182. data/app/queries/decidim/assemblies/admin/assembly_members.rb +0 -56
  183. data/app/views/decidim/assemblies/_filter_by_type.html.erb +0 -19
  184. data/app/views/decidim/assemblies/admin/assemblies_settings/_form.html.erb +0 -10
  185. data/app/views/decidim/assemblies/admin/assemblies_settings/edit.html.erb +0 -7
  186. data/app/views/decidim/assemblies/assemblies/_count.html.erb +0 -1
  187. data/app/views/decidim/assemblies/assemblies/_nav_breadcumb.html.erb +0 -11
  188. data/app/views/decidim/assemblies/assemblies/_parent_assemblies.html.erb +0 -15
  189. data/app/views/decidim/assemblies/assemblies/_promoted_assembly.html.erb +0 -27
  190. data/app/views/layouts/decidim/_assembly_header.html.erb +0 -27
  191. data/app/views/layouts/decidim/_assembly_navigation.html.erb +0 -24
  192. data/app/views/layouts/decidim/admin/assembly_members.html.erb +0 -18
  193. data/config/locales/he-IL.yml +0 -110
  194. data/db/seeds/Exampledocument.pdf +0 -0
  195. data/db/seeds/city.jpeg +0 -0
  196. data/db/seeds/city2.jpeg +0 -0
  197. data/db/seeds/homepage_image.jpg +0 -0
  198. data/decidim-assemblies.gemspec +0 -32
@@ -1,701 +0,0 @@
1
- /* eslint-disable require-jsdoc, max-lines, no-return-assign, func-style, id-length, no-plusplus, no-use-before-define, no-negated-condition, init-declarations, no-invalid-this, no-param-reassign, no-ternary, multiline-ternary, no-nested-ternary, no-eval, no-extend-native, prefer-reflect */
2
- /* eslint dot-location: ["error", "property"], no-negated-condition: "error" */
3
- /* eslint no-unused-expressions: ["error", { "allowTernary": true }] */
4
- /* eslint no-unused-vars: 0 */
5
-
6
- import { select, selectAll, event } from "d3-selection";
7
- import { max } from "d3-array";
8
- import { hierarchy } from "d3-hierarchy";
9
- import { forceManyBody, forceCollide, forceCenter, forceX, forceY, forceSimulation, forceLink } from "d3-force";
10
- import { drag } from "d3-drag";
11
- import { json } from "d3-fetch";
12
-
13
- // lib
14
- const renderOrgCharts = () => {
15
- const $orgChartContainer = $(".js-orgchart")
16
- const $btnReset = $(".js-reset-orgchart")
17
-
18
- let dataDepicted = null
19
- let fake = false
20
- let orgchart = {}
21
-
22
- // lib - https://bl.ocks.org/bumbeishvili/b96ba47ea21d14dfce6ebb859b002d3a
23
- const renderChartCollapsibleNetwork = (params) => {
24
-
25
- // exposed variables
26
- let attrs = {
27
- id: `id${Math.floor(Math.random() * 1000000)}`,
28
- svgWidth: 960,
29
- svgHeight: 600,
30
- marginTop: 0,
31
- marginBottom: 5,
32
- marginRight: 0,
33
- marginLeft: 30,
34
- container: "body",
35
- distance: 150,
36
- hiddenChildLevel: 1,
37
- hoverOpacity: 0.2,
38
- maxTextDisplayZoomLevel: 1,
39
- lineStrokeWidth: 1.5,
40
- fakeRoot: false,
41
- nodeGutter: { x: 16, y: 8 },
42
- childrenIndicatorRadius: 15,
43
- fakeBorderWidth: 32,
44
- data: null
45
- }
46
-
47
- /* ############### IF EXISTS OVERWRITE ATTRIBUTES FROM PASSED PARAM ####### */
48
-
49
- let attrKeys = Object.keys(attrs)
50
- attrKeys.forEach(function (key) {
51
- if (params && params[key]) {
52
- attrs[key] = params[key]
53
- }
54
- })
55
-
56
- // innerFunctions which will update visuals
57
- let updateData
58
- let collapse, expand
59
- let filter
60
- let _hierarchy = {}
61
-
62
- // main chart object
63
- let main = function (_selection) {
64
- _selection.each(function scope() {
65
-
66
- // calculated properties
67
- let calc = {}
68
- calc.chartLeftMargin = attrs.marginLeft
69
- calc.chartTopMargin = attrs.marginTop
70
- calc.chartWidth = attrs.svgWidth - attrs.marginRight - calc.chartLeftMargin
71
- calc.chartHeight = attrs.svgHeight - attrs.marginBottom - calc.chartTopMargin
72
-
73
- // ########################## HIERARCHY STUFF #########################
74
- _hierarchy.root = hierarchy(attrs.data.root)
75
-
76
- // ########################### BEHAVIORS #########################
77
- let behaviors = {}
78
- // behaviors.zoom = zoom().scaleExtent([0.75, 100, 8]).on("zoom", zoomed)
79
- behaviors.drag = drag().on("start", dragstarted).on("drag", dragged).on("end", dragended)
80
-
81
- // ########################### LAYOUTS #########################
82
- let layouts = {}
83
-
84
- // custom radial layout
85
- layouts.radial = radial()
86
-
87
- // ########################### FORCE STUFF #########################
88
- let force = {}
89
- force.link = forceLink().id((d) => d.id)
90
- force.charge = forceManyBody().strength(-240)
91
- force.center = forceCenter(calc.chartWidth / 2, calc.chartHeight / 2)
92
-
93
- // prevent collide
94
- force.collide = forceCollide().radius((d) => {
95
- // Creates an invented radius based on element measures: diagonal = 2 * radius = sqrt(width^2, height^2)
96
- let base = (d.bbox || {}).width + (attrs.nodeGutter.x * 2)
97
- let height = (d.bbox || {}).height + (attrs.nodeGutter.y * 2)
98
- let diagonal = Math.sqrt(Math.pow(base, 2) + Math.pow(height, 2))
99
- let fakeRadius = (diagonal / 2)
100
-
101
- // return max([attrs.nodeDistance * 3, fakeRadius])
102
- return fakeRadius * 1.5
103
- })
104
-
105
- // manually set x positions (which is calculated using custom radial layout)
106
- force.x = forceX()
107
- .strength(0.5)
108
- .x(function (d) {
109
-
110
- // if node does not have children and is channel (depth=2) , then position it on parent's coordinate
111
- if (!d.children && d.depth > 2) {
112
- if (d.parent) {
113
- d = d.parent
114
- }
115
- }
116
-
117
- // custom circle projection - radius will be - (d.depth - 1) * 150
118
- return projectCircle(d.proportion, (d.depth - 1) * attrs.distance)[0]
119
- })
120
-
121
- // manually set y positions (which is calculated using cluster)
122
- force.y = forceY()
123
- .strength(0.5)
124
- .y(function (d) {
125
-
126
- // if node does not have children and is channel (depth=2) , then position it on parent's coordinate
127
- if (!d.children && d.depth > 2) {
128
- if (d.parent) {
129
- d = d.parent
130
- }
131
- }
132
-
133
- // custom circle projection - radius will be - (d.depth - 1) * 150
134
- return projectCircle(d.proportion, (d.depth - 1) * attrs.distance)[1]
135
- })
136
-
137
- // --------------------------------- INITIALISE FORCE SIMULATION ----------------------------
138
-
139
- // get based on top parameter simulation
140
- force.simulation = forceSimulation()
141
- .force("link", force.link)
142
- .force("charge", force.charge)
143
- .force("center", force.center)
144
- .force("collide", force.collide)
145
- .force("x", force.x)
146
- .force("y", force.y)
147
-
148
- // ########################### HIERARCHY STUFF #########################
149
-
150
- // flatten root
151
- let arr = flatten(_hierarchy.root)
152
-
153
- // hide members based on their depth
154
- arr.forEach((d) => {
155
- // Hide fake root node
156
- if ((attrs.fakeRoot) && (d.depth === 1)) {
157
- d.hidden = true
158
- }
159
-
160
- if (d.depth > attrs.hiddenChildLevel) {
161
- d._children = d.children
162
- d.children = null
163
- }
164
- })
165
-
166
- // #################################### DRAWINGS #######################
167
-
168
- // drawing containers
169
- let container = select(this)
170
-
171
- // add svg
172
- let svg = patternify(container, { tag: "svg", selector: "svg-chart-container" })
173
- .attr("width", attrs.svgWidth)
174
- .attr("height", attrs.svgHeight)
175
- // .call(behaviors.zoom)
176
-
177
- // add container g element
178
- let chart = patternify(svg, { tag: "g", selector: "chart" })
179
- .attr("transform", `translate(${calc.chartLeftMargin},${calc.chartTopMargin})`)
180
-
181
- // ################################ Chart Content Drawing ##################################
182
-
183
- // link wrapper
184
- let linksWrapper = patternify(chart, { tag: "g", selector: "links-wrapper" })
185
-
186
- // node wrapper
187
- let nodesWrapper = patternify(chart, { tag: "g", selector: "nodes-wrapper" })
188
- let links, nodes
189
-
190
- // reusable function which updates visual based on data change
191
- update()
192
-
193
- // update visual based on data change
194
- function update(clickedNode) {
195
-
196
- // Show/hide reset button
197
- (clickedNode) ? $btnReset.removeClass("invisible") : $btnReset.addClass("invisible")
198
-
199
- // set xy and proportion properties with custom radial layout
200
- layouts.radial(_hierarchy.root)
201
-
202
- // nodes and links array
203
- let nodesArr = flatten(_hierarchy.root, true)
204
- .orderBy((d) => d.depth)
205
- .filter((d) => !d.hidden)
206
-
207
- let linksArr = _hierarchy.root.links()
208
- .filter((d) => !d.source.hidden)
209
- .filter((d) => !d.target.hidden)
210
-
211
- // make new nodes to appear near the parents
212
- nodesArr.forEach(function (d) {
213
- if (clickedNode && clickedNode.id === (d.parent && d.parent.id)) {
214
- d.x = d.parent.x
215
- d.y = d.parent.y
216
- }
217
- })
218
-
219
- // links
220
- links = linksWrapper.selectAll(".link")
221
- .data(linksArr, (d) => d.target.id)
222
- links.exit().remove()
223
-
224
- links = links.enter()
225
- .append("line")
226
- .attr("class", "link")
227
- .merge(links)
228
-
229
- // node groups
230
- nodes = nodesWrapper.selectAll(".node")
231
- .data(nodesArr, (d) => d.id)
232
- nodes.exit().remove()
233
-
234
- let enteredNodes = nodes.enter()
235
- .append("g")
236
- .attr("class", "node")
237
-
238
- // bind event handlers
239
- enteredNodes
240
- .on("click", nodeClick)
241
- .on("mouseenter", nodeMouseEnter)
242
- .on("mouseleave", nodeMouseLeave)
243
- .call(behaviors.drag)
244
-
245
- // channels grandchildren
246
- enteredNodes.append("rect")
247
- .attr("class", "as-card")
248
- .attr("rx", 4)
249
- .attr("ry", 4)
250
-
251
- enteredNodes.append("text")
252
- .attr("class", "as-text")
253
- .text((d) => d.data.name)
254
-
255
- enteredNodes.selectAll("text").each(function(d) {
256
- d.bbox = this.getBBox()
257
- })
258
-
259
- enteredNodes.selectAll("rect")
260
- .attr("x", (d) => d.bbox.x - attrs.nodeGutter.x)
261
- .attr("y", (d) => d.bbox.y - attrs.nodeGutter.y)
262
- .attr("width", (d) => d.bbox.width + (2 * attrs.nodeGutter.x))
263
- .attr("height", (d) => d.bbox.height + (2 * attrs.nodeGutter.y))
264
-
265
- // append circle & text only when there are children
266
- enteredNodes
267
- .append("circle")
268
- .filter((d) => Boolean(d.children) || Boolean(d._children))
269
- .attr("class", "as-circle")
270
- .attr("r", attrs.childrenIndicatorRadius)
271
- .attr("cx", (d) => d.bbox.x + d.bbox.width + attrs.nodeGutter.x)
272
- .attr("cy", (d) => d.bbox.y + d.bbox.height + attrs.nodeGutter.y)
273
-
274
- enteredNodes
275
- .append("text")
276
- .filter((d) => Boolean(d.children) || Boolean(d._children))
277
- .attr("class", "as-text")
278
- .attr("dx", (d) => d.bbox.x + d.bbox.width + attrs.nodeGutter.x)
279
- .attr("dy", attrs.childrenIndicatorRadius + 3)
280
- .text((d) => max([(d.children || {}).length, (d._children || {}).length]))
281
-
282
- // merge node groups and style it
283
- nodes = enteredNodes.merge(nodes)
284
-
285
- // force simulation
286
- force.simulation.nodes(nodesArr).on("tick", ticked)
287
-
288
- // links simulation
289
- force.simulation.force("link").links(links).id((d) => d.id).distance(attrs.distance * 2).strength(2)
290
- }
291
-
292
- // ####################################### EVENT HANDLERS ########################
293
-
294
- // zoom handler
295
- // function zoomed() {
296
- // // get transform event
297
- // let transform = event.transform
298
- // attrs.lastTransform = transform
299
- //
300
- // // apply transform event props to the wrapper
301
- // chart.attr("transform", transform)
302
- //
303
- // svg.selectAll(".node").attr("transform", (d) => `translate(${d.x},${d.y}) scale(${1 / (attrs.lastTransform ? attrs.lastTransform.k : 1)})`)
304
- // svg.selectAll(".link").attr("stroke-width", attrs.lineStrokeWidth / (attrs.lastTransform ? attrs.lastTransform.k : 1))
305
- // }
306
-
307
- // tick handler
308
- function ticked() {
309
- const fakeBorderWidth = attrs.fakeBorderWidth
310
- const maxXValueAvailable = (value) => Math.max(Math.min(calc.chartWidth - fakeBorderWidth, value), fakeBorderWidth)
311
- const maxYValueAvailable = (value) => Math.max(Math.min(calc.chartHeight - fakeBorderWidth, value), fakeBorderWidth)
312
- // set links position
313
- links
314
- .attr("x1", (d) => maxXValueAvailable(d.source.x))
315
- .attr("y1", (d) => maxYValueAvailable(d.source.y))
316
- .attr("x2", (d) => maxXValueAvailable(d.target.x))
317
- .attr("y2", (d) => maxYValueAvailable(d.target.y))
318
-
319
- // set nodes position
320
- svg.selectAll(".node")
321
- .attr("transform", (d) => `translate(${maxXValueAvailable(d.x)},${maxYValueAvailable(d.y)})`)
322
- }
323
-
324
- // handler drag start event
325
- function dragstarted() {
326
- // disable node fixing
327
- nodes.each((d) => {
328
- d.fx = null
329
- d.fy = null
330
- })
331
- }
332
-
333
- // handle dragging event
334
- function dragged(d) {
335
- // make dragged node fixed
336
- d.fx = event.x
337
- d.fy = event.y
338
- }
339
-
340
- // -------------------- handle drag end event ---------------
341
- function dragended() {
342
- // we are doing nothing, here , aren't we?
343
- }
344
-
345
- // -------------------------- node mouse hover handler ---------------
346
- function nodeMouseEnter(d) {
347
- // get links
348
- let _links = _hierarchy.root.links()
349
-
350
- // get hovered node connected links
351
- let connectedLinks = _links.filter((l) => l.source.id === d.id || l.target.id === d.id)
352
-
353
- // get hovered node linked nodes
354
- let linkedNodes = connectedLinks.map((s) => s.source.id).concat(connectedLinks.map((c) => c.target.id))
355
-
356
- // reduce all other nodes opacity
357
- nodesWrapper.selectAll(".node")
358
- .filter((n) => linkedNodes.indexOf(n.id) === -1)
359
- .attr("opacity", attrs.hoverOpacity)
360
-
361
- // reduce all other links opacity
362
- linksWrapper.selectAll(".link")
363
- .attr("opacity", attrs.hoverOpacity)
364
-
365
- // highlight hovered nodes connections
366
- linksWrapper.selectAll(".link")
367
- .filter((l) => l.source.id === d.id || l.target.id === d.id)
368
- .attr("opacity", 1)
369
- }
370
-
371
- // --------------- handle mouseleave event ---------------
372
- function nodeMouseLeave() {
373
- // return things back to normal
374
- nodesWrapper.selectAll(".node")
375
- .attr("opacity", 1)
376
- linksWrapper.selectAll(".link")
377
- .attr("opacity", 1)
378
- }
379
-
380
- // --------------- handle node click event ---------------
381
- function nodeClick(d) {
382
- // free fixed nodes
383
- nodes.each((di) => {
384
- di.fx = null
385
- di.fy = null
386
- })
387
-
388
- // collapse or expand node
389
- if (d.children) {
390
- collapse(d)
391
- } else if (d._children) {
392
- expand(d)
393
- } else {
394
- // nothing is to collapse or expand
395
- }
396
-
397
- freeNodes()
398
- }
399
-
400
- // ######################################### UTIL FUNCS ##################################
401
- updateData = function () {
402
- main.run()
403
- }
404
-
405
- collapse = function (d, deep = false) {
406
- if (d.children) {
407
- if (deep) {
408
- d.children.forEach((e) => collapse(e, true))
409
- }
410
-
411
- d._children = d.children
412
- d.children = null
413
- }
414
-
415
- update(d)
416
- force.simulation.restart()
417
- force.simulation.alphaTarget(0.15)
418
- }
419
-
420
- expand = function (d, deep = false) {
421
- if (d._children) {
422
- if (deep) {
423
- d._children.forEach((e) => expand(e, true))
424
- }
425
-
426
- d.children = d._children
427
- d._children = null
428
- }
429
-
430
- update(d)
431
- force.simulation.restart()
432
- force.simulation.alphaTarget(0.15)
433
- }
434
-
435
- // function slowDownNodes() {
436
- // force.simulation.alphaTarget(0.05)
437
- // }
438
-
439
- // function speedUpNodes() {
440
- // force.simulation.alphaTarget(0.45)
441
- // }
442
-
443
- function freeNodes() {
444
- selectAll(".node").each((n) => {
445
- n.fx = null
446
- n.fy = null
447
- })
448
- }
449
-
450
- function projectCircle(value, radius) {
451
- let r = radius || 0
452
- let corner = value * 2 * Math.PI
453
- return [Math.sin(corner) * r, -Math.cos(corner) * r]
454
- }
455
-
456
- // recursively loop on children and extract nodes as an array
457
- function flatten(root, clustered) {
458
- let nodesArray = []
459
- let i = 0
460
- function recurse(node, depth) {
461
- if (node.children) {
462
- node.children.forEach(function (child) {
463
- recurse(child, depth + 1)
464
- })
465
- }
466
-
467
- if (!node.id) {
468
- node.id = ++i
469
- } else {
470
- ++i
471
- }
472
-
473
- node.depth = depth
474
- if (clustered) {
475
- if (!node.cluster) {
476
- // if cluster coordinates are not set, set it
477
- node.cluster = { x: node.x, y: node.y }
478
- }
479
- }
480
- nodesArray.push(node)
481
- }
482
- recurse(root, 1)
483
- return nodesArray
484
- }
485
-
486
- function debug() {
487
- if (attrs.isDebug) {
488
- // stringify func
489
- let stringified = String(scope)
490
-
491
- // parse variable names
492
- let groupVariables = stringified
493
- // match var x-xx= {}
494
- .match(/var\s+([\w])+\s*=\s*{\s*}/gi)
495
- // match xxx
496
- .map((d) => d.match(/\s+\w*/gi).filter((s) => s.trim()))
497
- // get xxx
498
- .map((v) => v[0].trim())
499
-
500
- // assign local variables to the scope
501
- groupVariables.forEach((v) => {
502
- main[`P_${v}`] = eval(v)
503
- })
504
- }
505
- }
506
-
507
- debug()
508
-
509
- })
510
- }
511
-
512
- // ----------- PROTOTYEPE FUNCTIONS ----------------------
513
- function patternify(node, _params) {
514
- let selector = _params.selector
515
- let elementTag = _params.tag
516
- let _data = _params.data || [selector]
517
-
518
- // pattern in action
519
- let _selection = node.selectAll(`.${selector}`).data(_data)
520
- _selection.exit().remove()
521
- _selection = _selection.enter().append(elementTag).merge(_selection)
522
- _selection.attr("class", selector)
523
-
524
- return _selection
525
- }
526
-
527
- // custom radial layout
528
- function radial() {
529
- return function (root) {
530
-
531
- recurse(root, 0, 1)
532
-
533
- function recurse(node, min, _max) {
534
- node.proportion = (_max + min) / 2
535
- if (!node.x) {
536
-
537
- // if node has parent, match entered node positions to it's parent
538
- if (node.parent) {
539
- node.x = node.parent.x
540
- } else {
541
- node.x = 0
542
- }
543
- }
544
-
545
- // if node had parent, match entered node positions to it's parent
546
- if (!node.y) {
547
- if (node.parent) {
548
- node.y = node.parent.y
549
- } else {
550
- node.y = 0
551
- }
552
- }
553
-
554
- // recursively do the same for children
555
- if (node.children) {
556
- let offset = (_max - min) / node.children.length
557
- node.children.forEach(function (child, i) {
558
- let newMin = min + (offset * i)
559
- let newMax = newMin + offset
560
-
561
- recurse(child, newMin, newMax)
562
- })
563
- }
564
- }
565
- }
566
- }
567
-
568
- // https://github.com/bumbeishvili/d3js-boilerplates#orderby
569
- Array.prototype.orderBy = function (func) {
570
- this.sort((_a, _b) => {
571
- let a = func(_a)
572
- let b = func(_b)
573
- if (typeof a === "string" || a instanceof String) {
574
- return a.localeCompare(b)
575
- }
576
- return a - b
577
- })
578
-
579
- return this
580
- }
581
-
582
- // ########################## BOILEPLATE STUFF ################
583
-
584
- // dinamic keys functions
585
- Object.keys(attrs).forEach((key) => {
586
- // Attach variables to main function
587
- return main[key] = function (_) {
588
- let string = `attrs['${key}'] = _`
589
-
590
- if (!arguments.length) {
591
- return eval(` attrs['${key}'];`)
592
- }
593
-
594
- eval(string)
595
-
596
- return main
597
- }
598
- })
599
-
600
- // set attrs as property
601
- main.attrs = attrs
602
-
603
- // debugging visuals
604
- main.debug = function (isDebug) {
605
- attrs.isDebug = isDebug
606
- if (isDebug) {
607
- if (!window.charts) {
608
- window.charts = []
609
- }
610
- window.charts.push(main)
611
- }
612
- return main
613
- }
614
-
615
- // exposed update functions
616
- main.data = function (value) {
617
- if (!arguments.length) {
618
- return attrs.data
619
- }
620
-
621
- attrs.data = value
622
- if (typeof updateData === "function") {
623
- updateData()
624
- }
625
- return main
626
- }
627
-
628
- // run visual
629
- main.run = function () {
630
- selectAll(attrs.container)
631
- .call(main)
632
- return main
633
- }
634
-
635
- main.filter = function (filterParams) {
636
- if (!arguments.length) {
637
- return attrs.filterParams
638
- }
639
-
640
- attrs.filterParams = filterParams
641
- if (typeof filter === "function") {
642
- filter()
643
- }
644
- return main
645
- }
646
-
647
- main.reset = function () {
648
-
649
- _hierarchy.root.children.forEach((e) => collapse(e, true))
650
- main.run()
651
-
652
- return main
653
- }
654
-
655
- return main
656
- }
657
-
658
- // initialization
659
- $orgChartContainer.each((i, container) => {
660
-
661
- let $container = $(container)
662
- let width = $container.width()
663
- let height = width / (16 / 9)
664
-
665
- json($container.data("url")).then((data) => {
666
- // Make a fake previous node if the data entry is not hierarchical
667
- if (data instanceof Array) {
668
- fake = true
669
- dataDepicted = {
670
- name: null,
671
- children: data
672
- }
673
- } else {
674
- dataDepicted = data
675
- }
676
-
677
- orgchart = renderChartCollapsibleNetwork()
678
- .svgHeight(height)
679
- .svgWidth(width)
680
- .fakeRoot(fake)
681
- .container(`#${container.id}`)
682
- .data({
683
- root: dataDepicted
684
- })
685
- .debug(true)
686
- .run()
687
- })
688
- })
689
-
690
- // reset
691
- $btnReset.click(function() {
692
- orgchart.reset()
693
- })
694
- }
695
-
696
- $(() => {
697
- renderOrgCharts()
698
- $(document).on("change.zf.tabs", () => {
699
- renderOrgCharts()
700
- });
701
- })