Giter Club home page Giter Club logo

Comments (6)

eventualbuddha avatar eventualbuddha commented on August 15, 2024

I'm having a hard time grokking the problem. Could you come up with something that doesn't use d3 (only crossfilter) and shows some numbers rather than bars? That might help identify the problem.

from crossfilter.

flamebunny avatar flamebunny commented on August 15, 2024

hey there, I think i narrowed it down, the problem isnt with reduceSum

its to do with the y.domain([-100, group.top(1)[0].value]);

which shows the key and value of the largest in the group
This works fine when all values in the y axis are positive:


Object { key=3, value=300} // selects correct value // key:[1] value:[90] // key:[2] value:[100] // key:[3] value:[300] // largest value

however when you have negative values the largest number is the smallest negative.


Object { key=1, value=-90} // selects incorrect value // key:[1] value:[-90] // key:[2] value:[-100] // key:[3] value:[-300] // largest negative value

The reason why the bars are exceeding the 0-100 y range is that the maximum value is based on an incorrect figure (of -90, when it should be based on -300)

i wonder if it would be possible to create another function - that would return the top array sorted with absolute values

y.domain([0, group.topAbs(1)[0].value]);

I believe that using absolute values would solve this issue

from crossfilter.

flamebunny avatar flamebunny commented on August 15, 2024

I think i solved it, but dont know what the effects will be on the rest of the crossfilter plugin

http://www.pixeltradr.com/crossfilter/indexPaymentsCrossfilter.html
http://www.pixeltradr.com/crossfilter/indexPaymentsCrossfilterNegative.html
http://www.pixeltradr.com/crossfilter/indexPaymentsCrossfilterPositive.html

Ive changed the crossfilter plugin in function heapselect() to include Math.abs() in three places:


function heapselect(a, lo, hi, k) { var queue = new Array(k = Math.min(hi - lo, k)), min, i, x, d; for (i = 0; i < k; ++i) queue[i] = a[lo++]; heap(queue, 0, k); if (lo < hi) { min = Math.abs(f(queue[0])); do { if (x = Math.abs(f(d = a[lo])) > min) { queue[0] = d; min = Math.abs(f(heap(queue, 0, k)[0])); } } while (++lo < hi); } return queue; }

Also edited the html file itself and added Math.abs() to:

y.domain([0, Math.abs(group.top(1)[0].value)]);

and in function barPath(group)


function barPath(groups) { var path = [], pathPositive = [], pathNegative = [], pathBoth = [], i = -1, n = groups.length, d; while (++i < n) { d = groups[i]; if(d.value < 0 || d.key < 0){ pathNegative.push("M", x(d.key), ",", height, "V", y(Math.abs(d.value)), "h9V", height); }else{ pathPositive.push("M", x(d.key), ",", height, "V", y(Math.abs(d.value)), "h9V", height); } pathBoth.push("M", x(d.key), ",", height, "V", y(Math.abs(d.value)), "h9V", height); } path[0] = pathPositive.join("") path[1] = pathNegative.join("") path[2] = pathBoth.join("") return path; }

I think it would probably be better to create new functions like - function heapselectAbs(a, lo, hi, k) {}
for example to to handle this situation.

from crossfilter.

flamebunny avatar flamebunny commented on August 15, 2024

Decided to leave the old sort functions alone, and create new ones to handle this situation:

instead of:
y.domain([0, group.top(1)[0].value]);
its now
y.domain([0, group.topAbs(1)[0].value]);

New crossfilter file:
http://pixeltradr.com/crossfilter/crossfilter.v1.abs.js

changes:

  • function topAbs(k)
  • function heapselectAbs_by(f)
    ----- function heapselectAbs(a, lo, hi, k)

http://pixeltradr.com/crossfilter/crossfilter.v1.abs.js

from crossfilter.

notmatt avatar notmatt commented on August 15, 2024

I think the result you're looking for is entirely achievable via the existing API. The easiest way I can think of is to order the group by the absolute value of the sum.

var data = [ { key : 1, value : 1 }, { key : 2, value : -2 }, { key : 3, value : 3 }, { key : 4, value : -4 } ]
var cf = crossfilter(data);
var key = cf.dimension(function(d) { return d.key });

var group = key.group().order(function(p) { return Math.abs(p) });
group.reduceSum(function(d) { return d.value });
group.top(2);

// producing
[ { key: 4, value: -4 },
  { key: 3, value: 3 } ]

It also possible to use group.reduce() to write your own reduction that finds the absolute value directly (and you wouldn't need to change the ordering).

from crossfilter.

flamebunny avatar flamebunny commented on August 15, 2024

Wow thats awesome!
It works, Thanks alot!

from crossfilter.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    šŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. šŸ“ŠšŸ“ˆšŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ā¤ļø Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.