Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
74ba65a
feat: 차트 κ΄€λ ¨ μ—”ν‹°ν‹° 및 νƒ€μž… μΆ”κ°€
Dobbymin Aug 21, 2025
b045e2d
feat: 차트 κ΄€λ ¨ μ»΄ν¬λ„ŒνŠΈ μΆ”κ°€ (ChartAxis, ChartGrid, ChartLineItem, LegendLine,…
Dobbymin Aug 21, 2025
68ff9ca
feat: 차트 μ„€μ • κ΄€λ ¨ hook(useChartConfig) μΆ”κ°€
Dobbymin Aug 21, 2025
d6b469e
feat: μ•„μ΄μ½˜ μ»΄ν¬λ„ŒνŠΈ μΆ”κ°€
Dobbymin Aug 21, 2025
724a13a
feat: 차트 데이터 λͺ©λ‘μ„ CHART_DATA_LIST둜 λ³€κ²½ν•˜κ³  λ ˆμ΄μ•„μ›ƒ μˆ˜μ •
Dobbymin Aug 21, 2025
41baf30
fix: 차트 데이터 ꡬ쑰 κ°œμ„  및 데이터 ν•­λͺ© 및 제λͺ© μ—…λ°μ΄νŠΈ
Dobbymin Aug 21, 2025
d59ccf1
feat: μœ„ν—˜λ„ 차트 ꡬ간 μ •μ˜ 및 κ΄€λ ¨ νƒ€μž… μΆ”κ°€
Dobbymin Aug 21, 2025
21f97ec
feat: μœ„ν—˜ 뢄석 μš”μ•½ μ„Ήμ…˜ μΆ”κ°€
Dobbymin Aug 21, 2025
3b411d1
feat: μœ„ν—˜ ꡬ간 μ •μ˜ 및 데이터 λͺ¨λΈ μΆ”κ°€
Dobbymin Aug 21, 2025
5045033
feat: μœ„ν—˜ 뢄석 데이터 μΆ”κ°€ 및 λͺ¨λ“ˆν™”
Dobbymin Aug 21, 2025
67a9580
feat: μœ„ν—˜λ„ 차트 κ΄€λ ¨ μœ ν‹Έλ¦¬ν‹° μΆ”κ°€ 및 λͺ¨λ“ˆν™”
Dobbymin Aug 21, 2025
2e5bddc
feat: μœ„ν—˜ μš”μΈ λ°•μŠ€ μ»΄ν¬λ„ŒνŠΈ μΆ”κ°€
Dobbymin Aug 21, 2025
ebd241e
feat: μœ„ν—˜λ„ 차트 λ°•μŠ€ μ»΄ν¬λ„ŒνŠΈ μΆ”κ°€
Dobbymin Aug 21, 2025
10cf558
feat: μœ„ν—˜ 뢄석 μš”μ•½ μ„Ήμ…˜μ„ 메인 νŽ˜μ΄μ§€μ— μΆ”κ°€
Dobbymin Aug 21, 2025
e89e231
refactor: μœ„ν—˜ μš”μΈ λ°•μŠ€ μ»΄ν¬λ„ŒνŠΈ μŠ€νƒ€μΌ μˆ˜μ • 및 λ ˆμ΄μ•„μ›ƒ κ°œμ„ 
Dobbymin Aug 21, 2025
dbe46ec
fix: Needle μ»΄ν¬λ„ŒνŠΈμ—μ„œ GaugeData와 NeedleIcon μž„ν¬νŠΈ 경둜 톡합
Dobbymin Aug 21, 2025
3cb6508
style: μœ„ν—˜λ„ 차트 λ°•μŠ€ μ»΄ν¬λ„ŒνŠΈμ˜ μŠ€νƒ€μΌ μˆ˜μ •
Dobbymin Aug 21, 2025
69af24e
style: InputSection μ»΄ν¬λ„ŒνŠΈμ˜ ν…μŠ€νŠΈ λ ˆμ΄μ•„μ›ƒ μˆ˜μ •
Dobbymin Aug 21, 2025
041668b
feat: μœ„ν—˜λ„ 뢄석 κ΄€λ ¨ μ—”ν‹°ν‹° 및 응닡 데이터 λͺ¨λΈ μΆ”κ°€
Dobbymin Aug 21, 2025
d186abe
style: μœ„ν—˜λ„ 차트 λ°•μŠ€ μ»΄ν¬λ„ŒνŠΈμ˜ ν…μŠ€νŠΈ 크기 및 λ ˆμ΄μ•„μ›ƒ μˆ˜μ •, κ²Œμ΄μ§€ λ°”λŠ˜ μœ„μΉ˜ μ‘°μ •
Dobbymin Aug 21, 2025
d9f0aff
style: μœ„ν—˜ 뢄석 μš”μ•½ μ„Ήμ…˜μ˜ λ ˆμ΄μ•„μ›ƒ 및 μŠ€νƒ€μΌ μˆ˜μ •
Dobbymin Aug 21, 2025
6866db0
fix: ChartLineItem μ»΄ν¬λ„ŒνŠΈμ—μ„œ Line μš”μ†Œμ— key 속성 μΆ”κ°€
Dobbymin Aug 21, 2025
419995e
fix: μœ„ν—˜ μš”μΈ λ°•μŠ€ μ»΄ν¬λ„ŒνŠΈμ—μ„œ key 속성을 factor.name으둜 λ³€κ²½ν•˜μ—¬ κ³ μœ μ„±μ„ 확보
Dobbymin Aug 21, 2025
1cdd1aa
fix: getLineConfig ν•¨μˆ˜μ—μ„œ key 속성 μ œκ±°ν•˜μ—¬ 쀑볡 λ°©μ§€
Dobbymin Aug 21, 2025
3ffd9cb
style: Needle μ»΄ν¬λ„ŒνŠΈμ˜ NeedleIcon 크기 및 μœ„μΉ˜ μ‘°μ •
Dobbymin Aug 21, 2025
20e10f7
refactor: MainPage μ»΄ν¬λ„ŒνŠΈμ—μ„œ μœ„ν—˜ 뢄석 μš”μ•½ μ„Ήμ…˜κ³Ό 차트 μ„Ήμ…˜μ˜ λ ˆμ΄μ•„μ›ƒ κ°„μ†Œν™”
Dobbymin Aug 21, 2025
7595056
refactor: μœ„ν—˜λ„ 차트 κ΄€λ ¨ ν•¨μˆ˜μ˜ 주석 μˆ˜μ • 및 GaugeData νƒ€μž… μ •μ˜ λ³€κ²½
Dobbymin Aug 21, 2025
c9d891a
refactor: 차트 κ΄€λ ¨ μ—”ν‹°ν‹°λ₯Ό types ν΄λ”λ‘œ μ΄λ™ν•˜κ³  λΆˆν•„μš”ν•œ 파일 μ‚­μ œ
Dobbymin Aug 21, 2025
4190df2
refactor: μœ„ν—˜λ„ 레벨 및 색상 μƒμˆ˜μ˜ λͺ…μΉ­ μˆ˜μ •
Dobbymin Aug 21, 2025
2e64208
refactor: μœ„ν—˜ 뢄석 λ°μ΄ν„°μ˜ 점수 및 λ“±κΈ‰ μˆ˜μ •, μœ„ν—˜ μš”μΈ λΉ„μœ¨ μ—…λ°μ΄νŠΈ
Dobbymin Aug 21, 2025
0908db3
refactor: Needle μ»΄ν¬λ„ŒνŠΈμ˜ 크기 및 μœ„μΉ˜ μ‘°μ •μœΌλ‘œ λ°˜μ‘ν˜• λ””μžμΈ κ°œμ„ 
Dobbymin Aug 21, 2025
49c39c9
refactor: μœ„ν—˜λ„ 차트의 innerRadius 및 outerRadius 값을 λΉ„μœ¨λ‘œ λ³€κ²½ν•˜μ—¬ λ°˜μ‘ν˜• λ””μžμΈ κ°œμ„ 
Dobbymin Aug 21, 2025
3b7de49
fix: λ°”λŠ˜ μœ„μΉ˜ μˆ˜μ •
Dobbymin Aug 21, 2025
93548c2
refactor: μœ„ν—˜ 뢄석 λ°μ΄ν„°μ˜ 점수 및 λ“±κΈ‰ μˆ˜μ •, μœ„ν—˜λ„ 등급별 색상 λ§€ν•‘ μ—…λ°μ΄νŠΈ
Dobbymin Aug 21, 2025
000b4ec
style: μœ„ν—˜λ„ 색상 λ³€μˆ˜ μΆ”κ°€ 및 μ—…λ°μ΄νŠΈ
Dobbymin Aug 21, 2025
a535aed
refactor: μœ„ν—˜λ„ μ μˆ˜μ— λ”°λ₯Έ ꡬ간 인덱슀 및 각도 계산 둜직 μˆ˜μ •
Dobbymin Aug 21, 2025
76dbc46
refactor: μœ„ν—˜λ„ μ°¨νŠΈμ—μ„œ 점수 색상 및 λ°”λŠ˜ 각도 계산 둜직 μΆ”κ°€
Dobbymin Aug 21, 2025
3007cfa
refactor: μœ„ν—˜ μš”μ•½μ—μ„œ λ“±κΈ‰ ν•„λ“œ 제거
Dobbymin Aug 21, 2025
4ad5889
feat: 차트 색상 μƒμˆ˜ 및 Tailwind CSS 클래슀 μΆ”κ°€
Dobbymin Aug 21, 2025
a47562b
refactor: μœ„ν—˜λ„ λ“±κΈ‰ 및 색상 μƒμˆ˜ μ—…λ°μ΄νŠΈ, μœ„ν—˜λ„ ꡬ간 μ •μ˜ μˆ˜μ •
Dobbymin Aug 21, 2025
5988a87
feat: μœ„ν—˜λ„ μ μˆ˜μ— λ”°λ₯Έ 색상 클래슀 및 λ°•μŠ€ 그림자 클래슀 μΆ”κ°€
Dobbymin Aug 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/entities/chart/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './types';
21 changes: 21 additions & 0 deletions src/entities/chart/types/chart.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* 차트 κ΄€λ ¨ entities
*/

// 차트 라인 데이터
export interface ChartLine {
key: string;
name: string;
}

// 차트 데이터 포인트
export interface ChartDataPoint {
[key: string]: string | number;
}

// 차트 데이터
export interface ChartData {
title: string;
lines: ChartLine[];
data: ChartDataPoint[];
}
2 changes: 2 additions & 0 deletions src/entities/chart/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './chart.type';
export * from './risk-analysis.type';
58 changes: 58 additions & 0 deletions src/entities/chart/types/risk-analysis.type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* μœ„ν—˜λ„ 뢄석 κ΄€λ ¨ entities
*/

// μœ„ν—˜ μš”μΈ
export type RiskFactor = {
name: string;
percent: number;
};

// μœ„ν—˜λ„ μš”μ•½
export type RiskSummary = {
score: number;
factors: RiskFactor[];
};

// μž„λŒ€μΈ 정보
export type Landlord = {
landlordId: number;
name: string;
normalizedKey: string;
ownedCount: number;
grade: string;
createdAt: string;
updatedAt: string;
};

// μž„λŒ€μΈ 신뒰도
export type LandlordTrust = {
trustScore: number;
subrogationCount: number;
arrearsCount: number;
litigationCount: number;
ownedUnsoldCount: number;
grade: string;
};

// μž„λŒ€μΈ μ†Œμœ  λ§€λ¬Ό
export type LandlordPlace = {
placeId: number;
label: string;
address: string;
addressDetail: string;
};

// μœ„ν—˜λ„ 뢄석 응닡 데이터
export type RiskAnalysisResponse = {
data: {
riskSummary: RiskSummary;
landlord: Landlord;
landlordTrust: LandlordTrust;
landlordPlaces: LandlordPlace[];
};
status: string;
serverDateTime: string;
errorCode: string | null;
errorMessage: string | null;
};
3 changes: 3 additions & 0 deletions src/entities/index.ts
Original file line number Diff line number Diff line change
@@ -1,0 +1,3 @@
export * from './auth';
export * from './chart';
export * from './risk-analysis';

Check failure on line 3 in src/entities/index.ts

View workflow job for this annotation

GitHub Actions / test

Unable to resolve path to module './risk-analysis'
18 changes: 18 additions & 0 deletions src/features/main/components/common/ChartAxis.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { XAxis, YAxis } from 'recharts';

import { useChartConfig } from '../../hooks';

type Props = {
dataKey: string;
};

export const ChartAxis = ({ dataKey }: Props) => {
const { xAxisConfig, yAxisConfig } = useChartConfig();

return (
<>
<XAxis dataKey={dataKey} {...xAxisConfig} />
<YAxis {...yAxisConfig} />
</>
);
};
16 changes: 16 additions & 0 deletions src/features/main/components/common/ChartGrid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { CartesianGrid } from 'recharts';

import { useChartConfig } from '../../hooks';

export const ChartGrid = () => {
const { gridConfig } = useChartConfig();

return (
<>
{/* κ°€λ‘œμ„  - μ‹€μ„  */}
<CartesianGrid {...gridConfig.horizontal} />
{/* μ„Έλ‘œμ„  - 점선 */}
<CartesianGrid {...gridConfig.vertical} />
</>
);
};
17 changes: 17 additions & 0 deletions src/features/main/components/common/ChartLineItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Line } from 'recharts';

import type { ChartLine } from '@/entities';

import { useChartConfig } from '../../hooks';

type Props = {
line: ChartLine;
index: number;
};

export const ChartLineItem = ({ line, index }: Props) => {
const { getLineConfig } = useChartConfig();
const config = getLineConfig(line, index);

return <Line key={line.key} {...config} />;
};
25 changes: 25 additions & 0 deletions src/features/main/components/common/LegendLine.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { ChartLine } from '@/entities';

import { useChartConfig } from '../../hooks';

type Props = {
lines: ChartLine[];
};

export const LegendLine = ({ lines }: Props) => {
const { getLegendItemConfig } = useChartConfig();

return (
<ul className='m-0 flex list-none gap-5 p-0'>
{lines.map((line, index) => {
const config = getLegendItemConfig(line, index);
return (
<li key={config.key} className='flex items-center gap-2'>
<div className={`h-1 w-5 ${config.colorClass}`} />
<span className='text-sm text-gray-600'>{config.name}</span>
</li>
);
})}
</ul>
);
};
22 changes: 22 additions & 0 deletions src/features/main/components/common/Needle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { NeedleIcon } from '@/shared';

type Props = {
needleAngle: number;
};

export const Needle = ({ needleAngle }: Props) => {
const correctedAngle = needleAngle - 90;

return (
<div
className='absolute top-1/2 left-1/2 origin-bottom -translate-x-1/2 -translate-y-full transition-transform duration-500 ease-in-out sm:h-20 md:h-16 lg:h-24'
style={{
transform: `rotate(${correctedAngle}deg)`,
}}
>
<div className='absolute bottom-0 left-1/2 z-10 size-2 -translate-x-1/2 translate-y-1/2 rounded-full bg-gray-400 sm:size-4 md:size-5 lg:size-6' />

<NeedleIcon className='absolute bottom-0 left-1/2 h-12 w-24 -translate-x-1/2 rounded-md text-gray-800 sm:h-16 sm:w-32 md:h-20 md:w-40 lg:h-24 lg:w-50' />
</div>
);
};
5 changes: 5 additions & 0 deletions src/features/main/components/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from './ChartAxis';
export * from './ChartGrid';
export * from './ChartLineItem';
export * from './LegendLine';
export * from './Needle';
119 changes: 17 additions & 102 deletions src/features/main/components/features/chart/ChartBox.tsx
Original file line number Diff line number Diff line change
@@ -1,87 +1,24 @@
import {
CartesianGrid,
Legend,
Line,
LineChart,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis,
} from 'recharts';
import { Legend, LineChart, ResponsiveContainer, Tooltip } from 'recharts';

import { getChartColor, getChartColorClass } from '@/shared';
import type { ChartData } from '@/entities';

type DataPoint = {
year: string;
[key: string]: string | number;
};
import { ChartAxis, ChartGrid, ChartLineItem, LegendLine } from '../../common';

type Props = {
data: DataPoint[];
lines: {
key: string;
name: string;
showDot?: boolean;
}[];
title?: string;
height?: number;
yAxisFormatter?: (value: number) => string;
tooltipFormatter?: (value: number, name: string) => [string, string];
labelFormatter?: (label: string) => string;
chartData: ChartData;
};

export const ChartBox = ({
data,
lines,
title,
yAxisFormatter = (value) => value.toFixed(2),
tooltipFormatter = (value, name) => [`${value}%`, name],
labelFormatter = (label) => `20${label}λ…„`,
}: Props) => {
export const ChartBox = ({ chartData }: Props) => {
const { title, lines, data } = chartData;

return (
<div className='pt-5 pr-8 pb-1 pl-5'>
{title && (
<h3 className='mb-10 ml-5 text-start text-3xl font-bold text-[#333D4B]'>{title}</h3>
)}
<div className='w-full rounded-lg bg-white p-3'>
<h3 className='mb-10 ml-5 text-xl font-bold text-gray-900'>{title}</h3>
<ResponsiveContainer width='100%' height={300}>
<LineChart data={data}>
{/* κ°€λ‘œμ„  - μ‹€μ„  */}
<CartesianGrid horizontal={true} vertical={false} strokeDasharray='0' stroke='#BDBDBF' />
{/* μ„Έλ‘œμ„  - 점선 */}
<CartesianGrid
horizontal={false}
vertical={true}
strokeDasharray='3 3'
stroke='#f0f0f0'
/>
<XAxis
dataKey='year'
stroke='#BDBDBF'
fontSize={12}
tickLine={false}
axisLine={false}
tickMargin={10}
/>
<YAxis
stroke='#BDBDBF'
fontSize={12}
tickLine={false}
axisLine={false}
tickFormatter={yAxisFormatter}
tickMargin={10}
domain={[0, 6]}
ticks={[0, 1, 2, 3, 4, 5, 6]}
/>
<Tooltip
contentStyle={{
backgroundColor: 'white',
border: '1px solid #e0e0e0',
borderRadius: '8px',
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
}}
formatter={tooltipFormatter}
labelFormatter={labelFormatter}
/>
<LineChart data={data} margin={{ top: 5, right: 30, left: 0, bottom: 5 }}>
<ChartGrid />
<ChartAxis dataKey='month' />
<Tooltip />
<Legend
verticalAlign='top'
align='left'
Expand All @@ -94,34 +31,12 @@ export const ChartBox = ({
content={({ payload }) => {
if (!payload || payload.length === 0) return null;

// lines λ°°μ—΄μ˜ μˆœμ„œλŒ€λ‘œ λ²”λ‘€λ₯Ό 생성
return (
<ul className='m-0 flex list-none gap-5 p-0'>
{lines.map((line, index) => (
<li key={line.key} className='flex items-center gap-2'>
<div className={`h-1 w-5 ${getChartColorClass(index)}`} />
<span className='text-sm text-gray-600'>{line.name}</span>
</li>
))}
</ul>
);
return <LegendLine lines={lines} />;
}}
/>
{lines.map((line, index) => {
const color = getChartColor(index);
return (
<Line
key={line.key}
type='monotone'
dataKey={line.key}
name={line.name}
stroke={color}
strokeWidth={2}
dot={line.showDot ? { r: 4, fill: color } : false}
activeDot={line.showDot ? { r: 6, stroke: color, strokeWidth: 2 } : false}
/>
);
})}
{lines.map((line, index) => (
<ChartLineItem key={line.key} line={line} index={index} />
))}
</LineChart>
</ResponsiveContainer>
</div>
Expand Down
Loading
Loading