SVG를 사용하여 메시 3D 막대 차트 작성
First, you can check out the results of my application in production: Playground of SSR-Contributions-svg.
기본 정육면체 그리기
가장 기본적인 큐브 중 하나부터 시작하겠습니다.
Cartesian coordinate system에 배치된 여러 기하학적 도형의 조합으로 생각하면 다음과 같이 보일 수 있습니다(svg의 좌표계에서 y축의 양의 방향은 아래쪽입니다).
아래 그림과 같이 정점과 면의 기본 개념을 정의합니다. 정점 O를 입방체의 원점으로 사용합니다.
여기서 원근감은 실제로 윗면의 모양에 따라 결정됩니다. 따라서 가로 세로 방향의 두 대각선 길이를 정의하여 원근법을 수정해야 합니다.
그런 다음 모든 점의 좌표를 얻을 수 있습니다(원점 O의 좌표가 'ox', 'oy'라고 가정).
변수 정의로 코딩 시작(html 파일의
<script>
태그 안에 작성):const sizeX = 20;
const ratio = 2;
const sizeY = sizeX / ratio;
const height = 40;
const ox = 100;
const oy = 100;
const pA = [ox - sizeX, oy + sizeY];
const pB = [ox, oy + 2 * sizeY];
const pC = [ox + sizeX, oy + sizeY];
const pD = [ox - sizeX, oy - height + sizeY];
const pE = [ox, oy - height + 2 * sizeY];
const pF = [ox + sizeX, oy - height + sizeY];
const pG = [ox, oy - height];
const pO = [ox, oy];
const face_l = [pE, pD, pA, pB];
const face_r = [pE, pF, pC, pB];
const face_t = [pE, pD, pG, pF];
svg의 경로 태그를 통해 기하학적 표면을 그릴 것이므로 먼저 코드를 더 쉽게 작성할 수 있도록 중요한 경로를 생성하는 방법을 정의합니다.
function d(points) {
const raw = points
.map((point) => `${point[0]} ${point[1]}`)
.join(' ');
return "M" + raw + "z";
}
그런 다음 svg 코드를 가져와서 문서에 쓸 수 있습니다.
const svg = `<svg width="200" height="200">
<path d="${d(face_l)}" stroke="#000" fill="transparent" />
<path d="${d(face_r)}" stroke="#000" fill="transparent" />
<path d="${d(face_t)}" stroke="#000" fill="transparent" />
</svg>`;
document.write(svg);
큐브 그리드 그리기
rowNum 및 colNum을 지정하여 그리드를 정의합니다.
svg의 원점이 그리드(노란색 블록)의 0, 0에 있다고 가정하면 전체 그리드를 수평으로 이동해야 합니다. 그리고
maxBarHeight = 100
를 설정합니다.그리드 너비는 :
sizeX * (rowNum + colNum)
, 높이는 다음과 같아야 합니다.기본 정육면체를 그리는 함수를 정의합니다.
function cube(ox, oy, height) {
const pO = [ox, oy];
const pA = [ox - sizeX, oy + sizeY];
const pB = [ox, oy + 2 * sizeY];
const pC = [ox + sizeX, oy + sizeY];
const pD = [ox - sizeX, oy - height + sizeY];
const pE = [ox, oy - height + 2 * sizeY];
const pF = [ox + sizeX, oy - height + sizeY];
const pG = [ox, oy - height];
const face_l = [pE, pD, pA, pB];
const face_r = [pE, pF, pC, pB];
const face_t = [pE, pD, pG, pF];
return `<g>
<path d="${d(face_l)}" stroke="#000" fill="#555" />
<path d="${d(face_r)}" stroke="#000" fill="#888" />
<path d="${d(face_t)}" stroke="#000" fill="#aaa" />
</g>`;
}
sizeY * (rowNum + colNum) + maxBarHeight
및 translateX
를 픽셀로 조정하는 함수를 정의합니다.function coordIndex(rowIndex, colIndex) {
return [
(rowIndex - colIndex) * sizeX,
(rowIndex + colIndex) * sizeY
];
}
무작위 데이터 생성:
const colNum = 6; // num of cols
const rowNum = 4; // num of rows
const cubes = [];
for (let i = 0; i < colNum; i++) {
for (let j = 0; j < rowNum; j++) {
cubes.push([
i,
j,
Math.floor(Math.random() * maxBarHeight)
]);
}
}
svg 코드 생성:
// render
const svg = `<svg width="${svgWidth}" height="${svgHeight}">
<g transform="translate(${translateX}, ${translateY})">
${cubes.map((opt) => cube(
...coordIndex(...opt),
opt[2]
)).join('')}
</g>
</svg>`;
codepen의 최종 코드:
https://codepen.io/catsjuice/pen/MWVqNdQ
Reference
이 문제에 관하여(SVG를 사용하여 메시 3D 막대 차트 작성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/catsjuice/build-a-mesh-3d-bar-chart-using-svg-4dd3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)