我剛開始dc.js,並期待在主網站在納斯達克例如:https://dc-js.github.io/dc.js/變化百分比/ crossfilter
我創建a Fiddle一些樣本僞數據,只是兩個相關的圖表這個問題。
與納斯達克例子類似,我想要有一個氣泡圖,Y軸是在不同圖表中由畫筆控制的時間範圍內的%變化值。對於NASDAQ示例的代碼執行以下操作:
var yearlyPerformanceGroup = yearlyDimension.group().reduce(
/* callback for when data is added to the current filter results */
function (p, v) {
++p.count;
p.absGain += v.close - v.open;
p.fluctuation += Math.abs(v.close - v.open);
p.sumIndex += (v.open + v.close)/2;
p.avgIndex = p.sumIndex/p.count;
p.percentageGain = p.avgIndex ? (p.absGain/p.avgIndex) * 100 : 0;
p.fluctuationPercentage = p.avgIndex ? (p.fluctuation/p.avgIndex) * 100 : 0;
return p;
},
/* callback for when data is removed from the current filter results */
function (p, v) {
--p.count;
p.absGain -= v.close - v.open;
p.fluctuation -= Math.abs(v.close - v.open);
p.sumIndex -= (v.open + v.close)/2;
p.avgIndex = p.count ? p.sumIndex/p.count : 0;
p.percentageGain = p.avgIndex ? (p.absGain/p.avgIndex) * 100 : 0;
p.fluctuationPercentage = p.avgIndex ? (p.fluctuation/p.avgIndex) * 100 : 0;
return p;
},
/* initialize p */
function() {
return {
count: 0,
absGain: 0,
fluctuation: 0,
fluctuationPercentage: 0,
sumIndex: 0,
avgIndex: 0,
percentageGain: 0
};
}
);
我目前解釋爲求和(關 - 開)對所有的數據和由平均每日平均指數的分裂。但這不是我熟悉的百分比變化公式。 (例如,(新老)/舊×100)
雖然它似乎爲納斯達克例如工作,我的數據會比較像下面這樣:
country_id,received_week,product_type,my_quantity,my_revenue,country_other_quantity
3,2017-04-02,1,1,361,93881
1,2017-04-02,4,45,140,93881
2,2017-04-02,4,2,30,93881
3,2017-04-02,3,1,462,93881
2,2017-04-02,3,48,497,93881
等。在許多月和product_types 。
假設我對計算特定國家的百分比變化感興趣。如何獲得給定國家的開始和結束數量,以便我可以將變化計算爲結束開始/開始* 100?
我在想的東西,如以下(假設我建立合適的尺寸和一切)
var country_dim = ndx.dimension(function (d) { return d['country_id']; })
var received_day_dim = ndx.dimension(function (d) { return d['received_day']; })
var date_min = received_day_dim.bottom(1)[0]['received_day']
var date_max = received_day_dim.top(1)[0]['received_day']
然後在我的自定義減少目前的例子(錯誤)的靜脈功能:
var statsByCountry = country_dim.group().reduce(
function (p, v) {
++p.count;
p.units += +v["my_units"];
p.example_rate = +v['my_units']/(v['quantity_unpacked']*90) //place holder for total units per day per country
p.sumRate += p.opp_buy_rate;
p.avgRate = p.opp_buy_rate/p.count;
p.percentageGain = p.avgRate ? (p.opp_buy_rate/p.avgRate) * 100 : 0;
p.dollars += +v["quantity_unpacked"]/2;
// p.max_date = v['received_week'].max();
// p.min_date
//dateDimension.top(Infinity)[dateDimension.top(Infinity).length - 1]['distance'] - dateDimension.top(Infinity)[0]['distance']
return p;
},
function (p, v) {
--p.count;
if (v.region_id > 2) {
p.test -= 100;
}
p.units -= +v["quantity_unpacked"];
p.opp_buy_rate = +v['quantity_unpacked']/(v['quantity_unpacked']*90) //place holder for total units per day per country
p.sumRate -= p.opp_buy_rate;
p.avgRate = p.count ? p.opp_buy_rate/p.count : 0;
p.percentageGain = p.avgRate ? (p.opp_buy_rate/p.avgRate) * 100 : 0;
p.dollars -= +v["quantity_unpacked"]/2;
// p.max_date = v['received_week'].max();
return p;
},
function() {
return {quantity_unpacked: 0,
count: 0,
units: 0,
opp_buy_rate: 0,
sumRate: 0,
avgRate: 0,
percentageGain: 0,
dollars: 0,
test: 0
};//, dollars: 0}
}
);
和我的圖表:
country_bubble
.width(990)
.height(250)
.margins({top:10, right: 50, bottom: 30, left:80})
.dimension(country_dim)
.group(statsByCountry)
.keyAccessor(function (p) {
return p.value.units;
})
.valueAccessor(function (p) { //y alue
return p.value.percentageGain;
})
.radiusValueAccessor(function (p) { //radius
return p.value.dollars/10000000;
})
.maxBubbleRelativeSize(0.05)
.elasticX(true)
.elasticY(true)
.elasticRadius(true)
.x(d3.scale.linear())
.y(d3.scale.linear())
// .x(d3.scale.linear().domain([0, 1.2*bubble_xmax]))
// .y(d3.scale.linear().domain([0, 10000000]))
.r(d3.scale.linear().domain([0, 10]))
.yAxisPadding('25%')
.xAxisPadding('15%')
.renderHorizontalGridLines(true)
.renderVerticalGridLines(true)
.on('renderlet', function(chart, filter){
chart.svg().select(".chart-body").attr("clip-path",null);
});
原本以爲具有在statsbycountry類似於以下內容:
if (v.received_day == date_min) {
p.start_value += v.my_quantity;
}
if (v.received_day == date_max) {
p.end_value += v.my_quantity;
}
這似乎有點笨拙?但是如果我這樣做,我不認爲這會隨着其他過濾器的變化(比如時間或產品)而不斷更新? Ethan建議我使用假組,但我有點失落。
Crossfilter不會是在這個計算中多好,所以它不是真的值得嘗試它楔進Crossfilter範例。進行過濾,然後用'dimension.top(Infinity)'提取當前過濾器中的數據,然後使用該數據計算一個時間範圍內的變化。如果你需要在dc.js圖表中顯示,那麼使用假組(https://github.com/dc-js/dc.js/wiki/FAQ#fake-groups) –
@Ethan,這樣做你是否建議我不使用你對dimension.top(infinity)的建議?有什麼方法可以進行計算,以便在更改時間範圍時進行更新?對不起,我有點困惑和新奇。 – user3878014
我說的是使用一個維度,但不是一個組。改用假組。對不起,我在這幾個星期沒有在線,所以希望其他人可以幫忙 –