Skip to content

Commit 5aa52ce

Browse files
committed
Very rough carpet scatter trace
1 parent 4e4c093 commit 5aa52ce

File tree

6 files changed

+68
-91
lines changed

6 files changed

+68
-91
lines changed

src/plots/cartesian/index.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,11 @@ exports.plot = function(gd, traces, transitionOpts, makeOnCompleteCallback) {
6262
// Skip trace if whitelist provided and it's not whitelisted:
6363
// if (Array.isArray(traces) && traces.indexOf(i) === -1) continue;
6464
if(trace.xaxis + trace.yaxis === subplot) {
65+
// XXX: Should trace carpet dependencies. Only replot all carpet plots if the carpet
66+
// axis has actually changed:
67+
//
6568
// If this trace is specifically requested, add it to the list:
66-
if(traces.indexOf(trace.index) !== -1) {
69+
if(traces.indexOf(trace.index) !== -1 || trace.carpetid) {
6770
// Okay, so example: traces 0, 1, and 2 have fill = tonext. You animate
6871
// traces 0 and 2. Trace 1 also needs to be updated, otherwise its fill
6972
// is outdated. So this retroactively adds the previous trace if the

src/traces/carpet/set_convert.js

+18
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,24 @@ module.exports = function setConvert(trace) {
105105
return trace._evalxy([], i0, j0, ti, tj);
106106
};
107107

108+
trace.ab2xy = function (aval, bval) {
109+
if (aval < a[0] || aval > a[na - 1] | bval < b[0] || bval > b[nb - 1]) {
110+
return [false, false];
111+
}
112+
var i = trace.a2i(aval);
113+
var i0 = Math.max(0, Math.min(na - 2, Math.floor(i)));
114+
var ti = i - i0;
115+
116+
var j = trace.b2j(bval);
117+
var j0 = Math.max(0, Math.min(nb - 2, Math.floor(j)));
118+
var tj = j - j0;
119+
120+
if (tj < 0 || tj > 1 || ti < 0 || ti > 1) {
121+
return [false, false];
122+
}
123+
return trace._evalxy([], i0, j0, ti, tj);
124+
}
125+
108126
trace.c2p = function (xy, xa, ya) {
109127
return [xa.c2p(xy[0]), ya.c2p(xy[1])];
110128
};

src/traces/scattercarpet/attributes.js

+8-9
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,16 @@ var scatterMarkerAttrs = scatterAttrs.marker,
2020
scatterMarkerLineAttrs = scatterMarkerAttrs.line;
2121

2222
module.exports = {
23-
a: {
24-
valType: 'data_array',
23+
carpetid: {
24+
valType: 'string',
25+
role: 'info',
2526
description: [
26-
'Sets the quantity of component `a` in each data point.',
27-
'If `a`, `b`, and `c` are all provided, they need not be',
28-
'normalized, only the relative values matter. If only two',
29-
'arrays are provided they must be normalized to match',
30-
'`ternary<i>.sum`.'
27+
'An identifier for this carpet, so that `scattercarpet` and',
28+
'`scattercontour` traces can specify a carpet plot on which',
29+
'they lie'
3130
].join(' ')
3231
},
33-
b: {
32+
a: {
3433
valType: 'data_array',
3534
description: [
3635
'Sets the quantity of component `a` in each data point.',
@@ -40,7 +39,7 @@ module.exports = {
4039
'`ternary<i>.sum`.'
4140
].join(' ')
4241
},
43-
c: {
42+
b: {
4443
valType: 'data_array',
4544
description: [
4645
'Sets the quantity of component `a` in each data point.',

src/traces/scattercarpet/calc.js

+18-47
Original file line numberDiff line numberDiff line change
@@ -17,74 +17,45 @@ var Lib = require('../../lib');
1717
var subTypes = require('../scatter/subtypes');
1818
var calcColorscale = require('../scatter/colorscale_calc');
1919

20-
var dataArrays = ['a', 'b', 'c'];
21-
var arraysToFill = {a: ['b', 'c'], b: ['a', 'c'], c: ['a', 'b']};
22-
20+
var dataArrays = ['a', 'b'];
2321

2422
module.exports = function calc(gd, trace) {
25-
var i, j, dataArray, newArray, fillArray1, fillArray2, trace;
23+
var i, j, dataArray, newArray, fillArray1, fillArray2, carpet;
2624

27-
for (i = 0; i < gd.traces.length; i++) {
28-
if (gd.traces[i].carpetid === trace.carpetid) {
29-
trace = gd.traces[i];
25+
for (i = 0; i < gd._fullData.length; i++) {
26+
if (gd._fullData[i].carpetid === trace.carpetid && gd._fullData[i].type === 'carpet') {
27+
carpet = gd._fullData[i];
3028
break;
3129
}
3230
}
3331

34-
if (!trace) return;
35-
36-
console.log('trace:', trace);
32+
if (!carpet) return;
3733

38-
return;
34+
// Transfer this over from carpet before plotting since this is a necessary
35+
// condition in order for cartesian to actually plot this trace:
36+
trace.xaxis = carpet.xaxis;
37+
trace.yaxis = carpet.yaxis;
3938

40-
var ternary = gd._fullLayout[trace.subplot],
41-
displaySum = ternary.sum,
39+
var displaySum = carpet.sum,
4240
normSum = trace.sum || displaySum;
4341

44-
// fill in one missing component
45-
for(i = 0; i < dataArrays.length; i++) {
46-
dataArray = dataArrays[i];
47-
if(trace[dataArray]) continue;
48-
49-
fillArray1 = trace[arraysToFill[dataArray][0]];
50-
fillArray2 = trace[arraysToFill[dataArray][1]];
51-
newArray = new Array(fillArray1.length);
52-
for(j = 0; j < fillArray1.length; j++) {
53-
newArray[j] = normSum - fillArray1[j] - fillArray2[j];
54-
}
55-
trace[dataArray] = newArray;
56-
}
57-
5842
// make the calcdata array
5943
var serieslen = trace.a.length;
6044
var cd = new Array(serieslen);
61-
var a, b, c, norm, x, y;
45+
var a, b, norm, x, y;
6246
for(i = 0; i < serieslen; i++) {
6347
a = trace.a[i];
6448
b = trace.b[i];
65-
c = trace.c[i];
66-
if(isNumeric(a) && isNumeric(b) && isNumeric(c)) {
67-
a = +a;
68-
b = +b;
69-
c = +c;
70-
norm = displaySum / (a + b + c);
71-
if(norm !== 1) {
72-
a *= norm;
73-
b *= norm;
74-
c *= norm;
75-
}
76-
// map a, b, c onto x and y where the full scale of y
77-
// is [0, sum], and x is [-sum, sum]
78-
// TODO: this makes `a` always the top, `b` the bottom left,
79-
// and `c` the bottom right. Do we want options to rearrange
80-
// these?
81-
y = a;
82-
x = c - b;
83-
cd[i] = {x: x, y: y, a: a, b: b, c: c};
49+
if(isNumeric(a) && isNumeric(b)) {
50+
var xy = carpet.ab2xy(+a, +b);
51+
cd[i] = {x: xy[0], y: xy[1], a: a, b: b};
8452
}
8553
else cd[i] = {x: false, y: false};
8654
}
8755

56+
cd[0].carpet = carpet;
57+
cd[0].trace = trace;
58+
8859
// fill in some extras
8960
var marker, s;
9061
if(subTypes.hasMarkers(trace)) {

src/traces/scattercarpet/defaults.js

+8-20
Original file line numberDiff line numberDiff line change
@@ -27,28 +27,17 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
2727
return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);
2828
}
2929

30+
coerce('carpetid');
31+
32+
// XXX: Don't hard code this
33+
traceOut.xaxis = 'x';
34+
traceOut.yaxis = 'y';
35+
3036
var a = coerce('a'),
3137
b = coerce('b'),
32-
c = coerce('c'),
3338
len;
3439

35-
// allow any one array to be missing, len is the minimum length of those
36-
// present. Note that after coerce data_array's are either Arrays (which
37-
// are truthy even if empty) or undefined. As in scatter, an empty array
38-
// is different from undefined, because it can signify that this data is
39-
// not known yet but expected in the future
40-
if(a) {
41-
len = a.length;
42-
if(b) {
43-
len = Math.min(len, b.length);
44-
if(c) len = Math.min(len, c.length);
45-
}
46-
else if(c) len = Math.min(len, c.length);
47-
else len = 0;
48-
}
49-
else if(b && c) {
50-
len = Math.min(b.length, c.length);
51-
}
40+
len = Math.min(a.length, b.length);
5241

5342
if(!len) {
5443
traceOut.visible = false;
@@ -58,7 +47,6 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
5847
// cut all data arrays down to same length
5948
if(a && len < a.length) traceOut.a = a.slice(0, len);
6049
if(b && len < b.length) traceOut.b = b.slice(0, len);
61-
if(c && len < c.length) traceOut.c = c.slice(0, len);
6250

6351
coerce('sum');
6452

@@ -94,7 +82,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
9482
if(!subTypes.hasLines(traceOut)) handleLineShapeDefaults(traceIn, traceOut, coerce);
9583
}
9684

97-
coerce('hoverinfo', (layout._dataLength === 1) ? 'a+b+c+text' : undefined);
85+
coerce('hoverinfo', (layout._dataLength === 1) ? 'a+b+text' : undefined);
9886

9987
if(traceOut.fill === 'tonext' || traceOut.fill === 'toself') {
10088
dfltHoverOn.push('fills');

src/traces/scattercarpet/plot.js

+12-14
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,21 @@
1010
'use strict';
1111

1212
var scatterPlot = require('../scatter/plot');
13+
var Axes = require('../../plots/cartesian/axes');
1314

15+
module.exports = function plot(gd, plotinfoproxy, data) {
1416

15-
module.exports = function plot(ternary, data) {
16-
var plotContainer = ternary.plotContainer;
17-
18-
// remove all nodes inside the scatter layer
19-
plotContainer.select('.scatterlayer').selectAll('*').remove();
17+
var carpet = data[0][0].carpet;
2018

2119
// mimic cartesian plotinfo
2220
var plotinfo = {
23-
xaxis: ternary.xaxis,
24-
yaxis: ternary.yaxis,
25-
plot: plotContainer
21+
xaxis: Axes.getFromId(gd, carpet.xaxis || 'x'),
22+
yaxis: Axes.getFromId(gd, carpet.yaxis || 'y'),
23+
plot: plotinfoproxy.plot
2624
};
2725

28-
var calcdata = new Array(data.length),
29-
fullCalcdata = ternary.graphDiv.calcdata;
26+
/*var calcdata = new Array(data.length),
27+
fullCalcdata = gd.calcdata;
3028
3129
for(var i = 0; i < fullCalcdata.length; i++) {
3230
var j = data.indexOf(fullCalcdata[i][0].trace);
@@ -35,10 +33,10 @@ module.exports = function plot(ternary, data) {
3533
3634
calcdata[j] = fullCalcdata[i];
3735
38-
// while we're here and have references to both the Ternary object
36+
// while we're here and have references to both the Carpet object
3937
// and fullData, connect the two (for use by hover)
40-
data[j]._ternary = ternary;
41-
}
38+
data[j]._carpet = plotinfo;
39+
}*/
4240

43-
scatterPlot(ternary.graphDiv, plotinfo, calcdata);
41+
scatterPlot(plotinfo.graphDiv, plotinfo, data);
4442
};

0 commit comments

Comments
 (0)