Skip to content

Commit 1256c4f

Browse files
authored
Merge pull request #2377 from plotly/regl-scatter-fix
Fix color clustering
2 parents ce5bc97 + 0e746bf commit 1256c4f

10 files changed

+942
-1316
lines changed

package-lock.json

+827-1,286
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+6-6
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
"gl-select-box": "^1.0.2",
8484
"gl-spikes2d": "^1.0.1",
8585
"gl-surface3d": "^1.3.4",
86-
"glslify": "^6.1.0",
86+
"glslify": "^6.1.1",
8787
"has-hover": "^1.0.1",
8888
"has-passive-events": "^1.0.0",
8989
"kdgrass": "^1.0.1",
@@ -99,8 +99,8 @@
9999
"polybooljs": "^1.2.0",
100100
"regl": "^1.3.1",
101101
"regl-error2d": "^2.0.3",
102-
"regl-line2d": "^2.1.4",
103-
"regl-scatter2d": "^2.1.13",
102+
"regl-line2d": "^2.1.5",
103+
"regl-scatter2d": "^2.1.17",
104104
"right-now": "^1.0.0",
105105
"robust-orientation": "^1.1.3",
106106
"sane-topojson": "^2.0.0",
@@ -119,18 +119,18 @@
119119
"check-node-version": "^3.2.0",
120120
"deep-equal": "^1.0.1",
121121
"ecstatic": "^3.2.0",
122-
"eslint": "^4.17.0",
122+
"eslint": "^4.18.0",
123123
"falafel": "^2.0.0",
124124
"fs-extra": "^2.0.0",
125125
"fuse.js": "^3.2.0",
126126
"glob": "^7.0.0",
127127
"gzip-size": "^4.1.0",
128128
"image-size": "^0.6.2",
129129
"into-stream": "^3.1.0",
130-
"jasmine-core": "^2.4.1",
130+
"jasmine-core": "^2.99.1",
131131
"jsdom": "^11.6.2",
132132
"karma": "^2.0.0",
133-
"karma-browserify": "^5.1.1",
133+
"karma-browserify": "^5.2.0",
134134
"karma-chrome-launcher": "^2.0.0",
135135
"karma-coverage": "^1.0.0",
136136
"karma-firefox-launcher": "^1.0.1",

src/lib/index.js

+16
Original file line numberDiff line numberDiff line change
@@ -876,3 +876,19 @@ lib.subplotSort = function(a, b) {
876876
}
877877
return numB - numA;
878878
};
879+
880+
// repeatable pseudorandom generator
881+
var randSeed = 2000000000;
882+
883+
lib.seedPseudoRandom = function() {
884+
randSeed = 2000000000;
885+
};
886+
887+
lib.pseudoRandom = function() {
888+
var lastVal = randSeed;
889+
randSeed = (69069 * randSeed + 1) % 4294967296;
890+
// don't let consecutive vals be too close together
891+
// gets away from really trying to be random, in favor of better local uniformity
892+
if(Math.abs(randSeed - lastVal) < 429496729) return lib.pseudoRandom();
893+
return randSeed / 4294967296;
894+
};

src/traces/box/plot.js

+3-19
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,6 @@ var d3 = require('d3');
1313
var Lib = require('../../lib');
1414
var Drawing = require('../../components/drawing');
1515

16-
// repeatable pseudorandom generator
17-
var randSeed = 2000000000;
18-
19-
function seed() {
20-
randSeed = 2000000000;
21-
}
22-
23-
function rand() {
24-
var lastVal = randSeed;
25-
randSeed = (69069 * randSeed + 1) % 4294967296;
26-
// don't let consecutive vals be too close together
27-
// gets away from really trying to be random, in favor of better local uniformity
28-
if(Math.abs(randSeed - lastVal) < 429496729) return rand();
29-
return randSeed / 4294967296;
30-
}
31-
3216
// constants for dynamic jitter (ie less jitter for sparser points)
3317
var JITTERCOUNT = 5; // points either side of this to include
3418
var JITTERSPREAD = 0.01; // fraction of IQR to count as "dense"
@@ -179,8 +163,8 @@ function plotPoints(sel, axes, trace, t) {
179163
// to support violin points
180164
var mode = trace.boxpoints || trace.points;
181165

182-
// repeatable pseudorandom number generator
183-
seed();
166+
// repeatable pseudo-random number generator
167+
Lib.seedPseudoRandom();
184168

185169
sel.selectAll('g.points')
186170
// since box plot points get an extra level of nesting, each
@@ -247,7 +231,7 @@ function plotPoints(sel, axes, trace, t) {
247231
var v = pt.v;
248232

249233
var jitterOffset = trace.jitter ?
250-
(newJitter * jitterFactors[i] * (rand() - 0.5)) :
234+
(newJitter * jitterFactors[i] * (Lib.pseudoRandom() - 0.5)) :
251235
0;
252236

253237
var posPx = d.pos + bPos + bdPos * (trace.pointpos + jitterOffset);

src/traces/scattergl/index.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -779,9 +779,9 @@ function plot(container, subplot, cdata) {
779779
}
780780
// fill requires linked traces, so we generate it's positions here
781781
if(scene.fill2d) {
782-
scene.fillOptions.forEach(function(fillOptions, i) {
782+
scene.fillOptions = scene.fillOptions.map(function(fillOptions, i) {
783783
var cdscatter = cdata[i];
784-
if(!fillOptions || !cdscatter || !cdscatter[0] || !cdscatter[0].trace) return;
784+
if(!fillOptions || !cdscatter || !cdscatter[0] || !cdscatter[0].trace) return null;
785785
var cd = cdscatter[0];
786786
var trace = cd.trace;
787787
var stash = cd.t;
@@ -861,6 +861,8 @@ function plot(container, subplot, cdata) {
861861

862862
fillOptions.opacity = trace.opacity;
863863
fillOptions.positions = pos;
864+
865+
return fillOptions;
864866
});
865867

866868
scene.fill2d.update(scene.fillOptions);
@@ -945,7 +947,7 @@ function plot(container, subplot, cdata) {
945947
scene.select2d = createScatter(layout._glcanvas.data()[1].regl, {clone: scene.scatter2d});
946948
}
947949

948-
if(scene.scatter2d) {
950+
if(scene.scatter2d && scene.selectBatch && scene.selectBatch.length) {
949951
// update only traces with selection
950952
scene.scatter2d.update(scene.unselectedOptions.map(function(opts, i) {
951953
return scene.selectBatch[i] ? opts : null;
11.3 KB
Loading
Loading
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"data": [{
3+
"type": "scattergl",
4+
"mode": "lines",
5+
"x": [1, 2, 3],
6+
"y": [1, 2, 1]
7+
}],
8+
"layout": {
9+
"dragmode": "select",
10+
"showlegend": false,
11+
"width": 400,
12+
"height": 400
13+
}
14+
}

test/image/mocks/gl2d_scatter-color-clustering.json

+9
Large diffs are not rendered by default.

test/jasmine/tests/gl2d_plot_interact_test.js

+62-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ var selectButton = require('../assets/modebar_button');
1616
var delay = require('../assets/delay');
1717
var readPixel = require('../assets/read_pixel');
1818

19-
2019
function countCanvases() {
2120
return d3.selectAll('canvas').size();
2221
}
@@ -648,7 +647,6 @@ describe('@gl Test gl2d plots', function() {
648647
.then(done);
649648
});
650649

651-
652650
it('should not scroll document while panning', function(done) {
653651
var mock = {
654652
data: [
@@ -773,4 +771,66 @@ describe('@gl Test gl2d plots', function() {
773771
.catch(fail)
774772
.then(done);
775773
});
774+
775+
it('should remove fill2d', function(done) {
776+
var mock = require('@mocks/gl2d_axes_labels2.json');
777+
778+
Plotly.plot(gd, mock.data, mock.layout)
779+
.then(delay(1000))
780+
.then(function() {
781+
expect(readPixel(gd.querySelector('.gl-canvas-context'), 100, 80)[0]).not.toBe(0);
782+
783+
return Plotly.restyle(gd, {fill: 'none'});
784+
})
785+
.then(function() {
786+
expect(readPixel(gd.querySelector('.gl-canvas-context'), 100, 80)[0]).toBe(0);
787+
})
788+
.catch(fail)
789+
.then(done);
790+
});
791+
792+
it('should be able to draw more than 4096 colors', function(done) {
793+
var x = [];
794+
var color = [];
795+
var N = 1e5;
796+
var w = 500;
797+
var h = 500;
798+
799+
Lib.seedPseudoRandom();
800+
801+
for(var i = 0; i < N; i++) {
802+
x.push(i);
803+
color.push(Lib.pseudoRandom());
804+
}
805+
806+
Plotly.newPlot(gd, [{
807+
type: 'scattergl',
808+
mode: 'markers',
809+
x: x,
810+
y: color,
811+
marker: {
812+
color: color,
813+
colorscale: [
814+
[0, 'rgb(255, 0, 0)'],
815+
[0.5, 'rgb(0, 255, 0)'],
816+
[1.0, 'rgb(0, 0, 255)']
817+
]
818+
}
819+
}], {
820+
width: w,
821+
height: h,
822+
margin: {l: 0, t: 0, b: 0, r: 0}
823+
})
824+
.then(function() {
825+
var total = readPixel(gd.querySelector('.gl-canvas-context'), 0, 0, w, h)
826+
.reduce(function(acc, v) { return acc + v; }, 0);
827+
828+
// the total value was 3777134 before PR
829+
// https://github.com/plotly/plotly.js/pull/2377
830+
// and 105545275 after.
831+
expect(total).toBeGreaterThan(4e6);
832+
})
833+
.catch(fail)
834+
.then(done);
835+
});
776836
});

0 commit comments

Comments
 (0)