오늘은 차트 영역인 캔버스 영역에서 margin을 설정하는 방법에 대해서 이야기 하고자 합니다. 이전 축 post를 하기전에 이야기 했어야 했는데 순서가 바뀌었네요. 자 본격으로 margin 틀을 만들어서 좀더 효율적으로 차트를 만들어 볼까요.
위 그림으로 보면 전체 캔버스 회색부분에서 부분 연한노란색 영역이 바로 margin 설정으로 실제 데이터 시각화를 할 때 캔버스 영역안에 이쁘게 차트로 시각화 할 수 있게 설정할 수 있습니다.
그렇다면 margin 설정은 캔버스 영역 안에서 그릴 때 필요한 부분으로 대충 아래와 같이 4가지 방향으로 영역을 줄일 수 있습니다.
margin =>{ left: 20, right: 20, top: 20, bottom: 20 }
margin은 캔버스 영역에서 left, right, top, bottom으로 나누어서 영역을 잡아주게 됩니다. 위 그림처럼 출력하기 위해서 캔버스로부터 20씩 잡아 주었습니다.
그러면, 500x500의 캔버스 영역에서 margin 각 4방향으로 20씩 잡아주면
캔버스 영역 :
outWidth = 500;
outHeight = 500;
이라고 했을 때 margin 20씩 일괄적으로 잡아주면 위 그림처럼 나오게 하려면 아래와 같은 코딩을 하게 됩니다.
내부폭 : 외부폭 - 왼쪽margin - 오른쪽margin
inWidth = outWidth - margin.left - margin.right;
내부높이 : 외부높이 - 위쪽margin - 아래쪽margin
inHeight = outHeight - margin.top - margin.bottom;
이렇게 해서 전체 캔버스 영역에서 margin을 잡아서 데이터를 시각화하는 내부 inWidth, inHeight 잡을 수 있게 됩니다.
이 방법을 이용하여 시각화를 한번 해볼까요.
오늘 배운 내용을 기반으로 지난 시간에 배운 축(Axis)을 출력해 볼까요.
아래 코딩이 핵심입니다.
var svg = d3.select("body").append("svg")
.attr("width",outWidth)
.attr("height",outHeight);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg은 캔버스로 전체 그림영역인데 g은 margin값에 의한 그릴 시작 위치가 됩니다.
참고로 inWidth, inHeight변수는 margin값 left, right, top, bottom의 값을 빼준 그림을 그리는 실제 캔버스 영역으로 보시면 될 듯 싶네요.
이전시간에는 "svg.???" 이였다면 지금은 "g.???"이 됩니다. 어떤 느낌인지 아시겠지요. Scale도 margin값에 의해 재정의된 width, heght인 inWidth, inHeight로 재정의하면 되고요. 그릴 때는 g객체를 기준으로 출력을 하면 됩니다. 축을 지난시간에 배웠기 때문에 다시 설명하는 것은 생략하고 오늘 배운 내용을 합쳐서 한번 코딩을 완성해 봅시다.
[종합소스]
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var outWidth=500;
var outHeight=500;
var m_number = new Array();
var margin = { left: 20, right: 20, top: 20, bottom: 20 };
var inWidth = outWidth - margin.left - margin.right;
var inHeight = outHeight - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width",outWidth)
.attr("height",outHeight);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xScale=d3.scaleLinear().domain([0,45]).range([0,inHeight]);
var yScale=d3.scaleLinear().domain([0,100]).range([0,inWidth]);
var axis = d3.axisBottom().scale(yScale);
// var xAxis = d3.axisLeft().ticks(0).scale(xScale);
var xAxis = d3.axisLeft().scale(xScale);
svg.append("g")
.attr("transform","translate(20,480)")
.call(axis);
svg.append("g")
.attr("transform","translate(20,20)")
.call(xAxis);
</script>
</body>
[결과]
만약 margin값으로 잡아주지 않았다면 어떻게 될까요. 축이 씹혀버리겠죠. 어느정도 테두리 공간 확보를 위해 margin를 자주 이용됩니다.
오늘 내용은 전체 캔버스에서 margin이란 원리를 이용하여 차트나 이미지를 캔버스 영역 안에 좀더 깔끔하게 시각화 하기 위해서 테두리에 일정 공백 영역을 잡아준다고 생각하시면 됩니다. 축에 관한 post에서도 margin 원리를 이용하기 했지만 오늘처럼 하나의 틀로 잡아놓고 코딩하지 않았었죠. 오늘 내용의 틀은 햇갈리는데 d3 튜토리얼에서 배웠던 내용인데 한번 찾아보세요. 유튜브 외국강사분이였는데 참깔끔하게 틀을 만들어서 이 표현을 실전에 사용한다면 자주 이용하게 되겠더군요. 그분의 유튜브 강좌 링크주소가 기억이 안나서 링크를 달지 못해 아쉽네요.
부에나 비스타 소셜 클럽2: 아디오스 Buena Vista Social Club: Adios ...