mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
removed modules folder, renamed files to use lowercase and underscore, made appropriate changes to require references in vislib and the test files, removed console_logs in x_axis, restructured the organization of vislib
This commit is contained in:
parent
acdc482e45
commit
7934946334
24 changed files with 22 additions and 1085 deletions
|
@ -1,54 +0,0 @@
|
|||
define(function (require) {
|
||||
return function AxisTitleFactory(d3, Private) {
|
||||
var $ = require('jquery');
|
||||
var _ = require('lodash');
|
||||
|
||||
var ErrorHandler = Private(require('components/vislib/modules/_error_handler'));
|
||||
|
||||
function AxisTitle(el, xTitle, yTitle) {
|
||||
if (!(this instanceof AxisTitle)) {
|
||||
return new AxisTitle(el, xTitle, yTitle);
|
||||
}
|
||||
|
||||
this.el = el;
|
||||
this.xTitle = xTitle;
|
||||
this.yTitle = yTitle;
|
||||
}
|
||||
|
||||
_(AxisTitle.prototype).extend(ErrorHandler.prototype);
|
||||
|
||||
AxisTitle.prototype.render = function () {
|
||||
d3.select(this.el).select('.x-axis-title').call(this.draw(this.xTitle));
|
||||
d3.select(this.el).select('.y-axis-title').call(this.draw(this.yTitle));
|
||||
};
|
||||
|
||||
AxisTitle.prototype.draw = function (title) {
|
||||
var self = this;
|
||||
|
||||
return function (selection) {
|
||||
selection.each(function () {
|
||||
var div = d3.select(this);
|
||||
var width = $(this).width();
|
||||
var height = $(this).height();
|
||||
|
||||
self.validateWidthandHeight(width, height);
|
||||
|
||||
div.append('svg')
|
||||
.attr('width', width)
|
||||
.attr('height', height)
|
||||
.append('text')
|
||||
.attr('transform', function () {
|
||||
if (div.attr('class') === 'x-axis-title') {
|
||||
return 'translate(' + width / 2 + ',11)';
|
||||
}
|
||||
return 'translate(11,' + height / 2 + ')rotate(270)';
|
||||
})
|
||||
.attr('text-anchor', 'middle')
|
||||
.text(title);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
return AxisTitle;
|
||||
};
|
||||
});
|
|
@ -1,79 +0,0 @@
|
|||
define(function (require) {
|
||||
return function ChartTitleFactory(d3, Private) {
|
||||
var $ = require('jquery');
|
||||
var _ = require('lodash');
|
||||
|
||||
var ErrorHandler = Private(require('components/vislib/modules/_error_handler'));
|
||||
|
||||
function ChartTitle(el) {
|
||||
if (!(this instanceof ChartTitle)) {
|
||||
return new ChartTitle(el);
|
||||
}
|
||||
|
||||
this.el = el;
|
||||
}
|
||||
|
||||
_(ChartTitle.prototype).extend(ErrorHandler.prototype);
|
||||
|
||||
ChartTitle.prototype.render = function () {
|
||||
d3.select(this.el).selectAll('.chart-title').call(this.draw());
|
||||
d3.select(this.el).selectAll('.chart-title').call(this.truncate());
|
||||
};
|
||||
|
||||
ChartTitle.prototype.truncate = function () {
|
||||
return function (selection) {
|
||||
selection.each(function () {
|
||||
var div = d3.select(this);
|
||||
var dataType = this.parentNode.__data__.rows ? 'rows' : 'columns';
|
||||
var text = div.select('text');
|
||||
var textLength = text.node().getComputedTextLength();
|
||||
var maxWidth = dataType === 'rows' ? $(this).height() : $(this).width();
|
||||
var subtractionPercentage = maxWidth * 0.05;
|
||||
var str = text.text();
|
||||
|
||||
maxWidth = maxWidth - subtractionPercentage;
|
||||
if (textLength > maxWidth) {
|
||||
var avg = textLength / str.length;
|
||||
var end = Math.floor(maxWidth / avg);
|
||||
|
||||
str = str.substr(0, end) + '...';
|
||||
}
|
||||
|
||||
text.text(str);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
ChartTitle.prototype.draw = function () {
|
||||
var self = this;
|
||||
|
||||
return function (selection) {
|
||||
selection.each(function () {
|
||||
var div = d3.select(this);
|
||||
var dataType = this.parentNode.__data__.rows ? 'rows' : 'columns';
|
||||
var width = $(this).width();
|
||||
var height = $(this).height();
|
||||
|
||||
self.validateWidthandHeight(width, height);
|
||||
|
||||
div.append('svg')
|
||||
.attr('width', width)
|
||||
.attr('height', height)
|
||||
.append('text')
|
||||
.attr('transform', function () {
|
||||
if (dataType === 'rows') {
|
||||
return 'translate(11,' + height / 2 + ')rotate(270)';
|
||||
}
|
||||
return 'translate(' + width / 2 + ',11)';
|
||||
})
|
||||
.attr('text-anchor', 'middle')
|
||||
.text(function (d) {
|
||||
return d.label;
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
return ChartTitle;
|
||||
};
|
||||
});
|
|
@ -1,62 +0,0 @@
|
|||
define(function (require) {
|
||||
return function DataFactory(d3, Private) {
|
||||
var _ = require('lodash');
|
||||
|
||||
var injectZeros = Private(require('components/vislib/components/_functions/zero_injection/inject_zeros'));
|
||||
var orderKeys = Private(require('components/vislib/components/_functions/zero_injection/ordered_x_keys'));
|
||||
var getLabels = Private(require('components/vislib/components/_functions/labels/labels'));
|
||||
var color = Private(require('components/vislib/components/_functions/color/color'));
|
||||
|
||||
function Data(data) {
|
||||
if (!(this instanceof Data)) {
|
||||
return new Data(data);
|
||||
}
|
||||
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
Data.prototype.chartData = function () {
|
||||
if (!this.data.series) {
|
||||
var arr = this.data.rows ? this.data.rows : this.data.columns;
|
||||
return _.pluck(arr);
|
||||
}
|
||||
return [this.data];
|
||||
};
|
||||
|
||||
Data.prototype.get = function (thing) {
|
||||
var data = this.chartData();
|
||||
// returns the first thing in the array
|
||||
return _.pluck(data, thing)[0];
|
||||
};
|
||||
|
||||
Data.prototype.flatten = function () {
|
||||
var data = this.chartData();
|
||||
var series = _.chain(data).pluck('series').pluck().value();
|
||||
var values = [];
|
||||
|
||||
_(series).forEach(function (d) {
|
||||
values.push(_.chain(d).flatten().pluck('values').value());
|
||||
});
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
Data.prototype.injectZeros = function () {
|
||||
return injectZeros(this.data);
|
||||
};
|
||||
|
||||
Data.prototype.xValues = function () {
|
||||
return orderKeys(this.data);
|
||||
};
|
||||
|
||||
Data.prototype.getLabels = function () {
|
||||
return getLabels(this.data);
|
||||
};
|
||||
|
||||
Data.prototype.getColorFunc = function () {
|
||||
return color(this.getLabels(this.data));
|
||||
};
|
||||
|
||||
return Data;
|
||||
};
|
||||
});
|
|
@ -1,125 +0,0 @@
|
|||
define(function (require) {
|
||||
var _ = require('lodash');
|
||||
var $ = require('jquery');
|
||||
|
||||
return function HandlerBaseClass(d3, Private) {
|
||||
var Data = Private(require('components/vislib/modules/Data'));
|
||||
var Layout = Private(require('components/vislib/modules/Layout'));
|
||||
var Legend = Private(require('components/vislib/modules/legend'));
|
||||
var Tooltip = Private(require('components/vislib/modules/tooltip'));
|
||||
var XAxis = Private(require('components/vislib/modules/Xaxis'));
|
||||
var YAxis = Private(require('components/vislib/modules/YAxis'));
|
||||
var AxisTitle = Private(require('components/vislib/modules/AxisTitle'));
|
||||
var ChartTitle = Private(require('components/vislib/modules/ChartTitle'));
|
||||
|
||||
function Handler(vis) {
|
||||
if (!(this instanceof Handler)) {
|
||||
return new Handler(vis);
|
||||
}
|
||||
|
||||
this.data = new Data(vis.data);
|
||||
this.vis = vis;
|
||||
this.el = vis.el;
|
||||
this.ChartClass = vis.ChartClass;
|
||||
this._attr = _.defaults(vis._attr || {}, {
|
||||
'margin' : { top: 10, right: 3, bottom: 5, left: 3 },
|
||||
destroyFlag: false
|
||||
});
|
||||
|
||||
// Visualization Classes
|
||||
this.layout = new Layout(this.el, this.data.injectZeros(), this._attr.type);
|
||||
|
||||
if (this._attr.addLegend) {
|
||||
this.legend = new Legend(this.data.getLabels(), this.data.getColorFunc(), this._attr, this.el);
|
||||
}
|
||||
|
||||
if (this._attr.addTooltip) {
|
||||
this.tooltip = new Tooltip(this.data.get('tooltipFormatter'));
|
||||
}
|
||||
|
||||
this.xAxis = new XAxis({
|
||||
el: this.el,
|
||||
xValues: this.data.xValues(),
|
||||
ordered: this.data.get('ordered'),
|
||||
xAxisFormatter: this.data.get('xAxisFormatter'),
|
||||
_attr: this._attr
|
||||
});
|
||||
this.yAxis = new YAxis({
|
||||
el: this.el,
|
||||
chartData: this.data.chartData(),
|
||||
dataArray: this.data.flatten(),
|
||||
_attr: this._attr
|
||||
});
|
||||
this.axisTitle = new AxisTitle(this.el, this.data.get('xAxisLabel'), this.data.get('yAxisLabel'));
|
||||
this.chartTitle = new ChartTitle(this.el);
|
||||
|
||||
this.renderArray = [
|
||||
this.layout,
|
||||
this.legend,
|
||||
this.tooltip,
|
||||
this.xAxis,
|
||||
this.yAxis,
|
||||
this.axisTitle,
|
||||
this.chartTitle
|
||||
];
|
||||
}
|
||||
|
||||
Handler.prototype.render = function () {
|
||||
var self = this;
|
||||
var charts = this.charts = [];
|
||||
|
||||
_.forEach(this.renderArray, function (property) {
|
||||
if (typeof property.render === 'function') {
|
||||
property.render();
|
||||
}
|
||||
});
|
||||
|
||||
d3.select(this.el)
|
||||
.selectAll('.chart')
|
||||
.each(function (chartData) {
|
||||
var chart = new self.ChartClass(self, this, chartData);
|
||||
|
||||
// Bind events to the chart
|
||||
d3.rebind(chart, chart._attr.dispatch, 'on');
|
||||
|
||||
// Bubbles the events up to the Vis Class and Events Class
|
||||
chart.on('click', function (e) {
|
||||
self.vis.emit('click', e);
|
||||
});
|
||||
|
||||
chart.on('hover', function (e) {
|
||||
self.vis.emit('hover', e);
|
||||
});
|
||||
|
||||
chart.on('brush', function (e) {
|
||||
self.vis.emit('brush', e);
|
||||
});
|
||||
|
||||
charts.push(chart);
|
||||
chart.render();
|
||||
});
|
||||
};
|
||||
|
||||
Handler.prototype.removeAll = function (el) {
|
||||
return d3.select(el).selectAll('*').remove();
|
||||
};
|
||||
|
||||
Handler.prototype.error = function (message) {
|
||||
// Removes the legend container
|
||||
this.removeAll(this.el);
|
||||
|
||||
return d3.select(this.el)
|
||||
.append('div')
|
||||
.attr('class', 'error-wrapper')
|
||||
.append('div')
|
||||
.attr('class', 'chart error')
|
||||
.append('p')
|
||||
.style('line-height', function () {
|
||||
return $(this.el).height() + 'px';
|
||||
})
|
||||
.text(message);
|
||||
};
|
||||
|
||||
return Handler;
|
||||
};
|
||||
});
|
|
@ -1,94 +0,0 @@
|
|||
define(function (require) {
|
||||
return function LayoutFactory(d3, Private) {
|
||||
var _ = require('lodash');
|
||||
|
||||
var layoutType = Private(require('components/vislib/layout_types'));
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
function Layout(el, data, chartType) {
|
||||
if (!(this instanceof Layout)) {
|
||||
return new Layout(el, data, chartType);
|
||||
}
|
||||
|
||||
this.el = el;
|
||||
this.data = data;
|
||||
this.layoutType = layoutType[chartType](el, data);
|
||||
}
|
||||
|
||||
Layout.prototype.render = function () {
|
||||
// Remove all elements from the current visualization
|
||||
this.removeAll(this.el);
|
||||
|
||||
// Create the layout
|
||||
this.createLayout(this.layoutType);
|
||||
};
|
||||
|
||||
// Accepts the layoutType array
|
||||
Layout.prototype.createLayout = function (arr) {
|
||||
var self = this;
|
||||
|
||||
// for each object in the layout array, calls the layout function on it
|
||||
return _(arr).forEach(function (obj) {
|
||||
self.layout(obj);
|
||||
});
|
||||
};
|
||||
|
||||
// Appends a DOM element based on the object keys
|
||||
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 = '.' + obj.parent;
|
||||
}
|
||||
|
||||
var el = this.appendElem(obj.parent, obj.type, obj.class);
|
||||
|
||||
if (obj.datum) {
|
||||
el.datum(obj.datum);
|
||||
}
|
||||
|
||||
if (obj.splits) {
|
||||
d3.select('.' + obj.class).call(obj.splits);
|
||||
}
|
||||
|
||||
if (obj.children) {
|
||||
this.createLayout(obj.children);
|
||||
}
|
||||
|
||||
return el;
|
||||
};
|
||||
|
||||
// Appends a `type` of DOM element to `el` and gives it a class attribute `elClass`
|
||||
Layout.prototype.appendElem = function (el, type, className) {
|
||||
if (!el || !type || !className) {
|
||||
throw new Error('Function requires that an el, type, and class be provided');
|
||||
}
|
||||
return d3.select(el).append(type)
|
||||
.attr('class', className);
|
||||
};
|
||||
|
||||
// Removes all DOM elements from `el`
|
||||
Layout.prototype.removeAll = function (el) {
|
||||
return d3.select(el).selectAll('*').remove();
|
||||
};
|
||||
|
||||
return Layout;
|
||||
};
|
||||
});
|
|
@ -1,299 +0,0 @@
|
|||
define(function (require) {
|
||||
return function XAxisFactory(d3, Private) {
|
||||
var $ = require('jquery');
|
||||
var _ = require('lodash');
|
||||
|
||||
var ErrorHandler = Private(require('components/vislib/modules/_error_handler'));
|
||||
function XAxis(args) {
|
||||
if (!(this instanceof XAxis)) {
|
||||
return new XAxis(args);
|
||||
}
|
||||
|
||||
this.el = args.el;
|
||||
this.xValues = args.xValues;
|
||||
this.ordered = args.ordered;
|
||||
this.xAxisFormatter = args.xAxisFormatter;
|
||||
this._attr = args._attr;
|
||||
}
|
||||
|
||||
_(XAxis.prototype).extend(ErrorHandler.prototype);
|
||||
|
||||
XAxis.prototype.render = function () {
|
||||
d3.select(this.el).selectAll('.x-axis-div').call(this.draw());
|
||||
d3.select(this.el).selectAll('.x-axis-div').call(this.checkTickLabels());
|
||||
d3.select(this.el).selectAll('.x-axis-div').call(this.resizeAxisLayoutForLabels());
|
||||
};
|
||||
|
||||
XAxis.prototype.getScale = function (ordered) {
|
||||
if (ordered && ordered.date) {
|
||||
return d3.time.scale();
|
||||
}
|
||||
return d3.scale.ordinal();
|
||||
};
|
||||
|
||||
XAxis.prototype.getDomain = function (scale, ordered) {
|
||||
if (ordered && ordered.date) {
|
||||
// Calculate the min date, max date, and time interval;
|
||||
return this.getTimeDomain(scale, this.xValues, ordered);
|
||||
}
|
||||
return this.getOrdinalDomain(scale, this.xValues);
|
||||
};
|
||||
|
||||
XAxis.prototype.getTimeDomain = function (scale, xValues, ordered) {
|
||||
// Should think about replacing
|
||||
var spacingPercentage = 0.25;
|
||||
var maxXValue = d3.max(xValues);
|
||||
var timeInterval = ordered.interval;
|
||||
// Take the min of the xValues or the ordered object
|
||||
var minDate = Math.min(d3.min(xValues), ordered.min);
|
||||
// Take the max of the xValues or the max date that is sent
|
||||
var maxDate = +maxXValue <= ordered.max ? ordered.max : +maxXValue + timeInterval;
|
||||
|
||||
scale.domain([minDate, maxDate]);
|
||||
|
||||
return scale;
|
||||
};
|
||||
|
||||
XAxis.prototype.getOrdinalDomain = function (scale, xValues) {
|
||||
return scale.domain(xValues);
|
||||
};
|
||||
|
||||
XAxis.prototype.getRange = function (scale, ordered, width) {
|
||||
if (ordered && ordered.date) {
|
||||
scale.range([0, width]);
|
||||
return scale;
|
||||
}
|
||||
scale.rangeBands([0, width], 0.1);
|
||||
return scale;
|
||||
};
|
||||
|
||||
XAxis.prototype.getXScale = function (ordered, width) {
|
||||
var scale = this.getScale(ordered);
|
||||
var domain = this.getDomain(scale, ordered);
|
||||
var xScale = this.getRange(domain, ordered, width);
|
||||
|
||||
return xScale;
|
||||
};
|
||||
|
||||
XAxis.prototype.getXAxis = function (width) {
|
||||
this.xAxisFormatter = this.xAxisFormatter;
|
||||
this.xScale = this.getXScale(this.ordered, width);
|
||||
|
||||
if (!this.xScale || _.isNaN(this.xScale)) {
|
||||
throw new Error('xScale is ' + this.xScale);
|
||||
}
|
||||
|
||||
this.xAxis = d3.svg.axis()
|
||||
.scale(this.xScale)
|
||||
.tickFormat(this.xAxisFormatter)
|
||||
.orient('bottom');
|
||||
};
|
||||
|
||||
XAxis.prototype.draw = function () {
|
||||
var self = this;
|
||||
var margin = this._attr.margin;
|
||||
var div;
|
||||
var width;
|
||||
var height;
|
||||
var svg;
|
||||
|
||||
this.getXAxis();
|
||||
|
||||
// set var for discover view
|
||||
if ($('.discover-timechart').length) {
|
||||
self._attr.isDiscover = true;
|
||||
self._attr.isRotated = false;
|
||||
} else {
|
||||
self._attr.isDiscover = false;
|
||||
}
|
||||
return function (selection) {
|
||||
|
||||
selection.each(function () {
|
||||
div = d3.select(this);
|
||||
width = $(this).width() - margin.left - margin.right;
|
||||
height = $(this).height();
|
||||
|
||||
self.validateWidthandHeight(width, height);
|
||||
|
||||
// Return access to xAxis variable on the object
|
||||
self.getXAxis(width);
|
||||
|
||||
svg = div.append('svg')
|
||||
.attr('width', width + margin.left + margin.right)
|
||||
.attr('height', height);
|
||||
|
||||
svg.append('g')
|
||||
.attr('class', 'x axis')
|
||||
.attr('transform', 'translate(' + margin.left + ',0)')
|
||||
.call(self.xAxis);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
XAxis.prototype.checkTickLabels = function (selection) {
|
||||
|
||||
var self = this;
|
||||
var margin = this._attr.margin;
|
||||
var div;
|
||||
var width;
|
||||
var height;
|
||||
var labels;
|
||||
var widthArr = [];
|
||||
var heightArr = [];
|
||||
var subtotalW;
|
||||
var subtotalH;
|
||||
var tickN;
|
||||
var maxWidth;
|
||||
var maxHeight;
|
||||
var total;
|
||||
var nth;
|
||||
var rotate = false;
|
||||
self._attr.isRotated = false;
|
||||
|
||||
return function (selection) {
|
||||
|
||||
selection.each(function () {
|
||||
// select each x axis
|
||||
div = d3.select(this);
|
||||
width = $(this).width() - margin.left - margin.right;
|
||||
height = $(this).height();
|
||||
labels = selection.selectAll('.tick text');
|
||||
|
||||
// total widths for every label from each x axis
|
||||
subtotalW = 0;
|
||||
subtotalH = 0;
|
||||
_.forEach(labels[0], function (n) {
|
||||
subtotalW += n.getBBox().width;
|
||||
subtotalH += n.getBBox().height;
|
||||
});
|
||||
|
||||
widthArr.push(subtotalW);
|
||||
heightArr.push(subtotalH);
|
||||
|
||||
// should rotate if any chart subtotal > width
|
||||
if (subtotalW > width) {
|
||||
rotate = true;
|
||||
}
|
||||
});
|
||||
|
||||
// apply rotate if not discover view
|
||||
if (!self._attr.isDiscover && rotate) {
|
||||
self.rotateAxisLabels(selection);
|
||||
self._attr.isRotated = true;
|
||||
}
|
||||
|
||||
// filter labels to prevent overlap of text
|
||||
if (self._attr.isRotated) {
|
||||
// if rotated, use label heights
|
||||
maxHeight = _.max(heightArr);
|
||||
total = _.reduce(heightArr, function (sum, n) {
|
||||
return sum + (n * 1.05);
|
||||
});
|
||||
nth = 1 + Math.floor(maxHeight / width);
|
||||
} else {
|
||||
// if not rotated, use label widths
|
||||
maxWidth = _.max(widthArr);
|
||||
total = _.reduce(widthArr, function (sum, n) {
|
||||
return sum + (n * 1.05);
|
||||
});
|
||||
nth = 1 + Math.floor(maxWidth / width);
|
||||
}
|
||||
if (nth > 1) {
|
||||
self.filterAxisLabels(selection, nth);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
XAxis.prototype.rotateAxisLabels = function (selection) {
|
||||
return selection.selectAll('.tick text')
|
||||
.style('text-anchor', 'end')
|
||||
.attr('dx', '-.8em')
|
||||
.attr('dy', '-.60em')
|
||||
.attr('transform', function () {
|
||||
return 'rotate(-90)';
|
||||
});
|
||||
};
|
||||
|
||||
XAxis.prototype.filterAxisLabels = function (selection, nth) {
|
||||
var self = this;
|
||||
return selection.selectAll('text')
|
||||
.text(function (d, i) {
|
||||
return i % nth === 0 ? self.xAxisFormatter(d) : '';
|
||||
});
|
||||
};
|
||||
|
||||
XAxis.prototype.resizeAxisLayoutForLabels = function (selection) {
|
||||
var self = this;
|
||||
var visEl = $(self.el);
|
||||
var div;
|
||||
var svg;
|
||||
var tick;
|
||||
var chartwrap;
|
||||
var titlespace;
|
||||
var xwrapper;
|
||||
var xdiv;
|
||||
var xdivwrapper;
|
||||
var yspacerblock;
|
||||
var ratio;
|
||||
var flex;
|
||||
var chartToXaxis;
|
||||
var dataType;
|
||||
|
||||
return function (selection) {
|
||||
var rotScale = d3.scale.linear()
|
||||
.domain([0.14, 0.28, 0.6, 0.8, 0.9, 2.6])
|
||||
.range([5, 10, 30, 55, 80, 100]);
|
||||
var flatScale = d3.scale.linear()
|
||||
.domain([1.3, 8, 14.5, 29])
|
||||
.range([1.1, 9, 13, 30]);
|
||||
|
||||
selection.each(function () {
|
||||
div = d3.select(this);
|
||||
svg = div.select('svg');
|
||||
tick = svg.select('.tick');
|
||||
dataType = this.parentNode.__data__.series ? 'series' : this.parentNode.__data__.rows ? 'rows' : 'columns';
|
||||
|
||||
xwrapper = visEl.find('.x-axis-wrapper');
|
||||
xdiv = visEl.find('.x-axis-div');
|
||||
xdivwrapper = visEl.find('.x-axis-div-wrapper');
|
||||
yspacerblock = visEl.find('.y-axis-spacer-block');
|
||||
|
||||
if (dataType === 'series') {
|
||||
chartwrap = visEl.find('.chart-wrapper');
|
||||
titlespace = 15;
|
||||
} else if (dataType === 'rows') {
|
||||
chartwrap = visEl.find('.chart-wrapper-row');
|
||||
titlespace = 15;
|
||||
} else {
|
||||
chartwrap = visEl.find('.chart-wrapper-column');
|
||||
titlespace = 30;
|
||||
}
|
||||
|
||||
if (!self._attr.isRotated) {
|
||||
// flat labels
|
||||
ratio = flatScale(35 * (titlespace +
|
||||
tick.node().getBBox().height) / chartwrap.height());
|
||||
//console.log('FLAT:', ratio);
|
||||
//console.log(35 * (titlespace + tick.node().getBBox().height) / chartwrap.height());
|
||||
} else {
|
||||
// rotated labels
|
||||
ratio = rotScale((titlespace + tick.node().getBBox().height) / chartwrap.height());
|
||||
div.style('height', 2 + tick.node().getBBox().height + 'px');
|
||||
svg.attr('height', 2 + tick.node().getBBox().height + 'px');
|
||||
//console.log('ROT:', ratio);
|
||||
//console.log((titlespace + tick.node().getBBox().height) / chartwrap.height());
|
||||
}
|
||||
|
||||
flex = ratio.toFixed(1);
|
||||
xwrapper.css('flex', flex + ' 1');
|
||||
xdiv.css('flex', flex + ' 1');
|
||||
yspacerblock.css('flex', flex + ' 1');
|
||||
//console.log('flex:', flex);
|
||||
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
return XAxis;
|
||||
};
|
||||
});
|
|
@ -1,159 +0,0 @@
|
|||
define(function (require) {
|
||||
return function YAxisFactory(d3, Private) {
|
||||
var _ = require('lodash');
|
||||
var $ = require('jquery');
|
||||
|
||||
var ErrorHandler = Private(require('components/vislib/modules/_error_handler'));
|
||||
|
||||
function YAxis(args) {
|
||||
this.el = args.el;
|
||||
this.chartData = args.chartData;
|
||||
this.dataArray = args.dataArray;
|
||||
this._attr = _.defaults(args._attr || {}, {
|
||||
stack: d3.layout.stack()
|
||||
.x(function (d) { return d.x; })
|
||||
.y(function (d) { return d.y; })
|
||||
});
|
||||
}
|
||||
|
||||
_(YAxis.prototype).extend(ErrorHandler.prototype);
|
||||
|
||||
YAxis.prototype.render = function () {
|
||||
d3.select(this.el).selectAll('.y-axis-div').call(this.draw());
|
||||
};
|
||||
|
||||
// should be moved to yAxis class
|
||||
YAxis.prototype.isStacked = function () {
|
||||
var data = this.chartData;
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
if (data[i].series.length > 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// should be moved to yAxis class
|
||||
YAxis.prototype.getYMaxValue = function () {
|
||||
var self = this;
|
||||
var arr = [];
|
||||
|
||||
_.forEach(this.dataArray, function (series) {
|
||||
arr.push(self.getYStackMax(series));
|
||||
});
|
||||
|
||||
return _.max(arr);
|
||||
};
|
||||
|
||||
// should be moved to yAxis class
|
||||
YAxis.prototype.getYStackMax = function (series) {
|
||||
var self = this;
|
||||
|
||||
if (this.isStacked()) {
|
||||
series = this._attr.stack(series);
|
||||
}
|
||||
|
||||
return d3.max(series, function (data) {
|
||||
return d3.max(data, function (d) {
|
||||
if (self.isStacked()) {
|
||||
return d.y0 + d.y;
|
||||
}
|
||||
return d.y;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
YAxis.prototype.getYScale = function (height) {
|
||||
this.yMax = this.getYMaxValue();
|
||||
|
||||
this.yScale = d3.scale.linear()
|
||||
.domain([0, this.yMax])
|
||||
.range([height, 0])
|
||||
.nice(this.tickScale(height));
|
||||
|
||||
return this.yScale;
|
||||
};
|
||||
|
||||
YAxis.prototype.getYAxis = function (height) {
|
||||
var yScale = this.getYScale(height);
|
||||
|
||||
if (!yScale || _.isNaN(yScale)) {
|
||||
throw new Error('yScale is ' + yScale);
|
||||
}
|
||||
|
||||
this.yAxis = d3.svg.axis()
|
||||
.scale(yScale)
|
||||
.tickFormat(d3.format('s'))
|
||||
.ticks(this.tickScale(height))
|
||||
.orient('left');
|
||||
|
||||
return this.yAxis;
|
||||
};
|
||||
|
||||
YAxis.prototype.tickScale = function (height) {
|
||||
// Avoid using even numbers in the yTickScale.range
|
||||
// Causes the top most tickValue in the chart to be missing
|
||||
var yTickScale = d3.scale.linear()
|
||||
.clamp(true)
|
||||
.domain([20, 40, 1000])
|
||||
.range([0, 3, 11]);
|
||||
|
||||
return Math.ceil(yTickScale(height));
|
||||
};
|
||||
|
||||
YAxis.prototype.draw = function () {
|
||||
var self = this;
|
||||
var margin = this._attr.margin;
|
||||
var div;
|
||||
var width;
|
||||
var height;
|
||||
var svg;
|
||||
|
||||
return function (selection) {
|
||||
selection.each(function () {
|
||||
div = d3.select(this);
|
||||
width = $(this).width();
|
||||
height = $(this).height() - margin.top - margin.bottom;
|
||||
|
||||
self.validateWidthandHeight(width, height);
|
||||
|
||||
var yAxis = self.getYAxis(height);
|
||||
|
||||
svg = div.append('svg')
|
||||
.attr('width', width)
|
||||
.attr('height', height + margin.top + margin.bottom);
|
||||
|
||||
svg.append('g')
|
||||
.attr('class', 'y axis')
|
||||
.attr('transform', 'translate(' + (width - 2) + ',' + margin.top + ')')
|
||||
.call(yAxis);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
YAxis.prototype.getMaxLabelLength = function (labels) {
|
||||
var arr = [];
|
||||
|
||||
// get max tick label length
|
||||
_.forEach(labels[0], function (n) {
|
||||
arr.push(n.getBBox().width);
|
||||
});
|
||||
|
||||
return _.max(arr);
|
||||
};
|
||||
|
||||
YAxis.prototype.updateLayoutForRotatedLabels = function (svg, length) {
|
||||
var margin = this._attr.margin;
|
||||
var tickspace = 14;
|
||||
|
||||
length += tickspace;
|
||||
|
||||
// set widths of svg, x-axis-div and x-axis-div-wrapper to fit ticklabels
|
||||
svg.attr('width', length + 6);
|
||||
d3.selectAll('.y.axis').attr('transform', 'translate(' + (length + 2) + ',' + margin.top + ')');
|
||||
};
|
||||
|
||||
return YAxis;
|
||||
};
|
||||
});
|
|
@ -1,17 +0,0 @@
|
|||
define(function (require) {
|
||||
return function ErrorHandlerFactory(Private) {
|
||||
var _ = require('lodash');
|
||||
|
||||
function ErrorHandler() {}
|
||||
|
||||
ErrorHandler.prototype.validateWidthandHeight = function (width, height) {
|
||||
if (_.isNaN(height) || height <= 0 || _.isNaN(width) || width <= 0) {
|
||||
throw new Error('The height and/or width of this container is too ' +
|
||||
'small for this chart. Height: ' + height + ', width: ' + width);
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
return ErrorHandler;
|
||||
};
|
||||
});
|
|
@ -1,108 +0,0 @@
|
|||
define(function (require) {
|
||||
return function LegendFactory(d3, Private) {
|
||||
var $ = require('jquery');
|
||||
var _ = require('lodash');
|
||||
|
||||
// Dynamically adds css file
|
||||
require('css!components/vislib/components/styles/main');
|
||||
|
||||
function Legend(labels, color, config, el) {
|
||||
this.el = el;
|
||||
this.labels = labels;
|
||||
this.color = color;
|
||||
this._attr = _.defaults(config || {}, {
|
||||
'legendClass' : 'legend-col-wrapper',
|
||||
'blurredOpacity' : 0.3,
|
||||
'focusOpacity' : 1,
|
||||
'defaultOpacity' : 1,
|
||||
'isOpen' : false,
|
||||
'width': 20
|
||||
});
|
||||
}
|
||||
|
||||
Legend.prototype.header = function (el) {
|
||||
return el.append('div')
|
||||
.attr('class', 'header')
|
||||
.append('div')
|
||||
.attr('class', 'column-labels')
|
||||
.html('<span class="btn btn-xs btn-default legend-toggle">' +
|
||||
'<i class="fa fa-list-ul"></i></span>');
|
||||
};
|
||||
|
||||
Legend.prototype.list = function (el, arrOfItms, args) {
|
||||
var self = this;
|
||||
|
||||
return el.append('ul')
|
||||
.attr('class', function () {
|
||||
if (args._attr.isOpen) {
|
||||
return 'legend-ul';
|
||||
}
|
||||
return 'legend-ul hidden';
|
||||
})
|
||||
.selectAll('li')
|
||||
.data(arrOfItms)
|
||||
.enter()
|
||||
.append('li')
|
||||
.attr('class', function (d) {
|
||||
return 'color ' + self.classify(args.color(d));
|
||||
})
|
||||
.html(function (d) {
|
||||
return '<span class="dots" style="background:' + args.color(d) + '"></span>' + d;
|
||||
});
|
||||
};
|
||||
|
||||
Legend.prototype.classify = function (name) {
|
||||
return 'c' + name.replace(/[#]/g, '');
|
||||
};
|
||||
|
||||
Legend.prototype.render = function () {
|
||||
var visEl = d3.select(this.el);
|
||||
var legendDiv = visEl.select('.' + this._attr.legendClass);
|
||||
var items = this.labels;
|
||||
var header = this.header(legendDiv);
|
||||
var headerIcon = visEl.select('.legend-toggle');
|
||||
var list = this.list(legendDiv, items, this);
|
||||
|
||||
var self = this;
|
||||
|
||||
// toggle
|
||||
headerIcon.on('click', function (d) {
|
||||
if (self._attr.isOpen) {
|
||||
// close legend
|
||||
visEl.select('ul.legend-ul')
|
||||
.classed('hidden', true);
|
||||
self._attr.isOpen = false;
|
||||
|
||||
} else {
|
||||
// open legend
|
||||
visEl.select('ul.legend-ul')
|
||||
.classed('hidden', false);
|
||||
self._attr.isOpen = true;
|
||||
}
|
||||
});
|
||||
|
||||
visEl.selectAll('.color')
|
||||
.on('mouseover', function (d) {
|
||||
var liClass = '.' + self.classify(self.color(d));
|
||||
visEl.selectAll('.color').style('opacity', self._attr.blurredOpacity);
|
||||
|
||||
// select series on chart
|
||||
visEl.selectAll(liClass).style('opacity', self._attr.focusOpacity);
|
||||
|
||||
visEl.selectAll('.color')
|
||||
.style('opacity', self._attr.blurredOpacity);
|
||||
|
||||
// Select series on chart
|
||||
visEl.selectAll(liClass)
|
||||
.style('opacity', self._attr.focusOpacity);
|
||||
});
|
||||
|
||||
visEl.selectAll('.color')
|
||||
.on('mouseout', function () {
|
||||
visEl.selectAll('.color').style('opacity', self._attr.defaultOpacity);
|
||||
});
|
||||
};
|
||||
|
||||
return Legend;
|
||||
};
|
||||
});
|
|
@ -1,66 +0,0 @@
|
|||
define(function (require) {
|
||||
return function TooltipFactory(d3, Private) {
|
||||
var _ = require('lodash');
|
||||
var $ = require('jquery');
|
||||
|
||||
// Dynamically adds css file
|
||||
require('css!components/vislib/components/styles/main');
|
||||
|
||||
function Tooltip(formatter) {
|
||||
if (!(this instanceof Tooltip)) {
|
||||
return new Tooltip(formatter);
|
||||
}
|
||||
|
||||
this.tooltipFormatter = formatter;
|
||||
this.tooltipClass = 'k4tip';
|
||||
this.chartWidth = $('.chart').width();
|
||||
this.chartHeight = $('.chart').height();
|
||||
}
|
||||
|
||||
Tooltip.prototype.render = function () {
|
||||
var self = this;
|
||||
|
||||
return function (selection) {
|
||||
selection.each(function () {
|
||||
var tooltipDiv = d3.select('.' + self.tooltipClass);
|
||||
var element = d3.select(this);
|
||||
|
||||
element
|
||||
.on('mousemove.tip', function (d) {
|
||||
var mouseMove = {
|
||||
left: d3.event.x,
|
||||
top: d3.event.y
|
||||
};
|
||||
|
||||
var chartWidth = self.chartWidth;
|
||||
var offsetX = d3.event.offsetX;
|
||||
var tipWidth = tooltipDiv[0][0].clientWidth;
|
||||
var xOffset = 10;
|
||||
if ((chartWidth - offsetX) < tipWidth) {
|
||||
xOffset = -10 - tipWidth;
|
||||
}
|
||||
|
||||
var chartHeight = self.chartHeight;
|
||||
var offsetY = d3.event.offsetY;
|
||||
var tipHeight = tooltipDiv[0][0].clientHeight;
|
||||
var yOffset = 5;
|
||||
if ((chartHeight - offsetY + 10) < (tipHeight)) {
|
||||
yOffset = tipHeight - (chartHeight - offsetY + 5);
|
||||
}
|
||||
|
||||
return tooltipDiv.datum(d)
|
||||
.text(self.tooltipFormatter)
|
||||
.style('visibility', 'visible')
|
||||
.style('left', mouseMove.left + xOffset + 'px')
|
||||
.style('top', mouseMove.top - yOffset + 'px');
|
||||
})
|
||||
.on('mouseout.tip', function () {
|
||||
return tooltipDiv.style('visibility', 'hidden');
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
return Tooltip;
|
||||
};
|
||||
});
|
|
@ -3,7 +3,7 @@ define(function (require) {
|
|||
var $ = require('jquery');
|
||||
var _ = require('lodash');
|
||||
|
||||
var Handler = Private(require('components/vislib/modules/Handler'));
|
||||
var Handler = Private(require('components/vislib/lib/handler'));
|
||||
var Events = Private(require('factories/events'));
|
||||
var chartTypes = Private(require('components/vislib/vis_types'));
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ define(function (require) {
|
|||
return function VisTypeFactory(Private) {
|
||||
// VisLib Visualization Types
|
||||
return {
|
||||
histogram: Private(require('components/vislib/modules/ColumnChart'))
|
||||
histogram: Private(require('components/vislib/visualizations/column_chart'))
|
||||
};
|
||||
};
|
||||
});
|
|
@ -3,8 +3,8 @@ define(function (require) {
|
|||
var _ = require('lodash');
|
||||
var $ = require('jquery');
|
||||
|
||||
var Chart = Private(require('components/vislib/modules/_chart'));
|
||||
var Legend = Private(require('components/vislib/modules/legend'));
|
||||
var Chart = Private(require('components/vislib/visualizations/_chart'));
|
||||
var Legend = Private(require('components/vislib/lib/legend'));
|
||||
|
||||
// Dynamically adds css file
|
||||
require('css!components/vislib/components/styles/main');
|
|
@ -19,8 +19,8 @@ define(function (require) {
|
|||
|
||||
beforeEach(function () {
|
||||
inject(function (d3, Private) {
|
||||
ColumnChart = Private(require('components/vislib/modules/ColumnChart'));
|
||||
Chart = Private(require('components/vislib/modules/_chart'));
|
||||
ColumnChart = Private(require('components/vislib/visualizations/column_chart'));
|
||||
Chart = Private(require('components/vislib/visualizations/_chart'));
|
||||
|
||||
el = d3.select('body').append('div').attr('class', 'column-chart');
|
||||
vis = {
|
||||
|
|
|
@ -13,7 +13,7 @@ define(function (require) {
|
|||
|
||||
beforeEach(function () {
|
||||
inject(function (Private) {
|
||||
ErrorHandler = Private(require('components/vislib/modules/_error_handler'));
|
||||
ErrorHandler = Private(require('components/vislib/lib/_error_handler'));
|
||||
errorHandler = new ErrorHandler();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -78,8 +78,8 @@ define(function (require) {
|
|||
|
||||
beforeEach(function () {
|
||||
inject(function (d3, Private) {
|
||||
AxisTitle = Private(require('components/vislib/modules/AxisTitle'));
|
||||
Data = Private(require('components/vislib/modules/Data'));
|
||||
AxisTitle = Private(require('components/vislib/lib/axis_title'));
|
||||
Data = Private(require('components/vislib/lib/data'));
|
||||
|
||||
el = d3.select('body').append('div')
|
||||
.attr('class', 'vis-wrapper');
|
||||
|
|
|
@ -76,8 +76,8 @@ define(function (require) {
|
|||
|
||||
beforeEach(function () {
|
||||
inject(function (d3, Private) {
|
||||
ChartTitle = Private(require('components/vislib/modules/ChartTitle'));
|
||||
Data = Private(require('components/vislib/modules/Data'));
|
||||
ChartTitle = Private(require('components/vislib/lib/chart_title'));
|
||||
Data = Private(require('components/vislib/lib/data'));
|
||||
|
||||
el = d3.select('body').append('div')
|
||||
.attr('class', 'vis-wrapper')
|
||||
|
|
|
@ -76,8 +76,8 @@ define(function (require) {
|
|||
|
||||
beforeEach(function () {
|
||||
inject(function (d3, Private) {
|
||||
ColumnChart = Private(require('components/vislib/modules/ColumnChart'));
|
||||
Data = Private(require('components/vislib/modules/Data'));
|
||||
ColumnChart = Private(require('components/vislib/visualizations/column_chart'));
|
||||
Data = Private(require('components/vislib/lib/data'));
|
||||
|
||||
el = d3.select('body').append('div')
|
||||
.attr('class', 'vis-wrapper')
|
||||
|
|
|
@ -190,7 +190,7 @@ define(function (require) {
|
|||
|
||||
beforeEach(function () {
|
||||
inject(function (d3, Private) {
|
||||
dataFactory = Private(require('components/vislib/modules/Data'));
|
||||
dataFactory = Private(require('components/vislib/lib/data'));
|
||||
});
|
||||
rowIn = new dataFactory(rowsData);
|
||||
});
|
||||
|
@ -220,7 +220,7 @@ define(function (require) {
|
|||
|
||||
beforeEach(function () {
|
||||
inject(function (d3, Private) {
|
||||
dataFactory = Private(require('components/vislib/modules/Data'));
|
||||
dataFactory = Private(require('components/vislib/lib/data'));
|
||||
});
|
||||
serIn = new dataFactory(seriesData);
|
||||
rowIn = new dataFactory(rowsData);
|
||||
|
|
|
@ -91,8 +91,8 @@ define(function (require) {
|
|||
beforeEach(function () {
|
||||
inject(function (d3, Private) {
|
||||
Vis = Private(require('components/vislib/vis'));
|
||||
Data = Private(require('components/vislib/modules/Data'));
|
||||
Handler = Private(require('components/vislib/modules/Handler'));
|
||||
Data = Private(require('components/vislib/lib/data'));
|
||||
Handler = Private(require('components/vislib/lib/handler'));
|
||||
|
||||
el = d3.select('body').append('div')
|
||||
.attr('class', 'visualize');
|
||||
|
|
|
@ -77,7 +77,7 @@ define(function (require) {
|
|||
|
||||
beforeEach(function () {
|
||||
inject(function (d3, Private) {
|
||||
Layout = Private(require('components/vislib/modules/Layout'));
|
||||
Layout = Private(require('components/vislib/lib/layout'));
|
||||
xAxisSplit = Private(require('components/vislib/components/layouts/splits/column_chart/x_axis_split'));
|
||||
|
||||
el = d3.select('body').append('div')
|
||||
|
|
|
@ -80,8 +80,8 @@ define(function (require) {
|
|||
|
||||
beforeEach(function () {
|
||||
inject(function (d3, Private) {
|
||||
Data = Private(require('components/vislib/modules/Data'));
|
||||
XAxis = Private(require('components/vislib/modules/Xaxis'));
|
||||
Data = Private(require('components/vislib/lib/data'));
|
||||
XAxis = Private(require('components/vislib/lib/x_axis'));
|
||||
|
||||
el = d3.select('body').append('div')
|
||||
.attr('class', 'x-axis-wrapper');
|
||||
|
|
|
@ -121,8 +121,8 @@ define(function (require) {
|
|||
|
||||
beforeEach(function () {
|
||||
inject(function (d3, Private) {
|
||||
YAxis = Private(require('components/vislib/modules/YAxis'));
|
||||
Data = Private(require('components/vislib/modules/Data'));
|
||||
YAxis = Private(require('components/vislib/lib/y_axis'));
|
||||
Data = Private(require('components/vislib/lib/data'));
|
||||
|
||||
el = d3.select('body').append('div')
|
||||
.attr('class', 'y-axis-wrapper');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue