@dra2020/dra-types 1.8.92 → 1.8.93
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/datasets.d.ts +4 -1
- package/dist/dra-types.js +154 -86
- package/dist/dra-types.js.map +1 -1
- package/dist/packedfields.d.ts +24 -28
- package/lib/colormgr.ts +6 -6
- package/lib/datasets.ts +7 -1
- package/lib/packedfields.ts +155 -74
- package/package.json +1 -1
package/dist/packedfields.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PlanType } from './dra-types';
|
|
2
|
+
import { DatasetMeta, DatasetsMeta } from './datasets';
|
|
2
3
|
export declare const AGG_DEMOGRAPHIC = "demographic";
|
|
3
4
|
export declare const AGG_DEMOGRAPHIC18 = "demographic18";
|
|
4
5
|
export declare const AGG_pres2008 = "pres2008";
|
|
@@ -7,6 +8,7 @@ export declare const AGG_pvi = "pvi";
|
|
|
7
8
|
export declare const DATASET_TYPE_DEMOGRAPHIC = "demographic";
|
|
8
9
|
export declare const DATASET_TYPE_ELECTION = "election";
|
|
9
10
|
export declare const DATASET_TYPE_PVI = "pvi";
|
|
11
|
+
export declare const DATASET_TYPE_OTHER = "other";
|
|
10
12
|
export declare const DS_PVI2020 = "P20GPR";
|
|
11
13
|
export declare const PVI2020_Title = "PVI 2016/2020";
|
|
12
14
|
export declare const DS_PVI2016 = "P16GPR";
|
|
@@ -23,9 +25,10 @@ export interface StatesMetaIndex {
|
|
|
23
25
|
export interface StatesMeta {
|
|
24
26
|
[key: string]: StatesMetaIndex;
|
|
25
27
|
}
|
|
26
|
-
export type
|
|
27
|
-
export
|
|
28
|
-
|
|
28
|
+
export type PackedFieldsArray = Float64Array;
|
|
29
|
+
export type PackedFields = {
|
|
30
|
+
[datasetid: string]: PackedFieldsArray;
|
|
31
|
+
};
|
|
29
32
|
export interface PackedFieldsIndex {
|
|
30
33
|
[field: string]: number;
|
|
31
34
|
}
|
|
@@ -36,25 +39,8 @@ export interface PackedMetaIndex {
|
|
|
36
39
|
};
|
|
37
40
|
getDatasetField: (f: any, dataset: string, field: string) => number;
|
|
38
41
|
}
|
|
39
|
-
export
|
|
40
|
-
|
|
41
|
-
year: number;
|
|
42
|
-
title: string;
|
|
43
|
-
fields: {
|
|
44
|
-
[key: string]: any;
|
|
45
|
-
};
|
|
46
|
-
votingAge?: boolean;
|
|
47
|
-
office?: string;
|
|
48
|
-
subtype?: string;
|
|
49
|
-
description?: string;
|
|
50
|
-
nhAlone?: boolean;
|
|
51
|
-
privateKey?: string;
|
|
52
|
-
members?: {
|
|
53
|
-
[key: number]: string;
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
export type DatasetsMeta = {
|
|
57
|
-
[dataset: string]: DatasetMeta;
|
|
42
|
+
export type GroupPackedMetaIndex = {
|
|
43
|
+
[datasetid: string]: PackedMetaIndex;
|
|
58
44
|
};
|
|
59
45
|
export interface PrimaryDatasetKeys {
|
|
60
46
|
SHAPES?: string;
|
|
@@ -63,7 +49,7 @@ export interface PrimaryDatasetKeys {
|
|
|
63
49
|
ELECTION: string;
|
|
64
50
|
}
|
|
65
51
|
export interface DatasetContext {
|
|
66
|
-
dsIndex:
|
|
52
|
+
dsIndex: GroupPackedMetaIndex;
|
|
67
53
|
primeDDS: string;
|
|
68
54
|
primeVDS: string;
|
|
69
55
|
primeEDS: string;
|
|
@@ -85,19 +71,29 @@ export type DSLists = {
|
|
|
85
71
|
export type PlanTypePlus = PlanType | '';
|
|
86
72
|
export declare function fGetJoined(f: any): any[];
|
|
87
73
|
export declare function fGet(f: any, p: string): any;
|
|
88
|
-
export declare function computeMetaIndex(meta: DatasetsMeta): PackedMetaIndex;
|
|
74
|
+
export declare function computeMetaIndex(datasetid: string, meta: DatasetsMeta): PackedMetaIndex;
|
|
89
75
|
export declare function computePackedFields(f: any, index: PackedMetaIndex): PackedFields;
|
|
90
76
|
export declare function hasPackedFields(f: any): boolean;
|
|
91
77
|
export declare function setPackedFields(f: any, pf: PackedFields, fIndex: any): void;
|
|
78
|
+
export declare function isExtDataset(did: string): boolean;
|
|
79
|
+
export type ExtPackedFields = Uint32Array;
|
|
80
|
+
export type ExtBlockCardinality = Map<string, number>;
|
|
81
|
+
export declare function featurePushExtPackedFields(f: any, datasetid: string, data: ExtPackedFields, card: ExtBlockCardinality): void;
|
|
82
|
+
export declare function featurePushedExtPackedFields(f: any, datasetid: string, card: ExtBlockCardinality): boolean;
|
|
83
|
+
export declare function pushedExtPackedFields(pf: PackedFields, datasetids: string[]): boolean;
|
|
92
84
|
export declare function retrievePackedFields(f: any): PackedFields;
|
|
93
|
-
export declare function zeroPackedFields(index:
|
|
85
|
+
export declare function zeroPackedFields(index: GroupPackedMetaIndex): PackedFields;
|
|
94
86
|
export declare function zeroPackedCopy(pf: PackedFields): PackedFields;
|
|
95
87
|
export declare function packedCopy(pf: PackedFields): PackedFields;
|
|
96
88
|
export declare function aggregatePackedFields(agg: PackedFields, pf: PackedFields): PackedFields;
|
|
89
|
+
export declare function aggregateCount(agg: PackedFields): number;
|
|
90
|
+
export declare function decrementPackedFields(agg: PackedFields, pf: PackedFields): PackedFields;
|
|
97
91
|
export declare function diffPackedFields(main: any, parts: any[]): PackedFields;
|
|
98
|
-
export declare function getPackedField(index:
|
|
99
|
-
export declare function findPackedField(index:
|
|
100
|
-
export
|
|
92
|
+
export declare function getPackedField(index: GroupPackedMetaIndex, pf: PackedFields, datasetid: string, dataset: string, field: string): number;
|
|
93
|
+
export declare function findPackedField(index: GroupPackedMetaIndex, pf: PackedFields, datasetid: string, dataset: string, field: string): number;
|
|
94
|
+
export type FieldGetter = (f: string) => number;
|
|
95
|
+
export declare function fieldGetterNotLoaded(f: string): number;
|
|
96
|
+
export declare function ToGetter(agg: PackedFields, dc: DatasetContext, datasetid: string, datasetKey: string): FieldGetter;
|
|
101
97
|
export declare function ToGetterPvi16(agg: PackedFields, dc: DatasetContext, datasetKey: string): FieldGetter;
|
|
102
98
|
export declare function ToGetterPvi20(agg: PackedFields, dc: DatasetContext): FieldGetter;
|
|
103
99
|
export declare function calcShift(agg: PackedFields, dc: DatasetContext, datasetOld: string, datasetNew: string): number;
|
package/lib/colormgr.ts
CHANGED
|
@@ -172,7 +172,7 @@ export function ToAllEthnicColor(agg: PF.PackedFields, dc: PF.DatasetContext, pd
|
|
|
172
172
|
{
|
|
173
173
|
// Use VAP/CVAP if it exists
|
|
174
174
|
const dataset: string = dc.primeVDS ? dc.primeVDS : dc.primeDDS
|
|
175
|
-
return AggregateEthnicColor(PF.ToGetter(agg, dc, dataset), pd, dataset.endsWith('NH'));
|
|
175
|
+
return AggregateEthnicColor(PF.ToGetter(agg, dc, '', dataset), pd, dataset.endsWith('NH'));
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
export function ToPartisanColorStr(agg: PF.PackedFields, dc: PF.DatasetContext, pd: PaletteDefaults): string
|
|
@@ -189,8 +189,8 @@ function ToPartisanColor(agg: PF.PackedFields, dc: PF.DatasetContext, stops: Uti
|
|
|
189
189
|
{
|
|
190
190
|
if (dc.primeEDS === PF.DS_PVI2020)
|
|
191
191
|
{
|
|
192
|
-
const getter16 = PF.ToGetter(agg, dc, PF.DS_PRES2016);
|
|
193
|
-
const getter20 = PF.ToGetter(agg, dc, PF.DS_PRES2020);
|
|
192
|
+
const getter16 = PF.ToGetter(agg, dc, '', PF.DS_PRES2016);
|
|
193
|
+
const getter20 = PF.ToGetter(agg, dc, '', PF.DS_PRES2020);
|
|
194
194
|
|
|
195
195
|
const pviRaw = PF.calcRaw2020Pvi(getter16, getter20);
|
|
196
196
|
const color: string = ColorFromRGBPcts((1 - pviRaw / 100), 0, pviRaw / 100, stops);
|
|
@@ -199,14 +199,14 @@ function ToPartisanColor(agg: PF.PackedFields, dc: PF.DatasetContext, stops: Uti
|
|
|
199
199
|
}
|
|
200
200
|
else if (dc.primeEDS === PF.DS_PVI2016)
|
|
201
201
|
{
|
|
202
|
-
const getter = PF.ToGetter(agg, dc, dc.primeEDS);
|
|
202
|
+
const getter = PF.ToGetter(agg, dc, '', dc.primeEDS);
|
|
203
203
|
const pviRaw = PF.calcRawPvi(getter);
|
|
204
204
|
const color: string = ColorFromRGBPcts((1 - pviRaw/100), 0, pviRaw/100, stops);
|
|
205
205
|
return color;
|
|
206
206
|
}
|
|
207
207
|
else
|
|
208
208
|
{
|
|
209
|
-
const getter = PF.ToGetter(agg, dc, dc.primeEDS);
|
|
209
|
+
const getter = PF.ToGetter(agg, dc, '', dc.primeEDS);
|
|
210
210
|
return AggregatePartisanColorStr(getter, stops);
|
|
211
211
|
}
|
|
212
212
|
}
|
|
@@ -251,7 +251,7 @@ export function ToEthnicColorStr(agg: PF.PackedFields, dc: PF.DatasetContext, pd
|
|
|
251
251
|
default: break;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
const getter = PF.ToGetter(agg, dc, dataset);
|
|
254
|
+
const getter = PF.ToGetter(agg, dc, '', dataset);
|
|
255
255
|
let den = getter(total);
|
|
256
256
|
let num = getter(ethnic);
|
|
257
257
|
if (den === undefined || isNaN(den) || num === undefined || isNaN(num))
|
package/lib/datasets.ts
CHANGED
|
@@ -3,6 +3,12 @@ export interface DatasetField
|
|
|
3
3
|
{
|
|
4
4
|
shortCaption: string, // Typically 2-4 letters
|
|
5
5
|
longCaption: string, // Can be longer descriptive phrase, especially for combinations
|
|
6
|
+
order?: number, // For ordering fields in UI
|
|
7
|
+
isCombo?: boolean, // Built-in, for census combos
|
|
8
|
+
}
|
|
9
|
+
export function sortFields(f1: DatasetField, f2: DatasetField): number
|
|
10
|
+
{
|
|
11
|
+
return (f1.order || 0) - (f2.order || 0);
|
|
6
12
|
}
|
|
7
13
|
|
|
8
14
|
// For Partisan fields, expect keys of 'D', 'R' and 'Tot'
|
|
@@ -37,7 +43,7 @@ export interface Dataset
|
|
|
37
43
|
createTime?: string,
|
|
38
44
|
modifyTime?: string,
|
|
39
45
|
deleted?: boolean,
|
|
40
|
-
published?:
|
|
46
|
+
published?: string,
|
|
41
47
|
official?: boolean,
|
|
42
48
|
state?: string,
|
|
43
49
|
datasource?: string,
|
package/lib/packedfields.ts
CHANGED
|
@@ -29,6 +29,8 @@ import { PlanType } from './dra-types';
|
|
|
29
29
|
// Mix: Two or more races, not Hispanic
|
|
30
30
|
// AsnPI: Asian + Pacific, not Hispanic
|
|
31
31
|
|
|
32
|
+
import { DatasetMeta, DatasetsMeta } from './datasets';
|
|
33
|
+
|
|
32
34
|
|
|
33
35
|
export const AGG_DEMOGRAPHIC = 'demographic';
|
|
34
36
|
export const AGG_DEMOGRAPHIC18 = 'demographic18';
|
|
@@ -39,6 +41,7 @@ export const AGG_pvi = 'pvi';
|
|
|
39
41
|
export const DATASET_TYPE_DEMOGRAPHIC = 'demographic';
|
|
40
42
|
export const DATASET_TYPE_ELECTION = 'election';
|
|
41
43
|
export const DATASET_TYPE_PVI = 'pvi';
|
|
44
|
+
export const DATASET_TYPE_OTHER = 'other';
|
|
42
45
|
|
|
43
46
|
export const DS_PVI2020 = 'P20GPR';
|
|
44
47
|
export const PVI2020_Title = 'PVI 2016/2020';
|
|
@@ -63,9 +66,8 @@ export interface StatesMeta
|
|
|
63
66
|
[key: string]: StatesMetaIndex; // key is one of the datasource strings
|
|
64
67
|
}
|
|
65
68
|
|
|
66
|
-
export type
|
|
67
|
-
export
|
|
68
|
-
export type PackedFields = Float64Array;
|
|
69
|
+
export type PackedFieldsArray = Float64Array;
|
|
70
|
+
export type PackedFields = { [datasetid: string]: PackedFieldsArray };
|
|
69
71
|
export interface PackedFieldsIndex
|
|
70
72
|
{
|
|
71
73
|
[field: string]: number; // offset into PackedFields
|
|
@@ -78,23 +80,7 @@ export interface PackedMetaIndex
|
|
|
78
80
|
getDatasetField: (f: any, dataset: string, field: string) => number;
|
|
79
81
|
}
|
|
80
82
|
|
|
81
|
-
export
|
|
82
|
-
{
|
|
83
|
-
type: string,
|
|
84
|
-
year: number,
|
|
85
|
-
title: string,
|
|
86
|
-
fields: {
|
|
87
|
-
[key: string]: any,
|
|
88
|
-
},
|
|
89
|
-
votingAge?: boolean,
|
|
90
|
-
office?: string,
|
|
91
|
-
subtype?: string,
|
|
92
|
-
description?: string,
|
|
93
|
-
nhAlone?: boolean,
|
|
94
|
-
privateKey?: string, // key for private data
|
|
95
|
-
members?: {[key: number]: string},
|
|
96
|
-
}
|
|
97
|
-
export type DatasetsMeta = { [dataset: string]: DatasetMeta };
|
|
83
|
+
export type GroupPackedMetaIndex = { [datasetid: string]: PackedMetaIndex };
|
|
98
84
|
|
|
99
85
|
export interface PrimaryDatasetKeys
|
|
100
86
|
{
|
|
@@ -108,7 +94,7 @@ export interface PrimaryDatasetKeys
|
|
|
108
94
|
// well as user selections around which datasets to view. Used to propagate through UI.
|
|
109
95
|
export interface DatasetContext
|
|
110
96
|
{
|
|
111
|
-
dsIndex:
|
|
97
|
+
dsIndex: GroupPackedMetaIndex;
|
|
112
98
|
primeDDS: string; // Demographic (Census)
|
|
113
99
|
primeVDS: string; // VAP/CVAP
|
|
114
100
|
primeEDS: string; // Election
|
|
@@ -189,7 +175,7 @@ function fGetW(f: any, datasetKey: string, p: string): any
|
|
|
189
175
|
return undefined;
|
|
190
176
|
}
|
|
191
177
|
|
|
192
|
-
export function computeMetaIndex(meta: DatasetsMeta): PackedMetaIndex
|
|
178
|
+
export function computeMetaIndex(datasetid: string, meta: DatasetsMeta): PackedMetaIndex
|
|
193
179
|
{
|
|
194
180
|
if (meta == null) return null;
|
|
195
181
|
let offset = 1; // first entry is count of aggregates
|
|
@@ -202,21 +188,22 @@ export function computeMetaIndex(meta: DatasetsMeta): PackedMetaIndex
|
|
|
202
188
|
});
|
|
203
189
|
index.fields[datasetKey] = fieldsIndex;
|
|
204
190
|
});
|
|
191
|
+
let groupindex = { [datasetid]: index };
|
|
205
192
|
index.length = offset;
|
|
206
193
|
index.getDatasetField = (f: any, dataset: string, field: string): number => {
|
|
207
194
|
let pf = retrievePackedFields(f);
|
|
208
|
-
return getPackedField(
|
|
195
|
+
return getPackedField(groupindex, pf, datasetid, dataset, field);
|
|
209
196
|
};
|
|
210
197
|
return index;
|
|
211
198
|
}
|
|
212
199
|
|
|
213
200
|
let nAlloc = 0;
|
|
214
|
-
function
|
|
201
|
+
function allocPackedFieldsArray(length: number): PackedFieldsArray
|
|
215
202
|
{
|
|
216
203
|
let ab = new ArrayBuffer(8 * length);
|
|
217
204
|
let af = new Float64Array(ab);
|
|
218
205
|
nAlloc++;
|
|
219
|
-
//if ((nAlloc % 10000) == 0) console.log(`
|
|
206
|
+
//if ((nAlloc % 10000) == 0) console.log(`allocPackedFieldsArray: ${nAlloc} allocs`);
|
|
220
207
|
return af;
|
|
221
208
|
}
|
|
222
209
|
|
|
@@ -224,7 +211,7 @@ export function computePackedFields(f: any, index: PackedMetaIndex): PackedField
|
|
|
224
211
|
{
|
|
225
212
|
if (f.properties.packedFields) return f.properties.packedFields as PackedFields;
|
|
226
213
|
|
|
227
|
-
let af =
|
|
214
|
+
let af = allocPackedFieldsArray(index.length);
|
|
228
215
|
af[0] = 0; // count of number of aggregates
|
|
229
216
|
Object.keys(index.fields).forEach((dataset: string) => {
|
|
230
217
|
let fields = index.fields[dataset];
|
|
@@ -235,12 +222,12 @@ export function computePackedFields(f: any, index: PackedMetaIndex): PackedField
|
|
|
235
222
|
af[fields[field]] = n;
|
|
236
223
|
});
|
|
237
224
|
});
|
|
238
|
-
f.properties.packedFields = af; // cache here
|
|
225
|
+
f.properties.packedFields = { ['']: af }; // cache here
|
|
239
226
|
f.properties.getDatasetField = index.getDatasetField;
|
|
240
227
|
|
|
241
228
|
// Major memory savings to delete this after packing
|
|
242
229
|
delete f.properties.datasets;
|
|
243
|
-
return
|
|
230
|
+
return f.properties.packedFields;
|
|
244
231
|
}
|
|
245
232
|
|
|
246
233
|
export function hasPackedFields(f: any): boolean
|
|
@@ -255,6 +242,60 @@ export function setPackedFields(f: any, pf: PackedFields, fIndex: any): void
|
|
|
255
242
|
f.properties.getDatasetField = fIndex.properties.getDatasetField
|
|
256
243
|
}
|
|
257
244
|
|
|
245
|
+
const reExtDataset = /^.*\.ds$/;
|
|
246
|
+
export function isExtDataset(did: string): boolean
|
|
247
|
+
{
|
|
248
|
+
return did && reExtDataset.test(did);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export type ExtPackedFields = Uint32Array; // [nblocks][nfields][fields]...
|
|
252
|
+
export type ExtBlockCardinality = Map<string, number>;
|
|
253
|
+
|
|
254
|
+
export function featurePushExtPackedFields(f: any, datasetid: string, data: ExtPackedFields, card: ExtBlockCardinality): void
|
|
255
|
+
{
|
|
256
|
+
let blocks = f?.properties?.blocks || (card.has(f.properties.id) ? [ f.properties.id ] : null);
|
|
257
|
+
if (!blocks)
|
|
258
|
+
return;
|
|
259
|
+
if (!f.properties.packedFields)
|
|
260
|
+
throw('pushExtPackedFields: base datasets should be pushed first');
|
|
261
|
+
if (card.size != data[0])
|
|
262
|
+
throw('pushExtPackedFields: packed fields and block cardinality do not match');
|
|
263
|
+
if (f.properties.packedFields[datasetid])
|
|
264
|
+
return; // already pushed
|
|
265
|
+
let nfields = data[1];
|
|
266
|
+
let pfa = allocPackedFieldsArray(nfields+1); // field count
|
|
267
|
+
pfa[0] = 0;
|
|
268
|
+
for (let j = 0; j < nfields; j++) pfa[j] = 0;
|
|
269
|
+
blocks.forEach((blockid: string) => {
|
|
270
|
+
if (! card.has(blockid))
|
|
271
|
+
throw(`pushExtPackedFields: missing blockid ${blockid} in cardinality set`);
|
|
272
|
+
let x = 2 + (nfields * card.get(blockid));
|
|
273
|
+
for (let i = 1; i <= nfields; i++)
|
|
274
|
+
pfa[i] += data[x++];
|
|
275
|
+
});
|
|
276
|
+
f.properties.packedFields[datasetid] = pfa;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export function featurePushedExtPackedFields(f: any, datasetid: string, card: ExtBlockCardinality): boolean
|
|
280
|
+
{
|
|
281
|
+
if (! f) return true;
|
|
282
|
+
if (f.features) return featurePushedExtPackedFields(f.features[0], datasetid, card);
|
|
283
|
+
if (!f?.properties?.blocks && !card.has(f.properties.id))
|
|
284
|
+
return true;
|
|
285
|
+
if (!f.properties.packedFields)
|
|
286
|
+
return true;
|
|
287
|
+
return !!f.properties.packedFields[datasetid];
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function pushedExtPackedFields(pf: PackedFields, datasetids: string[]): boolean
|
|
291
|
+
{
|
|
292
|
+
if (pf && datasetids)
|
|
293
|
+
for (let i = 0; i < datasetids.length; i++)
|
|
294
|
+
if (! pf[datasetids[i]])
|
|
295
|
+
return false;
|
|
296
|
+
return !!pf;
|
|
297
|
+
}
|
|
298
|
+
|
|
258
299
|
export function retrievePackedFields(f: any): PackedFields
|
|
259
300
|
{
|
|
260
301
|
if (f.properties.packedFields === undefined) throw 'Feature should have pre-computed packed fields';
|
|
@@ -266,46 +307,85 @@ export function retrievePackedFields(f: any): PackedFields
|
|
|
266
307
|
let abZero = new ArrayBuffer(8);
|
|
267
308
|
let afZero = new Float64Array(abZero);
|
|
268
309
|
afZero[0] = 0;
|
|
310
|
+
let pfZero = { ['']: afZero };
|
|
269
311
|
|
|
270
|
-
export function zeroPackedFields(index:
|
|
312
|
+
export function zeroPackedFields(index: GroupPackedMetaIndex): PackedFields
|
|
271
313
|
{
|
|
272
|
-
if (index == null) return
|
|
273
|
-
let
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
314
|
+
if (index == null) return pfZero;
|
|
315
|
+
let pf: PackedFields = {};
|
|
316
|
+
Object.keys(index).forEach(datasetid => {
|
|
317
|
+
let af = allocPackedFieldsArray(index[datasetid].length);
|
|
318
|
+
for (let i = 0; i < af.length; i++)
|
|
319
|
+
af[i] = 0;
|
|
320
|
+
pf[datasetid] = af;
|
|
321
|
+
});
|
|
322
|
+
return pf;
|
|
277
323
|
}
|
|
278
324
|
|
|
279
325
|
export function zeroPackedCopy(pf: PackedFields): PackedFields
|
|
280
326
|
{
|
|
281
|
-
if (pf == null) return
|
|
282
|
-
let
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
327
|
+
if (pf == null) return pfZero;
|
|
328
|
+
let copy: PackedFields = {};
|
|
329
|
+
Object.keys(pf).forEach(datasetid => {
|
|
330
|
+
let cf = allocPackedFieldsArray(pf[datasetid].length);
|
|
331
|
+
for (let i = 0; i < cf.length; i++)
|
|
332
|
+
cf[i] = 0;
|
|
333
|
+
copy[datasetid] = cf;
|
|
334
|
+
});
|
|
335
|
+
return copy;
|
|
286
336
|
}
|
|
287
337
|
|
|
288
338
|
export function packedCopy(pf: PackedFields): PackedFields
|
|
289
339
|
{
|
|
290
340
|
if (pf == null) return null;
|
|
291
|
-
let
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
341
|
+
let copy: PackedFields = {};
|
|
342
|
+
Object.keys(pf).forEach(datasetid => {
|
|
343
|
+
let af = pf[datasetid];
|
|
344
|
+
let cf = allocPackedFieldsArray(af.length);
|
|
345
|
+
for (let i = 0; i < af.length; i++)
|
|
346
|
+
cf[i] = af[i];
|
|
347
|
+
copy[datasetid] = cf;
|
|
348
|
+
});
|
|
349
|
+
return copy;
|
|
295
350
|
}
|
|
296
351
|
|
|
297
352
|
export function aggregatePackedFields(agg: PackedFields, pf: PackedFields): PackedFields
|
|
298
353
|
{
|
|
299
354
|
if (agg == null || pf == null) return agg;
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
355
|
+
Object.keys(agg).forEach(datasetid => {
|
|
356
|
+
let af = agg[datasetid];
|
|
357
|
+
let sf = pf[datasetid];
|
|
358
|
+
if (sf && sf.length == af.length)
|
|
359
|
+
{
|
|
360
|
+
let n = af.length;
|
|
361
|
+
for (let i = 1; i < n; i++)
|
|
362
|
+
af[i] += sf[i];
|
|
363
|
+
af[0]++; // count of aggregates
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
return agg;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
export function aggregateCount(agg: PackedFields): number
|
|
370
|
+
{
|
|
371
|
+
if (!agg || !agg['']) return 0;
|
|
372
|
+
return agg[''][0];
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export function decrementPackedFields(agg: PackedFields, pf: PackedFields): PackedFields
|
|
376
|
+
{
|
|
377
|
+
if (agg == null || pf == null) return agg;
|
|
378
|
+
Object.keys(agg).forEach(datasetid => {
|
|
379
|
+
let af = agg[datasetid];
|
|
380
|
+
let sf = pf[datasetid];
|
|
381
|
+
if (sf && sf.length == af.length)
|
|
382
|
+
{
|
|
383
|
+
let n = af.length;
|
|
384
|
+
for (let i = 1; i < n; i++)
|
|
385
|
+
af[i] -= sf[i];
|
|
386
|
+
af[0]++; // count of aggregates
|
|
387
|
+
}
|
|
388
|
+
});
|
|
309
389
|
return agg;
|
|
310
390
|
}
|
|
311
391
|
|
|
@@ -314,29 +394,30 @@ export function diffPackedFields(main: any, parts: any[]): PackedFields
|
|
|
314
394
|
main = packedCopy(retrievePackedFields(main));
|
|
315
395
|
if (main == null || parts == null || parts.length == 0) return null;
|
|
316
396
|
parts = parts.map(retrievePackedFields);
|
|
317
|
-
parts.forEach((pf: PackedFields) =>
|
|
318
|
-
for (let i = 0; i < main.length; i++)
|
|
319
|
-
main[i] -= pf[i];
|
|
320
|
-
});
|
|
397
|
+
parts.forEach((pf: PackedFields) => decrementPackedFields(main, pf));
|
|
321
398
|
return main;
|
|
322
399
|
}
|
|
323
400
|
|
|
324
|
-
export function getPackedField(index:
|
|
401
|
+
export function getPackedField(index: GroupPackedMetaIndex, pf: PackedFields, datasetid: string, dataset: string, field: string): number
|
|
325
402
|
{
|
|
326
|
-
if (index
|
|
327
|
-
let fields = index.fields[dataset];
|
|
328
|
-
return fields ? (fields[field] !== undefined ? pf[fields[field]] : 0) : 0;
|
|
403
|
+
if (!index || !pf || !index[datasetid] || !pf[datasetid]) return 0;
|
|
404
|
+
let fields = index[datasetid].fields[dataset];
|
|
405
|
+
return fields ? (fields[field] !== undefined ? pf[datasetid][fields[field]] : 0) : 0;
|
|
329
406
|
}
|
|
330
407
|
|
|
331
|
-
export function findPackedField(index:
|
|
408
|
+
export function findPackedField(index: GroupPackedMetaIndex, pf: PackedFields, datasetid: string, dataset: string, field: string): number
|
|
332
409
|
{
|
|
333
|
-
let fields = index.fields[dataset];
|
|
410
|
+
let fields = index[datasetid].fields[dataset];
|
|
334
411
|
return fields ? (fields[field] !== undefined ? fields[field] : -1) : -1;
|
|
335
412
|
}
|
|
336
413
|
|
|
337
|
-
|
|
414
|
+
// Utility type to simplify code that pulls from same dataset to compute some composite
|
|
415
|
+
export type FieldGetter = (f: string) => number;
|
|
416
|
+
export function fieldGetterNotLoaded(f: string): number { return undefined }
|
|
417
|
+
|
|
418
|
+
export function ToGetter(agg: PackedFields, dc: DatasetContext, datasetid: string, datasetKey: string): FieldGetter
|
|
338
419
|
{
|
|
339
|
-
return (field: string) => { return getPackedField(dc.dsIndex, agg, datasetKey, field) };
|
|
420
|
+
return (field: string) => { return getPackedField(dc.dsIndex, agg, datasetid, datasetKey, field) };
|
|
340
421
|
}
|
|
341
422
|
|
|
342
423
|
export function ToGetterPvi16(agg: PackedFields, dc: DatasetContext, datasetKey: string): FieldGetter
|
|
@@ -344,13 +425,13 @@ export function ToGetterPvi16(agg: PackedFields, dc: DatasetContext, datasetKey:
|
|
|
344
425
|
return (field: string) =>
|
|
345
426
|
{
|
|
346
427
|
if (field === 'R')
|
|
347
|
-
return Math.round((getPackedField(dc.dsIndex, agg, datasetKey, 'R12') + getPackedField(dc.dsIndex, agg, datasetKey, 'R16')) / 2);
|
|
428
|
+
return Math.round((getPackedField(dc.dsIndex, agg, '', datasetKey, 'R12') + getPackedField(dc.dsIndex, agg, '', datasetKey, 'R16')) / 2);
|
|
348
429
|
if (field === 'D')
|
|
349
|
-
return Math.round((getPackedField(dc.dsIndex, agg, datasetKey, 'D12') + getPackedField(dc.dsIndex, agg, datasetKey, 'D16')) / 2);
|
|
430
|
+
return Math.round((getPackedField(dc.dsIndex, agg, '', datasetKey, 'D12') + getPackedField(dc.dsIndex, agg, '', datasetKey, 'D16')) / 2);
|
|
350
431
|
if (field === 'Tot')
|
|
351
432
|
return Math.round((
|
|
352
|
-
getPackedField(dc.dsIndex, agg, datasetKey, 'R12') + getPackedField(dc.dsIndex, agg, datasetKey, 'R16') +
|
|
353
|
-
getPackedField(dc.dsIndex, agg, datasetKey, 'D12') + getPackedField(dc.dsIndex, agg, datasetKey, 'D16')) / 2);
|
|
433
|
+
getPackedField(dc.dsIndex, agg, '', datasetKey, 'R12') + getPackedField(dc.dsIndex, agg, '', datasetKey, 'R16') +
|
|
434
|
+
getPackedField(dc.dsIndex, agg, '', datasetKey, 'D12') + getPackedField(dc.dsIndex, agg, '', datasetKey, 'D16')) / 2);
|
|
354
435
|
return 0;
|
|
355
436
|
};
|
|
356
437
|
}
|
|
@@ -360,13 +441,13 @@ export function ToGetterPvi20(agg: PackedFields, dc: DatasetContext): FieldGette
|
|
|
360
441
|
return (field: string) =>
|
|
361
442
|
{
|
|
362
443
|
if (field === 'R')
|
|
363
|
-
return Math.round((getPackedField(dc.dsIndex, agg, DS_PRES2016, 'R') + getPackedField(dc.dsIndex, agg, DS_PRES2020, 'R')) / 2);
|
|
444
|
+
return Math.round((getPackedField(dc.dsIndex, agg, '', DS_PRES2016, 'R') + getPackedField(dc.dsIndex, agg, '', DS_PRES2020, 'R')) / 2);
|
|
364
445
|
if (field === 'D')
|
|
365
|
-
return Math.round((getPackedField(dc.dsIndex, agg, DS_PRES2016, 'D') + getPackedField(dc.dsIndex, agg, DS_PRES2020, 'D')) / 2);
|
|
446
|
+
return Math.round((getPackedField(dc.dsIndex, agg, '', DS_PRES2016, 'D') + getPackedField(dc.dsIndex, agg, '', DS_PRES2020, 'D')) / 2);
|
|
366
447
|
if (field === 'Tot')
|
|
367
448
|
return Math.round((
|
|
368
|
-
getPackedField(dc.dsIndex, agg, DS_PRES2016, 'R') + getPackedField(dc.dsIndex, agg, DS_PRES2020, 'R') +
|
|
369
|
-
getPackedField(dc.dsIndex, agg, DS_PRES2016, 'D') + getPackedField(dc.dsIndex, agg, DS_PRES2020, 'D')) / 2);
|
|
449
|
+
getPackedField(dc.dsIndex, agg, '', DS_PRES2016, 'R') + getPackedField(dc.dsIndex, agg, '', DS_PRES2020, 'R') +
|
|
450
|
+
getPackedField(dc.dsIndex, agg, '', DS_PRES2016, 'D') + getPackedField(dc.dsIndex, agg, '', DS_PRES2020, 'D')) / 2);
|
|
370
451
|
return 0;
|
|
371
452
|
};
|
|
372
453
|
|
|
@@ -378,12 +459,12 @@ export function calcShift(agg: PackedFields, dc: DatasetContext, datasetOld: str
|
|
|
378
459
|
ToGetterPvi16(agg, dc, datasetOld) :
|
|
379
460
|
datasetOld === DS_PVI2020 ?
|
|
380
461
|
ToGetterPvi20(agg, dc) :
|
|
381
|
-
ToGetter(agg, dc, datasetOld);
|
|
462
|
+
ToGetter(agg, dc, '', datasetOld);
|
|
382
463
|
const getterNew = datasetNew === DS_PVI2016 ?
|
|
383
464
|
ToGetterPvi16(agg, dc, datasetNew) :
|
|
384
465
|
datasetNew === DS_PVI2020 ?
|
|
385
466
|
ToGetterPvi20(agg, dc) :
|
|
386
|
-
ToGetter(agg, dc, datasetNew);
|
|
467
|
+
ToGetter(agg, dc, '', datasetNew);
|
|
387
468
|
|
|
388
469
|
// Calc two-party Swing
|
|
389
470
|
const repOld = getterOld('R');
|