-
Notifications
You must be signed in to change notification settings - Fork 8.5k
Add comments and inline docs for visualization saving and editing process. #7968
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,16 +66,27 @@ uiModules | |
| location: 'Visualization Editor' | ||
| }); | ||
|
|
||
| // Retrieve the resolved SavedVis instance. | ||
| const savedVis = $route.current.locals.savedVis; | ||
|
|
||
| // Instance of vis.js. | ||
| const vis = savedVis.vis; | ||
|
|
||
| // Clone the _vis instance. | ||
| const editableVis = vis.createEditableVis(); | ||
|
|
||
| // NOTE: Why is this instance method being overwritten? | ||
| vis.requesting = function () { | ||
| const requesting = editableVis.requesting; | ||
| // Invoking requesting() calls onRequest on each agg's type param. | ||
| // NOTE: What is the structure of an agg_config, and the role of type | ||
|
||
| // and type.params? | ||
| requesting.call(vis); | ||
| requesting.call(editableVis); | ||
| }; | ||
|
|
||
| // Boolean by default, but then something else later | ||
| // NOTE: What is the role of searchSource? Why does it default to a boolean? | ||
|
||
| const searchSource = savedVis.searchSource; | ||
|
|
||
| $scope.topNavMenu = [{ | ||
|
|
@@ -104,8 +115,12 @@ uiModules | |
| docTitle.change(savedVis.title); | ||
| } | ||
|
|
||
|
||
| // Instance of app_state.js. | ||
| let $state = $scope.$state = (function initState() { | ||
| // Extract visualization state with filtered aggs. | ||
| // Consists of: aggs, params, listeners, title, and type. | ||
| const savedVisState = vis.getState(); | ||
|
|
||
| const stateDefaults = { | ||
| uiState: savedVis.uiStateJSON ? JSON.parse(savedVis.uiStateJSON) : {}, | ||
| linked: !!savedVis.savedSearchId, | ||
|
|
@@ -114,19 +129,22 @@ uiModules | |
| vis: savedVisState | ||
| }; | ||
|
|
||
| $state = new AppState(stateDefaults); | ||
| // This is used to generate a 'uiState' PersistedState instance, and | ||
| // implictly add 'change' and 'fetch_with_changes' event handlers. | ||
| const appState = new AppState(stateDefaults); | ||
|
|
||
| if (!angular.equals($state.vis, savedVisState)) { | ||
| // NOTE: Why would appState.vis not equal the savedVisState? | ||
|
||
| if (!angular.equals(appState.vis, savedVisState)) { | ||
| Promise.try(function () { | ||
| editableVis.setState($state.vis); | ||
| editableVis.setState(appState.vis); | ||
| vis.setState(editableVis.getEnabledState()); | ||
| }) | ||
| .catch(courier.redirectWhenMissing({ | ||
| 'index-pattern-field': '/visualize' | ||
| })); | ||
| } | ||
|
|
||
| return $state; | ||
| return appState; | ||
| }()); | ||
|
|
||
| function init() { | ||
|
|
@@ -137,8 +155,14 @@ uiModules | |
| $scope.indexPattern = vis.indexPattern; | ||
| $scope.editableVis = editableVis; | ||
| $scope.state = $state; | ||
|
|
||
| // Create a PersistedState instance. | ||
| $scope.uiState = $state.makeStateful('uiState'); | ||
| // Associate PersistedState instance with the Vis instance, so that | ||
| // `uiStateVal` can be called on it. Currently this is only used to extract | ||
| // map-specific information (e.g. mapZoom, mapCenter). | ||
| vis.setUiState($scope.uiState); | ||
|
|
||
| $scope.timefilter = timefilter; | ||
| $scope.opts = _.pick($scope, 'doSave', 'savedVis', 'shareData', 'timefilter'); | ||
|
|
||
|
|
@@ -239,6 +263,9 @@ uiModules | |
| kbnUrl.change('/visualize', {}); | ||
| }; | ||
|
|
||
| /** | ||
| * Called when the user clicks "Save" button. | ||
| */ | ||
| $scope.doSave = function () { | ||
| savedVis.id = savedVis.title; | ||
| // vis.title was not bound and it's needed to reflect title into visState | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,14 @@ | ||
|
|
||
| /** | ||
| * @name Vis | ||
| * | ||
| * @description This class consists of aggs, params, listeners, title, and type. | ||
| * - Aggs: Instances of AggConfig. | ||
| * - Params: Are these the settings in the Options tab? | ||
|
||
| * | ||
| * Not to be confused with vislib/vis.js. | ||
| */ | ||
|
|
||
| import _ from 'lodash'; | ||
| import AggTypesIndexProvider from 'ui/agg_types/index'; | ||
| import RegistryVisTypesProvider from 'ui/registry/vis_types'; | ||
|
|
@@ -24,7 +35,6 @@ export default function VisFactory(Notifier, Private) { | |
|
|
||
| this.indexPattern = indexPattern; | ||
|
|
||
| // http://aphyr.com/data/posts/317/state.gif | ||
| this.setState(state); | ||
| this.setUiState(uiState); | ||
| } | ||
|
|
@@ -36,6 +46,7 @@ export default function VisFactory(Notifier, Private) { | |
|
|
||
| let schemas = type.schemas; | ||
|
|
||
| // NOTE: What is this doing? | ||
|
||
| let aggs = _.transform(oldState, function (newConfigs, oldConfigs, oldGroupName) { | ||
| let schema = schemas.all.byName[oldGroupName]; | ||
|
|
||
|
|
@@ -119,6 +130,7 @@ export default function VisFactory(Notifier, Private) { | |
| }; | ||
|
|
||
| Vis.prototype.requesting = function () { | ||
| // Invoke requesting() on each agg. Aggs is an instance of AggConfigs. | ||
| _.invoke(this.aggs.getRequestAggs(), 'requesting'); | ||
| }; | ||
|
|
||
|
|
@@ -149,6 +161,11 @@ export default function VisFactory(Notifier, Private) { | |
| Vis.prototype.getUiState = function () { | ||
| return this.__uiState; | ||
| }; | ||
|
|
||
| /** | ||
| * Currently this is only used to extract map-specific information | ||
| * (e.g. mapZoom, mapCenter). | ||
| */ | ||
| Vis.prototype.uiStateVal = function (key, val) { | ||
| if (this.hasUiState()) { | ||
| if (_.isUndefined(val)) { | ||
|
|
||
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.
@spalger Question
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
editableVisis intended to be a mirror of the vis object, and as such it needs to go through the same lifecycle methods that vis does (in this case#requesting()). I'm not certain what benefits from the requesting method being called on the editable vis though...