Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clickable legends #3641

Merged
merged 68 commits into from
Jul 16, 2015
Merged
Show file tree
Hide file tree
Changes from 59 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
7fb7866
troubleshooting
stormpython Apr 10, 2015
8bdcd7c
Merge branch 'master' into clickable-legends
stormpython Apr 17, 2015
68f0bba
shaping up the click events for legend
stormpython Apr 21, 2015
6a9a336
removing labels code since its no longer needed
stormpython Apr 21, 2015
3e58851
fixing data-labels in the legend
stormpython Apr 21, 2015
fb0c811
troubleshooting mouseover on legend for area charts
stormpython Apr 21, 2015
a7490c2
Merge branch 'master' into clickable-legends
stormpython Apr 21, 2015
2803c47
fixing broken tests
stormpython Apr 21, 2015
745cfbc
removing console.log
stormpython Apr 21, 2015
416cb6a
adding tests for the legend class
stormpython Apr 21, 2015
765d28a
bring back aggConfigResult
stormpython Apr 21, 2015
8e4b47c
adding an onclick listener test for the first li.color in the legend …
stormpython Apr 21, 2015
cd7353c
hooking up legend filtering
stormpython Apr 23, 2015
c17f132
troubleshooting issues with aggConfigResults
stormpython Apr 24, 2015
5c11aaf
fixing tests and issues with clickable legend not returning the prope…
stormpython Apr 24, 2015
8fb8dfa
addressing review comments
stormpython Apr 28, 2015
8ea33be
Merge branch 'master' into clickable-legends
stormpython Apr 28, 2015
5ad0617
Merge branch 'master' into clickable-legends
stormpython Apr 28, 2015
3085962
Merge branch 'master' into clickable-legends
stormpython Apr 29, 2015
ffb35ad
addressing review comments, added _.deepGet to dispatch for retrievin…
stormpython Apr 30, 2015
439f625
Merge branch 'master' into clickable-legends
stormpython Apr 30, 2015
2d6a29c
Merge branch 'master' into clickable-legends
stormpython Apr 30, 2015
c7bfd38
Merge branch 'master' into clickable-legends
stormpython May 1, 2015
9a86651
Merge branch 'master' into clickable-legends
stormpython May 4, 2015
0327be4
troubleshooting
stormpython May 5, 2015
e4f7d14
troubleshooting bugs with pie in the legend
stormpython May 6, 2015
3314dd0
fixing point series legend
stormpython May 6, 2015
983fbe2
fixing bugs
stormpython May 6, 2015
eee7ee1
fixing tests
stormpython May 7, 2015
2d65598
Merge branch 'master' into clickable-legends
stormpython May 7, 2015
918f587
Merge branch 'master' into clickable-legends
stormpython May 8, 2015
28290a2
Merge branch 'master' into clickable-legends
stormpython May 11, 2015
f054ca3
adding back clickable legend labels
stormpython May 11, 2015
391a571
Merge branch 'master' into clickable-legends
stormpython May 12, 2015
ae73e96
Merge branch 'master' into clickable-legends
stormpython May 13, 2015
b846d4c
Merge branch 'master' into clickable-legends
stormpython May 18, 2015
deca719
fixing bug
stormpython May 18, 2015
bece5b4
Merge branch 'master' into clickable-legends
stormpython May 19, 2015
ef3da96
resolving issue with undefined labels in legend
stormpython May 19, 2015
1bf987f
#3873. Fixing issue with numbers and dates not being highlighted prop…
stormpython May 19, 2015
960292d
fixing tests
stormpython May 19, 2015
12a21b8
removing reference to aggConfigResult.aggConfig.fieldFormatter()
stormpython May 19, 2015
418c153
making corrections based on @spalger pr comments
stormpython May 19, 2015
c94727e
Merge branch 'master' into clickable-legends
stormpython Jun 11, 2015
a5ca179
fixing test in data.js
stormpython Jun 11, 2015
d6a6587
Merge branch 'master' into clickable-legends
stormpython Jun 12, 2015
ae16129
changes
stormpython Jun 15, 2015
ebaeb49
creating data label functions
stormpython Jun 15, 2015
d244ddb
changes
stormpython Jun 16, 2015
b36434e
troubleshooting
stormpython Jun 16, 2015
f6954cf
adding code to click handler to deal with legend values
stormpython Jun 17, 2015
ac3243c
refactoring
stormpython Jun 17, 2015
c19a0af
cleaning up tests, fixing issues with pie charts
stormpython Jun 18, 2015
4c8548e
correcting _.uniq function
stormpython Jun 18, 2015
5495c7f
removing commented code
stormpython Jun 18, 2015
67c7c44
Merge branch 'master' into clickable-legends
stormpython Jun 18, 2015
57e8858
Merge branch 'master' into clickable-legends
stormpython Jun 25, 2015
17a6ae5
refactoring
stormpython Jun 25, 2015
9ca8f33
Merge branch 'master' into clickable-legends
stormpython Jun 29, 2015
ad2d228
refactoring based on review comments
stormpython Jul 9, 2015
13f8a1a
Merge branch 'master' into clickable-legends
stormpython Jul 9, 2015
6a63f54
Merge branch 'master' into clickable-legends
stormpython Jul 13, 2015
69524a5
Merge branch 'master' into clickable-legends
stormpython Jul 15, 2015
1060a41
refactoring according to @jbudz 's comments.
stormpython Jul 15, 2015
153a60a
fixing bug with clicking on a legend that is not associated with any …
stormpython Jul 15, 2015
d1c3b14
Merge branch 'master' into clickable-legends
stormpython Jul 16, 2015
c243f8d
removing pointer from legend when value === Count
stormpython Jul 16, 2015
7dbba6b
reverting previous change
stormpython Jul 16, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion src/kibana/components/filter_bar/filter_bar_click_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,32 @@ define(function (require) {
// Hierarchical and tabular data set their aggConfigResult parameter
// differently because of how the point is rewritten between the two. So
// we need to check if the point.orig is set, if not use try the point.aggConfigResult
var aggConfigResult = event.point.orig && event.point.orig.aggConfigResult || event.point.aggConfigResult;
var aggConfigResult = event.point.orig && event.point.orig.aggConfigResult ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this could be clearer using if statements.

event.point.values && findAggConfig(event.point.values) || event.point.aggConfigResult;
var notify = new Notifier({
location: 'Filter bar'
});

function findAggConfig(values) {
if (_.isArray(values)) { // point series chart
var index = _.findIndex(values, 'aggConfigResult');
return values[index].aggConfigResult;
}
return values.aggConfigResult; // pie chart
}

function findLabel(obj) {
// TODO: find out if there is always a fieldFormatter
var formatter = obj.aggConfig.fieldFormatter();
return formatter(obj.key) === event.label;
}

if (aggConfigResult) {
var isLegendLabel = !!event.point.values;
var results = _.filter(aggConfigResult.getPath(), { type: 'bucket' });

if (isLegendLabel) results = _.filter(results, findLabel); // filter results array by legend label

var filters = _(results)
.map(function (result) {
try {
Expand Down
7 changes: 1 addition & 6 deletions src/kibana/components/vislib/components/labels/data_array.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
define(function (require) {
return function GetArrayUtilService(Private) {
var _ = require('lodash');

var flattenSeries = Private(require('components/vislib/components/labels/flatten_series'));

/*
* Accepts a Kibana data object and returns an array of values objects.
*/

return function (obj) {
if (!_.isObject(obj) || !obj.rows && !obj.columns && !obj.series) {
throw new TypeError('GetArrayUtilService expects an object with a series, rows, or columns key');
}

if (!obj.series) {
return flattenSeries(obj);
}

if (!obj.series) return flattenSeries(obj);
return obj.series;
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ define(function (require) {
* Accepts a Kibana data object with a rows or columns key
* and returns an array of flattened series values.
*/

return function (obj) {
if (!_.isObject(obj) || !obj.rows && !obj.columns) {
throw new TypeError('GetSeriesUtilService expects an object with either a rows or columns key');
Expand Down
10 changes: 4 additions & 6 deletions src/kibana/components/vislib/components/labels/labels.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ define(function (require) {

var createArr = Private(require('components/vislib/components/labels/data_array'));
var getArrOfUniqLabels = Private(require('components/vislib/components/labels/uniq_labels'));
var getPieLabels = Private(require('components/vislib/components/labels/pie/pie_labels'));

/*
* Accepts a Kibana data object and returns an array of unique labels (strings).
Expand All @@ -12,12 +13,9 @@ define(function (require) {
*
* Currently, this service is only used for vertical bar charts and line charts.
*/

return function (obj) {
if (!_.isObject(obj)) {
throw new TypeError('LabelUtil expects an object');
}

return function (obj, chartType) {
if (!_.isObject(obj)) { throw new TypeError('LabelUtil expects an object'); }
if (chartType === 'pie') { return getPieLabels(obj); }
return getArrOfUniqLabels(createArr(obj));
};
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
define(function (require) {
var _ = require('lodash');

return function GetPieNames(Private) {
var returnNames = Private(require('components/vislib/components/labels/pie/return_pie_names'));

return function (data, columns) {
var slices = data.slices;

if (slices.children) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be better as an early return.

return _(returnNames(slices.children, 0, columns))
.sortBy(function (obj) {
return obj.index;
})
.pluck('key')
.unique()
.value();
}
};
};
});
26 changes: 26 additions & 0 deletions src/kibana/components/vislib/components/labels/pie/pie_labels.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
define(function (require) {
var _ = require('lodash');

return function PieLabels(Private) {
var removeZeroSlices = Private(require('components/vislib/components/labels/pie/remove_zero_slices'));
var getNames = Private(require('components/vislib/components/labels/pie/get_pie_names'));

return function (obj) {
var data = obj.columns || obj.rows || [obj];
var names = [];

if (!_.isObject(obj)) { throw new TypeError('PieLabel expects an object'); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be more helpful if it's before the var data = obj... assignment


data.forEach(function (obj) {
var columns = obj.raw ? obj.raw.columns : undefined;
obj.slices = removeZeroSlices(obj.slices);

getNames(obj, columns).forEach(function (name) {
names.push(name);
});
});

return _.uniq(names);
};
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
define(function (require) {
var _ = require('lodash');

return function RemoveZeroSlices() {
return function removeZeroSlices(slices) {
if (!slices.children) return slices;

slices = _.clone(slices);
slices.children = slices.children.reduce(function (children, child) {
if (child.size !== 0) { children.push(removeZeroSlices(child)); }
return children;
}, []);

return slices;
};
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
define(function () {
return function ReturnPieNames() {
return function returnNames(array, index, columns) {
var names = [];

array.forEach(function (obj) {
names.push({ key: obj.name, index: index });

if (obj.children) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be better as an early return.

returnNames(obj.children, (index + 1), columns).forEach(function (namedObj) {
names.push(namedObj);
});
}
});

return names;
};
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ define(function (require) {
* Accepts an array of data objects and a formatter function.
* Returns a unique list of formatted labels (strings).
*/

return function (arr) {
if (!_.isArray(arr)) {
throw new TypeError('UniqLabelUtil expects an array of objects');
Expand Down
39 changes: 18 additions & 21 deletions src/kibana/components/vislib/lib/data.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,8 @@ define(function (require) {

this.data = data;
this.type = this.getDataType();

this.labels;

if (this.type === 'series') {
if (getLabels(data).length === 1 && getLabels(data)[0] === '') {
this.labels = [(this.get('yAxisLabel'))];
} else {
this.labels = getLabels(data);
}
} else if (this.type === 'slices') {
this.labels = this.pieNames();
}

this.labels = this._getLabels(this.data);
this.color = this.labels ? color(this.labels) : undefined;

this._normalizeOrdered();

this._attr = _.defaults(attr || {}, {
Expand All @@ -73,6 +60,14 @@ define(function (require) {
}
}

Data.prototype._getLabels = function (data) {
if (this.type === 'series') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

every branch of this if resolves to a return, so no need for the else statements.`

if (getLabels(data).length === 1 && getLabels(data)[0] === '') return [(this.get('yAxisLabel'))];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps you should use variable for this if statement.

return getLabels(data);
}
return this.pieNames();
};

/**
* Returns true for positive numbers
*/
Expand Down Expand Up @@ -468,7 +463,7 @@ define(function (require) {
var self = this;

_.forEach(array, function (obj) {
names.push({ key: obj.name, index: index });
names.push({ label: obj.name, values: obj, index: index });

if (obj.children) {
var plusIndex = index + 1;
Expand Down Expand Up @@ -502,8 +497,9 @@ define(function (require) {
.sortBy(function (obj) {
return obj.index;
})
.pluck('key')
.unique()
.unique(function (d) {
return d.label;
})
.value();
}
};
Expand Down Expand Up @@ -536,9 +532,8 @@ define(function (require) {
* @method pieNames
* @returns {Array} Array of unique names (strings)
*/
Data.prototype.pieNames = function () {
Data.prototype.pieNames = function (data) {
var self = this;
var data = this.getVisData();
var names = [];

_.forEach(data, function (obj) {
Expand All @@ -550,7 +545,7 @@ define(function (require) {
});
});

return _.uniq(names);
return _.uniq(names, 'label');
};

/**
Expand Down Expand Up @@ -602,7 +597,9 @@ define(function (require) {
* @returns {Function} Performs lookup on string and returns hex color
*/
Data.prototype.getPieColorFunc = function () {
return color(this.pieNames());
return color(this.pieNames(this.getVisData()).map(function (d) {
return d.label;
}));
};

/**
Expand Down
17 changes: 9 additions & 8 deletions src/kibana/components/vislib/lib/dispatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,27 @@ define(function (require) {
*/
Dispatch.prototype.eventResponse = function (d, i) {
var datum = d._input || d;
var data = d3.event.target.nearestViewportElement.__data__;
var data = d3.event.target.nearestViewportElement ?
d3.event.target.nearestViewportElement.__data__ : d3.event.target.__data__;
var label = d.label ? d.label : d.name;
var isSeries = !!(data.series);
var isSlices = !!(data.slices);
var isSeries = !!(data && data.series);
var isSlices = !!(data && data.slices);
var series = isSeries ? data.series : undefined;
var slices = isSlices ? data.slices : undefined;
var handler = this.handler;
var color = handler.data.color;
var isPercentage = (handler._attr.mode === 'percentage');
var color = _.get(handler, 'data.color');
var isPercentage = (handler && handler._attr.mode === 'percentage');

var eventData = {
value: d.y,
point: datum,
datum: datum,
label: label,
color: color(label),
color: color ? color(label) : undefined,
pointIndex: i,
series: series,
slices: slices,
config: handler._attr,
config: handler && handler._attr,
data: data,
e: d3.event,
handler: handler
Expand Down Expand Up @@ -231,7 +232,7 @@ define(function (require) {
.select('.legend-ul')
.selectAll('li.color')
.filter(function (d, i) {
return this.getAttribute('data-label') !== label;
return String(d.label) !== label;
})
.classed('blur_shape', true);
};
Expand Down
7 changes: 7 additions & 0 deletions src/kibana/components/vislib/lib/handler/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ define(function (require) {
var errors = require('errors');

var Data = Private(require('components/vislib/lib/data'));
var Legend = Private(require('components/vislib/lib/legend'));
var Layout = Private(require('components/vislib/lib/layout/layout'));

/**
Expand Down Expand Up @@ -93,6 +94,12 @@ define(function (require) {

this._validateData();
this.renderArray.forEach(function (property) {
if (property instanceof Legend) {
self.vis.activeEvents().forEach(function (event) {
self.enable(event, property);
});
}

if (typeof property.render === 'function') {
property.render();
}
Expand Down
4 changes: 1 addition & 3 deletions src/kibana/components/vislib/lib/handler/types/pie.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@ define(function (require) {
*/

return function (vis) {
var data = new Data(vis.data, vis._attr);

return new Handler(vis, {
legend: new Legend(vis, vis.el, data.pieNames(), data.getPieColorFunc(), vis._attr),
legend: new Legend(vis),
chartTitle: new ChartTitle(vis.el)
});
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ define(function (require) {

return new Handler(vis, {
data: data,
legend: new Legend(vis, vis.el, data.labels, data.color, vis._attr),
legend: new Legend(vis, vis.data),
axisTitle: new AxisTitle(vis.el, data.get('xAxisLabel'), data.get('yAxisLabel')),
chartTitle: new ChartTitle(vis.el),
xAxis: new XAxis({
Expand Down
Loading