From 69009214ca5e15d20491de9581ef5a72df80a376 Mon Sep 17 00:00:00 2001 From: Spencer Alger Date: Tue, 15 Apr 2014 10:43:05 -0700 Subject: [PATCH] restored visualize app to it's previous working state, now backed by savedObject --- .../apps/visualize/controllers/editor.js | 15 +++--- .../apps/visualize/controllers/wizard.js | 21 -------- .../visualize/directives/config_controlls.js | 3 +- .../visualize/directives/visualization.js | 52 ++----------------- .../visualize/{editor.html => index.html} | 0 src/kibana/apps/visualize/index.js | 9 ++-- .../visualize/saved_visualizations/_aggs.js | 3 +- .../saved_visualizations/_build_chart_data.js | 10 +++- .../saved_visualizations/_read_config.js | 9 +++- .../saved_visualizations/_saved_vis.js | 44 +++++++++++----- .../resp_converters/histogram.js | 9 +++- src/kibana/apps/visualize/wizard.html | 23 -------- .../components/saved_object/saved_object.js | 6 +-- 13 files changed, 80 insertions(+), 124 deletions(-) delete mode 100644 src/kibana/apps/visualize/controllers/wizard.js rename src/kibana/apps/visualize/{editor.html => index.html} (100%) delete mode 100644 src/kibana/apps/visualize/wizard.html diff --git a/src/kibana/apps/visualize/controllers/editor.js b/src/kibana/apps/visualize/controllers/editor.js index 5d043ec02bbc63..5d1fdabd497185 100644 --- a/src/kibana/apps/visualize/controllers/editor.js +++ b/src/kibana/apps/visualize/controllers/editor.js @@ -21,11 +21,11 @@ define(function (require) { $scope.refreshFields = function () { $scope.fields = null; - vis.dataSource.clearFieldCache().then(getFields, notify.error); + vis.searchSource.clearFieldCache().then(getFields, notify.error); }; function getFields() { - return vis.dataSource.getFields() + return vis.searchSource.getFields() .then(function (fieldsHash) { // create a sorted list of the fields for display purposes $scope.fields = _(fieldsHash) @@ -49,8 +49,8 @@ define(function (require) { $scope.visConfigCategories = visConfigCategories; $scope.$on('change:config.defaultIndex', function () { - if (!vis.dataSource.get('index')) { - vis.dataSource.index(config.get('defaultIndex')); + if (!vis.searchSource.get('index')) { + vis.searchSource.index(config.get('defaultIndex')); getFields(); } }); @@ -73,7 +73,8 @@ define(function (require) { if (!config.dimension) { // use the global aggregation if we don't have any dimensions config.dimension = [{ - agg: 'global' + agg: 'global', + aggParams: {} }]; } @@ -100,7 +101,7 @@ define(function (require) { notify.log('config', config); notify.log('aggs', dsl.aggs); - vis.dataSource.aggs(dsl.aggs); + vis.searchSource.aggs(dsl.aggs); notify.event('update data source', true); }; @@ -109,7 +110,7 @@ define(function (require) { *********/ $scope.doVisualize = function () { updateDataSource(); - vis.dataSource.fetch(); + vis.searchSource.fetch(); }; $scope.doSave = function () { updateDataSource(); diff --git a/src/kibana/apps/visualize/controllers/wizard.js b/src/kibana/apps/visualize/controllers/wizard.js deleted file mode 100644 index 92aee79e6bd878..00000000000000 --- a/src/kibana/apps/visualize/controllers/wizard.js +++ /dev/null @@ -1,21 +0,0 @@ -define(function (require) { - var _ = require('lodash'); - - require('../saved_visualizations/saved_visualizations'); - require('notify/notify'); - require('saved_object/finder.directive'); - require('apps/discover/saved_searches/saved_searches'); - - var app = require('modules').get('app/visualize', [ - 'kibana/notify', - 'kibana/courier' - ]); - - app.controller('VisualizeWizard', function ($route, $scope, courier, createNotifier, config, $location, savedSearches) { - var notify = createNotifier({ - location: 'Visualization Wizard' - }); - - $scope.savedSearches = savedSearches; - }); -}); \ No newline at end of file diff --git a/src/kibana/apps/visualize/directives/config_controlls.js b/src/kibana/apps/visualize/directives/config_controlls.js index 49f81600736278..89ba75105431e1 100644 --- a/src/kibana/apps/visualize/directives/config_controlls.js +++ b/src/kibana/apps/visualize/directives/config_controlls.js @@ -1,6 +1,7 @@ define(function (require) { var app = require('modules').get('app/visualize'); var _ = require('lodash'); + var aggs = require('../saved_visualizations/_aggs'); var templates = { orderAndSize: require('text!../partials/controls/order_and_size.html'), @@ -8,7 +9,7 @@ define(function (require) { globalLocal: require('text!../partials/controls/global_local.html') }; - app.directive('visConfigControls', function ($compile, visConfigCategories, aggs) { + app.directive('visConfigControls', function ($compile, visConfigCategories) { return { restrict: 'E', scope: { diff --git a/src/kibana/apps/visualize/directives/visualization.js b/src/kibana/apps/visualize/directives/visualization.js index 71affe402b3230..575db41fd949fc 100644 --- a/src/kibana/apps/visualize/directives/visualization.js +++ b/src/kibana/apps/visualize/directives/visualization.js @@ -5,7 +5,7 @@ define(function (require) { function VisualizationDirective(createNotifier) { return { restrict: 'E', - template: '
', + template: '
{{ data | json }}
', scope: { vis: '=' }, @@ -15,55 +15,13 @@ define(function (require) { location: vis.type + ' visualization' }); - function renderData(data, $el) { - var splitBy, splits, inherit; - - if (data.rows) { - splits = data.rows; - splitBy = 'height'; - inherit = 'width'; - } - else if (data.columns) { - splits = data.columns; - splitBy = 'width'; - inherit = 'height'; - } - - if (splitBy && splits && inherit) { - var splitSize = $el[splitBy]() / splits.length; - var charts = splits.map(function (splitData) { - // create the element that will contain this splits data - var $splitEl = $(document.createElement('div')); - - // set the height and width - $splitEl[splitBy](splitSize); - $splitEl[inherit]('100%'); - - // append it to the parent - $el.append($splitEl); - - // render the splits data into the new $el - return renderData(splitData, $splitEl); - }); - return charts; - } - else { - // we can ignore splits completely now - var chart = new k4d3.Chart($el.get(0), { - type: 'histogram' - }); - chart.render(data); - return chart; - } - } - - vis.dataSource.onResults().then(function onResults(resp) { + vis.searchSource.onResults().then(function onResults(resp) { notify.event('render visualization'); - $el.html(''); - renderData(vis.buildChartDataFromResponse(resp), $el); + $scope.data = vis.buildChartDataFromResponse(resp); notify.event('render visualization', true); - return vis.dataSource.onResults(onResults); + window.canvasVisSource = vis.searchSource; + return vis.searchSource.onResults().then(onResults); }).catch(notify.fatal); } }; diff --git a/src/kibana/apps/visualize/editor.html b/src/kibana/apps/visualize/index.html similarity index 100% rename from src/kibana/apps/visualize/editor.html rename to src/kibana/apps/visualize/index.html diff --git a/src/kibana/apps/visualize/index.js b/src/kibana/apps/visualize/index.js index d484e1eb02475d..4df262c55ddb0a 100644 --- a/src/kibana/apps/visualize/index.js +++ b/src/kibana/apps/visualize/index.js @@ -1,7 +1,6 @@ define(function (require) { require('css!./styles/main.css'); - require('./controllers/wizard'); require('./controllers/editor'); require('./directives/config_category'); @@ -10,13 +9,13 @@ define(function (require) { require('routes') .when('/visualize', { - template: require('text!./wizard.html') + redirectTo: '/visualize/histogram' }) .when('/visualize/:type/:id?', { - template: require('text!./editor.html'), + template: require('text!./index.html'), resolve: { - vis: function ($route, savedVis) { - return savedVis.get($route.current.params.type, $route.current.params.id); + vis: function ($route, savedVisualizations) { + return savedVisualizations.get($route.current.params.type, $route.current.params.id); } } }); diff --git a/src/kibana/apps/visualize/saved_visualizations/_aggs.js b/src/kibana/apps/visualize/saved_visualizations/_aggs.js index 598d2584afacb1..5691a73a3657c9 100644 --- a/src/kibana/apps/visualize/saved_visualizations/_aggs.js +++ b/src/kibana/apps/visualize/saved_visualizations/_aggs.js @@ -66,7 +66,8 @@ define(function (require) { } }, makeLabel: function (params) { - var order = _.find(aggs.params.order.options, { val: params.order._count }); + var agg = aggs.byName.terms; + var order = _.find(agg.params.order.options, { val: params.order._count }); return order.display + ' ' + params.size + ' ' + params.field; } }, diff --git a/src/kibana/apps/visualize/saved_visualizations/_build_chart_data.js b/src/kibana/apps/visualize/saved_visualizations/_build_chart_data.js index f832f1ba4316a6..402af7eedd994d 100644 --- a/src/kibana/apps/visualize/saved_visualizations/_build_chart_data.js +++ b/src/kibana/apps/visualize/saved_visualizations/_build_chart_data.js @@ -1,9 +1,10 @@ define(function (require) { var converters = require('./resp_converters/index'); + var aggs = require('./_aggs'); // private functionality for Vis.buildChartDataFromResp() - return function (createNotifier, aggs) { + return function (createNotifier) { var notify = createNotifier(); return function (resp) { @@ -151,6 +152,13 @@ define(function (require) { }; if (resp.aggregations) { + if (!configs.length) { + configs.push({ + categoryName: 'metric', + agg: aggs.byName.count.name, + label: aggs.byName.count.display + }); + } splitAndFlatten(chartData, resp.aggregations); } diff --git a/src/kibana/apps/visualize/saved_visualizations/_read_config.js b/src/kibana/apps/visualize/saved_visualizations/_read_config.js index 3d3afad5d0cac7..37612b1f60d3aa 100644 --- a/src/kibana/apps/visualize/saved_visualizations/_read_config.js +++ b/src/kibana/apps/visualize/saved_visualizations/_read_config.js @@ -42,9 +42,14 @@ define(function (require) { field: config.field }; - // copy over the row if this is a split - if (config.categoryName === 'split') { + // copy over other properties based ont he category + switch (config.categoryName) { + case 'split': validated.row = !!config.row; + break; + case 'group': + validated.global = !!config.global; + break; } // this function will move valus from config.* to validated.aggParams.* when they are diff --git a/src/kibana/apps/visualize/saved_visualizations/_saved_vis.js b/src/kibana/apps/visualize/saved_visualizations/_saved_vis.js index 29f404020f8c98..2289802378148d 100644 --- a/src/kibana/apps/visualize/saved_visualizations/_saved_vis.js +++ b/src/kibana/apps/visualize/saved_visualizations/_saved_vis.js @@ -4,13 +4,17 @@ define(function (require) { var configCats = require('./_config_categories'); var aggs = require('./_aggs'); + var typeDefs = require('./_type_defs'); require('services/root_search'); var module = require('modules').get('kibana/services'); - module.factory('Vis', function (config, $injector, SavedObject, rootSearch, Promise, savedSearches) { - function Vis(id) { + module.factory('SavedVis', function (config, $injector, SavedObject, rootSearch, Promise, savedSearches) { + function SavedVis(type, id) { + var typeDef = typeDefs.byName[type]; + if (!typeDef) throw new Error('Unknown visualization type: "' + type + '"'); + SavedObject.call(this, { type: 'visualization', @@ -18,25 +22,29 @@ define(function (require) { mapping: { stateJSON: 'string', - savedSearchId: 'string' + savedSearchId: 'string', + typeName: 'string', }, defaults: { - stateJSON: '[]' + stateJSON: '{}', + typeName: type, }, searchSource: true, - afterESResp: function setVisState(resp) { + afterESResp: function setVisState() { var vis = this; var state = {}; if (vis.stateJSON) try { state = JSON.parse(vis.stateJSON); } catch (e) {} - var parent = vis.savedSearch; - if (!parent || parent.id !== vis.savedSearchId) { - // returns a promise - parent = savedSearches.get(vis.savedSearchId); + var parent = rootSearch; + if (vis.savedSearchId) { + if (!vis.savedSearch || vis.savedSearch.id !== vis.savedSearchId) { + // returns a promise + parent = savedSearches.get(vis.savedSearchId); + } } configCats.forEach(function (category) { @@ -53,7 +61,11 @@ define(function (require) { return Promise.cast(parent) .then(function (parent) { vis.savedSearch = parent; - vis.searchSource.inherits(vis.savedSearch); + + vis.searchSource + .inherits(vis.savedSearch) + .size(0); + vis._fillConfigsToMinimum(); // get and cache the field list return vis.searchSource.getFields(); @@ -85,6 +97,14 @@ define(function (require) { // satify the min count for each category configCats.fetchOrder.forEach(function (category) { var myCat = vis[category.name]; + + if (!myCat) { + + myCat = _.defaults(typeDef.config[category.name] || {}, category.defaults); + myCat.configs = []; + vis[category.name] = myCat; + } + if (myCat.configs.length < myCat.min) { _.times(myCat.min - myCat.configs.length, function () { vis.addConfig(category.name); @@ -107,8 +127,8 @@ define(function (require) { */ this.buildChartDataFromResponse = $injector.invoke(require('./_build_chart_data')); } - inherits(Vis, SavedObject); + inherits(SavedVis, SavedObject); - return Vis; + return SavedVis; }); }); \ No newline at end of file diff --git a/src/kibana/apps/visualize/saved_visualizations/resp_converters/histogram.js b/src/kibana/apps/visualize/saved_visualizations/resp_converters/histogram.js index aa5bf7c4f133dd..e3bf3ac9482c43 100644 --- a/src/kibana/apps/visualize/saved_visualizations/resp_converters/histogram.js +++ b/src/kibana/apps/visualize/saved_visualizations/resp_converters/histogram.js @@ -11,6 +11,13 @@ define(function (require) { // index of y-axis var iY = _.findIndex(columns, { categoryName: 'metric'}); + // when we don't have an x-axis, just push everything into '_all' + if (iX === -1) { + iX = columns.push({ + label: '' + }) - 1; + } + chart.xAxisLabel = columns[iX].label; chart.yAxisLabel = columns[iY].label; @@ -38,7 +45,7 @@ define(function (require) { } s.values.push({ - x: row[iX], + x: row[iX] || '_all', y: row[iY === -1 ? row.length - 1 : iY] // y-axis value }); }); diff --git a/src/kibana/apps/visualize/wizard.html b/src/kibana/apps/visualize/wizard.html deleted file mode 100644 index a5483c8a032791..00000000000000 --- a/src/kibana/apps/visualize/wizard.html +++ /dev/null @@ -1,23 +0,0 @@ -
-

- Create a new visualization -

-
-

- Choose a Saved Search -

-
- -
-
-

- Choose a Visualization Type -

-
    -
  • - -
  • -
-
-
-
\ No newline at end of file diff --git a/src/kibana/components/saved_object/saved_object.js b/src/kibana/components/saved_object/saved_object.js index 77260e9b194049..34fe83a5b92dba 100644 --- a/src/kibana/components/saved_object/saved_object.js +++ b/src/kibana/components/saved_object/saved_object.js @@ -34,7 +34,7 @@ define(function (require) { // default field values, assigned when the source is loaded var defaults = config.defaults || {}; - var afterESResp = config.afterESResp || null; + var afterESResp = config.afterESResp || _.noop; // optional search source which this object configures obj.searchSource = config.searchSource && courier.createSource('search'); @@ -97,7 +97,7 @@ define(function (require) { if (!obj.id) { // just assign the defaults and be done _.assign(obj, defaults); - return false; + return afterESResp.call(obj); } // fetch the object from ES @@ -123,7 +123,7 @@ define(function (require) { obj.searchSource.set(state); } - return Promise.cast(afterESResp && afterESResp.call(obj, resp)) + return Promise.cast(afterESResp.call(obj, resp)) .then(function () { // Any time obj is updated, re-call applyESResp docSource.onUpdate().then(applyESResp, notify.fatal);