Skip to content

Commit bf285d0

Browse files
author
Tom Pearson
authored
Fix adjustments (#16)
* provide calculation list to the indexEntity function * allow individual indicators to be reset * allow bulk resetting of adjusted indicators * add tests for adjusting and resetting * Update docs * version bump * remove redundant clone() (indexEntity already clones the entity)
1 parent 27132f3 commit bf285d0

File tree

4 files changed

+57
-16
lines changed

4 files changed

+57
-16
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ __allowOverwrite__, optional. By default this is set to true ensuring that all c
7474

7575

7676
### indexCore.__adjustValue(_entityName:String_, _indicatorID:String_, _value:Number_)__
77-
A function that allows the user to adjust an entity's indicator score within the index the index is recalculated using the new value. The index is recalculated after calling this function.
77+
A function that allows the user to adjust an entity's (_entityName_) indicator (_indicatorID_) score to a specified _value_. Calculated values for that entity are re-calculated using the new value. If the function is called without _value_ the indicator is reset to it's inital value. If the function is called without _indicatorId_ or _value_ all indicators on the entity are reset to their initial values.
7878

7979
_NOTE: whislt the old value is retained there's currently no way to reset it._
8080

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@economist/index-core",
3-
"version": "1.4.0",
3+
"version": "1.4.1",
44
"description": "",
55
"main": "src/index-core.js",
66
"type": "module",

src/index-core.js

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,27 @@ function indexCore(indicatorsData = [], entitiesData = [], indexMax = 100, allow
124124

125125
function adjustValue(entityName, indicatorID, value) {
126126
const e = getEntity(entityName);
127-
if (indicatorLookup[indicatorID].type === 'calculated') {
127+
128+
if(!indicatorID && !value || !e.user){
129+
e.user = {}; // no value or indicator specified, reset
130+
}else if(!value && e.user){
131+
delete e.user[indicatorID]; // no value specified, reset the indicator
132+
}
133+
134+
135+
if (indicatorLookup[indicatorID] && indicatorLookup[indicatorID].type === 'calculated') {
128136
console.warn(`${indicatorID} is a calculated value and can not be adjusted directly, perhaps you meant to adjust the weighting?`);
129137
return clone(e);
130138
}
131-
if (!e.user) e.user = {};
132-
e.user[indicatorID] = value;
133-
//note the re-indexed value for the entity is not stored
134-
//only the adjustment the re-indexed value is returned to the caller
135-
return indexEntity(Object.assign(clone(e), e.user));
139+
if(indicatorID !== undefined && value !== undefined){
140+
e.user[indicatorID] = value;
141+
}
142+
143+
const onlyIdIndicators = getIndexableIndicators(indicatorsData);
144+
const calculationList = getCalculationList(onlyIdIndicators);
145+
146+
indexedData[e.name] = indexEntity(e, calculationList, true);
147+
return indexedData[e.name];
136148
}
137149

138150
function createStructure(indicatorIds) {
@@ -162,19 +174,27 @@ function indexCore(indicatorsData = [], entitiesData = [], indexMax = 100, allow
162174
return tree;
163175
}
164176

165-
function calculateIndex(overwrite = allowOverwrite) {
166-
const onlyIdIndicators = indicatorsData
177+
function getCalculationList(indicators){
178+
return indicators
179+
.filter((i) => (i.type === 'calculated' && !excludeIndicator(i)))
180+
.map((i) => i.id)
181+
.sort((i1, i2) => (i2.split('.').length - i1.split('.').length));
182+
}
183+
184+
function getIndexableIndicators(indicators){
185+
return indicatorsData
167186
.filter((i) =>{
168187
const isIndicator = String(i.id).match(indicatorIdTest)
169188
const isExcluded = excludeIndicator(i);
170189
return isIndicator && !isExcluded;
171190
});
191+
}
192+
193+
function calculateIndex(overwrite = allowOverwrite) {
172194
// get a list of the values we need to calculate
173-
// in order of deepest in the heirachy to to shallowist
174-
const calculationList = onlyIdIndicators
175-
.filter((i) => (i.type === 'calculated' && !excludeIndicator(i)))
176-
.map((i) => i.id)
177-
.sort((i1, i2) => (i2.split('.').length - i1.split('.').length));
195+
// in order of deepest in the heirachy to the shallowist
196+
const onlyIdIndicators = getIndexableIndicators(indicatorsData);
197+
const calculationList = getCalculationList(onlyIdIndicators);
178198

179199
indexStructure = createStructure(onlyIdIndicators.map((i) => i.id));
180200

@@ -189,7 +209,7 @@ function indexCore(indicatorsData = [], entitiesData = [], indexMax = 100, allow
189209
// TODO: make the index recalculating take into account what
190210
// has changed in the data rather than doing the whole shebang
191211
indicatorLookup[indicatorID].userWeighting = weight;
192-
calculateIndex();
212+
calculateIndex(true);
193213
}
194214

195215
function filterIndicators(exclude = ()=>false, overwrite=allowOverwrite){

test/index-core.test.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,27 @@ test('create index-core', ()=>{
1919
expect(waterOptimisationIndex.indexedData['Naples'].value.toFixed(1)).toBe('76.2');
2020
});
2121

22+
test('adjust indicator', ()=>{
23+
const simpleIndex = indexCore(simpleIndicators, simpleEntities);
24+
const originalValue = simpleIndex.indexedData['Monopoly'].value;
25+
simpleIndex.adjustValue('Monopoly','1.1',10);
26+
const adjustedValue = simpleIndex.indexedData['Monopoly'].value;
27+
simpleIndex.adjustValue('Monopoly');
28+
const resetValue = simpleIndex.indexedData['Monopoly'].value;
29+
expect(originalValue.toFixed(3)).toBe('49.118')
30+
expect(adjustedValue.toFixed(3)).toBe('53.118')
31+
expect(originalValue).toBe(resetValue);
32+
})
33+
34+
test('reset individual indicator', ()=>{
35+
const simpleIndex = indexCore(simpleIndicators, simpleEntities);
36+
simpleIndex.adjustValue('Monopoly','1.1',10);
37+
simpleIndex.adjustValue('Monopoly','1.2',1);
38+
simpleIndex.adjustValue('Monopoly','1.2');
39+
const resetValue = simpleIndex.indexedData['Monopoly'].value;
40+
expect(resetValue.toFixed(3)).toBe('53.118')
41+
})
42+
2243
test('getIndicatorMean index-core', ()=>{
2344
const waterOptimisationIndex = indexCore(waterIndicators, waterEntities);
2445
expect(waterOptimisationIndex.getIndexMean('1').toFixed(1)).toBe('72.2');

0 commit comments

Comments
 (0)