交叉过滤器在dc.js上显示负数,数据集中没有负数 [英] Crossfilter showing negative numbers on dc.js with no negative numbers in the dataset

查看:83
本文介绍了交叉过滤器在dc.js上显示负数,数据集中没有负数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用CrossFilter和dc.js来创建4个不同的条形图,并允许用户通过使用图表上的画笔功能来更改数据,因此当用户更改一个图表上的画笔时,其他用户会动态更改。



这在分钟内对我都有用,这是一个有趣的问题,它看起来像CrossFilter或dc.js在图表上放置了负值,但仅当选择一个图形。



因此,从图像中可以看到,当我选择图表中似乎没有任何值的区域时,在其他图表中将显示负值。





我的数据中有四个项目,日期,类型(字符串),值(数字)和分组值(这是将值分为50个较小的块)



然后我在每个数据上有4个维度和4个组,这些都提供给图表。



数据中的负值,那么我的图表如何显示负值?



我是CrossFilter和dc.js的新手,所以我不确定在此处显示的最佳方法或最佳代码片段应该分享,请让我知道,我真的需要帮助尝试了解为什么我的图表中存在负数。



编辑:添加代码



以下是我的数据示例:


[{ Id: 1, InDate: 31/10/2015, Type: New, Category: cat1, Value: 1.400874145},
{ Id: 2, InDate: 21/10/2014, Type: Old, Category: cat2, Value: 0}]


我从CSV文件中使用d3.csv函数读取了它。我对CSV文件中的负值进行了三重检查。



这是我设置尺寸的方法:

  var ndx = crossfilter(data); 

var parseDate = d3.time.format(%d /%m /%Y)。parse;

data.forEach(function(d){
d.date = parseDate(d.InDate);
d.valueGrouped = createValueGrouping(parseFloat(d.Value));
});

var dateDim = ndx.dimension(function(d){return d.date;});
var typeDim = ndx.dimension(function(d){return d.Type;});
var valueGroupDim = ndx.dimension(function(d){return d.valueGrouped;});
var categoryDim = ndx.dimension(function(d){return d.Category;});

以下是创建valueGrouped属性的函数:

 函数createValueGrouping(value){
return 50 * Math.round(value / 50);
}

最后,这是我设置组的方式:

  var timelineGroup = dateDim.group()。reduceSum(function(d){return parseFloat(d.Value);}); 
var typeGroup = typeDim.group()。reduceSum(function(d){return parseFloat(d.Value);});
var valueGrouped = valueGroupDim.group()。reduceSum(function(d){return parseFloat(d.Value);});
var categoryGroup = categoryDim.group()。reduceSum(function(d){return parseFloat(d.Value);});

编辑2:添加JSFiddle



Fiddle - JSFiddle

解决方案

这些似乎是无穷小的负数,这可能表明由浮点数不能完美抵消所引起的故障。



当添加浮点数时点数的大小变化很大,操作不一定是关联的或分布的,这意味着如果以不同的顺序添加数字,您将获得不同的结果。



https://en.m.wikipedia.org/wiki/Floating_point#Accuracy_problems



由于交叉过滤器可能会以与值相加的方式不同的方式减去值,并且也不一定要定义相加的顺序,因此经常会出现这种问题。 / p>

我建议创建一个假组来包装您的数据,并在它们非常接近时将值设置为零:

  function snap_to_zero(source_group){
return {
all:function(){
return source_group.all()。map(function(d){
return {键:d.key,
值:(Math.abs(d.value)< 1e-6)? 0:d.value};
});
}
};
}

无论您在哪里遇到问题,都可以使用此功能包装原始组:

  chart.group(snap_to_zero(valueGrouped))


I am using CrossFilter along with dc.js to create 4 different bar charts and allow a user to change the data by using the brush feature on the charts, so when the user changes the brush on one chart the others dynamically changes.

This is all working for me at the minute bar one interesting issue, it looks like CrossFilter or dc.js are putting negative values on the graphs but only when certain sections of a graph is selected.

So as you can see from the image when I select an area of a chart that seems to have no values this shows up negative values in the other charts.

I have four items in my data, date, a type (string), value (number) and grouped value (this is the value grouped into smaller chunks of values of 50)

And then I have 4 dimensions on each piece of data and 4 groups and these are supplied to the charts.

There is never any negative values in my data so how can my charts be showing negative values?

I am new to CrossFilter and dc.js so I'm not sure of the best approach or the best snippets of code to show here, if there is something else I should share please let me know, I really need help trying to understand why there are negative numbers in my graphs.

EDIT: Adding code

Here is an example of my data:

[{"Id":"1","InDate":"31/10/2015","Type":"New","Category":"cat1","Value":"1.400874145"}, {"Id":"2","InDate":"21/10/2014","Type":"Old","Category":"cat2","Value":"0"}]

I read it in using the d3.csv function from a CSV file. I have triple checked for negative values in the CSV file.

Here is how I set up the dimensions:

var ndx = crossfilter(data);

var parseDate = d3.time.format("%d/%m/%Y").parse;

data.forEach(function(d) {
    d.date = parseDate(d.InDate);
    d.valueGrouped = createValueGrouping(parseFloat(d.Value));
});

var dateDim = ndx.dimension(function(d) {return d.date;});
var typeDim = ndx.dimension(function(d) {return d.Type;});
var valueGroupDim = ndx.dimension(function(d) {return d.valueGrouped;});
var categoryDim = ndx.dimension(function(d) {return d.Category;});

Here is the function that creates the valueGrouped attribute:

function createValueGrouping(value){
    return 50 * Math.round(value/50);
}

Finally here is how I set up the groups:

var timelineGroup = dateDim.group().reduceSum(function(d) {return parseFloat(d.Value);});
var typeGroup = typeDim.group().reduceSum(function(d) {return parseFloat(d.Value);});
var valueGrouped = valueGroupDim.group().reduceSum(function(d) {return parseFloat(d.Value);});
var categoryGroup = categoryDim.group().reduceSum(function(d) {return parseFloat(d.Value);});

EDIT 2: Adding JSFiddle

Fiddle - JSFiddle

解决方案

It looks like these are infinitesimal negative numbers, which would probably indicate a glitch caused by floating point numbers not canceling out perfectly.

When you are adding floating point numbers with greatly varying magnitude, the operations are not necessarily associative or distributive, which means that if you add numbers in a different order you will get different results.

https://en.m.wikipedia.org/wiki/Floating_point#Accuracy_problems

Since crossfilter is liable to subtract out values in a different order from how they were added, and the order of addition is not necessarily defined either, this kind of problem often arises.

I would suggest creating a fake group wrapping your data and setting the values to zero when they are very close:

function snap_to_zero(source_group) {
    return {
        all:function () {
            return source_group.all().map(function(d) {
                return {key: d.key, 
                        value: (Math.abs(d.value)<1e-6) ? 0 : d.value};
            });
        }
    };
}

Wrap your original group with this function wherever you're seeing the problem:

chart.group(snap_to_zero(valueGrouped))

这篇关于交叉过滤器在dc.js上显示负数,数据集中没有负数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆