我是使用crossfilter,dc.js和d3.js的新手。我正在努力让过滤器应用于我的复合折线图。我已经完成了几个教程,但显然我遗漏了一些东西,因为如果我在应用过滤器的情况下移除尺寸,图表不会改变或看起来完全不同。
以下是我的数据示例:
var data = array(
{
price:{value: 38}
shipment:{start_date: "2017-12-06", end_date: "2018-01-15"}
side:"sell"
},
{
price:{value: 44}
shipment:{start_date: "2017-10-08", end_date: "2018-01-15"}
side:"sell"
},
{
price:{value: 38}
shipment:{start_date: "2017-11-15", end_date: "2018-01-15"}
side:"buy"
},
{
price:{value: 38}
shipment:{start_date: "2017-10-25", end_date: "2018-01-15"}
side:"buy"
}
);
这是我宣布我的尺寸的地方:
` var crossFilteredData = crossfilter(data);
// Dimension by start_date
var dateDimension = crossFilteredData.dimension(function(d) {
var date = Date.parse(d.shipment.start_date);
return date;
});
// Dimension by side
var sideDimension = crossFilteredData.dimension(function(d) {
console.log(d.side);
return d.side;
});
sideDimension.filter("buy");
sideDimension.top(Infinity);`
在声明我的尺寸并对sideDimension应用过滤器后,我正在建立我的小组并计算每天的日期最高价格和最低价格:
var performanceByDateGroup = dateDimension.group().reduce(
function (p, v) {
++p.count;
p.sum += v.price.value;
// Calculate Min
if (p.minPrice > v.price.value) {
p.minPrice = v.price.value;
}
// Calculate Max
if (p.maxPrice < v.price.value) {
p.maxPrice = v.price.value;
}
return p;
},
function (p, v) {
--p.count;
p.sum -= v.price.value;
return p;
},
function () {
return {
count: 0,
sum: 0,
minPrice: 1000,
maxPrice: 0
};
}
);
最后,我将尺寸和组放入复合折线图中:
priceChart
.width(960)
.height(400)
.margins({top: 10, right: 10, bottom: 40, left: 10})
.transitionDuration(500)
.elasticY(true)
.renderHorizontalGridLines(true)
.yAxisLabel('Price')
.shareTitle(false)
.x(d3.time.scale().domain([Date.parse("2017-11-01"), Date.parse("2018-03-31")]))
.xAxisLabel('Shipment Start Date')
.legend(dc.legend().x(40).y(0).itemHeight(16).gap(4))
.compose([
dc.lineChart(priceChart)
.dimension(dateDimension)
.group(performanceByDateGroup, 'Min Price')
.colors('red')
.renderTitle(true)
.title(function(d) {
return 'Min: $' + d.value.minPrice.toFixed(2);
})
.valueAccessor(function (d) {
return d.value.minPrice;
}),
dc.lineChart(priceChart)
.dimension(dateDimension)
.group(performanceByDateGroup, 'Max Price')
.colors('green')
.renderTitle(true)
.title(function(d) {
return 'Max: $' + d.value.maxPrice.toFixed(2);
})
.valueAccessor(function (d) {
return d.value.maxPrice;
})
])
.brushOn(false);
dc.renderAll();
该图表显示了所有绘制的点,就好像根本没有识别整个sideDimension变量一样。如果我删除sideDimension变量并过滤,则图表看起来完全相同。
我非常感谢您提供的任何帮助或建议。
答案 0 :(得分:0)
使用交叉滤波器减少计算最小值和最大值很困难,但并非不可能。
当crossfilter评估某个群组时,它会首先添加所有记录,然后删除与过滤器不匹配的记录。这样,无论在创建维度时是否存在过滤器,结果都是一致的。 (例如,对于存在但已过滤掉的值,您需要零。)
在这种情况下,您在minPrice
函数内部maxPrice
和reduceRemove
没有做任何事情:
function (p, v) {
--p.count;
p.sum -= v.price.value;
return p;
},
正如我们所观察到的,记录被添加但从未被删除。
然而,情况比这更糟糕,因为最小和最大的聚合比总和和平均值更复杂。想一想:你可以记住最小值和最大值,但是当它们被移除时,你会重视什么价值?
reductio有最简单和最大的功能,或者你想自己做,this example shows how。