2016-12-01 123 views
0

我有兩個問題,我正在努力理解或解決我的以下d3代碼(顯示問題的最簡單版本)。背景是,我試圖從csv文件中繪製線條(整個內容粘貼在最後,完整的代碼也在下面運行)。前2行(說明CSV格式)爲:d3多重線條圖

date,cust,prod,units 
2012-04-01,team1,A,34 

基本上有客戶(TEAM1,TEAM2,team3)的產品即購買單元(A,B,C,d)。我正在嘗試繪製由產品(A,B,C,D)過濾的線圖。這個獨立工作。然而,由於單位和日期範圍因產品而異(A,B,C,D),我首先嚐試將我的範圍修改爲最大日期範圍和最大銷售單位。當我這樣做時,軸看起來是正確的,但圖形沒有繪製。如果我只使用過濾的數據,圖表工作正常。我錯過了什麼?我在控制檯中看不到任何JS錯誤。我的下一個目標是添加和刪除圖形(通過複選框)而不重繪任何東西,最簡單的方法是什麼?

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> /* set the CSS */ 

#line1 { 
    fill: none; 
    stroke: steelblue; 
    stroke-width: 1px; 
} 

</style> 

<div id="customer"> 

    <input class="custCB" type="checkbox" id="D_CB" name="cust" value="D" enabled onclick="showGraph('D')"> D<br> 
    <input class="custCB" type="checkbox" id="C_cb" name="cust" value="C" enabled onclick="showGraph('C')"> C<br> 
    <input class="custCB" type="checkbox" id="B_cb" name="cust" value="B" enabled onclick="showGraph('B')"> B<br> 
    <input class="custCB" type="checkbox" id="A_cb" name="cust" value="A" enabled onclick="showGraph('A')"> A<br> 
</div> 
<body> 

<!-- load the d3.js library --> 
<script src="https://d3js.org/d3.v4.min.js"></script> 
<script> 
    showGraph("D"); 

    function showGraph(prod_name) { 
    var mydomain = 5000; 
    var margin = {top: 20, right: 20, bottom: 30, left: 50}, 
      width = 960 - margin.left - margin.right, 
      height = 500 - margin.top - margin.bottom; 
    // parse the date/time 
    var parseTime = d3.timeParse("%Y-%m-%d"); 
    // set the ranges 
    var x = d3.scaleTime().range([0, width]); 
    var y = d3.scaleLinear().domain([mydomain, 0]).range([height, 0]); 
    //console.log(y); 
    // define the 1st line 
    var valueline = d3.line() 
      .x(function (d) { 
       return x(d.date); 
      }) 
      .y(function (d) { 
       return y(d.units); 
      }); 

    d3.select("svg").remove(); 
    var svg = d3.select("body").append("svg") 
      .attr("width", width + margin.left + margin.right) 
      .attr("height", height + margin.top + margin.bottom) 
      .append("g") 
      .attr("id", "parentgroup") 
      .attr("transform", 
      "translate(" + margin.left + "," + margin.top + ")"); 


    // Get the data 
    d3.csv("test2.csv", function (error, tdata) { 

     if (error) throw error; 

     data = tdata.filter(e=> e.prod===prod_name); 
     //_data = data.filter(e=> e.cust==="team2"); 
     //console.log("__data_", _data); 
     // format the data 
     console.log("data:", data); 

     data.forEach(function (d) { 
      d.date = parseTime(d.date); 
      d.units = parseInt(d.units); 
     }); 
     tdata.forEach(function (d) { 
      d.date = parseTime(d.date); 
      d.units = parseInt(d.units); 
     }); 
     x.domain(d3.extent(tdata, function (d) { 
      console.log(d.date); 
      return d.date; 
     })); 
     //console.log("data", data); 
     var m = d3.max(tdata, function (d) { 
      console.log(d.units); 
      var m = parseInt(d.units); 
      return m; 
     }); 
     console.log("Max:", m); 
     y.domain([0, m]); 
     console.log("tdata:", tdata); 
     //console.log("data:", data); 
     svg.append("path") 
       .data([data]) 
       .attr("id", "line1") 
       .attr("d", valueline); 
     //console.log("DATA", data); 
     svg.selectAll(".point") 
       .data(data) 
       .enter() 
       .append("circle") 
       .attr("class", "point") 
       .attr("cx", function (d) { 
        return x(d.date); 
       }) 
       .attr("cy", function (d) { 
        return y(d.units); 
       }) 
       .attr("r", 4) 
       .on("mouseover", function (d) { 
        console.log(d.units) 
       }); 

     svg.append("g") 
       .attr("id", "xaxis") 
       .attr("transform", "translate(0," + height + ")") 
       .call(d3.axisBottom(x)); 

     // Add the Y Axis 
     svg.append("g") 
       .attr("id", "yaxis") 
       .call(d3.axisLeft(y)); 

    }); 
    } 

</script> 
</body> 

test2.csv 
date,cust,prod,units 
2012-04-01,team1,A,34 
2012-04-02,team1,B,45 
2012-04-03,team2,D,67 
2012-04-04,team1,A,78 
2012-04-05,team3,C,89 
2012-04-06,team2,D,99 
2012-04-07,team2,A,101 
2012-04-08,team3,A,122 
2012-04-09,team1,C,134 
2012-04-10,team1,C,160 
2012-04-11,team2,C,180 
2012-04-12,team2,D,210 
2012-04-13,team3,D,223 
2012-04-14,team1,D,229 
2012-04-15,team1,D,241 
2012-04-16,team2,D,258 
2012-04-17,team2,C,350 
2012-04-18,team3,D,305 
2012-04-19,team3,B,335 
2012-04-20,team2,B,375 
2012-04-21,team3,D,345 
2012-04-22,team1,A,534 
2012-04-23,team1,C,578 
2012-04-24,team2,A,590 
2012-04-25,team1,B,601 
2012-04-26,team3,B,387 
2012-04-27,team2,C,613 
2012-04-28,team2,D,645 
2012-04-29,team3,D,410 
2012-04-30,team1,A,612 
2012-05-01,team2,A,670 
2012-05-02,team3,A,657 
2012-05-03,team1,A,690 
2012-05-04,team3,A,709 
2012-05-05,team2,C,690 
2012-05-06,team3,B,740 
2012-05-07,team1,A,1000 

回答

1

這個片段是有問題的:

data.forEach(function (d) { 
    d.date = parseTime(d.date); 
    d.units = parseInt(d.units); 
}); 
tdata.forEach(function (d) { 
    d.date = parseTime(d.date); 
    d.units = parseInt(d.units); 
}); 

tdatadata是保持引用到相同的對象陣列。因此,第二個forEach然後對相同的對象起作用,並且parseTime失敗。只要做到:

tdata.forEach(function(d) { 
    d.date = parseTime(d.date); 
    d.units = parseInt(d.units); 
}); 

var data = tdata.filter(e => e.prod === prod_name); 

Here's your code all cleaned up.

+0

非常感謝,張貼後,我竟然想通了不久。 – user3079275