[D3.js] 드래그(d3.drag()) 함수

in #dclick6 years ago (edited)

[D3.js] 드래그(d3.drag()) 함수


오늘은 차트의 이미지를 움직이게 하는 드래그 함수에 대해서 살펴보고자 합니다. 지난 시간에는 로또볼로 너무 이상한 쪽으로 post 흐르는 것 같아서 멈추고 다시 원래 코스로 복귀 합니다. 사실 로또볼 다음 내용이 좀 더 있지만 사행성 내용으로 post가 흐르는 것은 약간 좀 그렇더군요. d3.js로 로또 관련해서 통계 분석하는 것을 구현하긴 했는데 지극히 개인적 용도로 사용한거라 post로 거론하기는 좀 그렇더군요. 아무튼 다시 원래 코스로 드래그 함수를 다뤄 보도록 하겠습니다.

1. d3.drag() 함수


드래그 함수는 캔버스에 그려진 특정 이미지를 클릭하여 드래그 할 때 해당 이미지를 움직이게 하는 함수입니다. 한번쯤 차트를 보실 때 사용 해보셨을 거에요. 특정 대상 이미지를 드래그 해서 다른 위치로 이동시켜서 원하는 이미지가 특정 위치로 모울때에 한번쯤은 이 기능을 써봤을 거에요.

이 기능은 d3.js 함수에서는 어떤식으로 코딩하는지 알아봅시다.

선택객체.call(d3.drag().on(동작));

위 모습이 기본 틀입니다. 여기에서 동작은 3가지 동작이 있습니다.

  • 시작 : .on("start", 시작동작코딩)
  • 이동 : .on("drag", 이동동작코딩)
  • 종료 : .on("end", 종료동작코딩)

시작, 이동, 종료로 나누고 선택객체를 클릭하고 이동시키고 클릭을 종료하면 최종 선택객체의 이동 위치가 됩니다.

좀 더 자세히 시작, 이동, 종료 동작코딩을 살펴 봅시다.

  • 시작동작코딩 : this은 현재 선택객체이고 active가 true상태
    .on("start", function(d){d3.select(this).raise().classed("active", true);})
  • 이동동작코딩 : 현재객체(this)의 좌표 event x,y좌표를 대입
    .on("drag", function(d) {d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);})
  • 종료동작코딩 : 현재객체(this)의 active가 false상태
    .on("end", function(d) {d3.select(this).classed("active", false);}));

지난 시간의 circle(원) 이미지 예제를 한번 오늘 drag()함수를 적용하여 움직여 볼까요.

2. Circle(원)을 드래그 시키자(예제)



[참조 예제 데이터]

x,y,r
50,50,1
100,150,3
150,50,5
200,150,7
250,50,9

[참조 예제 소스]

<script src="https://d3js.org/d3.v5.min.js"></script>

<body>
 <script>

   var rScale ;
   var ColorScale ;
   var svg = d3.select("body").append("svg")
         .attr("width",500)
         .attr("height",500)
         .style("background-color","yellow");

   function render(dataset){
     var circle = svg.selectAll("circle").data(dataset)
           .enter().append("circle")
            .attr("cx",function(d){return d.x;})
            .attr("cy",function(d){return d.y;})
            .attr("r",function(d){return rScale(d.r);})
            .attr("fill",function(d){return ColorScale(d.r);});
   }

   d3.csv("data.csv",type).then(function(data){
        var max_r = d3.max(data, function(d) { return d.r; });
        rScale = d3.scaleLinear().domain([0,max_r]).range([0,50]);
        ColorScale = d3.scaleLinear().domain([0,max_r]).range(["red","blue"]);
        render(data);
   });

   function type(d){
     d.x=+d.x;  //parseFloat(d.x);
     d.y=+d.y;  //parseFloat(d.y);
     return d;
   }
 </script>
</body>

여기에 어느 위치에 드래그 함수를 코딩해야 할까요. Circle(원)을 움직인다면 Circle(원)을 그리는 마지막 위치에 drag()함수를 코딩하면 됩니다.

     var circle = svg.selectAll("circle").data(dataset)
           .enter().append("circle")
            .attr("cx",function(d){return d.x;})
            .attr("cy",function(d){return d.y;})
            .attr("r",function(d){return rScale(d.r);})
            .attr("fill",function(d){return ColorScale(d.r);})
                        .call(d3.drag().on(시작).on(이동).on(종료));

.call(d3.drag().on(시작).on(이동).on(종료)) 코딩은 보기 좋으라고 표현한 것이고 실제 코딩을 하면 아래와 같습니다.

   .call(d3.drag()
               .on("start", function(d){d3.select(this).raise().classed("active", true);})
               .on("drag", function(d) {d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);})
               .on("end",  function(d) {d3.select(this).classed("active", false);}));

이렇게 마지막 위치에 drage()함수를 코딩하면 됩니다.

3. 종합 코딩


<script src="https://d3js.org/d3.v5.min.js"></script>
<body>
  <script>
    var rScale = d3.scaleLinear().domain([0,10]).range([0,50]);
    var ColorScale = d3.scaleLinear().domain([0,10]).range(["red","blue"]);

    //배경
    var svg = d3.select("body").append("svg")
          .attr("width",500)
          .attr("height",500)
          .style("background-color","yellow");
                    
    //데이터 출력
    function render(dataset){
      var circle = svg.selectAll("circle").data(dataset)
            .enter().append("circle")
             .attr("cx",function(d){return d.x;})
             .attr("cy",function(d){return d.y;})
             .attr("r",function(d){return rScale(d.r);})
             .attr("fill",function(d){return ColorScale(d.r);})
             .call(d3.drag()
               .on("start", function(d){d3.select(this).raise().classed("active", true);})
               .on("drag", function(d) {d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);})
               .on("end",  function(d) {d3.select(this).classed("active", false);}));
    }
        
    //데이터 읽기
    d3.csv("data.csv",type).then(function(data){      
         render(data);
    });
        
    //데이터 타입
    function type(d){
      d.x=+d.x;  //parseFloat(d.x);
      d.y=+d.y;  //parseFloat(d.y);
      return d;
    }
  </script>
</body> 

4. 결과


아래 애니메이션 이미지를 보는 것 같이 잘 움직이네요.

마무리


D3.js API 함수를 이용하여 그린 Circle(원)을 다시 드래그 함수를 이용하여 움직이게 해 보았습니다. 그렇게 어렵지 않죠. 여기서는 Circle(원)을 움직였지만 다른 이미지도 여러분들이 해당 객체그리고 그 객체에 오늘 배운 drag()함수를 삽입하면 해당 이미지객체를 움직이게 할 수 있습니다. 한번 여러분들도 Circle(원) 이미지로 실험하지 말고 다른 이미지를 한번 움직이는 실험을 한번 해보세요.


Sponsored ( Powered by dclick )
1011 일기

#1 날씨는 겨울인데 아직 나무는 단풍도 완성하지 못했네요. 이런 언밸런스한 날씨... 내일은...

logo

이 글은 스팀 기반 광고 플랫폼
dclick 에 의해 작성 되었습니다.

Sort:  

(디클릭은 사랑입니다.)
힘내세요^^
활기찬 한 주 되시구요~~

감사합니다.
주사위 굴리고 싶은 것 20분간 고민하다가 참고 왔네요. ^^
주사위 운 있으면 해보고 싶은데 주사위 운은 더럽게 없네요. ^^

1스달만 해보세요.ㅎㅎㅎㅎ
기부한다 생각하고.ㅋㅋㅋㅋ

아! 유혹에 약한데! 저번에 참가상 주신걸로 1스달 도전해볼께요.

움직이는 그림도 코딩으로 가능하네요.

그쵸!
게임을 d3.js로 만든 분들이 많아요.

저에겐...너무 무리ㅜ_ㅜ 보기만해두 어지러워요 하핳

뭐든지 처음이 힘들고 보다보면 이해가 안되더라고 친숙해져요. ^^

Coin Marketplace

STEEM 0.30
TRX 0.12
JST 0.034
BTC 64058.80
ETH 3150.15
USDT 1.00
SBD 3.99