2017-10-31 1 views
1

Zur Zeit habe ich ein Blasendiagramm mit d3js hergestellt, die als enter image description hered3js: Wie kann man das Blasendiagramm zoombar machen?

gezeigt Ich habe eine Menge von Daten auf der Karte aufgezeichnet werden (Zur Zeit zeige ich einige Blasen nur). Gibt es eine Möglichkeit, den Graphen fokussierbar zu machen? Ich möchte dem Benutzer eine Funktion geben, wo er bestimmte Bereiche vergrößern kann.

Wie mache ich das in d3js?

Das Skript, das ich habe, ist wie folgt:

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

Aktie editierbare Geige – Anbarasan

+0

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

Antwort

1

Sie einfach Zoom in/out Funktionalität hinzufügen können d3 des Zoom-Ereignishandler und verwandeln die Diagramm Dimensionen verwenden.

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

Um der Benutzer kann entweder verwenden Sie die Maus blättern oder doppelklicken Sie zum Vergrößern und Shift + Doppelklick Zum Verkleinern Zoom in/out.

Ein alternativer Ansatz ist d3js Pinsel Funktion zu verwenden, um einen Bereich auszuwählen und Zoom in/out

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

Danke für Ihr Lösung. Ich habe versucht, dies nach einigem Nachforschungen zu tun, aber sobald der Benutzer auf die Seite doppelklickt, wird er vergrößert, aber ohne die Seite zu aktualisieren, gibt es keine Möglichkeit, in den Anfangszustand zurückzukehren. Ich habe auch einige Tutorials ausprobiert, aber alle hatten dieses Problem. Was ist im Prinzip das Auszoomen? – Yesha

+0

@Yesha Die benutzerfreundlichste Methode ist das Vergrößern/Verkleinern mit der Maus. Die andere Aktion, um das gleiche zu erreichen, ist ein Doppelklick, um hineinzuzoomen und zu scheissen + doppelt zu klicken, um herauszuzoomen. Da dies keine intuitive Interaktion ist, werde ich meine Antwort aktualisieren, um die d3js-Brush-Funktionalität zu verwenden. – tejesh95

+0

Vielen Dank. Ich kann Ihre erste Lösung verwenden, aber es tut mir wirklich leid zu sagen, dass ich nicht in der Lage bin, die zweite Lösung zu verstehen. Ich habe die Methoden aufgerufen, die Sie mit meinem aktuellen SVG-Element angegeben haben. Was meinst du danach mit "einen Bereich auswählen und vergrößern/verkleinern". Ich benutze ein Web-Interface. Also, ich bin nicht in der Lage zu verstehen, was ich tun soll, um es zu testen? Außerdem ist unsere Website reaktionsschnell, so dass ich die gleiche Funktionalität für Mobilgeräte nutzen werde. – Yesha