@geo2france/api-dashboard 1.15.0 → 1.16.0
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.
- package/dist/components/Charts/Pie.js +1 -1
- package/dist/components/Charts/Statistics.js +1 -1
- package/dist/components/Charts/YearSerie.d.ts +13 -0
- package/dist/components/Charts/YearSerie.js +36 -9
- package/dist/components/DashboardPage/Block.js +2 -1
- package/dist/components/DashboardPage/Page.d.ts +0 -13
- package/dist/components/DashboardPage/Page.js +24 -27
- package/dist/components/Dataset/Dataset.d.ts +11 -0
- package/dist/components/Dataset/Dataset.js +3 -2
- package/dist/components/Dataset/context.d.ts +9 -0
- package/dist/components/Dataset/context.js +7 -0
- package/dist/components/Dataset/hooks.d.ts +10 -30
- package/dist/components/Dataset/hooks.js +42 -12
- package/dist/components/Layout/DashboardApp.js +3 -1
- package/dist/components/Map/Map.js +0 -2
- package/dist/dsl/index.d.ts +2 -1
- package/dist/dsl/index.js +2 -1
- package/dist/utils/usechartexports.js +1 -1
- package/package.json +1 -1
|
@@ -32,7 +32,7 @@ export const ChartPie = ({ dataset: dataset_id, nameKey, dataKey, unit, title, d
|
|
|
32
32
|
color: usePalette({ nColors: chart_data?.length }),
|
|
33
33
|
itemStyle: {
|
|
34
34
|
/* Use label's color if any, otherwise fallback to Echarts calculated color */
|
|
35
|
-
color: (p) =>
|
|
35
|
+
color: (p) => colors_labels.find(i => i.label.toLowerCase() === p.name.toLowerCase())?.color ?? colors?.[p.dataIndex] ?? '#000'
|
|
36
36
|
},
|
|
37
37
|
data: chart_data,
|
|
38
38
|
radius: donut ? ['40%', '75%'] : [0, '75%'],
|
|
@@ -69,5 +69,5 @@ export const Statistics = ({ dataset: dataset_id, dataKey, unit, evolutionSuffix
|
|
|
69
69
|
export const StatisticsCollection = ({ children, columns = 3, title }) => {
|
|
70
70
|
const arrayChildren = Children.toArray(children);
|
|
71
71
|
useBlockConfig({ title: title });
|
|
72
|
-
return (_jsx(Row, { gutter: [8, 8], children: arrayChildren.map((c, index) => (_jsx(Col, { xl: 24 / columns, xs: 24, children: c }, index))) }));
|
|
72
|
+
return (_jsx(Row, { gutter: [8, 8], style: { margin: 8 }, children: arrayChildren.map((c, index) => (_jsx(Col, { xl: 24 / columns, xs: 24, children: c }, index))) }));
|
|
73
73
|
};
|
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Graphique standard pour afficher des données annuelles
|
|
3
3
|
*/
|
|
4
|
+
import { EChartsOption, SeriesOption } from "echarts";
|
|
4
5
|
interface IYearSerieProps {
|
|
5
6
|
dataset: string;
|
|
6
7
|
title?: string;
|
|
7
8
|
yearKey: string;
|
|
8
9
|
valueKey: string;
|
|
10
|
+
secondaryValueKey?: string;
|
|
9
11
|
categoryKey?: string;
|
|
10
12
|
stack?: boolean;
|
|
11
13
|
yearMark?: number | string;
|
|
14
|
+
normalize?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Fonction de tri appliquée aux séries (SeriesOption) avant affichage.
|
|
17
|
+
* Passée directement à `Array.sort()`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // Tri alphabétique des séries par leur nom
|
|
21
|
+
* seriesSort: (a, b) => a.name.localeCompare(b.name)
|
|
22
|
+
*/
|
|
23
|
+
seriesSort?: (a: SeriesOption, b: SeriesOption) => number;
|
|
12
24
|
type?: 'bar' | 'line' | 'area';
|
|
25
|
+
options?: Partial<EChartsOption>;
|
|
13
26
|
}
|
|
14
27
|
export declare const ChartYearSerie: React.FC<IYearSerieProps>;
|
|
15
28
|
export {};
|
|
@@ -7,7 +7,8 @@ import { useDataset } from "../Dataset/hooks";
|
|
|
7
7
|
import { usePalette, usePaletteLabels } from "../Palette/Palette";
|
|
8
8
|
import { ChartEcharts } from "./ChartEcharts";
|
|
9
9
|
import { useBlockConfig } from "../DashboardPage/Block";
|
|
10
|
-
|
|
10
|
+
import deepMerge from "../../utils/deepmerge";
|
|
11
|
+
export const ChartYearSerie = ({ dataset: dataset_id, categoryKey, valueKey, secondaryValueKey, yearKey, yearMark, stack: stack_input, title, type: chart_type = 'bar', normalize = false, seriesSort, options: custom_options = {} }) => {
|
|
11
12
|
const stack = stack_input || chart_type == 'line' ? false : true; // Pas de stack par défaut pour le type line
|
|
12
13
|
const dataset = useDataset(dataset_id);
|
|
13
14
|
const data = dataset?.data;
|
|
@@ -17,26 +18,48 @@ export const ChartYearSerie = ({ dataset: dataset_id, categoryKey, valueKey, yea
|
|
|
17
18
|
title: title,
|
|
18
19
|
dataExport: data
|
|
19
20
|
});
|
|
21
|
+
const rollupSpec = {
|
|
22
|
+
'value': op.sum(valueKey),
|
|
23
|
+
};
|
|
24
|
+
if (secondaryValueKey) {
|
|
25
|
+
rollupSpec['secondaryValue'] = op.sum(secondaryValueKey);
|
|
26
|
+
}
|
|
20
27
|
if (data && data.length > 0) {
|
|
21
28
|
const grouped_data = categoryKey ? from(data).groupby(yearKey, categoryKey) //Somme par année et categorykey
|
|
22
|
-
.rollup(
|
|
29
|
+
.rollup(rollupSpec)
|
|
23
30
|
.groupby(yearKey).orderby(yearKey)
|
|
24
31
|
:
|
|
25
32
|
from(data).groupby(yearKey) //Somme par année seulement
|
|
26
|
-
.rollup(
|
|
33
|
+
.rollup(rollupSpec)
|
|
34
|
+
.orderby(yearKey);
|
|
27
35
|
const all_years = from(data).groupby(yearKey).rollup({ [yearKey]: op.any(yearKey) });
|
|
28
36
|
const all_cats = categoryKey ? (from(data).groupby(categoryKey).rollup({ [categoryKey]: op.any(categoryKey) })) : from([{ 'cat': valueKey }]);
|
|
29
37
|
const full = all_years.cross(all_cats); // Contient chaque annee x catégorie (pour éviter les trous)
|
|
30
38
|
distinct_cat = all_cats.array(categoryKey || 'cat'); // Pour générer chaque serie
|
|
31
|
-
chart_data = full.join_left(grouped_data
|
|
39
|
+
chart_data = full.join_left(grouped_data
|
|
40
|
+
.derive({ part: d => 100 * d.value / op.sum(d.value) }) // Data for normalized view
|
|
41
|
+
.rename({ value: valueKey, part: `${valueKey}_pct`, secondaryValue: secondaryValueKey || '' }) // Rename to original var name
|
|
42
|
+
).objects();
|
|
32
43
|
}
|
|
33
44
|
const COLORS = usePalette({ nColors: distinct_cat?.length }) || [];
|
|
34
45
|
const colors_labels = usePaletteLabels();
|
|
35
46
|
const series = distinct_cat.map((cat, idx) => ({
|
|
36
47
|
name: cat,
|
|
37
48
|
type: chart_type === 'area' ? 'line' : chart_type,
|
|
38
|
-
data: categoryKey ? chart_data?.filter((row) => row[categoryKey] === cat)
|
|
39
|
-
|
|
49
|
+
data: categoryKey ? chart_data?.filter((row) => row[categoryKey] === cat)
|
|
50
|
+
.map((row) => ([String(row[yearKey]),
|
|
51
|
+
row[valueKey] || 0,
|
|
52
|
+
secondaryValueKey ? row[secondaryValueKey] : undefined,
|
|
53
|
+
row[`${valueKey}_pct`]
|
|
54
|
+
]))
|
|
55
|
+
: chart_data?.map((row) => ([String(row[yearKey]),
|
|
56
|
+
row[valueKey] || 0,
|
|
57
|
+
secondaryValueKey ? row[secondaryValueKey] : undefined,
|
|
58
|
+
row[`${valueKey}_pct`]])),
|
|
59
|
+
encode: {
|
|
60
|
+
x: 0, // annee
|
|
61
|
+
y: normalize ? 3 : 1 // valueKey ou `${ValueKey}_pct`
|
|
62
|
+
},
|
|
40
63
|
itemStyle: {
|
|
41
64
|
color: colors_labels.find(i => i.label.toLowerCase() === cat.toLowerCase())?.color ?? (COLORS && COLORS[idx % COLORS.length]),
|
|
42
65
|
},
|
|
@@ -44,11 +67,13 @@ export const ChartYearSerie = ({ dataset: dataset_id, categoryKey, valueKey, yea
|
|
|
44
67
|
areaStyle: chart_type === 'area' ? {} : undefined,
|
|
45
68
|
markLine: idx === 0 && yearMark ? {
|
|
46
69
|
symbol: 'none',
|
|
70
|
+
animation: false,
|
|
71
|
+
silent: true,
|
|
47
72
|
data: [
|
|
48
73
|
{ xAxis: String(yearMark) }
|
|
49
74
|
]
|
|
50
|
-
} : undefined
|
|
51
|
-
}));
|
|
75
|
+
} : undefined,
|
|
76
|
+
})).sort(seriesSort);
|
|
52
77
|
function tooltipFormatter(params) {
|
|
53
78
|
if (!params || params.length === 0)
|
|
54
79
|
return '';
|
|
@@ -74,7 +99,9 @@ export const ChartYearSerie = ({ dataset: dataset_id, categoryKey, valueKey, yea
|
|
|
74
99
|
},
|
|
75
100
|
yAxis: {
|
|
76
101
|
type: 'value',
|
|
102
|
+
max: normalize ? 100 : undefined,
|
|
103
|
+
min: normalize ? 0 : undefined,
|
|
77
104
|
},
|
|
78
105
|
};
|
|
79
|
-
return (_jsx(ChartEcharts, { option: option }));
|
|
106
|
+
return (_jsx(ChartEcharts, { notMerge: true, option: deepMerge({}, option, custom_options) }));
|
|
80
107
|
};
|
|
@@ -5,6 +5,7 @@ import { Icon } from "@iconify/react";
|
|
|
5
5
|
import { ProducersFooter } from "../Dataset/Producer";
|
|
6
6
|
import { MoreOutlined } from '@ant-design/icons';
|
|
7
7
|
import { ErrorBoundary } from "../Layout/Error";
|
|
8
|
+
import { cardStyles } from "../../utils/cardStyles";
|
|
8
9
|
const { useToken } = theme;
|
|
9
10
|
export const ChartBlockContext = createContext(undefined);
|
|
10
11
|
export const DSL_ChartBlock = ({ children }) => {
|
|
@@ -37,7 +38,7 @@ export const DSL_ChartBlock = ({ children }) => {
|
|
|
37
38
|
};
|
|
38
39
|
DL();
|
|
39
40
|
};
|
|
40
|
-
return (_jsx(ChartBlockContext.Provider, { value: { config: config, setConfig: (e) => setConfig(e) }, children: _jsx(Card, { style: { height: '100%' }, extra: has_action && dropdown_toolbox, title: config.title, children: _jsxs(ErrorBoundary, { children: [children, _jsx(ProducersFooter, { component: children })] }) }) }));
|
|
41
|
+
return (_jsx(ChartBlockContext.Provider, { value: { config: config, setConfig: (e) => setConfig(e) }, children: _jsx(Card, { className: "dashboard-element", style: { height: '100%' }, styles: cardStyles, extra: has_action && dropdown_toolbox, title: config.title, children: _jsxs(ErrorBoundary, { children: [children, _jsx(ProducersFooter, { component: children })] }) }) }));
|
|
41
42
|
};
|
|
42
43
|
export const useBlockConfig = ({ title, dataExport }) => {
|
|
43
44
|
const blockContext = useContext(ChartBlockContext);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { RowProps } from "antd";
|
|
2
2
|
import DashboardElement from "../DashboardElement/DashboardElement";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import { SimpleRecord } from "../../types";
|
|
5
4
|
import { Section } from "./Section";
|
|
6
5
|
type Section = {
|
|
7
6
|
key: string;
|
|
@@ -18,16 +17,6 @@ interface IDashboardPageProps {
|
|
|
18
17
|
}
|
|
19
18
|
declare const DashboardPage: React.FC<IDashboardPageProps>;
|
|
20
19
|
export default DashboardPage;
|
|
21
|
-
type dataset = {
|
|
22
|
-
id: string;
|
|
23
|
-
resource: string;
|
|
24
|
-
data?: SimpleRecord[];
|
|
25
|
-
isFetching: boolean;
|
|
26
|
-
isError: boolean;
|
|
27
|
-
producers?: any[];
|
|
28
|
-
geojson?: any;
|
|
29
|
-
dataHash?: number;
|
|
30
|
-
};
|
|
31
20
|
type ControlContextType = {
|
|
32
21
|
values: Record<string, any>;
|
|
33
22
|
pushValue: (control: {
|
|
@@ -35,8 +24,6 @@ type ControlContextType = {
|
|
|
35
24
|
value: any;
|
|
36
25
|
}) => void;
|
|
37
26
|
};
|
|
38
|
-
export declare const DatasetContext: React.Context<Record<string, dataset>>;
|
|
39
|
-
export declare const DatasetRegistryContext: React.Context<(dataset: dataset) => void>;
|
|
40
27
|
export declare const ControlContext: React.Context<ControlContextType | undefined>;
|
|
41
28
|
interface IDSLDashboardPageProps {
|
|
42
29
|
children: React.ReactNode;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Button, Col, Dropdown, Flex, Grid, Layout, Radio, Row, Tabs, theme } from "antd";
|
|
3
|
-
import React, { isValidElement, useState, createContext, } from "react";
|
|
3
|
+
import React, { isValidElement, useState, createContext, useEffect } from "react";
|
|
4
4
|
import { Helmet } from "react-helmet-async";
|
|
5
5
|
import { useSearchParamsState } from "../../utils/useSearchParamsState";
|
|
6
6
|
import Control, { DSL_Control } from "../Control/Control";
|
|
@@ -8,6 +8,7 @@ import { Dataset, Debug, Provider } from "../../dsl";
|
|
|
8
8
|
import { DEFAULT_PALETTE, Palette, PaletteContext } from "../Palette/Palette";
|
|
9
9
|
import { Section } from "./Section";
|
|
10
10
|
import { Icon } from "@iconify/react";
|
|
11
|
+
import { useDatasetRegistry } from "../Dataset/hooks";
|
|
11
12
|
const { Header } = Layout;
|
|
12
13
|
const { useToken } = theme;
|
|
13
14
|
const getSection = (child) => React.isValidElement(child) ? child.props.section : undefined;
|
|
@@ -39,22 +40,18 @@ const DashboardPage = ({ children: children_input, control, row_gutter = [8, 8],
|
|
|
39
40
|
})), value: activeTab, onChange: (e) => setActiveTab(e.target.value) }), control] }) }), _jsx(Row, { gutter: row_gutter, style: { margin: 16 }, children: children.map((child, idx) => ({ child, idx })).filter(({ child }) => (getSection(child) ?? 'Autres') == activeTab).map(({ child, idx }) => _jsx(Col, { xl: 12, xs: 24, children: child }, idx)) })] }));
|
|
40
41
|
};
|
|
41
42
|
export default DashboardPage;
|
|
42
|
-
export const DatasetContext = createContext({});
|
|
43
|
-
export const DatasetRegistryContext = createContext(() => { }); // A modifier, utiliser un seul context
|
|
44
43
|
export const ControlContext = createContext(undefined);
|
|
45
44
|
export const DSL_DashboardPage = ({ name = 'Tableau de bord', columns = 2, children, debug = false }) => {
|
|
46
45
|
const { token } = useToken();
|
|
47
|
-
const [datasets, setdatasets] = useState({});
|
|
48
46
|
const [palette, setPalette] = useState(DEFAULT_PALETTE);
|
|
47
|
+
const datasetRegistry = useDatasetRegistry();
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
return () => {
|
|
50
|
+
datasetRegistry.clear();
|
|
51
|
+
};
|
|
52
|
+
}, []);
|
|
49
53
|
//const allDatasetLoaded = Object.values(datasets).every(d => !d.isFetching);
|
|
50
54
|
//const isDatasetError = Object.values(datasets).some(d => d.isError);
|
|
51
|
-
// Ajouter ou mettre à jour un dataset
|
|
52
|
-
const pushDataset = (d) => {
|
|
53
|
-
setdatasets(prev => ({
|
|
54
|
-
...prev,
|
|
55
|
-
[d.id]: d
|
|
56
|
-
}));
|
|
57
|
-
};
|
|
58
55
|
const childrenArray = React.Children.toArray(children).filter(isValidElement);
|
|
59
56
|
const logicalComponents = [Dataset.name, Provider.name, Palette.name, Debug.name]; //Composant logiques, a ne pas mettre dans la grid
|
|
60
57
|
const getComponentKind = (c) => {
|
|
@@ -91,20 +88,20 @@ export const DSL_DashboardPage = ({ name = 'Tableau de bord', columns = 2, child
|
|
|
91
88
|
children: _jsx(Section, { title: 'Autres', children: visible_components })
|
|
92
89
|
});
|
|
93
90
|
}
|
|
94
|
-
return (_jsxs(_Fragment, { children: [_jsx(Helmet, { children: _jsx("title", { children: name }) }),
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
91
|
+
return (_jsxs(_Fragment, { children: [_jsx(Helmet, { children: _jsx("title", { children: name }) }), _jsxs(PaletteContext.Provider, { value: { palette, setPalette }, children: [control_components.length > 0 && _jsx(Header, { style: {
|
|
92
|
+
padding: 12,
|
|
93
|
+
position: "sticky",
|
|
94
|
+
top: 0,
|
|
95
|
+
zIndex: 600, // maplibre top zIndex if 500
|
|
96
|
+
backgroundColor: "#fff",
|
|
97
|
+
height: "auto",
|
|
98
|
+
width: "100%",
|
|
99
|
+
}, children: control_components }), items.length > 1 ?
|
|
100
|
+
_jsx(Tabs, { defaultActiveKey: "1", items: items, centered: true, tabBarStyle: { margin: 6,
|
|
101
|
+
padding: 4,
|
|
102
|
+
background: token.colorBgContainer,
|
|
103
|
+
borderRadius: token.borderRadiusLG }, style: { margin: 4 } })
|
|
104
|
+
:
|
|
105
|
+
_jsxs("div", { style: { margin: 4 }, children: [" ", items?.[0].children, " "] }) //Show content without tabs if only one
|
|
106
|
+
, logic_components] })] }));
|
|
110
107
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
+
import { SimpleRecord } from "../..";
|
|
2
3
|
import { CrudFilters, DataProvider } from "../../data_providers/types";
|
|
3
4
|
import React from "react";
|
|
4
5
|
import { ProviderType } from "./Provider";
|
|
@@ -13,5 +14,15 @@ interface IDatasetProps {
|
|
|
13
14
|
pageSize?: number;
|
|
14
15
|
meta?: any;
|
|
15
16
|
}
|
|
17
|
+
export type dataset = {
|
|
18
|
+
id: string;
|
|
19
|
+
resource: string;
|
|
20
|
+
data?: SimpleRecord[];
|
|
21
|
+
isFetching: boolean;
|
|
22
|
+
isError: boolean;
|
|
23
|
+
producers?: any[];
|
|
24
|
+
geojson?: any;
|
|
25
|
+
dataHash?: number;
|
|
26
|
+
};
|
|
16
27
|
export declare const DSL_Dataset: React.FC<IDatasetProps>;
|
|
17
28
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useContext, useEffect } from "react";
|
|
3
3
|
import { useApi } from "../..";
|
|
4
|
-
import { ControlContext
|
|
4
|
+
import { ControlContext } from "../DashboardPage/Page";
|
|
5
5
|
import { Producer } from "./Producer";
|
|
6
6
|
import React from "react";
|
|
7
7
|
import { Filter, Transform, useAllDatasets, useDatasets } from "../../dsl";
|
|
@@ -10,6 +10,7 @@ import { DataProviderContext, getProviderFromType } from "./Provider";
|
|
|
10
10
|
import { Join } from "./Join";
|
|
11
11
|
import { from } from "arquero";
|
|
12
12
|
import hashCode from "../../utils/hash_data";
|
|
13
|
+
import { DatasetRegistryContext } from "./context";
|
|
13
14
|
export const DSL_Dataset = ({ children, id, provider: provider_input, type: providerType = 'file', url: providerUrl, resource, pageSize, meta }) => {
|
|
14
15
|
const getTransformerFn = (component) => {
|
|
15
16
|
/*
|
|
@@ -99,7 +100,7 @@ export const DSL_Dataset = ({ children, id, provider: provider_input, type: prov
|
|
|
99
100
|
useEffect(() => {
|
|
100
101
|
const finalData = data?.data && transformers.reduce((datat, fn) => fn(datat), data.data);
|
|
101
102
|
if (datasetRegistryContext) {
|
|
102
|
-
datasetRegistryContext({
|
|
103
|
+
datasetRegistryContext.register({
|
|
103
104
|
id: id,
|
|
104
105
|
resource: resource,
|
|
105
106
|
data: finalData,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { dataset } from "./Dataset";
|
|
2
|
+
interface DatasetRegistryContextValue {
|
|
3
|
+
register: (dataset: dataset) => void;
|
|
4
|
+
clear: () => void;
|
|
5
|
+
get: (name: string) => dataset | undefined;
|
|
6
|
+
getAll: () => Record<string, dataset>;
|
|
7
|
+
}
|
|
8
|
+
export declare const DatasetRegistryContext: import("react").Context<DatasetRegistryContextValue>;
|
|
9
|
+
export {};
|
|
@@ -1,30 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
export declare const useDatasets: (dataset_ids?: string[]) => {
|
|
12
|
-
id: string;
|
|
13
|
-
resource: string;
|
|
14
|
-
data?: import("../..").SimpleRecord[];
|
|
15
|
-
isFetching: boolean;
|
|
16
|
-
isError: boolean;
|
|
17
|
-
producers?: any[];
|
|
18
|
-
geojson?: any;
|
|
19
|
-
dataHash?: number;
|
|
20
|
-
}[] | undefined;
|
|
21
|
-
export declare const useAllDatasets: () => {
|
|
22
|
-
id: string;
|
|
23
|
-
resource: string;
|
|
24
|
-
data?: import("../..").SimpleRecord[];
|
|
25
|
-
isFetching: boolean;
|
|
26
|
-
isError: boolean;
|
|
27
|
-
producers?: any[];
|
|
28
|
-
geojson?: any;
|
|
29
|
-
dataHash?: number;
|
|
30
|
-
}[] | undefined;
|
|
1
|
+
import { dataset } from "./Dataset";
|
|
2
|
+
export declare const useDataset: (dataset_id?: string) => dataset | undefined;
|
|
3
|
+
export declare const useAllDatasets: () => dataset[];
|
|
4
|
+
export declare const useDatasets: (dataset_ids?: string[]) => dataset[];
|
|
5
|
+
export declare const useDatasetRegistry: () => {
|
|
6
|
+
register: (d: dataset) => void;
|
|
7
|
+
clear: () => void;
|
|
8
|
+
get: (dataset_id?: string) => dataset | undefined;
|
|
9
|
+
getAll: () => Record<string, dataset>;
|
|
10
|
+
};
|
|
@@ -1,19 +1,49 @@
|
|
|
1
|
-
import { useContext } from "react";
|
|
2
|
-
import {
|
|
1
|
+
import { useCallback, useContext, useState } from "react";
|
|
2
|
+
import { DatasetRegistryContext } from "./context";
|
|
3
|
+
// 🔹 Hook pour récupérer un dataset unique
|
|
3
4
|
export const useDataset = (dataset_id) => {
|
|
4
|
-
const
|
|
5
|
+
const datasetRegistry = useContext(DatasetRegistryContext);
|
|
5
6
|
if (dataset_id) {
|
|
6
|
-
return
|
|
7
|
+
return datasetRegistry.get(dataset_id);
|
|
7
8
|
}
|
|
8
|
-
// Retourne le premier dataset si pas d'id
|
|
9
|
-
const firstKey = Object.keys(datasetContext)[0];
|
|
10
|
-
return firstKey ? datasetContext[firstKey] : undefined;
|
|
11
9
|
};
|
|
10
|
+
// 🔹 Hook pour récupérer tous les datasets sous forme de tableau
|
|
11
|
+
export const useAllDatasets = () => {
|
|
12
|
+
const datasetRegistry = useContext(DatasetRegistryContext);
|
|
13
|
+
return Object.values(datasetRegistry.getAll());
|
|
14
|
+
};
|
|
15
|
+
// 🔹 Hook pour filtrer plusieurs datasets par id
|
|
12
16
|
export const useDatasets = (dataset_ids) => {
|
|
13
|
-
const
|
|
14
|
-
return (
|
|
17
|
+
const datasets = useAllDatasets();
|
|
18
|
+
return (datasets.filter(d => dataset_ids?.includes(d.id)));
|
|
15
19
|
};
|
|
16
|
-
export const
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
export const useDatasetRegistry = () => {
|
|
21
|
+
/* DATASET */
|
|
22
|
+
const [datasets, setdatasets] = useState({});
|
|
23
|
+
const pushDataset = useCallback((d) => {
|
|
24
|
+
setdatasets(prev => {
|
|
25
|
+
const existing = prev[d.id];
|
|
26
|
+
if (existing && existing.dataHash === d.dataHash && existing.isFetching === d.isFetching) { // Eviter les rerender si les données n'ont pas changé
|
|
27
|
+
return prev;
|
|
28
|
+
}
|
|
29
|
+
return { ...prev, [d.id]: d };
|
|
30
|
+
});
|
|
31
|
+
}, []);
|
|
32
|
+
const clearDatasets = useCallback(() => {
|
|
33
|
+
setdatasets({});
|
|
34
|
+
}, []);
|
|
35
|
+
const getDataset = useCallback((dataset_id) => {
|
|
36
|
+
if (!dataset_id)
|
|
37
|
+
return undefined;
|
|
38
|
+
return datasets[dataset_id] ?? undefined;
|
|
39
|
+
}, [datasets]);
|
|
40
|
+
const getAllDataset = useCallback(() => {
|
|
41
|
+
return datasets;
|
|
42
|
+
}, [datasets]);
|
|
43
|
+
return {
|
|
44
|
+
register: pushDataset,
|
|
45
|
+
clear: clearDatasets,
|
|
46
|
+
get: getDataset,
|
|
47
|
+
getAll: getAllDataset,
|
|
48
|
+
};
|
|
19
49
|
};
|
|
@@ -10,6 +10,8 @@ import { DasbhoardFooter } from "./Footer";
|
|
|
10
10
|
import { createContext, useState } from "react";
|
|
11
11
|
import { ControlContext } from "../DashboardPage/Page";
|
|
12
12
|
import { HelmetProvider } from "react-helmet-async";
|
|
13
|
+
import { useDatasetRegistry } from "../Dataset/hooks";
|
|
14
|
+
import { DatasetRegistryContext } from "../Dataset/context";
|
|
13
15
|
//import '../../index.css' //TODO a intégrer en jsx
|
|
14
16
|
const queryClient = new QueryClient();
|
|
15
17
|
const default_theme = {
|
|
@@ -41,6 +43,6 @@ const DashboardApp = ({ routes, theme, logo, brands, footerSlider, title, subtit
|
|
|
41
43
|
...c
|
|
42
44
|
}));
|
|
43
45
|
};
|
|
44
|
-
return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ConfigProvider, { theme: theme || default_theme /* Merger plutôt ?*/, children: _jsx(HelmetProvider, { children: _jsx(AppContext.Provider, { value: context_values, children: _jsx(ControlContext.Provider, { value: { values: controls, pushValue: pushControl }, children: _jsx(HashRouter, { children: _jsx(Routes, { children: _jsxs(Route, { element: _jsxs(Layout, { hasSider: true, style: { minHeight: '100vh' }, children: [_jsx(DashboardSider, { route_config: routes }), _jsxs(Layout, { children: [_jsx(Content, { style: { width: "100%" }, children: _jsx(Outlet, {}) }), _jsx(DasbhoardFooter, { brands: brands, slider: footerSlider })] })] }), children: [generateRoutes(routes), _jsx(Route, { path: "*", element: _jsx(ErrorComponent, {}) })] }) }) }) }) }) }) }) }));
|
|
46
|
+
return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ConfigProvider, { theme: theme || default_theme /* Merger plutôt ?*/, children: _jsx(HelmetProvider, { children: _jsx(AppContext.Provider, { value: context_values, children: _jsx(DatasetRegistryContext.Provider, { value: useDatasetRegistry(), children: _jsx(ControlContext.Provider, { value: { values: controls, pushValue: pushControl }, children: _jsx(HashRouter, { children: _jsx(Routes, { children: _jsxs(Route, { element: _jsxs(Layout, { hasSider: true, style: { minHeight: '100vh' }, children: [_jsx(DashboardSider, { route_config: routes }), _jsxs(Layout, { children: [_jsx(Content, { style: { width: "100%" }, children: _jsx(Outlet, {}) }), _jsx(DasbhoardFooter, { brands: brands, slider: footerSlider })] })] }), children: [generateRoutes(routes), _jsx(Route, { path: "*", element: _jsx(ErrorComponent, {}) })] }) }) }) }) }) }) }) }) }));
|
|
45
47
|
};
|
|
46
48
|
export default DashboardApp;
|
|
@@ -35,7 +35,6 @@ const build_geojson = (params) => {
|
|
|
35
35
|
else {
|
|
36
36
|
features_collection = undefined;
|
|
37
37
|
}
|
|
38
|
-
console.log(geomKey, features_collection);
|
|
39
38
|
return features_collection;
|
|
40
39
|
};
|
|
41
40
|
export const Map = ({ dataset, color, type, paint, categoryKey, popup = false, popupFormatter: popupFormatterUser, title, xKey, yKey }) => {
|
|
@@ -74,7 +73,6 @@ export const MapLayer = ({ dataset, categoryKey, color = 'red', type = 'circle',
|
|
|
74
73
|
// src (lib proj4 pour convertir)
|
|
75
74
|
const keys = data?.data?.[0] ? Object.keys(data?.data?.[0]) : undefined;
|
|
76
75
|
const geomKey = [geomKey_input, "geom", "geometry"].find(c => c && keys?.includes(c));
|
|
77
|
-
console.log(data?.id, data?.data, geomKey);
|
|
78
76
|
// Si x et y sont definie, on construit le geojson
|
|
79
77
|
const geojson = xKey && yKey && data?.data ?
|
|
80
78
|
build_geojson({ data: data.data, xKey: xKey, yKey: yKey })
|
package/dist/dsl/index.d.ts
CHANGED
|
@@ -20,4 +20,5 @@ import { useBlockConfig } from "../components/DashboardPage/Block";
|
|
|
20
20
|
import { Statistics, StatisticsCollection } from "../components/Charts/Statistics";
|
|
21
21
|
import { MapLayer, Map } from "../components/Map/Map";
|
|
22
22
|
import { Section } from "../components/DashboardPage/Section";
|
|
23
|
-
|
|
23
|
+
import { LegendControl } from "../components/MapLegend/MapLegend";
|
|
24
|
+
export { Dashboard, Dataset, Provider, Transform, Join, Filter, Section, DataPreview, ChartEcharts, ChartPie, ChartYearSerie, Statistics, StatisticsCollection, useDataset, useDatasets, useAllDatasets, useBlockConfig, Producer, Control, useControl, useAllControls, Radio, Select, Input, Palette, usePalette, usePaletteLabels, PalettePreview, Debug, Map, MapLayer, LegendControl };
|
package/dist/dsl/index.js
CHANGED
|
@@ -20,4 +20,5 @@ import { useBlockConfig } from "../components/DashboardPage/Block";
|
|
|
20
20
|
import { Statistics, StatisticsCollection } from "../components/Charts/Statistics";
|
|
21
21
|
import { MapLayer, Map } from "../components/Map/Map";
|
|
22
22
|
import { Section } from "../components/DashboardPage/Section";
|
|
23
|
-
|
|
23
|
+
import { LegendControl } from "../components/MapLegend/MapLegend";
|
|
24
|
+
export { Dashboard, Dataset, Provider, Transform, Join, Filter, Section, DataPreview, ChartEcharts, ChartPie, ChartYearSerie, Statistics, StatisticsCollection, useDataset, useDatasets, useAllDatasets, useBlockConfig, Producer, Control, useControl, useAllControls, Radio, Select, Input, Palette, usePalette, usePaletteLabels, PalettePreview, Debug, Map, MapLayer, LegendControl };
|