Skip to content

Commit 1aec7f7

Browse files
committed
clean up parcoords handling of uneven and missing arrays
Apparently I missed parcoords in the Plotly.react cleanup
1 parent cd6e823 commit 1aec7f7

File tree

6 files changed

+61
-40
lines changed

6 files changed

+61
-40
lines changed

src/lib/stats.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ var isNumeric = require('fast-isnumeric');
2828
exports.aggNums = function(f, v, a, len) {
2929
var i,
3030
b;
31-
if(!len) len = a.length;
31+
if(!len || len > a.length) len = a.length;
3232
if(!isNumeric(v)) v = false;
3333
if(Array.isArray(a[0])) {
3434
b = new Array(len);

src/traces/parcoords/attributes.js

-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ module.exports = {
9292
values: {
9393
valType: 'data_array',
9494
role: 'info',
95-
dflt: [],
9695
editType: 'calc',
9796
description: [
9897
'Dimension values. `values[n]` represents the value of the `n`th point in the dataset,',

src/traces/parcoords/calc.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,23 @@ var wrap = require('../../lib/gup').wrap;
1515

1616
module.exports = function calc(gd, trace) {
1717
var cs = !!trace.line.colorscale && Lib.isArray(trace.line.color);
18-
var color = cs ? trace.line.color : Array.apply(0, Array(trace.dimensions.reduce(function(p, n) {return Math.max(p, n.values.length);}, 0))).map(function() {return 0.5;});
18+
var color = cs ? trace.line.color : constHalf(trace._commonLength);
1919
var cscale = cs ? trace.line.colorscale : [[0, trace.line.color], [1, trace.line.color]];
2020

2121
if(hasColorscale(trace, 'line')) {
22-
calcColorscale(trace, trace.line.color, 'line', 'c');
22+
calcColorscale(trace, color, 'line', 'c');
2323
}
2424

2525
return wrap({
2626
lineColor: color,
2727
cscale: cscale
2828
});
2929
};
30+
31+
function constHalf(len) {
32+
var out = new Array(len);
33+
for(var i = 0; i < len; i++) {
34+
out[i] = 0.5;
35+
}
36+
return out;
37+
}

src/traces/parcoords/defaults.js

+29-20
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,20 @@ var handleDomainDefaults = require('../../plots/domain').defaults;
1717

1818
function handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce) {
1919

20-
coerce('line.color', defaultColor);
21-
22-
if(hasColorscale(traceIn, 'line') && Lib.isArray(traceIn.line.color)) {
23-
coerce('line.colorscale');
24-
colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'line.', cLetter: 'c'});
25-
}
26-
else {
27-
coerce('line.color', defaultColor);
20+
var lineColor = coerce('line.color', defaultColor);
21+
22+
if(hasColorscale(traceIn, 'line') && Lib.isArray(lineColor)) {
23+
if(lineColor.length) {
24+
coerce('line.colorscale');
25+
colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: 'line.', cLetter: 'c'});
26+
// TODO: I think it would be better to keep showing lines beyond the last line color
27+
// but I'm not sure what color to give these lines - probably black or white
28+
// depending on the background color?
29+
traceOut._commonLength = Math.min(traceOut._commonLength, lineColor.length);
30+
}
31+
else {
32+
traceOut.line.color = defaultColor;
33+
}
2834
}
2935
}
3036

@@ -53,7 +59,10 @@ function dimensionsDefaults(traceIn, traceOut) {
5359
}
5460

5561
var values = coerce('values');
56-
var visible = coerce('visible', values.length > 0);
62+
var visible = coerce('visible');
63+
if(!(values && values.length)) {
64+
visible = dimensionOut.visible = false;
65+
}
5766

5867
if(visible) {
5968
coerce('label');
@@ -63,21 +72,14 @@ function dimensionsDefaults(traceIn, traceOut) {
6372
coerce('range');
6473
coerce('constraintrange');
6574

66-
commonLength = Math.min(commonLength, dimensionOut.values.length);
75+
commonLength = Math.min(commonLength, values.length);
6776
}
6877

6978
dimensionOut._index = i;
7079
dimensionsOut.push(dimensionOut);
7180
}
7281

73-
if(isFinite(commonLength)) {
74-
for(i = 0; i < dimensionsOut.length; i++) {
75-
dimensionOut = dimensionsOut[i];
76-
if(dimensionOut.visible && dimensionOut.values.length > commonLength) {
77-
dimensionOut.values = dimensionOut.values.slice(0, commonLength);
78-
}
79-
}
80-
}
82+
traceOut._commonLength = commonLength;
8183

8284
return dimensionsOut;
8385
}
@@ -97,11 +99,18 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
9799
traceOut.visible = false;
98100
}
99101

100-
// make default font size 10px,
102+
// since we're not slicing uneven arrays anymore, stash the length in each dimension
103+
// but we can't do this in dimensionsDefaults (yet?) because line.color can also
104+
// truncate
105+
for(var i = 0; i < dimensions.length; i++) {
106+
if(dimensions[i].visible) dimensions[i]._length = traceOut._commonLength;
107+
}
108+
109+
// make default font size 10px (default is 12),
101110
// scale linearly with global font size
102111
var fontDflt = {
103112
family: layout.font.family,
104-
size: Math.round(layout.font.size * (10 / 12)),
113+
size: Math.round(layout.font.size / 1.2),
105114
color: layout.font.color
106115
};
107116

src/traces/parcoords/parcoords.js

+15-5
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ function visible(dimension) {return !('visible' in dimension) || dimension.visib
2121

2222
function dimensionExtent(dimension) {
2323

24-
var lo = dimension.range ? dimension.range[0] : d3.min(dimension.values);
25-
var hi = dimension.range ? dimension.range[1] : d3.max(dimension.values);
24+
var lo = dimension.range ? dimension.range[0] : Lib.aggNums(Math.min, null, dimension.values, dimension._length);
25+
var hi = dimension.range ? dimension.range[1] : Lib.aggNums(Math.max, null, dimension.values, dimension._length);
2626

2727
if(isNaN(lo) || !isFinite(lo)) {
2828
lo = 0;
@@ -139,7 +139,11 @@ function model(layout, d, i) {
139139
rangeFont = trace.rangefont;
140140

141141
var lines = Lib.extendDeep({}, line, {
142-
color: lineColor.map(domainToUnitScale({values: lineColor, range: [line.cmin, line.cmax]})),
142+
color: lineColor.map(domainToUnitScale({
143+
values: lineColor,
144+
range: [line.cmin, line.cmax],
145+
_length: trace._commonLength
146+
})),
143147
blockLineCount: c.blockLineCount,
144148
canvasOverdrag: c.overdrag * c.canvasPixelRatio
145149
});
@@ -201,6 +205,12 @@ function viewModel(model) {
201205
var foundKey = uniqueKeys[dimension.label];
202206
uniqueKeys[dimension.label] = (foundKey || 0) + 1;
203207
var key = dimension.label + (foundKey ? '__' + foundKey : '');
208+
209+
var truncatedValues = dimension.values;
210+
if(truncatedValues.length > dimension._length) {
211+
truncatedValues = truncatedValues.slice(0, dimension._length);
212+
}
213+
204214
return {
205215
key: key,
206216
label: dimension.label,
@@ -213,8 +223,8 @@ function viewModel(model) {
213223
crossfilterDimensionIndex: i,
214224
visibleIndex: dimension._index,
215225
height: height,
216-
values: dimension.values,
217-
paddedUnitValues: dimension.values.map(domainToUnit).map(paddedUnitScale),
226+
values: truncatedValues,
227+
paddedUnitValues: truncatedValues.map(domainToUnit).map(paddedUnitScale),
218228
xScale: xScale,
219229
x: xScale(i),
220230
canvasX: xScale(i) * canvasPixelRatio,

test/jasmine/tests/parcoords_test.js

+6-11
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ describe('parcoords initialization tests', function() {
118118
alienProperty: 'Alpha Centauri'
119119
}]
120120
});
121-
expect(fullTrace.dimensions).toEqual([{values: [1], visible: true, tickformat: '3s', _index: 0}]);
121+
expect(fullTrace.dimensions).toEqual([{values: [1], visible: true, tickformat: '3s', _index: 0, _length: 1}]);
122122
});
123123

124124
it('\'dimension.visible\' should be set to false, and other props just passed through if \'values\' is not provided', function() {
@@ -127,7 +127,7 @@ describe('parcoords initialization tests', function() {
127127
alienProperty: 'Alpha Centauri'
128128
}]
129129
});
130-
expect(fullTrace.dimensions).toEqual([{visible: false, values: [], _index: 0}]);
130+
expect(fullTrace.dimensions).toEqual([{visible: false, _index: 0}]);
131131
});
132132

133133
it('\'dimension.visible\' should be set to false, and other props just passed through if \'values\' is an empty array', function() {
@@ -147,22 +147,17 @@ describe('parcoords initialization tests', function() {
147147
alienProperty: 'Alpha Centauri'
148148
}]
149149
});
150-
expect(fullTrace.dimensions).toEqual([{visible: false, values: [], _index: 0}]);
150+
expect(fullTrace.dimensions).toEqual([{visible: false, _index: 0}]);
151151
});
152152

153-
it('\'dimension.values\' should get truncated to a common shortest length', function() {
153+
it('\'dimension.values\' should get truncated to a common shortest *nonzero* length', function() {
154154
var fullTrace = _supply({dimensions: [
155155
{values: [321, 534, 542, 674]},
156156
{values: [562, 124, 942]},
157157
{values: [], visible: true},
158-
{values: [1, 2], visible: false} // shouldn't be truncated to as false
158+
{values: [1, 2], visible: false} // shouldn't be truncated to as visible: false
159159
]});
160-
expect(fullTrace.dimensions).toEqual([
161-
{values: [], visible: true, tickformat: '3s', _index: 0},
162-
{values: [], visible: true, tickformat: '3s', _index: 1},
163-
{values: [], visible: true, tickformat: '3s', _index: 2},
164-
{values: [1, 2], visible: false, _index: 3}
165-
]);
160+
expect(fullTrace._commonLength).toBe(3);
166161
});
167162
});
168163

0 commit comments

Comments
 (0)