datastake-daf 0.6.814 → 0.6.816

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.
@@ -12752,7 +12752,8 @@ const mapDataForChainOfCustody = (data = {}, options = {}, goTo = () => {}) => {
12752
12752
 
12753
12753
  const Container$1 = styled__default["default"].div`
12754
12754
  height: ${props => props.height || '300px'};
12755
- width: ${props => props.isPdf ? props.width ? props.width : '1000px' : 'calc(100% - 48px)'};
12755
+ width: ${props => props.isPdf ? props.width ? props.width : '1000px' : 'calc(100% - 48px)'};
12756
+ overflow: ${props => props.style?.overflow || 'visible'};
12756
12757
  `;
12757
12758
 
12758
12759
  const useLegendConfig = ({
@@ -48955,17 +48956,10 @@ function VegetationWidget({
48955
48956
  ...props
48956
48957
  }) {
48957
48958
  let vegetationConfig = getVegetationConfig();
48958
-
48959
- // Get all VEGETATION_KEYS values before filtering (needed for mapping check)
48960
48959
  const allVegetationKeys = vegetationConfig.map(item => item.key);
48961
-
48962
- // Filter to show only specific keys if filterKeys is provided
48963
48960
  if (filterKeys && Array.isArray(filterKeys)) {
48964
48961
  vegetationConfig = vegetationConfig.filter(item => filterKeys.includes(item.key));
48965
48962
  }
48966
-
48967
- // Map growthObservations to VEGETATION_KEYS
48968
- // Handle both formats: growthObservations keys (e.g., "yellowing_leaves") and VEGETATION_KEYS (e.g., "yellowing")
48969
48963
  const mappedGrowthObservations = Array.isArray(growthObservations) ? growthObservations.map(obs => {
48970
48964
  // First try to map from growthObservations format
48971
48965
  const mapped = GROWTH_OBSERVATIONS_TO_VEGETATION_KEYS[obs];
@@ -51463,9 +51457,17 @@ const RadarChart = ({
51463
51457
  ...tooltipConfig
51464
51458
  },
51465
51459
  color: color || token.colorPrimary7,
51460
+ paddingX: 60,
51461
+ paddingY: 60,
51466
51462
  xAxis: {
51467
51463
  label: {
51468
- formatter: formattedXAxis
51464
+ formatter: formattedXAxis,
51465
+ offset: 15,
51466
+ style: {
51467
+ fontSize: 12,
51468
+ fill: '#666',
51469
+ textAlign: 'center'
51470
+ }
51469
51471
  },
51470
51472
  line: null,
51471
51473
  tickLine: null,
@@ -51534,12 +51536,23 @@ const RadarChart = ({
51534
51536
  }, []);
51535
51537
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
51536
51538
  className: "flex flex-1 flex-column justify-content-center",
51539
+ style: {
51540
+ overflow: 'visible'
51541
+ },
51537
51542
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
51538
51543
  className: "flex justify-content-center",
51544
+ style: {
51545
+ paddingX: '30px',
51546
+ overflow: 'visible',
51547
+ width: '100%'
51548
+ },
51539
51549
  children: /*#__PURE__*/jsxRuntime.jsx(Container$1, {
51540
51550
  ref: containerRef,
51541
51551
  height: height,
51542
- isPdf: isPdf
51552
+ isPdf: isPdf,
51553
+ style: {
51554
+ paddingX: '30px'
51555
+ }
51543
51556
  })
51544
51557
  }), legendEnabled && legendPosition === 'bottom' && /*#__PURE__*/jsxRuntime.jsx(CustomLegend, {
51545
51558
  items: legendItems,
@@ -56849,7 +56862,20 @@ const MonitoringScopeAndFindings = ({
56849
56862
  });
56850
56863
  };
56851
56864
 
56852
- const COLORS$3 = ['#016C6E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
56865
+ const VEGETATION_HEALTH_COLORS = {
56866
+ healthy_leaves: '#6AD99E',
56867
+ white_spots: '#E8F0F0',
56868
+ yellowing_leaves: '#CDC14F',
56869
+ black_spots: '#2E3131',
56870
+ reddish_spots: '#CB2525',
56871
+ leaf_mosaic: '#B59E76',
56872
+ spider_webs: '#F8F6EF',
56873
+ damage_from_insects: '#DE8954',
56874
+ dry_dead_leaves: '#767870',
56875
+ no_leaves: '#F97066',
56876
+ other: '#BDBDBD'
56877
+ };
56878
+ const DEFAULT_COLOR$3 = '#9E9E9E';
56853
56879
  const VegetationHealth = ({
56854
56880
  vegetationHealthChart,
56855
56881
  t = s => s,
@@ -56870,7 +56896,7 @@ const VegetationHealth = ({
56870
56896
  return data.map((item, index) => ({
56871
56897
  value: Number(item?.count) || 0,
56872
56898
  percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
56873
- color: COLORS$3[index % COLORS$3.length],
56899
+ color: VEGETATION_HEALTH_COLORS[item?.name] || DEFAULT_COLOR$3,
56874
56900
  label: optionsMap[item?.name] || item?.name || '',
56875
56901
  key: item?.name || `item-${index}`
56876
56902
  }));
@@ -56968,6 +56994,80 @@ const calculateNiceAxisConfig = (data, valueField = 'value', multiplier = 1.2, d
56968
56994
  };
56969
56995
  };
56970
56996
 
56997
+ /**
56998
+ * Calculate y-axis configuration with natural numbers (integers) only
56999
+ * Always starts from 0 and extends slightly above max for better visualization
57000
+ * @param {number} maxValue - Maximum value from the data
57001
+ * @param {Object} options - Optional configuration
57002
+ * @param {number} options.minTicks - Minimum number of ticks to show (default: 4)
57003
+ * @param {number} options.maxTicks - Maximum number of ticks to show (default: 6)
57004
+ * @returns {Object} Axis configuration with min, max, and tickMethod
57005
+ */
57006
+ const calculateNaturalAxisConfig = (maxValue, options = {}) => {
57007
+ const {
57008
+ minTicks = 4,
57009
+ maxTicks = 6
57010
+ } = options;
57011
+ if (maxValue <= 0) {
57012
+ return {
57013
+ min: 0,
57014
+ max: 4,
57015
+ tickMethod: () => [0, 1, 2, 3, 4]
57016
+ };
57017
+ }
57018
+
57019
+ // For very small values (max <= 1), always show 0, 1, 2, 3, 4
57020
+ if (maxValue <= 1) {
57021
+ return {
57022
+ min: 0,
57023
+ max: 4,
57024
+ tickMethod: () => [0, 1, 2, 3, 4]
57025
+ };
57026
+ }
57027
+
57028
+ // Calculate appropriate step size based on max value
57029
+ let step = 1;
57030
+ let displayMax = maxValue;
57031
+ if (maxValue <= 5) {
57032
+ // For small values, use step of 1 and extend a bit above
57033
+ step = 1;
57034
+ displayMax = Math.max(5, Math.ceil(maxValue * 1.5));
57035
+ } else if (maxValue <= 10) {
57036
+ // For medium-small values, use step of 2
57037
+ step = 2;
57038
+ displayMax = Math.ceil(maxValue * 1.2 / step) * step;
57039
+ } else if (maxValue <= 20) {
57040
+ // For medium values, use step of 5
57041
+ step = 5;
57042
+ displayMax = Math.ceil(maxValue * 1.2 / step) * step;
57043
+ } else if (maxValue <= 50) {
57044
+ // For larger values, use step of 10
57045
+ step = 10;
57046
+ displayMax = Math.ceil(maxValue * 1.2 / step) * step;
57047
+ } else {
57048
+ // For very large values, calculate step to get 4-6 ticks
57049
+ const targetTicks = Math.min(maxTicks, Math.max(minTicks, Math.ceil(maxValue / 20)));
57050
+ step = Math.ceil(maxValue / targetTicks / 10) * 10; // Round to nearest 10
57051
+ displayMax = Math.ceil(maxValue * 1.2 / step) * step;
57052
+ }
57053
+
57054
+ // Generate ticks from 0 to displayMax
57055
+ const ticks = [];
57056
+ for (let i = 0; i <= displayMax; i += step) {
57057
+ ticks.push(i);
57058
+ }
57059
+
57060
+ // Ensure max value is included if it's close
57061
+ if (ticks[ticks.length - 1] < maxValue && maxValue - ticks[ticks.length - 1] <= step / 2) {
57062
+ ticks.push(maxValue);
57063
+ }
57064
+ return {
57065
+ min: 0,
57066
+ max: displayMax,
57067
+ tickMethod: () => ticks
57068
+ };
57069
+ };
57070
+
56971
57071
  /**
56972
57072
  * Merge default categories with backend data
56973
57073
  * Ensures all categories are displayed even if they have no data
@@ -57023,13 +57123,11 @@ const SeedlingsHeight$1 = ({
57023
57123
  return mergeDefaultCategories(seedlingsHeightChart, DEFAULT_HEIGHT_RANGES, 'range', 'count', 'label', 'value');
57024
57124
  }, [seedlingsHeightChart]);
57025
57125
  const yAxisConfig = React.useMemo(() => {
57026
- return calculateNiceAxisConfig(chartData, 'value', 2,
57027
- // multiplier: double the max value
57028
- {
57029
- min: 0,
57030
- max: 20,
57031
- tickMethod: () => [0, 5, 10, 15, 20]
57032
- });
57126
+ // Calculate max value from data
57127
+ const maxValue = chartData && chartData.length > 0 ? Math.max(...chartData.map(item => Number(item?.value) || 0)) : 0;
57128
+
57129
+ // Use the helper function to calculate natural number axis configuration
57130
+ return calculateNaturalAxisConfig(maxValue);
57033
57131
  }, [chartData]);
57034
57132
  return /*#__PURE__*/jsxRuntime.jsx(Widget, {
57035
57133
  title: t("Seedlings Height"),
@@ -57051,9 +57149,9 @@ const SeedlingsHeight$1 = ({
57051
57149
  const item = data[0]?.data || data[0];
57052
57150
  return {
57053
57151
  title: t("Seedlings Height"),
57054
- subTitle: title,
57055
57152
  items: [{
57056
- label: t("Count"),
57153
+ color: "#016C6E",
57154
+ label: title,
57057
57155
  value: item?.value || 0
57058
57156
  }]
57059
57157
  };
@@ -57064,7 +57162,12 @@ const SeedlingsHeight$1 = ({
57064
57162
  });
57065
57163
  };
57066
57164
 
57067
- const COLORS$2 = ['#6AD99E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
57165
+ const PLANTED_SPECIES_COLORS = {
57166
+ rhyzophora_mangle: '#016C6E',
57167
+ rhyzophora: '#00AEB1',
57168
+ rhyzophora_sp: '#A0EBEC'
57169
+ };
57170
+ const DEFAULT_COLOR$2 = '#9E9E9E';
57068
57171
  const PlantedSpecies$1 = ({
57069
57172
  plantedSpeciesChart,
57070
57173
  t = s => s,
@@ -57085,7 +57188,7 @@ const PlantedSpecies$1 = ({
57085
57188
  return data.map((item, index) => ({
57086
57189
  value: Number(item?.count) || 0,
57087
57190
  percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
57088
- color: COLORS$2[index % COLORS$2.length],
57191
+ color: PLANTED_SPECIES_COLORS[item?.name] || DEFAULT_COLOR$2,
57089
57192
  label: optionsMap[item?.name] || item?.name || '',
57090
57193
  key: item?.name || `item-${index}`
57091
57194
  }));
@@ -57097,15 +57200,22 @@ const PlantedSpecies$1 = ({
57097
57200
  if (isEmpty) {
57098
57201
  return null;
57099
57202
  }
57203
+
57204
+ // Calculate total from all items
57205
+ const total = pieData.reduce((sum, dataItem) => sum + (dataItem.value || 0), 0);
57206
+
57207
+ // Show all items in the tooltip, sorted by value (descending)
57208
+ const allItems = pieData.filter(dataItem => dataItem.value > 0).sort((a, b) => b.value - a.value).map(dataItem => ({
57209
+ color: dataItem.color,
57210
+ label: dataItem.label || '',
57211
+ value: dataItem.value || 0
57212
+ }));
57100
57213
  return renderTooltipJsx({
57101
57214
  title: t("Planted Species"),
57102
- items: [{
57103
- color: item.color,
57104
- label: item.label || '',
57105
- value: item.value || 0
57106
- }]
57215
+ subTitle: total.toLocaleString(),
57216
+ items: allItems
57107
57217
  });
57108
- }, [t, isEmpty]);
57218
+ }, [t, isEmpty, pieData]);
57109
57219
  return /*#__PURE__*/jsxRuntime.jsx(Widget, {
57110
57220
  title: t("Planted Species"),
57111
57221
  className: "with-border-header h-w-btn-header",
@@ -57370,13 +57480,8 @@ const ObservedFauna = ({
57370
57480
  }));
57371
57481
  }, [observedFaunaChart, options]);
57372
57482
  const xAxisConfig = React.useMemo(() => {
57373
- return calculateNiceAxisConfig(chartData, 'value', 1.2,
57374
- // multiplier: 20% padding
57375
- {
57376
- min: 0,
57377
- max: 10,
57378
- tickMethod: () => [0, 2, 4, 6, 8, 10]
57379
- });
57483
+ const maxValue = chartData && chartData.length > 0 ? Math.max(...chartData.map(item => Number(item?.value) || 0)) : 0;
57484
+ return calculateNaturalAxisConfig(maxValue);
57380
57485
  }, [chartData]);
57381
57486
  return /*#__PURE__*/jsxRuntime.jsx(Widget, {
57382
57487
  title: t("Observed Fauna"),
@@ -57646,7 +57751,13 @@ const Stats = ({
57646
57751
  });
57647
57752
  };
57648
57753
 
57649
- const COLORS$1 = ['#016C6E', '#4FB3A1', '#A8E6CF', '#FFD93D', '#F0A888', '#DF571E', '#C04B19'];
57754
+ const SOIL_TYPE_COLORS$1 = {
57755
+ sandy: '#00AEB1',
57756
+ mixed: '#016C6E',
57757
+ clay: '#A0EBEC',
57758
+ muddy: '#4FB3A1'
57759
+ };
57760
+ const DEFAULT_COLOR$1 = '#9E9E9E';
57650
57761
  const SoilType = ({
57651
57762
  soilTypeChart,
57652
57763
  t = s => s,
@@ -57667,7 +57778,7 @@ const SoilType = ({
57667
57778
  return data.map((item, index) => ({
57668
57779
  value: Number(item?.count) || 0,
57669
57780
  percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
57670
- color: COLORS$1[index % COLORS$1.length],
57781
+ color: SOIL_TYPE_COLORS$1[item?.soilType] || DEFAULT_COLOR$1,
57671
57782
  label: optionsMap[item?.soilType] || item?.soilType || '',
57672
57783
  key: item?.soilType || `item-${index}`
57673
57784
  }));
@@ -57679,15 +57790,18 @@ const SoilType = ({
57679
57790
  if (isEmpty) {
57680
57791
  return null;
57681
57792
  }
57793
+
57794
+ // Show all items in the tooltip, sorted by percentage (descending)
57795
+ const allItems = pieData.filter(dataItem => dataItem.value > 0).sort((a, b) => b.percent - a.percent).map(dataItem => ({
57796
+ color: dataItem.color,
57797
+ label: dataItem.label || '',
57798
+ value: renderPercentage(Math.round(dataItem.percent * 100))
57799
+ }));
57682
57800
  return renderTooltipJsx({
57683
57801
  title: t("Soil Type"),
57684
- items: [{
57685
- color: item.color,
57686
- label: optionsMap[item.label] || item.label || '',
57687
- value: `${renderPercentage(item.percent.toFixed(2) * 100)}`
57688
- }]
57802
+ items: allItems
57689
57803
  });
57690
- }, [t, isEmpty, optionsMap]);
57804
+ }, [t, isEmpty, pieData]);
57691
57805
  return /*#__PURE__*/jsxRuntime.jsx(Widget, {
57692
57806
  title: t("Soil Type"),
57693
57807
  className: "with-border-header h-w-btn-header",
@@ -57788,7 +57902,16 @@ const SalinityLevels = ({
57788
57902
  });
57789
57903
  };
57790
57904
 
57791
- const COLORS = ['#6AD99E', '#FFD93D', '#F0A888', '#DF571E', '#B0B0B0', '#016C6E', '#4FB3A1'];
57905
+ const WATER_QUALITY_COLORS = {
57906
+ fairly_clear: '#32D583',
57907
+ turbid: '#FFA940',
57908
+ polluted: '#F97066',
57909
+ oil_traces: '#2B3644',
57910
+ no_water: '#DAD6CE',
57911
+ clear: '#6AD99E',
57912
+ other: '#9E9E9E'
57913
+ };
57914
+ const DEFAULT_COLOR = '#9E9E9E';
57792
57915
  const WaterQuality = ({
57793
57916
  waterQualityChart,
57794
57917
  t = s => s,
@@ -57809,7 +57932,7 @@ const WaterQuality = ({
57809
57932
  return data.map((item, index) => ({
57810
57933
  value: Number(item?.count) || 0,
57811
57934
  percent: total > 0 ? (Number(item?.count) || 0) / total : 0,
57812
- color: COLORS[index % COLORS.length],
57935
+ color: WATER_QUALITY_COLORS[item?.waterQuality] || DEFAULT_COLOR,
57813
57936
  label: optionsMap[item?.waterQuality] || item?.waterQuality || '',
57814
57937
  key: item?.waterQuality || `item-${index}`
57815
57938
  }));
@@ -57821,15 +57944,18 @@ const WaterQuality = ({
57821
57944
  if (isEmpty) {
57822
57945
  return null;
57823
57946
  }
57947
+
57948
+ // Show all items in the tooltip, sorted by percentage (descending)
57949
+ const allItems = pieData.filter(dataItem => dataItem.value > 0).sort((a, b) => b.percent - a.percent).map(dataItem => ({
57950
+ color: dataItem.color,
57951
+ label: dataItem.label || '',
57952
+ value: renderPercentage(Math.round(dataItem.percent * 100))
57953
+ }));
57824
57954
  return renderTooltipJsx({
57825
57955
  title: t("Water Quality"),
57826
- items: [{
57827
- color: item.color,
57828
- label: item.label || '',
57829
- value: `${Math.round(item.percent * 100)}%`
57830
- }]
57956
+ items: allItems
57831
57957
  });
57832
- }, [t, isEmpty]);
57958
+ }, [t, isEmpty, pieData]);
57833
57959
  return /*#__PURE__*/jsxRuntime.jsx(Widget, {
57834
57960
  title: t("Water Quality"),
57835
57961
  className: "with-border-header h-w-btn-header",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.814",
3
+ "version": "0.6.816",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -59,9 +59,18 @@ const RadarChart = ({
59
59
  }
60
60
  : { showCrosshairs: false, showMarkers: true, ...tooltipConfig },
61
61
  color: color || token.colorPrimary7,
62
+
63
+ paddingX: 60,
64
+ paddingY: 60,
62
65
  xAxis: {
63
66
  label: {
64
67
  formatter: formattedXAxis,
68
+ offset: 15,
69
+ style: {
70
+ fontSize: 12,
71
+ fill: '#666',
72
+ textAlign: 'center',
73
+ },
65
74
  },
66
75
  line: null,
67
76
  tickLine: null,
@@ -142,9 +151,9 @@ const RadarChart = ({
142
151
  }, []);
143
152
 
144
153
  return (
145
- <div className="flex flex-1 flex-column justify-content-center">
146
- <div className="flex justify-content-center">
147
- <Container ref={containerRef} height={height} isPdf={isPdf}></Container>
154
+ <div className="flex flex-1 flex-column justify-content-center" style={{ overflow: 'visible' }}>
155
+ <div className="flex justify-content-center" style={{ paddingX: '30px', overflow: 'visible', width: '100%' }}>
156
+ <Container ref={containerRef} height={height} isPdf={isPdf} style={{ paddingX: '30px' }}></Container>
148
157
  </div>
149
158
  {legendEnabled && legendPosition === 'bottom' && (
150
159
  <CustomLegend
@@ -2,7 +2,8 @@ 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
+ overflow: ${props => props.style?.overflow || 'visible'};
6
7
  `;
7
8
 
8
9
  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 => {
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import { Widget, BarChart } from '../../../../../../../../src/index.js';
3
- import { calculateNiceAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
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
- return calculateNiceAxisConfig(
36
- chartData,
37
- 'value',
38
- 1.2, // multiplier: 20% padding
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 (
@@ -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
- const COLORS = ['#6AD99E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
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: COLORS[index % COLORS.length],
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
- items: [
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 { calculateNiceAxisConfig, mergeDefaultCategories } from '../chartHelpers.js';
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
- return calculateNiceAxisConfig(
30
- chartData,
31
- 'value',
32
- 2, // multiplier: double the max value
33
- {
34
- min: 0,
35
- max: 20,
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
- label: t("Count"),
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
- const COLORS = ['#016C6E', '#F5C2AC', '#F0A888', '#DF571E', '#C04B19', '#9B3D14', '#7A2F0F'];
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: COLORS[index % COLORS.length],
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
- vegetationHealthChart.every(item => !item?.count || Number(item.count) === 0);
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(