Skip to content

scatter marker color gradients #1620

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 9 commits into from
May 3, 2017
86 changes: 86 additions & 0 deletions test/jasmine/tests/drawing_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ var Drawing = require('@src/components/drawing');

var d3 = require('d3');

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('Drawing', function() {
'use strict';

Expand Down Expand Up @@ -309,3 +315,83 @@ describe('Drawing', function() {
});
});
});

describe('gradients', function() {
var gd;

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

afterEach(destroyGraphDiv);

function checkGradientIds(uid, specs) {
var sortedExpected = specs.map(function(spec) {
return (spec[0] + uid + '-' + spec[1] + '-' + spec[2]).replace(/[^\w\-]+/g, '_');
}).sort();

var gids = [];
var gradients = d3.select(gd).selectAll('radialGradient,linearGradient');
gradients.each(function() { gids.push(this.id); });
gids.sort();

expect(gids.length).toBe(sortedExpected.length);

for(var i = 0; i < Math.min(gids.length, sortedExpected.length); i++) {
expect(gids[i]).toBe(sortedExpected[i]);
}
}

it('clears unused gradients after a replot', function(done) {
Plotly.plot(gd, [{
y: [0, 1, 2],
mode: 'markers',
marker: {
color: '#123',
gradient: {
type: 'radial',
color: ['#fff', '#eee', '#ddd']
}
}
}])
.then(function() {
checkGradientIds(gd._fullLayout._uid, [
['radial', '#123', '#fff'],
['radial', '#123', '#eee'],
['radial', '#123', '#ddd']
]);

return Plotly.restyle(gd, {'marker.color': '#456'});
})
.then(function() {
// simple scalar restyle doesn't trigger a full replot, so
// doesn't clear the old gradients
checkGradientIds(gd._fullLayout._uid, [
['radial', '#123', '#fff'],
['radial', '#123', '#eee'],
['radial', '#123', '#ddd'],
['radial', '#456', '#fff'],
['radial', '#456', '#eee'],
['radial', '#456', '#ddd']
]);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not happy with this... there are a bunch of ways for it to blow up in actual use, like if someone makes 1000 different gradients via different marker colors, and animates them through 1000 intermediate states, suddenly you have a million gradients lying around.

I think I need to change it to associating the gradient with the point rather than with the color combo - unless someone has another idea how to keep this in check.


return Plotly.restyle(gd, {'marker.gradient.type': [['horizontal', 'vertical', 'radial']]});
})
.then(function() {
// array restyle does replot
checkGradientIds(gd._fullLayout._uid, [
['horizontal', '#456', '#fff'],
['vertical', '#456', '#eee'],
['radial', '#456', '#ddd']
]);

return Plotly.restyle(gd, {'mode': 'lines'});
})
.then(function() {
// full replot and no resulting markers at all -> no gradients
checkGradientIds(gd._fullLayout._uid, []);
})
.catch(fail)
.then(done);
});
});