-
+
);
}
diff --git a/frontend/components/admin/dashboard/charts/PieChart.tsx b/frontend/components/admin/dashboard/charts/PieChart.tsx
index 8afcb4c0..ab24219f 100644
--- a/frontend/components/admin/dashboard/charts/PieChart.tsx
+++ b/frontend/components/admin/dashboard/charts/PieChart.tsx
@@ -24,12 +24,17 @@ export function PieChart({ data, config, width = 500, height = 500, isDonut = fa
const svg = d3.select(svgRef.current);
svg.selectAll("*").remove();
- const margin = { top: 40, right: 150, bottom: 40, left: 120 };
+ // 범례를 위한 여백 확보 (아래 80px)
+ const legendHeight = config.showLegend !== false ? 80 : 0;
+ const margin = { top: 20, right: 20, bottom: 20 + legendHeight, left: 20 };
const chartWidth = width - margin.left - margin.right;
- const chartHeight = height - margin.top - margin.bottom;
+ const chartHeight = height - margin.top - margin.bottom - legendHeight;
const radius = Math.min(chartWidth, chartHeight) / 2;
- const g = svg.append("g").attr("transform", `translate(${width / 2},${height / 2})`);
+ // 차트를 위쪽에 배치 (범례 공간 확보)
+ const centerX = width / 2;
+ const centerY = margin.top + radius + 20;
+ const g = svg.append("g").attr("transform", `translate(${centerX},${centerY})`);
// 색상 팔레트
const colors = config.colors || ["#3B82F6", "#EF4444", "#10B981", "#F59E0B", "#8B5CF6", "#EC4899"];
@@ -136,33 +141,35 @@ export function PieChart({ data, config, width = 500, height = 500, isDonut = fa
.text(config.title);
}
- // 범례 (차트 오른쪽, 세로 배치)
+ // 범례 (차트 아래, 가로 배치, 중앙 정렬)
if (config.showLegend !== false) {
- const legendX = width / 2 + radius + 30; // 차트 오른쪽
- const legendY = (height - pieData.length * 25) / 2; // 세로 중앙 정렬
-
- const legend = svg
- .append("g")
- .attr("class", "legend")
- .attr("transform", `translate(${legendX}, ${legendY})`);
+ const itemSpacing = 100; // 각 범례 항목 사이 간격 (줄임)
+ const totalWidth = pieData.length * itemSpacing;
+ const legendStartX = (width - totalWidth) / 2; // 시작 위치
+ const legendY = centerY + radius + 40; // 차트 아래 40px
+
+ const legend = svg.append("g").attr("class", "legend");
pieData.forEach((d, i) => {
const legendItem = legend
.append("g")
- .attr("transform", `translate(0, ${i * 25})`);
+ .attr("transform", `translate(${legendStartX + i * itemSpacing + itemSpacing / 2}, ${legendY})`);
legendItem
.append("rect")
- .attr("width", 15)
- .attr("height", 15)
+ .attr("x", -6) // 사각형을 중앙 기준으로
+ .attr("y", -6)
+ .attr("width", 12)
+ .attr("height", 12)
.attr("fill", colors[i % colors.length])
- .attr("rx", 3);
+ .attr("rx", 2);
legendItem
.append("text")
- .attr("x", 20)
- .attr("y", 12)
- .style("font-size", "11px")
+ .attr("x", 0)
+ .attr("y", 18)
+ .attr("text-anchor", "middle") // 텍스트 중앙 정렬
+ .style("font-size", "10px")
.style("fill", "#333")
.text(`${d.label} (${d.value})`);
});
diff --git a/frontend/components/admin/dashboard/widgets/ClockWidget.tsx b/frontend/components/admin/dashboard/widgets/ClockWidget.tsx
index e85623f8..fff65bc4 100644
--- a/frontend/components/admin/dashboard/widgets/ClockWidget.tsx
+++ b/frontend/components/admin/dashboard/widgets/ClockWidget.tsx
@@ -111,19 +111,21 @@ export function ClockWidget({ element, onConfigUpdate }: ClockWidgetProps) {
{/* 시계 콘텐츠 */}
{renderClockContent()}
- {/* 설정 버튼 - 우측 상단 */}
-
-
-
-
-
-
- setSettingsOpen(false)} />
-
-
-
+ {/* 설정 버튼 - 우측 상단 (디자이너 모드에서만 표시) */}
+ {onConfigUpdate && (
+
+
+
+
+
+
+ setSettingsOpen(false)} />
+
+
+
+ )}
);
}
diff --git a/frontend/components/admin/dashboard/widgets/ListWidget.tsx b/frontend/components/admin/dashboard/widgets/ListWidget.tsx
index 252831c5..6d3e6929 100644
--- a/frontend/components/admin/dashboard/widgets/ListWidget.tsx
+++ b/frontend/components/admin/dashboard/widgets/ListWidget.tsx
@@ -216,7 +216,7 @@ export function ListWidget({ element }: ListWidgetProps) {
const paginatedRows = config.enablePagination ? data.rows.slice(startIdx, endIdx) : data.rows;
return (
-