2015-12-29 80 views
2

我無法制作顯示按周(和不同年份)數據組的正確圖形。dc.js /交叉過濾器尺寸(年/周)

僞SQL會給:

select sum ('task') 
group by 'year', 'week' (and maybe later 'site') 

我的數據看起來或多或少是這樣的:

{ "date" : "20150427", "week" : 18, "site" : "a" "task" : 3, } 
{ "date" : "20150427", "week" : 18, "site" : "b" "task" : 4, } 
{ "date" : "20150427", "week" : 18, "site" : "c" "task" : 2, } 
{ "date" : "20150427", "week" : 18, "site" : "d" "task" : 3, } 
{ "date" : "20150428", "week" : 18, "site" : "a" "task" : 3, } 
{ "date" : "20150428", "week" : 18, "site" : "b" "task" : 3, } 
{ "date" : "20150429", "week" : 18, "site" : "c" "task" : 2, } 
{ "date" : "20150429", "week" : 18, "site" : "d" "task" : 3, } 
{ "date" : "20140512", "week" : 20, "site" : "d" "task" : 6, } 
{ "date" : "20140512", "week" : 20, "site" : "a" "task" : 6, } 
{ "date" : "20140513", "week" : 20, "site" : "b" "task" : 4, } 
{ "date" : "20140513", "week" : 20, "site" : "c" "task" : 1, } 
{ "date" : "20140519", "week" : 21, "site" : "b" "task" : 2, } 
{ "date" : "20140519", "week" : 21, "site" : "c" "task" : 1, } 
{ "date" : "20140519", "week" : 21, "site" : "d" "task" : 3, } 
{ "date" : "20140519", "week" : 21, "site" : "a" "task" : 1, } 
{ "date" : "20140520", "week" : 21, "site" : "b" "task" : 2, } 
{ "date" : "20140520", "week" : 21, "site" : "c" "task" : 3, } 
{ "date" : "20140520", "week" : 21, "site" : "d" "task" : 1, } 
{ "date" : "20140520", "week" : 21, "site" : "a" "task" : 1, } 

這是我的數據的樣本,它可以有不同的年份,網站或任務

我試過了,它不起作用,因爲barChart累積了所有年份的周:

d3.json("/graph", function(dataJson) { 


var dataTable = dc.dataTable("#dc-table-graph"); 
var barChart = dc.barChart("#chart-bar-ordersperweek"); 

var data = dataJson; 
var dateFormat = d3.time.format("%Y%m%d"); 
data.forEach(function (d) { d.date = dateFormat.parse(d.date); }); 


//dimension 
var dateDim = ndx.dimension(function (d) { return d.date; }); 
var weekDim = ndx.dimension(function(d) {return d.week;}); 

//group 
var orderByWD = weekDim.group().reduceSum(function (d) { return d.task; }); 


barChart 
    .width(1000).height(250) 
    .dimension(weekDim) 
    .group(orderByWD) 
    .x(d3.scale.ordinal().domain(d3.range(minWeek.week-1,maxWeek.week+1))) 
    .xUnits(dc.units.ordinal) 
    .y(d3.scale.linear().domain([0, 6000])) 
    .margins({top: 20, right: 30, bottom: 50, left: 80}) 
    .label(function(d) { return d.value}) 
    ; 


dataTable.width(800).height(800) 
     .dimension(dateDim)  
     .group(function (d) { return 'Week ' + d.week}) 
     .size(5000) 
     .columns([ 
      function (d) { var format = d3.format('02d'); 
       return d.date.getFullYear() +'/'+ format(d.date.getMonth()+1) + '/' + format(d.date.getDate()); }, 
      function (d) { return d.week; }, 
      function (d) { return d.site; }, 
      function (d) { return d.task; } 
     ]) 
     .sortBy(function (d) { return Number(d.date) + d.task; }) 
     .order(d3.descending); 

     dataTable.on('renderlet', function(chart){ 
      chart.selectAll('.dc-table-group').classed('info',true); 
     }); 

dc.renderAll(); 

我的目標是總結同一周發生的所有任務,並將其繪製到行圖中,當我選擇一週更新所選星期的數據表時。

在dataTable中我怎麼總結(累積)按網站分組的任務?

感謝所有幫助

編輯 我有添加的jsfiddle https://jsfiddle.net/d4qsd8wh/

+0

我認爲基於尺寸,而不是組dataTable的運行,所以你可能需要創建一個假的維度,返回要顯示的記錄。如果你使用jsfiddle或類似的東西來組裝一個工作示例,我或其他人可能會爲你工作。 –

+0

我只是將它加入 https://jsfiddle.net/d4qsd8wh/ – okuteur

回答

0

D3有一些非常強大的工具來幫助你塑造您的數據。這只是一個例子。通過使年+周的關鍵,我們可以總結的任務

var out = d3.nest() 
    .key(function(d) { return d.date.substring(0,4)+d.week; }) 
    .rollup(function(v) { return { 
     date: v[0].date, 
     task: d3.sum(v, function(d) { return d.task; }) 
    }; 
    }) 
    .entries(data); 

這將使out對象的數組,看起來像這樣。

[ 
    { 
    "key": "201420", 
    "values": { 
     "date": "20140512", 
     "task": 17 
    } 
    }, 
    { 
    "key": "201421", 
    "values": { 
     "date": "20140519", 
     "task": 14 
    } 
    }, 
    { 
    "key": "201518", 
    "values": { 
     "date": "20150427", 
     "task": 23 
    } 
    } 
] 

既然你是按周分組然後將日期大多是任意的,我只是它顯示分組日期列表中的第一個。您也可以將第一個.key下的另一個.key(function(d) { return d.site; }添加到網站的子組中。

1

所以,你想要做的是爲dataTable創建一個虛假的「維度」。在當前的方法,你可以做這樣的:DataTable中

// Actually a dimension keyed on week and site 
var fakeDateDim = { 
    top: function(d) { 
    var m = dc.d3.map(); 
    dateDim.top(Infinity).forEach(function(g) { 
     if(m.has(g.week + g.site)) { 
     m.get(g.week + g.site).task += g.task 
     } else { 
     // Create the "record" 
     m.set(g.week + g.site, { 
      week: g.week, 
      site: g.site, 
      task: g.task 
     }) 
     } 
    }) 

    return m.values(); 
    } 
} 

然後,使用在當前的dateDim的地方fakeDateDim。 (您還必須刪除表列日期和星期。)

這裏的基礎上,比如你把一個工作示例:https://jsfiddle.net/s2c9rhxw/

注意,您可以使用d3.nest,正如上文@ ian-h的答案,但是它掩蓋了你正在做的一些事情,所以我認爲使用低級構造如Map或d3.map可能會更好,直到你對計算感到滿意爲止。無論您如何實際執行計算,關鍵在於將其包裝在dc.js可以使用的假維對象中。

+0

是解決我的問題的另一部分。 – okuteur

1

我不知道我是否有問題,因爲其他答案似乎解決了不同的問題。我會假設你只是問在你的領域的一週沒有指定年份的時候,如何讓每週一週的工作 - 所以你可以從不同的年份堆積成一個星期。

換句話說,我解釋這是你的問題的心臟:

我嘗試這樣做,這是行不通的,因爲BARCHART累加所有年份

其中ISN的一週真的不是關於數據表,而是barChart。

要回答這個問題:是的,我想你week場是無用的。相反,按周使用解析日期和d3.time.week以斌:

var weekDim = ndx.dimension(function(d) {return d3.time.week(d.date);}); 

然後設置您的條形圖使用日期單位,而不是序數:

barChart 
    ... 
    .x(d3.time.scale()) 
    .xUnits(d3.time.weeks) 
    .elasticX(true) // or calculate minWeek/maxWeek using date objects 

什麼d3.time.week呢,像其他d3 time interval functions,是返回間隔開始的日期。 (由於d3.time.weekd3.time.sunday的代名詞,它返回上週日午夜每個日期前 - 使用d3.time.monday如果您想根據週一周來代替。)裁剪每個日期的時間間隔的開始是斌的好辦法沒有忘記日期這是他們的一部分。

然後d3.time.weeks(注意s)是一個相關函數,可以計算任何時間範圍內的間隔數(周)。 dc.js需要xUnits計數功能才能確定要顯示的小節數。

既然你已經得到了答案,三個不同的問題,你可能要花費一分鐘煉你的下一個問題,以確保它是明確的。

+0

我認爲可能有多個問題。也許我們可以拼湊一個綜合性的答案:-) –

+0

好了,這解決我的問題:) 的一部分,但我怎麼能界定「星期一」作爲一週的開始(目前星期日是第一天)? _is this part d3.time.week(d.date)_ 感謝您的幫助Gordon – okuteur

+0

太好了,我希望其他一些答案也有幫助! [d3.time.week](https://github.com/mbostock/d3/wiki/Time-Intervals#week)只是'd3.time.sunday'的同義詞,所以你應該可以使用'd3。 time.monday'來得到你想要的。我會澄清上面的內容。 – Gordon

0

您需要創建weekDim如下:

var weekDim = ndx.dimension(function(d) { 
    return d.date.substring(0,4) + "" + d.week; 
}); 

,然後在這個維度創建組,如下所示:

function reduceAdd(p, v) { 
    return p + v.task; 
} 

function reduceRemove(p, v) { 
    return p - v.task; 
} 

function reduceInitial() { 
    return 0; 
} 
var m = weekDim.group().reduce(reduceAdd,reduceRemove,reduceInitial); 

和你得到的結果作爲m.top(無窮大)。 我不知道你如何使用這個數據表,但上面的輸出將正是你想要的。 希望這有助於

+0

對不起,但我不認爲這有幫助。這個減少等價於問題中的'reduceSum',而d3有更好的處理時間的方法。感謝您的貢獻! – Gordon