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.
@@ -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
- const COLORS = ['#016C6E', '#4FB3A1', '#A8E6CF', '#FFD93D', '#F0A888', '#DF571E', '#C04B19'];
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: COLORS[index % COLORS.length],
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, optionsMap]);
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
- const COLORS = ['#6AD99E', '#FFD93D', '#F0A888', '#DF571E', '#B0B0B0', '#016C6E', '#4FB3A1'];
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: COLORS[index % COLORS.length],
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