@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
179 lines (157 loc) • 5.32 kB
JavaScript
define(function (require) {
return function VisFactory(Private) {
var _ = require('lodash');
var d3 = require('d3');
var ResizeChecker = Private(require('ui/vislib/lib/resize_checker'));
var Events = Private(require('ui/events'));
var handlerTypes = Private(require('ui/vislib/lib/handler/handler_types'));
var chartTypes = Private(require('ui/vislib/visualizations/vis_types'));
var errors = require('ui/errors');
require('ui/vislib/styles/main.less');
/**
* Creates the visualizations.
*
* @class Vis
* @constructor
* @param $el {HTMLElement} jQuery selected HTML element
* @param config {Object} Parameters that define the chart type and chart options
*/
_.class(Vis).inherits(Events);
function Vis($el, config) {
if (!(this instanceof Vis)) {
return new Vis($el, config);
}
Vis.Super.apply(this, arguments);
this.el = $el.get ? $el.get(0) : $el;
this.ChartClass = chartTypes[config.type];
this._attr = _.defaults({}, config || {}, {});
// bind the resize function so it can be used as an event handler
this.resize = _.bind(this.resize, this);
this.resizeChecker = new ResizeChecker(this.el);
this.resizeChecker.on('resize', this.resize);
}
/**
* Renders the visualization
*
* @method render
* @param data {Object} Elasticsearch query results
*/
Vis.prototype.render = function (data) {
var chartType = this._attr.type;
if (!data) {
throw new Error('No valid data!');
}
if (this.handler) {
this.data = null;
this._runOnHandler('destroy');
}
this.data = data;
this.handler = handlerTypes[chartType](this) || handlerTypes.column(this);
this._runOnHandler('render');
};
/**
* Resizes the visualization
*
* @method resize
*/
Vis.prototype.resize = function () {
if (!this.data) {
// TODO: need to come up with a solution for resizing when no data is available
return;
}
if (this.handler && _.isFunction(this.handler.resize)) {
this._runOnHandler('resize');
} else {
this.render(this.data);
}
};
Vis.prototype._runOnHandler = function (method) {
try {
this.handler[method]();
} catch (error) {
// If involving height and width of the container, log error to screen.
// Because we have to wait for the DOM element to initialize, we do not
// want to throw an error when the DOM `el` is zero
if (error instanceof errors.ContainerTooSmall ||
error instanceof errors.InvalidWiggleSelection ||
error instanceof errors.InvalidLogScaleValues ||
error instanceof errors.PieContainsAllZeros ||
error instanceof errors.NotEnoughData ||
error instanceof errors.NoResults) {
this.handler.error(error.message);
} else {
throw error;
}
}
};
/**
* Destroys the visualization
* Removes chart and all elements associated with it.
* Removes chart and all elements associated with it.
* Remove event listeners and pass destroy call down to owned objects.
*
* @method destroy
*/
Vis.prototype.destroy = function () {
var selection = d3.select(this.el).select('.vis-wrapper');
this.resizeChecker.off('resize', this.resize);
this.resizeChecker.destroy();
if (this.handler) this._runOnHandler('destroy');
selection.remove();
selection = null;
};
/**
* Sets attributes on the visualization
*
* @method set
* @param name {String} An attribute name
* @param val {*} Value to which the attribute name is set
*/
Vis.prototype.set = function (name, val) {
this._attr[name] = val;
this.render(this.data);
};
/**
* Gets attributes from the visualization
*
* @method get
* @param name {String} An attribute name
* @returns {*} The value of the attribute name
*/
Vis.prototype.get = function (name) {
return this._attr[name];
};
/**
* Turns on event listeners.
*
* @param event {String}
* @param listener{Function}
* @returns {*}
*/
Vis.prototype.on = function (event, listener) {
var first = this.listenerCount(event) === 0;
var ret = Events.prototype.on.call(this, event, listener);
var added = this.listenerCount(event) > 0;
// if this is the first listener added for the event
// enable the event in the handler
if (first && added && this.handler) this.handler.enable(event);
return ret;
};
/**
* Turns off event listeners.
*
* @param event {String}
* @param listener{Function}
* @returns {*}
*/
Vis.prototype.off = function (event, listener) {
var last = this.listenerCount(event) === 1;
var ret = Events.prototype.off.call(this, event, listener);
var removed = this.listenerCount(event) === 0;
// Once all listeners are removed, disable the events in the handler
if (last && removed && this.handler) this.handler.disable(event);
return ret;
};
return Vis;
};
});