feat: [company-analysis] 피플라이프 기업분석 리포트 페이지 추가

This commit is contained in:
김보곤
2026-03-20 08:40:10 +09:00
parent b47ab0f0fd
commit 98004a3780

View File

@@ -0,0 +1,637 @@
@extends('layouts.app')
@section('title', '피플라이프 기업 분석')
@section('content')
<!-- 뒤로가기 -->
<div class="mb-4">
<a href="{{ route('rd.company-analysis.index') }}" class="inline-flex items-center gap-1 text-sm text-gray-500 hover:text-blue-600 transition-colors">
<i class="ri-arrow-left-line"></i>
기업 분석 라이브러리로 돌아가기
</a>
</div>
<!-- 페이지 헤더 -->
<div class="mb-6">
<h1 class="text-2xl font-bold text-gray-800 flex items-center gap-2 mb-2">
<i class="ri-shield-check-line text-indigo-600"></i>
피플라이프 (PeopleLife) 기업 분석
</h1>
<p class="text-gray-500">대한민국 대표 초대형 GA - 법인 컨설팅 전문성을 바탕으로 보험클리닉 O2O 플랫폼을 운영하는 보험 금융 그룹</p>
</div>
<!-- 네비게이션 -->
<div class="mb-6 border-b border-gray-200">
<div class="flex gap-1">
<button id="tab-overview" onclick="switchTab('overview')"
class="px-4 py-2.5 text-sm font-medium text-gray-600 hover:text-blue-600 transition-colors ca-nav-active"
style="border-bottom: 2px solid #2563eb; color: #2563eb; font-weight: 700;">
<i class="ri-dashboard-line mr-1"></i>개요
</button>
<button id="tab-financials" onclick="switchTab('financials')"
class="px-4 py-2.5 text-sm font-medium text-gray-600 hover:text-blue-600 transition-colors"
style="border-bottom: 2px solid transparent;">
<i class="ri-bar-chart-box-line mr-1"></i>재무성과
</button>
<button id="tab-growth" onclick="switchTab('growth')"
class="px-4 py-2.5 text-sm font-medium text-gray-600 hover:text-blue-600 transition-colors"
style="border-bottom: 2px solid transparent;">
<i class="ri-road-map-line mr-1"></i>성장과정
</button>
<button id="tab-business" onclick="switchTab('business')"
class="px-4 py-2.5 text-sm font-medium text-gray-600 hover:text-blue-600 transition-colors"
style="border-bottom: 2px solid transparent;">
<i class="ri-building-2-line mr-1"></i>사업모델
</button>
</div>
</div>
<!-- 콘텐츠 영역 -->
<div id="tab-content"></div>
<!-- 푸터 -->
<div class="mt-10 pt-6 border-t border-gray-200 text-center text-xs text-gray-400">
&copy; 2024 PeopleLife Analysis Dashboard. 분석 자료는 공개된 정보를 기반으로 작성되었으며, 투자 판단의 근거로 활용될 없습니다.
</div>
@endsection
@push('scripts')
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<script src="https://cdn.plot.ly/plotly-2.24.1.min.js"></script>
@verbatim
<script>
// ===== 데이터 =====
const companyData = {
summary: {
revenue: "3,035억 원",
employees: "4,000+",
founded: "2003년",
slogan: "보험을 연구합니다, 고객을 연구합니다."
},
financials: {
years: ['2019', '2020', '2021', '2022', '2023(E)'],
revenue: [2186, 2468, 2580, 3035, 3200],
profit: [-120, -50, 10, 85, 120],
commentary: "2019년부터 공격적인 '보험클리닉' 오프라인 매장 투자로 인해 일시적인 영업손실을 기록했으나, 2021년 흑자 전환에 성공하며 매출과 이익이 동반 성장하는 턴어라운드 국면에 진입했습니다."
},
workforce: {
years: ['2018', '2019', '2020', '2021', '2022'],
fp_count: [3500, 3800, 4100, 4050, 3950],
channel_mix: {
labels: ['법인영업(Corporate)', '개인영업(Individual)', '보험클리닉(OTC/In-bound)'],
values: [40, 35, 25]
}
},
history: [
{ year: "2003", title: "설립", desc: "법인 컨설팅 전문 기업으로 출범" },
{ year: "2013", title: "GA 전환", desc: "초대형 GA(법인보험대리점)로 비즈니스 모델 확장" },
{ year: "2018", title: "보험클리닉 런칭", desc: "국내 최초 내방형 오프라인 보험샵 '보험클리닉' 오픈" },
{ year: "2021", title: "흑자 전환", desc: "공격적 투자의 결실로 영업이익 흑자 달성 및 내실 다지기" },
{ year: "2023", title: "디지털 전환", desc: "온-오프라인 통합 플랫폼 고도화 및 신규 시장 공략" }
]
};
// ===== 탭 전환 =====
let currentTab = 'overview';
function switchTab(tab) {
currentTab = tab;
// 탭 버튼 스타일 업데이트
['overview', 'financials', 'growth', 'business'].forEach(function(t) {
const btn = document.getElementById('tab-' + t);
if (t === tab) {
btn.style.borderBottom = '2px solid #2563eb';
btn.style.color = '#2563eb';
btn.style.fontWeight = '700';
btn.classList.add('ca-nav-active');
} else {
btn.style.borderBottom = '2px solid transparent';
btn.style.color = '';
btn.style.fontWeight = '';
btn.classList.remove('ca-nav-active');
}
});
// 콘텐츠 렌더링
const contentEl = document.getElementById('tab-content');
switch (tab) {
case 'overview':
contentEl.innerHTML = renderOverview();
break;
case 'financials':
contentEl.innerHTML = renderFinancials();
setTimeout(initFinancialChart, 100);
break;
case 'growth':
contentEl.innerHTML = renderGrowth();
break;
case 'business':
contentEl.innerHTML = renderBusiness();
setTimeout(function() {
initChannelMixChart();
initHeadcountChart();
}, 100);
break;
}
}
// ===== 개요 탭 =====
function renderOverview() {
var s = companyData.summary;
return ''
// Hero Section
+ '<div class="rounded-lg shadow-sm overflow-hidden mb-6" style="background: linear-gradient(135deg, #1e40af 0%, #3b82f6 50%, #6366f1 100%);">'
+ ' <div class="p-8 text-white">'
+ ' <div class="flex items-center gap-3 mb-2">'
+ ' <div class="w-12 h-12 bg-white/20 rounded-lg flex items-center justify-center">'
+ ' <i class="ri-shield-check-line text-2xl"></i>'
+ ' </div>'
+ ' <div>'
+ ' <h2 class="text-2xl font-bold">피플라이프 (PeopleLife)</h2>'
+ ' <p class="text-blue-100 text-sm">대한민국 대표 초대형 GA (법인보험대리점)</p>'
+ ' </div>'
+ ' </div>'
+ ' <p class="text-blue-100 text-lg mt-4 italic">"' + s.slogan + '"</p>'
+ ' <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-6">'
+ ' <div class="bg-white/10 backdrop-blur rounded-lg p-4 text-center">'
+ ' <div class="text-2xl font-bold">' + s.revenue + '</div>'
+ ' <div class="text-blue-200 text-sm mt-1"><i class="ri-money-dollar-circle-line mr-1"></i>매출액 (2022)</div>'
+ ' </div>'
+ ' <div class="bg-white/10 backdrop-blur rounded-lg p-4 text-center">'
+ ' <div class="text-2xl font-bold">' + s.employees + '</div>'
+ ' <div class="text-blue-200 text-sm mt-1"><i class="ri-team-line mr-1"></i>임직원 수</div>'
+ ' </div>'
+ ' <div class="bg-white/10 backdrop-blur rounded-lg p-4 text-center">'
+ ' <div class="text-2xl font-bold">' + s.founded + '</div>'
+ ' <div class="text-blue-200 text-sm mt-1"><i class="ri-calendar-line mr-1"></i>설립년도</div>'
+ ' </div>'
+ ' </div>'
+ ' </div>'
+ '</div>'
// 핵심 역량
+ '<h3 class="text-lg font-bold text-gray-800 mb-4 flex items-center gap-2">'
+ ' <i class="ri-star-line text-yellow-500"></i>핵심 역량 (Core Competency)'
+ '</h3>'
+ '<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">'
// 보험클리닉
+ ' <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-5 ca-card">'
+ ' <div class="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center text-blue-600 mb-3">'
+ ' <i class="ri-hospital-line text-xl"></i>'
+ ' </div>'
+ ' <h4 class="font-bold text-gray-800 mb-2">보험클리닉 (OTC)</h4>'
+ ' <p class="text-sm text-gray-500">국내 최초 내방형 오프라인 보험샵. 고객이 직접 방문하여 상담받는 O2O 혁신 모델로, 전국 주요 상권에 매장을 운영합니다.</p>'
+ ' </div>'
// 법인 영업 전문성
+ ' <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-5 ca-card">'
+ ' <div class="w-10 h-10 bg-indigo-100 rounded-lg flex items-center justify-center text-indigo-600 mb-3">'
+ ' <i class="ri-building-4-line text-xl"></i>'
+ ' </div>'
+ ' <h4 class="font-bold text-gray-800 mb-2">법인 영업 전문성</h4>'
+ ' <p class="text-sm text-gray-500">창업 초기부터 축적해 온 법인 컨설팅 역량을 바탕으로, 기업 대상 단체보험 및 임원배상책임보험 등 전문 영역을 리드합니다.</p>'
+ ' </div>'
// 정규직 상담 매니저
+ ' <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-5 ca-card">'
+ ' <div class="w-10 h-10 bg-emerald-100 rounded-lg flex items-center justify-center text-emerald-600 mb-3">'
+ ' <i class="ri-user-star-line text-xl"></i>'
+ ' </div>'
+ ' <h4 class="font-bold text-gray-800 mb-2">정규직 상담 매니저</h4>'
+ ' <p class="text-sm text-gray-500">보험클리닉의 상담 매니저를 정규직으로 채용하여 고객 신뢰도를 높이고, 장기적인 서비스 품질을 보장합니다.</p>'
+ ' </div>'
+ '</div>'
// 분석 요약
+ '<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 ca-card">'
+ ' <div class="flex items-start gap-3">'
+ ' <div class="w-10 h-10 bg-amber-100 rounded-lg flex items-center justify-center text-amber-600 shrink-0">'
+ ' <i class="ri-lightbulb-line text-xl"></i>'
+ ' </div>'
+ ' <div>'
+ ' <h4 class="font-bold text-gray-800 mb-2">분석 요약</h4>'
+ ' <p class="text-sm text-gray-600 leading-relaxed">'
+ ' 피플라이프는 법인 컨설팅 전문 기업으로 출발하여, 초대형 GA로 전환 후 보험클리닉이라는 혁신적인 O2O 채널을 구축했습니다. '
+ ' 단기적으로 공격적 투자에 따른 적자를 감수했으나, 2021년 흑자 전환에 성공하며 성장 궤도에 진입했습니다.'
+ ' </p>'
+ ' <button onclick="switchTab(\'financials\')" class="mt-3 inline-flex items-center gap-1 text-sm text-blue-600 hover:text-blue-800 font-medium">'
+ ' <i class="ri-arrow-right-line"></i>재무성과 자세히 보기'
+ ' </button>'
+ ' </div>'
+ ' </div>'
+ '</div>';
}
// ===== 재무성과 탭 =====
function renderFinancials() {
var f = companyData.financials;
var tableRows = '';
for (var i = 0; i < f.years.length; i++) {
var profitColor = f.profit[i] >= 0 ? 'text-blue-600' : 'text-red-500';
var profitSign = f.profit[i] >= 0 ? '+' : '';
tableRows += ''
+ '<tr class="border-b border-gray-100 hover:bg-gray-50">'
+ ' <td class="py-3 px-4 text-sm font-medium text-gray-800">' + f.years[i] + '</td>'
+ ' <td class="py-3 px-4 text-sm text-gray-600 text-right">' + f.revenue[i].toLocaleString() + '억 원</td>'
+ ' <td class="py-3 px-4 text-sm text-right ' + profitColor + ' font-medium">' + profitSign + f.profit[i] + '억 원</td>'
+ '</tr>';
}
return ''
+ '<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">'
// 차트 영역 (2/3)
+ ' <div class="lg:col-span-2">'
+ ' <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 ca-card">'
+ ' <h3 class="text-lg font-bold text-gray-800 mb-4 flex items-center gap-2">'
+ ' <i class="ri-bar-chart-box-line text-blue-600"></i>매출액 & 영업이익 추이'
+ ' </h3>'
+ ' <div style="position: relative; height: 350px;">'
+ ' <canvas id="financialChart"></canvas>'
+ ' </div>'
+ ' </div>'
+ ' </div>'
// 사이드바 (1/3)
+ ' <div>'
+ ' <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 ca-card mb-4">'
+ ' <h4 class="font-bold text-gray-800 mb-3 flex items-center gap-2">'
+ ' <i class="ri-focus-3-line text-indigo-600"></i>Key Insight'
+ ' </h4>'
+ ' <div class="space-y-3">'
+ ' <div class="bg-blue-50 rounded-lg p-3">'
+ ' <div class="text-xs text-blue-600 font-semibold mb-1">매출 CAGR (2019-2023E)</div>'
+ ' <div class="text-xl font-bold text-blue-800">~10.5%</div>'
+ ' </div>'
+ ' <div class="bg-emerald-50 rounded-lg p-3">'
+ ' <div class="text-xs text-emerald-600 font-semibold mb-1">흑자 전환</div>'
+ ' <div class="text-xl font-bold text-emerald-800">2021년</div>'
+ ' </div>'
+ ' </div>'
+ ' </div>'
+ ' <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 ca-card">'
+ ' <h4 class="font-bold text-gray-800 mb-3 flex items-center gap-2">'
+ ' <i class="ri-chat-quote-line text-amber-600"></i>Commentary'
+ ' </h4>'
+ ' <p class="text-sm text-gray-600 leading-relaxed">' + f.commentary + '</p>'
+ ' </div>'
+ ' </div>'
+ '</div>'
// 데이터 테이블
+ '<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 mt-6 ca-card">'
+ ' <h3 class="text-lg font-bold text-gray-800 mb-4 flex items-center gap-2">'
+ ' <i class="ri-table-line text-gray-600"></i>연도별 실적 데이터'
+ ' </h3>'
+ ' <div class="overflow-x-auto">'
+ ' <table class="w-full">'
+ ' <thead>'
+ ' <tr class="border-b-2 border-gray-200">'
+ ' <th class="py-3 px-4 text-left text-xs font-semibold text-gray-500 uppercase">연도</th>'
+ ' <th class="py-3 px-4 text-right text-xs font-semibold text-gray-500 uppercase">매출액</th>'
+ ' <th class="py-3 px-4 text-right text-xs font-semibold text-gray-500 uppercase">영업이익</th>'
+ ' </tr>'
+ ' </thead>'
+ ' <tbody>'
+ tableRows
+ ' </tbody>'
+ ' </table>'
+ ' </div>'
+ '</div>';
}
function initFinancialChart() {
var ctx = document.getElementById('financialChart');
if (!ctx) return;
var f = companyData.financials;
new Chart(ctx, {
type: 'bar',
data: {
labels: f.years,
datasets: [
{
label: '매출액 (억 원)',
data: f.revenue,
backgroundColor: 'rgba(59, 130, 246, 0.7)',
borderColor: 'rgba(59, 130, 246, 1)',
borderWidth: 1,
borderRadius: 4,
order: 2
},
{
label: '영업이익 (억 원)',
data: f.profit,
type: 'line',
borderColor: '#ef4444',
backgroundColor: 'rgba(239, 68, 68, 0.1)',
borderWidth: 2,
pointBackgroundColor: '#ef4444',
pointRadius: 5,
pointHoverRadius: 7,
fill: true,
tension: 0.3,
order: 1,
yAxisID: 'y1'
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false
},
plugins: {
legend: {
position: 'top',
labels: { usePointStyle: true, padding: 20 }
},
tooltip: {
backgroundColor: 'rgba(0,0,0,0.8)',
padding: 12,
cornerRadius: 8
}
},
scales: {
y: {
position: 'left',
title: { display: true, text: '매출액 (억 원)', font: { size: 12 } },
beginAtZero: true,
grid: { color: 'rgba(0,0,0,0.05)' }
},
y1: {
position: 'right',
title: { display: true, text: '영업이익 (억 원)', font: { size: 12 } },
grid: { drawOnChartArea: false }
},
x: {
grid: { display: false }
}
}
}
});
}
// ===== 성장과정 탭 =====
function renderGrowth() {
var h = companyData.history;
var timelineItems = '';
var colors = ['blue', 'indigo', 'purple', 'emerald', 'amber'];
var icons = ['ri-seedling-line', 'ri-exchange-line', 'ri-store-3-line', 'ri-line-chart-line', 'ri-rocket-line'];
for (var i = 0; i < h.length; i++) {
var color = colors[i % colors.length];
var icon = icons[i % icons.length];
var isLast = i === h.length - 1;
timelineItems += ''
+ '<div class="relative flex gap-4">'
// 타임라인 라인
+ ' <div class="flex flex-col items-center">'
+ ' <div class="w-10 h-10 bg-' + color + '-100 rounded-full flex items-center justify-center text-' + color + '-600 shrink-0 z-10">'
+ ' <i class="' + icon + ' text-lg"></i>'
+ ' </div>'
+ (isLast ? '' : ' <div class="w-0.5 bg-gray-200 flex-1 mt-2"></div>')
+ ' </div>'
// 콘텐츠
+ ' <div class="pb-8">'
+ ' <div class="flex items-center gap-2 mb-1">'
+ ' <span class="inline-flex items-center rounded-full bg-' + color + '-50 px-2.5 py-0.5 text-xs font-bold text-' + color + '-700">' + h[i].year + '</span>'
+ ' <h4 class="font-bold text-gray-800">' + h[i].title + '</h4>'
+ ' </div>'
+ ' <p class="text-sm text-gray-600">' + h[i].desc + '</p>'
+ ' </div>'
+ '</div>';
}
return ''
+ '<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 ca-card mb-6">'
+ ' <h3 class="text-lg font-bold text-gray-800 mb-6 flex items-center gap-2">'
+ ' <i class="ri-road-map-line text-indigo-600"></i>성장 타임라인'
+ ' </h3>'
+ ' <div class="ml-2">'
+ timelineItems
+ ' </div>'
+ '</div>'
// The Next Step
+ '<div class="rounded-lg shadow-sm overflow-hidden" style="background: linear-gradient(135deg, #1e293b 0%, #334155 100%);">'
+ ' <div class="p-6">'
+ ' <div class="flex items-center gap-3 mb-4">'
+ ' <div class="w-10 h-10 bg-white/10 rounded-lg flex items-center justify-center">'
+ ' <i class="ri-rocket-2-line text-xl text-amber-400"></i>'
+ ' </div>'
+ ' <h3 class="text-lg font-bold text-white">The Next Step</h3>'
+ ' </div>'
+ ' <p class="text-gray-300 text-sm leading-relaxed mb-4">'
+ ' 피플라이프는 기존 보험 중개의 틀을 넘어, 디지털 헬스케어와 웰니스 영역으로의 확장을 준비하고 있습니다. '
+ ' 축적된 고객 데이터와 오프라인 접점을 활용한 개인 맞춤형 건강관리 서비스로, '
+ ' 보험-헬스케어 통합 플랫폼으로의 진화를 목표로 합니다.'
+ ' </p>'
+ ' <div class="flex flex-wrap gap-2">'
+ ' <span class="inline-flex items-center rounded-full bg-white/10 px-3 py-1 text-xs text-gray-300">'
+ ' <i class="ri-heart-pulse-line mr-1 text-red-400"></i>디지털 헬스케어'
+ ' </span>'
+ ' <span class="inline-flex items-center rounded-full bg-white/10 px-3 py-1 text-xs text-gray-300">'
+ ' <i class="ri-robot-2-line mr-1 text-blue-400"></i>AI 보험 추천'
+ ' </span>'
+ ' <span class="inline-flex items-center rounded-full bg-white/10 px-3 py-1 text-xs text-gray-300">'
+ ' <i class="ri-smartphone-line mr-1 text-green-400"></i>모바일 플랫폼'
+ ' </span>'
+ ' </div>'
+ ' </div>'
+ '</div>';
}
// ===== 사업모델 탭 =====
function renderBusiness() {
return ''
// 3대 사업 축
+ '<h3 class="text-lg font-bold text-gray-800 mb-4 flex items-center gap-2">'
+ ' <i class="ri-layout-masonry-line text-indigo-600"></i>3대 사업 축 (Business Pillars)'
+ '</h3>'
+ '<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">'
// 법인 컨설팅
+ ' <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-5 ca-card">'
+ ' <div class="flex items-center gap-3 mb-3">'
+ ' <div class="w-10 h-10 bg-blue-100 rounded-lg flex items-center justify-center text-blue-600">'
+ ' <i class="ri-building-4-line text-xl"></i>'
+ ' </div>'
+ ' <div>'
+ ' <h4 class="font-bold text-gray-800">법인 컨설팅</h4>'
+ ' <span class="text-xs text-blue-600 font-semibold">매출 비중 40%</span>'
+ ' </div>'
+ ' </div>'
+ ' <p class="text-sm text-gray-500">기업 대상 단체보험, 임원배상책임보험, 퇴직연금 등 법인 특화 컨설팅 서비스. 창업 이래 핵심 사업 영역입니다.</p>'
+ ' </div>'
// 보험클리닉
+ ' <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-5 ca-card">'
+ ' <div class="flex items-center gap-3 mb-3">'
+ ' <div class="w-10 h-10 bg-purple-100 rounded-lg flex items-center justify-center text-purple-600">'
+ ' <i class="ri-store-3-line text-xl"></i>'
+ ' </div>'
+ ' <div>'
+ ' <h4 class="font-bold text-gray-800">보험클리닉</h4>'
+ ' <span class="text-xs text-purple-600 font-semibold">매출 비중 25%</span>'
+ ' </div>'
+ ' </div>'
+ ' <p class="text-sm text-gray-500">고객이 직접 매장을 방문하는 내방형(In-bound) 보험 상담 채널. 전국 주요 상권에 운영되며, 정규직 매니저가 상담합니다.</p>'
+ ' </div>'
// 개인 영업 (EFA)
+ ' <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-5 ca-card">'
+ ' <div class="flex items-center gap-3 mb-3">'
+ ' <div class="w-10 h-10 bg-emerald-100 rounded-lg flex items-center justify-center text-emerald-600">'
+ ' <i class="ri-user-heart-line text-xl"></i>'
+ ' </div>'
+ ' <div>'
+ ' <h4 class="font-bold text-gray-800">개인 영업 (EFA)</h4>'
+ ' <span class="text-xs text-emerald-600 font-semibold">매출 비중 35%</span>'
+ ' </div>'
+ ' </div>'
+ ' <p class="text-sm text-gray-500">전문 재무설계사(FA)를 통한 개인 고객 대상 보험 컨설팅. 생명보험, 손해보험 등 종합 금융 상품을 취급합니다.</p>'
+ ' </div>'
+ '</div>'
// 차트 영역
+ '<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">'
// 채널 믹스 (Plotly 도넛)
+ ' <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 ca-card">'
+ ' <h3 class="text-lg font-bold text-gray-800 mb-4 flex items-center gap-2">'
+ ' <i class="ri-pie-chart-line text-purple-600"></i>채널 믹스 (Channel Mix)'
+ ' </h3>'
+ ' <div id="channelMixChart" style="height: 320px;"></div>'
+ ' </div>'
// FA 인원 추이 (Chart.js 라인)
+ ' <div class="bg-white rounded-lg shadow-sm border border-gray-200 p-6 ca-card">'
+ ' <h3 class="text-lg font-bold text-gray-800 mb-4 flex items-center gap-2">'
+ ' <i class="ri-group-line text-blue-600"></i>FA 인원 추이'
+ ' </h3>'
+ ' <div style="position: relative; height: 320px;">'
+ ' <canvas id="headcountChart"></canvas>'
+ ' </div>'
+ ' </div>'
+ '</div>';
}
function initChannelMixChart() {
var el = document.getElementById('channelMixChart');
if (!el) return;
var mix = companyData.workforce.channel_mix;
var data = [{
values: mix.values,
labels: mix.labels,
type: 'pie',
hole: 0.5,
marker: {
colors: ['#3b82f6', '#10b981', '#8b5cf6']
},
textinfo: 'label+percent',
textposition: 'outside',
automargin: true,
hoverinfo: 'label+value+percent',
textfont: { size: 12 }
}];
var layout = {
showlegend: true,
legend: {
orientation: 'h',
y: -0.15,
x: 0.5,
xanchor: 'center',
font: { size: 11 }
},
margin: { t: 20, b: 60, l: 20, r: 20 },
annotations: [{
text: '<b>채널<br>비중</b>',
showarrow: false,
font: { size: 14, color: '#374151' },
x: 0.5,
y: 0.5
}]
};
Plotly.newPlot(el, data, layout, { responsive: true, displayModeBar: false });
}
function initHeadcountChart() {
var ctx = document.getElementById('headcountChart');
if (!ctx) return;
var w = companyData.workforce;
new Chart(ctx, {
type: 'line',
data: {
labels: w.years,
datasets: [{
label: 'FA 인원 (명)',
data: w.fp_count,
borderColor: '#6366f1',
backgroundColor: 'rgba(99, 102, 241, 0.1)',
borderWidth: 2,
pointBackgroundColor: '#6366f1',
pointRadius: 5,
pointHoverRadius: 7,
fill: true,
tension: 0.3
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'top',
labels: { usePointStyle: true, padding: 20 }
},
tooltip: {
backgroundColor: 'rgba(0,0,0,0.8)',
padding: 12,
cornerRadius: 8,
callbacks: {
label: function(context) {
return context.parsed.y.toLocaleString() + '명';
}
}
}
},
scales: {
y: {
title: { display: true, text: 'FA 인원 (명)', font: { size: 12 } },
beginAtZero: false,
grid: { color: 'rgba(0,0,0,0.05)' },
ticks: {
callback: function(value) {
return value.toLocaleString();
}
}
},
x: {
grid: { display: false }
}
}
}
});
}
// ===== 초기 렌더링 =====
document.addEventListener('DOMContentLoaded', function() {
switchTab('overview');
});
</script>
@endverbatim
@endpush