UNPKG

@spalger/kibana

Version:

Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elastic

155 lines (132 loc) 4.54 kB
define(function (require) { return function LayoutFactory(Private) { var d3 = require('d3'); var _ = require('lodash'); var layoutType = Private(require('ui/vislib/lib/layout/layout_types')); /** * Builds the visualization DOM layout * * The Layout Constructor is responsible for rendering the visualization * layout, which includes all the DOM div elements. * Input: * 1. DOM div - parent element for which the layout is attached * 2. data - data is bound to the div element * 3. chartType (e.g. 'histogram') - specifies the layout type to grab * * @class Layout * @constructor * @param el {HTMLElement} HTML element to which the chart will be appended * @param data {Object} Elasticsearch query results for this specific chart * @param chartType {Object} Reference to chart functions, i.e. Pie */ function Layout(el, data, chartType, opts) { if (!(this instanceof Layout)) { return new Layout(el, data, chartType, opts); } this.el = el; this.data = data; this.opts = opts; this.layoutType = layoutType[chartType](this.el, this.data); } // Render the layout /** * Renders visualization HTML layout * Remove all elements from the current visualization and creates the layout * * @method render */ Layout.prototype.render = function () { this.removeAll(this.el); this.createLayout(this.layoutType); }; /** * Create the layout based on the json array provided * for each object in the layout array, call the layout function * * @method createLayout * @param arr {Array} Json array * @returns {*} Creates the visualization layout */ Layout.prototype.createLayout = function (arr) { var self = this; return _.each(arr, function (obj) { self.layout(obj); }); }; /** * Appends a DOM element based on the object keys * check to see if reference to DOM element is string but not class selector * Create a class selector * * @method layout * @param obj {Object} Instructions for creating the layout of a DOM Element * @returns {*} DOM Element */ Layout.prototype.layout = function (obj) { if (!obj.parent) { throw new Error('No parent element provided'); } if (!obj.type) { throw new Error('No element type provided'); } if (typeof obj.type !== 'string') { throw new Error(obj.type + ' must be a string'); } if (typeof obj.parent === 'string' && obj.parent.charAt(0) !== '.') { obj.parent = '.' + obj.parent; } var childEl = this.appendElem(obj.parent, obj.type, obj.class); if (obj.datum) { childEl.datum(obj.datum); } if (obj.splits) { childEl.call(obj.splits, obj.parent, this.opts); } if (obj.children) { var newParent = childEl[0][0]; _.forEach(obj.children, function (obj) { if (!obj.parent) { obj.parent = newParent; } }); this.createLayout(obj.children); } return childEl; }; /** * Appends a `type` of DOM element to `el` and gives it a class name attribute `className` * * @method appendElem * @param el {HTMLElement} Reference to a DOM Element * @param type {String} DOM element type * @param className {String} CSS class name * @returns {*} Reference to D3 Selection */ Layout.prototype.appendElem = function (el, type, className) { if (!el || !type || !className) { throw new Error('Function requires that an el, type, and class be provided'); } if (typeof el === 'string') { // Create a DOM reference with a d3 selection // Need to make sure that the `el` is bound to this object // to prevent it from being appended to another Layout el = d3.select(this.el) .select(el)[0][0]; } return d3.select(el) .append(type) .attr('class', className); }; /** * Removes all DOM elements from DOM element * * @method removeAll * @param el {HTMLElement} Reference to DOM element * @returns {D3.Selection|D3.Transition.Transition} Reference to an empty DOM element */ Layout.prototype.removeAll = function (el) { return d3.select(el).selectAll('*').remove(); }; return Layout; }; });