Skip to content

Pass customdata through to scatter calcdata #1379

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

Merged
merged 7 commits into from
Feb 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions src/traces/scatter/arrays_to_calcdata.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ var Lib = require('../../lib');
module.exports = function arraysToCalcdata(cd, trace) {

Lib.mergeArray(trace.text, cd, 'tx');
Lib.mergeArray(trace.customdata, cd, 'data');
Lib.mergeArray(trace.textposition, cd, 'tp');
if(trace.textfont) {
Lib.mergeArray(trace.textfont.size, cd, 'ts');
Expand Down
4 changes: 4 additions & 0 deletions src/traces/scatter/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ 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 Down
1 change: 1 addition & 0 deletions src/traces/scatter/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
return;
}

coerce('customdata');
coerce('text');
coerce('mode', defaultMode);
coerce('ids');
Expand Down
7 changes: 6 additions & 1 deletion src/traces/scatter/plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,9 +428,14 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
}

join.each(function(d) {
var sel = transition(d3.select(this));
var el = d3.select(this);
var sel = transition(el);
Drawing.translatePoint(d, sel, xa, ya);
Drawing.singlePointStyle(d, sel, trace);

if(trace.customdata) {
el.classed('plotly-customdata', d.data !== null && d.data !== undefined);
}
});

if(hasTransition) {
Expand Down
12 changes: 8 additions & 4 deletions src/traces/scatter/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ module.exports = function style(gd) {

s.selectAll('g.points')
.each(function(d) {
d3.select(this).selectAll('path.point')
.call(Drawing.pointStyle, d.trace || d[0].trace);
d3.select(this).selectAll('text')
.call(Drawing.textPointStyle, d.trace || d[0].trace);
var el = d3.select(this);
var pts = el.selectAll('path.point');
var trace = d.trace || d[0].trace;

pts.call(Drawing.pointStyle, trace);

el.selectAll('text')
.call(Drawing.textPointStyle, trace);
});

s.selectAll('g.trace path.js-line')
Expand Down
14 changes: 14 additions & 0 deletions test/jasmine/tests/calcdata_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -862,4 +862,18 @@ describe('calculated data and points', function() {
});
});
});

describe('customdata', function() {
it('should pass customdata to the calcdata points', function() {
Plotly.plot(gd, [{
x: [0, 1, 3],
y: [4, 5, 7],
customdata: ['a', 'b', {foo: 'bar'}]
}], {});

expect(gd.calcdata[0][0]).toEqual(jasmine.objectContaining({data: 'a'}));
expect(gd.calcdata[0][1]).toEqual(jasmine.objectContaining({data: 'b'}));
expect(gd.calcdata[0][2]).toEqual(jasmine.objectContaining({data: {foo: 'bar'}}));
});
});
});
46 changes: 46 additions & 0 deletions test/jasmine/tests/scatter_test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
var d3 = require('d3');
var Scatter = require('@src/traces/scatter');
var makeBubbleSizeFn = require('@src/traces/scatter/make_bubble_size_func');
var linePoints = require('@src/traces/scatter/line_points');
var Lib = require('@src/lib');

var Plotly = require('@lib/index');
var createGraphDiv = require('../assets/create_graph_div');
var destroyGraphDiv = require('../assets/destroy_graph_div');
var fail = require('../assets/fail_test');

describe('Test scatter', function() {
'use strict';

Expand Down Expand Up @@ -326,3 +332,43 @@ describe('Test scatter', function() {
});

});

describe('end-to-end scatter tests', function() {
var gd;

beforeEach(function() {
gd = createGraphDiv();
});

afterEach(destroyGraphDiv);

it('should add a plotly-customdata class to points with custom data', function(done) {
Plotly.plot(gd, [{
x: [1, 2, 3, 4, 5, 6, 7],
y: [2, 3, 4, 5, 6, 7, 8],
customdata: [null, undefined, 0, false, {foo: 'bar'}, 'a']
}]).then(function() {
var points = d3.selectAll('g.scatterlayer').selectAll('.point');

// Rather than just duplicating the logic, let's be explicit about
// what's expected. Specifially, only null and undefined (the default)
// do *not* add the class.
var expected = [false, false, true, true, true, true, false];

points.each(function(cd, i) {
expect(d3.select(this).classed('plotly-customdata')).toBe(expected[i]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Beautiful test. I agree, end-to-end is the right way to test this particular beast.

});

return Plotly.animate(gd, [{
data: [{customdata: []}]
}], {frame: {redraw: false, duration: 0}});
}).then(function() {
var points = d3.selectAll('g.scatterlayer').selectAll('.point');

points.each(function() {
expect(d3.select(this).classed('plotly-customdata')).toBe(false);
});

}).catch(fail).then(done);
});
});