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

Fix multilayer geoviz and color picker error #5767

Merged
merged 4 commits into from
Aug 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ function getCategories(fd, data) {

const propTypes = {
slice: PropTypes.object.isRequired,
data: PropTypes.array.isRequired,
mapboxApiKey: PropTypes.string.isRequired,
setControlValue: PropTypes.func.isRequired,
viewport: PropTypes.object.isRequired,
getLayer: PropTypes.func.isRequired,
payload: PropTypes.object.isRequired,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove data from the props, since it can fetched from the payload.

};

export default class CategoricalDeckGLContainer extends React.PureComponent {
Expand All @@ -50,9 +50,9 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
const fd = nextProps.slice.formData;

const timeGrain = fd.time_grain_sqla || fd.granularity || 'PT1M';
const timestamps = nextProps.data.map(f => f.__timestamp);
const timestamps = nextProps.payload.data.features.map(f => f.__timestamp);
const { start, end, step, values, disabled } = getPlaySliderParams(timestamps, timeGrain);
const categories = getCategories(fd, nextProps.data);
const categories = getCategories(fd, nextProps.payload.data.features);

return { start, end, step, values, disabled, categories };
}
Expand All @@ -79,8 +79,9 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
});
}
getLayers(values) {
const fd = this.props.slice.formData;
let data = [...this.props.data];
const { getLayer, payload, slice } = this.props;
const fd = slice.formData;
let data = [...payload.data.features];

// Add colors from categories or fixed color
data = this.addColor(data, fd);
Expand All @@ -103,7 +104,8 @@ export default class CategoricalDeckGLContainer extends React.PureComponent {
data = data.filter(d => this.state.categories[d.cat_color].enabled);
}

return [this.props.getLayer(fd, data, this.props.slice)];
payload.data.features = data;
return [getLayer(fd, payload, slice)];
}
toggleCategory(category) {
const categoryState = this.state.categories[category];
Expand Down
7 changes: 4 additions & 3 deletions superset/assets/src/visualizations/deckgl/layers/arc.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ function getPoints(data) {
return points;
}

function getLayer(fd, data, slice) {
function getLayer(fd, payload, slice) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I simplified the getLayer interface but forgot that other deck.gl vizs need other attributes in the payload.

const data = payload.data.features;
const sc = fd.color_picker;
const tc = fd.target_color_picker;
return new ArcLayer({
Expand All @@ -40,17 +41,17 @@ function deckArc(slice, payload, setControlValue) {
};

if (fd.autozoom) {
viewport = common.fitViewport(viewport, getPoints(payload.data.arcs));
viewport = common.fitViewport(viewport, getPoints(payload.data.features));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: you can use data here instead of payload.data.features.

Copy link
Contributor Author

@youngyjd youngyjd Aug 29, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems not. data is not defined in function deckArc(slice, payload, setControlValue){} so I feel using data here will not work. It is extracted in function getLayer(fd, payload, slice){} instead.

function getLayer(fd, payload, slice) {
  const data = payload.data.features;
  const sc = fd.color_picker;
  const tc = fd.target_color_picker;
  return new ArcLayer({
    id: `path-layer-${fd.slice_id}`,
    data,
    getSourceColor: d => d.sourceColor || d.color || [sc.r, sc.g, sc.b, 255 * sc.a],
    getTargetColor: d => d.targetColor || d.color || [tc.r, tc.g, tc.b, 255 * tc.a],
    strokeWidth: (fd.stroke_width) ? fd.stroke_width : 3,
    ...common.commonLayerProps(fd, slice),
  });
}

function deckArc(slice, payload, setControlValue) {
  const fd = slice.formData;
  let viewport = {
    ...fd.viewport,
    width: slice.width(),
    height: slice.height(),
  };

  if (fd.autozoom) {
    viewport = common.fitViewport(viewport, getPoints(payload.data.features));
  }
...
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you're right. I got confused by the hidden lines, my bad!

}

ReactDOM.render(
<CategoricalDeckGLContainer
slice={slice}
data={payload.data.arcs}
mapboxApiKey={payload.data.mapboxApiKey}
setControlValue={setControlValue}
viewport={viewport}
getLayer={getLayer}
payload={payload}
/>,
document.getElementById(slice.containerId),
);
Expand Down
13 changes: 9 additions & 4 deletions superset/assets/src/visualizations/deckgl/layers/scatter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,18 @@ function getPoints(data) {
return data.map(d => d.position);
}

function getLayer(fd, data, slice) {
const dataWithRadius = data.map((d) => {
function getLayer(fd, payload, slice) {
const dataWithRadius = payload.data.features.map((d) => {
let radius = unitToRadius(fd.point_unit, d.radius) || 10;
if (fd.multiplier) {
radius *= fd.multiplier;
}
return { ...d, radius };
if (d.color) {
return { ...d, radius };
}
const c = fd.color_picker || { r: 0, g: 0, b: 0, a: 1 };
const color = [c.r, c.g, c.b, c.a * 255];
return { ...d, radius, color };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this, I think I must've removed it by mistake.

});

return new ScatterplotLayer({
Expand Down Expand Up @@ -49,11 +54,11 @@ function deckScatter(slice, payload, setControlValue) {
ReactDOM.render(
<CategoricalDeckGLContainer
slice={slice}
data={payload.data.features}
mapboxApiKey={payload.data.mapboxApiKey}
setControlValue={setControlValue}
viewport={viewport}
getLayer={getLayer}
payload={payload}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove data above, since we're passing the payload.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! make sense

/>,
document.getElementById(slice.containerId),
);
Expand Down
9 changes: 5 additions & 4 deletions superset/assets/src/visualizations/deckgl/multi.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ function deckMulti(slice, payload, setControlValue) {
// Filters applied to multi_deck are passed down to underlying charts
// note that dashboard contextual information (filter_immune_slices and such) aren't
// taken into consideration here
let filters = subslice.form_data.filters.concat(fd.filters);
if (fd.extra_filters) {
filters = filters.concat(fd.extra_filters);
}
const filters = [
...(subslice.form_data.filters || []),
...(fd.filters || []),
...(fd.extra_filters || []),
];
const subsliceCopy = {
...subslice,
form_data: {
Expand Down
5 changes: 2 additions & 3 deletions superset/viz.py
Original file line number Diff line number Diff line change
Expand Up @@ -2161,7 +2161,7 @@ def query_obj(self):
fd = self.form_data

# add NULL filters
if fd.get('filter_nulls'):
if fd.get('filter_nulls', True):
self.add_null_filters()

d = super(BaseDeckGLViz, self).query_obj()
Expand Down Expand Up @@ -2409,10 +2409,9 @@ def get_properties(self, d):

def get_data(self, df):
d = super(DeckArc, self).get_data(df)
arcs = d['features']

return {
'arcs': arcs,
'features': d['features'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 I think it's good to standardize on the key value here.

'mapboxApiKey': config.get('MAPBOX_API_KEY'),
}

Expand Down