ECharts-GL 아키텍처 분석
목차
GL 레이어 구조
// 각 레이어마다 역할이 있습니다, 상위 레이어에서 하위 레이어를 사용하여 기능을 구현합니다.
ECharts Core
↓
EChartsGL (최상위 레이어)
↓
LayerGL (WebGL 렌더링 레이어)
↓
ViewGL (장면, 카메라, 뷰포트 관리)
↓
ClayGL (저수준 WebGL 라이브러리)
GL 컴포넌트 상세
EChartsGL
ehcart-gl은 echarts의 확장으로, 3D 기능을 제공합니다.
// echarts-gl.js
function EChartsGL(zr) {
// 각 zlevel별로 LayerGL 객체를 저장할 빈 객체 생성
this._layers = {};
// zrender 인스턴스를 저장 (렌더링을 위한 엔진)
this._zr = zr;
}
// ECharts에 후처리 훅 등록
echarts.registerPostUpdate(function (ecModel, api) {
var zr = api.getZr();
var egl = zr.__egl = zr.__egl || new EChartsGL(zr);
egl.update(ecModel, api);
});
echarts-gl의 주요 역할:
layer-gl인스턴스 관리- ECharts 업데이트 후 GL 렌더링 처리
- 시리즈 및 컴포넌트의
view-gl관리
GraphicGL
graphic-gl은 clay-gl의 기능을 echarts-gl에 맞게 래핑하는 유틸리티 모듈입니다. 다른 컴포넌트에서 clay-gl의 기능을 쉽게 사용할 수 있게 해줍니다.
// graphicGL.js
var graphicGL = {};
// ClayGL 클래스들을 graphicGL에 추가
graphicGL.Renderer = Renderer;
graphicGL.Node = Node3D;
graphicGL.Mesh = Mesh;
graphicGL.Shader = Shader;
graphicGL.Material = Material;
graphicGL.Texture = Texture;
graphicGL.Texture2D = Texture2D;
// ... 기타 ClayGL 클래스들
// 유틸리티 함수 추가
graphicGL.createShader = function (prefix) { /* ... */ };
graphicGL.createMaterial = function (prefix, defines) { /* ... */ };
graphicGL.setMaterialFromModel = function (shading, material, model, api) { /* ... */ };
graphic-gl의 역할:
clay-gl클래스 및 유틸리티 함수 제공- 셰이더 및 재질 생성 헬퍼 함수 제공
- 텍스처 로딩 및 관리 기능 제공
LayerGL
layer-gl은 web-gl 렌더링을 담당하는 레이어로, zrender의 레이어 시스템에 통합됩니다.
// LayerGL.js
var LayerGL = function (id, zr) {
// Layer ID
this.id = id;
// zrender 인스턴스
this.zr = zr;
// ClayGL 렌더러 생성
this.renderer = new Renderer({
clearBit: 0,
devicePixelRatio: zr.painter.dpr,
preserveDrawingBuffer: true,
premultipliedAlpha: true
});
// 뷰 목록
this.views = [];
// 레이 피킹 (마우스 이벤트 처리용)
this._picking = new RayPicking({
renderer: this.renderer
});
};
layer-gl의 주요 역할:
web-gl컨텍스트 및 렌더러 관리view-gl인스턴스 관리- 이벤트 처리 및 피킹 기능
- 렌더링 프로세스 조정
ViewGL
view-gl은 3D 장면, 카메라, 뷰포트를 관리하는 컴포넌트입니다.
// ViewGL.js
function ViewGL(projection) {
projection = projection || 'perspective';
// 소속된 레이어
this.layer = null;
// ClayGL 장면
this.scene = new Scene();
// 루트 노드
this.rootNode = this.scene;
// 뷰포트 정보
this.viewport = { x: 0, y: 0, width: 0, height: 0 };
// 투영 방식 설정
this.setProjection(projection);
// 이펙트 컴포지터 (후처리 효과용)
this._compositor = new EffectCompositor();
// 시간적 슈퍼샘플링 (안티앨리어싱용)
this._temporalSS = new TemporalSuperSampling();
// 그림자 맵 패스
this._shadowMapPass = new ShadowMapPass();
}
view-gl의 주요 역할:
- 3D 장면(Scene) 및 카메라 관리
- 뷰포트 설정 및 관리
- 후처리 효과 적용
- 실제 렌더링 수행
ClayGL
clay-gl은 echarts-gl에서 사용하는 web-gl 라이브러리입니다.
clay-gl의 주요 역할:
web-gl컨텍스트 관리- 3D 기하 데이터 및 재질 관리
- 셰이더 프로그램 관리
- 장면 그래프 및 렌더링 파이프라인 제공
컴포넌트 간 의존 관계
각 컴포넌트 간의 의존 관계는 다음과 같습니다:
- EChartsGL → LayerGL:
ehcarts-gl은 여러layer-gl인스턴스를 관리합니다.- 각
zlevel에 대해 하나의layer-gl을 생성합니다.zlevel은 레이어의 깊이를 나타내며, 요소들도 분리됩니다.
// EChartsGL에서 LayerGL 생성 및 관리
function getLayerGL(model) {
var zlevel = model.get('zlevel');
var layers = self._layers;
var layerGL = layers[zlevel];
if (!layerGL) {
layerGL = layers[zlevel] = new LayerGL('gl-' + zlevel, zr);
zr.painter.insertLayer(zlevel, layerGL);
}
return layerGL;
}
- LayerGL → ViewGL:
layer-gl은 여러view-gl인스턴스를 관리합니다.- 각
view-gl은 하나의 3D 장면과 카메라를 관리합니다.
// LayerGL에 ViewGL 추가
LayerGL.prototype.addView = function (view) {
if (view.layer === this) {
return;
}
this.views.push(view);
view.layer = this;
var zr = this.zr;
view.scene.traverse(function (node) {
node.__zr = zr;
if (node.addAnimatorsToZr) {
node.addAnimatorsToZr(zr);
}
});
};
- ViewGL → ClayGl:
view-gl은clay-gl의 Scene, Camera 등을 직접 사용합니다. (렌더링 시clay-gl의 기능을 사용)
// ViewGL에서 ClayGL 사용
function ViewGL(projection) {
// ClayGL Scene 생성
this.scene = new Scene();
// ClayGL Camera 생성
if (projection === 'perspective') {
this.camera = new PerspectiveCamera();
}
else {
this.camera = new OrthographicCamera();
}
}
- GraphicGL → ClayGL:
graphic-gl은clay-gl의 클래스와 유틸리티를 래핑 -> 다른 컴포넌트에서clay-gl기능을 쉽게 사용할 수 있습니다
// GraphicGL에서 ClayGL 래핑
graphicGL.Mesh = Mesh;
graphicGL.Material = Material;
graphicGL.Shader = Shader;
Geometry 클래스 생성 패턴
echarts-gl에서는 특정 차트 유형에 대해 별도의 Geometry 클래스를 생성하는 경우가 있습니다.
복잡한 기하 데이터 생성이 필요한 경우:
Bar3D,Surface등 특수한 형태의 기하 데이터가 필요한 경우- 데이터에 따라 동적으로 기하 데이터를 생성해야 하는 경우
특수한 렌더링 최적화가 필요한 경우:
- 정점 정렬, 삼각형 정렬 등 특수한 최적화가 필요한 경우
- 인스턴싱, 배칭 등의 최적화 기법을 적용해야 하는 경우
예를 들어, Cones3DGeometry는 다음과 같이 구현됩니다:
// Cones3DGeometry.js
var ConesGeometry = Geometry.extend(function () {
return {
// 정점 속성 정의
attributes: {
position: new Geometry.Attribute('position', 'float', 3, 'POSITION'),
normal: new Geometry.Attribute('normal', 'float', 3, 'NORMAL'),
color: new Geometry.Attribute('color', 'float', 4, 'COLOR'),
// 기타 속성...
},
// 동적 업데이트 활성화
dynamic: true,
// 기타 설정...
};
},
{
// 원뿔 추가 메서드
addBar: function (start, dir, leftDir, size, color, dataIndex) {
// 원뿔 기하 데이터 생성 로직...
}
});
반면, 단순한 기하 데이터는 별도의 클래스 없이 직접 생성하기도 합니다:
// 단순한 기하 데이터 직접 생성 예시
var planeGeometry = new graphicGL.PlaneGeometry();
var mesh = new graphicGL.Mesh({
geometry: planeGeometry,
material: material
});
좌표계와 GL 컴포넌트 통합
echarts-gl에서 좌표계(Grid3D, Globe, Geo3D 등)는 view-gl과 통합되어 작동합니다:
- 좌표계 모델에서 ViewGL 생성:
- 각 좌표계 모델(Grid3DModel, GlobeModel 등)은 자체 ViewGL 인스턴스를 생성합니다.
- 이 ViewGL은 좌표계의 3D 시각화를 담당합니다.
// grid3DCreator.js
grid3DModel.__viewGL = grid3DModel.__viewGL || new ViewGL();
cartesian3D.viewGL = grid3DModel.__viewGL;
- 좌표계와 시리즈 연결:
- 시리즈는 좌표계의 ViewGL을 사용하여 3D 요소를 렌더링합니다.
- 좌표계는 데이터 좌표를 3D 공간 좌표로 변환하는 기능을 제공합니다.
// echarts-gl.js
var viewGL = coordSys.viewGL;
layerGL.addView(viewGL);
- 좌표 변환 프로세스:
- 원본 데이터 → 좌표계 데이터 → 3D 공간 좌표 → 화면 좌표
// 좌표 변환 예시
var point = coordSys.dataToPoint([x, y, z]);