pulled in new handler and merged in master

This commit is contained in:
Juan Thomassie 2014-08-28 11:10:23 -05:00
commit 69a2b8b876
14 changed files with 171 additions and 225 deletions

View file

@ -5,13 +5,11 @@ define(function (require) {
var Chart = Private(require('components/vislib/modules/_chart'));
_(AxisTitle).inherits(Chart);
function AxisTitle(el, xTitle, yTitle) {
if (!(this instanceof AxisTitle)) {
return new AxisTitle(el, xTitle, yTitle);
}
AxisTitle.Super.apply(this, arguments);
this.el = el;
this.xTitle = xTitle;
this.yTitle = yTitle;
@ -34,8 +32,6 @@ define(function (require) {
width = $(this).width();
height = $(this).height();
self.validateHeightAndWidth(div, width, height);
div.append('svg')
.attr('width', width)
.attr('height', height)

View file

@ -3,15 +3,11 @@ define(function (require) {
var $ = require('jquery');
var _ = require('lodash');
var Chart = Private(require('components/vislib/modules/_chart'));
_(ChartTitle).inherits(Chart);
function ChartTitle(el) {
if (!(this instanceof ChartTitle)) {
return new ChartTitle(el);
}
ChartTitle.Super.apply(this, arguments);
this.el = el;
}
@ -56,8 +52,6 @@ define(function (require) {
var width = $(this).width();
var height = $(this).height();
self.validateHeightAndWidth(div, width, height);
div.append('svg')
.attr('width', width)
.attr('height', height)

View file

@ -120,6 +120,20 @@ define(function (require) {
width = elWidth - margin.left - margin.right;
height = elHeight - margin.top - margin.bottom;
if (_.isNaN(width) || _.isNaN(height)) {
throw new Error('width: ' + width + '; height:' + height);
}
if (height <= margin.top + margin.bottom) {
throw new Error('The container is too small for this chart.');
}
/* Error Handler that prevents a chart from being rendered when
there are too many data points for the width of the container. */
if (width / layers.length <= 4) {
throw new Error('The container is too small for this chart.');
}
// Create the canvas for the visualization
div = d3.select(this);
@ -180,10 +194,18 @@ define(function (require) {
return xScale.rangeBand();
})
.attr('y', function (d) {
return yScale(d.y0 + d.y);
var y = yScale(d.y0 + d.y);
if (!_.isNaN(y) || y < 0) {
return y;
}
throw new Error('The container is too small for this chart.');
})
.attr('height', function (d) {
return yScale(d.y0) - yScale(d.y0 + d.y);
var height = yScale(d.y0) - yScale(d.y0 + d.y);
if (!_.isNaN(height) || height < 0) {
return height;
}
throw new Error('The container is too small for this chart.');
});
bars

View file

@ -0,0 +1,101 @@
define(function (require) {
var _ = require('lodash');
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.vis = vis;
this.el = vis.el;
this.data = new Data(vis.data);
this.ChartClass = vis.ChartClass;
this._attr = _.defaults(vis._attr || {}, {
'margin' : { top: 10, right: 3, bottom: 5, left: 3 }
});
this.layout = new Layout(this.el, this.data.injectZeros());
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.chartTitle = new ChartTitle(this.el);
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,
yMax: this.data.getYMaxValue(),
_attr: this._attr
});
this.axisTitle = new AxisTitle(this.el, this.data.get('xAxisLabel'), this.data.get('yAxisLabel'));
this.renderArray = [
this.layout,
this.legend,
this.tooltip,
this.chartTitle,
this.xAxis,
this.yAxis,
this.axisTitle
];
}
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.error = function () {};
return Handler;
};
});

View file

@ -4,6 +4,10 @@ define(function (require) {
var $ = require('jquery');
function Layout(el, data) {
if (!(this instanceof Layout)) {
return new Layout(el, data);
}
this.el = el;
this.data = data;
}

View file

@ -3,18 +3,16 @@ define(function (require) {
var $ = require('jquery');
var _ = require('lodash');
var Chart = Private(require('components/vislib/modules/_chart'));
_(XAxis).inherits(Chart);
function XAxis(args) {
if (!(this instanceof XAxis)) {
return new XAxis(args);
}
XAxis.Super.apply(this, arguments);
this.el = args.el;
this.data = args.data;
this._attr = args.attr;
this.xValues = args.xValues;
this.ordered = args.ordered;
this.xAxisFormatter = args.xAxisFormatter;
this._attr = args._attr;
}
XAxis.prototype.render = function () {
@ -33,13 +31,11 @@ define(function (require) {
};
XAxis.prototype.getDomain = function (scale, ordered) {
var xValues = this.data.xValues();
if (ordered && ordered.date) {
// Calculate the min date, max date, and time interval;
return this.getTimeDomain(scale, xValues, ordered);
return this.getTimeDomain(scale, this.xValues, ordered);
}
return this.getOrdinalDomain(scale, xValues);
return this.getOrdinalDomain(scale, this.xValues);
};
XAxis.prototype.getTimeDomain = function (scale, xValues, ordered) {
@ -50,7 +46,7 @@ define(function (require) {
// 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 + timeInterval <= ordered.max ? ordered.max : +maxXValue + timeInterval * (1 - spacingPercentage);
var maxDate = +maxXValue <= ordered.max ? ordered.max : +maxXValue + timeInterval;
scale.domain([minDate, maxDate]);
@ -79,10 +75,8 @@ define(function (require) {
};
XAxis.prototype.getXAxis = function (width) {
var ordered = this.data.get('ordered');
this.xAxisFormatter = this.data.get('xAxisFormatter');
this.xScale = this.getXScale(ordered, width);
this.xAxisFormatter = this.xAxisFormatter;
this.xScale = this.getXScale(this.ordered, width);
this.xAxis = d3.svg.axis()
.scale(this.xScale)
@ -114,8 +108,6 @@ define(function (require) {
width = $(this).width() - margin.left - margin.right;
height = $(this).height();
self.validateHeightAndWidth(div, width, height);
// Return access to xAxis variable on the object
self.getXAxis(width);
@ -219,10 +211,9 @@ define(function (require) {
XAxis.prototype.filterAxisLabels = function (selection, nth) {
var self = this;
var xAxisFormatter = this.data.get('xAxisFormatter');
return selection.selectAll('text')
.text(function (d, i) {
return i % nth === 0 ? xAxisFormatter(d) : '';
return i % nth === 0 ? self.xAxisFormatter(d) : '';
});
};

View file

@ -3,14 +3,10 @@ define(function (require) {
var _ = require('lodash');
var $ = require('jquery');
var Chart = Private(require('components/vislib/modules/_chart'));
_(YAxis).inherits(Chart);
function YAxis(args) {
YAxis.Super.apply(this, arguments);
this.el = args.el;
this.yMax = args.yMax;
this._attr = args.attr;
this._attr = args._attr;
}
YAxis.prototype.render = function () {
@ -62,9 +58,12 @@ define(function (require) {
div = d3.select(this);
width = $(this).width();
height = $(this).height() - margin.top - margin.bottom;
self.validateHeightAndWidth(div, width, height);
// Return access to the yAxis
if (_.isNaN(height) || height <= 0) {
throw new Error('The container is too small for this chart.');
}
var yAxis = self.getYAxis(height);
svg = div.append('svg')
@ -74,8 +73,7 @@ define(function (require) {
svg.append('g')
.attr('class', 'y axis')
.attr('transform', 'translate(' + (width - 2) + ',' + margin.top + ')')
.call(self.yAxis);
.call(yAxis);
});
};
};

View file

@ -11,7 +11,7 @@ define(function (require) {
this.vis = vis;
this.chartEl = el;
this.chartData = chartData;
this._attr = _.defaults(vis.config || {}, {});
this._attr = _.defaults(vis._attr || {}, {});
}
Chart.prototype.render = function () {

View file

@ -1,112 +0,0 @@
define(function (require) {
var _ = require('lodash');
return function VisFunctionsBaseClass(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 VisFunctions() {}
VisFunctions.prototype.instantiateData = function (data) {
this.data = new Data(data);
};
VisFunctions.prototype.renderLayout = function (data) {
this.layout = new Layout(this.el, data);
try {
this.layout.render();
} catch (error) {
// console.group(error.message);
}
};
VisFunctions.prototype.renderLegend = function (legend, config, el) {
this.legend = new Legend(legend, config, el);
try {
this.legend.render();
} catch (error) {
// console.group(error.message);
}
};
VisFunctions.prototype.renderTooltip = function (elClass, formatter) {
this.tooltip = new Tooltip(elClass, formatter);
};
VisFunctions.prototype.renderChartTitles = function (splitType) {
this.chartTitle = new ChartTitle(this.el);
try {
this.chartTitle.render();
} catch (error) {
// console.group(error.message);
}
};
VisFunctions.prototype.renderXAxis = function (args) {
this.xAxis = new XAxis(args);
try {
this.xAxis.render();
} catch (error) {
// console.group(error.message);
}
};
VisFunctions.prototype.renderYAxis = function (args) {
this.yAxis = new YAxis(args);
try {
this.yAxis.render();
} catch (error) {
// console.group(error.message);
}
};
VisFunctions.prototype.renderAxisTitles = function (xTitle, yTitle) {
this.axisTitle = new AxisTitle(this.el, xTitle, yTitle);
try {
this.axisTitle.render();
} catch (error) {
// console.group(error.message);
}
};
VisFunctions.prototype.renderCharts = function (vis, charts) {
var self = this;
d3.select(this.el)
.selectAll('.chart')
.each(function (chartData) {
var chart = new vis.ChartClass(vis, 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.emit('click', e);
});
chart.on('hover', function (e) {
self.emit('hover', e);
});
chart.on('brush', function (e) {
self.emit('brush', e);
});
charts.push(chart);
try {
chart.render();
} catch (error) {
// console.group(error.message);
}
});
};
return VisFunctions;
};
});

View file

@ -10,9 +10,9 @@ define(function (require) {
// Dynamically adds css file
require('css!components/vislib/components/styles/main');
function Legend(legend, config, el) {
this.labels = legend.labels;
this.color = legend.color;
function Legend(labels, color, config, el) {
this.labels = labels;
this.color = color;
this._attr = _.defaults(config || {}, {
'legendClass' : 'legend-col-wrapper',
'blurredOpacity' : 0.3,

View file

@ -6,13 +6,13 @@ define(function (require) {
// Dynamically adds css file
require('css!components/vislib/components/styles/main');
function Tooltip(className, formatter) {
function Tooltip(formatter) {
if (!(this instanceof Tooltip)) {
return new Tooltip(className, formatter);
return new Tooltip(formatter);
}
this.tooltipClass = className;
this.tooltipFormatter = formatter;
this.tooltipClass = 'k4tip';
this.chartWidth = $('.chart').width();
this.chartHeight = $('.chart').height();
}

View file

@ -3,7 +3,7 @@ define(function (require) {
var $ = require('jquery');
var _ = require('lodash');
var VisFunctions = Private(require('components/vislib/modules/_functions'));
var Handler = Private(require('components/vislib/modules/Handler'));
var Events = Private(require('factories/events'));
// VisLib Visualization Types
@ -20,83 +20,31 @@ define(function (require) {
Vis.Super.apply(this, arguments);
this.el = $el.get ? $el.get(0) : $el;
this.ChartClass = chartTypes[config.type];
this._attr = _.defaults(config || {}, {
'margin' : { top: 10, right: 3, bottom: 5, left: 3 }
});
this._attr = _.defaults(config || {}, {});
}
_(Vis.prototype).extend(VisFunctions.prototype);
Vis.prototype.render = function (data) {
var tooltipFormatter;
var zeroInjectedData;
var legend;
var xTitle;
var yTitle;
var vis;
var charts;
if (!data) {
throw new Error('No valid data!');
}
// DATA CLASS
this.instantiateData(data);
this.data = data;
this.handler = new Handler(this);
// LAYOUT CLASS
zeroInjectedData = this.data.injectZeros();
this.renderLayout(zeroInjectedData);
// LEGEND CLASS
if (this._attr.addLegend) {
legend = {
color: this.data.getColorFunc(),
labels: this.data.getLabels()
};
this.renderLegend(legend, this._attr, this.el);
try {
this.handler.render();
} catch (error) {
console.error(error.message);
}
// TOOLTIP CLASS
if (this._attr.addTooltip) {
tooltipFormatter = this.data.get('tooltipFormatter');
this.renderTooltip('k4tip', tooltipFormatter);
}
// CHART TITLE CLASS
this.renderChartTitles();
// XAXIS CLASS
this.renderXAxis({
el: this.el,
data: this.data,
attr: this._attr
});
// YAXIS CLASS
this.renderYAxis({
el: this.el,
yMax: this.data.getYMaxValue(),
attr: this._attr
});
// AXIS TITLE CLASS
xTitle = this.data.get('xAxisLabel');
yTitle = this.data.get('yAxisLabel');
this.renderAxisTitles(xTitle, yTitle);
// CHART CLASS
vis = this;
charts = this.charts = [];
this.renderCharts(vis, charts);
this.checkSize();
};
Vis.prototype.resize = function () {
if (!this.data.data) {
if (!this.data) {
throw new Error('No valid data');
}
this.render(this.data.data);
this.render(this.data);
};
Vis.prototype.checkSize = _.debounce(function () {

View file

@ -10,6 +10,7 @@ define(function (require) {
var Data;
var xAxis;
var el;
var dataObj;
var data = {
hits: 621,
label: '',
@ -87,10 +88,13 @@ define(function (require) {
.attr('class', 'x-axis-div')
.style('height', '20px');
dataObj = new Data(data);
xAxis = new XAxis({
el: $('.x-axis-wrapper')[0],
data: new Data(data),
attr: { margin: { top: 0, right: 0, bottom: 0, left: 0 } }
xValues: dataObj.xValues(),
ordered: dataObj.get('ordered'),
xAxisFormatter: dataObj.get('xAxisFormatter'),
_attr: { margin: { top: 0, right: 0, bottom: 0, left: 0 } }
});
});
});
@ -127,7 +131,7 @@ define(function (require) {
var range;
beforeEach(function () {
ordered = xAxis.data.get('ordered');
ordered = dataObj.get('ordered');
timeScale = xAxis.getScale(ordered);
timeDomain = xAxis.getDomain(timeScale, ordered);
ordinalScale = xAxis.getScale(false);
@ -163,7 +167,7 @@ define(function (require) {
var xScale;
beforeEach(function () {
ordered = xAxis.data.get('ordered');
ordered = dataObj.get('ordered');
width = $('.x-axis-div').width();
xScale = xAxis.getXScale(ordered, width);
});

View file

@ -89,7 +89,7 @@ define(function (require) {
yAxis = new YAxis({
el: $('.y-axis-wrapper')[0],
yMax: dataObj.getYMaxValue(),
attr: { margin: { top: 0, right: 0, bottom: 0, left: 0 } }
_attr: { margin: { top: 0, right: 0, bottom: 0, left: 0 } }
});
});
});