Skip to content

Commit

Permalink
Merge pull request #1770 from plotly/all-array-attrs-in-event-data
Browse files Browse the repository at this point in the history
Include values of all array attributes in hover/click/select event data
  • Loading branch information
etpinard committed Jun 15, 2017
2 parents b6843a6 + 3399a58 commit ffb3791
Show file tree
Hide file tree
Showing 20 changed files with 212 additions and 89 deletions.
27 changes: 27 additions & 0 deletions src/components/fx/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

'use strict';

var Lib = require('../../lib');
var constants = require('./constants');

// look for either subplot or xaxis and yaxis attributes
Expand Down Expand Up @@ -83,3 +84,29 @@ function quadrature(dx, dy) {
return Math.sqrt(x * x + y * y);
};
}

/** Appends values inside array attributes corresponding to given point number
*
* @param {object} pointData : point data object (gets mutated here)
* @param {object} trace : full trace object
* @param {number} pointNumber : point number
*/
exports.appendArrayPointValue = function(pointData, trace, pointNumber) {
var arrayAttrs = trace._arrayAttrs;

for(var i = 0; i < arrayAttrs.length; i++) {
var astr = arrayAttrs[i];
var key;

if(astr === 'ids') key = 'id';
else if(astr === 'locations') key = 'location';
else key = astr;

if(pointData[key] === undefined) {
var val = Lib.nestedProperty(trace, astr).get();
pointData[key] = Array.isArray(pointNumber) ?
val[pointNumber[0]][pointNumber[1]] :
val[pointNumber];
}
}
};
1 change: 1 addition & 0 deletions src/components/fx/hover.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,7 @@ function _hover(gd, evt, subplot) {
if(pt.zLabelVal !== undefined) out.z = pt.zLabelVal;
}

helpers.appendArrayPointValue(out, pt.trace, pt.index);
newhoverdata.push(out);
}

Expand Down
1 change: 1 addition & 0 deletions src/components/fx/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module.exports = {
getDistanceFunction: helpers.getDistanceFunction,
getClosest: helpers.getClosest,
inbox: helpers.inbox,
appendArrayPointValue: helpers.appendArrayPointValue,

castHoverOption: castHoverOption,
castHoverinfo: castHoverinfo,
Expand Down
7 changes: 4 additions & 3 deletions src/plot_api/plot_schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ exports.findArrayAttributes = function(trace) {
}

exports.crawl(baseAttributes, callback);
exports.crawl(trace._module.attributes, callback);
if(trace._module && trace._module.attributes) {
exports.crawl(trace._module.attributes, callback);
}

if(trace.transforms) {
var transforms = trace.transforms;
Expand All @@ -177,9 +179,8 @@ exports.findArrayAttributes = function(trace) {
// At the moment, we need this block to make sure that
// ohlc and candlestick 'open', 'high', 'low', 'close' can be
// used with filter ang groupby transforms.
if(trace._fullInput) {
if(trace._fullInput && trace._fullInput._module && trace._fullInput._module.attributes) {
exports.crawl(trace._fullInput._module.attributes, callback);

arrayAttributes = Lib.filterUnique(arrayAttributes);
}

Expand Down
16 changes: 16 additions & 0 deletions src/plots/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ module.exports = {
role: 'info',
dflt: ''
},
ids: {
valType: 'data_array',
description: [
'Assigns id labels to each datum.',
'These ids for object constancy of data points during animation.'
].join(' ')
},
customdata: {
valType: 'data_array',
description: [
'Assigns extra data each datum.',
'This may be useful when listening to hover, click and selection events.',
'Note that, *scatter* traces also appends customdata items in the markers',
'DOM elements'
].join(' ')
},
hoverinfo: {
valType: 'flaglist',
role: 'info',
Expand Down
22 changes: 21 additions & 1 deletion src/plots/cartesian/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

var polygon = require('../../lib/polygon');
var color = require('../../components/color');
var appendArrayPointValue = require('../../components/fx/helpers').appendArrayPointValue;

var axes = require('./axes');
var constants = require('./constants');
Expand Down Expand Up @@ -151,7 +152,9 @@ module.exports = function prepSelect(e, startX, startY, dragOptions, mode) {
selection = [];
for(i = 0; i < searchTraces.length; i++) {
searchInfo = searchTraces[i];
[].push.apply(selection, searchInfo.selectPoints(searchInfo, poly));
[].push.apply(selection, fillSelectionItem(
searchInfo.selectPoints(searchInfo, poly), searchInfo
));
}

eventData = {points: selection};
Expand Down Expand Up @@ -196,3 +199,20 @@ module.exports = function prepSelect(e, startX, startY, dragOptions, mode) {
}
};
};

function fillSelectionItem(selection, searchInfo) {
if(Array.isArray(selection)) {
var trace = searchInfo.cd[0].trace;

for(var i = 0; i < selection.length; i++) {
var sel = selection[i];

sel.curveNumber = trace.index;
sel.data = trace._input;
sel.fullData = trace;
appendArrayPointValue(sel, trace, sel.pointNumber);
}
}

return selection;
}
27 changes: 15 additions & 12 deletions src/plots/gl2d/scene2d.js
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ proto.updateTraces = function(fullData, calcData) {

proto.emitPointAction = function(nextSelection, eventType) {
var uid = nextSelection.trace.uid;
var ptNumber = nextSelection.pointIndex;
var trace;

for(var i = 0; i < this.fullData.length; i++) {
Expand All @@ -533,18 +534,20 @@ proto.emitPointAction = function(nextSelection, eventType) {
}
}

this.graphDiv.emit(eventType, {
points: [{
x: nextSelection.traceCoord[0],
y: nextSelection.traceCoord[1],
curveNumber: trace.index,
pointNumber: nextSelection.pointIndex,
data: trace._input,
fullData: this.fullData,
xaxis: this.xaxis,
yaxis: this.yaxis
}]
});
var pointData = {
x: nextSelection.traceCoord[0],
y: nextSelection.traceCoord[1],
curveNumber: trace.index,
pointNumber: ptNumber,
data: trace._input,
fullData: this.fullData,
xaxis: this.xaxis,
yaxis: this.yaxis
};

Fx.appendArrayPointValue(pointData, trace, ptNumber);

this.graphDiv.emit(eventType, {points: [pointData]});
};

proto.draw = function() {
Expand Down
22 changes: 12 additions & 10 deletions src/plots/gl3d/scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,18 +103,20 @@ function render(scene) {
});
}

var eventData = {
points: [{
x: selection.traceCoordinate[0],
y: selection.traceCoordinate[1],
z: selection.traceCoordinate[2],
data: trace._input,
fullData: trace,
curveNumber: trace.index,
pointNumber: ptNumber
}]
var pointData = {
x: selection.traceCoordinate[0],
y: selection.traceCoordinate[1],
z: selection.traceCoordinate[2],
data: trace._input,
fullData: trace,
curveNumber: trace.index,
pointNumber: ptNumber
};

Fx.appendArrayPointValue(pointData, trace, ptNumber);

var eventData = {points: [pointData]};

if(selection.buttons && selection.distance < 5) {
scene.graphDiv.emit('plotly_click', eventData);
}
Expand Down
11 changes: 10 additions & 1 deletion src/plots/plots.js
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ plots.supplyDefaults = function(gd) {

function remapTransformedArrays(cd0, newTrace) {
var oldTrace = cd0.trace;
var arrayAttrs = PlotSchema.findArrayAttributes(oldTrace);
var arrayAttrs = oldTrace._arrayAttrs;
var transformedArrayHash = {};
var i, astr;

Expand Down Expand Up @@ -862,6 +862,9 @@ plots.supplyTraceDefaults = function(traceIn, traceOutIndex, layout, traceInInde
}

if(visible) {
coerce('customdata');
coerce('ids');

var _module = plots.getModule(traceOut);
traceOut._module = _module;

Expand Down Expand Up @@ -2032,6 +2035,12 @@ plots.doCalcdata = function(gd, traces) {
}
}

// find array attributes in trace
for(i = 0; i < fullData.length; i++) {
trace = fullData[i];
trace._arrayAttrs = PlotSchema.findArrayAttributes(trace);
}

initCategories(axList);

var hasCalcTransform = false;
Expand Down
8 changes: 0 additions & 8 deletions src/traces/scatter/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ module.exports = {
'where `y0` is the starting coordinate and `dy` the step.'
].join(' ')
},
customdata: {
valType: 'data_array',
description: 'Assigns extra data to each scatter point DOM element'
},
dy: {
valType: 'number',
dflt: 1,
Expand All @@ -70,10 +66,6 @@ module.exports = {
'See `y0` for more info.'
].join(' ')
},
ids: {
valType: 'data_array',
description: 'A list of keys for object constancy of data points during animation'
},
text: {
valType: 'string',
role: 'info',
Expand Down
2 changes: 0 additions & 2 deletions src/traces/scatter/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
return;
}

coerce('customdata');
coerce('text');
coerce('hovertext');
coerce('mode', defaultMode);
coerce('ids');

if(subTypes.hasLines(traceOut)) {
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
Expand Down
5 changes: 1 addition & 4 deletions src/traces/scatter/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ module.exports = function selectPoints(searchInfo, polygon) {
ya = searchInfo.yaxis,
selection = [],
trace = cd[0].trace,
curveNumber = trace.index,
marker = trace.marker,
i,
di,
Expand All @@ -43,11 +42,9 @@ module.exports = function selectPoints(searchInfo, polygon) {

if(polygon.contains([x, y])) {
selection.push({
curveNumber: curveNumber,
pointNumber: i,
x: di.x,
y: di.y,
id: di.id
y: di.y
});
di.dim = 0;
}
Expand Down
3 changes: 1 addition & 2 deletions src/transforms/filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

var Lib = require('../lib');
var Registry = require('../registry');
var PlotSchema = require('../plot_api/plot_schema');
var Axes = require('../plots/cartesian/axes');

var COMPARISON_OPS = ['=', '!=', '<', '>=', '>', '<='];
Expand Down Expand Up @@ -148,6 +147,7 @@ exports.calcTransform = function(gd, trace, opts) {
var target = opts.target;
var len = targetArray.length;
var targetCalendar = opts.targetcalendar;
var arrayAttrs = trace._arrayAttrs;

// even if you provide targetcalendar, if target is a string and there
// is a calendar attribute matching target it will get used instead.
Expand All @@ -158,7 +158,6 @@ exports.calcTransform = function(gd, trace, opts) {

var d2c = Axes.getDataToCoordFunc(gd, trace, target, targetArray);
var filterFunc = getFilterFunc(opts, d2c, targetCalendar);
var arrayAttrs = PlotSchema.findArrayAttributes(trace);
var originalArrays = {};

function forAllAttrs(fn, index) {
Expand Down
3 changes: 1 addition & 2 deletions src/transforms/sort.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
'use strict';

var Lib = require('../lib');
var PlotSchema = require('../plot_api/plot_schema');
var Axes = require('../plots/cartesian/axes');

exports.moduleType = 'transform';
Expand Down Expand Up @@ -78,7 +77,7 @@ exports.calcTransform = function(gd, trace, opts) {

var target = opts.target;
var len = targetArray.length;
var arrayAttrs = PlotSchema.findArrayAttributes(trace);
var arrayAttrs = trace._arrayAttrs;
var d2c = Axes.getDataToCoordFunc(gd, trace, target, targetArray);
var indices = getIndices(opts, targetArray, d2c);

Expand Down
Loading

0 comments on commit ffb3791

Please sign in to comment.