8000 Carpet clip path · rpaskowitz/plotly.js@56f9662 · GitHub
[go: up one dir, main page]

Skip to content

Commit 56f9662

Browse files
committed
Carpet clip path
1 parent 656a8db commit 56f9662

File tree

6 files changed

+105
-14
lines changed

6 files changed

+105
-14
lines changed

src/traces/carpet/axis_attributes.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ module.exports = {
2424
].join(' ')
2525
},
2626
smoothing: {
27-
valType: 'boolean',
28-
dflt: true,
27+
valType: 'number',
28+
dflt: 1,
29+
min: 0,
30+
max: 1,
2931
role: 'info'
3032
},
3133
title: {

src/traces/carpet/axis_defaults.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, options)
7676
}
7777

7878
coerce('smoothing');
79-
containerOut.smoothing = containerOut.smoothing ? 1 : 0;
8079
coerce('cheatertype');
8180

8281
coerce('showticklabels');

src/traces/carpet/calc.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ var map2dArray = require('./map_2d_array');
1515
var setConvert = require('./set_convert');
1616
var calcGridlines = require('./calc_gridlines');
1717
var calcLabels = require('./calc_labels');
18+
var calcClipPath = require('./calc_clippath');
1819
var clean2dArray = require('../heatmap/clean_2d_array');
1920
var smoothFill2dArray = require('./smooth_fill_2d_array');
2021

@@ -65,31 +66,34 @@ module.exports = function calc(gd, trace) {
6566
var dy = 0.5 * (yrange[1] - yrange[0]);
6667
var yc = 0.5 * (yrange[1] + yrange[0]);
6768

69+
// Expand the axes to fit the plot, except just grow it by a factor of 1.3
70+
// because the labels should be taken into account except that's difficult
71+
// hence 1.3.
6872
var grow = 1.3;
6973
xrange = [xc - dx * grow, xc + dx * grow];
7074
yrange = [yc - dy * grow, yc + dy * grow];
7175

7276
Axes.expand(xa, xrange, {padded: true});
7377
Axes.expand(ya, yrange, {padded: true});
7478

79+
// Enumerate the gridlines, both major and minor, and store them on the trace
80+
// object:
7581
calcGridlines(trace, 'a', 'b');
7682
calcGridlines(trace, 'b', 'a');
7783

84+
// Calculate the text labels for each major gridline and store them on the
85+
// trace object:
7886
calcLabels(trace, aax);
7987
calcLabels(trace, bax);
8088

89+
// Tabulate points for the four segments that bound the axes so that we can
90+
// map to pixel coordinates in the plot function and create a clip rect:
91+
trace._clipsegments = calcClipPath(trace._xctrl, trace._yctrl, aax, bax);
92+
8193
return [{
8294
x: x,
8395
y: y,
8496
a: a,
8597
b: b
8698
}];
8799
};
88-
89-
/*
90-
* Given a data range from starting at x1, this function computes the first
91-
* point distributed along x0 + n * dx that lies within the range.
92-
*/
93-
/* function getLinspaceStartingPoint(xlow, x0, dx) {
94-
return x0 + dx * Math.ceil((xlow - x0) / dx);
95-
}*/

src/traces/carpet/calc_clippath.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Copyright 2012-2016, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
module.exports = function makeClipPath(xctrl, yctrl, aax, bax) {
13+
var i, xc, yc, x, y;
14+
var segments = [];
15+
16+
var asmoothing = !!aax.smoothing;
17+
var bsmoothing = !!bax.smoothing;
18+
var nea1 = xctrl.length - 1;
19+
var neb1 = xctrl[0].length - 1;
20+
21+
// Along the lower a axis:
22+
for(i = 0, x = [], y = []; i <= nea1; i++) {
23+
x[i] = xctrl[i][0];
24+
y[i] = yctrl[i][0];
25+
}
26+
segments.push({x: x, y: y, bicubic: asmoothing});
27+
28+
// Along the upper b axis:
29+
xc = xctrl[nea1];
30+
yc = yctrl[nea1];
31+
for(i = 0, x = [], y = []; i <= neb1; i++) {
32+
x[i] = xc[i];
33+
y[i] = yc[i];
34+
}
35+
segments.push({x: x, y: y, bicubic: bsmoothing});
36+
37+
// Backwards along the upper a axis:
38+
for(i = nea1, x = [], y = []; i >= 0; i--) {
39+
x[nea1 - i] = xctrl[i][neb1];
40+
y[nea1 - i] = yctrl[i][neb1];
41+
}
42+
segments.push({x: x, y: y, bicubic: asmoothing});
43+
44+
// Backwards along the lower b axis:
45+
xc = xctrl[0];
46+
yc = yctrl[0];
47+
for(i = neb1, x = [], y = []; i >= 0; i--) {
48+
x[neb1 - i] = xc[i];
49+
y[neb1 - i] = yc[i];
50+
}
51+
segments.push({x: x, y: y, bicubic: bsmoothing});
52+
53+
return segments;
54+
};

src/traces/carpet/makepath.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ module.exports = function makePath(xp, yp, isBicubic) {
2525
].join(' '));
2626
}
2727
}
28-
return 'M' + path.join(isBicubic ? '' : 'L');
28+
return path.join(isBicubic ? '' : 'L');
2929
};

src/traces/carpet/plot.js

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ function plotOne(gd, plotinfo, cd) {
3232
xa = plotinfo.xaxis,
3333
ya = plotinfo.yaxis,
3434
aax = trace.aaxis,
35-
bax = trace.baxis;
35+
bax = trace.baxis,
36+
fullLayout = gd._fullLayout;
3637
// uid = trace.uid,
3738
// id = 'carpet' + uid;
3839

@@ -43,6 +44,7 @@ function plotOne(gd, plotinfo, cd) {
4344

4445
// XXX: Layer choice??
4546
var gridLayer = plotinfo.plot.selectAll('.maplayer');
47+
var clipLayer = makeg(fullLayout._defs, 'g', 'clips');
4648

4749
var minorLayer = makeg(gridLayer, 'g', 'minorlayer');
4850
var majorLayer = makeg(gridLayer, 'g', 'majorlayer');
@@ -61,6 +63,36 @@ function plotOne(gd, plotinfo, cd) {
6163

6264
drawAxisLabels(xa, ya, trace, labelLayer, aax._labels, 'a-label');
6365
drawAxisLabels(xa, ya, trace, labelLayer, bax._labels, 'b-label');
66+
67+
// Swap for debugging in order to draw directly:
68+
// drawClipPath(trace, gridLayer, xa, ya);
69+
drawClipPath(trace, clipLayer, xa, ya);
70+
}
71+
72+
function drawClipPath(trace, layer, xaxis, yaxis) {
73+
var seg, xp, yp, i;
74+
// var clip = makeg(layer, 'g', 'carpetclip');
75+
var clip = makeg(layer, 'clipPath', 'carpetclip');
76+
var path = makeg(clip, 'path', 'carpetboundary');
77+
var segments = trace._clipsegments;
78+
var segs = [];
79+
80+
for(i = 0; i < segments.length; i++) {
81+
seg = segments[i];
82+
xp = map1dArray([], seg.x, xaxis.c2p);
83+
yp = map1dArray([], seg.y, yaxis.c2p);
84+
segs.push(makepath(xp, yp, seg.bicubic));
85+
}
86+
87+
// This could be optimized ever so slightly to avoid no-op L segments
88+
// at the corners, but it's so negligible that I don't think it's worth
89+
// the extra complexity
90+
path.attr('id', 'clip' + trace.uid + 'carpet')
91+
.attr('d', 'M' + segs.join('L') + 'Z');
92+
// .style('vector-effect', 'non-scaling-stroke')
93+
// .style('stroke-width', 2)
94+
// .style('stroke', 'black')
95+
// .style('fill', 'rgba(0, 0, 0, 0.1)');
6496
}
6597

6698
function drawGridLines(xaxis, yaxis, layer, axis, axisLetter, gridlines) {
@@ -79,7 +111,7 @@ function drawGridLines(xaxis, yaxis, layer, axis, axisLetter, gridlines) {
79111
var xp = map1dArray([], x, xaxis.c2p);
80112
var yp = map1dArray([], y, yaxis.c2p);
81113

82-
var path = makepath(xp, yp, gridline.smoothing);
114+
var path = 'M' + makepath(xp, yp, gridline.smoothing);
83115

84116
var el = d3.select(this);
85117

0 commit comments

Comments
 (0)
0