2016-12-19 85 views
2

注意:This question約爲曲線D3.js:如何在版本4中將分佈線添加到直方圖

這是我目前的狀態: enter image description here

我不太瞭解如何繪製兩個分佈的直方圖線,你看我嘗試在代碼中註釋掉。我的主要問題是如何給出x和y參數,因爲每個觀察值都只有一個附加值。

這是我的代碼:

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <style> 
    .bar1 rect { 
     fill: rgba(0,0,255,0.6); 
    } 

    .bar1:hover rect{ 
     fill: rgba(0,0,255,0.9); 
    } 

    .bar1 text { 
     fill: #fff; 
     font: 10px sans-serif; 
    } 

    .bar2 rect { 
     fill: rgba(255,0,0,0.6); 
    } 

    .bar2:hover rect{ 
     fill: rgba(255,0,0,0.9); 
    } 

    .bar2 text { 
     fill: #fff; 
     font: 10px sans-serif; 
    } 

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

    <script> 

    function draw(data) { 

     var allCongruentData = data.map(function(e){ return e.Congruent;}); 
     var allIncongruentData = data.map(function(e){ return e.Incongruent;}); 

     var formatCount = d3.format(",.0f"); 

     var svg = d3.select("svg"), 
      margin = {top: 10, right: 30, bottom: 30, left: 30}, 
      width = +svg.attr("width") - margin.left - margin.right, 
      height = +svg.attr("height") - margin.top - margin.bottom, 
      g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

     var x = d3.scaleLinear() 
      .rangeRound([0, width]) 
      .domain([8, 36]); 

     var bins1 = d3.histogram() 
      .domain(x.domain()) 
      .thresholds(x.ticks(40)) 
      (allCongruentData); 

     // var line = d3.line() 
     //  .x(function(d) { return ???; }) 
     //  .y(function(d) { return y(d.Congruent); }) 
     //  .curve(d3.curveCatmullRom.alpha(0.5)); 

     var bins2 = d3.histogram() 
      .domain(x.domain()) 
      .thresholds(x.ticks(40)) 
      (allIncongruentData); 

     var y = d3.scaleLinear() 
      .domain([0, d3.max(bins1, function(d) { return d.length; })]) 
      .range([height, 0]); 

     var bar1 = g.selectAll(".bar1") 
     .data(bins1) 
     .enter().append("g") 
      .attr("class", "bar1") 
      .attr("transform", function(d) { return "translate(" + x(d.x0) + "," + y(d.length) + ")"; }); 

     bar1.append("rect") 
      .attr("x", 0.5) 
      .attr("width", x(bins1[0].x1) - x(bins1[0].x0) - 1) 
      .attr("height", function(d) { return height - y(d.length); }); 


     var bar2 = g.selectAll(".bar2") 
     .data(bins2) 
     .enter().append("g") 
      .attr("class", "bar2") 
      .attr("transform", function(d) { return "translate(" + x(d.x0) + "," + y(d.length) + ")"; }); 

     bar2.append("rect") 
      .attr("x", 0.5) 
      .attr("width", x(bins2[0].x1) - x(bins2[0].x0) - 1) 
      .attr("height", function(d) { return height - y(d.length); }); 

     bar1.append("text") 
      .attr("dy", ".75em") // why? 
      .attr("y", 6) 
      .attr("x", (x(bins1[0].x1) - x(bins1[0].x0))/2) 
      .attr("text-anchor", "middle") 
      .text(function(d) { return formatCount(d.length); }); 

     bar2.append("text") 
      .attr("dy", ".75em") // why? 
      .attr("y", 6) 
      .attr("x", (x(bins2[0].x1) - x(bins2[0].x0))/2) 
      .attr("text-anchor", "middle") 
      .text(function(d) { return formatCount(d.length); }); 

     g.append("g") 
      .attr("class", "axis axis--x") 
      .attr("transform", "translate(0," + height + ")") 
      .call(d3.axisBottom(x)); 

     var legend = svg.append("g") 
       .attr("class", "legend") 
       .attr("transform", "translate(" + (width - 245) + "," + 40 + ")") 
       .selectAll("g") 
       .data(["Congruent", "Incongruent"]) 
       .enter().append("g"); 

      legend.append("text") 
       .attr("y", function(d, i) { 
        return i * 30 + 5; 
       }) 
       .attr("x", 200) 
       .text(function(d) { 
        return d; 
       }); 

      legend.append("rect") 
       .attr("y", function(d, i) { 
        return i * 30 - 8; 
       }) 
       .attr("x", 167) 
       .attr("width", 20) 
       .attr("height", 20) 
       .attr("fill", function(d) { 
        if (d == "Congruent") { 
         return 'rgba(0,0,255,0.6'; 
        } else { 
         return 'rgba(255,0,0,0.6'; 
        } 
       }); 

     // g.append("path") 
     //  .datum(data) 
     //  .attr("d", line); 

    } 
    </script> 
    </head> 
    <body> 
    <h1>Stroop Test</h1> 
    <svg width="960" height="500"></svg> 
    <script type="text/javascript"> 
     d3.csv("stroopdata.csv", function(d) { 
      d.Congruent = +d.Congruent; 
      d.Incongruent = +d.Incongruent; 
      return d; 
     }, draw); 
    </script> 
    </body> 
</html> 

的數據是這樣的:

Congruent,Incongruent 
12.079,19.278 
16.791,18.741 
9.564,21.214 

任何幫助表示讚賞。

回答

1

你在想這件事。這是簡單的:

var line = d3.line() 
     .x(function(d) { return x((d.x0 + d.x1)/2); }) 
     .y(function(d) { return y(d.length); }) 
     .curve(d3.curveCatmullRom.alpha(0.5)); 

    g.append("path") 
    .attr("d", line(bins1)) 
    .attr("class", "bins1"); 

    g.append("path") 
    .attr("d", line(bins2)) 
    .attr("class", "bins2"); 

運行代碼:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <meta charset="utf-8"> 
 
    <style> 
 
    .bar1 rect { 
 
     fill: rgba(0, 0, 255, 0.6); 
 
    } 
 
    
 
    path.bins1 { 
 
     stroke: rgba(0, 0, 255, 0.6); 
 
     stroke-width: 4px; 
 
     fill: none; 
 
    } 
 
    
 
    .bar1:hover rect { 
 
     fill: rgba(0, 0, 255, 0.9); 
 
    } 
 
    
 
    .bar1 text { 
 
     fill: #fff; 
 
     font: 10px sans-serif; 
 
    } 
 
    
 
    .bar2 rect { 
 
     fill: rgba(255, 0, 0, 0.6); 
 
    } 
 
    
 
    path.bins2 { 
 
     stroke: rgba(255, 0, 0, 0.6); 
 
     stroke-width: 4px; 
 
     fill: none; 
 
    } 
 
    
 
    .bar2:hover rect { 
 
     fill: rgba(255, 0, 0, 0.9); 
 
    } 
 
    
 
    .bar2 text { 
 
     fill: #fff; 
 
     font: 10px sans-serif; 
 
    } 
 
    </style> 
 
    <script src="https://d3js.org/d3.v4.min.js"></script> 
 

 
    <script> 
 
    function draw(data) { 
 

 
     var allCongruentData = data.map(function(e) { 
 
     return e.Congruent; 
 
     }); 
 
     var allIncongruentData = data.map(function(e) { 
 
     return e.Incongruent; 
 
     }); 
 

 
     var formatCount = d3.format(",.0f"); 
 

 
     var svg = d3.select("svg"), 
 
     margin = { 
 
      top: 10, 
 
      right: 30, 
 
      bottom: 30, 
 
      left: 30 
 
     }, 
 
     width = +svg.attr("width") - margin.left - margin.right, 
 
     height = +svg.attr("height") - margin.top - margin.bottom, 
 
     g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
     var x = d3.scaleLinear() 
 
     .rangeRound([0, width]) 
 
     .domain([8, 36]); 
 

 
     var bins1 = d3.histogram() 
 
     .domain(x.domain()) 
 
     .thresholds(x.ticks(40)) 
 
     (allCongruentData); 
 

 
     var line = d3.line() 
 
      .x(function(d) { return x((d.x0 + d.x1)/2); }) 
 
      .y(function(d) { return y(d.length); }) 
 
      .curve(d3.curveCatmullRom.alpha(0.5)); 
 

 
     var bins2 = d3.histogram() 
 
     .domain(x.domain()) 
 
     .thresholds(x.ticks(40)) 
 
     (allIncongruentData); 
 

 
     var y = d3.scaleLinear() 
 
     .domain([0, d3.max(bins1, function(d) { 
 
      return d.length; 
 
     })]) 
 
     .range([height, 0]); 
 

 
     var bar1 = g.selectAll(".bar1") 
 
     .data(bins1) 
 
     .enter().append("g") 
 
     .attr("class", "bar1") 
 
     .attr("transform", function(d) { 
 
      return "translate(" + x(d.x0) + "," + y(d.length) + ")"; 
 
     }); 
 
     
 
     g.append("path") 
 
     .attr("d", line(bins1)) 
 
     .attr("class", "bins1"); 
 

 
     bar1.append("rect") 
 
     .attr("x", 0.5) 
 
     .attr("width", x(bins1[0].x1) - x(bins1[0].x0) - 1) 
 
     .attr("height", function(d) { 
 
      return height - y(d.length); 
 
     }); 
 

 

 
     var bar2 = g.selectAll(".bar2") 
 
     .data(bins2) 
 
     .enter().append("g") 
 
     .attr("class", "bar2") 
 
     .attr("transform", function(d) { 
 
      return "translate(" + x(d.x0) + "," + y(d.length) + ")"; 
 
     }); 
 
     
 
     g.append("path") 
 
     .attr("d", line(bins2)) 
 
     .attr("class", "bins2"); 
 

 
     bar2.append("rect") 
 
     .attr("x", 0.5) 
 
     .attr("width", x(bins2[0].x1) - x(bins2[0].x0) - 1) 
 
     .attr("height", function(d) { 
 
      return height - y(d.length); 
 
     }); 
 

 
     bar1.append("text") 
 
     .attr("dy", ".75em") // why? 
 
     .attr("y", 6) 
 
     .attr("x", (x(bins1[0].x1) - x(bins1[0].x0))/2) 
 
     .attr("text-anchor", "middle") 
 
     .text(function(d) { 
 
      return formatCount(d.length); 
 
     }); 
 

 
     bar2.append("text") 
 
     .attr("dy", ".75em") // why? 
 
     .attr("y", 6) 
 
     .attr("x", (x(bins2[0].x1) - x(bins2[0].x0))/2) 
 
     .attr("text-anchor", "middle") 
 
     .text(function(d) { 
 
      return formatCount(d.length); 
 
     }); 
 

 
     g.append("g") 
 
     .attr("class", "axis axis--x") 
 
     .attr("transform", "translate(0," + height + ")") 
 
     .call(d3.axisBottom(x)); 
 

 
     var legend = svg.append("g") 
 
     .attr("class", "legend") 
 
     .attr("transform", "translate(" + (width - 245) + "," + 40 + ")") 
 
     .selectAll("g") 
 
     .data(["Congruent", "Incongruent"]) 
 
     .enter().append("g"); 
 

 
     legend.append("text") 
 
     .attr("y", function(d, i) { 
 
      return i * 30 + 5; 
 
     }) 
 
     .attr("x", 200) 
 
     .text(function(d) { 
 
      return d; 
 
     }); 
 

 
     legend.append("rect") 
 
     .attr("y", function(d, i) { 
 
      return i * 30 - 8; 
 
     }) 
 
     .attr("x", 167) 
 
     .attr("width", 20) 
 
     .attr("height", 20) 
 
     .attr("fill", function(d) { 
 
      if (d == "Congruent") { 
 
      return 'rgba(0,0,255,0.6'; 
 
      } else { 
 
      return 'rgba(255,0,0,0.6'; 
 
      } 
 
     }); 
 

 
     // g.append("path") 
 
     //  .datum(data) 
 
     //  .attr("d", line); 
 

 
    } 
 
    </script> 
 
</head> 
 

 
<body> 
 
    <h1>Stroop Test</h1> 
 
    <svg width="960" height="500"></svg> 
 
    <script type="text/javascript"> 
 
    
 
    var data = []; 
 
    for (var i = 0; i < 50; i++){ 
 
     data.push({ 
 
     Congruent: (Math.random() * (36 - 8)) + 8, 
 
     Incongruent: (Math.random() * (36 - 8)) + 8 
 
     }) 
 
    } 
 
    draw(data); 
 
    
 
    /* 
 
    d3.csv("stroopdata.csv", function(d) { 
 
     d.Congruent = +d.Congruent; 
 
     d.Incongruent = +d.Incongruent; 
 
     return d; 
 
    }, draw); 
 
    */ 
 
    
 
    </script> 
 
</body> 
 

 
</html>

+0

非常感謝。我學到了新的東西:)但是,現在我知道我犯了一個錯誤:我在談論分佈曲線:像這樣:http://www.statmethods.net/graphs/images/histogram3.jpg - 我更新了我的問題。再次抱歉! –

+0

我將問題改回「行」並將其標記爲已解決。我在這裏發佈了關於曲線的另一個問題:http://stackoverflow.com/questions/41248649/d3-js-how-to-add-distribution-curves-to-histograms-in-version-4 –