Skip to content

Commit 6630336

Browse files
authored
Merge pull request #5500 from plotly/scattergl_glpixelratio
Improve rendering of scattergl, splom and parcoords by implementing plotGlPixelRatio for those traces
2 parents 5c50174 + 89e2437 commit 6630336

File tree

131 files changed

+213
-112
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+213
-112
lines changed

draftlogs/5500_fix.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Improve rendering of scattergl, splom and parcoords by implementing plotGlPixelRatio for those traces [[#5500](https://github.com/plotly/plotly.js/pull/5500)]

src/plot_api/plot_api.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -222,17 +222,20 @@ function _doPlot(gd, data, layout, config) {
222222
});
223223
}
224224

225+
var plotGlPixelRatio = gd._context.plotGlPixelRatio;
225226
if(fullLayout._glcanvas) {
226227
fullLayout._glcanvas
227-
.attr('width', fullLayout.width)
228-
.attr('height', fullLayout.height);
228+
.attr('width', fullLayout.width * plotGlPixelRatio)
229+
.attr('height', fullLayout.height * plotGlPixelRatio)
230+
.style('width', fullLayout.width + 'px')
231+
.style('height', fullLayout.height + 'px');
229232

230233
var regl = fullLayout._glcanvas.data()[0].regl;
231234
if(regl) {
232235
// Unfortunately, this can happen when relayouting to large
233236
// width/height on some browsers.
234-
if(Math.floor(fullLayout.width) !== regl._gl.drawingBufferWidth ||
235-
Math.floor(fullLayout.height) !== regl._gl.drawingBufferHeight
237+
if(Math.floor(fullLayout.width * plotGlPixelRatio) !== regl._gl.drawingBufferWidth ||
238+
Math.floor(fullLayout.height * plotGlPixelRatio) !== regl._gl.drawingBufferHeight
236239
) {
237240
var msg = 'WebGL context buffer and canvas dimensions do not match due to browser/WebGL bug.';
238241
if(drawFrameworkCalls) {

src/plots/cartesian/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -596,8 +596,8 @@ exports.toSVG = function(gd) {
596596
preserveAspectRatio: 'none',
597597
x: 0,
598598
y: 0,
599-
width: canvas.width,
600-
height: canvas.height
599+
width: canvas.style.width,
600+
height: canvas.style.height
601601
});
602602
}
603603

src/traces/parcoords/base_plot.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ exports.toSVG = function(gd) {
3939
preserveAspectRatio: 'none',
4040
x: 0,
4141
y: 0,
42-
width: canvas.width,
43-
height: canvas.height
42+
width: canvas.style.width,
43+
height: canvas.style.height
4444
});
4545
}
4646

src/traces/parcoords/lines.js

+33-11
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,27 @@ function emptyAttributes(regl) {
160160
return attributes;
161161
}
162162

163-
function makeItem(model, leftmost, rightmost, itemNumber, i0, i1, x, y, panelSizeX, panelSizeY, crossfilterDimensionIndex, drwLayer, constraints) {
163+
function makeItem(
164+
model, leftmost, rightmost, itemNumber, i0, i1, x, y, panelSizeX, panelSizeY,
165+
crossfilterDimensionIndex, drwLayer, constraints, plotGlPixelRatio
166+
) {
164167
var dims = [[], []];
165168
for(var k = 0; k < 64; k++) {
166169
dims[0][k] = (k === i0) ? 1 : 0;
167170
dims[1][k] = (k === i1) ? 1 : 0;
168171
}
169-
170-
var overdrag = model.lines.canvasOverdrag;
172+
x *= plotGlPixelRatio;
173+
y *= plotGlPixelRatio;
174+
panelSizeX *= plotGlPixelRatio;
175+
panelSizeY *= plotGlPixelRatio;
176+
var overdrag = model.lines.canvasOverdrag * plotGlPixelRatio;
171177
var domain = model.domain;
172-
var canvasWidth = model.canvasWidth;
173-
var canvasHeight = model.canvasHeight;
178+
var canvasWidth = model.canvasWidth * plotGlPixelRatio;
179+
var canvasHeight = model.canvasHeight * plotGlPixelRatio;
180+
var padL = model.pad.l * plotGlPixelRatio;
181+
var padB = model.pad.b * plotGlPixelRatio;
182+
var layoutHeight = model.layoutHeight * plotGlPixelRatio;
183+
var layoutWidth = model.layoutWidth * plotGlPixelRatio;
174184

175185
var deselectedLinesColor = model.deselectedLines.color;
176186

@@ -201,13 +211,13 @@ function makeItem(model, leftmost, rightmost, itemNumber, i0, i1, x, y, panelSiz
201211
Math.max(1 / 255, Math.pow(1 / model.lines.color.length, 1 / 3))
202212
],
203213

204-
scissorX: (itemNumber === leftmost ? 0 : x + overdrag) + (model.pad.l - overdrag) + model.layoutWidth * domain.x[0],
214+
scissorX: (itemNumber === leftmost ? 0 : x + overdrag) + (padL - overdrag) + layoutWidth * domain.x[0],
205215
scissorWidth: (itemNumber === rightmost ? canvasWidth - x + overdrag : panelSizeX + 0.5) + (itemNumber === leftmost ? x + overdrag : 0),
206-
scissorY: y + model.pad.b + model.layoutHeight * domain.y[0],
216+
scissorY: y + padB + layoutHeight * domain.y[0],
207217
scissorHeight: panelSizeY,
208218

209-
viewportX: model.pad.l - overdrag + model.layoutWidth * domain.x[0],
210-
viewportY: model.pad.b + model.layoutHeight * domain.y[0],
219+
viewportX: padL - overdrag + layoutWidth * domain.x[0],
220+
viewportY: padB + layoutHeight * domain.y[0],
211221
viewportWidth: canvasWidth,
212222
viewportHeight: canvasHeight
213223
}, constraints);
@@ -231,6 +241,16 @@ module.exports = function(canvasGL, d) {
231241
var isPick = d.pick;
232242

233243
var regl = d.regl;
244+
var gl = regl._gl;
245+
var supportedLineWidth = gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE);
246+
// ensure here that plotGlPixelRatio is within supported range; otherwise regl throws error
247+
var plotGlPixelRatio = Math.max(
248+
supportedLineWidth[0],
249+
Math.min(
250+
supportedLineWidth[1],
251+
d.viewModel.plotGlPixelRatio
252+
)
253+
);
234254

235255
var renderState = {
236256
currentRafs: {},
@@ -307,7 +327,7 @@ module.exports = function(canvasGL, d) {
307327
frag: fragmentShaderSource,
308328

309329
primitive: 'lines',
310-
lineWidth: 1,
330+
lineWidth: plotGlPixelRatio,
311331
attributes: attributes,
312332
uniforms: {
313333
resolution: regl.prop('resolution'),
@@ -454,6 +474,7 @@ module.exports = function(canvasGL, d) {
454474
var x = p.canvasX;
455475
var y = p.canvasY;
456476
var nextX = x + p.panelSizeX;
477+
var plotGlPixelRatio = p.plotGlPixelRatio;
457478
if(setChanged ||
458479
!prevAxisOrder[i0] ||
459480
prevAxisOrder[i0][0] !== x ||
@@ -467,7 +488,8 @@ module.exports = function(canvasGL, d) {
467488
p.panelSizeX, p.panelSizeY,
468489
p.dim0.crossfilterDimensionIndex,
469490
isContext ? 0 : isPick ? 2 : 1,
470-
constraints
491+
constraints,
492+
plotGlPixelRatio
471493
);
472494

473495
renderState.clearOnly = clearOnly;

src/traces/parcoords/parcoords.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ function calcTilt(angle, position) {
369369
};
370370
}
371371

372-
function updatePanelLayout(yAxis, vm) {
372+
function updatePanelLayout(yAxis, vm, plotGlPixelRatio) {
373373
var panels = vm.panels || (vm.panels = []);
374374
var data = yAxis.data();
375375
for(var i = 0; i < data.length - 1; i++) {
@@ -383,6 +383,7 @@ function updatePanelLayout(yAxis, vm) {
383383
p.panelSizeY = vm.model.canvasHeight;
384384
p.y = 0;
385385
p.canvasY = 0;
386+
p.plotGlPixelRatio = plotGlPixelRatio;
386387
}
387388
}
388389

@@ -433,6 +434,7 @@ module.exports = function parcoords(gd, cdModule, layout, callbacks) {
433434
var fullLayout = gd._fullLayout;
434435
var svg = fullLayout._toppaper;
435436
var glContainer = fullLayout._glcontainer;
437+
var plotGlPixelRatio = gd._context.plotGlPixelRatio;
436438
var paperColor = gd._fullLayout.paper_bgcolor;
437439

438440
calcAllTicks(cdModule);
@@ -452,6 +454,7 @@ module.exports = function parcoords(gd, cdModule, layout, callbacks) {
452454
.each(function(d) {
453455
// FIXME: figure out how to handle multiple instances
454456
d.viewModel = vm[0];
457+
d.viewModel.plotGlPixelRatio = plotGlPixelRatio;
455458
d.viewModel.paperColor = paperColor;
456459
d.model = d.viewModel ? d.viewModel.model : null;
457460
});
@@ -536,7 +539,7 @@ module.exports = function parcoords(gd, cdModule, layout, callbacks) {
536539
.classed(c.cn.yAxis, true);
537540

538541
parcoordsControlView.each(function(p) {
539-
updatePanelLayout(yAxis, p);
542+
updatePanelLayout(yAxis, p, plotGlPixelRatio);
540543
});
541544

542545
glLayers
@@ -575,7 +578,7 @@ module.exports = function parcoords(gd, cdModule, layout, callbacks) {
575578
e.canvasX = e.x * e.model.canvasPixelRatio;
576579
});
577580

578-
updatePanelLayout(yAxis, p);
581+
updatePanelLayout(yAxis, p, plotGlPixelRatio);
579582

580583
yAxis.filter(function(e) { return Math.abs(d.xIndex - e.xIndex) !== 0; })
581584
.attr('transform', function(d) { return strTranslate(d.xScale(d.xIndex), 0); });
@@ -588,7 +591,7 @@ module.exports = function parcoords(gd, cdModule, layout, callbacks) {
588591
var p = d.parent;
589592
d.x = d.xScale(d.xIndex);
590593
d.canvasX = d.x * d.model.canvasPixelRatio;
591-
updatePanelLayout(yAxis, p);
594+
updatePanelLayout(yAxis, p, plotGlPixelRatio);
592595
d3.select(this)
593596
.attr('transform', function(d) { return strTranslate(d.x, 0); });
594597
p.contextLayer && p.contextLayer.render(p.panels, false, !someFiltersActive(p));

src/traces/scatter/make_bubble_size_func.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ var isNumeric = require('fast-isnumeric');
55

66
// used in the drawing step for 'scatter' and 'scattegeo' and
77
// in the convert step for 'scatter3d'
8-
module.exports = function makeBubbleSizeFn(trace) {
8+
module.exports = function makeBubbleSizeFn(trace, factor) {
9+
if(!factor) {
10+
factor = 2;
11+
}
912
var marker = trace.marker;
1013
var sizeRef = marker.sizeref || 1;
1114
var sizeMin = marker.sizemin || 0;
@@ -21,7 +24,7 @@ module.exports = function makeBubbleSizeFn(trace) {
2124
// TODO add support for position/negative bubbles?
2225
// TODO add 'sizeoffset' attribute?
2326
return function(v) {
24-
var baseSize = baseFn(v / 2);
27+
var baseSize = baseFn(v / factor);
2528

2629
// don't show non-numeric and negative sizes
2730
return (isNumeric(baseSize) && (baseSize > 0)) ?

src/traces/scattergl/calc.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ module.exports = function calc(gd, trace) {
8383
if(!hasTooManyPoints) {
8484
ppad = calcMarkerSize(trace, len);
8585
} else if(opts.marker) {
86-
ppad = 2 * (opts.marker.sizeAvg || Math.max(opts.marker.size, 3));
86+
ppad = opts.marker.sizeAvg || Math.max(opts.marker.size, 3);
8787
}
8888
calcAxisExpansion(gd, trace, xa, ya, x, y, ppad);
8989
if(opts.errorX) expandForErrorBars(trace, xa, opts.errorX);

src/traces/scattergl/convert.js

+17-13
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ function convertStyle(gd, trace) {
3939
textUnsel: undefined
4040
};
4141

42+
var plotGlPixelRatio = gd._context.plotGlPixelRatio;
43+
4244
if(trace.visible !== true) return opts;
4345

4446
if(subTypes.hasText(trace)) {
@@ -64,24 +66,24 @@ function convertStyle(gd, trace) {
6466
if(subTypes.hasLines(trace)) {
6567
opts.line = {
6668
overlay: true,
67-
thickness: trace.line.width,
69+
thickness: trace.line.width * plotGlPixelRatio,
6870
color: trace.line.color,
6971
opacity: trace.opacity
7072
};
7173

7274
var dashes = (constants.DASHES[trace.line.dash] || [1]).slice();
7375
for(i = 0; i < dashes.length; ++i) {
74-
dashes[i] *= trace.line.width;
76+
dashes[i] *= trace.line.width * plotGlPixelRatio;
7577
}
7678
opts.line.dashes = dashes;
7779
}
7880

7981
if(trace.error_x && trace.error_x.visible) {
80-
opts.errorX = convertErrorBarStyle(trace, trace.error_x);
82+
opts.errorX = convertErrorBarStyle(trace, trace.error_x, plotGlPixelRatio);
8183
}
8284

8385
if(trace.error_y && trace.error_y.visible) {
84-
opts.errorY = convertErrorBarStyle(trace, trace.error_y);
86+
opts.errorY = convertErrorBarStyle(trace, trace.error_y, plotGlPixelRatio);
8587
}
8688

8789
if(!!trace.fill && trace.fill !== 'none') {
@@ -106,6 +108,7 @@ function convertTextStyle(gd, trace) {
106108
var tff = textfontIn.family;
107109
var optsOut = {};
108110
var i;
111+
var plotGlPixelRatio = gd._context.plotGlPixelRatio;
109112

110113
var texttemplate = trace.texttemplate;
111114
if(texttemplate) {
@@ -191,13 +194,13 @@ function convertTextStyle(gd, trace) {
191194
Array.isArray(tfs) ? (
192195
isNumeric(tfs[i]) ? tfs[i] : 0
193196
) : tfs
194-
);
197+
) * plotGlPixelRatio;
195198

196199
fonti.family = Array.isArray(tff) ? tff[i] : tff;
197200
}
198201
} else {
199202
// if both are single values, make render fast single-value
200-
optsOut.font = {size: tfs, family: tff};
203+
optsOut.font = {size: tfs * plotGlPixelRatio, family: tff};
201204
}
202205

203206
return optsOut;
@@ -283,7 +286,8 @@ function convertMarkerStyle(trace) {
283286
}
284287

285288
// prepare sizes
286-
var markerSizeFunc = makeBubbleSizeFn(trace);
289+
var sizeFactor = 1;
290+
var markerSizeFunc = makeBubbleSizeFn(trace, sizeFactor);
287291
var s;
288292

289293
if(multiSize || multiLineWidth) {
@@ -308,10 +312,10 @@ function convertMarkerStyle(trace) {
308312
// See https://github.com/plotly/plotly.js/pull/1781#discussion_r121820798
309313
if(multiLineWidth) {
310314
for(i = 0; i < count; i++) {
311-
borderSizes[i] = optsIn.line.width[i] / 2;
315+
borderSizes[i] = optsIn.line.width[i];
312316
}
313317
} else {
314-
s = optsIn.line.width / 2;
318+
s = optsIn.line.width;
315319
for(i = 0; i < count; i++) {
316320
borderSizes[i] = s;
317321
}
@@ -335,7 +339,7 @@ function convertMarkerSelection(trace, target) {
335339
if(target.marker && target.marker.symbol) {
336340
optsOut = convertMarkerStyle(Lib.extendFlat({}, optsIn, target.marker));
337341
} else if(target.marker) {
338-
if(target.marker.size) optsOut.size = target.marker.size / 2;
342+
if(target.marker.size) optsOut.size = target.marker.size;
339343
if(target.marker.color) optsOut.colors = target.marker.color;
340344
if(target.marker.opacity !== undefined) optsOut.opacity = target.marker.opacity;
341345
}
@@ -365,10 +369,10 @@ function convertTextSelection(gd, trace, target) {
365369
return optsOut;
366370
}
367371

368-
function convertErrorBarStyle(trace, target) {
372+
function convertErrorBarStyle(trace, target, plotGlPixelRatio) {
369373
var optsOut = {
370-
capSize: target.width * 2,
371-
lineWidth: target.thickness,
374+
capSize: target.width * 2 * plotGlPixelRatio,
375+
lineWidth: target.thickness * plotGlPixelRatio,
372376
color: target.color
373377
};
374378

src/traces/scattergl/plot.js

+17-9
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,23 @@ var linkTraces = require('../scatter/link_traces');
1414

1515
var styleTextSelection = require('./edit_style').styleTextSelection;
1616

17-
function getViewport(fullLayout, xaxis, yaxis) {
17+
18+
function getViewport(fullLayout, xaxis, yaxis, plotGlPixelRatio) {
1819
var gs = fullLayout._size;
19-
var width = fullLayout.width;
20-
var height = fullLayout.height;
20+
var width = fullLayout.width * plotGlPixelRatio;
21+
var height = fullLayout.height * plotGlPixelRatio;
22+
23+
var l = gs.l * plotGlPixelRatio;
24+
var b = gs.b * plotGlPixelRatio;
25+
var r = gs.r * plotGlPixelRatio;
26+
var t = gs.t * plotGlPixelRatio;
27+
var w = gs.w * plotGlPixelRatio;
28+
var h = gs.h * plotGlPixelRatio;
2129
return [
22-
gs.l + xaxis.domain[0] * gs.w,
23-
gs.b + yaxis.domain[0] * gs.h,
24-
(width - gs.r) - (1 - xaxis.domain[1]) * gs.w,
25-
(height - gs.t) - (1 - yaxis.domain[1]) * gs.h
30+
l + xaxis.domain[0] * w,
31+
b + yaxis.domain[0] * h,
32+
(width - r) - (1 - xaxis.domain[1]) * w,
33+
(height - t) - (1 - yaxis.domain[1]) * h
2634
];
2735
}
2836

@@ -59,7 +67,7 @@ module.exports = function plot(gd, subplot, cdata) {
5967
scene.line2d = createLine(regl);
6068
}
6169
if(scene.scatter2d === true) {
62-
scene.scatter2d = createScatter(regl, { constPointSize: true });
70+
scene.scatter2d = createScatter(regl);
6371
}
6472
if(scene.fill2d === true) {
6573
scene.fill2d = createLine(regl);
@@ -330,7 +338,7 @@ module.exports = function plot(gd, subplot, cdata) {
330338

331339
// provide viewport and range
332340
var vpRange0 = {
333-
viewport: getViewport(fullLayout, xaxis, yaxis),
341+
viewport: getViewport(fullLayout, xaxis, yaxis, gd._context.plotGlPixelRatio),
334342
// TODO do we need those fallbacks?
335343
range: [
336344
(xaxis._rl || xaxis.range)[0],

0 commit comments

Comments
 (0)