Crossfilter在dc.js上显示负数,数据集中没有负数

时间:2015-03-24 12:03:48

标签: javascript dc.js crossfilter

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

这一切都在我的分钟栏上工作一个有趣的问题,看起来像CrossFilter或dc.js在图表上放置负值,但仅在选择图表的某些部分时。

因此,当我从图像中看到,当我选择一个似乎没有值的图表区域时,这会在其他图表中显示负值。

enter image description here

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

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

我的数据中从不存在任何负值,因此我的图表如何显示负值?

我是CrossFilter和dc.js的新手,所以我不确定这里展示的最佳方法或最佳代码片段,如果有其他我应该分享的内容请告诉我,我真的需要帮助我们了解为什么我的图表中有负数。

编辑:添加代码

以下是我的数据示例:

  

[{"标识":" 1""铟酸":&#34 31 /二千零十五​​分之一十""类型& #34;:"新""分类":" CAT1""值":" 1.400874145"} ,   {"标识":" 2""铟酸":&#34 21/10/2014年""类型&#34 ;: "旧""分类":" CAT2""值":" 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属性的函数:

function 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

小提琴 - JSFiddle

1 个答案:

答案 0 :(得分:6)

看起来这些是无穷小的负数,这可能表示由浮点数不能完全抵消引起的故障。

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

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

由于交叉滤波器可能会以与添加顺序不同的顺序减去值,并且添加顺序也不一定定义,因此经常出现这种问题。

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

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};
            });
        }
    };
}

使用此功能将原始群组包裹在您遇到问题的地方:

chart.group(snap_to_zero(valueGrouped))