@dra2020/district-analytics 9.2.1 → 9.4.0
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 +109 -64
- package/dist/district-analytics.js.map +1 -1
- package/dist/src/_data.d.ts +18 -17
- package/dist/src/compact.d.ts +1 -1
- 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;
|
|
@@ -1263,8 +1281,12 @@ function scoreKIWYSICompactness(s, bLog = false) {
|
|
|
1263
1281
|
}
|
|
1264
1282
|
}
|
|
1265
1283
|
const scores = Compactness.scoreShapes(goodShapes);
|
|
1266
|
-
|
|
1267
|
-
|
|
1284
|
+
// 10-21-2020
|
|
1285
|
+
// - Return all by-district scores instead of just the average.
|
|
1286
|
+
// - Round & invert the scores here at the source vs. later on, higher up.
|
|
1287
|
+
return scores.map(n => 100 - Math.round(n));
|
|
1288
|
+
// const avgKIWYSIScore: number = U.avgArray(scores);
|
|
1289
|
+
// return avgKIWYSIScore;
|
|
1268
1290
|
}
|
|
1269
1291
|
exports.scoreKIWYSICompactness = scoreKIWYSICompactness;
|
|
1270
1292
|
// SAVE THESE NOTES, IN CASE WE NEED TO REWORK HOW WE PERFORM THESE CALCS.
|
|
@@ -1909,6 +1931,7 @@ const D = __importStar(__webpack_require__(/*! ./_data */ "./src/_data.ts"));
|
|
|
1909
1931
|
const M = __importStar(__webpack_require__(/*! ./minority */ "./src/minority.ts"));
|
|
1910
1932
|
const C = __importStar(__webpack_require__(/*! ./compact */ "./src/compact.ts"));
|
|
1911
1933
|
// PROFILE A PLAN
|
|
1934
|
+
const KEEP_DECIMALS = 6;
|
|
1912
1935
|
function profilePlan(s, bLog = false) {
|
|
1913
1936
|
const state = s.state.xx;
|
|
1914
1937
|
const planName = s.title;
|
|
@@ -1919,8 +1942,22 @@ function profilePlan(s, bLog = false) {
|
|
|
1919
1942
|
const geoPropsByDistrict = makeArrayOfGeoProps(s, bLog);
|
|
1920
1943
|
const splits = makeNakedCxD(s);
|
|
1921
1944
|
const summaryRow = s.districts.numberOfRows() - 1;
|
|
1922
|
-
|
|
1923
|
-
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[];
|
|
1924
1961
|
const statewideDemographics = getStatewideDemographics(s);
|
|
1925
1962
|
const demographicsByDistrict = getDemographicsByDistrict(s);
|
|
1926
1963
|
const profile = {
|
|
@@ -1970,9 +2007,9 @@ function makeArrayOfGeoProps(s, bLog = false) {
|
|
|
1970
2007
|
let districtProps = s.districts.getGeoProperties(districtID);
|
|
1971
2008
|
// Guard against no shape and no properties
|
|
1972
2009
|
if (districtProps) {
|
|
1973
|
-
let a = districtProps[0 /* Area */];
|
|
1974
|
-
let p = districtProps[2 /* Perimeter */];
|
|
1975
|
-
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);
|
|
1976
2013
|
// Save each triple
|
|
1977
2014
|
geometryByDistrict.push([a, p, d]);
|
|
1978
2015
|
}
|
|
@@ -1984,13 +2021,13 @@ function getDemographicsByDistrict(s, bLog = false) {
|
|
|
1984
2021
|
// Remove the unassigned & total dummy "districts"
|
|
1985
2022
|
for (let districtID = 1; districtID <= s.state.nDistricts; districtID++) {
|
|
1986
2023
|
const districtDemographics = [
|
|
1987
|
-
U.
|
|
1988
|
-
U.
|
|
1989
|
-
U.
|
|
1990
|
-
U.
|
|
1991
|
-
U.
|
|
1992
|
-
U.
|
|
1993
|
-
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)
|
|
1994
2031
|
];
|
|
1995
2032
|
demographicsArray.push(districtDemographics);
|
|
1996
2033
|
}
|
|
@@ -1999,13 +2036,13 @@ function getDemographicsByDistrict(s, bLog = false) {
|
|
|
1999
2036
|
function getStatewideDemographics(s, bLog = false) {
|
|
2000
2037
|
const summaryRow = s.districts.numberOfRows() - 1;
|
|
2001
2038
|
const demographicsArray = [
|
|
2002
|
-
U.
|
|
2003
|
-
U.
|
|
2004
|
-
U.
|
|
2005
|
-
U.
|
|
2006
|
-
U.
|
|
2007
|
-
U.
|
|
2008
|
-
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)
|
|
2009
2046
|
];
|
|
2010
2047
|
return demographicsArray;
|
|
2011
2048
|
}
|
|
@@ -2034,8 +2071,16 @@ function scorePlan(s, p, bLog = false, overridesJSON) {
|
|
|
2034
2071
|
scorecard.minority.details['vraPreclearance'] = M.getVRASection5(s);
|
|
2035
2072
|
try {
|
|
2036
2073
|
// Add KIWYSI compactness score
|
|
2037
|
-
const
|
|
2038
|
-
|
|
2074
|
+
const kiwysiScores = C.scoreKIWYSICompactness(s, bLog);
|
|
2075
|
+
// 10-21-2020 - Compute the average score here
|
|
2076
|
+
const avgKIWYSIScore = Math.round(U.avgArray(kiwysiScores));
|
|
2077
|
+
scorecard.compactness.details['kiwysi'] = avgKIWYSIScore;
|
|
2078
|
+
// 10-21-2020 - Add KIWYSI scores to the by-district details
|
|
2079
|
+
let byDistrict = scorecard.compactness.details['byDistrict'];
|
|
2080
|
+
const nDistricts = byDistrict.length;
|
|
2081
|
+
for (let districtID = 1; districtID <= nDistricts; districtID++) {
|
|
2082
|
+
byDistrict[districtID - 1].kiwysiScore = kiwysiScores[districtID - 1];
|
|
2083
|
+
}
|
|
2039
2084
|
}
|
|
2040
2085
|
catch (e) {
|
|
2041
2086
|
console.log("Exception caught scoring KIWYSI compactness.");
|