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
Add Flatten transform #3812
Add Flatten transform #3812
Conversation
src/compile/data/flatten.ts
Outdated
private getDefaultName(field: string): string { | ||
const index = this.transform.flatten.indexOf(field); | ||
// Returns the "as" entry corresponding to field if it exists else returns field | ||
return (this.transform.as === undefined || this.transform.as[index] === undefined) ? field : this.transform.as[index]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now this follows Vega Defaults. Not sure whether to change this and introduce different behavior when as
is not specified.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we just pass nothing and let Vega handle the default case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kanitw mentioned in slack that we need to set as
, so that producedFields
gives the correct output. But here, since the default is the field
value, I think passing nothing might be ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try it out and I'd always prefer to output less.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can output as=undefined
if you modify producedFields
to output field
name instead if as
is undefined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this method is pretty unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try it out and I'd always prefer to output less.
I just check the rest of transform are all explicit though, so doing so would be quite inconsistent. So let's make them explicit for consistency for now.
If @domoritz doesn't like it, he can refactor all of the transforms later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great start. Please see comments. :)
src/compile/data/flatten.ts
Outdated
const fields: string[] = []; | ||
const as = []; | ||
for (const field of this.transform.flatten) { | ||
fields.push(field === undefined ? null : field); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why converting undefined to null?
src/compile/data/flatten.ts
Outdated
} | ||
|
||
private getDefaultName(field: string): string { | ||
const index = this.transform.flatten.indexOf(field); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
The use of
indexOf
here is a bit unnecessary complex. Why don't you passindex
in as a parameter. Your producedFields method can use the index in the reducer. -
when referring to properties of an object multiple times, always use destructure syntax.
const {flatten, as} = this.transform
src/compile/data/flatten.ts
Outdated
} | ||
|
||
public producedFields() { | ||
const out = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better just use reduce
return this.transform.flatten.reduce((index, field, i) => {
out[as[i] || field] = true;
return out
}, {});
src/compile/data/flatten.ts
Outdated
private getDefaultName(field: string): string { | ||
const index = this.transform.flatten.indexOf(field); | ||
// Returns the "as" entry corresponding to field if it exists else returns field | ||
return (this.transform.as === undefined || this.transform.as[index] === undefined) ? field : this.transform.as[index]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this method is pretty unnecessary.
src/compile/data/flatten.ts
Outdated
private getDefaultName(field: string): string { | ||
const index = this.transform.flatten.indexOf(field); | ||
// Returns the "as" entry corresponding to field if it exists else returns field | ||
return (this.transform.as === undefined || this.transform.as[index] === undefined) ? field : this.transform.as[index]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try it out and I'd always prefer to output less.
I just check the rest of transform are all explicit though, so doing so would be quite inconsistent. So let's make them explicit for consistency for now.
If @domoritz doesn't like it, he can refactor all of the transforms later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Please make last minor fix and make the test pass and we can merge this to feature/transform. (Let's do docs separately so it's easier to review.)
src/compile/data/flatten.ts
Outdated
}, {}); | ||
} | ||
|
||
private getNames() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this method and move the logic above?
producedFields and getNames
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. We're almost done there. Here are some comments.
"data": { | ||
"values": [ | ||
{ "id": "001", | ||
"ra": "243.35", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to put these numbers as strings? Same for "time".
} | ||
] | ||
}, | ||
"transform": [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why transforming it up here? Doing so require you to apply aggregate to basically unflatten it for the upper plot.
"width": 300, | ||
"height": 200, | ||
"title": "Sky position", | ||
"transform": [{"aggregate": [], "groupby": ["ra", "dec", "id"]}], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We shouldn't have to aggregate here.
}, | ||
"size": {"value": 100} | ||
}, | ||
"mark": "circle" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We always put mark before encoding in our examples.
"color": {"value": "steelblue"}, | ||
"detail": {"field": "id", "type": "nominal"} | ||
}, | ||
"mark": "line" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We always put mark before encoding in our examples.
site/docs/transform/flatten.md
Outdated
<div class="vl-example" data-name="circle_flatten"></div> | ||
|
||
|
||
### Concat Circle and Line Marks with Nested Data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
### Advanced Example: Coordinated View with Nested Time Series
site/docs/transform/flatten.md
Outdated
|
||
{% include table.html props="flatten,as" source="FlattenTransform" %} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having a usage section without specs like Vega does is helpful.
The visual example is good additions, but having explicit examples how data is reshaped is useful.
"mark": "circle", | ||
"encoding": { | ||
"x": { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Why line breaks here.
-
I think you can fit field and type in one online for each of x, y, and color
TODO: