rest api 기능 구현
This commit is contained in:
@@ -8,19 +8,45 @@ export function transformQueryResultToChartData(queryResult: QueryResult, config
|
||||
return null;
|
||||
}
|
||||
|
||||
let rows = queryResult.rows;
|
||||
|
||||
// 그룹핑 처리
|
||||
if (config.groupBy && config.groupBy !== "__none__") {
|
||||
rows = applyGrouping(rows, config.groupBy, config.aggregation, config.yAxis);
|
||||
}
|
||||
|
||||
// X축 라벨 추출
|
||||
const labels = queryResult.rows.map((row) => String(row[config.xAxis!] || ""));
|
||||
const labels = rows.map((row) => String(row[config.xAxis!] || ""));
|
||||
|
||||
// Y축 데이터 추출
|
||||
const yAxisFields = Array.isArray(config.yAxis) ? config.yAxis : config.yAxis ? [config.yAxis] : [];
|
||||
|
||||
// 집계 함수가 COUNT이고 Y축이 없으면 자동으로 count 필드 추가
|
||||
if (config.aggregation === "count" && yAxisFields.length === 0) {
|
||||
const datasets: ChartDataset[] = [
|
||||
{
|
||||
label: "개수",
|
||||
data: rows.map((row) => {
|
||||
const value = row["count"];
|
||||
return typeof value === "number" ? value : parseFloat(String(value)) || 0;
|
||||
}),
|
||||
color: config.colors?.[0],
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
labels,
|
||||
datasets,
|
||||
};
|
||||
}
|
||||
|
||||
if (yAxisFields.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 각 Y축 필드에 대해 데이터셋 생성
|
||||
const datasets: ChartDataset[] = yAxisFields.map((field, index) => {
|
||||
const data = queryResult.rows.map((row) => {
|
||||
const data = rows.map((row) => {
|
||||
const value = row[field];
|
||||
return typeof value === "number" ? value : parseFloat(String(value)) || 0;
|
||||
});
|
||||
@@ -38,6 +64,73 @@ export function transformQueryResultToChartData(queryResult: QueryResult, config
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 그룹핑 및 집계 처리
|
||||
*/
|
||||
function applyGrouping(
|
||||
rows: Record<string, any>[],
|
||||
groupByField: string,
|
||||
aggregation?: "sum" | "avg" | "count" | "max" | "min",
|
||||
yAxis?: string | string[],
|
||||
): Record<string, any>[] {
|
||||
// 그룹별로 데이터 묶기
|
||||
const groups = new Map<string, Record<string, any>[]>();
|
||||
|
||||
rows.forEach((row) => {
|
||||
const key = String(row[groupByField] || "");
|
||||
if (!groups.has(key)) {
|
||||
groups.set(key, []);
|
||||
}
|
||||
groups.get(key)!.push(row);
|
||||
});
|
||||
|
||||
// 각 그룹에 대해 집계 수행
|
||||
const aggregatedRows: Record<string, any>[] = [];
|
||||
|
||||
groups.forEach((groupRows, key) => {
|
||||
const aggregatedRow: Record<string, any> = {
|
||||
[groupByField]: key,
|
||||
};
|
||||
|
||||
// Y축 필드에 대해 집계
|
||||
const yAxisFields = Array.isArray(yAxis) ? yAxis : yAxis ? [yAxis] : [];
|
||||
|
||||
if (aggregation === "count") {
|
||||
// COUNT: 그룹의 행 개수
|
||||
aggregatedRow["count"] = groupRows.length;
|
||||
} else if (yAxisFields.length > 0) {
|
||||
yAxisFields.forEach((field) => {
|
||||
const values = groupRows.map((row) => {
|
||||
const value = row[field];
|
||||
return typeof value === "number" ? value : parseFloat(String(value)) || 0;
|
||||
});
|
||||
|
||||
switch (aggregation) {
|
||||
case "sum":
|
||||
aggregatedRow[field] = values.reduce((a, b) => a + b, 0);
|
||||
break;
|
||||
case "avg":
|
||||
aggregatedRow[field] = values.reduce((a, b) => a + b, 0) / values.length;
|
||||
break;
|
||||
case "max":
|
||||
aggregatedRow[field] = Math.max(...values);
|
||||
break;
|
||||
case "min":
|
||||
aggregatedRow[field] = Math.min(...values);
|
||||
break;
|
||||
default:
|
||||
// 집계 없으면 첫 번째 값 사용
|
||||
aggregatedRow[field] = values[0];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
aggregatedRows.push(aggregatedRow);
|
||||
});
|
||||
|
||||
return aggregatedRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* API 응답을 차트 데이터로 변환
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user