我正在尝试使用自定义缩减(reduceAdd,reduceRemove等)创建一个用于放入dc.js的变量,并且无法弄清楚如何编写它。
我在这些reduce函数之外编写了函数,现在必须复制相同的reduce函数内部,以便对绘制的图形使用相同的函数。为外部reduce函数编写的逻辑和代码如下
逻辑:对于每个唯一的contact_week available(日期),找到weeknumber的最大值,然后总结TOTCOUNT变量和DECAY_CNT变量并计算百分比(DECAY_CNT / TOTCOUNT)。
以下是不使用crossfilter的原始代码:
//Decay % logic
var dates = d3.map(filter1,function(d) { return d.CONTACT_WEEK;}).keys() ;
console.log(dates);
var sum1,sum2 = 0;
for(var i=0; i<dates.length; i++)
{
data1 = filter1.filter(function(d) { return d.CONTACT_WEEK == dates[i] ;});
//console.log(data1);
var max = d3.max(data1, function(d) { return +d.WEEK_NUMBER ;});
//console.log(max);
data2 = data1.filter(function(d) { return d.WEEK_NUMBER == max ;});
var sum1 = d3.sum(data2, function(d) { return d.TOTCOUNT ;});
var sum2 = d3.sum(data2, function(d) { return d.DECAY_CNT ;});
console.log(sum1);
var decay = sum2/sum1 * 100 ;
console.log(decay);
}
这样做的第一步是确定日期的唯一值(contact_week) - 如何在reduce函数中执行此操作,因为它已经是遍历数据的for循环?
我想对于max等,我们可以使用reductio或其他一些逻辑,如评论中所述,但我并没有真正得到这里的方法/设计
对方法/解决方案的任何帮助都将受到高度赞赏。
UPDATE2:
尝试新方法数据说明:
我的数据中的几列 - contact_week(日期); week_number(数字 - -4到6); decay_cnt(整数); totcount(整数);持续时间(序数值 - 前,中,后);
现在,我需要计算一个称为衰减%的百分比,其计算方法如下: 对于每个唯一的contact_week,找到最大的week_number,现在对于此过滤的数据集,计算sum(decay_cnt)/ sum(totcount)
这必须在条形图中绘制,其中x轴是持续时间,公制 - 衰减%是y轴
为了计算各个日期的周数的最大值,我现在绘制了一个条形图,其中contact_week为x轴,最大为week_number为y轴。 如何获得我需要的图表?
代码:
dateDimension2 = ndx.dimension(function(d) {return d.CONTACT_WEEK ;});
decayGroup = reductio().max(function (d) { return d.WEEK_NUMBER; })(dateDimension2.group());
chart2
.width(500)
.height(200)
.x(d3.scale.ordinal())
//.x(d3.scale.ordinal().domain(["DURING","POST1"]))
.xUnits(dc.units.ordinal)
//.xUnits(function(){return 10;})
//.brushOn(false)
.yAxisLabel("Decay (in %)")
.dimension(dateDimension)
.group(decayGroup)
.gap(10)
.elasticY(true)
//.yAxis().tickValues([0, 5, 10, 15])
//.title(function(d) { return d.key + ": " + d3.round(d.value.new_count,2); })
/*.valueAccessor(function (p) {
//return p.value.count > 0 ? (p.value.dec_total / p.value.new_count) * 100 : 0;
return p.value.decay ;
})*/
.valueAccessor(function(d) { return d.value.max; })
.on('renderlet', function(chart) {
chart.selectAll('rect').on("click", function(d) {
console.log("click!", d);
});
})
.yAxis().ticks(5);
任何方法/建议都将受到高度赞赏
我认为解决方案主要在于假组/维度和减少组合方法。任何替代品都是最受欢迎的!
答案 0 :(得分:3)
我刚刚为这类问题添加了a FAQ和an example。
正如那里所解释的那样,我们的想法是保持一系列行,这些行落入每个bin,因为crossfilter doesn't provide access to that yet。一旦我们获得了实际行,您的计算几乎与您现在的计算相同,除了交叉过滤器跟踪您的周列表。
因此您可以使用示例中的这些函数:
protected void writeDirEntry(int id, DirectoryHandle dir, Buffer buffer, int index, Path f, String shortName, LinkOption... options) throws IOException {
...
if (version == SFTP_V3) {
// added shortName argument
String longName = getLongName(f, options, shortName);
} else {
...
}
// added shortName parameter
protected String getLongName(Path f, LinkOption... options, String shortName) throws IOException {
// added shortName argument
return getLongName(f, true, options, shortName);
}
// added shortName parameter
private String getLongName(Path f, boolean sendAttrs, LinkOption... options, String shortName) throws IOException {
...
// added shortName argument
return getLongName(f, attributes, shortName);
}
// added shortName parameter
private String getLongName(Path f, Map<String, ?> attributes, String shortName) throws IOException {
...
return (SftpHelper.getBool(isDirectory) ? "d" : (SftpHelper.getBool(isLink) ? "l" : "-"))
+ PosixFilePermissions.toString(perms) + " "
+ (attributes.containsKey("nlink") ? attributes.get("nlink") : "1")
+ " " + username + " " + group + " " + lengthString + " "
+ UnixDateFormat.getUnixDate((FileTime) attributes.get("lastModifiedTime"))
// using shortName instead of getShortName(f)
+ " " + shortName;
}
// + you need to modify sendPath to pass getShortName(f)
// to its call to getLongName
您需要在记录中使用唯一键,以便可以可靠地添加和删除它们。我假设您的记录中有 function groupArrayAdd(keyfn) {
var bisect = d3.bisector(keyfn);
return function(elements, item) {
var pos = bisect.right(elements, keyfn(item));
elements.splice(pos, 0, item);
return elements;
};
}
function groupArrayRemove(keyfn) {
var bisect = d3.bisector(keyfn);
return function(elements, item) {
var pos = bisect.left(elements, keyfn(item));
if(keyfn(elements[pos])===keyfn(item))
elements.splice(pos, 1);
return elements;
};
}
function groupArrayInit() {
return [];
}
字段。
定义您的周尺寸和组,如下所示:
ID
然后,在价值访问者中,最有效的时间来计算您的指标。因此,您可以使用在问题中发布的代码的核心来定义值访问器。
(当然,此代码未经测试,因为我不知道您的数据。)
var weekDimension = ndx.dimension(function(d) {return d.CONTACT_WEEK ;}),
id_function = function(r) { return r.ID; },
weekGroup = weekDimension.group().reduce(groupArrayAdd(id_function), groupArrayRemove(id_function), groupArrayInit);