строки не обнуляются, как ожидалось - PullRequest
2 голосов
/ 02 июля 2019

При фильтрации на другом графике мои верхние строки дают бессмысленные бесконечно малые значения, где я мог бы ожидать нулей.

Я думаю, что проблема заключается в том, что при фильтрации по значению, которое изначально не былов верхних значениях dc не знает, как извлечь значения, которые вы отфильтровали, из панели «другие», даже если вы ее не отображаете.В моем случае я не показываю это специально, чтобы избежать описанного поведения.

Я создал jsfiddle , который показывает проблему в действии: Попробуйте нажать SGD на нижнем графике,KRW - это тот, который работает, как и следовало ожидать (т. Е. 2 ​​верхних графика, показывающие одно и то же).

ТАК заставляет меня написать код для проблемы, так что вот так:

var ndx = crossfilter(theData);
var dims = {};
var groups = {};


var field1Chart = dc.barChart("#field1Chart");
dims.field1 = ndx.dimension("field1");
groups.field1 = {};
groups.field1.valueSum = dims.field1.group().reduceSum((d) => d.value1);
field1Chart
    .height(200)
    .width(800)
    .dimension(dims.field1)
    .group(groups.field1.valueSum)
    .valueAccessor((d) => d.value)
    .x(d3.scaleBand())
    .elasticX(true)
    .xUnits(dc.units.ordinal);

var field2Chart = dc.barChart("#field2Chart");
dims.field2 = ndx.dimension("field2");
groups.field2 = {};
groups.field2.valueSum = dims.field2.group().reduceSum((d) => d.value2);
field2Chart
    .height(200)
    .width(800)
    .dimension(dims.field2)
    .group(groups.field2.valueSum)
    .valueAccessor((d) => d.value)
    .x(d3.scaleBand())
    .elasticX(true)
    .xUnits(dc.units.ordinal);

var field3Chart = dc.rowChart("#field3Chart");
dims.field3 = ndx.dimension("field3");
groups.field3 = {};
groups.field3.valueSum = dims.field3.group().reduceSum((d) => d.value3);
field3Chart
    .dimension(dims.field3)
    .group(groups.field3.valueSum)
    .valueAccessor(d => Math.abs(d.value))
    .renderLabel(true)
    .labelOffsetY(10)
    .elasticX(true)
    .rowsCap(10)
    .othersGrouper(null);

var field3Chart2 = dc.rowChart("#field3ChartBis");
field3Chart2
    .dimension(dims.field3)
    .group(groups.field3.valueSum)
    .valueAccessor(d => Math.abs(d.value))
    .renderLabel(true)
    .labelOffsetY(10)
    .elasticX(true)
    .rowsCap(10);

var combinedChart = dc.barChart("#combinedChart");
dims.combined = ndx.dimension((d) => [d.field1, d.field2], true);
groups.combined = {}
groups.combined.valueSum = dims.combined.group().reduce(
    (p, v) => {
        if (!p.hasOwnProperty(v.field1)) {
            p[v.field1] = 0;
        }
        if (!p.hasOwnProperty(v.field2)) {
            p[v.field2] = 0;
        }
        p[v.field1] += +v.value1;
        p[v.field2] += +v.value2;
        return p;
    },
    (p, v) => {
        p[v.field1] -= +v.value1;
        p[v.field2] -= +v.value2;
        return p;
    },
    () => {
        return {}
    }
);
combinedChart
    .height(200)
    .width(800)
    .dimension(dims.combined)
    .group(groups.combined.valueSum)
    .valueAccessor((d) => Math.abs(d.value[d.key]))
    .x(d3.scaleBand())
    .elasticX(true)
    .xUnits(dc.units.ordinal);


dc.renderAll();

1 Ответ

1 голос
/ 02 июля 2019

У вас проблемы с округлением с плавающей запятой. Это часто происходит, когда у вас есть значения с большим разбросом по величине.

Если вы добавите несколько чисел с плавающей запятой, а затем вычтете те же самые числа, результат часто не будет равен нулю. Это связано с тем, что сложение и вычитание с плавающей запятой не обязательно является ассоциативным или дистрибутивным .

Числа с плавающей точкой по своей сути неточны. Чтобы взять очень простой пример,

1000000000 + 0.00000001 - 1000000000 - 0.00000001 === -0.00000001

Вы не видите этого, когда нажимаете на валюту, такую ​​как KRW или CHF, потому что есть некоторые строки, которые имеют существенные значения, поэтому бесконечно малые строки слишком малы, чтобы их видеть.

Это рассматривается в часто задаваемых вопросах о dc.js , а решение snap_to_zero исправляет вашу скрипку .

...