Skip to content

Commit 79e908f

Browse files
committed
feat: enhance response parsers to support dynamic SQL query results for various chart types
1 parent 0c7acfd commit 79e908f

File tree

10 files changed

+123
-74
lines changed

10 files changed

+123
-74
lines changed

backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/responses/ResponseParserFactory.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,24 @@ public ResponseParser instance(ChartType chartType) throws UtmChartBuilderExcept
2828
final String ctx = CLASS_NAME + ".instance";
2929

3030
if (chartType.equals(ChartType.METRIC_CHART))
31-
return new ResponseParserForMetricChart(); // Listo ELENA
31+
return new ResponseParserForMetricChart();
3232
else if (chartType.equals(ChartType.PIE_CHART))
33-
return new ResponseParserForPieChart(); //Listo ELENA
33+
return new ResponseParserForPieChart();
3434
else if (chartType.equals(ChartType.GAUGE_CHART) || chartType.equals(ChartType.GOAL_CHART))
35-
return new ResponseParserForGaugeGoalChart(); //Listo ELENA
35+
return new ResponseParserForGaugeGoalChart();
3636
else if (chartType.equals(ChartType.TAG_CLOUD_CHART))
37-
return new ResponseParserForTagCloudChart(); //Listo ELENA
37+
return new ResponseParserForTagCloudChart();
3838
else if (chartType.equals(ChartType.TABLE_CHART))
39-
return new ResponseParserForTableChart(); // Listo ELENA
39+
return new ResponseParserForTableChart();
4040
else if (chartType.equals(ChartType.LINE_CHART) || chartType.equals(ChartType.AREA_CHART) || chartType.equals(
4141
ChartType.VERTICAL_BAR_CHART) || chartType.equals(ChartType.HORIZONTAL_BAR_CHART))
42-
return new ResponseParserForBarChart(); // Listo ELENA
42+
return new ResponseParserForBarChart();
4343
else if (chartType.equals(ChartType.HEATMAP_CHART))
44-
return new ResponseParserForHeatMapChart(); // Listo ELENA
44+
return new ResponseParserForHeatMapChart();
4545
else if (chartType.equals(ChartType.COORDINATE_MAP_CHART))
46-
return responseParserForCoordinateMapChart; // Listo ELENA
46+
return responseParserForCoordinateMapChart;
4747
else if (chartType.equals(ChartType.LIST_CHART))
48-
return new ResponseParserForListChart(); // Error en el original ELENA
48+
return new ResponseParserForListChart();
4949

5050
throw new UtmChartBuilderException(ctx + ": No implementation founded for chart type: " + chartType.name());
5151
}

backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/responses/impl/bar_chart/ResponseParserForBarChart.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,9 @@ public List<BarChartResult> parse(UtmVisualization visualization, SearchSqlRespo
209209
try {
210210
BarChartResult retValue = new BarChartResult();
211211

212-
// Serie única
213212
BarChartResult.Serie serie = new BarChartResult.Serie();
214-
serie.setMetricId("1"); // id de la métrica COUNT
215-
serie.setName(""); // nombre vacío como en tu ejemplo
213+
serie.setMetricId("1");
216214

217-
// Recorremos filas y llenamos categorías + datos
218215
for (Object rowObj : result.getData()) {
219216
if (!(rowObj instanceof Map)) {
220217
continue;
@@ -228,6 +225,9 @@ public List<BarChartResult> parse(UtmVisualization visualization, SearchSqlRespo
228225
Object val = entry.getValue();
229226
if (val instanceof Number) {
230227
value = ((Number) val).doubleValue();
228+
if (serie.getName() == null) {
229+
serie.setName(entry.getKey() != null ? entry.getKey() : "metric");
230+
}
231231
} else {
232232
category = val != null ? val.toString() : "UNKNOWN";
233233
}

backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/responses/impl/coordinate_map/ResponseParserForCoordinateMapChart.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ public List<CoordinateMapChartResult> parse(UtmVisualization visualization, Sear
128128
String ip = null;
129129
Double metricValue = null;
130130

131-
// Buscar IP y métrica en la fila
132131
for (Map.Entry<String, Object> entry : row.entrySet()) {
133132
Object val = entry.getValue();
134133
if (val == null) continue;
@@ -143,7 +142,6 @@ public List<CoordinateMapChartResult> parse(UtmVisualization visualization, Sear
143142

144143
if (ip == null || metricValue == null) continue;
145144

146-
// Resolver lat/long con tu servicio de GeoIP
147145
GeoIp ipInfo;
148146
try {
149147
ipInfo = ipInfoService.getIpInfo(ip);
@@ -153,7 +151,6 @@ public List<CoordinateMapChartResult> parse(UtmVisualization visualization, Sear
153151
continue;
154152
}
155153

156-
// Construir resultado
157154
CoordinateMapChartResult chartResult = new CoordinateMapChartResult();
158155
chartResult.setName(ip);
159156
chartResult.setValue(new Double[] {

backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/responses/impl/gauge_goal_chart/ResponseParserForGaugeGoalChart.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -121,32 +121,35 @@ public List<GaugeGoalChartResult> parse(UtmVisualization visualization, SearchSq
121121

122122
List<GaugeGoalChartResult> results = new ArrayList<>();
123123

124-
// IDs: puedes obtenerlos de la visualización o usar valores por defecto
125-
String metricId = "1";
126-
String bucketId = "1000";
127-
128124
for (Object rowObj : result.getData()) {
129125
if (!(rowObj instanceof Map)) continue;
130126
Map<String, Object> row = (Map<String, Object>) rowObj;
131127

132-
String bucketKey = "UNKNOWN";
128+
String bucketKey = null;
129+
String bucketId = null;
130+
133131
Double metricValue = null;
132+
String metricId = null;
134133

135-
// recorrer dinámicamente las columnas
136134
for (Map.Entry<String, Object> entry : row.entrySet()) {
135+
String key = entry.getKey();
137136
Object val = entry.getValue();
137+
138138
if (val == null) continue;
139139

140-
if (bucketKey.equals("UNKNOWN") && val instanceof String) {
141-
bucketKey = val.toString();
142-
} else if (metricValue == null && val instanceof Number) {
140+
if (val instanceof Number) {
143141
metricValue = ((Number) val).doubleValue();
142+
metricId = key;
143+
} else {
144+
bucketKey = val.toString();
145+
bucketId = key;
144146
}
145147
}
146148

147-
if (metricValue == null) {
148-
metricValue = 0.0;
149-
}
149+
if (metricValue == null) metricValue = 0.0;
150+
if (metricId == null) metricId = "metric";
151+
if (bucketKey == null) bucketKey = "UNKNOWN";
152+
if (bucketId == null) bucketId = "bucket";
150153

151154
results.add(new GaugeGoalChartResult(metricId, metricValue, bucketKey, bucketId));
152155
}

backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/responses/impl/heat_map_chart/ResponseParserForHeatMapChart.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -161,42 +161,46 @@ public List<HeatMapChartResult> parse(UtmVisualization visualization, SearchSqlR
161161

162162
HeatMapChartResult retValue = new HeatMapChartResult();
163163

164-
// Definir ejes
165-
retValue.addYAxis("Count"); // métrica COUNT
166-
// XAxis se llenará dinámicamente con las claves encontradas
164+
String metricAlias = "Count";
165+
if (!result.getData().isEmpty() && result.getData().get(0) instanceof Map) {
166+
Map<String, Object> firstRow = (Map<String, Object>) result.getData().get(0);
167+
for (Map.Entry<String, Object> entry : firstRow.entrySet()) {
168+
if (entry.getValue() instanceof Number) {
169+
metricAlias = entry.getKey();
170+
break;
171+
}
172+
}
173+
}
174+
175+
retValue.addYAxis(metricAlias);
167176

168177
int index = 0;
169178
for (Object rowObj : result.getData()) {
170179
if (!(rowObj instanceof Map)) continue;
171180
Map<String, Object> row = (Map<String, Object>) rowObj;
172181

173-
// Buscar bucketKey (ej. IP)
174182
String bucketKey = null;
175183
Double metricValue = null;
176184

177185
for (Map.Entry<String, Object> entry : row.entrySet()) {
178186
Object val = entry.getValue();
179187
if (val == null) continue;
180188

181-
// Si es IP o string, lo usamos como bucketKey
182189
if (bucketKey == null && val instanceof String) {
183190
bucketKey = entry.getKey() + ":=" + val.toString();
184191
}
185-
// Si es número, lo usamos como métrica
186192
if (metricValue == null && val instanceof Number) {
187193
metricValue = ((Number) val).doubleValue();
188194
}
189195
}
190196

191197
if (bucketKey == null || metricValue == null) continue;
192198

193-
// Añadir XAxis
194199
retValue.addXAxis(bucketKey);
195200

196-
// Construir punto [x, y, value]
197201
Double[] data = new Double[3];
198-
data[0] = (double) index; // posición en XAxis
199-
data[1] = 0.0; // único eje Y (Count)
202+
data[0] = (double) index;
203+
data[1] = 0.0;
200204
data[2] = metricValue;
201205

202206
retValue.addData(data);
@@ -208,5 +212,4 @@ public List<HeatMapChartResult> parse(UtmVisualization visualization, SearchSqlR
208212
throw new RuntimeException(ctx + ": " + e.getMessage(), e);
209213
}
210214
}
211-
212215
}

backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/responses/impl/list_chart/ResponseParserForListChart.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.park.utmstack.util.MapUtil;
99
import com.park.utmstack.util.chart_builder.elasticsearch_dsl.responses.ResponseParser;
1010
import com.park.utmstack.util.chart_builder.elasticsearch_dsl.responses.impl.table_chart.TableChartResult;
11+
import com.utmstack.opensearch_connector.types.SearchSqlResponse;
1112
import org.opensearch.client.opensearch.core.SearchResponse;
1213
import org.springframework.util.CollectionUtils;
1314
import org.springframework.util.StringUtils;
@@ -83,4 +84,44 @@ private void extractColumns(Bucket bucket) {
8384
throw new RuntimeException(ctx + ": " + e.getLocalizedMessage());
8485
}
8586
}
87+
88+
@Override
89+
public List<TableChartResult> parse(UtmVisualization visualization, SearchSqlResponse<Map> result) {
90+
final String ctx = CLASSNAME + ".parse(SQL)";
91+
try {
92+
if (result == null || result.getData() == null || result.getData().isEmpty()) {
93+
return Collections.singletonList(retValue);
94+
}
95+
96+
List<Map<String, Object>> rows =
97+
(List<Map<String, Object>>) (List<?>) result.getData();
98+
99+
Map<String, Object> firstRow = rows.get(0);
100+
List<String> columns = new ArrayList<>(firstRow.keySet());
101+
102+
for (String col : columns) {
103+
retValue.addColumn(col);
104+
}
105+
106+
for (Map<String, Object> row : rows) {
107+
List<TableChartResult.Cell<?>> cells = new ArrayList<>();
108+
109+
for (String column : columns) {
110+
Object rawValue = row.get(column);
111+
112+
TableChartResult.Cell<String> cell = new TableChartResult.Cell<>();
113+
cell.setValue(rawValue != null ? rawValue.toString() : null);
114+
115+
cells.add(cell);
116+
}
117+
118+
retValue.addRow(cells);
119+
}
120+
121+
return Collections.singletonList(retValue);
122+
123+
} catch (Exception e) {
124+
throw new RuntimeException(ctx + ": " + e.getMessage(), e);
125+
}
126+
}
86127
}

backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/responses/impl/metric_chart/ResponseParserForMetricChart.java

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -122,39 +122,44 @@ public List<MetricChartResult> parse(UtmVisualization visualization, SearchSqlRe
122122

123123
List<MetricChartResult> results = new ArrayList<>();
124124

125-
// IDs: puedes obtenerlos de la visualización o usar valores por defecto
126-
String metricId = "1";
127-
String bucketId = "1000";
128-
129125
for (Object rowObj : result.getData()) {
130126
if (!(rowObj instanceof Map)) continue;
131127
Map<String, Object> row = (Map<String, Object>) rowObj;
132128

133-
String bucketKey = "UNKNOWN";
129+
String bucketKey = null;
130+
String bucketId = null;
131+
134132
Double metricValue = null;
133+
String metricId = null;
135134

136-
// recorrer dinámicamente las columnas
137135
for (Map.Entry<String, Object> entry : row.entrySet()) {
136+
String key = entry.getKey();
138137
Object val = entry.getValue();
138+
139139
if (val == null) continue;
140140

141-
if (bucketKey.equals("UNKNOWN") && val instanceof String) {
142-
bucketKey = val.toString();
143-
} else if (metricValue == null && val instanceof Number) {
141+
if (val instanceof Number) {
144142
metricValue = ((Number) val).doubleValue();
143+
metricId = key;
144+
} else {
145+
bucketKey = val.toString();
146+
bucketId = key;
145147
}
146148
}
147149

148-
if (metricValue == null) {
149-
metricValue = 0.0;
150-
}
150+
if (metricValue == null) metricValue = 0.0;
151+
if (metricId == null) metricId = "metric";
152+
if (bucketKey == null) bucketKey = "UNKNOWN";
153+
if (bucketId == null) bucketId = "bucket";
151154

152155
results.add(new MetricChartResult(metricId, metricValue, bucketKey, bucketId));
153156
}
154157

155158
return results;
159+
156160
} catch (Exception e) {
157161
throw new RuntimeException(ctx + ": " + e.getMessage(), e);
158162
}
159163
}
164+
160165
}

backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/responses/impl/pie_chart/ResponseParserForPieChart.java

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -123,34 +123,29 @@ public List<PieChartResult> parse(UtmVisualization visualization, SearchSqlRespo
123123
Map<String, Object> map = (Map<String, Object>) r;
124124

125125
String bucketKey = null;
126-
double value = 0.0;
126+
String bucketId = null;
127127

128-
Map<String, Object> extras = new HashMap<>();
128+
double value = 0.0;
129+
String metricId = null;
129130

130131
for (Map.Entry<?, ?> entry : map.entrySet()) {
131132
String key = entry.getKey().toString();
132133
Object val = entry.getValue();
133134

134-
extras.put(key, val);
135-
136-
if (bucketKey == null && val != null && !(val instanceof Number)) {
137-
bucketKey = val.toString();
138-
}
139-
140135
if (val instanceof Number) {
141136
value = ((Number) val).doubleValue();
137+
metricId = key;
142138
} else {
143-
try {
144-
value = Double.parseDouble(val.toString());
145-
} catch (Exception ignore) {
146-
147-
}
139+
bucketKey = val != null ? val.toString() : null;
140+
bucketId = key;
148141
}
149142
}
150143

151-
return new PieChartResult("dynamic", value, bucketKey, extras.toString());
144+
if (metricId == null) metricId = "metric";
145+
if (bucketId == null) bucketId = "bucket";
146+
147+
return new PieChartResult(metricId, value, bucketKey, bucketId);
152148
})
153149
.collect(Collectors.toList());
154150
}
155-
156151
}

backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/responses/impl/table_chart/ResponseParserForTableChart.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,13 @@ public List<TableChartResult> parse(UtmVisualization visualization, SearchSqlRes
163163

164164
TableChartResult table = new TableChartResult();
165165

166-
// Definir columnas dinámicamente a partir de las claves del primer row
167166
if (!result.getData().isEmpty() && result.getData().get(0) instanceof Map) {
168167
Map<String, Object> firstRow = (Map<String, Object>) result.getData().get(0);
169168
for (String key : firstRow.keySet()) {
170169
table.addColumn("->" + key);
171170
}
172171
}
173172

174-
// Recorrer filas del SQL y agregarlas a la tabla
175173
for (Object rowObj : result.getData()) {
176174
if (!(rowObj instanceof Map)) continue;
177175
Map<String, Object> row = (Map<String, Object>) rowObj;

0 commit comments

Comments
 (0)