데이터 차트를 보여줘야 하는데 이것을 도넛 모양으로 표현할 때가 있다.
이제 것 라이브러리를 사용하여 크게 신경 쓰지 않았지만,
데이터가 추가 된다거나, 변경되고, 유기적인 데이터가 아닌 가벼운 데이터의 경우 도넛 모양의 차트만 그려줄 거라 하드코딩으로 해보기로 했다.
일단 구조를....
이런 도넛 모양의 차트를 기준으로 시작해봤다.
1. 베이스 원형
2. 가운데 뚫어줄 원형
3. % 별로 컬러가 입혀질 원형
4. 데이터 표시 라벨
1. 일단 css로만 해볼까?
일단 한개 수치만 띄어보자.
<HTML>
<div class="chart">
<div class="chart-bar"></div>
</div>
<CSS3>
.chart{
margin:0;
padding:0;
list-style-type: none;
overflow: hidden;
position: relative;
width: 280px;
height: 280px;
border-radius:320px;
background:gray;
}
.chart:after{
content:'';
position:absolute;
top:0;left:0;bottom:0;right:0;
margin:auto;
width:80%;
height:80%;
background:#fff;
border-radius:100%;
}
.chart-bar{
position: absolute;
top:50%;left:50%;
background:skyblue;
height:110%;
width:45%;
transform: translate(-50%,-50%) rotateZ(-45deg);
transform-origin:center;
}
chart-bar의 width 값과 transform값의 rotateZ로 변경하면 될 거 같았다.
2. background:conic-gradient() 의 사용하기
원의 중심점에서 끝점, 각도 끝점까지 해서 대략 원뿔모양식으로 처리를 해야했다.
<HTML5>
<div class="chart">
<div class="chart-bar" data-deg="50"></div>
</div>
<CSS3>
.chart {
position: relative;
width: 300px;
height: 300px;
border-radius: 50%;
transition: 0.3s;
background:lightgray;
display:inline-block;
}
.chart:after{ /* 가상선택자는 도넛 모양을 만들기 위함이다.*/
content:'';
background: #fff; /* 백그라운드 컬러로 중앙가리기 */
position: absolute;
top:50%; left:50%;
width:200px; height:200px; /* 도넛의 너비 설정 */
border-radius: 50%;
transform: translate(-50%, -50%);
}
.chart-bar{
width: inherit;
height: inherit;
border-radius: 50%;
background: conic-gradient(#9986dd 50deg, #fbb871 50deg); /* 차트 설정 */
}
conic-gradient은 시작지점을 설정하지 않으면 12시부터(시계로 빗대어 말하자면) 시작하게 된다.
background: conic-gradient(#9986dd 50deg, #fbb871 50deg);
인자값 : 첫 시작 컬러 00번째 각도까지, 두 번째 컬러 00번째 각도부터 전체
background: conic-gradient( red 36deg, orange 36deg 170deg, yellow 170deg);
차트가 여러 개가 될 경우는 중간 차트 시작 지점 , 끝 지점 설정해야 한다.
굳이 시작점과 끝 지점 각도를 전부 설정하는 이유는 차트 경계를 엣지 있게 처리하기 위함이다.
컬러+시작각도 만 넣으면 경계는 스무스하게 그라데이션으로 처리된다.
background: conic-gradient( red 36deg, orange 170deg, yellow);
1) 첫번째 시작 기준점을 옮기고 싶다면 from
background: conic-gradient(from 45deg, red 36deg, orange 170deg, yellow);
2) 원 중심점 옮기기 - at(x축, y축)
background: conic-gradient(at 60% 25%, red 36deg, orange 170deg, yellow);
3) 여러 속성을 한꺼번에 사용
background: conic-gradient(from 30deg at 40% 35%, red , orange , yellow);
자세한 내용은 아래 링크 참고하자
https://developer.mozilla.org/en-US/docs/Web/CSS/gradient/conic-gradient()
ㄴ 링크에서 보시다시피 ie는 전혀 지원하진 않지만 엣지부터 다른 브라우저들은 지원하고 있다.
https://www.w3schools.com/css/css3_gradients_conic.asp
ㄴ 파이 차트 그리는 방식을 상세히 설명하고 있다
3. 최종 : 디테일하게 설계
이제 데이터 수치 라벨, 데이터 그래프를 나눠주면 그리고자 했었던 차트를 완성할 수 있다.
<HTML5>
<div class="chartWrap">
<div class="chart">
<div class="chart-bar" data-deg="50"></div>
<div class="chart-bar" data-deg="95"></div>
<div class="chart-bar" data-deg="200"></div>
<div class="chart-bar" data-deg="15"></div>
</div>
</div>
<CSS3>
.chartWrap{
position: relative;
width: 300px;
height: 300px;
margin:100px;
}
.chart {
position: relative;
width: 300px;
height: 300px;
border-radius: 50%;
transition: 0.3s;
background:lightgray;
display:inline-block;
}
.chart:after{
content:'';
background: #fff;
position: absolute;
top:50%; left:50%;
width:170px; height:170px;
border-radius: 50%;
transform: translate(-50%, -50%);
}
.chart-bar{
width: inherit;
height: inherit;
border-radius: 50%;
position: relative;
}
.chart-total{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background:gray;
width:100%;
}
.chart-total span{
position: absolute;
color:#777;
}
.chart-total-num{
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size:1.3rem;
font-weight:bold;
color:#333;
}
.chart-total-text1{
top:-150px;right:-10px;
}
.chart-total-text2{
top:-50px;right:-70px;
}
.chart-total-text3{
top:120px;right:30px;
}
.chart-total-text4{
top:0;left:-70px;
}
<javascript>
var _chart = document.querySelector('.chart');
var _chartBar = document.querySelectorAll('.chart-bar');
var color = ['#9986dd','#fbb871','#bd72ac','#f599dc'] //색상
var newDeg = []; //차트 deg
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function chartLabel(){
var _div = document.createElement('div');
_div.className = 'chart-total';
_div.innerHTML = `<span class="chart-total-num">Total:<br> 3,135</span>
<span class="chart-total-text1">Automobile</span>
<span class="chart-total-text2">Disablility</span>
<span class="chart-total-text3">Life</span>
<span class="chart-total-text4">Property</span>`;
insertAfter(_div,_chart);
}
function chartDraw(){
for( var i=0;i<_chartBar.length;i++){
var _num = _chartBar[i].dataset.deg
newDeg.push( _num )
}
var num = newDeg.length - newDeg.length;
_chart.style.background = 'conic-gradient(#9986dd '+
newDeg[num]+'deg, #fbb871 '+
newDeg[num]+'deg '+newDeg[num+1]+'deg, #bd72ac '+
newDeg[1]+'deg '+newDeg[2]+'deg, #f599dc '+
newDeg[2]+'deg )';
chartLabel();
}
chartDraw();
See the Pen Untitled by JNoony (@jnoony) on CodePen.
'css' 카테고리의 다른 글
[scss] scss 컴파일 해보기 (1) | 2022.08.07 |
---|---|
[css+javascript] 룰렛 (1) | 2021.04.21 |
[css] 레이아웃 그리기 (0) | 2021.03.30 |
[css] reset파일 만들기 귀찮을 때 (0) | 2021.03.17 |
[css] 크로스브라우징 (0) | 2021.03.17 |