2014-07-25 55 views
1

我目前正在運行一個頁面,該頁面會在加載頁面時生成具有默認值的圖形。該頁面從PHP腳本生成的TSV中獲取數據,並通過GET參數進行修改。刪除d3.js中的前一個路徑並轉換爲新數據

用戶可以輸入選項,並通過AJAX更新圖形。

目前該頁面幾乎可以正常工作,但它是用新數據覆蓋新路徑而不刪除舊路徑。

新數據具有相同的x範圍和域但不同的y座標值,有時具有不同數量的值。

理想情況下,我希望舊路徑從舊路徑流暢地過渡 - 我如何使這種情況發生?

我試着在下面包含相關代碼。對於質量差的道歉,我對d3非常陌生。

... 

var line = d3.svg.line() 
    .interpolate("basis") 
    .defined(function(d) { 
     return d.result != 0; 
    }) 
    .x(function(d) { 
     return x(d.date); 
    }) 
    .y(function(d) { 
     return y(d.result); 
    }); 

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

var txtDays = 7; 
var txtStartDate = "01/01/2013"; 
var txtEndDate = "01/01/2014"; 
var txtInterval = 1; 

requestDataURL = //removed for SO 


    d3.tsv("http://localhost" + requestDataURL, function(error, data) { 
     var varPolls = d3.keys(data[0]).filter(function(key) { 
      return key !== "date"; 
     }); 

     data.forEach(function(d) { 
      d.date = parseDate(d.date); 
     }); 

     var results = varPolls.map(function(name) { 
      return { 
       name: name, 
       values: data.map(function(d) { 
        return { 
         date: d.date, 
         result: +d[name] 
        }; 
       }) 
      }; 
     }); 


     x.domain(d3.extent(data, function(d) { 
      return d.date; 
     })); 



     svg.append("g") 
      .attr("class", "x axis") 
      .attr("transform", "translate(0," + height + ")") 
      .call(xAxis); 

     svg.append("g") 
      .attr("class", "y axis") 
      .call(yAxis) 

     var group = svg.selectAll(".group") 
      .data(results) 
      .enter().append("g") 
      .attr("class", "group") 
      .attr("data-name", function(d) { 
       return d.name; 
      }); 

     group.append("path") 
      .attr("class", "line") 
      .attr("d", function(d) { 
       return line(d.values); 
      }) 
      .style("stroke", function(d) { 
       return colors[d.name]; 
      }); 

     group.append("text") 
      .datum(function(d) { 
       return { 
        name: d.name, 
        value: d.values[d.values.length - 1] 
       }; 
      }) 
      .attr("transform", function(d) { 
       return "translate(" + x(d.value.date) + "," + y(d.value.result) + ")"; 
      }) 
      .attr("x", 3) 
      .attr("dy", ".35em") 
      .text(function(d) { 
       return Math.round(d.value.result);; 
      }); 

     d3.select(".submit") 
      .attr('disabled', null); 


    }); 

$(".submit").click(function(event) { 
    var data = []; 
    //SORT OUT VALIDATION 


    var req = $.ajax({ 
     url: requestDataURL, 
     dataType: 'text', 
     success: function(response) { 
      data = response; 
     } 
    }); 

    requestDataURL = //new data removed for SO 

     $.when(req).done(function() { 
      d3.tsv("http://localhost" + requestDataURL, function(error, data) { 

       var varPolls = d3.keys(data[0]).filter(function(key) { 
        return key !== "date"; 
       }); 

       data.forEach(function(d) { 
        d.date = parseDate(d.date); 
       }); 

       var results = varPolls.map(function(name) { 
        return { 
         name: name, 
         values: data.map(function(d) { 
          return { 
           date: d.date, 
           result: +d[name] 
          }; 
         }) 
        }; 
       }); 


       x.domain(d3.extent(data, function(d) { 
        return d.date; 
       })); 


       var group = svg.selectAll(".chart") 
        .data(results); 

       group.exit().remove(); 

       group.enter().append("g"); 
       group.attr("class", "group") 
        .attr("data-name", function(d) { 
         return d.name; 
        }); 

       group.append("path") 
        .attr("class", "line") 
        .attr("d", function(d) { 
         return line(d.values); 
        }) 
        .style("stroke", function(d) { 
         return colors[d.name]; 
        }); 




       group.transition() 
        .duration(500) 
        .ease("linear") 
        .attr("d", group); 

      }); 

     }); 
}); 

回答

1

問題是您沒有正確處理輸入和更新選擇。通常,追加操作只應發生在輸入選擇上,而不是更新。當你獲得新的數據,你有下面的代碼:

group.enter().append("g"); 
// ... 
group.append("path"); 

這將追加新path元素,以更新選擇,這是你在圖中看到的。處理新數據將如下的正確方法如下:

var enterSel = group.enter().append("g"); 
// set attributes on the g elements 
enterSel.append("path"); // append path elements to the new g elements 

group.select("path") // select the path elements that are present, this includes the newly appended ones 
    .attr("d", function(d) { // update the d attribute 
     return line(d.values); 
    }); 

該代碼將追加對沒有對應元素和現有元素更新path數據項目新的元素。

+0

感謝您的幫助,我當然在概念上對d3感到困惑。我試過這個,但無濟於事。最初有4個g元素,每個元素都有一個路徑,程序仍然追加4 g元素而沒有正確的新路徑。 – tom

+1

啊,看起來你的選擇器應該是'.group'而不是'.chart'。我會建議重構代碼以消除這種重複並避免這樣的問題。 –

+0

很好,非常感謝!應該看到我自己。重構是下一步非常需要的,只是非常渴望呈現原型。 – tom