2017-08-13 35 views
0

昨天我發佈了一個關於條形圖的問題,我不知道如何按字母順序排序。 @Mark_M非常友善地回答,併爲我提供了一個通常應該完美工作的良好解決方案。爲什麼我的xAxis不能在d3中排序?

下面是摘錄:

var xAxis = d3.axisBottom(xScale).tickSize(0) 

var sortBars = function() { 
    // Change domain based on sorted data 
    xScale.domain(data.sort(function(a, b) { 
     return d3.ascending(a.Region, b.Region); 
     }) 
     .map(function(d) {return d.Region}) 
    ) 

    // Redraw Rects with new position 
    svg.selectAll("rect") 
     .transition() 
     .duration(1000) 
     .attr("x", function(d, i) {return xScale(d.Region)}) 

    // Redraw x Axis 
    axeX.transition() 
    .duration(1000) 
    .call(xAxis) 

"rect"確實排序,但X軸(這裏稱爲axeX)不會改變的。看起來xAxis(最後一行)的呼叫不起作用。

想知道這裏發生了什麼?

下面是完整的代碼,分揀部分是在最後:

<!DOCTYPE html> 
<html> 
    <head> 
     <meta charset = "utf-8"> 
     <title>D3 Test</title> 
    </head> 
    <body> 
     <style> 
     div.tooltip {position: absolute;    
        text-align: center;    
        width: none;     
        height: none;     
        padding: none;    
        font: 12px futura; 
        color: thistle;   
        background: none; 
        border: 0px;  
        border-radius: 8px;    
        pointer-events: none;} 

     svg {background-color: none;} 


     .tooltip {font: 10px futura; 
        color: thistle;} 


     .axisX line{stroke: white;} 
     .axisX path{stroke: white;} 
     .axisX text{fill: black;} 

     .axisY line{stroke: black;} 
     .axisY path{stroke: white;} 


     .horizontalGrid line {stroke: lightgrey; 
           stroke-opacity: 0; 
           shape-rendering: crispEdges;} 
     .horizontalGrid path {stroke-width: 0;} 



     </style> 
     <script type ="text/javascript" src = d3/d3.js></script> 
     <script> 

     //Variables; dimensions du canevas 
     var margin = {top: 40, right: 20, bottom: 130, left: 120}, 
      svgWidth = 960 - margin.left - margin.right, 
      svgHeight = 400 - margin.top - margin.bottom, 
      barPadding = 2; 

     //Variables: domaines de l'Axe X et Y 
     var xScale = d3.scaleBand().range([0, svgWidth]).padding(0.1), //scaleBand pour des proportions 
      yScale = d3.scaleLinear().range([svgHeight, 0]); //scaleLinear pour des unités (noms, lettres) 

     //Variable: échelle de couleur divisée en 80 nuances entre deux couleurs 
     var colorScale = d3.scaleLinear().domain([0,80]).range(["white", "mediumturquoise"]); 

     //Variable: création du canevas dans <body> 
     var svg = d3.select("body") 
         .append("svg") 
         .attr("width", svgWidth + margin.left + margin.right) 
         .attr("height", svgHeight + margin.top + margin.bottom) 
         .append("g") 
         .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

     //Variable: petit encadré qui apparait au passage de la souris 
     var div = d3.select("body") 
         .append("div") 
         .attr("class", "tooltip") 
         .style("visibility", "hidden"); 

     var absoluteView = false 




     //Variable: format des nombre lors de la transition de chargement des nombres -> https://github.com/d3/d3-format 
     var format = d3.format("d"); //d = notation décimale arrondie aux entiers 



     var xAxis = d3.axisBottom(xScale).tickSize(0) 


     //Biding: 
     d3.csv("/Users/daumardlouis/Desktop/geid3.csv", function(error, data) {if (error) throw error; 

      data.forEach(function(d) {d.Classification = +d.Classification;}); 

      xScale.domain(data.map(function(d) {return d.Region})); 
      yScale.domain([0, d3.max(data,function(d) {return d.Classification})]); 

     var xAxis = d3.axisBottom(xScale).tickSize(0) //marqueur d'échelle de taille 0 


      //Définition des barres 
      rect = svg.selectAll("rect") 
       .data(data) 
       .enter() 
       .append("rect") 
       .attr("x", function(d) {return xScale(d.Region)}) 
       .attr("width", svgWidth/data.length - barPadding) 
       .attr("y", svgHeight) // écart de l'axe Y = hauteur du canevas SVG 
       .attr("height", 0) // hauteur de départ des barres à 0 pour l'effet de transition 
       .attr("fill", function (d) {return colorScale (d.Classification)}) 
       .style("opacity", 0.9) 
       .on("mouseover",function(d) {d3.select(this).style("fill", "thistle").style("opacity", 0.5); // rempli de couleur la barre au passage de la souris 
              div.transition() // affiche le div en 0.2 secondes avec opacité de .5 
               .duration(200) 
               .style("visibility", "hidden"); 
              div.html(d.Classification) // affiche une donnée ou un texte dans le div 
               .style("left", (d3.event.pageX - 50) + "px") 
               .style("top", (d3.event.pageY - 70) + "px"); // la hauteur du div par rapport à la souris (attention en html la hauteur est inversée) 
              if(!absoluteView) { 
               var xPos = parseFloat(d3.select(this).attr("x")) + 6; 
               var yPos = parseFloat(d3.select(this).attr("y")) + 2; 
               var height = parseFloat(d3.select(this).attr("height")); 
               svg.append("text") 
               .attr("x", xPos) 
               .attr("y", yPos - 10) 
               .attr("class", "tooltip") 
               .text(d.Classification) 
               .attr("fill", "thistle")}; 



            }) 

       .on("mouseout",function(d) {d3.select(this).transition().duration(150).style("fill", function (d) {return colorScale (d.Classification)}).style("opacity", 1); // renvoie la couleur initiale à la sortie de la souris 
              div.transition() // faire disparaitre la div après .5 secondes 
               .duration(200) 
               .style("visibility", "hidden") 
              svg.select(".tooltip").remove(); 

              }); 

      //Transition des barres (rect) 
      rect.transition() 
       .delay(1000) 
       .ease(d3.easePoly) 
       .duration(500) 
       .attr("y", function(d) {return yScale(d.Classification)}) 
       .attr("height", function(d) {return svgHeight - yScale(d.Classification)}); 



      //Transition: effet de chargement progressif des nombres 
      var texte = svg.selectAll("text") 
      .data(data) 
      .enter() 
      .append("text") 
      .text(0) //texte à 0 au départ de la transition 
      .attr("x", function(d, i) {return 8 + i * (svgWidth/data.length)}) 
      .attr("y", svgHeight) // commence à 0, cad à la hauteur du canevas 
      .attr("fill", "thistle") 
      .attr("font-family", "futura") 
      .attr("font-size", "10px") 
      .transition() 
      .delay(function(d,i){return i *30}) //ajouter un délai décalé pour chaque élément de data 
      .ease(d3.easePoly) 
      .duration(900) 
      .attr("x", function(d, i) {return 8 + i * (svgWidth/data.length)}) 
      .attr("y", function(d) {return yScale(d.Classification) + (yScale(svgHeight)/16) }) 
      .tween("text", function(d) {var that = d3.select(this), 
              i = d3.interpolateNumber(that.text(), d.Classification); //donner une val de départ et de fin 
              return function(t) {that.text(format(i(t)))}}) //retourne le texte au format défini plus haut 
      .transition() 
      .delay(function(d,i){return 500 + i * (-30)}) //delay de 500 + annulation du délai décalé 
      .style("opacity", 0); 


      //Axe X, son style et ses transitions 
      var axeX = svg.append("g") 
       .attr("transform", "translate(0," + svgHeight + ")") 
       .call(xAxis) 
       .attr("class", "axisX") // récupère les indications de style de .axisX à l'interieur de la balise <style>. Utile pour changer la couleur de l'axe 
       .selectAll("text") 
       .attr("display", "true") 
       .attr("font-size", 2) 
       .attr("dx", "-4.8em") 
       .attr("dy", "4.15em") 
       .style("text-anchor", "end") //centre la fin du texte au milieu de chaque barre (rect) 
       .attr("transform", "rotate(-65)"); //effectue une rotation de -65° 


       axeX.transition() 
       .duration(500) 
       .delay(function(d,i){return i *30}) 
       .attr("font-family", "futura", "Bold") 
       .attr("font-size", 10); //style de police de caractère 




      //Axe Y, son style et ses transitions 
      var axeY = svg.append("g") 
       .attr("class", "axisY") 
       .attr("transform", "translate(-5)") 
       .transition() 
       .duration(5000) 
       .call(d3.axisLeft(yScale).tickSize(3)) 
       .selectAll("text") 
       .attr("transform", "translate(-5)") 
       .attr("font-family", "futura") 
       .attr("fill", "thistle"); //couleur de police de caractère 



      //Rajoute une légende à laxe Y 
      svg.append("g") 
      .append("text") 
      .attr("font-family", "futura") 
      .attr("font-size", 10) 
      .attr("transform", "rotate(-90)") 
      .attr("y", -48) 
      .attr("x", -68) 
      .style("text-anchor", "end") 
      .text(""); 



      //Rajoute des lignes de fonds prolongeant l'axe Y 
      svg.selectAll("axisY") 
       .data(yScale) 
       .enter() 
       .append("line") 
       .attr("class", "horizontalGrid") 
       .attr("x1", 0) 
       .attr("x2", svgWidth) 
       .attr("y1", function(d){ return yScale(d);}) 
       .attr("y2", function(d){ return yScale(d);}); 





      //Title 
      title = svg.append("text") 
       .attr("x", (svgWidth/2)) 
       .attr("y", 0 - (margin.top/2)) 
       .attr("text-anchor", "middle") 
       .attr("font-family", "futura") 
       .style("fill", "#5a5a5a") 
       .text("Nombre d'observations par régions"); 

       title.on("click", function() {sortBars()}); 



      // Sorting 

      var sortBars = function() {xScale.domain(data.sort(function(a, b) 
            {return d3.ascending(a.Region, b.Region)}).map(function(d) {return d.Region})) 

      // Redraw Rects with new position 
       svg.selectAll("rect") 
       .transition() 
       .duration(1000) 
       .attr("x", function(d, i) {return xScale(d.Region)}) 

      // Redraw x Axis 
       axeX.transition() 
        .duration(1000) 
        .call(xAxis) 

              } 


     }); 
     </script> 
    <body> 
</html> 

回答

2

你需要確保你正在保存的正確的事情axeX。因爲您已將selectAll("text")鏈接到它,所以axeX變量指的是文本而不是軸。

嘗試這樣的事情,而不是:

//Axe X, son style et ses transitions 
    var axeX = svg.append("g") 
     .attr("transform", "translate(0," + svgHeight + ")") 
     .call(xAxis)   
     .attr("class", "axisX") // récupère les indications de style de .axisX à l'interieur de la balise <style>. Utile pour changer la couleur de l'axe 


    axeX.selectAll("text") 
     .attr("display", "true") 
     .attr("font-size", 2) 
     .attr("dx", "-10px") 
     .attr("dy", "10px") 
     .style("text-anchor", "end") //centre la fin du texte au milieu de chaque barre (rect) 
     .attr("transform", "rotate(-65)") //effectue une rotation de -65° 
     .transition() 
     .duration(500) 
     .delay(function(d,i){return i *30}) 
     .attr("font-family", "futura", "Bold") 
     .attr("font-size", 10); //style de police de caractère 

我改變了dxdy屬性的像素,因爲EMS正在文本跳來跳去上刷新。我不太清楚如何使用ems獲得你想要的效果。它們的值隨字體大小而變化。

+0

它現在完全有效......我不知道該說什麼,我真的很感謝你的幫助@Mark_M。先生,我將在今晚的鋼琴演奏會上演奏G小調的Haendel小步舞曲! – solub

相關問題