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.
- territories_dashboard_lib/commons/__init__.py +0 -0
- territories_dashboard_lib/commons/decorators.py +36 -0
- territories_dashboard_lib/commons/models.py +9 -0
- territories_dashboard_lib/geo_lib/__init__.py +0 -0
- territories_dashboard_lib/geo_lib/admin.py +64 -0
- territories_dashboard_lib/geo_lib/enums.py +7 -0
- territories_dashboard_lib/geo_lib/migrations/0001_initial.py +51 -0
- territories_dashboard_lib/geo_lib/migrations/__init__.py +0 -0
- territories_dashboard_lib/geo_lib/models.py +58 -0
- territories_dashboard_lib/geo_lib/urls.py +27 -0
- territories_dashboard_lib/geo_lib/views.py +239 -0
- territories_dashboard_lib/indicators_lib/__init__.py +0 -0
- territories_dashboard_lib/indicators_lib/admin.py +140 -0
- territories_dashboard_lib/indicators_lib/enums.py +59 -0
- territories_dashboard_lib/indicators_lib/export.py +29 -0
- territories_dashboard_lib/indicators_lib/format.py +34 -0
- territories_dashboard_lib/indicators_lib/methodo_pdf.py +99 -0
- territories_dashboard_lib/indicators_lib/migrations/0001_initial.py +138 -0
- territories_dashboard_lib/indicators_lib/migrations/__init__.py +0 -0
- territories_dashboard_lib/indicators_lib/models.py +230 -0
- territories_dashboard_lib/indicators_lib/payloads.py +54 -0
- territories_dashboard_lib/indicators_lib/query/commons.py +223 -0
- territories_dashboard_lib/indicators_lib/query/comparison.py +70 -0
- territories_dashboard_lib/indicators_lib/query/details.py +64 -0
- territories_dashboard_lib/indicators_lib/query/histogram.py +82 -0
- territories_dashboard_lib/indicators_lib/query/indicator_card.py +102 -0
- territories_dashboard_lib/indicators_lib/query/top_10.py +100 -0
- territories_dashboard_lib/indicators_lib/query/utils.py +20 -0
- territories_dashboard_lib/indicators_lib/refresh_filters.py +17 -0
- territories_dashboard_lib/indicators_lib/table.py +154 -0
- territories_dashboard_lib/indicators_lib/urls.py +97 -0
- territories_dashboard_lib/indicators_lib/views.py +490 -0
- territories_dashboard_lib/superset_lib/__init__.py +0 -0
- territories_dashboard_lib/superset_lib/admin.py +22 -0
- territories_dashboard_lib/superset_lib/guest_token.py +64 -0
- territories_dashboard_lib/superset_lib/logic.py +67 -0
- territories_dashboard_lib/superset_lib/migrations/0001_initial.py +45 -0
- territories_dashboard_lib/superset_lib/migrations/__init__.py +0 -0
- territories_dashboard_lib/superset_lib/models.py +52 -0
- territories_dashboard_lib/superset_lib/serializers.py +10 -0
- territories_dashboard_lib/superset_lib/urls.py +10 -0
- territories_dashboard_lib/superset_lib/views.py +19 -0
- territories_dashboard_lib/tracking_lib/__init__.py +0 -0
- territories_dashboard_lib/tracking_lib/enums.py +7 -0
- territories_dashboard_lib/tracking_lib/logic.py +78 -0
- territories_dashboard_lib/tracking_lib/migrations/0001_initial.py +45 -0
- territories_dashboard_lib/tracking_lib/migrations/__init__.py +0 -0
- territories_dashboard_lib/tracking_lib/models.py +79 -0
- territories_dashboard_lib/website_lib/__init__.py +0 -0
- territories_dashboard_lib/website_lib/admin.py +40 -0
- territories_dashboard_lib/website_lib/context_processors.py +27 -0
- territories_dashboard_lib/website_lib/forms.py +47 -0
- territories_dashboard_lib/website_lib/migrations/0001_initial.py +91 -0
- territories_dashboard_lib/website_lib/migrations/__init__.py +0 -0
- territories_dashboard_lib/website_lib/models.py +148 -0
- territories_dashboard_lib/website_lib/navigation.py +124 -0
- territories_dashboard_lib/website_lib/params.py +268 -0
- territories_dashboard_lib/website_lib/serializers.py +105 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/css/website.css +956 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/chart.js +13 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/chartjs-plugin-datalabels.js +1 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/html2canvas.js +20 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/data.mjs +62 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/history.mjs +98 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/main-values.mjs +30 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/page.mjs +105 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/comparaison/territory-chart.mjs +141 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/data.mjs +59 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/histogram.mjs +130 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/map.mjs +25 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/page.mjs +96 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/proportions.mjs +77 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/sankey.mjs +27 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/table.mjs +229 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/top10.mjs +76 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/details/utils.mjs +8 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/dom.mjs +92 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/enums.mjs +104 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/export-graph.mjs +15 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/export.mjs +20 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/filters.mjs +159 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/format.mjs +54 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/side_panel.mjs +103 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/history.mjs +89 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/main-value.mjs +22 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/page.mjs +162 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/theme/statistics.mjs +42 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/indicators/utils.mjs +93 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/pages/static/page.mjs +35 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/patternomaly.js +1452 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/react18.js +31 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/reactdom18.js +267 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/js/supersetEmbed.js +355 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/indicatorMap.bundle.js +2 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/sankeyGraph.bundle.js +2 -0
- territories_dashboard_lib/website_lib/static/territories_dashboard_lib/website/react/vendors-node_modules_mapbox-gl_dist_mapbox-gl_js.bundle.js +2 -0
- territories_dashboard_lib/website_lib/static_content.py +20 -0
- territories_dashboard_lib/website_lib/templates/admin/indicators_lib/indicator/change_form.html +8 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/404.html +10 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/500.html +10 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/base.html +42 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/base.js +47 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/footer.html +96 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/header.html +101 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/layout/header.js +102 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/comparaison/[theme]/components/indicateur-card.html +48 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/comparaison/[theme]/page.html +52 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/chart-buttons.html +29 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/geo_params.html +71 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/indicator-card.html +52 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/loader.html +28 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel.html +27 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_geo.html +80 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_geo.js +85 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.html +45 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/side_panel_methodo.js +19 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/themes-list.html +9 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/themes-nav.html +33 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/components/title.html +28 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/filters-reminder.html +19 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/components/table.html +123 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/details/page.html +166 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/components/extremum.html +15 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/components/indicateur-card.html +76 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/indicators/themes/page.html +66 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/lexique/page.html +17 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/page.html +14 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/sitemap/page.html +71 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/static/page.html +16 -0
- territories_dashboard_lib/website_lib/templates/territories_dashboard_lib/website/pages/superset/page.html +55 -0
- territories_dashboard_lib/website_lib/templatetags/htmlparams.py +75 -0
- territories_dashboard_lib/website_lib/templatetags/other_filters.py +30 -0
- territories_dashboard_lib/website_lib/views.py +212 -0
- {territories_dashboard_lib-0.1.0.dist-info → territories_dashboard_lib-0.1.2.dist-info}/METADATA +1 -1
- territories_dashboard_lib-0.1.2.dist-info/RECORD +138 -0
- territories_dashboard_lib-0.1.0.dist-info/RECORD +0 -5
- {territories_dashboard_lib-0.1.0.dist-info → territories_dashboard_lib-0.1.2.dist-info}/WHEEL +0 -0
- {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,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 };
|