decidim-assemblies 0.27.10 → 0.28.0.rc4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
- })