posts

ECharts-GL 3D 차트 컴포넌트 분석

Oct 1, 2025 updated Oct 1, 2025 3dawsjavascriptlegacyvisualization

목차

  1. 3D 관련 컴포넌트 분석
  2. 시리즈 렌더링 메커니즘

3D 관련 컴포넌트 분석

Bar3D 클래스

Bar3D는 ECharts-GL에서 제공하는 대표적인 3D 차트 유형으로, 데이터를 3차원 막대 형태로 시각화합니다. Bar3D 구현은 다음과 같은 주요 파일들로 구성됩니다:

구성 파일

graph TD
    A[Bar3D] --> B[Bar3DSeries.js]
    A --> C[Bar3DView.js]
    A --> D[bar3DLayout.js]
    A --> E[Bars3DGeometry.js]
    B --> F[SeriesModel]
    C --> G[ChartView]
    E --> H[Geometry]

Bar3DSeries.js

Bar3DSeries는 3D 막대 차트의 데이터 모델을 정의합니다. 이 클래스는 ECharts의 SeriesModel을 확장하여 다음과 같은 기능을 제공합니다:

// Bar3DSeries 클래스 구조
var Bar3DSeries = echarts.SeriesModel.extend({
    type: 'series.bar3D',
    dependencies: ['grid3D'],

    // 기본 옵션 설정
    defaultOption: {
        // 좌표계 설정
        coordinateSystem: 'grid3D',
        grid3DIndex: 0,

        // 막대 스타일 설정
        bevelSize: 0,
        bevelSmoothness: 2,
        barSize: [1, 1],
        minHeight: 0,

        // 시각적 효과 설정
        shading: 'color',
        realisticMaterial: {
            roughness: 0.5,
            metalness: 0
        },
        // 기타 옵션...
    },

    // 데이터 초기화 메서드
    getInitialData: function (option, ecModel) {
        // 데이터 처리 로직...
        return data;
    }
});

Bar3DView.js

Bar3DView는 3D 막대 차트의 시각적 표현을 담당합니다. 이 클래스는 ECharts의 ChartView를 확장하여 다음과 같은 기능을 제공합니다:

// Bar3DView 클래스 구조
var Bar3DView = echarts.ChartView.extend({
    type: 'bar3D',

    // 렌더링 메서드
    render: function (seriesModel, ecModel, api) {
        // 메시 생성 및 설정
        // 재질 설정
        // 라벨 처리
        // 애니메이션 설정
    },

    // 이벤트 처리 메서드
    _initHandler: function (seriesModel, api) {
        // 마우스 이벤트 처리
        // 하이라이트 효과
    }
});

기하학적 모델 생성 과정

Bar3D의 기하학적 모델은 Bars3DGeometry 클래스에서 생성됩니다. 주요 과정은 다음과 같습니다:

  1. 데이터 준비: 시리즈 데이터를 기하 데이터로 변환할 준비
  2. 정점 계산: 각 막대의 8개 정점(꼭지점) 계산
  3. 면 생성: 6개의 면(사각형)을 구성하는 12개의 삼각형 생성
  4. 법선 계산: 조명 효과를 위한 법선 벡터 계산
  5. 텍스처 좌표 설정: 텍스처 매핑을 위한 UV 좌표 설정
  6. 인덱스 버퍼 생성: 정점 인덱스를 이용한 삼각형 구성
// 막대 추가 메서드 예시
addBar: function (x, y, z, sx, sy, sz, color, index) {
    // 정점 계산
    var vertices = [
        [x, y, z],
        [x + sx, y, z],
        [x + sx, y, z + sz],
        [x, y, z + sz],
        [x, y + sy, z],
        [x + sx, y + sy, z],
        [x + sx, y + sy, z + sz],
        [x, y + sy, z + sz]
    ];

    // 면 구성 (삼각형)
    // 법선 계산
    // 색상 설정
    // 인덱스 버퍼 업데이트
}

3D 좌표계 시스템

ECharts-GL은 다양한 3D 좌표계 시스템을 제공하여 다양한 시각화 요구사항을 지원합니다.

Grid3D

Grid3D는 3차원 직교 좌표계로, x, y, z 축을 기반으로 데이터를 표현합니다.

// Grid3D 구조
var Grid3D = function (gridModel, ecModel, api) {
    // 축 생성
    this.axisPointerEnabled = true;
    this.dimensions = ['x', 'y', 'z'];

    // 뷰 설정
    this.viewGL = null;

    // 변환 행렬
    this.model = null;
    this._viewTransform = new Matrix4();

    // 축 객체
    this._axisHelper = new cartesian3DAxisHelper();
};

Grid3D.prototype = {
    // 좌표 변환 메서드
    dataToPoint: function (data, out) {
        // 데이터 좌표를 3D 공간 좌표로 변환
    },

    // 초기화 메서드
    update: function (ecModel, api) {
        // 축 업데이트
        // 뷰 설정
        // 카메라 설정
    }
};

Globe

Globe는 구형 좌표계로, 지구본과 같은 형태로 데이터를 표현합니다.

// Globe 구조
var Globe = function (globeModel, api) {
    // 구 생성
    this.dimensions = ['lng', 'lat', 'alt'];

    // 뷰 설정
    this.viewGL = null;

    // 지형 및 텍스처
    this._earthMesh = null;
    this._surfaceMesh = null;
};

Globe.prototype = {
    // 좌표 변환 메서드
    dataToPoint: function (data, out) {
        // 경위도 좌표를 3D 공간 좌표로 변환
    },

    // 초기화 메서드
    update: function (ecModel, api) {
        // 지형 업데이트
        // 텍스처 업데이트
        // 카메라 설정
    }
};

Cartesian3D

Cartesian3D는 Grid3D의 기반이 되는 3차원 데카르트 좌표계입니다.

// Cartesian3D 구조
var Cartesian3D = function (name) {
    this.name = name || '';
    this.dimensions = ['x', 'y', 'z'];

    // 축 설정
    this.xAxis = null;
    this.yAxis = null;
    this.zAxis = null;
};

Cartesian3D.prototype = {
    // 좌표 변환 메서드
    dataToPoint: function (data, out) {
        // x, y, z 좌표 변환
    },

    // 축 설정 메서드
    setAxis: function (xAxis, yAxis, zAxis) {
        this.xAxis = xAxis;
        this.yAxis = yAxis;
        this.zAxis = zAxis;
    }
};

좌표 변환 과정

3D 좌표계에서의 좌표 변환 과정은 다음과 같습니다:

graph LR
    A[원본 데이터] --> B[데이터 스케일링]
    B --> C[좌표계 변환]
    C --> D[뷰 변환]
    D --> E[투영 변환]
    E --> F[화면 좌표]
  1. 데이터 스케일링: 원본 데이터를 좌표계의 범위에 맞게 스케일링
  2. 좌표계 변환: 스케일링된 데이터를 3D 공간 좌표로 변환
  3. 뷰 변환: 카메라 위치와 방향에 따른 변환
  4. 투영 변환: 3D 좌표를 2D 화면 좌표로 투영
  5. 화면 좌표: 최종적으로 화면에 표시될 픽셀 좌표

시리즈 렌더링 메커니즘

데이터 → 3D 모델 변환 과정

ECharts-GL에서 데이터가 3D 모델로 변환되는 과정은 다음과 같습니다:

flowchart TD
    A[원본 데이터] --> B[데이터 처리]
    B --> C[레이아웃 계산]
    C --> D[기하 데이터 생성]
    D --> E[메시 생성]
    E --> F[재질 적용]
    F --> G[장면에 추가]

데이터 처리 과정

  1. 데이터 파싱: 원본 데이터를 파싱하여 내부 데이터 구조로 변환
  2. 데이터 필터링: 유효하지 않은 데이터 제거
  3. 데이터 정규화: 데이터 값을 정규화하여 일관된 범위로 변환
  4. 스택 처리: 스택 옵션이 활성화된 경우 데이터 스택 처리
// 데이터 처리 예시
function processData(data, coordSys) {
    // 데이터 필터링
    data.filterSelf(function (idx) {
        return data.hasValue(idx);
    });

    // 데이터 정규화
    var extent = data.getDataExtent('value');
    var min = extent[0];
    var max = extent[1];

    data.each('value', function (value, idx) {
        var normalized = (value - min) / (max - min);
        data.setItemLayout(idx, normalized);
    });
}

정규화 과정

데이터 정규화는 다양한 범위의 데이터 값을 일관된 범위(보통 0~1)로 변환하는 과정입니다:

// 정규화 함수
function normalize(value, min, max) {
    return (value - min) / (max - min);
}

// 역정규화 함수
function denormalize(normalized, min, max) {
    return normalized * (max - min) + min;
}

시각적 매핑 과정

정규화된 데이터는 시각적 속성(색상, 크기, 불투명도 등)에 매핑됩니다:

// 시각적 매핑 예시
function mapVisual(data, visualMap) {
    data.each(function (idx) {
        var value = data.get('value', idx);
        var color = visualMap.mapValueToVisual(value);
        var opacity = visualMap.mapValueToVisual('opacity', value);
        var size = visualMap.mapValueToVisual('symbolSize', value);

        // 시각적 속성 설정
        data.setItemVisual(idx, {
            color: color,
            opacity: opacity,
            symbolSize: size
        });
    });
}

메쉬 생성 과정과 옵션 처리 방식

메쉬 생성 과정

3D 메쉬는 다음과 같은 단계로 생성됩니다:

  1. 기하 데이터 생성: 정점, 법선, 텍스처 좌표, 색상 등의 기하 데이터 생성
  2. 버퍼 생성: WebGL 버퍼 객체 생성 및 데이터 업로드
  3. 재질 생성: 셰이더 프로그램 및 재질 속성 설정
  4. 메쉬 객체 생성: 기하 데이터와 재질을 결합하여 메쉬 객체 생성
// 메쉬 생성 예시
function createMesh(geometry, material) {
    var mesh = new graphicGL.Mesh({
        geometry: geometry,
        material: material,
        culling: true,
        renderOrder: 10
    });

    return mesh;
}

옵션 처리 방식

ECharts-GL은 사용자 옵션을 다음과 같은 방식으로 처리합니다:

  1. 기본 옵션 병합: 사용자 옵션과 기본 옵션을 병합
  2. 옵션 검증: 옵션 값의 유효성 검사
  3. 옵션 변환: 내부 사용을 위한 옵션 값 변환
  4. 옵션 적용: 변환된 옵션을 컴포넌트에 적용
// 옵션 처리 예시
function processOptions(userOptions, defaultOptions) {
    // 기본 옵션과 사용자 옵션 병합
    var options = echarts.util.merge(userOptions, defaultOptions, true);

    // 옵션 검증 및 변환
    if (options.shading) {
        options.material = createMaterial(options.shading, options);
    }

    return options;
}

// 재질 생성 함수
function createMaterial(shading, options) {
    var material;
    switch (shading) {
        case 'lambert':
            material = new graphicGL.Material({
                shader: graphicGL.createShader('lambert')
            });
            break;
        case 'color':
            material = new graphicGL.Material({
                shader: graphicGL.createShader('color')
            });
            break;
        // 기타 셰이딩 타입...
    }

    // 재질 속성 설정
    if (options.realisticMaterial) {
        material.set('roughness', options.realisticMaterial.roughness);
        material.set('metalness', options.realisticMaterial.metalness);
    }

    return material;
}

이러한 메커니즘을 통해 ECharts-GL은 사용자 데이터를 효과적으로 3D 시각화 모델로 변환하고, 다양한 시각적 효과와 상호작용을 제공합니다.