diff --git a/src/components/fx/helpers.js b/src/components/fx/helpers.js index c45da2b0ee5..a2b5580d026 100644 --- a/src/components/fx/helpers.js +++ b/src/components/fx/helpers.js @@ -8,6 +8,7 @@ 'use strict'; +var Lib = require('../../lib'); var constants = require('./constants'); // look for either subplot or xaxis and yaxis attributes @@ -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]; + } + } +}; diff --git a/src/components/fx/hover.js b/src/components/fx/hover.js index 4af8366b964..6f68788bd38 100644 --- a/src/components/fx/hover.js +++ b/src/components/fx/hover.js @@ -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); } diff --git a/src/components/fx/index.js b/src/components/fx/index.js index bec718443c8..34d7f711855 100644 --- a/src/components/fx/index.js +++ b/src/components/fx/index.js @@ -35,6 +35,7 @@ module.exports = { getDistanceFunction: helpers.getDistanceFunction, getClosest: helpers.getClosest, inbox: helpers.inbox, + appendArrayPointValue: helpers.appendArrayPointValue, castHoverOption: castHoverOption, castHoverinfo: castHoverinfo, diff --git a/src/plot_api/plot_schema.js b/src/plot_api/plot_schema.js index 0c88857c714..03bc35ad760 100644 --- a/src/plot_api/plot_schema.js +++ b/src/plot_api/plot_schema.js @@ -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; @@ -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); } diff --git a/src/plots/attributes.js b/src/plots/attributes.js index 43ce263b79d..405623be271 100644 --- a/src/plots/attributes.js +++ b/src/plots/attributes.js @@ -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', diff --git a/src/plots/cartesian/select.js b/src/plots/cartesian/select.js index 65835464e3d..cba5decac75 100644 --- a/src/plots/cartesian/select.js +++ b/src/plots/cartesian/select.js @@ -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'); @@ -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}; @@ -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; +} diff --git a/src/plots/gl2d/scene2d.js b/src/plots/gl2d/scene2d.js index ff92f2ac480..763ebf6470f 100644 --- a/src/plots/gl2d/scene2d.js +++ b/src/plots/gl2d/scene2d.js @@ -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++) { @@ -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() { diff --git a/src/plots/gl3d/scene.js b/src/plots/gl3d/scene.js index fdd678ace2b..fb550ed4a5d 100644 --- a/src/plots/gl3d/scene.js +++ b/src/plots/gl3d/scene.js @@ -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); } diff --git a/src/plots/plots.js b/src/plots/plots.js index ae79bcf7af5..38416678886 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -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; @@ -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; @@ -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; diff --git a/src/traces/scatter/attributes.js b/src/traces/scatter/attributes.js index 4d88511c280..726bb94bfef 100644 --- a/src/traces/scatter/attributes.js +++ b/src/traces/scatter/attributes.js @@ -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, @@ -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', diff --git a/src/traces/scatter/defaults.js b/src/traces/scatter/defaults.js index 5d0b9faf7c7..e7ed99fdda2 100644 --- a/src/traces/scatter/defaults.js +++ b/src/traces/scatter/defaults.js @@ -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); diff --git a/src/traces/scatter/select.js b/src/traces/scatter/select.js index 222d2b22566..127179a790c 100644 --- a/src/traces/scatter/select.js +++ b/src/traces/scatter/select.js @@ -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, @@ -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; } diff --git a/src/transforms/filter.js b/src/transforms/filter.js index 2a2a3182d2a..a9799c65818 100644 --- a/src/transforms/filter.js +++ b/src/transforms/filter.js @@ -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 = ['=', '!=', '<', '>=', '>', '<=']; @@ -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. @@ -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) { diff --git a/src/transforms/sort.js b/src/transforms/sort.js index 97fbec17b3e..41e34f1e8e9 100644 --- a/src/transforms/sort.js +++ b/src/transforms/sort.js @@ -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'; @@ -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); diff --git a/test/jasmine/tests/geo_test.js b/test/jasmine/tests/geo_test.js index bccd6ae3425..cdd6c90e261 100644 --- a/test/jasmine/tests/geo_test.js +++ b/test/jasmine/tests/geo_test.js @@ -536,7 +536,7 @@ describe('Test geo interactions', function() { it('should contain the correct fields', function() { expect(Object.keys(ptData)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', - 'lon', 'lat', 'location' + 'lon', 'lat', 'location', 'marker.size' ]); expect(cnt).toEqual(1); }); @@ -547,6 +547,7 @@ describe('Test geo interactions', function() { expect(ptData.location).toBe(null); expect(ptData.curveNumber).toEqual(0); expect(ptData.pointNumber).toEqual(0); + expect(ptData['marker.size']).toEqual(20); expect(cnt).toEqual(1); }); @@ -598,7 +599,7 @@ describe('Test geo interactions', function() { it('should contain the correct fields', function() { expect(Object.keys(ptData)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', - 'lon', 'lat', 'location' + 'lon', 'lat', 'location', 'marker.size' ]); }); @@ -608,6 +609,7 @@ describe('Test geo interactions', function() { expect(ptData.location).toBe(null); expect(ptData.curveNumber).toEqual(0); expect(ptData.pointNumber).toEqual(0); + expect(ptData['marker.size']).toEqual(20); }); }); @@ -629,7 +631,7 @@ describe('Test geo interactions', function() { it('should contain the correct fields', function() { expect(Object.keys(ptData)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', - 'lon', 'lat', 'location' + 'lon', 'lat', 'location', 'marker.size' ]); }); @@ -639,6 +641,7 @@ describe('Test geo interactions', function() { expect(ptData.location).toBe(null); expect(ptData.curveNumber).toEqual(0); expect(ptData.pointNumber).toEqual(0); + expect(ptData['marker.size']).toEqual(20); }); }); @@ -1100,7 +1103,7 @@ describe('Test event property of interactions on a geo plot:', function() { expect(Object.keys(pt)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', 'lon', 'lat', - 'location' + 'location', 'text', 'marker.size' ]); expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); @@ -1110,6 +1113,8 @@ describe('Test event property of interactions on a geo plot:', function() { expect(pt.lon).toEqual(57.75, 'points[0].lon'); expect(pt.location).toEqual(57.75, 'points[0].location'); expect(pt.pointNumber).toEqual(0, 'points[0].pointNumber'); + expect(pt.text).toEqual(20, 'points[0].text'); + expect(pt['marker.size']).toEqual(20, 'points[0][\'marker.size\']'); expect(evt.clientX).toEqual(pointPos[0], 'event.clientX'); expect(evt.clientY).toEqual(pointPos[1], 'event.clientY'); @@ -1146,7 +1151,7 @@ describe('Test event property of interactions on a geo plot:', function() { expect(Object.keys(pt)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', 'lon', 'lat', - 'location' + 'location', 'text', 'marker.size' ]); expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); @@ -1156,6 +1161,8 @@ describe('Test event property of interactions on a geo plot:', function() { expect(pt.lon).toEqual(57.75, 'points[0].lon'); expect(pt.location).toEqual(57.75, 'points[0].location'); expect(pt.pointNumber).toEqual(0, 'points[0].pointNumber'); + expect(pt.text).toEqual(20, 'points[0].text'); + expect(pt['marker.size']).toEqual(20, 'points[0][\'marker.size\']'); expect(evt.clientX).toEqual(pointPos[0], 'event.clientX'); expect(evt.clientY).toEqual(pointPos[1], 'event.clientY'); @@ -1185,7 +1192,7 @@ describe('Test event property of interactions on a geo plot:', function() { expect(Object.keys(pt)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', 'lon', 'lat', - 'location' + 'location', 'text', 'marker.size' ]); expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); @@ -1195,6 +1202,8 @@ describe('Test event property of interactions on a geo plot:', function() { expect(pt.lon).toEqual(57.75, 'points[0].lon'); expect(pt.location).toEqual(57.75, 'points[0].location'); expect(pt.pointNumber).toEqual(0, 'points[0].pointNumber'); + expect(pt.text).toEqual(20, 'points[0].text'); + expect(pt['marker.size']).toEqual(20, 'points[0][\'marker.size\']'); expect(evt.clientX).toEqual(pointPos[0], 'event.clientX'); expect(evt.clientY).toEqual(pointPos[1], 'event.clientY'); @@ -1219,7 +1228,7 @@ describe('Test event property of interactions on a geo plot:', function() { expect(Object.keys(pt)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', 'lon', 'lat', - 'location' + 'location', 'text', 'marker.size' ]); expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); @@ -1229,6 +1238,8 @@ describe('Test event property of interactions on a geo plot:', function() { expect(pt.lon).toEqual(57.75, 'points[0].lon'); expect(pt.location).toEqual(57.75, 'points[0].location'); expect(pt.pointNumber).toEqual(0, 'points[0].pointNumber'); + expect(pt.text).toEqual(20, 'points[0].text'); + expect(pt['marker.size']).toEqual(20, 'points[0][\'marker.size\']'); expect(evt.clientX).toEqual(nearPos[0], 'event.clientX'); expect(evt.clientY).toEqual(nearPos[1], 'event.clientY'); diff --git a/test/jasmine/tests/gl2d_click_test.js b/test/jasmine/tests/gl2d_click_test.js index 739055b81eb..134f3316d14 100644 --- a/test/jasmine/tests/gl2d_click_test.js +++ b/test/jasmine/tests/gl2d_click_test.js @@ -116,10 +116,10 @@ describe('Test hover and click interactions', function() { var pt = actual.points[0]; - expect(Object.keys(pt)).toEqual([ + expect(Object.keys(pt)).toEqual(jasmine.arrayContaining([ 'x', 'y', 'curveNumber', 'pointNumber', 'data', 'fullData', 'xaxis', 'yaxis' - ], 'event data keys'); + ]), 'event data keys'); expect(typeof pt.data.uid).toBe('string', msg + ' - uid'); expect(pt.xaxis.domain.length).toBe(2, msg + ' - xaxis'); diff --git a/test/jasmine/tests/gl_plot_interact_test.js b/test/jasmine/tests/gl_plot_interact_test.js index 8bc1f4cebba..f112a779a5b 100644 --- a/test/jasmine/tests/gl_plot_interact_test.js +++ b/test/jasmine/tests/gl_plot_interact_test.js @@ -59,17 +59,21 @@ describe('Test gl3d plots', function() { expect(text.style('fill')).toEqual(fontColor, 'font.color'); } - function assertEventData(x, y, z, curveNumber, pointNumber) { - expect(Object.keys(ptData)).toEqual([ + function assertEventData(x, y, z, curveNumber, pointNumber, extra) { + expect(Object.keys(ptData)).toEqual(jasmine.arrayContaining([ 'x', 'y', 'z', 'data', 'fullData', 'curveNumber', 'pointNumber' - ], 'correct hover data fields'); + ]), 'correct hover data fields'); expect(ptData.x).toEqual(x, 'x val'); expect(ptData.y).toEqual(y, 'y val'); expect(ptData.z).toEqual(z, 'z val'); expect(ptData.curveNumber).toEqual(curveNumber, 'curveNumber'); expect(ptData.pointNumber).toEqual(pointNumber, 'pointNumber'); + + Object.keys(extra || {}).forEach(function(k) { + expect(ptData[k]).toBe(extra[k], k + ' val'); + }); } beforeEach(function() { @@ -101,7 +105,12 @@ describe('Test gl3d plots', function() { .then(delay(20)) .then(function() { assertHoverText('x: 140.72', 'y: −96.97', 'z: −96.97'); - assertEventData(140.72, -96.97, -96.97, 0, 2); + assertEventData(140.72, -96.97, -96.97, 0, 2, { + 'marker.symbol': 'cross', + 'marker.size': 30, + 'marker.color': 'orange', + 'marker.line.color': undefined + }); assertHoverLabelStyle('rgb(0, 0, 255)', 'rgb(255, 255, 255)', 13, 'Arial', 'rgb(255, 255, 255)'); return Plotly.restyle(gd, { @@ -226,6 +235,10 @@ describe('Test gl3d plots', function() { }) .then(_hover) .then(function() { + assertEventData(1, 2, 43, 0, [1, 2], { + 'hoverinfo': 'y', + 'hoverlabel.font.color': 'cyan' + }); assertHoverLabelStyle('rgb(255, 255, 255)', 'rgb(68, 68, 68)', 9, 'Arial', 'rgb(0, 255, 255)'); var label = d3.selectAll('g.hovertext'); diff --git a/test/jasmine/tests/scattermapbox_test.js b/test/jasmine/tests/scattermapbox_test.js index 6b65c668f95..5045fd8532d 100644 --- a/test/jasmine/tests/scattermapbox_test.js +++ b/test/jasmine/tests/scattermapbox_test.js @@ -591,8 +591,8 @@ describe('@noCI Test plotly events on a scattermapbox plot:', function() { expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); expect(typeof pt.data).toEqual(typeof {}, 'points[0].data'); expect(typeof pt.fullData).toEqual(typeof {}, 'points[0].fullData'); - expect(pt.lat).toEqual(undefined, 'points[0].lat'); - expect(pt.lon).toEqual(undefined, 'points[0].lon'); + expect(pt.lat).toEqual(10, 'points[0].lat'); + expect(pt.lon).toEqual(10, 'points[0].lon'); expect(pt.pointNumber).toEqual(0, 'points[0].pointNumber'); expect(evt.clientX).toEqual(pointPos[0], 'event.clientX'); @@ -635,8 +635,8 @@ describe('@noCI Test plotly events on a scattermapbox plot:', function() { expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); expect(typeof pt.data).toEqual(typeof {}, 'points[0].data'); expect(typeof pt.fullData).toEqual(typeof {}, 'points[0].fullData'); - expect(pt.lat).toEqual(undefined, 'points[0].lat'); - expect(pt.lon).toEqual(undefined, 'points[0].lon'); + expect(pt.lat).toEqual(10, 'points[0].lat'); + expect(pt.lon).toEqual(10, 'points[0].lon'); expect(pt.pointNumber).toEqual(0, 'points[0].pointNumber'); expect(evt.clientX).toEqual(pointPos[0], 'event.clientX'); @@ -672,8 +672,8 @@ describe('@noCI Test plotly events on a scattermapbox plot:', function() { expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); expect(typeof pt.data).toEqual(typeof {}, 'points[0].data'); expect(typeof pt.fullData).toEqual(typeof {}, 'points[0].fullData'); - expect(pt.lat).toEqual(undefined, 'points[0].lat'); - expect(pt.lon).toEqual(undefined, 'points[0].lon'); + expect(pt.lat).toEqual(10, 'points[0].lat'); + expect(pt.lon).toEqual(10, 'points[0].lon'); expect(pt.pointNumber).toEqual(0, 'points[0].pointNumber'); expect(evt.clientX).toEqual(pointPos[0], 'event.clientX'); @@ -704,8 +704,8 @@ describe('@noCI Test plotly events on a scattermapbox plot:', function() { expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); expect(typeof pt.data).toEqual(typeof {}, 'points[0].data'); expect(typeof pt.fullData).toEqual(typeof {}, 'points[0].fullData'); - expect(pt.lat).toEqual(undefined, 'points[0].lat'); - expect(pt.lon).toEqual(undefined, 'points[0].lon'); + expect(pt.lat).toEqual(10, 'points[0].lat'); + expect(pt.lon).toEqual(10, 'points[0].lon'); expect(pt.pointNumber).toEqual(0, 'points[0].pointNumber'); expect(evt.clientX).toEqual(nearPos[0], 'event.clientX'); diff --git a/test/jasmine/tests/select_test.js b/test/jasmine/tests/select_test.js index cbad8d1504c..37cf778b940 100644 --- a/test/jasmine/tests/select_test.js +++ b/test/jasmine/tests/select_test.js @@ -42,6 +42,23 @@ describe('select box and lasso', function() { expect(actual.y).toBeCloseToArray(expected.y, PRECISION); } + function assertEventData(actual, expected, msg) { + expect(actual.length).toBe(expected.length, msg + ' same number of pts'); + + expected.forEach(function(e, i) { + var a = actual[i]; + var m = msg + ' (pt ' + i + ')'; + + expect(a.data).toBeDefined(m + ' has data ref'); + expect(a.fullData).toBeDefined(m + ' has fullData ref'); + expect(Object.keys(a).length - 2).toBe(Object.keys(e).length, m + ' has correct number of keys'); + + Object.keys(e).forEach(function(k) { + expect(a[k]).toBe(e[k], m + ' ' + k); + }); + }); + } + describe('select elements', function() { var mockCopy = Lib.extendDeep({}, mock); mockCopy.layout.dragmode = 'select'; @@ -143,6 +160,10 @@ describe('select box and lasso', function() { describe('select events', function() { var mockCopy = Lib.extendDeep({}, mock); mockCopy.layout.dragmode = 'select'; + mockCopy.data[0].ids = mockCopy.data[0].x + .map(function(v) { return 'id-' + v; }); + mockCopy.data[0].customdata = mockCopy.data[0].y + .map(function(v) { return 'customdata-' + v; }); var gd; beforeEach(function(done) { @@ -175,38 +196,41 @@ describe('select box and lasso', function() { drag(selectPath); expect(selectingCnt).toEqual(1, 'with the correct selecting count'); - expect(selectingData.points).toEqual([{ + assertEventData(selectingData.points, [{ curveNumber: 0, pointNumber: 0, x: 0.002, y: 16.25, - id: undefined + id: 'id-0.002', + customdata: 'customdata-16.25' }, { curveNumber: 0, pointNumber: 1, x: 0.004, y: 12.5, - id: undefined - }], 'with the correct selecting points'); + id: 'id-0.004', + customdata: 'customdata-12.5' + }], 'with the correct selecting points (1)'); assertRange(selectingData.range, { x: [0.002000, 0.0046236], y: [0.10209191961595454, 24.512223978291406] }, 'with the correct selecting range'); - expect(selectedCnt).toEqual(1, 'with the correct selected count'); - expect(selectedData.points).toEqual([{ + assertEventData(selectedData.points, [{ curveNumber: 0, pointNumber: 0, x: 0.002, y: 16.25, - id: undefined + id: 'id-0.002', + customdata: 'customdata-16.25' }, { curveNumber: 0, pointNumber: 1, x: 0.004, y: 12.5, - id: undefined - }], 'with the correct selected points'); + id: 'id-0.004', + customdata: 'customdata-12.5' + }], 'with the correct selected points (2)'); assertRange(selectedData.range, { x: [0.002000, 0.0046236], y: [0.10209191961595454, 24.512223978291406] @@ -255,22 +279,20 @@ describe('select box and lasso', function() { drag(lassoPath); expect(selectingCnt).toEqual(3, 'with the correct selecting count'); - expect(selectingData.points).toEqual([{ + assertEventData(selectingData.points, [{ curveNumber: 0, pointNumber: 10, x: 0.099, - y: 2.75, - id: undefined - }], 'with the correct selecting points'); + y: 2.75 + }], 'with the correct selecting points (1)'); expect(selectedCnt).toEqual(1, 'with the correct selected count'); - expect(selectedData.points).toEqual([{ + assertEventData(selectedData.points, [{ curveNumber: 0, pointNumber: 10, x: 0.099, y: 2.75, - id: undefined - }], 'with the correct selected points'); + }], 'with the correct selected points (2)'); doubleClick(250, 200).then(function() { expect(doubleClickData).toBe(null, 'with the correct deselect data'); diff --git a/test/jasmine/tests/ternary_test.js b/test/jasmine/tests/ternary_test.js index 741d45d511b..ade4abf3d2c 100644 --- a/test/jasmine/tests/ternary_test.js +++ b/test/jasmine/tests/ternary_test.js @@ -163,7 +163,7 @@ describe('ternary plots', function() { expect(hoverData).not.toBe(undefined, 'firing on data points'); expect(Object.keys(hoverData)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', - 'x', 'y', 'xaxis', 'yaxis' + 'x', 'y', 'xaxis', 'yaxis', 'a', 'b', 'c' ], 'returning the correct event data keys'); expect(hoverData.curveNumber).toEqual(0, 'returning the correct curve number'); expect(hoverData.pointNumber).toEqual(0, 'returning the correct point number'); @@ -172,7 +172,7 @@ describe('ternary plots', function() { expect(unhoverData).not.toBe(undefined, 'firing on data points'); expect(Object.keys(unhoverData)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', - 'x', 'y', 'xaxis', 'yaxis' + 'x', 'y', 'xaxis', 'yaxis', 'a', 'b', 'c' ], 'returning the correct event data keys'); expect(unhoverData.curveNumber).toEqual(0, 'returning the correct curve number'); expect(unhoverData.pointNumber).toEqual(0, 'returning the correct point number'); @@ -195,7 +195,7 @@ describe('ternary plots', function() { expect(ptData).not.toBe(undefined, 'firing on data points'); expect(Object.keys(ptData)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', - 'x', 'y', 'xaxis', 'yaxis' + 'x', 'y', 'xaxis', 'yaxis', 'a', 'b', 'c' ], 'returning the correct event data keys'); expect(ptData.curveNumber).toEqual(0, 'returning the correct curve number'); expect(ptData.pointNumber).toEqual(0, 'returning the correct point number'); @@ -404,7 +404,7 @@ describe('Test event property of interactions on a ternary plot:', function() { expect(Object.keys(pt)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', 'x', 'y', - 'xaxis', 'yaxis' + 'xaxis', 'yaxis', 'a', 'b', 'c' ]); expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); @@ -415,6 +415,9 @@ describe('Test event property of interactions on a ternary plot:', function() { expect(pt.y).toEqual(undefined, 'points[0].y'); expect(typeof pt.xaxis).toEqual(typeof {}, 'points[0].xaxis'); expect(typeof pt.yaxis).toEqual(typeof {}, 'points[0].yaxis'); + expect(pt.a).toEqual(2, 'points[0].a'); + expect(pt.b).toEqual(1, 'points[0].b'); + expect(pt.c).toEqual(1, 'points[0].c'); expect(evt.clientX).toEqual(pointPos[0], 'event.clientX'); expect(evt.clientY).toEqual(pointPos[1], 'event.clientY'); @@ -451,7 +454,7 @@ describe('Test event property of interactions on a ternary plot:', function() { expect(Object.keys(pt)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', 'x', 'y', - 'xaxis', 'yaxis' + 'xaxis', 'yaxis', 'a', 'b', 'c' ]); expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); @@ -462,6 +465,9 @@ describe('Test event property of interactions on a ternary plot:', function() { expect(pt.y).toEqual(undefined, 'points[0].y'); expect(typeof pt.xaxis).toEqual(typeof {}, 'points[0].xaxis'); expect(typeof pt.yaxis).toEqual(typeof {}, 'points[0].yaxis'); + expect(pt.a).toEqual(2, 'points[0].a'); + expect(pt.b).toEqual(1, 'points[0].b'); + expect(pt.c).toEqual(1, 'points[0].c'); expect(evt.clientX).toEqual(pointPos[0], 'event.clientX'); expect(evt.clientY).toEqual(pointPos[1], 'event.clientY'); @@ -495,7 +501,7 @@ describe('Test event property of interactions on a ternary plot:', function() { expect(Object.keys(pt)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', 'x', 'y', - 'xaxis', 'yaxis' + 'xaxis', 'yaxis', 'a', 'b', 'c' ]); expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); @@ -506,6 +512,9 @@ describe('Test event property of interactions on a ternary plot:', function() { expect(pt.y).toEqual(undefined, 'points[0].y'); expect(typeof pt.xaxis).toEqual(typeof {}, 'points[0].xaxis'); expect(typeof pt.yaxis).toEqual(typeof {}, 'points[0].yaxis'); + expect(pt.a).toEqual(2, 'points[0].a'); + expect(pt.b).toEqual(1, 'points[0].b'); + expect(pt.c).toEqual(1, 'points[0].c'); expect(xaxes0).toEqual(pt.xaxis, 'xaxes[0]'); expect(xvals0).toEqual(-0.0016654247744483342, 'xaxes[0]'); @@ -538,7 +547,7 @@ describe('Test event property of interactions on a ternary plot:', function() { expect(Object.keys(pt)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', 'x', 'y', - 'xaxis', 'yaxis' + 'xaxis', 'yaxis', 'a', 'b', 'c' ]); expect(pt.curveNumber).toEqual(0, 'points[0].curveNumber'); @@ -549,6 +558,9 @@ describe('Test event property of interactions on a ternary plot:', function() { expect(pt.y).toEqual(undefined, 'points[0].y'); expect(typeof pt.xaxis).toEqual(typeof {}, 'points[0].xaxis'); expect(typeof pt.yaxis).toEqual(typeof {}, 'points[0].yaxis'); + expect(pt.a).toEqual(2, 'points[0].a'); + expect(pt.b).toEqual(1, 'points[0].b'); + expect(pt.c).toEqual(1, 'points[0].c'); expect(evt.clientX).toEqual(pointPos[0], 'event.clientX'); expect(evt.clientY).toEqual(pointPos[1], 'event.clientY');