datastake-daf 0.6.817 → 0.6.819
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 +1215 -1074
- package/dist/pages/index.js +264 -89
- package/dist/services/index.js +0 -5
- 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/core/components/ViewForm/components/Records/config.js +1 -0
- package/src/@daf/core/components/ViewForm/components/Records/index.jsx +0 -1
- package/src/@daf/pages/Dashboards/SupplyChain/components/KeyIndicators/config.js +2 -2
- package/src/@daf/pages/Dashboards/SupplyChain/components/KeyIndicators/index.js +3 -2
- package/src/@daf/pages/Dashboards/SupplyChain/index.jsx +4 -1
- package/src/@daf/pages/Dashboards/UserDashboard/components/KeyIndicators/config.js +3 -3
- package/src/@daf/pages/Dashboards/UserDashboard/components/KeyIndicators/index.jsx +4 -2
- package/src/@daf/pages/Dashboards/UserDashboard/components/MineSites/config.js +2 -2
- package/src/@daf/pages/Dashboards/UserDashboard/config.js +2 -2
- package/src/@daf/pages/Dashboards/UserDashboard/index.jsx +1 -0
- package/src/@daf/pages/Dashboards/helper.js +2 -2
- package/src/@daf/pages/Events/config.js +1 -1
- package/src/@daf/pages/Locations/MineSite/columns.js +1 -1
- 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
- package/src/@daf/pages/TablePage/create.jsx +3 -1
- package/src/@daf/pages/TablePage/hook.js +2 -0
- package/src/@daf/services/LinkedSubjects.js +1 -1
package/dist/services/index.js
CHANGED
|
@@ -1458,11 +1458,6 @@ class LinkedSubjectsService extends BaseService {
|
|
|
1458
1458
|
getForm({
|
|
1459
1459
|
namespace
|
|
1460
1460
|
}, language = "en", scope) {
|
|
1461
|
-
console.log({
|
|
1462
|
-
namespace,
|
|
1463
|
-
language,
|
|
1464
|
-
scope
|
|
1465
|
-
});
|
|
1466
1461
|
return this.apiGet({
|
|
1467
1462
|
url: `forms/${namespace === "documents" ? namespace : getNamespace(namespace)}`,
|
|
1468
1463
|
isApp: true,
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useRef, useEffect } from "react";
|
|
1
|
+
import React, { useRef, useEffect, useCallback } from "react";
|
|
2
2
|
import { Radar } from "@antv/g2plot";
|
|
3
3
|
import { theme } from "antd";
|
|
4
4
|
import { renderTooltip } from "../../../../utils/tooltip";
|
|
@@ -39,6 +39,46 @@ const RadarChart = ({
|
|
|
39
39
|
legendStyle
|
|
40
40
|
} = useLegendConfig({legendConfig, isPdf});
|
|
41
41
|
|
|
42
|
+
// Helper function to wrap long text labels to multiple lines
|
|
43
|
+
// Ensures text is never hidden - wraps to multiple lines if needed
|
|
44
|
+
const wrapLabel = useCallback((text, maxLength = 10) => {
|
|
45
|
+
if (!text) {
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const formattedText = formattedXAxis(text);
|
|
50
|
+
|
|
51
|
+
// If text is short enough, return as is
|
|
52
|
+
if (formattedText.length <= maxLength) {
|
|
53
|
+
return formattedText;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Split by spaces to find word boundaries
|
|
57
|
+
const words = formattedText.split(' ');
|
|
58
|
+
const lines = [];
|
|
59
|
+
let currentLine = '';
|
|
60
|
+
|
|
61
|
+
words.forEach((word, index) => {
|
|
62
|
+
// If adding this word would exceed maxLength, start a new line
|
|
63
|
+
if (currentLine && (currentLine + ' ' + word).length > maxLength) {
|
|
64
|
+
if (currentLine) {
|
|
65
|
+
lines.push(currentLine);
|
|
66
|
+
}
|
|
67
|
+
currentLine = word;
|
|
68
|
+
} else {
|
|
69
|
+
currentLine = currentLine ? currentLine + ' ' + word : word;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// If it's the last word, add it to lines
|
|
73
|
+
if (index === words.length - 1 && currentLine) {
|
|
74
|
+
lines.push(currentLine);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Ensure we always return something - never empty
|
|
79
|
+
return lines.length > 0 ? lines.join('\n') : formattedText;
|
|
80
|
+
}, [formattedXAxis]);
|
|
81
|
+
|
|
42
82
|
useEffect(() => {
|
|
43
83
|
if (!containerRef.current) {
|
|
44
84
|
return;
|
|
@@ -59,9 +99,19 @@ const RadarChart = ({
|
|
|
59
99
|
}
|
|
60
100
|
: { showCrosshairs: false, showMarkers: true, ...tooltipConfig },
|
|
61
101
|
color: color || token.colorPrimary7,
|
|
102
|
+
// Increased padding to ensure labels are never clipped
|
|
103
|
+
padding: [50, 50, 50, 50],
|
|
62
104
|
xAxis: {
|
|
63
105
|
label: {
|
|
64
|
-
formatter:
|
|
106
|
+
formatter: (text) => wrapLabel(text, 10),
|
|
107
|
+
offset: 15,
|
|
108
|
+
autoRotate: false,
|
|
109
|
+
autoHide: false, // Never hide labels
|
|
110
|
+
autoEllipsis: false, // Never truncate with ellipsis
|
|
111
|
+
style: {
|
|
112
|
+
fontSize: 12,
|
|
113
|
+
fill: '#666',
|
|
114
|
+
},
|
|
65
115
|
},
|
|
66
116
|
line: null,
|
|
67
117
|
tickLine: null,
|
|
@@ -129,6 +179,7 @@ const RadarChart = ({
|
|
|
129
179
|
formattedXAxis,
|
|
130
180
|
score,
|
|
131
181
|
token.colorPrimary7,
|
|
182
|
+
wrapLabel,
|
|
132
183
|
rest,
|
|
133
184
|
]);
|
|
134
185
|
|
|
@@ -2,7 +2,7 @@ import styled from "styled-components";
|
|
|
2
2
|
|
|
3
3
|
const Container = styled.div`
|
|
4
4
|
height: ${props => props.height || '300px'};
|
|
5
|
-
width: ${props => props.isPdf ? (props.width ? props.width : '1000px') : 'calc(100% - 48px)'};
|
|
5
|
+
width: ${props => props.isPdf ? (props.width ? props.width : '1000px') : 'calc(100% - 48px)'};
|
|
6
6
|
`;
|
|
7
7
|
|
|
8
8
|
export default Container;
|
|
@@ -16,16 +16,12 @@ export default function VegetationWidget({
|
|
|
16
16
|
}) {
|
|
17
17
|
let vegetationConfig = getVegetationConfig();
|
|
18
18
|
|
|
19
|
-
// Get all VEGETATION_KEYS values before filtering (needed for mapping check)
|
|
20
19
|
const allVegetationKeys = vegetationConfig.map(item => item.key);
|
|
21
20
|
|
|
22
|
-
// Filter to show only specific keys if filterKeys is provided
|
|
23
21
|
if (filterKeys && Array.isArray(filterKeys)) {
|
|
24
22
|
vegetationConfig = vegetationConfig.filter(item => filterKeys.includes(item.key));
|
|
25
23
|
}
|
|
26
24
|
|
|
27
|
-
// Map growthObservations to VEGETATION_KEYS
|
|
28
|
-
// Handle both formats: growthObservations keys (e.g., "yellowing_leaves") and VEGETATION_KEYS (e.g., "yellowing")
|
|
29
25
|
const mappedGrowthObservations = Array.isArray(growthObservations)
|
|
30
26
|
? growthObservations
|
|
31
27
|
.map(obs => {
|
|
@@ -2,7 +2,7 @@ import React from "react";
|
|
|
2
2
|
import CustomIcon from '../../../../../core/components/Icon/CustomIcon.jsx';
|
|
3
3
|
import KeyIndicatorNavigateLabel from '../../../../../core/components/UI/KeyIndicatorNavigateLabel/index.jsx';
|
|
4
4
|
|
|
5
|
-
export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {} }) => [
|
|
5
|
+
export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {}, APP }) => [
|
|
6
6
|
{
|
|
7
7
|
label: (
|
|
8
8
|
<KeyIndicatorNavigateLabel
|
|
@@ -10,7 +10,7 @@ export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {} }
|
|
|
10
10
|
getRedirectLink={getRedirectLink}
|
|
11
11
|
theme={theme}
|
|
12
12
|
label="Identified Mine Sites"
|
|
13
|
-
link=
|
|
13
|
+
link={APP === 'nashiriki' ? '/app/scl' : '/app/production-sites'}
|
|
14
14
|
/>
|
|
15
15
|
),
|
|
16
16
|
render: () => {
|
|
@@ -13,7 +13,7 @@ const defaultFetchConfig = {
|
|
|
13
13
|
},
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
function KeyIndicators({selectedSources = {}, theme = {}, getRedirectLink = () => {}, t = () => {}, goTo = () => {} }) {
|
|
16
|
+
function KeyIndicators({selectedSources = {}, theme = {}, getRedirectLink = () => {}, t = () => {}, goTo = () => {}, APP }) {
|
|
17
17
|
const fetchConfig = useMemo(() => ({
|
|
18
18
|
...defaultFetchConfig,
|
|
19
19
|
filters: { ...defaultFetchConfig.filters, sources: selectedSources?.partners || [] },
|
|
@@ -29,8 +29,9 @@ function KeyIndicators({selectedSources = {}, theme = {}, getRedirectLink = () =
|
|
|
29
29
|
goTo,
|
|
30
30
|
getRedirectLink,
|
|
31
31
|
theme,
|
|
32
|
+
APP
|
|
32
33
|
})
|
|
33
|
-
}, [t, data, goTo, getRedirectLink, theme])
|
|
34
|
+
}, [t, data, goTo, getRedirectLink, theme, APP])
|
|
34
35
|
|
|
35
36
|
return (
|
|
36
37
|
<KeyIndicatorsWidget
|
|
@@ -21,6 +21,8 @@ function SupplyChain({
|
|
|
21
21
|
informationSources,
|
|
22
22
|
hardcodedData,
|
|
23
23
|
breadcrumbs = [],
|
|
24
|
+
supportText,
|
|
25
|
+
APP,
|
|
24
26
|
}) {
|
|
25
27
|
|
|
26
28
|
const sourceOptions = useMemo(() => {
|
|
@@ -69,12 +71,13 @@ function SupplyChain({
|
|
|
69
71
|
/>
|
|
70
72
|
</div>
|
|
71
73
|
}
|
|
74
|
+
supportText={supportText}
|
|
72
75
|
breadcrumbs={breadcrumbs}
|
|
73
76
|
/>
|
|
74
77
|
}
|
|
75
78
|
>
|
|
76
79
|
<section>
|
|
77
|
-
<KeyIndicators selectedSources={selectedPartners} theme={theme} t={t} goTo={goTo} getRedirectLink={getRedirectLink} />
|
|
80
|
+
<KeyIndicators selectedSources={selectedPartners} theme={theme} t={t} goTo={goTo} getRedirectLink={getRedirectLink} APP={APP} />
|
|
78
81
|
</section>
|
|
79
82
|
<section>
|
|
80
83
|
<SupplyChainMap selectedSources={selectedPartners} t={t} goTo={goTo} options={options} getRedirectLink={getRedirectLink} />
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import CustomIcon from '../../../../../core/components/Icon/CustomIcon.jsx';
|
|
3
3
|
import KeyIndicatorNavigateLabel from '../../../../../core/components/UI/KeyIndicatorNavigateLabel/index.jsx';
|
|
4
4
|
|
|
5
|
-
export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {} }) => [
|
|
5
|
+
export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {}, APP }) => [
|
|
6
6
|
{
|
|
7
7
|
label: (
|
|
8
8
|
<KeyIndicatorNavigateLabel
|
|
@@ -35,8 +35,8 @@ export const getRowConfig = ({ t, data = {}, goTo, getRedirectLink, theme = {} }
|
|
|
35
35
|
t={t}
|
|
36
36
|
getRedirectLink={getRedirectLink}
|
|
37
37
|
theme={theme}
|
|
38
|
-
label=
|
|
39
|
-
link=
|
|
38
|
+
label={APP === 'nashiriki' ? 'Corrective Actions' : 'Activities'}
|
|
39
|
+
link={APP === 'nashiriki' ? '/app/corrective-actions' : '/app/activities'}
|
|
40
40
|
/>
|
|
41
41
|
),
|
|
42
42
|
render: () => {
|
|
@@ -17,6 +17,7 @@ function KeyIndicators({
|
|
|
17
17
|
getRedirectLink = () => {},
|
|
18
18
|
theme = {},
|
|
19
19
|
partners = [],
|
|
20
|
+
APP,
|
|
20
21
|
}) {
|
|
21
22
|
const fetchConfig = useMemo(
|
|
22
23
|
() => ({
|
|
@@ -33,9 +34,10 @@ function KeyIndicators({
|
|
|
33
34
|
data: { ...data, partners },
|
|
34
35
|
goTo,
|
|
35
36
|
getRedirectLink,
|
|
36
|
-
theme
|
|
37
|
+
theme,
|
|
38
|
+
APP
|
|
37
39
|
}),
|
|
38
|
-
[t, data, goTo, getRedirectLink, partners, theme],
|
|
40
|
+
[t, data, goTo, getRedirectLink, partners, theme, APP],
|
|
39
41
|
);
|
|
40
42
|
|
|
41
43
|
return (
|
|
@@ -9,7 +9,7 @@ export const getTabs = (t) => {
|
|
|
9
9
|
export const getFiltersConfig = ({t, filters, activeTab, options}) => {
|
|
10
10
|
const value = filters.type ? { value: filters.type } : {};
|
|
11
11
|
|
|
12
|
-
const eventCategoryOptions = (options?.eventCategoryOptions || [])?.map((item) => ({
|
|
12
|
+
const eventCategoryOptions = (options?.eventCategoryOptions || options?.categoryOptions || [])?.map((item) => ({
|
|
13
13
|
value: item.value,
|
|
14
14
|
label: typeof item.label === 'object' ? Object.values(item.label)[1] : item.label,
|
|
15
15
|
}))
|
|
@@ -22,7 +22,7 @@ export const getFiltersConfig = ({t, filters, activeTab, options}) => {
|
|
|
22
22
|
key: "category",
|
|
23
23
|
type: "select",
|
|
24
24
|
...value,
|
|
25
|
-
options: options?.categoriesOptions
|
|
25
|
+
options: options?.categoriesOptions || options?.category || [],
|
|
26
26
|
},
|
|
27
27
|
];
|
|
28
28
|
}
|
|
@@ -2,12 +2,12 @@ export const getActionWidgetsConfig = ({ goTo, getRedirectLink, APP, t }) => [
|
|
|
2
2
|
{
|
|
3
3
|
icon: "MineSite",
|
|
4
4
|
title: t("Create Mine Site"),
|
|
5
|
-
onClick: () => goTo(getRedirectLink(
|
|
5
|
+
onClick: () => goTo(getRedirectLink(`/app/${APP === 'nashiriki' ? 'scl' : 'production-sites'}?create=true`)),
|
|
6
6
|
},
|
|
7
7
|
{
|
|
8
8
|
icon: "FileEdit",
|
|
9
9
|
title: "Report Activity",
|
|
10
|
-
onClick: () => goTo(getRedirectLink(
|
|
10
|
+
onClick: () => goTo(getRedirectLink(`/app/${APP === 'nashiriki' ? 'corrective-actions' : 'activities'}?create=true`)),
|
|
11
11
|
},
|
|
12
12
|
{
|
|
13
13
|
icon: "ReportIncidents",
|
|
@@ -53,7 +53,7 @@ export const mapDataForChainOfCustody = (data = {}, options = {}, goTo = () => {
|
|
|
53
53
|
number: 0,
|
|
54
54
|
name: item.name,
|
|
55
55
|
sources: parentId ? [parentId] : [],
|
|
56
|
-
subTitle: findOptions(item?.category, options?.categoriesOptions),
|
|
56
|
+
subTitle: findOptions(item?.category, options?.categoriesOptions || options?.category || []),
|
|
57
57
|
leftIcon: type === "client" ? rightIcon : leftIcon,
|
|
58
58
|
leftBackground: type === "client" ? rightBackground : leftBackground,
|
|
59
59
|
topIcon: mapIcon(item.category),
|
|
@@ -70,7 +70,7 @@ export const mapDataForChainOfCustody = (data = {}, options = {}, goTo = () => {
|
|
|
70
70
|
id: data.id,
|
|
71
71
|
number: 0,
|
|
72
72
|
name: data.name,
|
|
73
|
-
subTitle: findOptions(data?.category, options?.categoriesOptions),
|
|
73
|
+
subTitle: findOptions(data?.category, options?.categoriesOptions || options?.category || []),
|
|
74
74
|
leftIcon: middleIcon,
|
|
75
75
|
leftBackground: theme.colorPrimary10,
|
|
76
76
|
topIcon: mapIcon(data.category),
|
|
@@ -117,7 +117,7 @@ export const getFilterOptions = (options, t) => {
|
|
|
117
117
|
eventCategoryOptions,
|
|
118
118
|
} = options || {};
|
|
119
119
|
|
|
120
|
-
const catOptions = eventCategoryOptions?.map((item) => ({
|
|
120
|
+
const catOptions = (eventCategoryOptions || categoryOptions || [])?.map((item) => ({
|
|
121
121
|
value: item.value,
|
|
122
122
|
label: typeof item.label === 'object' ? Object.values(item.label)[1] : item.label,
|
|
123
123
|
}))
|
|
@@ -188,7 +188,7 @@ export const getColumns = ({t, goTo, user, options, activeTab, getRedirectLink,
|
|
|
188
188
|
label: t("Summary"),
|
|
189
189
|
value: "Summary",
|
|
190
190
|
onClick: () => {
|
|
191
|
-
let link = `/app
|
|
191
|
+
let link = `/app/mine-summary/${all.datastakeId}`
|
|
192
192
|
if (activeTab === "shared") {
|
|
193
193
|
link += `?sourceId=${all?.authorId?.id}`;
|
|
194
194
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import { Widget, BarChart } from '../../../../../../../../src/index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { calculateNaturalAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
|
|
4
4
|
|
|
5
5
|
const ObservedFauna = ({
|
|
6
6
|
observedFaunaChart,
|
|
@@ -32,16 +32,11 @@ const ObservedFauna = ({
|
|
|
32
32
|
}, [observedFaunaChart, options]);
|
|
33
33
|
|
|
34
34
|
const xAxisConfig = useMemo(() => {
|
|
35
|
-
|
|
36
|
-
chartData
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
min: 0,
|
|
41
|
-
max: 10,
|
|
42
|
-
tickMethod: () => [0, 2, 4, 6, 8, 10]
|
|
43
|
-
}
|
|
44
|
-
);
|
|
35
|
+
const maxValue = chartData && chartData.length > 0
|
|
36
|
+
? Math.max(...chartData.map(item => Number(item?.value) || 0))
|
|
37
|
+
: 0;
|
|
38
|
+
|
|
39
|
+
return calculateNaturalAxisConfig(maxValue);
|
|
45
40
|
}, [chartData]);
|
|
46
41
|
|
|
47
42
|
return (
|
|
@@ -83,8 +83,8 @@ const BiodiversityHabitat = ({
|
|
|
83
83
|
t={t}
|
|
84
84
|
/>
|
|
85
85
|
|
|
86
|
-
<div style={{ display: "flex", gap: "24px" }}>
|
|
87
|
-
<section style={{ flex: 1 }}>
|
|
86
|
+
<div style={{ display: "flex", gap: "24px", flexWrap: "wrap" }}>
|
|
87
|
+
<section style={{ flex: 1, minWidth: "300px" }}>
|
|
88
88
|
<ObservedFauna
|
|
89
89
|
observedFaunaChart={observedFauna}
|
|
90
90
|
t={t}
|
|
@@ -92,11 +92,13 @@ const BiodiversityHabitat = ({
|
|
|
92
92
|
/>
|
|
93
93
|
</section>
|
|
94
94
|
|
|
95
|
+
<section style={{ flex: 1, minWidth: "300px" }}>
|
|
95
96
|
<InvasiveSpecies
|
|
96
97
|
invasiveSpeciesChart={invasiveSpecies}
|
|
97
98
|
t={t}
|
|
98
99
|
options={options}
|
|
99
100
|
/>
|
|
101
|
+
</section>
|
|
100
102
|
|
|
101
103
|
</div>
|
|
102
104
|
</Widget>
|
|
@@ -2,7 +2,14 @@ import React, { useMemo, useCallback } from 'react';
|
|
|
2
2
|
import { Widget, PieChart } from '../../../../../../../../src/index.js';
|
|
3
3
|
import { renderTooltipJsx } from '../../../../../../utils/tooltip.js';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// Color mapping for planted species
|
|
6
|
+
const PLANTED_SPECIES_COLORS = {
|
|
7
|
+
rhyzophora_mangle: '#016C6E',
|
|
8
|
+
rhyzophora: '#00AEB1',
|
|
9
|
+
rhyzophora_sp: '#A0EBEC',
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const DEFAULT_COLOR = '#9E9E9E';
|
|
6
13
|
|
|
7
14
|
const PlantedSpecies = ({
|
|
8
15
|
plantedSpeciesChart,
|
|
@@ -27,7 +34,7 @@ const PlantedSpecies = ({
|
|
|
27
34
|
return data.map((item, index) => ({
|
|
28
35
|
value: Number(item?.count) || 0,
|
|
29
36
|
percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
|
|
30
|
-
color:
|
|
37
|
+
color: PLANTED_SPECIES_COLORS[item?.name] || DEFAULT_COLOR,
|
|
31
38
|
label: optionsMap[item?.name] || item?.name || '',
|
|
32
39
|
key: item?.name || `item-${index}`,
|
|
33
40
|
}));
|
|
@@ -44,18 +51,26 @@ const PlantedSpecies = ({
|
|
|
44
51
|
return null;
|
|
45
52
|
}
|
|
46
53
|
|
|
54
|
+
// Calculate total from all items
|
|
55
|
+
const total = pieData.reduce((sum, dataItem) => sum + (dataItem.value || 0), 0);
|
|
56
|
+
|
|
57
|
+
// Show all items in the tooltip, sorted by value (descending)
|
|
58
|
+
const allItems = pieData
|
|
59
|
+
.filter(dataItem => dataItem.value > 0)
|
|
60
|
+
.sort((a, b) => b.value - a.value)
|
|
61
|
+
.map(dataItem => ({
|
|
62
|
+
color: dataItem.color,
|
|
63
|
+
label: dataItem.label || '',
|
|
64
|
+
value: dataItem.value || 0,
|
|
65
|
+
}));
|
|
66
|
+
|
|
47
67
|
return renderTooltipJsx({
|
|
48
68
|
title: t("Planted Species"),
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
color: item.color,
|
|
52
|
-
label: item.label || '',
|
|
53
|
-
value: item.value || 0,
|
|
54
|
-
},
|
|
55
|
-
],
|
|
69
|
+
subTitle: total.toLocaleString(),
|
|
70
|
+
items: allItems,
|
|
56
71
|
});
|
|
57
72
|
},
|
|
58
|
-
[t, isEmpty]
|
|
73
|
+
[t, isEmpty, pieData]
|
|
59
74
|
);
|
|
60
75
|
|
|
61
76
|
return (
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import { Widget, ColumnChart } from '../../../../../../../../src/index.js';
|
|
3
|
-
import {
|
|
3
|
+
import { calculateNaturalAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
|
|
4
4
|
|
|
5
5
|
// Default height ranges to always display
|
|
6
6
|
const DEFAULT_HEIGHT_RANGES = [
|
|
@@ -26,16 +26,13 @@ const SeedlingsHeight = ({
|
|
|
26
26
|
}, [seedlingsHeightChart]);
|
|
27
27
|
|
|
28
28
|
const yAxisConfig = useMemo(() => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
tickMethod: () => [0, 5, 10, 15, 20]
|
|
37
|
-
}
|
|
38
|
-
);
|
|
29
|
+
// Calculate max value from data
|
|
30
|
+
const maxValue = chartData && chartData.length > 0
|
|
31
|
+
? Math.max(...chartData.map(item => Number(item?.value) || 0))
|
|
32
|
+
: 0;
|
|
33
|
+
|
|
34
|
+
// Use the helper function to calculate natural number axis configuration
|
|
35
|
+
return calculateNaturalAxisConfig(maxValue);
|
|
39
36
|
}, [chartData]);
|
|
40
37
|
|
|
41
38
|
return (
|
|
@@ -58,10 +55,10 @@ const SeedlingsHeight = ({
|
|
|
58
55
|
const item = data[0]?.data || data[0];
|
|
59
56
|
return {
|
|
60
57
|
title: t("Seedlings Height"),
|
|
61
|
-
subTitle: title,
|
|
62
58
|
items: [
|
|
63
59
|
{
|
|
64
|
-
|
|
60
|
+
color: "#016C6E",
|
|
61
|
+
label: title,
|
|
65
62
|
value: item?.value || 0,
|
|
66
63
|
},
|
|
67
64
|
],
|
|
@@ -2,7 +2,22 @@ import React, { useMemo, useCallback } from 'react';
|
|
|
2
2
|
import { Widget, PieChart } from '../../../../../../../../src/index.js';
|
|
3
3
|
import { renderTooltipJsx } from '../../../../../../utils/tooltip.js';
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// Color mapping for vegetation health conditions
|
|
6
|
+
const VEGETATION_HEALTH_COLORS = {
|
|
7
|
+
healthy_leaves: '#6AD99E',
|
|
8
|
+
white_spots: '#E8F0F0',
|
|
9
|
+
yellowing_leaves: '#CDC14F',
|
|
10
|
+
black_spots: '#2E3131',
|
|
11
|
+
reddish_spots: '#CB2525',
|
|
12
|
+
leaf_mosaic: '#B59E76',
|
|
13
|
+
spider_webs: '#F8F6EF',
|
|
14
|
+
damage_from_insects: '#DE8954',
|
|
15
|
+
dry_dead_leaves: '#767870',
|
|
16
|
+
no_leaves: '#F97066',
|
|
17
|
+
other: '#BDBDBD',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const DEFAULT_COLOR = '#9E9E9E';
|
|
6
21
|
|
|
7
22
|
const VegetationHealth = ({
|
|
8
23
|
vegetationHealthChart,
|
|
@@ -26,15 +41,15 @@ const VegetationHealth = ({
|
|
|
26
41
|
return data.map((item, index) => ({
|
|
27
42
|
value: Number(item?.count) || 0,
|
|
28
43
|
percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
|
|
29
|
-
color:
|
|
44
|
+
color: VEGETATION_HEALTH_COLORS[item?.name] || DEFAULT_COLOR,
|
|
30
45
|
label: optionsMap[item?.name] || item?.name || '',
|
|
31
46
|
key: item?.name || `item-${index}`,
|
|
32
47
|
}));
|
|
33
48
|
}, [vegetationHealthChart, optionsMap]);
|
|
34
49
|
|
|
35
50
|
const isEmpty = useMemo(() => {
|
|
36
|
-
return !vegetationHealthChart || vegetationHealthChart.length === 0 ||
|
|
37
|
-
|
|
51
|
+
return !vegetationHealthChart || vegetationHealthChart.length === 0 ||
|
|
52
|
+
vegetationHealthChart.every(item => !item?.count || Number(item.count) === 0);
|
|
38
53
|
}, [vegetationHealthChart]);
|
|
39
54
|
|
|
40
55
|
const getTooltipChildren = useCallback(
|
|
@@ -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
|