Skip to content

RelationChart

개요

RelationChart는 마이크로서비스 아키텍처에서 서비스 간의 관계와 성능 메트릭을 시각화하는 차트 컴포넌트입니다. RelationTree와 달리 차트 형태로 데이터를 표시하며, 응답 시간 또는 시작 시간별로 정렬 기능을 제공합니다.

주요 기능

  • 서비스 관계를 막대 차트 형태로 시각화
  • 응답 시간(response time) 또는 시작 시간(start time) 기준 정렬
  • 노드 선택 및 포커스 기능
  • 에러 상태 표시
  • 툴팁을 통한 상세 정보 표시
  • RelationTree와의 선택 동기화 지원

RelationTree와의 차이점

  • RelationTree: 트리 구조로 계층적 관계를 시각화
  • RelationChart: 차트 형태로 성능 메트릭 중심 시각화

Props 인터페이스

typescript
interface RelationChartProps {
    // 필수 Props
    children: RelationTreeData[]; // 관계 데이터 트리
    width: number; // 차트 너비
    height: number; // 차트 높이

    // 선택적 Props
    focusedId?: string; // 포커스된 노드 ID
    selectedId?: string; // 선택된 노드 ID
    useSort?: boolean; // 정렬 기능 사용 여부 (기본값: true)
    hideSort?: boolean; // 정렬 헤더 숨김 여부 (기본값: false)
    sortType?: string; // 정렬 타입 ('response' | 'start')
    selectedNode?: RelationTreeData; // 선택된 노드 데이터
}

이벤트

@select

노드가 선택되었을 때 발생합니다.

typescript
(node: RelationTreeData) => void

@focus

노드에 포커스가 설정되었을 때 발생합니다.

typescript
(node: RelationTreeData | undefined) => void

@node-click

노드가 클릭되었을 때 발생합니다. 일반적으로 xviewAnalysisV2 화면으로 이동할 때 사용됩니다.

typescript
(node: RelationTreeData) => void

기본 사용법

vue
<template>
    <RelationChart
        :children="relationData"
        :width="600"
        :height="400"
        @select="handleSelect"
        @focus="handleFocus"
        @node-click="handleNodeClick"
    />
</template>

<script setup>
import { RelationChart } from '@jennifersoft/apm-components';
import { ref, provide } from 'vue';

// i18n 메시지 제공 (필수)
provide('i18n', {
    responseTime: 'Response Time',
    startTime: 'Start Time',
});

const relationData = ref([
    {
        type: 'APPLICATION',
        id: '1',
        name: 'API Gateway',
        startTime: 1741307885018,
        relation: {
            hitSum: 100,
            elapsedTimeAverage: 250.5,
            errorCount: 2,
        },
        children: [],
    },
]);

const handleSelect = (node) => {
    console.log('Selected node:', node.name);
};

const handleFocus = (node) => {
    console.log('Focused node:', node?.name);
};

const handleNodeClick = (node) => {
    console.log('Open analysis for:', node.name);
};
</script>

인터랙티브 데모

RelationTree

RelationChart

Response Time
156.25
Payment Service
114
runTest
114
Order Service
78.36
Inventory Service
Current State:
  • Sort Type: response
  • Focused: None
  • Selected: None
  • Total Nodes: 4

데이터 구조

RelationTreeData 인터페이스

typescript
interface RelationTreeData extends ApiRelationData {
    rootId?: string;
}

interface ApiRelationData {
    type:
        | 'APPLICATION'
        | 'TRANSACTION'
        | 'INDIVIDUAL_DB'
        | 'INDIVIDUAL_EXTERNAL_CALL';
    id: string;
    name: string;
    startTime: number;
    relation: ApiTransactionRelationData | ApiApplicationRelationData;
    children: ApiRelationData[];
}

interface ApiApplicationRelationData {
    hitSum: number;
    elapsedTimeAverage: number;
    sqlTimeAverage: number;
    externalCallTimeAverage: number;
    elapsedTimeStandardDeviation: number;
    errorCount: number;
    transactionIdByDomain?: Record<string, string[]>;
    transactionSearchRange?: {
        startTime: number;
        endTime: number;
    };
}

고급 사용법

정렬 기능 커스터마이징

vue
<template>
    <RelationChart
        :children="relationData"
        :width="600"
        :height="400"
        :use-sort="true"
        :hide-sort="false"
        v-model:sort-type="currentSortType"
        @select="handleSelect"
    />
</template>

<script setup>
import { RelationChart } from '@jennifersoft/apm-components';
import { ref, watch, provide } from 'vue';

// i18n 메시지 제공 (필수)
provide('i18n', {
    responseTime: 'Response Time',
    startTime: 'Start Time',
});

const currentSortType = ref('response'); // 'response' | 'start'

// 정렬 타입 변경 감지
watch(currentSortType, (newType) => {
    console.log('Sort type changed to:', newType);
});
</script>

RelationTree와 선택 동기화

vue
<template>
    <div style="display: flex; gap: 1rem;">
        <RelationTree
            :children="relationData"
            :width="400"
            :height="400"
            :focused-id="focusedId"
            :selected-id="selectedId"
            @select="handleSelect"
            @focus="handleFocus"
        />

        <RelationChart
            :children="relationData"
            :width="400"
            :height="400"
            :focused-id="focusedId"
            :selected-id="selectedId"
            @select="handleSelect"
            @focus="handleFocus"
        />
    </div>
</template>

<script setup>
import { RelationChart, RelationTree } from '@jennifersoft/apm-components';
import { ref, provide } from 'vue';

// i18n 메시지 제공 (필수)
provide('i18n', {
    responseTime: 'Response Time',
    startTime: 'Start Time',
});

const focusedId = ref('');
const selectedId = ref('');

const handleSelect = (node) => {
    selectedId.value = node.id;
    console.log('Node selected:', node.name);
};

const handleFocus = (node) => {
    focusedId.value = node?.id || '';
    console.log('Node focused:', node?.name);
};
</script>

스타일링

컴포넌트는 CSS 변수를 통해 커스터마이징할 수 있습니다:

css
:root {
    --relation-chart-background: white;
    --relation-chart-border-color: #e5e7eb;
    --relation-chart-hover-color: #f3f4f6;
    --relation-chart-selected-color: #dbeafe;
    --relation-chart-error-color: #fca5a5;
}

접근성

  • 키보드 내비게이션 지원 (화살표 키로 노드 선택)
  • ARIA 레이블 제공
  • 포커스 상태 시각적 표시

성능 고려사항

  • 대량의 노드를 렌더링할 때는 가상 스크롤링이 자동으로 적용됩니다
  • 500개 이상의 노드를 표시할 경우 성능 저하가 발생할 수 있습니다
  • 필요한 경우 데이터를 페이지네이션하거나 필터링하는 것을 권장합니다

의존성

  • Vue 3.0+
  • @jennifersoft/vue-components-v2
  • @jennifersoft/apm-apis
  • d3-scale (차트 스케일링)
  • @vueuse/core (리사이즈 감지)