codeforthailand/election-live

View on GitHub
src/models/information/_filters.js

Summary

Maintainability
A
2 hrs
Test Coverage
import { getProvinceById } from "."

/** @type {IProvince[]} */
const provinces = require("./_provinces.json")

// @ts-check

// Provinces where zone boundaries were manipulated by NCPO
// @see https://github.com/codeforthailand/election-live/issues/21
const GERRYMANDERING_PROVINCES = [30, 32, 44, 35, 47, 41, 60, 73, 57, 64, 18]

// Provinces where vote count difference between 1st and 2nd parties
// is less than 5% (source: Thailand general election 2554)
// @see https://github.com/codeforthailand/election-live/issues/22
const SWING_PROVINCES = [37, 26, 70, 25, 20, 10, 62, 64, 74]

// Urban zone is zone which its density is more than 800 people / sq.km.
// (taken from the least dense zone in Bangkok)
// @see https://github.com/codeforthailand/election-live/issues/19
const URBAN_ZONES = [
  "10-1",
  "10-22",
  "10-7",
  "10-2",
  "10-3",
  "10-30",
  "10-5",
  "11-3",
  "10-4",
  "10-23",
  "10-6",
  "10-21",
  "10-8",
  "10-13",
  "10-14",
  "10-10",
  "90-2",
  "10-29",
  "10-12",
  "10-9",
  "12-2",
  "10-11",
  "13-4",
  "10-24",
  "11-1",
  "10-28",
  "12-1",
  "10-19",
  "11-6",
  "10-20",
  "10-26",
  "12-5",
  "12-4",
  "10-15",
  "10-27",
  "30-1",
  "11-2",
  "83-1",
  "40-1",
  "10-16",
  "74-2",
  "10-25",
  "41-1",
  "12-3",
  "10-18",
  "73-5",
  "13-3",
  "50-1",
  "11-7",
  "11-4",
  "20-1",
  "90-1",
  "73-1",
  "13-2",
  "20-2",
  "74-1",
  "94-1",
  "10-17",
]

const provinceFilter = function() {
  return provinces.reduce(
    (acc, p) => ({
      ...acc,
      [p.name]: {
        name: {
          th: p.name,
          en: p.name,
        },
        criterion: function(province, zone) {
          return province.id === p.id
        },
      },
    }),
    {}
  )
}

/**
 * Available filters.
 *
 * To add a new filter, please also add a new entry in ZoneFilterName type.
 *
 * @type {{ [filterName in ZoneFilterName]: IZoneFilter }}
 */
export const filters = {
  ...provinceFilter(),
  all: {
    name: {
      th: "ทั่วประเทศ",
      en: "All areas",
    },
    criterion: (province, zone) => true,
  },
  northern: {
    name: {
      th: "ภาคเหนือ",
      en: "Northern region",
    },
    criterion: (province, zone) => province.regionId === 1,
  },
  northeastern: {
    name: {
      th: "ภาคตะวันออกเฉียงเหนือ",
      en: "Northeastern region",
    },
    criterion: (province, zone) => province.regionId === 2,
  },
  central: {
    name: {
      th: "ภาคกลาง",
      en: "Central region",
    },
    criterion: (province, zone) => province.regionId === 3,
  },
  southern: {
    name: {
      th: "ภาคใต้",
      en: "Southern region",
    },
    criterion: (province, zone) => province.regionId === 4,
  },
  urban: {
    name: {
      th: "เขตพื้นที่ในเมือง",
      en: "Urban",
    },
    description: {
      th:
        "เขตที่มีความหนาแน่นประชากร 800 คน/ตร.กม. ขึ้นไป (≥ เขตที่หนาแน่นน้อยที่สุดของกทม.)",
      en:
        "เขตที่มีความหนาแน่นประชากร 800 คน/ตร.กม. ขึ้นไป (≥ เขตที่หนาแน่นน้อยที่สุดของกทม.)",
    },
    criterion: (province, zone) =>
      URBAN_ZONES.includes(`${zone.provinceId}-${zone.no}`),
  },
  rural: {
    name: {
      th: "เขตพื้นที่นอกเมือง",
      en: "Rural",
    },
    description: {
      th:
        "เขตที่มีความหนาแน่นประชากรน้อยกว่า 800 คน/ตร.กม (< เขตที่หนาแน่นน้อยที่สุดของกรุงเทพฯ)",
      en:
        "เขตที่มีความหนาแน่นประชากรน้อยกว่า 800 คน/ตร.กม (< เขตที่หนาแน่นน้อยที่สุดของกรุงเทพฯ)",
    },
    criterion: (province, zone) =>
      !URBAN_ZONES.includes(`${zone.provinceId}-${zone.no}`),
  },
  gerrymandering: {
    name: {
      th: "เขตถูกแบ่งโดย คสช.",
      en: "Gerrymandering",
    },
    description: {
      th:
        "จังหวัดที่มีรูปแบบเขตเลือกตั้งไม่ตรงกับที่ กกต.จังหวัดกำหนด เนื่องด้วยคำสั่ง คสช.",
      en:
        "จังหวัดที่มีรูปแบบเขตเลือกตั้งไม่ตรงกับที่ กกต.จังหวัดกำหนด เนื่องด้วยคำสั่ง คสช.",
    },
    criterion: (province, zone) =>
      GERRYMANDERING_PROVINCES.includes(province.id),
  },
  swing: {
    name: {
      th: "เขตที่ไม่มีฐานเสียงชัดเจน",
      en: "Swing District",
    },
    description: {
      th:
        "จังหวัดที่มีผลคะแนนเลือกตั้งปี 54 ของพรรคอันดับ 1 กับอันดับ 2 ห่างกันไม่ถึง 5%",
      en:
        "จังหวัดที่มีผลคะแนนเลือกตั้งปี 54 ของพรรคอันดับ 1 กับอันดับ 2 ห่างกันไม่ถึง 5%",
    },
    criterion: (province, zone) => SWING_PROVINCES.includes(province.id),
  },
}

/**
 * @param {ZoneFilterName} filterName
 */
export function filterPath(filterName) {
  return filterName === "all" ? "/" : `/filters/${filterName}`
}

/**
 * @param {IZoneFilter} filter
 * @param {IZone} zone
 */
export function checkFilter(filter, zone) {
  return filter.criterion(getProvinceById(zone.provinceId), zone)
}