-
Notifications
You must be signed in to change notification settings - Fork 14.1k
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
feat: standardized form_data #20010
feat: standardized form_data #20010
Conversation
88eaf86
to
923538d
Compare
8868739
to
b8bd5ce
Compare
Codecov Report
@@ Coverage Diff @@
## master #20010 +/- ##
==========================================
+ Coverage 66.44% 66.54% +0.09%
==========================================
Files 1725 1727 +2
Lines 64678 64728 +50
Branches 6824 6830 +6
==========================================
+ Hits 42978 43072 +94
+ Misses 19968 19906 -62
- Partials 1732 1750 +18
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
/testenv up |
@zhaoyongjie Ephemeral environment spinning up at http://52.34.220.70:8080. Credentials are |
superset-frontend/src/explore/controlUtils/standardizedFormData.ts
Outdated
Show resolved
Hide resolved
return this.sfd.memorizedFormData.get(vizType) as QueryFormData; | ||
} | ||
|
||
return this.memorizedFormData.slice(-1)[0][1]; |
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.
Should we add some null check in case memorizedFormData
is empty?
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 memorizedFormData
will not be empty, it is initialized in the constructor.
superset-frontend/packages/superset-ui-chart-controls/src/types.ts
Outdated
Show resolved
Hide resolved
Found a bug while switching between pivot table and and other charts. When pivot table has the same value added in Columns and Rows controls, then that value is going to be duplicated when switched to a chart with columns control. Screen.Recording.2022-05-13.at.13.38.00.mov |
Thanks, Kamil. I also noticed this but I want to discuss it with you for this. Since the Pivot Table allows |
I think that we should deduplicate control values by default, as we never allow drag and dropping duplicated values. In the case of Pivot Table it's allowed because Rows and Columns are separate controls. So I think that when we transition from Pivot Table to any other chart we should join values from Rows and Columns, remove duplicates and populate Dimensions of the new viz with the result |
632e635
to
0b35ea5
Compare
/testenv up |
@stephenLYZ Ephemeral environment spinning up at http://34.217.96.104:8080. Credentials are |
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.
Some minor comments, but in general this is a great move in the direction of making the Control panel more intuitive.
superset-frontend/packages/superset-ui-chart-controls/src/types.ts
Outdated
Show resolved
Hide resolved
superset-frontend/packages/superset-ui-chart-controls/src/types.ts
Outdated
Show resolved
Hide resolved
superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberTotal/controlPanel.ts
Outdated
Show resolved
Hide resolved
@@ -517,6 +517,11 @@ const config: ControlPanelConfig = { | |||
], | |||
}, | |||
], | |||
denormalizeFormData: formData => ({ | |||
...formData, | |||
metrics: formData.standardized_form_data.sharedFormData.metrics, |
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'm wondering if we should consider adding percent_metrics
to the metrics array in sharedFormData
? Let's say we have a table chart with just a single metric in percentage_metrics
and change to Pie - currently the metric will be lost.
As a solution - Maybe we could add a property to the normalized control values that states some additional context about the origin of the value. In this case it could specify that it originated from the percent_metrics
control rather than a "regular" metric control. So the additional value could, for instance, be called sourceControl
.
This would also address the problem identified in the Pivot table - if we had the additional context about what type of a control the value originated from, we would more easily be able to map them back to their original controls (groupbyRows
or groupbyColums
). Ping @kgabryje
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.
Not sure if I follow - it looks to me like rows and columns in pivot table do return to their original states?
Screen.Recording.2022-05-16.at.11.35.36.mov
Or do you mean that, for example, if both columns and rows in pivot table contain a value name
, then it gets deduplicated when switching to table but sourceControl
contains information that name
originates from both columns
and rows
in pivot table? If that's the point, I like this idea!
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.
Thanks for the response - I must have had something wrong with my devenv, as after I reloaded it worked just like you described 👍 To add to this comment:
So I think that when we transition from Pivot Table to any other chart we should join values from Rows and Columns, remove duplicates and populate Dimensions of the new viz with the result
I think we should keep the duplicates in the normalized form data, but we could enrich the interface so that we know where the values came from:
export interface SharedFormData {
metrics: {
value: QueryFormMetric;
sourceViz: string;
sourceControl: string;
}[];
columns: {
value: QueryFormColumn;
sourceViz: string;
sourceControl: string;
}[];
}
This way the pie chart might not care if the metric was from metrics
or percent_metrics
, but some other chart might decide to map the values over differently, depending on where the value came from. This is especially true for the x_axis
control, which in a sense is a column/groupby, but should be handled differently from the series control.
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 we should keep the duplicates in the normalized form data
I'm still not really sold on this, because we can enter a state which is not allowed via user interface
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 good thing here is this is all ephemeral state, so we don't have to be super cautious about breaking changes. So I vote iterating in small increments and not over-abstracting right now (which is precisely what I was doing 😆 )
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'm wondering if we should consider adding
percent_metrics
to the metrics array insharedFormData
? Let's say we have a table chart with just a single metric inpercentage_metrics
and change to Pie - currently the metric will be lost.
This is an interesting question. It is also a legacy of Superset's history. The Percentage Metrics
is a post-processing metric rather than a SQL base metric. basically, it can not simply be mapping from a source viz to a target viz. The same control is Contribution Mode
in the Line chart V2.
I have said before, to solve this issue, I think we eventually need to move all post-processing(AA) into the metric and column so that we can do the real mapping between different charts.
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.
Agreed, percent_metrics
always makes me cringe for that exact reason (=it's really a post transform op). I'm fine leaving it out for now, as we can easily iteratively improve this functionality as we don't have to worry about backward compatibility.
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.
This way the pie chart might not care if the metric was from metrics or percent_metrics, but some other chart might decide to map the values over differently, depending on where the value came from. This is especially true for the x_axis control, which in a sense is a column/groupby, but should be handled differently from the series control.
The xaxis
didn't put in the sharedControls
. it's a publicControls. In the other words, the x-axis just "inhert" latest chart x-axis value, it can not mapping from sharedControls
.
I suggest that the modeling(like metric/dimension/filter/etc...) should decouple from visualization. The sourceControl: string;
means that preserving the context of the control, will allow modeling and visualization to be mixed.
superset-frontend/src/explore/controlUtils/standardizedFormData.test.tsx
Outdated
Show resolved
Hide resolved
superset-frontend/packages/superset-ui-chart-controls/src/types.ts
Outdated
Show resolved
Hide resolved
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'm not sure we need to store the standardized form data in a state object. The re-mapping calculation should be ephemeral and wouldn't be useful once users have done switching viz types.
How about we just add a toStandardizedState
and fromStandardizedState
config to each plugin and use them in the explorer reducer when vizType
changes?
There is a function that initiates all control states, which should also be able to receive what is the previous viz type:
superset/superset-frontend/src/explore/store.js
Lines 34 to 62 in 24f805e
export function getControlsState(state, inputFormData) { | |
/* | |
* Gets a new controls object to put in the state. The controls object | |
* is similar to the configuration control with only the controls | |
* related to the current viz_type, materializes mapStateToProps functions, | |
* adds value keys coming from inputFormData passed here. This can't be an action creator | |
* just yet because it's used in both the explore and dashboard views. | |
* */ | |
// Getting a list of active control names for the current viz | |
const formData = { ...inputFormData }; | |
const vizType = | |
formData.viz_type || state.common.conf.DEFAULT_VIZ_TYPE || 'table'; | |
handleDeprecatedControls(formData); | |
const controlsState = getAllControlsState( | |
vizType, | |
state.datasource.type, | |
state, | |
formData, | |
); | |
const controlPanelConfig = getChartControlPanelRegistry().get(vizType) || {}; | |
if (controlPanelConfig.onInit) { | |
return controlPanelConfig.onInit(controlsState); | |
} | |
return controlsState; | |
} |
superset-frontend/packages/superset-ui-chart-controls/src/types.ts
Outdated
Show resolved
Hide resolved
superset-frontend/src/explore/controlUtils/standardizedFormData.ts
Outdated
Show resolved
Hide resolved
The Standardized Form Data has 2 uses.
The first use case can easily achieve by defining from/to function in each plugin, but the second use case has to save in form_data. |
/testenv up |
@zhaoyongjie Ephemeral environment spinning up at http://34.220.15.121:8080. Credentials are |
@zhaoyongjie Is 2 about allowing users to restore field values when they switch between chart types? Would it suffice if we just keep the history in a reducer state as well? It could be a simple vizType to formData dict. A plugin's |
Yes. The
I've tried this, and as you can see, it's hard to read the logic of the current reducer. In abstract terms. We just need to collect/calculate the current |
5a63fe2
to
a05c924
Compare
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 being an ephemeral piece of state that doesn't have any utility elsewhere in the application, there's not a strong need to complicate this with redux updates. If there is value in that, it seems like it would be fine as a follow-up PR. I think this provides a huge UX improvement as is, with little danger of side effects compared to the current implementation. I'd love to keep pressing on with doing this for more plugins, and making touchups/improvements in parallel as needed.
Ephemeral environment shutdown and build artifacts deleted. |
SUMMARY
Superset can't smoothly switch between visualizations and can not safe switching. When you change visualizations, all your work on Explore is about to be lost. For example, there are 3 metrics on the
line chart
, then switching to thebig number
, the3 metrics
will be lost, after then switching back to theline chart
, the3 metrics
was also gone.This PR introduces a simple data structure to maintain different viz switching and save switching history. The new data structure is called
Standardized Form Data
. The SFD will auto-mapping form_data when triggered viz changing action. EachcontrolPanel
in plugins provideddenormalizeFormData
function. The function supports a manual mapping approach when plugins have to map some control fromStandardized Form Data
.Note that the
Standardized Form Data
is intentionally designed not to persist, but to be hidden in the client's browser memory. In the other words, if the user closes the browser or refreshes the page, the viz changing history state will lose.This PR has supported
BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
Before
https://www.loom.com/share/08016e60cc594578b105ec1ab9847b4a?sharedAppSource=personal_library
After
https://www.loom.com/share/603dccc033d6496d9399811180842a16?sharedAppSource=personal_library
TESTING INSTRUCTIONS
ADDITIONAL INFORMATION