territories-dashboard-lib 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl

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.

Potentially problematic release.


This version of territories-dashboard-lib might be problematic. Click here for more details.

Files changed (138) hide show
  1. territories_dashboard_lib/commons/__init__.py +0 -0
  2. territories_dashboard_lib/commons/decorators.py +36 -0
  3. territories_dashboard_lib/commons/models.py +9 -0
  4. territories_dashboard_lib/geo_lib/__init__.py +0 -0
  5. territories_dashboard_lib/geo_lib/admin.py +64 -0
  6. territories_dashboard_lib/geo_lib/enums.py +7 -0
  7. territories_dashboard_lib/geo_lib/migrations/0001_initial.py +51 -0
  8. territories_dashboard_lib/geo_lib/migrations/__init__.py +0 -0
  9. territories_dashboard_lib/geo_lib/models.py +58 -0
  10. territories_dashboard_lib/geo_lib/urls.py +27 -0
  11. territories_dashboard_lib/geo_lib/views.py +239 -0
  12. territories_dashboard_lib/indicators_lib/__init__.py +0 -0
  13. territories_dashboard_lib/indicators_lib/admin.py +140 -0
  14. territories_dashboard_lib/indicators_lib/enums.py +59 -0
  15. territories_dashboard_lib/indicators_lib/export.py +29 -0
  16. territories_dashboard_lib/indicators_lib/format.py +34 -0
  17. territories_dashboard_lib/indicators_lib/methodo_pdf.py +99 -0
  18. territories_dashboard_lib/indicators_lib/migrations/0001_initial.py +138 -0
  19. territories_dashboard_lib/indicators_lib/migrations/__init__.py +0 -0
  20. territories_dashboard_lib/indicators_lib/models.py +230 -0
  21. territories_dashboard_lib/indicators_lib/payloads.py +54 -0
  22. territories_dashboard_lib/indicators_lib/query/commons.py +223 -0
  23. territories_dashboard_lib/indicators_lib/query/comparison.py +70 -0
  24. territories_dashboard_lib/indicators_lib/query/details.py +64 -0
  25. territories_dashboard_lib/indicators_lib/query/histogram.py +82 -0
  26. territories_dashboard_lib/indicators_lib/query/indicator_card.py +102 -0
  27. territories_dashboard_lib/indicators_lib/query/top_10.py +100 -0
  28. territories_dashboard_lib/indicators_lib/query/utils.py +20 -0
  29. territories_dashboard_lib/indicators_lib/refresh_filters.py +17 -0
  30. territories_dashboard_lib/indicators_lib/table.py +154 -0
  31. territories_dashboard_lib/indicators_lib/urls.py +97 -0
  32. territories_dashboard_lib/indicators_lib/views.py +490 -0
  33. territories_dashboard_lib/superset_lib/__init__.py +0 -0
  34. territories_dashboard_lib/superset_lib/admin.py +22 -0
  35. territories_dashboard_lib/superset_lib/guest_token.py +64 -0
  36. territories_dashboard_lib/superset_lib/logic.py +67 -0
  37. territories_dashboard_lib/superset_lib/migrations/0001_initial.py +45 -0
  38. territories_dashboard_lib/superset_lib/migrations/__init__.py +0 -0
  39. territories_dashboard_lib/superset_lib/models.py +52 -0
  40. territories_dashboard_lib/superset_lib/serializers.py +10 -0
  41. territories_dashboard_lib/superset_lib/urls.py +10 -0
  42. territories_dashboard_lib/superset_lib/views.py +19 -0
  43. territories_dashboard_lib/tracking_lib/__init__.py +0 -0
  44. territories_dashboard_lib/tracking_lib/enums.py +7 -0
  45. territories_dashboard_lib/tracking_lib/logic.py +78 -0
  46. territories_dashboard_lib/tracking_lib/migrations/0001_initial.py +45 -0
  47. territories_dashboard_lib/tracking_lib/migrations/__init__.py +0 -0
  48. territories_dashboard_lib/tracking_lib/models.py +79 -0
  49. territories_dashboard_lib/website_lib/__init__.py +0 -0
  50. territories_dashboard_lib/website_lib/admin.py +40 -0
  51. territories_dashboard_lib/website_lib/context_processors.py +27 -0
  52. territories_dashboard_lib/website_lib/forms.py +47 -0
  53. territories_dashboard_lib/website_lib/migrations/0001_initial.py +91 -0
  54. territories_dashboard_lib/website_lib/migrations/__init__.py +0 -0
  55. territories_dashboard_lib/website_lib/models.py +148 -0
  56. territories_dashboard_lib/website_lib/navigation.py +124 -0
  57. territories_dashboard_lib/website_lib/params.py +268 -0
  58. territories_dashboard_lib/website_lib/serializers.py +105 -0
  59. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/css/website.css +956 -0
  60. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/chart.js +13 -0
  61. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/chartjs-plugin-datalabels.js +1 -0
  62. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/html2canvas.js +20 -0
  63. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/data.mjs +62 -0
  64. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/history.mjs +98 -0
  65. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/main-values.mjs +30 -0
  66. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/page.mjs +105 -0
  67. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/territory-chart.mjs +141 -0
  68. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/data.mjs +59 -0
  69. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/histogram.mjs +130 -0
  70. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/map.mjs +25 -0
  71. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/page.mjs +96 -0
  72. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/proportions.mjs +77 -0
  73. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/sankey.mjs +27 -0
  74. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/table.mjs +229 -0
  75. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/top10.mjs +76 -0
  76. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/utils.mjs +8 -0
  77. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/dom.mjs +92 -0
  78. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/enums.mjs +104 -0
  79. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/export-graph.mjs +15 -0
  80. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/export.mjs +20 -0
  81. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/filters.mjs +159 -0
  82. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/format.mjs +54 -0
  83. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/side_panel.mjs +103 -0
  84. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/history.mjs +89 -0
  85. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/main-value.mjs +22 -0
  86. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/page.mjs +162 -0
  87. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/statistics.mjs +42 -0
  88. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/utils.mjs +93 -0
  89. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/static/page.mjs +35 -0
  90. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/patternomaly.js +1452 -0
  91. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/react18.js +31 -0
  92. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/reactdom18.js +267 -0
  93. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/supersetEmbed.js +355 -0
  94. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/indicatorMap.bundle.js +2 -0
  95. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/sankeyGraph.bundle.js +2 -0
  96. territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/vendors-node_modules_mapbox-gl_dist_mapbox-gl_js.bundle.js +2 -0
  97. territories_dashboard_lib/website_lib/static_content.py +20 -0
  98. territories_dashboard_lib/website_lib/templates/admin/indicators_lib/indicator/change_form.html +8 -0
  99. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/404.html +10 -0
  100. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/500.html +10 -0
  101. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/base.html +42 -0
  102. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/base.js +47 -0
  103. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/footer.html +96 -0
  104. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/header.html +101 -0
  105. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/header.js +102 -0
  106. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/comparaison/[theme]/components/indicateur-card.html +48 -0
  107. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/comparaison/[theme]/page.html +52 -0
  108. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/chart-buttons.html +29 -0
  109. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/geo_params.html +71 -0
  110. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/indicator-card.html +52 -0
  111. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/loader.html +28 -0
  112. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel.html +27 -0
  113. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_geo.html +80 -0
  114. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_geo.js +85 -0
  115. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.html +45 -0
  116. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.js +19 -0
  117. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/themes-list.html +9 -0
  118. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/themes-nav.html +33 -0
  119. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/title.html +28 -0
  120. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/filters-reminder.html +19 -0
  121. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/table.html +123 -0
  122. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/page.html +166 -0
  123. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/components/extremum.html +15 -0
  124. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/components/indicateur-card.html +76 -0
  125. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/page.html +66 -0
  126. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/lexique/page.html +17 -0
  127. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/page.html +14 -0
  128. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/sitemap/page.html +71 -0
  129. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/static/page.html +16 -0
  130. territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/superset/page.html +55 -0
  131. territories_dashboard_lib/website_lib/templatetags/htmlparams.py +75 -0
  132. territories_dashboard_lib/website_lib/templatetags/other_filters.py +30 -0
  133. territories_dashboard_lib/website_lib/views.py +212 -0
  134. {territories_dashboard_lib-0.1.0.dist-info → territories_dashboard_lib-0.1.2.dist-info}/METADATA +1 -1
  135. territories_dashboard_lib-0.1.2.dist-info/RECORD +138 -0
  136. territories_dashboard_lib-0.1.0.dist-info/RECORD +0 -5
  137. {territories_dashboard_lib-0.1.0.dist-info → territories_dashboard_lib-0.1.2.dist-info}/WHEEL +0 -0
  138. {territories_dashboard_lib-0.1.0.dist-info → territories_dashboard_lib-0.1.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,77 @@
1
+ import { getIndicatorDataScript, getParams } from "../dom.mjs";
2
+ import { getToolTip, makeChart, setBackgroundInDatasets } from "../utils.mjs";
3
+
4
+ import { COLORS } from "../enums.mjs";
5
+ import { addEmptyGraphMessage } from "./utils.mjs";
6
+ import { formatIndicatorValue } from "../format.mjs";
7
+
8
+ function getPlugins(indicator) {
9
+ return {
10
+ datalabels: {
11
+ display: true,
12
+ color: (context) => {
13
+ const bgColor = context.dataset.backgroundColor;
14
+ return COLORS[bgColor] || "white";
15
+ },
16
+ anchor: "center",
17
+ align: "center",
18
+ font: {
19
+ weight: "bold",
20
+ },
21
+ formatter: (value) =>
22
+ `${formatIndicatorValue(value)} ${indicator.unite}`,
23
+ },
24
+ tooltip: getToolTip(indicator.unite),
25
+ };
26
+ }
27
+
28
+ function makeProportionsChart(indicator) {
29
+ const { territory_name: label } = getParams();
30
+
31
+ const ctx = document.getElementById("proportionsChart");
32
+ if (ctx === null) {
33
+ return;
34
+ }
35
+
36
+ const proportionsData = getIndicatorDataScript(indicator, "proportions");
37
+ if (!proportionsData) {
38
+ return;
39
+ }
40
+
41
+ const datasets = proportionsData.values;
42
+
43
+ const emptyDatasets = datasets
44
+ .map((ds) => ds.data)
45
+ .flat()
46
+ .every((d) => d === null);
47
+ if (datasets.length === 0 || emptyDatasets) {
48
+ addEmptyGraphMessage(ctx);
49
+ return;
50
+ }
51
+
52
+ setBackgroundInDatasets(datasets);
53
+
54
+ const data = {
55
+ labels: [label],
56
+ datasets,
57
+ };
58
+ const options = {
59
+ indexAxis: "y",
60
+ maintainAspectRatio: false,
61
+ plugins: getPlugins(indicator),
62
+ scales: {
63
+ x: {
64
+ display: false,
65
+ stacked: true,
66
+ },
67
+ y: {
68
+ display: false,
69
+ stacked: true,
70
+ },
71
+ },
72
+ };
73
+
74
+ makeChart(ctx, "bar", data, options);
75
+ }
76
+
77
+ export { makeProportionsChart };
@@ -0,0 +1,27 @@
1
+ /* globals ReactDOM, React, SankeyGraph */
2
+
3
+ import { getParams } from "../dom.mjs";
4
+
5
+ function makeSankeyGraph(indicator) {
6
+ const params = getParams();
7
+ const container = document.getElementById("sankey-graph");
8
+ if (container) {
9
+ const root = ReactDOM.createRoot(container);
10
+ const element = React.createElement(
11
+ SankeyGraph,
12
+ {
13
+ indicator,
14
+ mesh: params.mesh,
15
+ territory: {
16
+ geoId: params.territory_id,
17
+ geoLevel: params.territory_mesh,
18
+ label: params.territory_name,
19
+ },
20
+ },
21
+ null
22
+ );
23
+ root.render(element);
24
+ }
25
+ }
26
+
27
+ export { makeSankeyGraph };
@@ -0,0 +1,229 @@
1
+ import { getApiUrls, getIndicator, getParams } from "../dom.mjs";
2
+ import { getIndicatorFilters } from "../filters.mjs";
3
+
4
+ function addClickEventOnTableHeader(tableContainer) {
5
+ tableContainer.querySelectorAll("thead th").forEach((element) => {
6
+ element.addEventListener("click", () => {
7
+ const orderflow =
8
+ element.dataset.orderflow === "ASC" ? "DESC" : "ASC";
9
+ updateTable({
10
+ tableContainer,
11
+ columnOrder: element.dataset.name,
12
+ columnOrderFlow: orderflow,
13
+ pagination: 1,
14
+ focus: true,
15
+ });
16
+ });
17
+ });
18
+ }
19
+
20
+ function addClickEventOnPagination(tableContainer) {
21
+ tableContainer.querySelectorAll(".fr-pagination__link").forEach((page) => {
22
+ page.addEventListener("click", () => {
23
+ const pagination = page.dataset.page;
24
+ updateTable({ tableContainer, pagination, focus: true });
25
+ });
26
+ });
27
+ }
28
+
29
+ function addOnSelectLimitInput(tableContainer) {
30
+ tableContainer
31
+ .querySelector(".select-table-limit")
32
+ .addEventListener("input", (event) => {
33
+ const limit = event.target.value;
34
+ updateTable({ tableContainer, limit, focus: true });
35
+ });
36
+ }
37
+
38
+ function addOnSearchInput(tableContainer) {
39
+ tableContainer
40
+ .querySelector(".table-search")
41
+ .addEventListener("change", (event) => {
42
+ const search = event.target.value;
43
+ updateTable({ tableContainer, pagination: 1, search, focus: true });
44
+ });
45
+ }
46
+
47
+ function addOnExportButtonClick(tableContainer, isFlows) {
48
+ const params = getParams();
49
+ const indicator = getIndicator();
50
+ const apiUrls = getApiUrls(indicator);
51
+
52
+ tableContainer.querySelectorAll(".table-export").forEach((button) => {
53
+ button.addEventListener("click", async () => {
54
+ const searchParams = new URLSearchParams(
55
+ `territory=${params.territory_id}-${params.territory_mesh}&submesh=${params.mesh}`
56
+ );
57
+ if (button.dataset.year) {
58
+ searchParams.set("year", button.dataset.year);
59
+ }
60
+ if (isFlows) {
61
+ searchParams.set("flows", true);
62
+ }
63
+ const response = await fetch(
64
+ `${apiUrls["details-table-export"]}?${searchParams.toString()}`
65
+ );
66
+ if (response.ok) {
67
+ const blob = await response.blob();
68
+ const url = window.URL.createObjectURL(blob);
69
+ const a = document.createElement("a");
70
+ a.href = url;
71
+ const name = isFlows ? "flux" : indicator.name;
72
+ a.download = `${name}${
73
+ button.dataset.year ? `_${button.dataset.year}` : ""
74
+ }_export.csv`;
75
+ document.body.appendChild(a);
76
+ a.click();
77
+ document.body.removeChild(a);
78
+ window.URL.revokeObjectURL(url);
79
+ }
80
+ });
81
+ });
82
+ }
83
+
84
+ function addFocusToLine(tableContainer) {
85
+ const table = tableContainer.querySelector("table");
86
+ const lineFocus = table.dataset.linefocus;
87
+ if (lineFocus) {
88
+ const line = table.querySelector(`tbody > tr:nth-child(${lineFocus})`);
89
+ line.focus();
90
+ }
91
+ }
92
+
93
+ function getDefaultValue({
94
+ table,
95
+ columnOrder,
96
+ columnOrderFlow,
97
+ pagination,
98
+ limit,
99
+ search,
100
+ }) {
101
+ let colOrder = columnOrder;
102
+ let colOrderFlow = columnOrderFlow;
103
+ if (table && colOrder === undefined) {
104
+ colOrder = table.dataset.sort;
105
+ }
106
+ if (table && colOrderFlow === undefined) {
107
+ colOrderFlow = table.dataset.orderflow;
108
+ }
109
+ let newLimit = limit;
110
+ if (table && newLimit === undefined) {
111
+ newLimit = table.dataset.limit;
112
+ }
113
+ let newSearch = search;
114
+ if (table && newSearch === undefined) {
115
+ newSearch = table.dataset.search;
116
+ }
117
+ let page = pagination;
118
+ if (table && page === undefined) {
119
+ page = table.dataset.page;
120
+ }
121
+
122
+ return { colOrder, colOrderFlow, newLimit, page, newSearch };
123
+ }
124
+
125
+ function getSearchParams({
126
+ indicator,
127
+ isFlows,
128
+ colOrder,
129
+ colOrderFlow,
130
+ newLimit,
131
+ newSearch,
132
+ page,
133
+ table,
134
+ focus,
135
+ }) {
136
+ const params = getParams();
137
+ const filters = getIndicatorFilters(indicator);
138
+ let filtersQuery = filters
139
+ .map(([dimension, filter]) => `&${dimension}=${filter}`)
140
+ .join("");
141
+ if (isFlows) {
142
+ filtersQuery = "";
143
+ }
144
+ const searchParams = new URLSearchParams(
145
+ `territory=${params.territory_id}-${params.territory_mesh}&submesh=${params.mesh}${filtersQuery}`
146
+ );
147
+ if (colOrder !== undefined) {
148
+ searchParams.set("column_order", colOrder);
149
+ }
150
+ if (colOrderFlow !== undefined) {
151
+ searchParams.set("column_order_flow", colOrderFlow);
152
+ }
153
+ if (page !== undefined) {
154
+ searchParams.set("pagination", page);
155
+ }
156
+ if (table) {
157
+ searchParams.set("previous_limit", table.dataset.limit);
158
+ }
159
+ if (newLimit !== undefined) {
160
+ searchParams.set("limit", newLimit);
161
+ }
162
+ if (newSearch !== undefined && newSearch !== "") {
163
+ searchParams.set("search", newSearch);
164
+ }
165
+ if (isFlows) {
166
+ searchParams.set("flows", true);
167
+ }
168
+ if (focus) {
169
+ searchParams.set("focus", true);
170
+ }
171
+ return searchParams;
172
+ }
173
+
174
+ async function updateTable({
175
+ tableContainer,
176
+ columnOrder,
177
+ columnOrderFlow,
178
+ pagination,
179
+ limit,
180
+ search,
181
+ focus,
182
+ }) {
183
+ const isFlows = tableContainer.dataset.source === "flows";
184
+ const indicator = getIndicator();
185
+ const apiUrls = getApiUrls(indicator);
186
+ const table = tableContainer.querySelector("table");
187
+ const { colOrder, colOrderFlow, newLimit, page, newSearch } =
188
+ getDefaultValue({
189
+ table,
190
+ columnOrder,
191
+ columnOrderFlow,
192
+ pagination,
193
+ limit,
194
+ search,
195
+ });
196
+ const searchParams = getSearchParams({
197
+ indicator,
198
+ isFlows,
199
+ table,
200
+ colOrder,
201
+ colOrderFlow,
202
+ newLimit,
203
+ page,
204
+ newSearch,
205
+ focus,
206
+ });
207
+ const response = await fetch(
208
+ `${apiUrls["details-table"]}?${searchParams.toString()}`
209
+ );
210
+ if (response.ok) {
211
+ const htmlData = await response.text();
212
+ tableContainer.innerHTML = htmlData;
213
+ addClickEventOnTableHeader(tableContainer);
214
+ addClickEventOnPagination(tableContainer);
215
+ addOnSelectLimitInput(tableContainer);
216
+ addOnSearchInput(tableContainer);
217
+ addOnExportButtonClick(tableContainer, isFlows);
218
+ addFocusToLine(tableContainer);
219
+ }
220
+ }
221
+
222
+ function makeTables() {
223
+ const tableContainers = document.querySelectorAll(".data-table");
224
+ tableContainers.forEach((tableContainer) => {
225
+ updateTable({ tableContainer });
226
+ });
227
+ }
228
+
229
+ export { makeTables };
@@ -0,0 +1,76 @@
1
+ import { getToolTip, makeChart, setBackgroundInDatasets } from "../utils.mjs";
2
+
3
+ import { addEmptyGraphMessage } from "./utils.mjs";
4
+ import { formatIndicatorValue } from "../format.mjs";
5
+ import { getIndicatorDataScript } from "../dom.mjs";
6
+
7
+ function getPlugins(indicator) {
8
+ return {
9
+ datalabels: {
10
+ display: function (context) {
11
+ return (
12
+ context.chart.isDatasetVisible(context.datasetIndex) &&
13
+ context.active
14
+ );
15
+ },
16
+ anchor: "center",
17
+ align: "center",
18
+ color: "white",
19
+ formatter: function (value) {
20
+ return formatIndicatorValue(value);
21
+ },
22
+ },
23
+ tooltip: getToolTip(indicator.unite),
24
+ };
25
+ }
26
+
27
+ function makeTop10Chart(indicator) {
28
+ const top10Data = getIndicatorDataScript(indicator, "top-10");
29
+ if (!top10Data) {
30
+ return;
31
+ }
32
+ const { datasetsTopBarChart: datasets, labelsTopBarChart: labels } =
33
+ top10Data;
34
+
35
+ setBackgroundInDatasets(datasets);
36
+
37
+ const ctx = document.getElementById("top10Chart");
38
+ const data = {
39
+ labels: labels.map((label, index) => {
40
+ const v = datasets.reduce(
41
+ (acc, dataset) => acc + dataset.data[index],
42
+ 0
43
+ );
44
+ if (datasets.length > 0) {
45
+ return `${label} (${formatIndicatorValue(v)} ${
46
+ indicator.unite
47
+ })`;
48
+ }
49
+ return label;
50
+ }),
51
+ datasets,
52
+ };
53
+
54
+ if (data.labels.length === 0) {
55
+ addEmptyGraphMessage(ctx);
56
+ return;
57
+ }
58
+
59
+ const options = {
60
+ indexAxis: "y",
61
+ plugins: getPlugins(indicator),
62
+ scales: {
63
+ x: {
64
+ stacked: true,
65
+ },
66
+ y: {
67
+ beginAtZero: true,
68
+ stacked: true,
69
+ },
70
+ },
71
+ };
72
+
73
+ makeChart(ctx, "bar", data, options);
74
+ }
75
+
76
+ export { makeTop10Chart };
@@ -0,0 +1,8 @@
1
+ function addEmptyGraphMessage(ctx) {
2
+ const div = document.createElement("div");
3
+ div.textContent =
4
+ "Il n'y a pas assez de données pour afficher le graphique.";
5
+ ctx.parentNode.insertBefore(div, ctx);
6
+ }
7
+
8
+ export { addEmptyGraphMessage };
@@ -0,0 +1,92 @@
1
+ function fillMethodoSidePanel(indicator) {
2
+ const container = document.getElementById(
3
+ "slide-panel-content-methodo-markdown"
4
+ );
5
+ container.innerHTML = indicator.methodo_html;
6
+ const exportButton = document.getElementById("methodo-export-button");
7
+ exportButton.dataset.indicatorName = indicator.name;
8
+ exportButton.dataset.indicatorTitle = indicator.title;
9
+ document.getElementById("slide-panel-methodo-indicator-title").textContent =
10
+ indicator.title;
11
+ document.getElementById("slide-panel-methodo-theme-title").textContent =
12
+ indicator.theme;
13
+ }
14
+
15
+ function getClosestIndicator(element) {
16
+ const indicatorId = element.closest(".indicator-card").dataset.indicator;
17
+ return JSON.parse(document.getElementById(indicatorId).textContent);
18
+ }
19
+
20
+ function getIndicator() {
21
+ return JSON.parse(document.getElementById("indicator-js").textContent);
22
+ }
23
+
24
+ function getScriptId(indicator, key) {
25
+ return `${indicator.id}-data-${key}`;
26
+ }
27
+
28
+ function makeIndicatorDataScript(indicator, key, data) {
29
+ const scriptId = getScriptId(indicator, key);
30
+
31
+ const existingScript = document.getElementById(scriptId);
32
+ if (existingScript) {
33
+ existingScript.remove();
34
+ }
35
+
36
+ const script = document.createElement("script");
37
+ script.id = scriptId;
38
+ script.type = "application/json";
39
+ script.textContent = JSON.stringify(data);
40
+
41
+ let container = document.getElementById(`card-${indicator.id}`);
42
+ if (container === null) {
43
+ container = document.querySelector("body");
44
+ }
45
+ container.insertBefore(script, container.firstChild);
46
+ }
47
+
48
+ function getIndicatorDataScript(indicator, key) {
49
+ const scriptId = getScriptId(indicator, key);
50
+ const script = document.getElementById(scriptId);
51
+ return script ? JSON.parse(script.textContent) : null;
52
+ }
53
+
54
+ function getIsAlternativeUnit(indicatorId) {
55
+ const input = document.getElementById(`${indicatorId}-toggle-unit`);
56
+ return input && input.checked;
57
+ }
58
+
59
+ function getParams() {
60
+ return JSON.parse(document.getElementById("params-js").textContent);
61
+ }
62
+
63
+ function getApiUrls(indicator) {
64
+ return JSON.parse(
65
+ document.getElementById(`${indicator.id}-api-urls`).textContent
66
+ );
67
+ }
68
+
69
+ function removeDelaySpinner(selector) {
70
+ document.querySelectorAll(selector).forEach((el) => {
71
+ el.classList.remove("delay-spinner");
72
+ });
73
+ }
74
+
75
+ function delaySpinner() {
76
+ setTimeout(() => {
77
+ removeDelaySpinner(".delay-spinner");
78
+ }, 1000);
79
+ }
80
+
81
+ export {
82
+ delaySpinner,
83
+ getClosestIndicator,
84
+ fillMethodoSidePanel,
85
+ makeIndicatorDataScript,
86
+ getIndicatorDataScript,
87
+ getIsAlternativeUnit,
88
+ getParams,
89
+ getIndicator,
90
+ getApiUrls,
91
+ removeDelaySpinner,
92
+ };
@@ -0,0 +1,104 @@
1
+ const THOUSANDS = "k";
2
+ const MILLIONS = "M";
3
+
4
+ const MeshLevel = {
5
+ National: "fr",
6
+ Region: "reg",
7
+ Department: "dep",
8
+ Epci: "epci",
9
+ Town: "com",
10
+ };
11
+
12
+ const COLORS = {
13
+ "#6A6AF4": "white",
14
+ "#000091": "white",
15
+ "#E1000F": "white",
16
+ "#B7A73F": "black",
17
+ "#66673D": "white",
18
+ "#68A532": "black",
19
+ "#447049": "white",
20
+ "#00A95F": "black",
21
+ "#297254": "white",
22
+ "#009081": "black",
23
+ "#37635F": "white",
24
+ "#009099": "black",
25
+ "#006A6F": "white",
26
+ "#465F9D": "white",
27
+ "#2F4077": "white",
28
+ "#417DC4": "black",
29
+ "#3558A2": "white",
30
+ "#A558A0": "black",
31
+ "#6E445A": "white",
32
+ "#E18B76": "black",
33
+ "#8D533E": "white",
34
+ "#CE614A": "black",
35
+ "#A94645": "white",
36
+ "#C8AA39": "black",
37
+ "#716043": "white",
38
+ "#C3992A": "black",
39
+ "#695240": "white",
40
+ "#E4794A": "black",
41
+ "#755348": "white",
42
+ "#D1B781": "black",
43
+ "#685C48": "white",
44
+ "#C08C65": "black",
45
+ "#845d48": "white",
46
+ "#BD987A": "black",
47
+ "#745B47": "white",
48
+ "#AEA397": "black",
49
+ "#6A6156": "white",
50
+ "#C9191E": "white",
51
+ };
52
+
53
+ const PATTERNS = [
54
+ "plus",
55
+ "square",
56
+ "zigzag",
57
+ "dash",
58
+ "dot",
59
+ "cross",
60
+ "weave",
61
+ "triangle",
62
+ "disc",
63
+ "box",
64
+ "ring",
65
+ "line",
66
+ "diagonal",
67
+ "cross-dash",
68
+ "dot-dash",
69
+ "triangle-inverted",
70
+ "diamond",
71
+ "line-vertical",
72
+ "zigzag-vertical",
73
+ "diagonal-right-left",
74
+ "diamond-box",
75
+ ];
76
+
77
+ function getMeshLevelTitle(meshLevel) {
78
+ switch (meshLevel) {
79
+ case MeshLevel.Region:
80
+ return "Région";
81
+ case MeshLevel.Department:
82
+ return "Département";
83
+ case MeshLevel.Epci:
84
+ return "Intercommunalité";
85
+ case MeshLevel.Town:
86
+ return "Commune";
87
+ case MeshLevel.National:
88
+ return "France entière";
89
+ }
90
+ }
91
+
92
+ const MAX_TERRITORIES_BEFORE_HIDE = 5;
93
+ const SHORT_MESH_NUMBER_OF_LETTERS = 3;
94
+
95
+ export {
96
+ MILLIONS,
97
+ THOUSANDS,
98
+ COLORS,
99
+ MeshLevel,
100
+ getMeshLevelTitle,
101
+ MAX_TERRITORIES_BEFORE_HIDE,
102
+ SHORT_MESH_NUMBER_OF_LETTERS,
103
+ PATTERNS,
104
+ };
@@ -0,0 +1,15 @@
1
+ /* globals html2canvas */
2
+
3
+ async function exportImageAsync(element, fileName) {
4
+ const canvas = await html2canvas(element);
5
+ const image = canvas.toDataURL("image/png", 1.0);
6
+ const tempLink = document.createElement("a");
7
+ tempLink.download = fileName;
8
+ tempLink.href = image;
9
+ document.body.appendChild(tempLink);
10
+ tempLink.click();
11
+ document.body.removeChild(tempLink);
12
+ tempLink.remove();
13
+ }
14
+
15
+ export { exportImageAsync };
@@ -0,0 +1,20 @@
1
+ import { getApiUrls } from "./dom.mjs";
2
+
3
+ async function exportToCSV(button, indicator, route, searchParams) {
4
+ const apiUrls = getApiUrls(indicator);
5
+ const response = await fetch(`${apiUrls[route]}export/?${searchParams}`);
6
+ button.removeAttribute("disabled");
7
+ if (response.ok) {
8
+ const blob = await response.blob();
9
+ const url = window.URL.createObjectURL(blob);
10
+ const a = document.createElement("a");
11
+ a.href = url;
12
+ a.download = `${indicator.name} - ${button.dataset.title}.csv`;
13
+ document.body.appendChild(a);
14
+ a.click();
15
+ document.body.removeChild(a);
16
+ window.URL.revokeObjectURL(url);
17
+ }
18
+ }
19
+
20
+ export { exportToCSV };