Skip to content

Commit daac59d

Browse files
committed
Enhance keyedContainer to accept nested props
1 parent efcef43 commit daac59d

File tree

4 files changed

+85
-37
lines changed

4 files changed

+85
-37
lines changed

src/components/legend/draw.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,7 @@ function drawTexts(g, gd) {
414414
var groupbyIndices = Registry.getTransformIndices(fullInput, 'groupby');
415415
var index = groupbyIndices[groupbyIndices.length - 1];
416416

417-
var carr = Lib.keyedContainer(fullInput, 'transforms[' + index + '].groupnames', 'group', 'name');
417+
var carr = Lib.keyedContainer(fullInput, 'transforms[' + index + '].styles', 'group', 'value.name');
418418

419419
if(BLANK_STRING_REGEX.test(origText)) {
420420
carr.remove(legendItem.trace._group);

src/lib/keyed_container.js

+25-5
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010

1111
var nestedProperty = require('./nested_property');
1212

13+
var SIMPLE_PROPERTY_REGEX = /^\w*$/;
14+
1315
// bitmask for deciding what's updated:
1416
var NONE = 0;
1517
var NAME = 1;
1618
var VALUE = 2;
1719
var BOTH = 3;
1820

1921
module.exports = function keyedContainer(baseObj, path, keyName, valueName) {
20-
2122
keyName = keyName || 'name';
2223
valueName = valueName || 'value';
2324
var i, arr;
@@ -37,6 +38,8 @@ module.exports = function keyedContainer(baseObj, path, keyName, valueName) {
3738
indexLookup[arr[i][keyName]] = i;
3839
}
3940

41+
var isSimpleValueProp = SIMPLE_PROPERTY_REGEX.test(valueName);
42+
4043
var obj = {
4144
// NB: this does not actually modify the baseObj
4245
set: function(name, value) {
@@ -46,12 +49,18 @@ module.exports = function keyedContainer(baseObj, path, keyName, valueName) {
4649
changeType = BOTH;
4750
idx = arr.length;
4851
indexLookup[name] = idx;
49-
} else if(value !== arr[idx][valueName]) {
52+
} else if(value !== (isSimpleValueProp ? arr[idx][valueName] : nestedProperty(arr[idx], valueName).get())) {
5053
changeType = VALUE;
5154
}
5255
var newValue = {};
5356
newValue[keyName] = name;
54-
newValue[valueName] = value;
57+
58+
if(isSimpleValueProp) {
59+
newValue[valueName] = value;
60+
} else {
61+
nestedProperty(newValue, valueName).set(value);
62+
}
63+
5564
arr[idx] = newValue;
5665

5766
changeTypes[idx] = changeTypes[idx] | changeType;
@@ -60,7 +69,14 @@ module.exports = function keyedContainer(baseObj, path, keyName, valueName) {
6069
},
6170
get: function(name) {
6271
var idx = indexLookup[name];
63-
return idx === undefined ? undefined : arr[idx][valueName];
72+
73+
if(idx === undefined) {
74+
return undefined;
75+
} else if(isSimpleValueProp) {
76+
return arr[idx][valueName];
77+
} else {
78+
return nestedProperty(arr[idx], valueName).get();
79+
}
6480
},
6581
rename: function(name, newName) {
6682
var idx = indexLookup[name];
@@ -101,7 +117,11 @@ module.exports = function keyedContainer(baseObj, path, keyName, valueName) {
101117
update[astr + '.' + keyName] = arr[idx][keyName];
102118
}
103119
if(changeTypes[idx] & VALUE) {
104-
update[astr + '.' + valueName] = arr[idx][valueName];
120+
if(isSimpleValueProp) {
121+
update[astr + '.' + valueName] = arr[idx][valueName];
122+
} else {
123+
update[astr + '.' + valueName] = nestedProperty(arr[idx], valueName).get();
124+
}
105125
}
106126
} else {
107127
update[astr] = null;

src/transforms/groupby.js

+2-31
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,6 @@ exports.attributes = {
4646
'default "%{group} (%{trace})" would return "Monaco (GDP per capita)".'
4747
].join(' ')
4848
},
49-
groupnames: {
50-
_isLinkedToArray: 'groupname',
51-
group: {
52-
valType: 'string',
53-
role: 'info',
54-
description: [
55-
'An group to which this name applies. If a `group` and `name` are specified,',
56-
'that name overrides the `nameformat` for that group\'s trace.'
57-
].join(' ')
58-
},
59-
name: {
60-
valType: 'string',
61-
role: 'info',
62-
description: [
63-
'Trace names assigned to the grouped traces of the corresponding `group`.'
64-
].join(' ')
65-
}
66-
},
6749
styles: {
6850
_isLinkedToArray: 'style',
6951
target: {
@@ -115,17 +97,6 @@ exports.supplyDefaults = function(transformIn, traceOut, layout) {
11597
coerce('groups');
11698
coerce('nameformat', layout._dataLength > 1 ? '%{group} (%{trace})' : '%{group}');
11799

118-
var nameFormatIn = transformIn.groupnames;
119-
var nameFormatOut = transformOut.groupnames = [];
120-
121-
if(nameFormatIn) {
122-
for(i = 0; i < nameFormatIn.length; i++) {
123-
nameFormatOut[i] = {};
124-
Lib.coerce(nameFormatIn[i], nameFormatOut[i], exports.attributes.groupnames, 'group');
125-
Lib.coerce(nameFormatIn[i], nameFormatOut[i], exports.attributes.groupnames, 'name');
126-
}
127-
}
128-
129100
var styleIn = transformIn.styles;
130101
var styleOut = transformOut.styles = [];
131102

@@ -195,8 +166,8 @@ function transformOne(trace, state) {
195166
styleLookup[styles[i].target] = styles[i].value;
196167
}
197168

198-
if(opts.groupnames) {
199-
groupNameObj = Lib.keyedContainer(opts, 'groupnames', 'group', 'name');
169+
if(opts.styles) {
170+
groupNameObj = Lib.keyedContainer(opts, 'styles', 'group', 'value.name');
200171
}
201172

202173
// An index to map group name --> expanded trace index

test/jasmine/tests/lib_test.js

+57
Original file line numberDiff line numberDiff line change
@@ -1727,6 +1727,63 @@ describe('Test lib.js:', function() {
17271727
});
17281728
});
17291729
});
1730+
1731+
describe('with nested valueName', function() {
1732+
it('gets and sets values', function() {
1733+
var container = {styles: []};
1734+
1735+
var carr = Lib.keyedContainer(container, 'styles', 'foo', 'bar.value');
1736+
1737+
carr.set('name1', 'value1');
1738+
1739+
expect(container).toEqual({styles: [
1740+
{foo: 'name1', bar: {value: 'value1'}}
1741+
]});
1742+
1743+
expect(carr.get('name1')).toEqual('value1');
1744+
});
1745+
1746+
it('renames values', function() {
1747+
var container = {styles: []};
1748+
1749+
var carr = Lib.keyedContainer(container, 'styles', 'foo', 'bar.value');
1750+
1751+
carr.set('name1', 'value1');
1752+
carr.rename('name1', 'name2');
1753+
1754+
expect(container).toEqual({styles: [
1755+
{foo: 'name2', bar: {value: 'value1'}}
1756+
]});
1757+
1758+
expect(carr.get('name2')).toEqual('value1');
1759+
expect(carr.get('name1')).toBeUndefined();
1760+
});
1761+
1762+
it('constructs updates', function() {
1763+
var container = {styles: [
1764+
{foo: 'name1', bar: {value: 'value1'}},
1765+
{foo: 'name2', bar: {value: 'value2'}}
1766+
]};
1767+
1768+
var carr = Lib.keyedContainer(container, 'styles', 'foo', 'bar.value');
1769+
1770+
carr.set('name3', 'value3');
1771+
carr.remove('name2');
1772+
carr.rename('name1', 'name2');
1773+
1774+
expect(container).toEqual({styles: [
1775+
{foo: 'name2', bar: {value: 'value1'}},
1776+
{foo: 'name3', bar: {value: 'value3'}}
1777+
]});
1778+
1779+
expect(carr.constructUpdate()).toEqual({
1780+
'styles[0].foo': 'name2',
1781+
'styles[1].foo': 'name3',
1782+
'styles[1].bar.value': 'value3',
1783+
'styles[2]': null
1784+
});
1785+
});
1786+
});
17301787
});
17311788

17321789
describe('templateString', function() {

0 commit comments

Comments
 (0)