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

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 (리사이즈 감지)