2014-10-29 22 views
0

我想通過使用Twitter數據分析刷牙學習d3.js重點+上下文。我試圖從給出的數據中生成時間序列圖,但是它不會像應該那樣提供。我創造了小提琴。有人可以看看它,並給我一個關於如何解決這個問題的建議嗎?D3.js重點+上下文通過刷牙

var margin = {top: 10, right: 10, bottom: 100, left: 40}, 
     margin2 = { top: 430, right: 10, bottom: 20, left: 40}, 
     width = 960 - margin.left - margin.right, 
     height = 500 - margin.top - margin.bottom, 
     height2 = 500 - margin2.top - margin2.bottom; 

    var parseDate = d3.time.format("%Y-%m-%d %I:%M:%S").parse; 

    var x = d3.time.scale().range([0, width]), 
     x2 = d3.time.scale().range([0, width]), 
     y = d3.scale.linear().range([height, 0]), 
     y2 = d3.scale.linear().range([height2, 0]); 

    var xAxis = d3.svg.axis().scale(x).orient("bottom"), 
     xAxis2 = d3.svg.axis().scale(x2).orient("bottom"), 
     yAxis = d3.svg.axis().scale(y).orient("left"); 

    var brush = d3.svg.brush() 
     .x(x2) 
     .on("brush", brushed); 

    var area = d3.svg.area() 
     .interpolate("monotone") 
     .x(function(d) { return x(d.date); }) 
     .y0(height) 
     .y1(function(d) { return y(d.count); }); 

    var area2 = d3.svg.area() 
     .interpolate("monotone") 
     .x(function(d) { return x2(d.date); }) 
     .y0(height2) 
     .y1(function(d) { return y2(d.count); }); 

    var svg = d3.select(".trend-graph").append("svg") 
     .attr("width", width + margin.left + margin.right) 
     .attr("height", height + margin.top + margin.bottom); 

    svg.append("defs").append("clipPath") 
     .attr("id","clip") 
     .append("rect") 
     .attr("width", width) 
     .attr("height", height); 

    var focus = svg.append("g") 
     .attr("class", "focus") 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

    var context = svg.append("g") 
     .attr("class", "context") 
     .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")"); 

    d3.csv("/TwitterProject/slides/results.csv", type, function(error, data){ 

     x.domain(d3.extent(data.map(function(d) { return d.date; }))); 
     y.domain([0, d3.max(data.map(function(d) { return d.count; }))]) 
     x2.domain(x.domain()); 
     y2.domain(y.domain()); 

     focus.append("path") 
      .datum(data) 
      .attr("class", "area") 
      .attr("d", area); 

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

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

     context.append("path") 
      .datum(data) 
      .attr("class","area") 
      .attr("d", area2); 

     context.append("g") 
      .attr("class", "x axis") 
      .attr("transform", "translate(0," + height2 + ")") 
      .call(xAxis2); 

     context.append("g") 
      .attr("class", "x brush") 
      .call(brush) 
     .selectAll("rect") 
      .attr("y", -6) 
      .attr("height", height2 + 7); 

    }); 

    function brushed(){ 

     x.domain(brush.empty() ? x2.domain() : brush.extent()); 
     focus.select(".area").attr("d", area); 
     focus.select(".x.axis").call(xAxis); 
    } 

    function type(d) { 
     d.date = parseDate(d.date); 
     d.count = +d.count;  
     return d; 
    } 

JSFiddle

此外,y軸示出了錯誤。我認爲問題在於每分鐘計數「計數」的地方,但我無法弄清楚如何解決這個問題。

情節應該看起來像這樣。

enter image description here

編輯:

改變我做:

var bins = {}; 

x.domain(d3.extent(data.map(function(d) { return d.date; }))); 
//y.domain([0, d3.max(data.map(function(d) { return d.count; }))]). 
y.domain([0, bins]).range([height, 0]); 
x2.domain(x.domain()); 
y2.domain(y.domain()).range([height2, 0]); 

function type(d) { 
    d.date = parseDate(d.date); 
    d.count = +d.count;  
    var key = d.date.toDateString(); 
    bins[key] = bins[key] || 0; 
    bins[key] += d.count; 
    console.log(bins); 
    return d; 
} 
+0

對我來說看起來不錯,因爲在您的數據完全按原樣繪製。您可能想考慮對其進行分箱以獲得更像您想要的圖表的東西。 – 2014-10-29 09:57:44

+0

@LarsKotthoff,謝謝你的回覆。由於我是d3.js的新手,我不確定如何進行分檔。我發現這個http://stackoverflow.com/questions/19408296/how-can-i-sum-binned-time-series-using-d3-js,但我不清楚你做了什麼,什麼「交易」是在我的情況。 – user1828605 2014-10-29 11:36:57

+0

那裏的交易會有你的情況下的推文。 – 2014-10-29 11:45:27

回答

1

您的數據的一秒的分辨率,所以你會得到一個非常嘈雜的圖(其實準確你會得到什麼)。您可能想要進行一些分箱操作,將數據聚合在一起以減少噪音。

原則上,代碼如下所示(以總按分鐘):

function type(d) { 
    d.date = parseDate(d.date); 
    d.count = +d.count; 
    d.date.setSeconds(0); 
    var key = df(d.date);   
    bins[key] = bins[key] || 0; 
    bins[key] += d.count; 
    return d; 
} 

,然後裏面d3.csv

var binData = d3.entries(bins); 
    binData.forEach(function(d) { d.key = parseDate(d.key); }); 
    binData.sort(function(a,b) { return b.key - a.key; }); 

有一點額外的克魯夫特,因爲Date對象別與關聯數組鍵一樣好。現在您可以使用key(日期)和value中的元素binData,您可以使用該元素創建圖表。

完整演示here

+0

很好的答案。感謝您的幫助。 – user1828605 2014-10-29 15:17:17