2017-10-31 24 views
1

현재 표시된 d3js를 사용하여 거품 형 차트를 만들었습니다. enter image description hered3js : 버블 차트를 확대/축소하는 방법?

많은 양의 데이터가지도에 표시됩니다 (현재 일부 거품 만 보여주고 있습니다). 그래프를 집중시킬 수있는 방법이 있습니까? 나는 특정 영역을 확대 할 수있는 기능을 사용자에게주고 싶다.

d3js에서 어떻게합니까? 다음과 같이 내가 가진

스크립트는 다음과 같습니다

var data = [{name: "A", rank: 0, student_percentile: 100.0, 
     admit_probability: 24}, 
     {name: "B", rank: 45, student_percentile: 40.3, 
     admit_probability: 24}, 
     {name: "C", rank: 89, student_percentile: 89.7, 
     admit_probability: 24}, 
     {name: "D", rank: 23, student_percentile: 10.9, 
     admit_probability: 24}, 
     {name: "E", rank: 56, student_percentile: 30.3, 
     admit_probability: 24}]; 

var margin = 40, 
    width = 600, 
    height = 400; 
function d3(data){ 
    //var margin = {top: 30, right: 20, bottom: 30, left: 50} 

    console.log(data); 
    //d3.extent(data, function(d) { return +d.admit_probability; }) 

    xscale = d3.scaleLinear() 
     .domain(
       d3.extent(data, function(d) { return +d.student_percentile; }) 
      ) 
     .nice() 
     .range([0, width]); 

    yscale = d3.scaleLinear() 
     .domain(d3.extent(data, function(d) { return +d.rank; })) 
     .nice() 
     .range([height, 0]); 

    var xAxis = d3.axisBottom().scale(xscale); 

    var yAxis = d3.axisLeft().scale(yscale); 

    svg = d3.select('.chart') 
     .classed("svg-container", true) 
     .append('svg') 
     .attr('class', 'chart') 
     .attr("viewBox", "0 0 680 490") 
     .attr("preserveAspectRatio", "xMinYMin meet") 
     .classed("svg-content-responsive", true) 
     .append("g") 
     .attr("transform", "translate(" + margin + "," + margin + ")"); 

    svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis); 

    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis); 

    var color = d3.scaleOrdinal(d3.schemeCategory10); 

    var local = d3.local(); 
    circles = svg.selectAll(null) 
      .data(data) 
      .enter() 
      .append("circle") 
      .attr("cx", width/2) 
      .attr("cy", height/2) 
      .attr("opacity", 0.3) 
      .attr("r", 20) 
      .style("fill", function(d){ 
      if(+d.admit_probability <= 40){ 
       return "red"; 
      } 
      else if(+d.admit_probability > 40 && +d.admit_probability <= 70){ 
       return "yellow"; 
      } 
      else{ 
       return "green"; 
      } 
      }) 
      .attr("cx", function(d) { 
      return xscale(+d.student_percentile); 
      }) 
      .attr("cy", function(d) { 
      return yscale(+d.rank); 
      }) 
      .on('mouseover', function(d, i) { 
      local.set(this, d3.select(this).style("fill")); 
      d3.select(this) 
       .transition() 
       .duration(1000) 
       .ease(d3.easeBounce) 
       .attr("r", 32) 
       .style("cursor", "pointer") 
       .attr("text-anchor", "middle"); 
      } 
      ) 
      .on('mouseout', function(d, i) { 
      d3.select(this).style("fill", local.get(this)); 
      d3.select(this).transition() 
       .style("opacity", 0.3) 
       .attr("r", 20) 
       .style("cursor", "default") 
      .transition() 
      .duration(1000) 
      .ease(d3.easeBounce) 
      }); 

    texts = svg.selectAll(null) 
     .data(data) 
     .enter() 
     .append('text') 
     .attr("x", function(d) { 
     return xscale(+d.student_percentile); 
     }) 
     .attr("text-anchor", "middle") 
     .attr("y", function(d) { 
     return yscale(+d.rank); 
     }) 
     .text(function(d) { 
     return +d.admit_probability; 
     }) 
     .attr("pointer-events", "none") 
     .attr("font-family", "sans-serif") 
     .attr("font-size", "12px") 
     .attr("fill", "red"); 

    svg.append("text") 
     .attr("transform", "translate(" + (width/2) + " ," + (height + margin) + ")") 
     .style("text-anchor", "middle") 
     .text("Percentile"); 

    svg.append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 0 - margin) 
     .attr("x",0 - (height/2)) 
     .attr("dy", "1em") 
     .style("text-anchor", "middle") 
     .text("Rank"); 

    $('circle').tipsy({ 
     gravity: 'w', 
     html: true, 
     title: function() { 
      var d = this.__data__; 
      return d.name + '<br/> Rank: ' + d.rank; 
     } 
    }); 
} 
+0

주에게 편집 바이올린을 확대 d3js 브러시 기능을 사용하는 것입니다 – Anbarasan

+0

http://jsfiddle.net/h87403om/1/ – Yesha

답변

1

당신은 D3의 줌 이벤트 핸들러를 사용하여/축소 기능으로 간단한 줌을 추가하고 차트의 크기를 변환 할 수 있습니다.

svg = d3.select('.chart') 
    .classed("svg-container", true) 
    .append('svg') 
    .attr('class', 'chart') 
    .attr("viewBox", "0 0 680 490") 
    .attr("preserveAspectRatio", "xMinYMin meet") 
    .classed("svg-content-responsive", true) 
    // call d3 Zoom 
    .call(d3.zoom().on("zoom", function() { 
     svg.attr("transform", d3.event.transform) 
     })) 
    .append("g") 
    .attr("transform", "translate(" + margin + "," + margin + ")"); 

확대/축소 사용자는 마우스 스크롤 또는 두 번 클릭하여 확대하고 두 번 클릭하여 이동하거나 축소하여 축소 할 수 있습니다.

다른 방법은 영역을 선택하고 인/아웃

var brush = d3.brush().extent([[0, 0], [width, height]]).on("end", brushended), 
     idleTimeout, 
     idleDelay = 350; 

    svg.append("g") 
     .attr("class", "brush") 
     .call(brush); 

    function brushended() { 
     var s = d3.event.selection; 
     if (!s) { 
      if (!idleTimeout) return idleTimeout = setTimeout(idled, idleDelay); 

      yscale.domain(d3.extent(data, function(d) { return +d.rank; })).nice(); 

      xscale.domain(d3.extent(data, function(d) { return +d.student_percentile; })).nice() 

     } else { 

      xscale.domain([s[0][0], s[1][0]].map(xscale.invert, xscale)); 
      yscale.domain([s[1][1], s[0][1]].map(yscale.invert, yscale)); 
      svg.select(".brush").call(brush.move, null); 
     } 
     zoom(); 
    } 

    function idled() { 
     idleTimeout = null; 
    } 

    function zoom() { 

     var t = svg.transition().duration(750); 
     svg.select(".x axis").transition(t).call(xAxis); 
     svg.select(".y axis").transition(t).call(yAxis); 
     // apply new scale to the svg elements that depend on scale. 
     svg.selectAll("text").transition(t) 
      .attr("x", function(d) { 
      return xscale(+d.student_percentile); 
      }) 
      .attr("y", function(d) { 
      return yscale(+d.rank); 
      }) 
    } 
+0

주셔서 감사합니다 당신의 해결책. 나는 더 많은 연구를 한 후에이 작업을 시도했지만 일단 사용자가 페이지를 두 번 클릭하면 확대 된 상태가되지만 페이지를 새로 고치지 않아도 원래 상태로 돌아갈 방법이 없습니다. 나는 튜토리얼도 시도해 보았지만 모두이 문제를 가지고 있었다. 기본적으로 축소하는 절차는 무엇입니까? – Yesha

+0

@Yesha 가장 사용하기 쉬운 방법은 마우스 스크롤을 사용하여 확대/축소하는 것입니다. 동일한 작업을 수행하는 다른 작업은 두 번 클릭하여 확대하고 두 번 클릭하여 축소하는 것입니다. 이것은 직관적 인 상호 작용이 아니기 때문에 d3js 브러시 기능을 사용하기 위해 내 대답을 업데이트합니다. – tejesh95

+0

고마워요. 첫 번째 솔루션을 사용할 수는 있지만 두 번째 방법을 사용하는 방법을 이해할 수 없다고 정말로 유감스럽게 생각합니다. 현재의 svg 요소를 사용하여 제공 한 메서드를 호출했습니다. 그 후에, "영역 선택 및 확대/축소"란 무엇을 의미합니까? 웹 인터페이스를 사용하고 있습니다. 그래서 나는 그것을 시험하기 위해 무엇을해야 하는지를 이해할 수 없다. 또한 웹 사이트는 모바일 반응 형이므로 모바일에서도 동일한 기능을 사용할 것입니다. – Yesha