mhkeller / layercake

graphics framework for sveltejs
https://layercake.graphics
MIT License
1.41k stars 31 forks source link

MultiLine doesn't render lines with undefined points #197

Closed rachelmarconi closed 5 months ago

rachelmarconi commented 5 months ago

Hello! If you don't think this is something LayerCake should handle, that's understandable and I'm happy to talk other solutions!

Issue:

In MultiLine.svelte, if a dataset skips x values, the svg is rendered with undefined in the path code, breaking the line and stopping it from being rendered after any undefined point. Examples: census data spanning over 2020 will stop at 2019, lines with different start values will simply not render any line with later starts.

Solution:

I found that adding a line to the path creation statement to filter out undefined variables works. This works better than filtering before feeding to LayerCake, at least in my case, because even missing values were manipulated, like transposing rectangles, so that the missing field was still present in the end and set to undefined at the stage when the dataset is fed to path.

MultiLine.svelte lines 10-17 become

$: path = values => {
    return 'M' + values
        .filter(d => $yGet(d) != undefined)
        .map(d => {
          return $xGet(d) + ',' + $yGet(d);
        })
        .join('L');
    };

Proof of Life

Note the different start values and how blue has no value at 2020. Screenshot 2024-05-13 at 12 37 47 PM

rachelmarconi commented 5 months ago

I also realize that there are lots of ways a user may want to handle NAs due to data considerations, like using a gap instead of a solid line through the missing x value, so this may not be the solution.

mhkeller commented 5 months ago

That line component is a super-simple one meant to show a dependency-free example. For this use case, you probably want to use the D3 line generator which comes with the .defined() method. That makes it easy to draw a line with a break in it / missing data (if I'm understanding your data needs properly): https://layercake.graphics/components/Line-D3.svelte

mhkeller commented 5 months ago

Since multi-lines are more likely to have weird, non-conforming data, maybe it's a good idea for the website to use the D3 component as a better starting point!

rachelmarconi commented 5 months ago

Thanks for fielding this! I'll look into this component and see how it works. A break in the line would definitely be helpful. Much appreciated!

mhkeller commented 5 months ago

Here's the new component: https://github.com/mhkeller/layercake/commit/5a0bb03c7a34ad4460afbe9ddccd999e11e66541

And here's an example where some of the data has a null value. We're using the y accessor to test whether there is a value there which will determine whether the line generator draws: https://svelte.dev/repl/410aed4174494fbca233c82d2213f1f9?version=3.46.2

mhkeller commented 5 months ago

Closing this for now but let me know if you have any questions.