datastake-daf 0.6.817 → 0.6.818
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/index.js +54 -10
- package/dist/pages/index.js +222 -58
- package/dist/style/datastake/mapbox-gl.css +330 -0
- package/package.json +1 -1
- package/public/Vegetation/damage-from-insects-default.svg +1 -0
- package/public/Vegetation/dry-or-dead-default.svg +1 -0
- package/public/Vegetation/healthy-default.svg +1 -0
- package/public/Vegetation/yellowing.svg +1 -0
- package/src/@daf/core/components/Charts/RadarChart/index.jsx +53 -2
- package/src/@daf/core/components/Charts/style.js +1 -1
- package/src/@daf/core/components/Dashboard/Widget/VegetationWidget/index.jsx +0 -4
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/BiodiversityHabitat/ObservedFauna.jsx +6 -11
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/BiodiversityHabitat/index.jsx +4 -2
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/PlantedSpecies.jsx +25 -10
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/SeedlingsHeight.jsx +10 -13
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/MangroveGrowth/VegetationHealth.jsx +19 -4
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/SoilWaterProfile/SoilType.jsx +22 -10
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/SoilWaterProfile/WaterQuality.jsx +26 -10
- package/src/@daf/pages/Summary/Activities/MonitoringCampaign/components/chartHelpers.js +74 -0
|
@@ -3,7 +3,15 @@ import { Widget, PieChart } from '../../../../../../../../src/index.js';
|
|
|
3
3
|
import { renderTooltipJsx } from '../../../../../../utils/tooltip.js';
|
|
4
4
|
import { renderPercentage } from '../../../../../../utils/numbers.js';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
// Color mapping for soil types
|
|
7
|
+
const SOIL_TYPE_COLORS = {
|
|
8
|
+
sandy: '#00AEB1',
|
|
9
|
+
mixed: '#016C6E',
|
|
10
|
+
clay: '#A0EBEC',
|
|
11
|
+
muddy: '#4FB3A1',
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const DEFAULT_COLOR = '#9E9E9E';
|
|
7
15
|
|
|
8
16
|
const SoilType = ({
|
|
9
17
|
soilTypeChart,
|
|
@@ -28,7 +36,7 @@ const SoilType = ({
|
|
|
28
36
|
return data.map((item, index) => ({
|
|
29
37
|
value: Number(item?.count) || 0,
|
|
30
38
|
percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
|
|
31
|
-
color:
|
|
39
|
+
color: SOIL_TYPE_COLORS[item?.soilType] || DEFAULT_COLOR,
|
|
32
40
|
label: optionsMap[item?.soilType] || item?.soilType || '',
|
|
33
41
|
key: item?.soilType || `item-${index}`,
|
|
34
42
|
}));
|
|
@@ -45,17 +53,21 @@ const SoilType = ({
|
|
|
45
53
|
return null;
|
|
46
54
|
}
|
|
47
55
|
|
|
56
|
+
// Show all items in the tooltip, sorted by percentage (descending)
|
|
57
|
+
const allItems = pieData
|
|
58
|
+
.filter(dataItem => dataItem.value > 0)
|
|
59
|
+
.sort((a, b) => b.percent - a.percent)
|
|
60
|
+
.map(dataItem => ({
|
|
61
|
+
color: dataItem.color,
|
|
62
|
+
label: dataItem.label || '',
|
|
63
|
+
value: renderPercentage(Math.round(dataItem.percent * 100)),
|
|
64
|
+
}));
|
|
65
|
+
|
|
48
66
|
return renderTooltipJsx({
|
|
49
67
|
title: t("Soil Type"),
|
|
50
|
-
items:
|
|
51
|
-
{
|
|
52
|
-
color: item.color,
|
|
53
|
-
label: optionsMap[item.label] || item.label || '',
|
|
54
|
-
value: `${ renderPercentage(item.percent.toFixed(2) * 100)}`,
|
|
55
|
-
},
|
|
56
|
-
],
|
|
68
|
+
items: allItems,
|
|
57
69
|
});
|
|
58
|
-
}, [t, isEmpty,
|
|
70
|
+
}, [t, isEmpty, pieData]);
|
|
59
71
|
|
|
60
72
|
return (
|
|
61
73
|
<Widget
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import React, { useMemo, useCallback } from 'react';
|
|
2
2
|
import { Widget, PieChart } from '../../../../../../../../src/index.js';
|
|
3
3
|
import { renderTooltipJsx } from '../../../../../../utils/tooltip.js';
|
|
4
|
+
import { renderPercentage } from '../../../../../../utils/numbers.js';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
// Color mapping for water quality types
|
|
7
|
+
const WATER_QUALITY_COLORS = {
|
|
8
|
+
fairly_clear: '#32D583',
|
|
9
|
+
turbid: '#FFA940',
|
|
10
|
+
polluted: '#F97066',
|
|
11
|
+
oil_traces: '#2B3644',
|
|
12
|
+
no_water: '#DAD6CE',
|
|
13
|
+
clear: '#6AD99E',
|
|
14
|
+
other: '#9E9E9E',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const DEFAULT_COLOR = '#9E9E9E';
|
|
6
18
|
|
|
7
19
|
const WaterQuality = ({
|
|
8
20
|
waterQualityChart,
|
|
@@ -26,7 +38,7 @@ const WaterQuality = ({
|
|
|
26
38
|
return data.map((item, index) => ({
|
|
27
39
|
value: Number(item?.count) || 0,
|
|
28
40
|
percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
|
|
29
|
-
color:
|
|
41
|
+
color: WATER_QUALITY_COLORS[item?.waterQuality] || DEFAULT_COLOR,
|
|
30
42
|
label: optionsMap[item?.waterQuality] || item?.waterQuality || '',
|
|
31
43
|
key: item?.waterQuality || `item-${index}`,
|
|
32
44
|
}));
|
|
@@ -43,18 +55,22 @@ const WaterQuality = ({
|
|
|
43
55
|
return null;
|
|
44
56
|
}
|
|
45
57
|
|
|
58
|
+
// Show all items in the tooltip, sorted by percentage (descending)
|
|
59
|
+
const allItems = pieData
|
|
60
|
+
.filter(dataItem => dataItem.value > 0)
|
|
61
|
+
.sort((a, b) => b.percent - a.percent)
|
|
62
|
+
.map(dataItem => ({
|
|
63
|
+
color: dataItem.color,
|
|
64
|
+
label: dataItem.label || '',
|
|
65
|
+
value: renderPercentage(Math.round(dataItem.percent * 100)),
|
|
66
|
+
}));
|
|
67
|
+
|
|
46
68
|
return renderTooltipJsx({
|
|
47
69
|
title: t("Water Quality"),
|
|
48
|
-
items:
|
|
49
|
-
{
|
|
50
|
-
color: item.color,
|
|
51
|
-
label: item.label || '',
|
|
52
|
-
value: `${Math.round(item.percent * 100)}%`,
|
|
53
|
-
},
|
|
54
|
-
],
|
|
70
|
+
items: allItems,
|
|
55
71
|
});
|
|
56
72
|
},
|
|
57
|
-
[t, isEmpty]
|
|
73
|
+
[t, isEmpty, pieData]
|
|
58
74
|
);
|
|
59
75
|
|
|
60
76
|
return (
|
|
@@ -59,6 +59,80 @@ export const calculateNiceAxisConfig = (data, valueField = 'value', multiplier =
|
|
|
59
59
|
};
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Calculate y-axis configuration with natural numbers (integers) only
|
|
64
|
+
* Always starts from 0 and extends slightly above max for better visualization
|
|
65
|
+
* @param {number} maxValue - Maximum value from the data
|
|
66
|
+
* @param {Object} options - Optional configuration
|
|
67
|
+
* @param {number} options.minTicks - Minimum number of ticks to show (default: 4)
|
|
68
|
+
* @param {number} options.maxTicks - Maximum number of ticks to show (default: 6)
|
|
69
|
+
* @returns {Object} Axis configuration with min, max, and tickMethod
|
|
70
|
+
*/
|
|
71
|
+
export const calculateNaturalAxisConfig = (maxValue, options = {}) => {
|
|
72
|
+
const { minTicks = 4, maxTicks = 6 } = options;
|
|
73
|
+
|
|
74
|
+
if (maxValue <= 0) {
|
|
75
|
+
return {
|
|
76
|
+
min: 0,
|
|
77
|
+
max: 4,
|
|
78
|
+
tickMethod: () => [0, 1, 2, 3, 4]
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// For very small values (max <= 1), always show 0, 1, 2, 3, 4
|
|
83
|
+
if (maxValue <= 1) {
|
|
84
|
+
return {
|
|
85
|
+
min: 0,
|
|
86
|
+
max: 4,
|
|
87
|
+
tickMethod: () => [0, 1, 2, 3, 4]
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Calculate appropriate step size based on max value
|
|
92
|
+
let step = 1;
|
|
93
|
+
let displayMax = maxValue;
|
|
94
|
+
|
|
95
|
+
if (maxValue <= 5) {
|
|
96
|
+
// For small values, use step of 1 and extend a bit above
|
|
97
|
+
step = 1;
|
|
98
|
+
displayMax = Math.max(5, Math.ceil(maxValue * 1.5));
|
|
99
|
+
} else if (maxValue <= 10) {
|
|
100
|
+
// For medium-small values, use step of 2
|
|
101
|
+
step = 2;
|
|
102
|
+
displayMax = Math.ceil((maxValue * 1.2) / step) * step;
|
|
103
|
+
} else if (maxValue <= 20) {
|
|
104
|
+
// For medium values, use step of 5
|
|
105
|
+
step = 5;
|
|
106
|
+
displayMax = Math.ceil((maxValue * 1.2) / step) * step;
|
|
107
|
+
} else if (maxValue <= 50) {
|
|
108
|
+
// For larger values, use step of 10
|
|
109
|
+
step = 10;
|
|
110
|
+
displayMax = Math.ceil((maxValue * 1.2) / step) * step;
|
|
111
|
+
} else {
|
|
112
|
+
// For very large values, calculate step to get 4-6 ticks
|
|
113
|
+
const targetTicks = Math.min(maxTicks, Math.max(minTicks, Math.ceil(maxValue / 20)));
|
|
114
|
+
step = Math.ceil(maxValue / targetTicks / 10) * 10; // Round to nearest 10
|
|
115
|
+
displayMax = Math.ceil((maxValue * 1.2) / step) * step;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Generate ticks from 0 to displayMax
|
|
119
|
+
const ticks = [];
|
|
120
|
+
for (let i = 0; i <= displayMax; i += step) {
|
|
121
|
+
ticks.push(i);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Ensure max value is included if it's close
|
|
125
|
+
if (ticks[ticks.length - 1] < maxValue && maxValue - ticks[ticks.length - 1] <= step / 2) {
|
|
126
|
+
ticks.push(maxValue);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
min: 0,
|
|
131
|
+
max: displayMax,
|
|
132
|
+
tickMethod: () => ticks
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
|
|
62
136
|
/**
|
|
63
137
|
* Merge default categories with backend data
|
|
64
138
|
* Ensures all categories are displayed even if they have no data
|