@dra2020/district-analytics 9.3.0 → 9.4.1
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/district-analytics.js +95 -62
- package/dist/district-analytics.js.map +1 -1
- package/dist/src/_data.d.ts +18 -17
- package/package.json +2 -2
|
@@ -351,28 +351,31 @@ var DistrictField;
|
|
|
351
351
|
DistrictField[DistrictField["bContiguous"] = 4] = "bContiguous";
|
|
352
352
|
DistrictField[DistrictField["bNotEmbedded"] = 5] = "bNotEmbedded";
|
|
353
353
|
DistrictField[DistrictField["CountySplits"] = 6] = "CountySplits";
|
|
354
|
+
// 10-22-2020 - Add OtherVotes
|
|
354
355
|
DistrictField[DistrictField["DemVotes"] = 7] = "DemVotes";
|
|
355
356
|
DistrictField[DistrictField["RepVotes"] = 8] = "RepVotes";
|
|
356
|
-
DistrictField[DistrictField["
|
|
357
|
+
DistrictField[DistrictField["OtherVotes"] = 9] = "OtherVotes";
|
|
358
|
+
// TwoPartyVote, // Two-party total ()= Dem + Rep) not all votes!
|
|
357
359
|
DistrictField[DistrictField["DemPct"] = 10] = "DemPct";
|
|
358
360
|
DistrictField[DistrictField["RepPct"] = 11] = "RepPct";
|
|
359
|
-
DistrictField[DistrictField["
|
|
360
|
-
|
|
361
|
-
DistrictField[DistrictField["
|
|
362
|
-
DistrictField[DistrictField["
|
|
363
|
-
DistrictField[DistrictField["
|
|
364
|
-
DistrictField[DistrictField["
|
|
365
|
-
DistrictField[DistrictField["
|
|
366
|
-
DistrictField[DistrictField["
|
|
367
|
-
DistrictField[DistrictField["
|
|
368
|
-
DistrictField[DistrictField["
|
|
369
|
-
DistrictField[DistrictField["
|
|
370
|
-
DistrictField[DistrictField["
|
|
371
|
-
DistrictField[DistrictField["
|
|
372
|
-
DistrictField[DistrictField["
|
|
373
|
-
DistrictField[DistrictField["
|
|
374
|
-
DistrictField[DistrictField["
|
|
375
|
-
|
|
361
|
+
DistrictField[DistrictField["OtherPct"] = 12] = "OtherPct";
|
|
362
|
+
// End - OtherVotes changes
|
|
363
|
+
DistrictField[DistrictField["DemSeat"] = 13] = "DemSeat";
|
|
364
|
+
DistrictField[DistrictField["TotalVAP"] = 14] = "TotalVAP";
|
|
365
|
+
DistrictField[DistrictField["MinorityPop"] = 15] = "MinorityPop";
|
|
366
|
+
DistrictField[DistrictField["WhitePop"] = 16] = "WhitePop";
|
|
367
|
+
DistrictField[DistrictField["BlackPop"] = 17] = "BlackPop";
|
|
368
|
+
DistrictField[DistrictField["HispanicPop"] = 18] = "HispanicPop";
|
|
369
|
+
DistrictField[DistrictField["PacificPop"] = 19] = "PacificPop";
|
|
370
|
+
DistrictField[DistrictField["AsianPop"] = 20] = "AsianPop";
|
|
371
|
+
DistrictField[DistrictField["NativePop"] = 21] = "NativePop";
|
|
372
|
+
DistrictField[DistrictField["WhitePct"] = 22] = "WhitePct";
|
|
373
|
+
DistrictField[DistrictField["MinorityPct"] = 23] = "MinorityPct";
|
|
374
|
+
DistrictField[DistrictField["BlackPct"] = 24] = "BlackPct";
|
|
375
|
+
DistrictField[DistrictField["HispanicPct"] = 25] = "HispanicPct";
|
|
376
|
+
DistrictField[DistrictField["PacificPct"] = 26] = "PacificPct";
|
|
377
|
+
DistrictField[DistrictField["AsianPct"] = 27] = "AsianPct";
|
|
378
|
+
DistrictField[DistrictField["NativePct"] = 28] = "NativePct"; // Display
|
|
376
379
|
})(DistrictField = exports.DistrictField || (exports.DistrictField = {}));
|
|
377
380
|
class Districts {
|
|
378
381
|
constructor(s, ds) {
|
|
@@ -419,12 +422,6 @@ class Districts {
|
|
|
419
422
|
return outer;
|
|
420
423
|
}
|
|
421
424
|
// This is the workhorse computational routine!
|
|
422
|
-
//
|
|
423
|
-
// NOTE - OPTIMIZE for getting multiple properties from the same feature?
|
|
424
|
-
// NOTE - OPTIMIZE by only re-calc'ing districts that have changed?
|
|
425
|
-
// In this case, special attention to getting county-splits right.
|
|
426
|
-
// NOTE - OPTIMIZE by async'ing this?
|
|
427
|
-
// NOTE - Is there a way to do this programmatically off data? Does it matter?
|
|
428
425
|
recalcStatistics(bLog = false) {
|
|
429
426
|
// Initialize debug counters
|
|
430
427
|
nMissingDataset = 0;
|
|
@@ -432,15 +429,18 @@ class Districts {
|
|
|
432
429
|
// Compute these once per recalc cycle
|
|
433
430
|
let targetSize = Math.round(this._session.state.totalPop / this._session.state.nDistricts);
|
|
434
431
|
let deviationThreshold = this._session.populationDeviationThreshold();
|
|
435
|
-
let planByDistrict = this._session.plan.byDistrictID();
|
|
432
|
+
// let planByDistrict = this._session.plan.byDistrictID();
|
|
436
433
|
let plan = this._session.plan;
|
|
437
434
|
let graph = this._session.graph;
|
|
438
435
|
// Add an extra 0th virtual county bucket for county-district splitting analysis
|
|
439
436
|
let nCountyBuckets = this._session.counties.nCounties + 1;
|
|
440
437
|
// INITIALIZE STATE VALUES THAT WILL BE ACCUMULATED
|
|
441
|
-
|
|
438
|
+
// 10-22-2020 - Add OtherVotes
|
|
442
439
|
let stateDemVote = 0;
|
|
443
440
|
let stateRepVote = 0;
|
|
441
|
+
let stateOthVote = 0;
|
|
442
|
+
let stateTotVote = 0;
|
|
443
|
+
// let stateTPVote = 0;
|
|
444
444
|
let stateVAPPop = 0;
|
|
445
445
|
let stateWhitePop = 0;
|
|
446
446
|
let stateMinorityPop = 0;
|
|
@@ -454,15 +454,17 @@ class Districts {
|
|
|
454
454
|
// - Complete (bNotEmpty)
|
|
455
455
|
// - Contiguous (bContiguous)
|
|
456
456
|
// - Free of holes (bNotEmbedded)
|
|
457
|
-
// 2 - MORE ...
|
|
458
457
|
// Loop over the districts (including the dummy unassigned one)
|
|
459
458
|
for (let i = 0; i < this.numberOfWorkingDistricts(); i++) {
|
|
460
459
|
// INITIALIZE DISTRICT VALUES THAT WILL BE ACCUMULATED (VS. DERIVED)
|
|
461
460
|
let featurePop;
|
|
462
461
|
let totalPop = 0;
|
|
463
462
|
let countySplits = U.initArray(nCountyBuckets, 0);
|
|
463
|
+
// 10-22-2020 - Add OtherVotes
|
|
464
464
|
let demVotes = 0;
|
|
465
465
|
let repVotes = 0;
|
|
466
|
+
let othVotes = 0;
|
|
467
|
+
let totVotes = 0;
|
|
466
468
|
let totalVAP = 0;
|
|
467
469
|
let whitePop = 0;
|
|
468
470
|
let blackPop = 0;
|
|
@@ -517,8 +519,13 @@ class Districts {
|
|
|
517
519
|
console.log("County not recognized:", geoID);
|
|
518
520
|
}
|
|
519
521
|
// Democratic and Republican vote totals
|
|
522
|
+
// 10-22-2020 - Add OtherVotes
|
|
520
523
|
demVotes += outerThis._session.features.fieldForFeature(f, "ELECTION" /* ELECTION */, "D" /* DemVotes */);
|
|
521
524
|
repVotes += outerThis._session.features.fieldForFeature(f, "ELECTION" /* ELECTION */, "R" /* RepVotes */);
|
|
525
|
+
totVotes += outerThis._session.features.fieldForFeature(f, "ELECTION" /* ELECTION */, "Tot" /* TotalVotes */);
|
|
526
|
+
// NOTE: Unless you grab the values above before accumulating them,
|
|
527
|
+
// you can't accumulate othVotes for districts. You must calculate
|
|
528
|
+
// them by implication later.
|
|
522
529
|
// Voting-age demographic breakdowns (or citizen voting-age)
|
|
523
530
|
totalVAP += outerThis._session.features.fieldForFeature(f, "VAP" /* VAP */, "Tot" /* TotalPop */);
|
|
524
531
|
whitePop += outerThis._session.features.fieldForFeature(f, "VAP" /* VAP */, "Wh" /* WhitePop */);
|
|
@@ -527,7 +534,6 @@ class Districts {
|
|
|
527
534
|
pacificPop += outerThis._session.features.fieldForFeature(f, "VAP" /* VAP */, "PacC" /* PacificPop */);
|
|
528
535
|
asianPop += outerThis._session.features.fieldForFeature(f, "VAP" /* VAP */, "AsnC" /* AsianPop */);
|
|
529
536
|
nativePop += outerThis._session.features.fieldForFeature(f, "VAP" /* VAP */, "NatC" /* NativePop */);
|
|
530
|
-
// 4 - MORE ...
|
|
531
537
|
}
|
|
532
538
|
}
|
|
533
539
|
else {
|
|
@@ -543,16 +549,18 @@ class Districts {
|
|
|
543
549
|
bEqualPop = (Math.abs(popDevPct) <= deviationThreshold);
|
|
544
550
|
}
|
|
545
551
|
}
|
|
546
|
-
//
|
|
547
|
-
//
|
|
548
|
-
let totVotes;
|
|
552
|
+
// 10-22-2020 - Add OtherVotes. Revised from two-party to include Other.
|
|
553
|
+
// let totVotes: number; <<< Now being accumulated by district
|
|
549
554
|
let demPct = 0;
|
|
550
555
|
let repPct = 0;
|
|
556
|
+
let othPct = 0;
|
|
551
557
|
let DemSeat = 0;
|
|
552
|
-
totVotes = demVotes + repVotes;
|
|
558
|
+
// totVotes = demVotes + repVotes; <<< Now being accumulated by district
|
|
553
559
|
if (totVotes > 0) {
|
|
560
|
+
othVotes = totVotes - demVotes - repVotes;
|
|
554
561
|
demPct = demVotes / totVotes;
|
|
555
562
|
repPct = repVotes / totVotes;
|
|
563
|
+
othPct = othVotes / totVotes;
|
|
556
564
|
DemSeat = political_1.fptpWin(demPct);
|
|
557
565
|
}
|
|
558
566
|
// Total minority VAP
|
|
@@ -574,7 +582,6 @@ class Districts {
|
|
|
574
582
|
asianPct = asianPop / totalVAP;
|
|
575
583
|
nativePct = nativePop / totalVAP;
|
|
576
584
|
}
|
|
577
|
-
// 5 - MORE ...
|
|
578
585
|
// COMPUTE DISTRICT-LEVEL VALUES
|
|
579
586
|
// Validations
|
|
580
587
|
// Leave the default values for the dummy unassigned district,
|
|
@@ -590,7 +597,6 @@ class Districts {
|
|
|
590
597
|
bContiguous = G.isConnected(features, nakedGraph);
|
|
591
598
|
bNotEmbedded = (!G.isEmbedded(i, features, nakedPlan, nakedGraph));
|
|
592
599
|
}
|
|
593
|
-
// 6 - MORE ...
|
|
594
600
|
{ // UPDATE THE DISTRICT STATISTICS
|
|
595
601
|
// NOTE - These are set below for both non-empty & empty districts:
|
|
596
602
|
// this.statistics[DistrictField.bNotEmpty][i] = bNotEmpty;
|
|
@@ -599,11 +605,14 @@ class Districts {
|
|
|
599
605
|
// this.statistics[DistrictField.TotalPop][i] = totalPop;
|
|
600
606
|
// this.statistics[DistrictField.bEqualPop][i] = bEqualPop;
|
|
601
607
|
this.statistics[DistrictField.PopDevPct][i] = popDevPct;
|
|
608
|
+
// 10-22-2020 - Add OtherVotes
|
|
602
609
|
this.statistics[DistrictField.DemVotes][i] = demVotes;
|
|
603
610
|
this.statistics[DistrictField.RepVotes][i] = repVotes;
|
|
604
|
-
this.statistics[DistrictField.
|
|
611
|
+
this.statistics[DistrictField.OtherVotes][i] = othVotes;
|
|
612
|
+
// this.statistics[DistrictField.TwoPartyVote][i] = totVotes;
|
|
605
613
|
this.statistics[DistrictField.DemPct][i] = demPct;
|
|
606
614
|
this.statistics[DistrictField.RepPct][i] = repPct;
|
|
615
|
+
this.statistics[DistrictField.OtherPct][i] = othPct;
|
|
607
616
|
this.statistics[DistrictField.DemSeat][i] = DemSeat;
|
|
608
617
|
this.statistics[DistrictField.WhitePop][i] = whitePop;
|
|
609
618
|
this.statistics[DistrictField.MinorityPop][i] = minorityPop;
|
|
@@ -621,11 +630,13 @@ class Districts {
|
|
|
621
630
|
this.statistics[DistrictField.AsianPct][i] = asianPct;
|
|
622
631
|
this.statistics[DistrictField.NativePct][i] = nativePct;
|
|
623
632
|
}
|
|
624
|
-
// 7 - MORE ...
|
|
625
633
|
{ // ACCUMULATE STATE STATISTICS FROM DISTRICT TOTALS
|
|
626
|
-
|
|
634
|
+
// 10-22-2020 - Add OtherVotes
|
|
635
|
+
stateTotVote += totVotes;
|
|
636
|
+
// stateTPVote += totVotes;
|
|
627
637
|
stateDemVote += demVotes;
|
|
628
638
|
stateRepVote += repVotes;
|
|
639
|
+
stateOthVote += othVotes;
|
|
629
640
|
stateVAPPop += totalVAP;
|
|
630
641
|
stateWhitePop += whitePop;
|
|
631
642
|
stateMinorityPop += minorityPop;
|
|
@@ -638,11 +649,14 @@ class Districts {
|
|
|
638
649
|
}
|
|
639
650
|
else { // If a district is empty, zero these results (vs. null)
|
|
640
651
|
this.statistics[DistrictField.PopDevPct][i] = popDevPct;
|
|
652
|
+
// 10-22-2020 - Add OtherVotes
|
|
641
653
|
this.statistics[DistrictField.DemVotes][i] = 0;
|
|
642
654
|
this.statistics[DistrictField.RepVotes][i] = 0;
|
|
643
|
-
this.statistics[DistrictField.
|
|
655
|
+
this.statistics[DistrictField.OtherVotes][i] = 0;
|
|
656
|
+
// this.statistics[DistrictField.TwoPartyVote][i] = 0;
|
|
644
657
|
this.statistics[DistrictField.DemPct][i] = 0;
|
|
645
658
|
this.statistics[DistrictField.RepPct][i] = 0;
|
|
659
|
+
this.statistics[DistrictField.OtherPct][i] = 0;
|
|
646
660
|
this.statistics[DistrictField.DemSeat][i] = 0;
|
|
647
661
|
this.statistics[DistrictField.WhitePop][i] = 0;
|
|
648
662
|
this.statistics[DistrictField.MinorityPop][i] = 0;
|
|
@@ -671,9 +685,13 @@ class Districts {
|
|
|
671
685
|
}
|
|
672
686
|
// UPDATE STATE STATISTICS
|
|
673
687
|
let summaryRow = this.numberOfRows() - 1;
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
this.statistics[DistrictField.
|
|
688
|
+
// 10-22-2020 - Add OtherVotes
|
|
689
|
+
if (stateTotVote > 0) {
|
|
690
|
+
this.statistics[DistrictField.DemVotes][summaryRow] = stateDemVote;
|
|
691
|
+
this.statistics[DistrictField.RepVotes][summaryRow] = stateRepVote;
|
|
692
|
+
this.statistics[DistrictField.DemPct][summaryRow] = stateDemVote / stateTotVote;
|
|
693
|
+
this.statistics[DistrictField.RepPct][summaryRow] = stateRepVote / stateTotVote;
|
|
694
|
+
this.statistics[DistrictField.OtherPct][summaryRow] = stateOthVote / stateTotVote;
|
|
677
695
|
}
|
|
678
696
|
if (stateVAPPop > 0) {
|
|
679
697
|
this.statistics[DistrictField.TotalVAP][summaryRow] = stateVAPPop;
|
|
@@ -1264,7 +1282,7 @@ function scoreKIWYSICompactness(s, bLog = false) {
|
|
|
1264
1282
|
}
|
|
1265
1283
|
const scores = Compactness.scoreShapes(goodShapes);
|
|
1266
1284
|
// 10-21-2020
|
|
1267
|
-
// - Return all by
|
|
1285
|
+
// - Return all by-district scores instead of just the average.
|
|
1268
1286
|
// - Round & invert the scores here at the source vs. later on, higher up.
|
|
1269
1287
|
return scores.map(n => 100 - Math.round(n));
|
|
1270
1288
|
// const avgKIWYSIScore: number = U.avgArray(scores);
|
|
@@ -1913,6 +1931,7 @@ const D = __importStar(__webpack_require__(/*! ./_data */ "./src/_data.ts"));
|
|
|
1913
1931
|
const M = __importStar(__webpack_require__(/*! ./minority */ "./src/minority.ts"));
|
|
1914
1932
|
const C = __importStar(__webpack_require__(/*! ./compact */ "./src/compact.ts"));
|
|
1915
1933
|
// PROFILE A PLAN
|
|
1934
|
+
const KEEP_DECIMALS = 6;
|
|
1916
1935
|
function profilePlan(s, bLog = false) {
|
|
1917
1936
|
const state = s.state.xx;
|
|
1918
1937
|
const planName = s.title;
|
|
@@ -1923,8 +1942,22 @@ function profilePlan(s, bLog = false) {
|
|
|
1923
1942
|
const geoPropsByDistrict = makeArrayOfGeoProps(s, bLog);
|
|
1924
1943
|
const splits = makeNakedCxD(s);
|
|
1925
1944
|
const summaryRow = s.districts.numberOfRows() - 1;
|
|
1926
|
-
|
|
1927
|
-
const
|
|
1945
|
+
// 10-22-2020 - TODO: Convert Dem + Rep + Other = Total to two-party vote shares for analytics.
|
|
1946
|
+
const demVote = s.districts.statistics[D.DistrictField.DemVotes][summaryRow];
|
|
1947
|
+
const repVote = s.districts.statistics[D.DistrictField.RepVotes][summaryRow];
|
|
1948
|
+
const statewideVf = U.trim(demVote / (demVote + repVote), KEEP_DECIMALS);
|
|
1949
|
+
// const statewideVf: number = U.trim(s.districts.statistics[D.DistrictField.DemPct][summaryRow], 6);
|
|
1950
|
+
let vpiArray = [];
|
|
1951
|
+
const demVotes = U.deepCopy(s.districts.statistics[D.DistrictField.DemVotes].slice(1, -1));
|
|
1952
|
+
const repVotes = U.deepCopy(s.districts.statistics[D.DistrictField.RepVotes].slice(1, -1));
|
|
1953
|
+
for (let districtID = 1; districtID <= nDistricts; districtID++) {
|
|
1954
|
+
const D = demVotes[districtID - 1];
|
|
1955
|
+
const R = repVotes[districtID - 1];
|
|
1956
|
+
const T = D + R;
|
|
1957
|
+
const v = (T > 0) ? U.trim(D / T, KEEP_DECIMALS) : 0;
|
|
1958
|
+
vpiArray.push(v);
|
|
1959
|
+
}
|
|
1960
|
+
// const vpiArray: number[] = U.deepCopy(s.districts.statistics[D.DistrictField.DemPct].slice(1, -1)) as number[];
|
|
1928
1961
|
const statewideDemographics = getStatewideDemographics(s);
|
|
1929
1962
|
const demographicsByDistrict = getDemographicsByDistrict(s);
|
|
1930
1963
|
const profile = {
|
|
@@ -1974,9 +2007,9 @@ function makeArrayOfGeoProps(s, bLog = false) {
|
|
|
1974
2007
|
let districtProps = s.districts.getGeoProperties(districtID);
|
|
1975
2008
|
// Guard against no shape and no properties
|
|
1976
2009
|
if (districtProps) {
|
|
1977
|
-
let a = districtProps[0 /* Area */];
|
|
1978
|
-
let p = districtProps[2 /* Perimeter */];
|
|
1979
|
-
let d = districtProps[1 /* Diameter */];
|
|
2010
|
+
let a = U.trim(districtProps[0 /* Area */], KEEP_DECIMALS);
|
|
2011
|
+
let p = U.trim(districtProps[2 /* Perimeter */], KEEP_DECIMALS);
|
|
2012
|
+
let d = U.trim(districtProps[1 /* Diameter */], KEEP_DECIMALS);
|
|
1980
2013
|
// Save each triple
|
|
1981
2014
|
geometryByDistrict.push([a, p, d]);
|
|
1982
2015
|
}
|
|
@@ -1988,13 +2021,13 @@ function getDemographicsByDistrict(s, bLog = false) {
|
|
|
1988
2021
|
// Remove the unassigned & total dummy "districts"
|
|
1989
2022
|
for (let districtID = 1; districtID <= s.state.nDistricts; districtID++) {
|
|
1990
2023
|
const districtDemographics = [
|
|
1991
|
-
U.
|
|
1992
|
-
U.
|
|
1993
|
-
U.
|
|
1994
|
-
U.
|
|
1995
|
-
U.
|
|
1996
|
-
U.
|
|
1997
|
-
U.
|
|
2024
|
+
U.trim(s.districts.statistics[D.DistrictField.WhitePct][districtID], KEEP_DECIMALS),
|
|
2025
|
+
U.trim(s.districts.statistics[D.DistrictField.MinorityPct][districtID], KEEP_DECIMALS),
|
|
2026
|
+
U.trim(s.districts.statistics[D.DistrictField.BlackPct][districtID], KEEP_DECIMALS),
|
|
2027
|
+
U.trim(s.districts.statistics[D.DistrictField.HispanicPct][districtID], KEEP_DECIMALS),
|
|
2028
|
+
U.trim(s.districts.statistics[D.DistrictField.PacificPct][districtID], KEEP_DECIMALS),
|
|
2029
|
+
U.trim(s.districts.statistics[D.DistrictField.AsianPct][districtID], KEEP_DECIMALS),
|
|
2030
|
+
U.trim(s.districts.statistics[D.DistrictField.NativePct][districtID], KEEP_DECIMALS)
|
|
1998
2031
|
];
|
|
1999
2032
|
demographicsArray.push(districtDemographics);
|
|
2000
2033
|
}
|
|
@@ -2003,13 +2036,13 @@ function getDemographicsByDistrict(s, bLog = false) {
|
|
|
2003
2036
|
function getStatewideDemographics(s, bLog = false) {
|
|
2004
2037
|
const summaryRow = s.districts.numberOfRows() - 1;
|
|
2005
2038
|
const demographicsArray = [
|
|
2006
|
-
U.
|
|
2007
|
-
U.
|
|
2008
|
-
U.
|
|
2009
|
-
U.
|
|
2010
|
-
U.
|
|
2011
|
-
U.
|
|
2012
|
-
U.
|
|
2039
|
+
U.trim(s.districts.statistics[D.DistrictField.WhitePct][summaryRow], KEEP_DECIMALS),
|
|
2040
|
+
U.trim(s.districts.statistics[D.DistrictField.MinorityPct][summaryRow], KEEP_DECIMALS),
|
|
2041
|
+
U.trim(s.districts.statistics[D.DistrictField.BlackPct][summaryRow], KEEP_DECIMALS),
|
|
2042
|
+
U.trim(s.districts.statistics[D.DistrictField.HispanicPct][summaryRow], KEEP_DECIMALS),
|
|
2043
|
+
U.trim(s.districts.statistics[D.DistrictField.PacificPct][summaryRow], KEEP_DECIMALS),
|
|
2044
|
+
U.trim(s.districts.statistics[D.DistrictField.AsianPct][summaryRow], KEEP_DECIMALS),
|
|
2045
|
+
U.trim(s.districts.statistics[D.DistrictField.NativePct][summaryRow], KEEP_DECIMALS)
|
|
2013
2046
|
];
|
|
2014
2047
|
return demographicsArray;
|
|
2015
2048
|
}
|
|
@@ -2043,8 +2076,8 @@ function scorePlan(s, p, bLog = false, overridesJSON) {
|
|
|
2043
2076
|
const avgKIWYSIScore = Math.round(U.avgArray(kiwysiScores));
|
|
2044
2077
|
scorecard.compactness.details['kiwysi'] = avgKIWYSIScore;
|
|
2045
2078
|
// 10-21-2020 - Add KIWYSI scores to the by-district details
|
|
2046
|
-
const nDistricts = s.state.nDistricts;
|
|
2047
2079
|
let byDistrict = scorecard.compactness.details['byDistrict'];
|
|
2080
|
+
const nDistricts = byDistrict.length;
|
|
2048
2081
|
for (let districtID = 1; districtID <= nDistricts; districtID++) {
|
|
2049
2082
|
byDistrict[districtID - 1].kiwysiScore = kiwysiScores[districtID - 1];
|
|
2050
2083
|
}
|