@dra2020/district-analytics 3.3.0 → 4.2.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.
@@ -1375,6 +1375,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
1375
1375
  const Poly = __importStar(__webpack_require__(/*! @dra2020/poly */ "@dra2020/poly"));
1376
1376
  const geofeature_1 = __webpack_require__(/*! ./geofeature */ "./src/geofeature.ts");
1377
1377
  const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
1378
+ // TODO - SCORE: Remove legacy code
1378
1379
  // Measures of compactness compare district shapes to various ideally compact
1379
1380
  // benchmarks, such as circles. All else equal, more compact districts are better.
1380
1381
  //
@@ -1670,6 +1671,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
1670
1671
  };
1671
1672
  Object.defineProperty(exports, "__esModule", { value: true });
1672
1673
  const Poly = __importStar(__webpack_require__(/*! @dra2020/poly */ "@dra2020/poly"));
1674
+ // TODO - SCORE: Remove legacy code
1673
1675
  // HELPER
1674
1676
  function polyParts(poly) {
1675
1677
  let parts = { type: 'FeatureCollection', features: [] };
@@ -1823,6 +1825,7 @@ __export(__webpack_require__(/*! ./types */ "./src/types.ts"));
1823
1825
  // PROTECTS MINORITIES
1824
1826
  //
1825
1827
  Object.defineProperty(exports, "__esModule", { value: true });
1828
+ // TODO - SCORE: Remove legacy code
1826
1829
  function doMajorityMinorityDistricts(s, bLog = false) {
1827
1830
  let test = s.getTest(16 /* MajorityMinorityDistricts */);
1828
1831
  if (bLog)
@@ -1861,6 +1864,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
1861
1864
  const assert_1 = __webpack_require__(/*! assert */ "assert");
1862
1865
  const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
1863
1866
  const D = __importStar(__webpack_require__(/*! ./_data */ "./src/_data.ts"));
1867
+ // TODO - SCORE: Remove legacy code
1864
1868
  // Partisan analytics need the following data:
1865
1869
  //
1866
1870
  // An "election model" by geo_id, where each item has 4 pieces of data:
@@ -2117,116 +2121,238 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
2117
2121
  };
2118
2122
  Object.defineProperty(exports, "__esModule", { value: true });
2119
2123
  const U = __importStar(__webpack_require__(/*! ./utils */ "./src/utils.ts"));
2124
+ const S = __importStar(__webpack_require__(/*! ./settings */ "./src/settings.ts"));
2120
2125
  const D = __importStar(__webpack_require__(/*! ./_data */ "./src/_data.ts"));
2121
2126
  const analyze_1 = __webpack_require__(/*! ./analyze */ "./src/analyze.ts");
2122
2127
  const state_reqs_json_1 = __importDefault(__webpack_require__(/*! ../static/state-reqs.json */ "./static/state-reqs.json"));
2123
- // Example
2124
- // TODO - DELETE?
2125
- let sampleRequirements = {
2126
- score: 2 /* Red */,
2127
- metrics: {
2128
- complete: 0 /* Green */,
2129
- contiguous: 2 /* Red */,
2130
- freeOfHoles: 1 /* Yellow */,
2131
- equalPopulation: 2 /* Red */
2132
- },
2133
- details: {
2134
- unassignedFeatures: [],
2135
- emptyDistricts: [],
2136
- discontiguousDistricts: [2],
2137
- embeddedDistricts: [],
2138
- populationDeviation: 0.6748,
2139
- deviationThreshold: 0.75 / 100
2140
- },
2141
- datasets: {
2142
- census: "2010 Census Total Population"
2143
- },
2144
- resources: {
2145
- stateReqs: "https://www.brennancenter.org/sites/default/files/publications/2019_06_50States_FINALsinglepages_20.pdf"
2146
- }
2128
+ // PLAN ANALYTICS
2129
+ /* TODO - DELETE
2130
+ export type RequirementsCategory = {
2131
+ score: T.TriState;
2132
+ metrics: {
2133
+ complete: T.TriState;
2134
+ contiguous: T.TriState;
2135
+ freeOfHoles: T.TriState;
2136
+ equalPopulation: T.TriState;
2137
+ };
2138
+ details: {
2139
+ unassignedFeatures: string[]; // A possibly empty list of GEOIDs
2140
+ emptyDistricts: number[]; // A possibly empty list of district IDs
2141
+ discontiguousDistricts: number[]; // Ditto
2142
+ embeddedDistricts: number[]; // Ditto
2143
+ populationDeviation: number; // A fraction [0.0 – 1.0] to represent as a %
2144
+ deviationThreshold: number; // A fraction [0.0 1.0] to represent as a %
2145
+ };
2146
+ datasets: T.Datasets;
2147
+ resources: {
2148
+ stateReqs: string;
2149
+ };
2147
2150
  };
2148
- // TODO - DELETE
2149
- let sampleCompactness = {
2150
- score: 60,
2151
- metrics: {
2152
- reock: 0.3773,
2153
- polsby: 0.3815
2154
- },
2155
- details: {},
2156
- datasets: {
2157
- shapes: "2010 VTD shapes"
2158
- },
2159
- resources: {}
2160
- };
2161
- // TODO - DELETE
2162
- let sampleSplitting = {
2163
- score: 73,
2164
- metrics: {
2165
- sqEnt_DCreduced: 1.531,
2166
- sqEnt_CDreduced: 1.760
2167
- },
2168
- details: {
2169
- countiesSplitUnexpectedly: [
2170
- "Bladen", "Buncombe", "Catawba", "Cumberland", "Durham", "Guilford", "Iredell", "Johnston", "Pitt", "Rowan", "Wilson"
2171
- ],
2172
- unexpectedAffected: 0.3096,
2173
- nSplitVTDs: 12,
2174
- splitVTDs: ["VTD-01", "VTD-02", "VTD-03", "VTD-04", "VTD-05", "VTD-06", "VTD-07", "VTD-08", "VTD-09", "VTD-10", "VTD-11", "VTD-12"]
2175
- },
2176
- datasets: {},
2177
- resources: {}
2151
+ */
2152
+ /* TODO - DELETE
2153
+ export type CompactnessCategory = {
2154
+ score: number; // An integer score [0–100]
2155
+ metrics: {
2156
+ reock: number; // A decimal number [0.0–1.0]
2157
+ polsby: number; // A decimal number [0.0–1.0]
2158
+ };
2159
+ details: {
2160
+ // None at this time
2161
+ };
2162
+ datasets: T.Datasets;
2163
+ resources: {
2164
+ // None at this time
2165
+ };
2178
2166
  };
2179
- // TODO - DELETE
2180
- let samplePartisan = {
2181
- score: 100,
2182
- metrics: {
2183
- partisanBias: 0.15,
2184
- responsiveness: 2.0
2185
- },
2186
- details: {},
2187
- datasets: {
2188
- election: "2016 Presidential, US Senate, Governor, and AG election results"
2189
- },
2190
- resources: {
2191
- planScore: "https://planscore.org/plan.html?20180219T202039.596761160Z"
2192
- }
2167
+ */
2168
+ /* TODO - DELETE
2169
+ export type SplittingCategory = {
2170
+ score: number; // An integer score [0–100]
2171
+ metrics: {
2172
+ sqEnt_DCreduced: number, // A decimal number [1.0 – < 2.0]
2173
+ sqEnt_CDreduced: number // A decimal number [1.0 – < 2.0]
2174
+ };
2175
+ details: {
2176
+ countiesSplitUnexpectedly: string[], // A possibly empty list of county names
2177
+ unexpectedAffected: number, // A fraction [0.0 – 1.0] to represent as a %
2178
+ nSplitVTDs: number, // An integer, possibly 0
2179
+ splitVTDs: string[] // A possibly empty list of GEOIDs
2180
+ };
2181
+ datasets: T.Datasets;
2182
+ resources: {
2183
+ // None at this time
2184
+ };
2193
2185
  };
2194
- // TODO - DELETE
2195
- let sampleMinority = {
2196
- score: null,
2197
- metrics: {
2198
- nBlack37to50: 1,
2199
- nBlackMajority: 12,
2200
- nHispanic37to50: 0,
2201
- nHispanicMajority: 0,
2202
- nPacific37to50: 0,
2203
- nPacificMajority: 0,
2204
- nAsian37to50: 0,
2205
- nAsianMajority: 0,
2206
- nNative37to50: 0,
2207
- nNativeMajority: 0,
2208
- nMinority37to50: 0,
2209
- nMinorityMajority: 0,
2210
- averageDVoteShare: 0.90
2211
- },
2212
- details: {
2213
- vap: true,
2214
- comboCategories: true
2215
- },
2216
- datasets: {
2217
- vap: "2010 Voting Age Population"
2218
- },
2219
- resources: {}
2186
+ */
2187
+ /* TODO - DELETE
2188
+ export type PartisanCategory = {
2189
+ score: number; // An integer score [0–100]
2190
+ metrics: {
2191
+ partisanBias: 0.15, // TBD
2192
+ responsiveness: 2.0 // TBD
2193
+ };
2194
+ details: {
2195
+ // TODO - Need to flesh this out
2196
+ };
2197
+ datasets: T.Datasets;
2198
+ resources: {
2199
+ planScore?: string;
2200
+ };
2220
2201
  };
2221
- // TODO - DELETE
2222
- exports.samplePlanAnalytics = {
2223
- requirements: sampleRequirements,
2224
- compactness: sampleCompactness,
2225
- // TODO - Don't show these categories yet
2226
- splitting: sampleSplitting,
2227
- partisan: samplePartisan,
2228
- minority: sampleMinority
2202
+ */
2203
+ /* TODO - DELETE
2204
+ export type MinorityCategory = {
2205
+ score: null; // Explicitly NOT scored
2206
+ metrics: {
2207
+ nBlack37to50: number, // Integer >= 0; two-digit maximum
2208
+ nBlackMajority: number, // Ditto
2209
+ nHispanic37to50: number, // Ditto
2210
+ nHispanicMajority: number, // Ditto
2211
+ nPacific37to50: number, // Ditto
2212
+ nPacificMajority: number, // Ditto
2213
+ nAsian37to50: number, // Ditto
2214
+ nAsianMajority: number, // Ditto
2215
+ nNative37to50: number, // Ditto
2216
+ nNativeMajority: number, // Ditto
2217
+ nMinority37to50: number, // Ditto
2218
+ nMinorityMajority: number, // Ditto
2219
+
2220
+ averageDVoteShare: number // A fraction [0.0 – 1.0] to represent as a %
2221
+ };
2222
+ details: {
2223
+ vap: true, // true = using VAP data; false = CVAP data
2224
+ comboCategories: true // true = using combo fields; false = mutually exclusive
2225
+ };
2226
+ datasets: T.Datasets;
2227
+ resources: {
2228
+ // TODO - Add these ...
2229
+ };
2229
2230
  };
2231
+ */
2232
+ /* TODO - DELETE
2233
+ export type PlanAnalytics = {
2234
+ requirements: RequirementsCategory;
2235
+ compactness: CompactnessCategory;
2236
+ // TODO - Don't show these categories yet
2237
+ splitting: SplittingCategory;
2238
+ partisan: PartisanCategory;
2239
+ minority: MinorityCategory;
2240
+ }
2241
+ */
2242
+ // EXAMPLE
2243
+ /* TODO - DELETE
2244
+ let sampleRequirements: RequirementsCategory = {
2245
+ score: T.TriState.Red,
2246
+ metrics: {
2247
+ complete: T.TriState.Green,
2248
+ contiguous: T.TriState.Red,
2249
+ freeOfHoles: T.TriState.Yellow,
2250
+ equalPopulation: T.TriState.Red
2251
+ },
2252
+ details: {
2253
+ unassignedFeatures: [],
2254
+ emptyDistricts: [],
2255
+ discontiguousDistricts: [2],
2256
+ embeddedDistricts: [],
2257
+ populationDeviation: 0.6748,
2258
+ deviationThreshold: 0.75 / 100
2259
+ },
2260
+ datasets: {
2261
+ census: "2010 Census Total Population"
2262
+ },
2263
+ resources: {
2264
+ stateReqs: "https://www.brennancenter.org/sites/default/files/publications/2019_06_50States_FINALsinglepages_20.pdf"
2265
+ }
2266
+ }
2267
+ */
2268
+ /* TODO - DELETE
2269
+ let sampleCompactness: CompactnessCategory = {
2270
+ score: 60,
2271
+ metrics: {
2272
+ reock: 0.3773,
2273
+ polsby: 0.3815
2274
+ },
2275
+ details: {},
2276
+ datasets: {
2277
+ shapes: "2010 VTD shapes"
2278
+ },
2279
+ resources: {}
2280
+ }
2281
+ */
2282
+ /* TODO - DELETE
2283
+ let sampleSplitting: SplittingCategory = {
2284
+ score: 73,
2285
+ metrics: {
2286
+ sqEnt_DCreduced: 1.531,
2287
+ sqEnt_CDreduced: 1.760
2288
+ },
2289
+ details: {
2290
+ countiesSplitUnexpectedly: [
2291
+ "Bladen", "Buncombe", "Catawba", "Cumberland", "Durham", "Guilford", "Iredell", "Johnston", "Pitt", "Rowan", "Wilson"
2292
+ ],
2293
+ unexpectedAffected: 0.3096,
2294
+ nSplitVTDs: 12,
2295
+ splitVTDs: ["VTD-01", "VTD-02", "VTD-03", "VTD-04", "VTD-05", "VTD-06", "VTD-07", "VTD-08", "VTD-09", "VTD-10", "VTD-11", "VTD-12"]
2296
+ },
2297
+ datasets: {},
2298
+ resources: {}
2299
+ }
2300
+ */
2301
+ /* TODO - DELETE
2302
+ let samplePartisan: PartisanCategory = {
2303
+ score: 100,
2304
+ metrics: {
2305
+ partisanBias: 0.15,
2306
+ responsiveness: 2.0
2307
+ },
2308
+ details: {},
2309
+ datasets: {
2310
+ election: "2016 Presidential, US Senate, Governor, and AG election results"
2311
+ },
2312
+ resources: {
2313
+ planScore: "https://planscore.org/plan.html?20180219T202039.596761160Z"
2314
+ }
2315
+ }
2316
+ */
2317
+ /* TODO - DELETE
2318
+ let sampleMinority: MinorityCategory = {
2319
+ score: null,
2320
+ metrics: {
2321
+ nBlack37to50: 1,
2322
+ nBlackMajority: 12,
2323
+ nHispanic37to50: 0,
2324
+ nHispanicMajority: 0,
2325
+ nPacific37to50: 0,
2326
+ nPacificMajority: 0,
2327
+ nAsian37to50: 0,
2328
+ nAsianMajority: 0,
2329
+ nNative37to50: 0,
2330
+ nNativeMajority: 0,
2331
+ nMinority37to50: 0,
2332
+ nMinorityMajority: 0,
2333
+
2334
+ averageDVoteShare: 0.90
2335
+ },
2336
+ details: {
2337
+ vap: true,
2338
+ comboCategories: true
2339
+ },
2340
+ datasets: {
2341
+ vap: "2010 Voting Age Population"
2342
+ },
2343
+ resources: {}
2344
+ }
2345
+ */
2346
+ /* TODO - DELETE
2347
+ export const samplePlanAnalytics: PlanAnalytics = {
2348
+ requirements: sampleRequirements,
2349
+ compactness: sampleCompactness,
2350
+ // TODO - Don't show these categories yet
2351
+ splitting: sampleSplitting,
2352
+ partisan: samplePartisan,
2353
+ minority: sampleMinority
2354
+ }
2355
+ */
2230
2356
  function prepareRequirementsChecklist(s, bLog = false) {
2231
2357
  if (!(s.bPostProcessingDone)) {
2232
2358
  doAnalyzePostProcessing(s);
@@ -2359,7 +2485,7 @@ function prepareDistrictStatistics(s, bLog = false) {
2359
2485
  // None at this time
2360
2486
  };
2361
2487
  let dsDatasets = {
2362
- shapes: "2010 VTD shapes",
2488
+ shapes: S.SHAPES,
2363
2489
  census: U.deepCopy(s.config['descriptions']['CENSUS']),
2364
2490
  vap: U.deepCopy(s.config['descriptions']['VAP']),
2365
2491
  election: U.deepCopy(s.config['descriptions']['ELECTION'])
@@ -2422,6 +2548,7 @@ const populationDeviationDefn = {
2422
2548
  externalType: TestType.Percentage,
2423
2549
  suites: [0 /* Legal */, 2 /* Best */] // Both so EqualPopulation can be assessed
2424
2550
  };
2551
+ // TODO - SCORE: Comment these out ...
2425
2552
  const reockDefn = {
2426
2553
  ID: 5 /* Reock */,
2427
2554
  name: "Reock",
@@ -2549,10 +2676,26 @@ function doAnalyzePostProcessing(s, bLog = false) {
2549
2676
  else {
2550
2677
  // Just populate the normalized population deviation score in the test
2551
2678
  const scorecard = s._scorecard;
2552
- let test = s.getTest(4 /* PopulationDeviation */);
2553
- test['normalizedScore'] = scorecard.traditionalPrinciples.populationDeviation.normalized;
2679
+ let popDev = s.getTest(4 /* PopulationDeviation */);
2680
+ popDev['normalizedScore'] = scorecard.traditionalPrinciples.populationDeviation.normalized;
2554
2681
  // TODO - DELETE
2555
2682
  // test['normalizedScore'] = scorecard.best.populationDeviation.normalized;
2683
+ // TODO - SCORE: Add datasets used to details by tab
2684
+ const datasets = {
2685
+ shapes: S.SHAPES,
2686
+ census: U.deepCopy(s.config['descriptions']['CENSUS']),
2687
+ vap: U.deepCopy(s.config['descriptions']['VAP']),
2688
+ election: U.deepCopy(s.config['descriptions']['ELECTION'])
2689
+ };
2690
+ scorecard.partisan.details['election'] = datasets.election;
2691
+ scorecard.minority.details['vap'] = datasets.vap;
2692
+ scorecard.traditionalPrinciples.details['shapes'] = datasets.shapes;
2693
+ scorecard.traditionalPrinciples.details['census'] = datasets.census;
2694
+ // TODO - SCORE: Add legacy splits details
2695
+ const simpleSplits = s.getTest(7 /* UnexpectedCountySplits */);
2696
+ scorecard.traditionalPrinciples.details['unexpectedAffected'] = simpleSplits['score'];
2697
+ scorecard.traditionalPrinciples.details['countiesSplitUnexpectedly'] = U.deepCopy(simpleSplits['details']['countiesSplitUnexpectedly']);
2698
+ // NOTE - Add split precincts in dra-client directly
2556
2699
  }
2557
2700
  // Derive secondary tests
2558
2701
  analyze_1.doDeriveSecondaryTests(s, bLog);
@@ -2600,7 +2743,8 @@ function profilePlan(s, bLog = false) {
2600
2743
  const summaryRow = s.districts.numberOfRows() - 1;
2601
2744
  const statewideVf = U.trim(s.districts.statistics[D.DistrictField.DemPct][summaryRow], 6);
2602
2745
  const vpiArray = U.deepCopy(s.districts.statistics[D.DistrictField.DemPct].slice(1, -1));
2603
- const demographicsByDistrict = makeArrayOfDemographics(s);
2746
+ const statewideDemographics = getStatewideDemographics(s);
2747
+ const demographicsByDistrict = getDemographicsByDistrict(s);
2604
2748
  const profile = {
2605
2749
  state: state,
2606
2750
  planName: planName,
@@ -2608,21 +2752,22 @@ function profilePlan(s, bLog = false) {
2608
2752
  nCounties: nCounties,
2609
2753
  legislativeDistricts: s.legislativeDistricts,
2610
2754
  populationProfile: {
2611
- TotalPopByDistrict: popByDistrict,
2755
+ totalPopByDistrict: popByDistrict,
2612
2756
  targetSize: targetSize
2613
2757
  },
2614
2758
  compactnessProfile: {
2615
- GeometryByDistrict: geoPropsByDistrict
2759
+ geometryByDistrict: geoPropsByDistrict
2616
2760
  },
2617
2761
  splittingProfile: {
2618
- CountyPopByDistrict: splits
2762
+ countyPopByDistrict: splits
2619
2763
  },
2620
2764
  partisanProfile: {
2621
2765
  statewideVf: statewideVf,
2622
- VfArray: vpiArray
2766
+ vfArray: vpiArray
2623
2767
  },
2624
2768
  demographicProfile: {
2625
- DemographicsByDistrict: demographicsByDistrict
2769
+ stateMfArray: statewideDemographics,
2770
+ mfArrayByDistrict: demographicsByDistrict
2626
2771
  }
2627
2772
  };
2628
2773
  return profile;
@@ -2656,7 +2801,7 @@ function makeArrayOfGeoProps(s, bLog = false) {
2656
2801
  }
2657
2802
  return geometryByDistrict;
2658
2803
  }
2659
- function makeArrayOfDemographics(s, bLog = false) {
2804
+ function getDemographicsByDistrict(s, bLog = false) {
2660
2805
  let demographicsArray = [];
2661
2806
  // Remove the unassigned & total dummy "districts"
2662
2807
  for (let districtID = 1; districtID <= s.state.nDistricts; districtID++) {
@@ -2673,6 +2818,19 @@ function makeArrayOfDemographics(s, bLog = false) {
2673
2818
  }
2674
2819
  return demographicsArray;
2675
2820
  }
2821
+ function getStatewideDemographics(s, bLog = false) {
2822
+ const summaryRow = s.districts.numberOfRows() - 1;
2823
+ const demographicsArray = [
2824
+ U.deepCopy(s.districts.statistics[D.DistrictField.WhitePct][summaryRow]),
2825
+ U.deepCopy(s.districts.statistics[D.DistrictField.MinorityPct][summaryRow]),
2826
+ U.deepCopy(s.districts.statistics[D.DistrictField.BlackPct][summaryRow]),
2827
+ U.deepCopy(s.districts.statistics[D.DistrictField.HispanicPct][summaryRow]),
2828
+ U.deepCopy(s.districts.statistics[D.DistrictField.PacificPct][summaryRow]),
2829
+ U.deepCopy(s.districts.statistics[D.DistrictField.AsianPct][summaryRow]),
2830
+ U.deepCopy(s.districts.statistics[D.DistrictField.NativePct][summaryRow])
2831
+ ];
2832
+ return demographicsArray;
2833
+ }
2676
2834
  // SCORE A PLAN
2677
2835
  function scorePlan(s, p, bLog = false, overridesJSON) {
2678
2836
  let scorer = new Score.Scorer();
@@ -2735,6 +2893,8 @@ exports.EQUAL_TOLERANCE = AVERAGE_BLOCK_SIZE / 2;
2735
2893
  // County & district splitting weights
2736
2894
  exports.COUNTY_SPLITTING_WEIGHT = 0.8;
2737
2895
  exports.DISTRICT_SPLITTING_WEIGHT = 1.0 - exports.COUNTY_SPLITTING_WEIGHT;
2896
+ // TODO - 2020
2897
+ exports.SHAPES = "2010 VTD shapes";
2738
2898
 
2739
2899
 
2740
2900
  /***/ }),