Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Line Chart's interpretation of null values #615

Closed
bgeels opened this issue Jun 12, 2014 · 13 comments
Closed

Line Chart's interpretation of null values #615

bgeels opened this issue Jun 12, 2014 · 13 comments

Comments

@bgeels
Copy link

bgeels commented Jun 12, 2014

Currently in the lineChart widget it is the default behavior to ignore null values and just connect the two closest data points resulting in a straight line going through the timestamps with null values.

Is there any way to override this behavior so I can say something like if( d.data.value === null) stop drawing this line segment and start a new one?

I included a jsfiddle example here, http://jsfiddle.net/mater_tua/QD9Ev/. The result I would want is two line segments. The first one ending at, 2014-06-09T18:50:00.000Z, and the second starting at, 2014-06-09T21:25:20.000Z.

@gordonwoodhull
Copy link
Contributor

Hi @bgeels. I didn't think it was possible, but I was proved wrong here:

http://stackoverflow.com/questions/22712739/dc-js-to-plot-line-chart-how-to-break-line-if-data-is-not-present

It would be great to add optional support for this directly in dc.js - should be a one-liner, or two lines to make it optional. Any chance you'd care to try it out and perhaps contribute a PR?

@bgeels
Copy link
Author

bgeels commented Jun 12, 2014

Thanks, for the quick response and yes I'd like to give that a shot. Any idea yet when version 2.0.0 will be released? I think I caught wind of a potential release in July in one of the lists, not sure if there's been any official date set or not though. Ideally, I'd like to get this feature in that release and move over to that.

@gordonwoodhull
Copy link
Contributor

Yes, I'm aiming for a release in mid-July. Submit a PR with tests and it's yours.

(Hopefully releases will be more frequent after that.)

@bgeels
Copy link
Author

bgeels commented Jun 12, 2014

Sounds good. Thanks.

@rakesh20026
Copy link

To solve this issue , you have to edit dc.js in the drawLine function...

//Note.- This .defined(..) is a new property added in the function to solve the issue
function drawLine(layersEnter, layers) {
        var line = d3.svg.line()
            .defined(function(d) { return d.y != null; })   //add this line in the existing code ..........
            .x(function (d) {
                return _chart.x()(d.x);
            })
            .y(function (d) {
                return _chart.y()(d.y + d.y0);
            })
          ........
} 

I hope , your issue will be solved.. Thanks @gordonwoodhull for remembering me.. :)

@gordonwoodhull
Copy link
Contributor

Thanks @rakesh20026, that's very helpful.

Just add the generalization that the function passed to .defined is a new property which defaults to the anonymous function passed in above , and a couple of tests, and we'll be there.

I will take it on if no one else does. ;-)

@gordonwoodhull gordonwoodhull added this to the v2.0 milestone Jul 5, 2014
@gordonwoodhull
Copy link
Contributor

Okay, now I'm confused - the .defined() function has existed since 2840573, although it doesn't have tests or documentation. Could anyone try this out and, if you're brave, submit a test or two?

@bgeels
Copy link
Author

bgeels commented Jul 15, 2014

So stepping through the code that @rakesh20026 posted above. When you get to a y value that should be null, in the defined function, it appears to have been converted to a 0 at some point. Trying to pinpoint where exactly this is happening.

@bgeels
Copy link
Author

bgeels commented Jul 15, 2014

Hmm, actually doing group.all() before instantiating the chart shows that it's crossfilter that is doing this.

@bgeels
Copy link
Author

bgeels commented Jul 15, 2014

TIL: In Javascript, null evaluates to 0 in the context of mathematical operations. So the defined function of the lineChart here was working exactly as expected.

The issue in my case was that I was using crossfilter's reduceSum function to create my groups. When the all function of the group is called, it gets to the point where the y value is null and adds it to the initial value 0, resulting in the value 0 for that point. This results in the defined function passed in always evaluating to true.

The fix here is to just be more explicit when defining the map reduce functions in your crossfilter groups. I have a working jsfiddle example below that demonstrates this.

tldr; There is no issue in the dc.js library, the issue comes down to correctly defining the map reduce functions of your crossfilter groups.

http://jsfiddle.net/mater_tua/Whbyw/
http://jsfiddle.net/gordonwoodhull/uvqjqc8d/3/

@gordonwoodhull
Copy link
Contributor

Thanks for the explanation and example @bgeels. These are important points to mention in the documentation.

@andorov
Copy link

andorov commented Mar 12, 2015

@pianomister
Copy link

I do not know if this was caused by my special setup:
I am rendering a bunch of composite charts with lines using the same configuration but different filters each. The charts are generated by a forEach loop. The function for defined() was only working on the first chart properly, although all charts used a copy of the same config:

.defined(function(d) {
    return d.y != null;
})

Using a function which is not returning true/false but the actual value (like the crossfilter filter functions), fixed the problem for me:

.defined(function(d) {
    if(d.y !== null) {
        return d.y;
    }
})

Maybe this helps in case someone has the same problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants