diff --git a/src/kibana/apps/visualize/directives/visualize.js b/src/kibana/apps/visualize/directives/visualize.js index 323e8e8a83e82..820c6a6a1390d 100644 --- a/src/kibana/apps/visualize/directives/visualize.js +++ b/src/kibana/apps/visualize/directives/visualize.js @@ -91,10 +91,10 @@ define(function (require) { // For each type of interaction, assign the the handler if the vis object has it // otherwise use the typeDef, otherwise, do nothing. -// _.each({hover: 'onHover', click: 'onClick', brush: 'onBrush'}, function (func, event) { -// var callback = vis[func] || typeDefinition[func]; -// if (!!callback) chart.on(event, callback); -// }); + _.each({hover: 'onHover', click: 'onClick', brush: 'onBrush'}, function (func, event) { + var callback = vis[func] || typeDefinition[func]; + if (!!callback) chart.on(event, callback); + }); if (!attr.esResp) { diff --git a/src/kibana/components/vislib/modules/ColumnChart.js b/src/kibana/components/vislib/modules/ColumnChart.js index b55495d4c1c2f..08d7c9828a741 100644 --- a/src/kibana/components/vislib/modules/ColumnChart.js +++ b/src/kibana/components/vislib/modules/ColumnChart.js @@ -1,5 +1,5 @@ define(function (require) { - return function HistogramChartFactory(d3, Private) { + return function ColumnChartFactory(d3, Private) { var _ = require('lodash'); var $ = require('jquery'); @@ -13,57 +13,70 @@ define(function (require) { function ColumnChart(vis, chartEl, chartData) { ColumnChart.Super.apply(this, arguments); this._attr = _.defaults(vis._attr || {}, { -// 'margin' : { top: 0, right: 0, bottom: 0, left: 0 }, -// 'offset' : 'zero' + offset: 'zero', + xValue: function (d, i) { return d.x; }, + yValue: function (d, i) { return d.y; }, + dispatch: d3.dispatch('brush', 'click', 'hover', 'mouseenter', 'mouseleave', 'mouseover', 'mouseout'), + stack: d3.layout.stack() + .x(function (d) { return d.x; }) + .y(function (d) { return d.y; }) + .offset(this.offset) }); } + ColumnChart.prototype.eventResponse = function (d, i) { + return { + value : this._attr.yValue(d, i), + point : d, + label : d.label, + color : this.vis.data.color(d.label), + pointIndex: i, + series : this.chartData.series, + config : this._attr, + data : this.chartData, + e : d3.event + }; + }; + + ColumnChart.prototype.stackData = function (data) { + var self = this; + + return this._attr.stack(data.series.map(function (d) { + var label = d.label; + return d.values.map(function (e, i) { + return { + label: label, + x : self._attr.xValue.call(d.values, e, i), + y : self._attr.yValue.call(d.values, e, i) + }; + }); + })); + }; + ColumnChart.prototype.draw = function () { - console.log(this); // Attributes + var self = this; var $elem = $(this.chartEl); var margin = this._attr.margin; var elWidth = this._attr.width = $elem.width(); var elHeight = this._attr.height = $elem.height(); - var offset = this._attr.offset; var isTooltip = this._attr.addTooltip; var color = this.vis.data.color; var tooltip = this.vis.tooltip; var yScale = this.vis.yAxis.yScale; var xScale = this.vis.xAxis.xScale; - var stack = d3.layout.stack() - .x(function (d) { - return d.x; - }) - .y(function (d) { - return d.y; - }) - .offset(offset); - var xValue = function (d, i) { - return d.x; - }; - var yValue = function (d, i) { - return d.y; - }; + var dispatch = this._attr.dispatch; var div; var svg; var width; var height; var layers; + var layer; + var bars; return function (selection) { selection.each(function (data) { - - layers = stack(data.series.map(function (d) { - var label = d.label; - return d.values.map(function (e, i) { - return { - label: label, - x: xValue.call(d.values, e, i), - y: yValue.call(d.values, e, i) - }; - }); - })); + layers = self.stackData(data); if (elWidth <= 0 || elHeight <= 0) { throw new Error($elem.attr('class') + ' height is ' + elHeight + ' and width is ' + elWidth); @@ -74,25 +87,27 @@ define(function (require) { height = elHeight - margin.top - margin.bottom; // Create the canvas for the visualization - var div = d3.select(this); + div = d3.select(this); - var svg = div.append('svg') + svg = div.append('svg') .attr('width', width + margin.left + margin.right) .attr('height', height + margin.top + margin.bottom) .append('g') .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); // Data layers - var layer = svg.selectAll('.layer') + layer = svg.selectAll('.layer') .data(layers) .enter().append('g') - .attr('class', function (d, i) { + .attr( + 'class', function (d, i) { return i; }); // Append the bars - var bars = layer.selectAll('rect') - .data(function (d) { + bars = layer.selectAll('rect') + .data( + function (d) { return d; }); @@ -102,36 +117,50 @@ define(function (require) { // enter bars.enter() .append('rect') - .attr('class', function (d) { + .attr( + 'class', function (d) { return 'color ' + classify(color(d.label)); }) - .attr('fill', function (d) { + .attr( + 'fill', function (d) { return color(d.label); }); // update bars - .attr('x', function (d) { + .attr( + 'x', function (d) { return xScale(d.x); }) - .attr('width', function () { + .attr( + 'width', function () { return xScale.rangeBand(); }) - .attr('y', function (d) { + .attr( + 'y', function (d) { return yScale(d.y0 + d.y); }) - .attr('height', function (d) { + .attr( + 'height', function (d) { return yScale(d.y0) - yScale(d.y0 + d.y); - }) + }); + bars .on('mouseover.bar', function (d, i) { d3.select(this) .classed('hover', true) - .style('stroke', '#333'); + .style('stroke', '#333') + .style('cursor', 'pointer'); + + dispatch.hover(self.eventResponse(d, i)); + d3.event.stopPropagation(); }) - .on('mouseout.bar', function (d) { - d3.select(this) - .classed('hover', false) + .on('click.bar', function (d, i) { + dispatch.click(self.eventResponse(d, i)); + d3.event.stopPropagation(); + }) + .on('mouseout.bar', function () { + d3.select(this).classed('hover', false) .style('stroke', null); }); @@ -153,7 +182,6 @@ define(function (require) { }); }; }; - return ColumnChart; }; }); \ No newline at end of file diff --git a/src/kibana/components/vislib/modules/_chart.js b/src/kibana/components/vislib/modules/_chart.js index b9ba92debe6ee..ac749bc5b8510 100644 --- a/src/kibana/components/vislib/modules/_chart.js +++ b/src/kibana/components/vislib/modules/_chart.js @@ -3,7 +3,11 @@ define(function (require) { var _ = require('lodash'); var $ = require('jquery'); + var Events = Private(require('factories/events')); + + _(Chart).inherits(Events); function Chart(vis, el, chartData) { + Chart.Super.apply(this, arguments); this.vis = vis; this.chartEl = el; this.chartData = chartData; @@ -14,9 +18,29 @@ define(function (require) { return d3.select(this.chartEl).call(this.draw()); }; - Chart.prototype.on = function () {}; + Chart.prototype.rebind = function () { + return d3.rebind(Chart.Super, Chart._attr.dispatch, 'on'); + }; - Chart.prototype.off = function () {}; + Chart.prototype.on = function () { + var args = Array.prototype.slice.call(arguments); + var eventName = args[0]; + var self = this; + console.log(this); + + // This should only be called the first time to wire up the D3 event handler + if (!this._listners[eventName]) { + this.dispatch.on.call(this.dispatch, eventName, function () { + var eventArgs = Array.prototype.slice.call(arguments); + self.emit.apply(eventName, eventArgs); + }); + } + Chart.Super.prototype.on.apply(this, args); + }; + + Chart.prototype.off = function (event) { + this.dispatch.on(event, null); + }; Chart.prototype.destroy = function () {}; diff --git a/src/kibana/components/vislib/modules/_functions.js b/src/kibana/components/vislib/modules/_functions.js index eebc4f3748fc8..0ff9a2471f643 100644 --- a/src/kibana/components/vislib/modules/_functions.js +++ b/src/kibana/components/vislib/modules/_functions.js @@ -54,6 +54,9 @@ define(function (require) { .selectAll('.chart') .each(function (chartData) { var chart = new vis.ChartClass(vis, this, chartData); + + d3.rebind(vis, chart._attr.dispatch, 'on'); + charts.push(chart); try { chart.render(); diff --git a/src/kibana/components/vislib/modules/eventDispatch.js b/src/kibana/components/vislib/modules/eventDispatch.js deleted file mode 100644 index deee1062301ae..0000000000000 --- a/src/kibana/components/vislib/modules/eventDispatch.js +++ /dev/null @@ -1,60 +0,0 @@ -define(function (require) { - return function HistogramChartFactory(d3, Private) { - - var _ = require('lodash'); - - var ChartFunctions = Private(require('components/vislib/modules/_functions')); - var Events = Private(require('factories/events')); - - _(Chart).inherits(Events); - function Chart(vis, el, chartData) { - Chart.Super.call(this); - - this.el = vis.el; - this.ChartClass = vis.ChartClass; - this.data = vis.data; - this.color = vis.color; - this.orderedKeys = vis.orderedKeys; - this.tooltip = vis.tooltip; - - // Chart specific items - this.chartEl = el; - this.chartData = chartData; - this._attr = _.defaults(vis.config || {}, {}); - - } - - _(Chart.prototype).extends(ChartFunctions.prototype); - Chart.prototype.on = function () { - var args = Array.prototype.slice.call(arguments); - var eventName = args[0]; - var self = this; - - // This should be called the first time to wire up the D3 event handler - if (!this._listners[eventName]) { - this.d3.dispatch.on.call(this.d3.dispatch, eventName, function () { - var eventArgs = Array.prototype.slice.call(arguments); - self.emit.apply(eventName, eventArgs); - }); - } - - Chart.Super.prototype.on.apply(this, args); - }; - - /* - - histogram.on('click', someFunction); - histogram.on('click', someOtherFunction); - - Vis.prototype.on = function () { - return this.chart.on.apply(this.chart, arguments); - }; - - Vis.prototype.off = function () { - return this.chart.off.apply(this.chart, arguments); - }; - - */ - - }; -}); \ No newline at end of file diff --git a/src/kibana/components/vislib/vis.js b/src/kibana/components/vislib/vis.js index d28a65d0fa0a7..ecb3f2ca51878 100644 --- a/src/kibana/components/vislib/vis.js +++ b/src/kibana/components/vislib/vis.js @@ -12,11 +12,9 @@ define(function (require) { function Vis($el, config) { this.el = $el.get ? $el.get(0) : $el; -// this.config = config; this.ChartClass = chartTypes[config.type]; this._attr = _.defaults(config || {}, { - 'margin' : { top: 6, right: 0, bottom: 0, left: 0 }, - 'offset' : 'zero' + 'margin' : { top: 6, right: 0, bottom: 0, left: 0 } }); } @@ -110,15 +108,15 @@ define(function (require) { }, 300); Vis.prototype.on = function () { - return this.chart.on(); + return this.ChartClass.prototype.on.apply(this, arguments); }; Vis.prototype.off = function () { - return this.chart.off(); + return this.charts.off.apply(this.charts, arguments); }; Vis.prototype.destroy = function () { - return this.chart.destroy(); + return this.ChartClass.prototype.destroy.apply(this, arguments); }; Vis.prototype.set = function (name, val) {