@dra2020/district-analytics 9.3.1 → 9.4.2

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.
@@ -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 - Added Other votes
354
355
  DistrictField[DistrictField["DemVotes"] = 7] = "DemVotes";
355
356
  DistrictField[DistrictField["RepVotes"] = 8] = "RepVotes";
356
- DistrictField[DistrictField["TwoPartyVote"] = 9] = "TwoPartyVote";
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["DemSeat"] = 12] = "DemSeat";
360
- DistrictField[DistrictField["TotalVAP"] = 13] = "TotalVAP";
361
- DistrictField[DistrictField["MinorityPop"] = 14] = "MinorityPop";
362
- DistrictField[DistrictField["WhitePop"] = 15] = "WhitePop";
363
- DistrictField[DistrictField["BlackPop"] = 16] = "BlackPop";
364
- DistrictField[DistrictField["HispanicPop"] = 17] = "HispanicPop";
365
- DistrictField[DistrictField["PacificPop"] = 18] = "PacificPop";
366
- DistrictField[DistrictField["AsianPop"] = 19] = "AsianPop";
367
- DistrictField[DistrictField["NativePop"] = 20] = "NativePop";
368
- DistrictField[DistrictField["WhitePct"] = 21] = "WhitePct";
369
- DistrictField[DistrictField["MinorityPct"] = 22] = "MinorityPct";
370
- DistrictField[DistrictField["BlackPct"] = 23] = "BlackPct";
371
- DistrictField[DistrictField["HispanicPct"] = 24] = "HispanicPct";
372
- DistrictField[DistrictField["PacificPct"] = 25] = "PacificPct";
373
- DistrictField[DistrictField["AsianPct"] = 26] = "AsianPct";
374
- DistrictField[DistrictField["NativePct"] = 27] = "NativePct"; // Display
375
- // 1 - MORE ...
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
- let stateTPVote = 0;
438
+ // 10-22-2020 - Added Other votes
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 - Added Other votes
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 - Added Other votes
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
- // Total two-party (not total total!) votes, Democratic and Republican vote
547
- // shares, and Democratic first-past-the-post win (= 1) or loss (= 0).
548
- let totVotes;
552
+ // 10-22-2020 - Added Other votes. 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 - Added Other votes
602
609
  this.statistics[DistrictField.DemVotes][i] = demVotes;
603
610
  this.statistics[DistrictField.RepVotes][i] = repVotes;
604
- this.statistics[DistrictField.TwoPartyVote][i] = totVotes;
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
- stateTPVote += totVotes;
634
+ // 10-22-2020 - Added Other votes
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 - Added Other votes
641
653
  this.statistics[DistrictField.DemVotes][i] = 0;
642
654
  this.statistics[DistrictField.RepVotes][i] = 0;
643
- this.statistics[DistrictField.TwoPartyVote][i] = 0;
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
- if (stateTPVote > 0) {
675
- this.statistics[DistrictField.DemPct][summaryRow] = stateDemVote / stateTPVote;
676
- this.statistics[DistrictField.RepPct][summaryRow] = stateRepVote / stateTPVote;
688
+ // 10-22-2020 - Added Other votes
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,7 @@ function scoreKIWYSICompactness(s, bLog = false) {
1263
1281
  }
1264
1282
  }
1265
1283
  const scores = Compactness.scoreShapes(goodShapes);
1266
- // 10-21-2020
1267
- // - Return all by-district scores instead of just the average.
1284
+ // 10-21-2020 - Returned all by-district scores instead of just the average.
1268
1285
  // - Round & invert the scores here at the source vs. later on, higher up.
1269
1286
  return scores.map(n => 100 - Math.round(n));
1270
1287
  // const avgKIWYSIScore: number = U.avgArray(scores);
@@ -1703,32 +1720,34 @@ function prepareRequirementsChecklist(s, bLog = false) {
1703
1720
  return paRequirements;
1704
1721
  }
1705
1722
  exports.prepareRequirementsChecklist = prepareRequirementsChecklist;
1706
- // Example
1707
- exports.sampleDistrictStatistics = {
1708
- table: [
1709
- // District 0 is the dummy unassigned district
1710
- // HACK - Total VAP #'s at the end are just so the same matches the type
1711
- [0, 0, 0, null, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
1712
- [1, 653133, -0.0950, 0 /* Green */, 2 /* Red */, 0 /* Green */, 0 /* Green */, 0.4177, 0.5823, 0.8631, 0.1369, 0.0734, 0.0360, 0.0009, 0.0235, 0.0064, 50000],
1713
- [2, 620961, -0.1396, 0 /* Green */, 2 /* Red */, 2 /* Red */, 0 /* Green */, 0.8820, 0.1180, 0.3129, 0.6871, 0.6169, 0.0391, 0.0013, 0.0310, 0.0099, 50000],
1714
- [3, 971777, 0.3465, 0 /* Green */, 2 /* Red */, 0 /* Green */, 0 /* Green */, 0.7261, 0.2739, 0.5174, 0.4826, 0.1745, 0.1572, 0.0020, 0.1531, 0.0090, 50000],
1715
- [4, 863420, 0.1964, 0 /* Green */, 2 /* Red */, 0 /* Green */, 0 /* Green */, 0.8957, 0.1043, 0.1734, 0.8266, 0.6489, 0.1348, 0.0020, 0.0496, 0.0127, 50000],
1716
- [5, 805029, 0.1155, 0 /* Green */, 2 /* Red */, 0 /* Green */, 1 /* Yellow */, 0.5743, 0.4257, 0.6587, 0.3413, 0.2494, 0.0363, 0.0012, 0.0536, 0.0081, 50000],
1717
- [6, 824741, 0.1428, 0 /* Green */, 2 /* Red */, 0 /* Green */, 2 /* Red */, 0.5341, 0.4659, 0.7045, 0.2955, 0.1619, 0.0526, 0.0018, 0.0782, 0.0090, 50000],
1718
- [7, 549714, -0.2383, 0 /* Green */, 0 /* Green */, 0 /* Green */, 0 /* Green */, 0.5025, 0.4975, 0.6906, 0.3094, 0.2468, 0.0319, 0.0013, 0.0258, 0.0111, 50000],
1719
- [8, 484777, -0.3283, 0 /* Green */, 0 /* Green */, 0 /* Green */, 0 /* Green */, 0.4105, 0.5895, 0.8370, 0.1630, 0.1074, 0.0316, 0.0013, 0.0197, 0.0077, 50000],
1720
- // District N+1 is the dummy state-summary district
1721
- [9, 721694, 0.6748, 0 /* Green */, 2 /* Red */, 2 /* Red */, 2 /* Red */, 0.6293, 0.3707, 0.5722, 0.4278, 0.2925, 0.0729, 0.0015, 0.0618, 0.0093, 400000]
1722
- ],
1723
- details: {},
1724
- datasets: {
1725
- shapes: "2010 VTD shapes",
1726
- census: "2010 Census Total Population",
1727
- vap: "2010 Voting Age Population",
1728
- election: "2016 Presidential, US Senate, Governor, and AG election results"
1729
- },
1730
- resources: {}
1731
- };
1723
+ /* 10-23-2020 - Removed the district statistics sample.
1724
+
1725
+ export const sampleDistrictStatistics: DistrictStatistics = {
1726
+ table: [
1727
+ // District 0 is the dummy unassigned district
1728
+ // HACK - Total VAP #'s at the end are just so the same matches the type
1729
+ [0, 0, 0, null, null, null, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
1730
+ [1, 653133, -0.0950, T.TriState.Green, T.TriState.Red, T.TriState.Green, T.TriState.Green, 0.4177, 0.5823, 0.8631, 0.1369, 0.0734, 0.0360, 0.0009, 0.0235, 0.0064, 50000],
1731
+ [2, 620961, -0.1396, T.TriState.Green, T.TriState.Red, T.TriState.Red, T.TriState.Green, 0.8820, 0.1180, 0.3129, 0.6871, 0.6169, 0.0391, 0.0013, 0.0310, 0.0099, 50000],
1732
+ [3, 971777, 0.3465, T.TriState.Green, T.TriState.Red, T.TriState.Green, T.TriState.Green, 0.7261, 0.2739, 0.5174, 0.4826, 0.1745, 0.1572, 0.0020, 0.1531, 0.0090, 50000],
1733
+ [4, 863420, 0.1964, T.TriState.Green, T.TriState.Red, T.TriState.Green, T.TriState.Green, 0.8957, 0.1043, 0.1734, 0.8266, 0.6489, 0.1348, 0.0020, 0.0496, 0.0127, 50000],
1734
+ [5, 805029, 0.1155, T.TriState.Green, T.TriState.Red, T.TriState.Green, T.TriState.Yellow, 0.5743, 0.4257, 0.6587, 0.3413, 0.2494, 0.0363, 0.0012, 0.0536, 0.0081, 50000],
1735
+ [6, 824741, 0.1428, T.TriState.Green, T.TriState.Red, T.TriState.Green, T.TriState.Red, 0.5341, 0.4659, 0.7045, 0.2955, 0.1619, 0.0526, 0.0018, 0.0782, 0.0090, 50000],
1736
+ [7, 549714, -0.2383, T.TriState.Green, T.TriState.Green, T.TriState.Green, T.TriState.Green, 0.5025, 0.4975, 0.6906, 0.3094, 0.2468, 0.0319, 0.0013, 0.0258, 0.0111, 50000],
1737
+ [8, 484777, -0.3283, T.TriState.Green, T.TriState.Green, T.TriState.Green, T.TriState.Green, 0.4105, 0.5895, 0.8370, 0.1630, 0.1074, 0.0316, 0.0013, 0.0197, 0.0077, 50000],
1738
+ // District N+1 is the dummy state-summary district
1739
+ [9, 721694, 0.6748, T.TriState.Green, T.TriState.Red, T.TriState.Red, T.TriState.Red, 0.6293, 0.3707, 0.5722, 0.4278, 0.2925, 0.0729, 0.0015, 0.0618, 0.0093, 400000]
1740
+ ],
1741
+ details: {},
1742
+ datasets: {
1743
+ shapes: "2010 VTD shapes",
1744
+ census: "2010 Census Total Population",
1745
+ vap: "2010 Voting Age Population",
1746
+ election: "2016 Presidential, US Senate, Governor, and AG election results"
1747
+ },
1748
+ resources: {}
1749
+ }
1750
+ */
1732
1751
  // Create a DistrictStatistics instance, deep copying the underlying values.
1733
1752
  function prepareDistrictStatistics(s, bLog = false) {
1734
1753
  if (!(s.bPostProcessingDone)) {
@@ -1746,6 +1765,8 @@ function prepareDistrictStatistics(s, bLog = false) {
1746
1765
  s.districts.statistics[D.DistrictField.bNotEmbedded][i],
1747
1766
  s.districts.statistics[D.DistrictField.DemPct][i],
1748
1767
  s.districts.statistics[D.DistrictField.RepPct][i],
1768
+ // 10-23-2020 - Added Other vote percentage
1769
+ s.districts.statistics[D.DistrictField.OtherPct][i],
1749
1770
  s.districts.statistics[D.DistrictField.WhitePct][i],
1750
1771
  s.districts.statistics[D.DistrictField.MinorityPct][i],
1751
1772
  s.districts.statistics[D.DistrictField.BlackPct][i],
@@ -1913,6 +1934,7 @@ const D = __importStar(__webpack_require__(/*! ./_data */ "./src/_data.ts"));
1913
1934
  const M = __importStar(__webpack_require__(/*! ./minority */ "./src/minority.ts"));
1914
1935
  const C = __importStar(__webpack_require__(/*! ./compact */ "./src/compact.ts"));
1915
1936
  // PROFILE A PLAN
1937
+ const KEEP_DECIMALS = 6;
1916
1938
  function profilePlan(s, bLog = false) {
1917
1939
  const state = s.state.xx;
1918
1940
  const planName = s.title;
@@ -1923,8 +1945,22 @@ function profilePlan(s, bLog = false) {
1923
1945
  const geoPropsByDistrict = makeArrayOfGeoProps(s, bLog);
1924
1946
  const splits = makeNakedCxD(s);
1925
1947
  const summaryRow = s.districts.numberOfRows() - 1;
1926
- const statewideVf = U.trim(s.districts.statistics[D.DistrictField.DemPct][summaryRow], 6);
1927
- const vpiArray = U.deepCopy(s.districts.statistics[D.DistrictField.DemPct].slice(1, -1));
1948
+ // 10-22-2020 - Converted Dem + Rep + Other = Total to two-party vote shares for analytics.
1949
+ const demVote = s.districts.statistics[D.DistrictField.DemVotes][summaryRow];
1950
+ const repVote = s.districts.statistics[D.DistrictField.RepVotes][summaryRow];
1951
+ const statewideVf = U.trim(demVote / (demVote + repVote), KEEP_DECIMALS);
1952
+ // const statewideVf: number = U.trim(s.districts.statistics[D.DistrictField.DemPct][summaryRow], 6);
1953
+ let vpiArray = [];
1954
+ const demVotes = U.deepCopy(s.districts.statistics[D.DistrictField.DemVotes].slice(1, -1));
1955
+ const repVotes = U.deepCopy(s.districts.statistics[D.DistrictField.RepVotes].slice(1, -1));
1956
+ for (let districtID = 1; districtID <= nDistricts; districtID++) {
1957
+ const D = demVotes[districtID - 1];
1958
+ const R = repVotes[districtID - 1];
1959
+ const T = D + R;
1960
+ const v = (T > 0) ? U.trim(D / T, KEEP_DECIMALS) : 0;
1961
+ vpiArray.push(v);
1962
+ }
1963
+ // const vpiArray: number[] = U.deepCopy(s.districts.statistics[D.DistrictField.DemPct].slice(1, -1)) as number[];
1928
1964
  const statewideDemographics = getStatewideDemographics(s);
1929
1965
  const demographicsByDistrict = getDemographicsByDistrict(s);
1930
1966
  const profile = {
@@ -1974,9 +2010,9 @@ function makeArrayOfGeoProps(s, bLog = false) {
1974
2010
  let districtProps = s.districts.getGeoProperties(districtID);
1975
2011
  // Guard against no shape and no properties
1976
2012
  if (districtProps) {
1977
- let a = districtProps[0 /* Area */];
1978
- let p = districtProps[2 /* Perimeter */];
1979
- let d = districtProps[1 /* Diameter */];
2013
+ let a = U.trim(districtProps[0 /* Area */], KEEP_DECIMALS);
2014
+ let p = U.trim(districtProps[2 /* Perimeter */], KEEP_DECIMALS);
2015
+ let d = U.trim(districtProps[1 /* Diameter */], KEEP_DECIMALS);
1980
2016
  // Save each triple
1981
2017
  geometryByDistrict.push([a, p, d]);
1982
2018
  }
@@ -1988,13 +2024,13 @@ function getDemographicsByDistrict(s, bLog = false) {
1988
2024
  // Remove the unassigned & total dummy "districts"
1989
2025
  for (let districtID = 1; districtID <= s.state.nDistricts; districtID++) {
1990
2026
  const districtDemographics = [
1991
- U.deepCopy(s.districts.statistics[D.DistrictField.WhitePct][districtID]),
1992
- U.deepCopy(s.districts.statistics[D.DistrictField.MinorityPct][districtID]),
1993
- U.deepCopy(s.districts.statistics[D.DistrictField.BlackPct][districtID]),
1994
- U.deepCopy(s.districts.statistics[D.DistrictField.HispanicPct][districtID]),
1995
- U.deepCopy(s.districts.statistics[D.DistrictField.PacificPct][districtID]),
1996
- U.deepCopy(s.districts.statistics[D.DistrictField.AsianPct][districtID]),
1997
- U.deepCopy(s.districts.statistics[D.DistrictField.NativePct][districtID])
2027
+ U.trim(s.districts.statistics[D.DistrictField.WhitePct][districtID], KEEP_DECIMALS),
2028
+ U.trim(s.districts.statistics[D.DistrictField.MinorityPct][districtID], KEEP_DECIMALS),
2029
+ U.trim(s.districts.statistics[D.DistrictField.BlackPct][districtID], KEEP_DECIMALS),
2030
+ U.trim(s.districts.statistics[D.DistrictField.HispanicPct][districtID], KEEP_DECIMALS),
2031
+ U.trim(s.districts.statistics[D.DistrictField.PacificPct][districtID], KEEP_DECIMALS),
2032
+ U.trim(s.districts.statistics[D.DistrictField.AsianPct][districtID], KEEP_DECIMALS),
2033
+ U.trim(s.districts.statistics[D.DistrictField.NativePct][districtID], KEEP_DECIMALS)
1998
2034
  ];
1999
2035
  demographicsArray.push(districtDemographics);
2000
2036
  }
@@ -2003,13 +2039,13 @@ function getDemographicsByDistrict(s, bLog = false) {
2003
2039
  function getStatewideDemographics(s, bLog = false) {
2004
2040
  const summaryRow = s.districts.numberOfRows() - 1;
2005
2041
  const demographicsArray = [
2006
- U.deepCopy(s.districts.statistics[D.DistrictField.WhitePct][summaryRow]),
2007
- U.deepCopy(s.districts.statistics[D.DistrictField.MinorityPct][summaryRow]),
2008
- U.deepCopy(s.districts.statistics[D.DistrictField.BlackPct][summaryRow]),
2009
- U.deepCopy(s.districts.statistics[D.DistrictField.HispanicPct][summaryRow]),
2010
- U.deepCopy(s.districts.statistics[D.DistrictField.PacificPct][summaryRow]),
2011
- U.deepCopy(s.districts.statistics[D.DistrictField.AsianPct][summaryRow]),
2012
- U.deepCopy(s.districts.statistics[D.DistrictField.NativePct][summaryRow])
2042
+ U.trim(s.districts.statistics[D.DistrictField.WhitePct][summaryRow], KEEP_DECIMALS),
2043
+ U.trim(s.districts.statistics[D.DistrictField.MinorityPct][summaryRow], KEEP_DECIMALS),
2044
+ U.trim(s.districts.statistics[D.DistrictField.BlackPct][summaryRow], KEEP_DECIMALS),
2045
+ U.trim(s.districts.statistics[D.DistrictField.HispanicPct][summaryRow], KEEP_DECIMALS),
2046
+ U.trim(s.districts.statistics[D.DistrictField.PacificPct][summaryRow], KEEP_DECIMALS),
2047
+ U.trim(s.districts.statistics[D.DistrictField.AsianPct][summaryRow], KEEP_DECIMALS),
2048
+ U.trim(s.districts.statistics[D.DistrictField.NativePct][summaryRow], KEEP_DECIMALS)
2013
2049
  ];
2014
2050
  return demographicsArray;
2015
2051
  }
@@ -2039,10 +2075,10 @@ function scorePlan(s, p, bLog = false, overridesJSON) {
2039
2075
  try {
2040
2076
  // Add KIWYSI compactness score
2041
2077
  const kiwysiScores = C.scoreKIWYSICompactness(s, bLog);
2042
- // 10-21-2020 - Compute the average score here
2078
+ // 10-21-2020 - Computing the average score here
2043
2079
  const avgKIWYSIScore = Math.round(U.avgArray(kiwysiScores));
2044
2080
  scorecard.compactness.details['kiwysi'] = avgKIWYSIScore;
2045
- // 10-21-2020 - Add KIWYSI scores to the by-district details
2081
+ // 10-21-2020 - Added KIWYSI scores to the by-district details
2046
2082
  let byDistrict = scorecard.compactness.details['byDistrict'];
2047
2083
  const nDistricts = byDistrict.length;
2048
2084
  for (let districtID = 1; districtID <= nDistricts; districtID++) {