d3js:如何使气泡图可缩放?

时间:2017-10-31 06:15:59

标签: javascript d3.js zoom

目前我有一个使用d3js制作的气泡图,如图所示enter image description here

我有很多数据要在地图上绘制(目前我只显示一些气泡)。有什么方法可以使图表可以集中注意力吗?我想给用户一个功能,他可以放大某个区域。

我如何在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; 
        }
    });
}

1 个答案:

答案 0 :(得分:1)

您可以使用d3的缩放事件处理程序添加简单的放大/缩小功能,并转换图表尺寸。

z-index: 2

要放大/缩小,用户可以使用鼠标滚动或双击放大并按住Shift键并双击缩小。

另一种方法是使用d3js画笔功能选择一个区域并放大/缩小

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 + ")");