Site News & Updates:

County Index

How the County Index Works:

Our mission is to showcase all agencies operating within the State of South Carolina. In order to properly display these agencies, we utilize the “County Index” format to help streamline our visual catalog. As you browse the individual county pages, you’ll notice that all agencies located within a particular county will appear in the listing. The top of the section will always kick-off with the Sheriff’s Office as they’re the largest agency in that county. Municipal agencies will then follow the line-up in alphabetic order and finish off with collegiate agencies at the bottom. The very bottom of the index will list agencies that have not yet been included.

Search by Department:

Looking for a particular agency? No worries! Use our search function at the bottom of the website to scroll through the listing of agencies operating within the state of South Carolina.

County Sections Last Updated: 11/11/2026

Interactive South Carolina County Map A metallic bronze three-dimensional map of South Carolina with clickable county boundaries.
/* ===================================================== MAIN CONTAINER ===================================================== */ #scpc-map-wrap { width: 100%; max-width: 1200px; margin: 30px auto; padding: 20px; box-sizing: border-box; background: linear-gradient( 145deg, #171717, #080808 ); border: 1px solid #7e4c21; border-radius: 18px; box-shadow: 0 25px 70px rgba(0,0,0,.75), inset 0 1px 0 rgba(255,255,255,.08), inset 0 -1px 0 rgba(0,0,0,.8); } /* ===================================================== HEADER ===================================================== */ .scpc-map-header { display: flex; align-items: center; justify-content: center; gap: 25px; padding: 15px 20px 25px; text-align: left; } .scpc-logo img { max-width: 180px; max-height: 85px; object-fit: contain; } .scpc-title-block { text-align: center; } .scpc-eyebrow { color: #b97b38; font-family: Arial, Helvetica, sans-serif; font-size: 12px; font-weight: 800; letter-spacing: 3px; text-transform: uppercase; margin-bottom: 6px; } .scpc-title-block h2 { margin: 0 0 8px; color: #e2aa5c; font-family: Georgia, serif; font-size: clamp( 30px, 4vw, 48px ); text-transform: uppercase; letter-spacing: 1px; text-shadow: 0 2px 3px #000, 0 0 18px rgba(210,145,60,.25); } .scpc-title-block p { margin: 0; color: #b7b7b7; font-family: Arial, Helvetica, sans-serif; font-size: 15px; line-height: 1.5; } /* ===================================================== MAP ===================================================== */ .scpc-map-frame { position: relative; overflow: hidden; border-radius: 16px; border: 1px solid rgba(179,113,48,.55); background: #090909; box-shadow: inset 0 0 35px rgba(0,0,0,.8), 0 10px 35px rgba(0,0,0,.55); } #sc-county-map { display: block; width: 100%; height: auto; } /* ===================================================== COUNTY ===================================================== */ .county { cursor: pointer; fill: url(#bronzeMetal); stroke: #2b1406; stroke-width: 1.3px; filter: url(#countyDepth); transition: fill .25s ease, stroke .25s ease, filter .25s ease, opacity .25s ease; } /* COUNTY HOVER */ .county-group:hover .county, .county-link:focus .county { fill: url(#bronzeHover); stroke: #ffe0a0; stroke-width: 2px; filter: url(#countyGlow); } /* COUNTY LABEL */ .county-label { pointer-events: none; fill: #fff1d1; stroke: #2a1306; stroke-width: 1px; paint-order: stroke; text-anchor: middle; dominant-baseline: middle; font-family: Arial, Helvetica, sans-serif; font-weight: 800; letter-spacing: .3px; filter: url(#labelShadow); transition: fill .2s ease; } .county-group:hover .county-label { fill: #ffffff; } /* ACCESSIBILITY */ .county-link:focus { outline: none; } .county-link:focus .county { stroke: #ffffff; stroke-width: 3px; } /* ===================================================== FOOTER ===================================================== */ .scpc-map-footer { text-align: center; padding: 16px 10px 2px; color: #8f8f8f; font-family: Arial, Helvetica, sans-serif; font-size: 11px; font-weight: 800; letter-spacing: 3px; } /* ===================================================== TOOLTIP ===================================================== */ #county-tooltip { position: fixed; display: none; z-index: 999999; pointer-events: none; padding: 10px 14px; background: linear-gradient( 145deg, #2b180c, #100904 ); color: #f5d38c; border: 1px solid #c7873d; border-radius: 7px; font-family: Arial, Helvetica, sans-serif; font-size: 13px; text-align: center; box-shadow: 0 10px 30px rgba(0,0,0,.75); } /* ===================================================== MOBILE ===================================================== */ @media (max-width: 700px) { #scpc-map-wrap { padding: 8px; border-radius: 10px; } .scpc-map-header { display: block; text-align: center; padding: 20px 10px; } .scpc-logo { margin-bottom: 12px; } .scpc-logo img { max-width: 150px; } .county-label { letter-spacing: 0; } .scpc-map-footer { font-size: 8px; } } https://cdn.jsdelivr.net/npm/d3@7 https://cdn.jsdelivr.net/npm/topojson-client@3 (async function () { /* ===================================================== COUNTY PAGE LINKS ===================================================== */ const countyLinks = { Abbeville: “https://scpolicecruisers.com/abbevillecounty/”, Aiken: “https://scpolicecruisers.com/aikencounty/”, Allendale: “https://scpolicecruisers.com/allendalecounty/”, Anderson: “https://scpolicecruisers.com/andersoncounty/”, Bamberg: “https://scpolicecruisers.com/bambergcounty/”, Barnwell: “https://scpolicecruisers.com/barnwellcounty/”, Beaufort: “https://scpolicecruisers.com/beaufortcounty/”, Berkeley: “https://scpolicecruisers.com/berkeleycounty/”, Calhoun: “https://scpolicecruisers.com/calhouncounty/”, Charleston: “https://scpolicecruisers.com/charlestoncounty/”, Cherokee: “https://scpolicecruisers.com/cherokeecounty/”, Chester: “https://scpolicecruisers.com/chestercounty/”, Chesterfield: “https://scpolicecruisers.com/chesterfieldcounty/”, Clarendon: “https://scpolicecruisers.com/clarendoncounty/”, Colleton: “https://scpolicecruisers.com/colletoncounty/”, Darlington: “https://scpolicecruisers.com/darlingtoncounty/”, Dillon: “https://scpolicecruisers.com/dilloncounty/”, Dorchester: “https://scpolicecruisers.com/dorchestercounty/”, Edgefield: “https://scpolicecruisers.com/edgefieldcounty/”, Fairfield: “https://scpolicecruisers.com/fairfieldcounty/”, Florence: “https://scpolicecruisers.com/florencecounty/”, Georgetown: “https://scpolicecruisers.com/georgetowncounty/”, Greenville: “https://scpolicecruisers.com/greenvillecounty/”, Greenwood: “https://scpolicecruisers.com/greenwoodcounty/”, Hampton: “https://scpolicecruisers.com/hamptoncounty/”, Horry: “https://scpolicecruisers.com/horrycounty/”, Jasper: “https://scpolicecruisers.com/jaspercounty/”, Kershaw: “https://scpolicecruisers.com/kershawcounty/”, Lancaster: “https://scpolicecruisers.com/lancastercounty/”, Laurens: “https://scpolicecruisers.com/laurenscounty/”, Lee: “https://scpolicecruisers.com/leecounty/”, Lexington: “https://scpolicecruisers.com/lexingtoncounty/”, McCormick: “https://scpolicecruisers.com/mccormickcounty/”, Marion: “https://scpolicecruisers.com/marioncounty/”, Marlboro: “https://scpolicecruisers.com/marlborocounty/”, Newberry: “https://scpolicecruisers.com/newberrycounty/”, Oconee: “https://scpolicecruisers.com/oconeecounty/”, Orangeburg: “https://scpolicecruisers.com/orangeburgcounty/”, Pickens: “https://scpolicecruisers.com/pickenscounty/”, Richland: “https://scpolicecruisers.com/richlandcounty/”, Saluda: “https://scpolicecruisers.com/saludacounty/”, Spartanburg: “https://scpolicecruisers.com/spartanburgcounty/”, Sumter: “https://scpolicecruisers.com/sumtercounty/”, Union: “https://scpolicecruisers.com/unioncounty/”, Williamsburg: “https://scpolicecruisers.com/williamsburgcounty/”, York: “https://scpolicecruisers.com/yorkcounty/” }; /* ===================================================== SOUTH CAROLINA COUNTY FIPS ===================================================== */ const countyNames = { “001”: “Abbeville”, “003”: “Aiken”, “005”: “Allendale”, “007”: “Anderson”, “009”: “Bamberg”, “011”: “Barnwell”, “013”: “Beaufort”, “015”: “Berkeley”, “017”: “Calhoun”, “019”: “Charleston”, “021”: “Cherokee”, “023”: “Chester”, “025”: “Chesterfield”, “027”: “Clarendon”, “029”: “Colleton”, “031”: “Darlington”, “033”: “Dillon”, “035”: “Dorchester”, “037”: “Edgefield”, “039”: “Fairfield”, “041”: “Florence”, “043”: “Georgetown”, “045”: “Greenville”, “047”: “Greenwood”, “049”: “Hampton”, “051”: “Horry”, “053”: “Jasper”, “055”: “Kershaw”, “057”: “Lancaster”, “059”: “Laurens”, “061”: “Lee”, “063”: “Lexington”, “065”: “McCormick”, “067”: “Marion”, “069”: “Marlboro”, “071”: “Newberry”, “073”: “Oconee”, “075”: “Orangeburg”, “077”: “Pickens”, “079”: “Richland”, “081”: “Saluda”, “083”: “Spartanburg”, “085”: “Sumter”, “087”: “Union”, “089”: “Williamsburg”, “091”: “York” }; /* ===================================================== SVG SETUP ===================================================== */ const svg = d3.select(“#sc-county-map”); const map = svg.select(“#map-content”); const width = 1100; const height = 800; const tooltip = document.getElementById(“county-tooltip”); const projection = d3.geoMercator(); const path = d3.geoPath(projection); /* ===================================================== LOAD COUNTY DATA ===================================================== */ const us = await d3.json( “https://cdn.jsdelivr.net/npm/us-atlas@3/counties-10m.json” ); const counties = topojson.feature( us, us.objects.counties ).features; const scCounties = counties.filter(d => String(d.id) .padStart(5, “0”) .startsWith(“45”) ); const featureCollection = { type: “FeatureCollection”, features: scCounties }; /* ===================================================== SIZE SOUTH CAROLINA ===================================================== */ projection.fitExtent( [ [100, 80], [1000, 720] ], featureCollection ); /* ===================================================== CREATE STATE SILHOUETTE ===================================================== */ const stateGeometry = topojson.merge( us, us.objects.counties.geometries.filter(d => String(d.id) .padStart(5, “0”) .startsWith(“45”) ) ); /* DARK DEPTH LAYER */ map .append(“path”) .datum(stateGeometry) .attr( “d”, path ) .attr( “transform”, “translate(8,12)” ) .attr( “fill”, “#211006” ) .attr( “stroke”, “#000000” ) .attr( “stroke-width”, 7 ) .attr( “opacity”, “.9” ); /* MAIN STATE OUTLINE */ map .append(“path”) .datum(stateGeometry) .attr( “d”, path ) .attr( “fill”, “url(#bronzeMetal)” ) .attr( “stroke”, “#e4ad61” ) .attr( “stroke-width”, 5 ) .attr( “filter”, “url(#stateShadow)” ); /* ===================================================== COUNTY GROUPS ===================================================== */ const groups = map .selectAll( “.county-group” ) .data(scCounties) .enter() .append(“g”) .attr( “class”, “county-group” ); /* ===================================================== CREATE CLICKABLE COUNTIES ===================================================== */ groups.each(function(d) { const group = d3.select(this); const fips = String(d.id) .padStart(5, “0”) .slice(-3); const countyName = countyNames[fips]; const countyURL = countyLinks[countyName] || “#”; /* * IMPORTANT: * Both the county shape AND label are * inside the same clickable element. */ const link = group .append(“a”) .attr( “class”, “county-link” ) .attr( “href”, countyURL ) .attr( “aria-label”, `Explore ${countyName} County` ); /* COUNTY SHAPE */ link .append(“path”) .datum(d) .attr( “class”, “county” ) .attr( “d”, path ); /* METALLIC HIGHLIGHT OVERLAY */ link .append(“path”) .datum(d) .attr( “d”, path ) .attr( “fill”, “url(#countyHighlight)” ) .attr( “pointer-events”, “none” ) .attr( “opacity”, “.55” ); /* ================================================= COUNTY LABEL POSITION ================================================= */ const centroid = path.centroid(d); const bounds = path.bounds(d); const countyWidth = bounds[1][0] – bounds[0][0]; const countyHeight = bounds[1][1] – bounds[0][1]; /* * Automatically size text based on the * smaller county dimension. */ const smallestDimension = Math.min( countyWidth, countyHeight ); let fontSize = smallestDimension * .16; /* * Keep labels within reasonable limits. */ fontSize = Math.max( 5, Math.min( fontSize, 14 ) ); /* * SMALL COUNTIES: * Hide labels that become too small. * * The county remains fully clickable * and the tooltip identifies it. */ const showLabel = fontSize >= 6.5; if (showLabel) { link .append(“text”) .attr( “class”, “county-label” ) .attr( “x”, centroid[0] ) .attr( “y”, centroid[1] ) .style( “font-size”, `${fontSize}px` ) .text( countyName ); } /* ================================================= TOOLTIP EVENTS ================================================= */ link .on( “mouseenter”, function(event) { tooltip.innerHTML = `${countyName} County` + `
` + `Click to explore`; tooltip.style.display = “block”; } ) .on( “mousemove”, function(event) { tooltip.style.left = `${event.clientX + 18}px`; tooltip.style.top = `${event.clientY + 18}px`; } ) .on( “mouseleave”, function() { tooltip.style.display = “none”; } ); }); /* ===================================================== STATE TITLE OVER MAP ===================================================== */ map .append(“text”) .attr( “x”, 550 ) .attr( “y”, 55 ) .attr( “text-anchor”, “middle” ) .attr( “fill”, “#dca158” ) .attr( “font-family”, “Georgia, serif” ) .attr( “font-size”, “18px” ) .attr( “font-weight”, “bold” ) .attr( “letter-spacing”, “6px” ) .attr( “opacity”, “.8” ) .text( “SOUTH CAROLINA” ); })();
<div id="scpc-map-wrap">

  <!-- HEADER -->
  <div class="scpc-map-header">

    <!-- OPTIONAL: Replace with your actual logo URL -->
    <div class="scpc-logo">
      <img
        src="YOUR-SCPOLICECRUISERS-LOGO-URL-HERE"
        alt="SCPoliceCruisers.com"
        onerror="this.style.display='none';"
      >
    </div>

    <div class="scpc-title-block">
      <div class="scpc-eyebrow">SCPoliceCruisers.com</div>
      <h2>Explore South Carolina</h2>
      <p>Select a county to explore South Carolina law enforcement vehicles and agencies.</p>
    </div>

  </div>


  <!-- INTERACTIVE MAP -->
  <div class="scpc-map-frame">

    <svg
      id="sc-county-map"
      viewBox="0 0 1100 800"
      role="img"
      aria-labelledby="mapTitle mapDescription"
      xmlns="http://www.w3.org/2000/svg">

      <title id="mapTitle">
        Interactive South Carolina County Map
      </title>

      <desc id="mapDescription">
        A metallic bronze three-dimensional map of South Carolina
        with clickable county boundaries.
      </desc>


      <defs>

        <!-- BACKGROUND -->
        <radialGradient id="backgroundGradient"
                        cx="50%"
                        cy="40%"
                        r="80%">

          <stop offset="0%" stop-color="#303030"/>
          <stop offset="45%" stop-color="#171717"/>
          <stop offset="100%" stop-color="#050505"/>

        </radialGradient>


        <!-- MAIN BRONZE -->
        <linearGradient id="bronzeMetal"
                        x1="0%"
                        y1="0%"
                        x2="100%"
                        y2="100%">

          <stop offset="0%" stop-color="#321607"/>
          <stop offset="10%" stop-color="#7a421c"/>
          <stop offset="22%" stop-color="#d89a4d"/>
          <stop offset="32%" stop-color="#8a4b20"/>
          <stop offset="45%" stop-color="#f0bf70"/>
          <stop offset="58%" stop-color="#9a5725"/>
          <stop offset="72%" stop-color="#6a3414"/>
          <stop offset="87%" stop-color="#c48138"/>
          <stop offset="100%" stop-color="#3b1a09"/>

        </linearGradient>


        <!-- HOVER BRONZE -->
        <linearGradient id="bronzeHover"
                        x1="0%"
                        y1="0%"
                        x2="100%"
                        y2="100%">

          <stop offset="0%" stop-color="#8c4b1d"/>
          <stop offset="25%" stop-color="#ffd98b"/>
          <stop offset="50%" stop-color="#d99032"/>
          <stop offset="72%" stop-color="#fff0b8"/>
          <stop offset="100%" stop-color="#8c4b1d"/>

        </linearGradient>


        <!-- COUNTY TOP HIGHLIGHT -->
        <linearGradient id="countyHighlight"
                        x1="0%"
                        y1="0%"
                        x2="0%"
                        y2="100%">

          <stop offset="0%" stop-color="#ffffff" stop-opacity=".28"/>
          <stop offset="18%" stop-color="#ffffff" stop-opacity=".08"/>
          <stop offset="55%" stop-color="#000000" stop-opacity="0"/>
          <stop offset="100%" stop-color="#000000" stop-opacity=".28"/>

        </linearGradient>


        <!-- MAP SHADOW -->
        <filter id="stateShadow"
                x="-20%"
                y="-20%"
                width="150%"
                height="150%">

          <feDropShadow
            dx="14"
            dy="18"
            stdDeviation="13"
            flood-color="#000000"
            flood-opacity=".85"
          />

          <feDropShadow
            dx="-4"
            dy="-4"
            stdDeviation="4"
            flood-color="#eec071"
            flood-opacity=".35"
          />

        </filter>


        <!-- COUNTY DEPTH -->
        <filter id="countyDepth"
                x="-20%"
                y="-20%"
                width="140%"
                height="140%">

          <feDropShadow
            dx="2"
            dy="3"
            stdDeviation="1.8"
            flood-color="#140902"
            flood-opacity=".8"
          />

        </filter>


        <!-- COUNTY HOVER GLOW -->
        <filter id="countyGlow"
                x="-40%"
                y="-40%"
                width="180%"
                height="180%">

          <feDropShadow
            dx="0"
            dy="0"
            stdDeviation="6"
            flood-color="#f6c26b"
            flood-opacity=".8"
          />

        </filter>


        <!-- LABEL SHADOW -->
        <filter id="labelShadow">

          <feDropShadow
            dx="1"
            dy="2"
            stdDeviation="1.5"
            flood-color="#000000"
            flood-opacity=".95"
          />

        </filter>

      </defs>


      <!-- BACKGROUND -->
      <rect
        width="1100"
        height="800"
        rx="20"
        fill="url(#backgroundGradient)"
      />


      <!-- DECORATIVE INNER BORDER -->
      <rect
        x="12"
        y="12"
        width="1076"
        height="776"
        rx="14"
        fill="none"
        stroke="#9d632b"
        stroke-opacity=".45"
        stroke-width="1"
      />


      <!-- MAP -->
      <g id="map-content"></g>

    </svg>

  </div>


  <!-- FOOTER -->
  <div class="scpc-map-footer">
    <span>SELECT A COUNTY TO EXPLORE</span>
  </div>


  <!-- TOOLTIP -->
  <div id="county-tooltip"></div>

</div>



<style>

/* =====================================================
   MAIN CONTAINER
===================================================== */

#scpc-map-wrap {
  width: 100%;
  max-width: 1200px;
  margin: 30px auto;
  padding: 20px;
  box-sizing: border-box;

  background:
    linear-gradient(
      145deg,
      #171717,
      #080808
    );

  border:
    1px solid #7e4c21;

  border-radius: 18px;

  box-shadow:
    0 25px 70px rgba(0,0,0,.75),
    inset 0 1px 0 rgba(255,255,255,.08),
    inset 0 -1px 0 rgba(0,0,0,.8);
}


/* =====================================================
   HEADER
===================================================== */

.scpc-map-header {

  display: flex;
  align-items: center;
  justify-content: center;

  gap: 25px;

  padding:
    15px
    20px
    25px;

  text-align: left;

}

.scpc-logo img {

  max-width: 180px;
  max-height: 85px;

  object-fit: contain;

}

.scpc-title-block {
  text-align: center;
}

.scpc-eyebrow {

  color: #b97b38;

  font-family:
    Arial,
    Helvetica,
    sans-serif;

  font-size: 12px;

  font-weight: 800;

  letter-spacing: 3px;

  text-transform: uppercase;

  margin-bottom: 6px;

}

.scpc-title-block h2 {

  margin: 0 0 8px;

  color: #e2aa5c;

  font-family:
    Georgia,
    serif;

  font-size:
    clamp(
      30px,
      4vw,
      48px
    );

  text-transform: uppercase;

  letter-spacing: 1px;

  text-shadow:

    0 2px 3px #000,

    0 0 18px
    rgba(210,145,60,.25);

}

.scpc-title-block p {

  margin: 0;

  color: #b7b7b7;

  font-family:
    Arial,
    Helvetica,
    sans-serif;

  font-size: 15px;

  line-height: 1.5;

}


/* =====================================================
   MAP
===================================================== */

.scpc-map-frame {

  position: relative;

  overflow: hidden;

  border-radius: 16px;

  border:
    1px solid
    rgba(179,113,48,.55);

  background: #090909;

  box-shadow:

    inset 0 0 35px
    rgba(0,0,0,.8),

    0 10px 35px
    rgba(0,0,0,.55);

}

#sc-county-map {

  display: block;

  width: 100%;

  height: auto;

}


/* =====================================================
   COUNTY
===================================================== */

.county {

  cursor: pointer;

  fill:
    url(#bronzeMetal);

  stroke:
    #2b1406;

  stroke-width:
    1.3px;

  filter:
    url(#countyDepth);

  transition:

    fill .25s ease,

    stroke .25s ease,

    filter .25s ease,

    opacity .25s ease;

}


/* COUNTY HOVER */

.county-group:hover .county,
.county-link:focus .county {

  fill:
    url(#bronzeHover);

  stroke:
    #ffe0a0;

  stroke-width:
    2px;

  filter:
    url(#countyGlow);

}


/* COUNTY LABEL */

.county-label {

  pointer-events: none;

  fill:
    #fff1d1;

  stroke:
    #2a1306;

  stroke-width:
    1px;

  paint-order:
    stroke;

  text-anchor:
    middle;

  dominant-baseline:
    middle;

  font-family:
    Arial,
    Helvetica,
    sans-serif;

  font-weight:
    800;

  letter-spacing:
    .3px;

  filter:
    url(#labelShadow);

  transition:
    fill .2s ease;

}

.county-group:hover .county-label {

  fill:
    #ffffff;

}


/* ACCESSIBILITY */

.county-link:focus {

  outline: none;

}

.county-link:focus .county {

  stroke:
    #ffffff;

  stroke-width:
    3px;

}


/* =====================================================
   FOOTER
===================================================== */

.scpc-map-footer {

  text-align: center;

  padding:
    16px
    10px
    2px;

  color:
    #8f8f8f;

  font-family:
    Arial,
    Helvetica,
    sans-serif;

  font-size:
    11px;

  font-weight:
    800;

  letter-spacing:
    3px;

}


/* =====================================================
   TOOLTIP
===================================================== */

#county-tooltip {

  position: fixed;

  display: none;

  z-index: 999999;

  pointer-events: none;

  padding:
    10px
    14px;

  background:

    linear-gradient(
      145deg,
      #2b180c,
      #100904
    );

  color:
    #f5d38c;

  border:
    1px solid #c7873d;

  border-radius:
    7px;

  font-family:
    Arial,
    Helvetica,
    sans-serif;

  font-size:
    13px;

  text-align:
    center;

  box-shadow:

    0 10px 30px
    rgba(0,0,0,.75);

}


/* =====================================================
   MOBILE
===================================================== */

@media (max-width: 700px) {

  #scpc-map-wrap {

    padding: 8px;

    border-radius: 10px;

  }

  .scpc-map-header {

    display: block;

    text-align: center;

    padding:
      20px
      10px;

  }

  .scpc-logo {

    margin-bottom: 12px;

  }

  .scpc-logo img {

    max-width: 150px;

  }

  .county-label {

    letter-spacing: 0;

  }

  .scpc-map-footer {

    font-size: 8px;

  }

}

</style>



<!-- =====================================================
     REQUIRED LIBRARIES
===================================================== -->

https://cdn.jsdelivr.net/npm/d3@7

https://cdn.jsdelivr.net/npm/topojson-client@3



<script>

(async function () {


  /* =====================================================
     COUNTY PAGE LINKS
  ===================================================== */

  const countyLinks = {

    Abbeville:
      "https://scpolicecruisers.com/abbevillecounty/",

    Aiken:
      "https://scpolicecruisers.com/aikencounty/",

    Allendale:
      "https://scpolicecruisers.com/allendalecounty/",

    Anderson:
      "https://scpolicecruisers.com/andersoncounty/",

    Bamberg:
      "https://scpolicecruisers.com/bambergcounty/",

    Barnwell:
      "https://scpolicecruisers.com/barnwellcounty/",

    Beaufort:
      "https://scpolicecruisers.com/beaufortcounty/",

    Berkeley:
      "https://scpolicecruisers.com/berkeleycounty/",

    Calhoun:
      "https://scpolicecruisers.com/calhouncounty/",

    Charleston:
      "https://scpolicecruisers.com/charlestoncounty/",

    Cherokee:
      "https://scpolicecruisers.com/cherokeecounty/",

    Chester:
      "https://scpolicecruisers.com/chestercounty/",

    Chesterfield:
      "https://scpolicecruisers.com/chesterfieldcounty/",

    Clarendon:
      "https://scpolicecruisers.com/clarendoncounty/",

    Colleton:
      "https://scpolicecruisers.com/colletoncounty/",

    Darlington:
      "https://scpolicecruisers.com/darlingtoncounty/",

    Dillon:
      "https://scpolicecruisers.com/dilloncounty/",

    Dorchester:
      "https://scpolicecruisers.com/dorchestercounty/",

    Edgefield:
      "https://scpolicecruisers.com/edgefieldcounty/",

    Fairfield:
      "https://scpolicecruisers.com/fairfieldcounty/",

    Florence:
      "https://scpolicecruisers.com/florencecounty/",

    Georgetown:
      "https://scpolicecruisers.com/georgetowncounty/",

    Greenville:
      "https://scpolicecruisers.com/greenvillecounty/",

    Greenwood:
      "https://scpolicecruisers.com/greenwoodcounty/",

    Hampton:
      "https://scpolicecruisers.com/hamptoncounty/",

    Horry:
      "https://scpolicecruisers.com/horrycounty/",

    Jasper:
      "https://scpolicecruisers.com/jaspercounty/",

    Kershaw:
      "https://scpolicecruisers.com/kershawcounty/",

    Lancaster:
      "https://scpolicecruisers.com/lancastercounty/",

    Laurens:
      "https://scpolicecruisers.com/laurenscounty/",

    Lee:
      "https://scpolicecruisers.com/leecounty/",

    Lexington:
      "https://scpolicecruisers.com/lexingtoncounty/",

    McCormick:
      "https://scpolicecruisers.com/mccormickcounty/",

    Marion:
      "https://scpolicecruisers.com/marioncounty/",

    Marlboro:
      "https://scpolicecruisers.com/marlborocounty/",

    Newberry:
      "https://scpolicecruisers.com/newberrycounty/",

    Oconee:
      "https://scpolicecruisers.com/oconeecounty/",

    Orangeburg:
      "https://scpolicecruisers.com/orangeburgcounty/",

    Pickens:
      "https://scpolicecruisers.com/pickenscounty/",

    Richland:
      "https://scpolicecruisers.com/richlandcounty/",

    Saluda:
      "https://scpolicecruisers.com/saludacounty/",

    Spartanburg:
      "https://scpolicecruisers.com/spartanburgcounty/",

    Sumter:
      "https://scpolicecruisers.com/sumtercounty/",

    Union:
      "https://scpolicecruisers.com/unioncounty/",

    Williamsburg:
      "https://scpolicecruisers.com/williamsburgcounty/",

    York:
      "https://scpolicecruisers.com/yorkcounty/"

  };


  /* =====================================================
     SOUTH CAROLINA COUNTY FIPS
  ===================================================== */

  const countyNames = {

    "001": "Abbeville",
    "003": "Aiken",
    "005": "Allendale",
    "007": "Anderson",
    "009": "Bamberg",
    "011": "Barnwell",
    "013": "Beaufort",
    "015": "Berkeley",
    "017": "Calhoun",
    "019": "Charleston",
    "021": "Cherokee",
    "023": "Chester",
    "025": "Chesterfield",
    "027": "Clarendon",
    "029": "Colleton",
    "031": "Darlington",
    "033": "Dillon",
    "035": "Dorchester",
    "037": "Edgefield",
    "039": "Fairfield",
    "041": "Florence",
    "043": "Georgetown",
    "045": "Greenville",
    "047": "Greenwood",
    "049": "Hampton",
    "051": "Horry",
    "053": "Jasper",
    "055": "Kershaw",
    "057": "Lancaster",
    "059": "Laurens",
    "061": "Lee",
    "063": "Lexington",
    "065": "McCormick",
    "067": "Marion",
    "069": "Marlboro",
    "071": "Newberry",
    "073": "Oconee",
    "075": "Orangeburg",
    "077": "Pickens",
    "079": "Richland",
    "081": "Saluda",
    "083": "Spartanburg",
    "085": "Sumter",
    "087": "Union",
    "089": "Williamsburg",
    "091": "York"

  };


  /* =====================================================
     SVG SETUP
  ===================================================== */

  const svg =
    d3.select("#sc-county-map");

  const map =
    svg.select("#map-content");

  const width = 1100;
  const height = 800;

  const tooltip =
    document.getElementById("county-tooltip");

  const projection =
    d3.geoMercator();

  const path =
    d3.geoPath(projection);


  /* =====================================================
     LOAD COUNTY DATA
  ===================================================== */

  const us =
    await d3.json(
      "https://cdn.jsdelivr.net/npm/us-atlas@3/counties-10m.json"
    );


  const counties =
    topojson.feature(
      us,
      us.objects.counties
    ).features;


  const scCounties =
    counties.filter(d =>
      String(d.id)
        .padStart(5, "0")
        .startsWith("45")
    );


  const featureCollection = {

    type: "FeatureCollection",

    features:
      scCounties

  };


  /* =====================================================
     SIZE SOUTH CAROLINA
  ===================================================== */

  projection.fitExtent(

    [
      [100, 80],
      [1000, 720]
    ],

    featureCollection

  );


  /* =====================================================
     CREATE STATE SILHOUETTE
  ===================================================== */

  const stateGeometry =
    topojson.merge(

      us,

      us.objects.counties.geometries.filter(d =>
        String(d.id)
          .padStart(5, "0")
          .startsWith("45")
      )

    );


  /* DARK DEPTH LAYER */

  map
    .append("path")

    .datum(stateGeometry)

    .attr(
      "d",
      path
    )

    .attr(
      "transform",
      "translate(8,12)"
    )

    .attr(
      "fill",
      "#211006"
    )

    .attr(
      "stroke",
      "#000000"
    )

    .attr(
      "stroke-width",
      7
    )

    .attr(
      "opacity",
      ".9"
    );


  /* MAIN STATE OUTLINE */

  map
    .append("path")

    .datum(stateGeometry)

    .attr(
      "d",
      path
    )

    .attr(
      "fill",
      "url(#bronzeMetal)"
    )

    .attr(
      "stroke",
      "#e4ad61"
    )

    .attr(
      "stroke-width",
      5
    )

    .attr(
      "filter",
      "url(#stateShadow)"
    );


  /* =====================================================
     COUNTY GROUPS
  ===================================================== */

  const groups =
    map

      .selectAll(
        ".county-group"
      )

      .data(scCounties)

      .enter()

      .append("g")

      .attr(
        "class",
        "county-group"
      );


  /* =====================================================
     CREATE CLICKABLE COUNTIES
  ===================================================== */

  groups.each(function(d) {

    const group =
      d3.select(this);


    const fips =
      String(d.id)
        .padStart(5, "0")
        .slice(-3);


    const countyName =
      countyNames[fips];


    const countyURL =
      countyLinks[countyName] ||
      "#";


    /*
     * IMPORTANT:
     * Both the county shape AND label are
     * inside the same clickable <a> element.
     */

    const link =
      group

        .append("a")

        .attr(
          "class",
          "county-link"
        )

        .attr(
          "href",
          countyURL
        )

        .attr(
          "aria-label",
          `Explore ${countyName} County`
        );


    /* COUNTY SHAPE */

    link

      .append("path")

      .datum(d)

      .attr(
        "class",
        "county"
      )

      .attr(
        "d",
        path
      );


    /* METALLIC HIGHLIGHT OVERLAY */

    link

      .append("path")

      .datum(d)

      .attr(
        "d",
        path
      )

      .attr(
        "fill",
        "url(#countyHighlight)"
      )

      .attr(
        "pointer-events",
        "none"
      )


      .attr(
        "opacity",
        ".55"
      );


    /* =================================================
       COUNTY LABEL POSITION
    ================================================= */

    const centroid =
      path.centroid(d);


    const bounds =
      path.bounds(d);


    const countyWidth =
      bounds[1][0] -
      bounds[0][0];


    const countyHeight =
      bounds[1][1] -
      bounds[0][1];


    /*
     * Automatically size text based on the
     * smaller county dimension.
     */

    const smallestDimension =
      Math.min(
        countyWidth,
        countyHeight
      );


    let fontSize =
      smallestDimension * .16;


    /*
     * Keep labels within reasonable limits.
     */

    fontSize =
      Math.max(
        5,
        Math.min(
          fontSize,
          14
        )
      );


    /*
     * SMALL COUNTIES:
     * Hide labels that become too small.
     *
     * The county remains fully clickable
     * and the tooltip identifies it.
     */

    const showLabel =
      fontSize >= 6.5;


    if (showLabel) {

      link

        .append("text")

        .attr(
          "class",
          "county-label"
        )

        .attr(
          "x",
          centroid[0]
        )

        .attr(
          "y",
          centroid[1]
        )

        .style(
          "font-size",
          `${fontSize}px`
        )

        .text(
          countyName
        );

    }


    /* =================================================
       TOOLTIP EVENTS
    ================================================= */

    link

      .on(
        "mouseenter",
        function(event) {

          tooltip.innerHTML =

            `<strong>${countyName} County</strong>` +

            `<br>` +

            `<span>Click to explore</span>`;


          tooltip.style.display =
            "block";

        }
      )


      .on(
        "mousemove",
        function(event) {

          tooltip.style.left =
            `${event.clientX + 18}px`;


          tooltip.style.top =
            `${event.clientY + 18}px`;

        }
      )


      .on(
        "mouseleave",
        function() {

          tooltip.style.display =
            "none";

        }
      );


  });


  /* =====================================================
     STATE TITLE OVER MAP
  ===================================================== */

  map

    .append("text")

    .attr(
      "x",
      550
    )

    .attr(
      "y",
      55
    )

    .attr(
      "text-anchor",
      "middle"
    )

    .attr(
      "fill",
      "#dca158"
    )

    .attr(
      "font-family",
      "Georgia, serif"
    )

    .attr(
      "font-size",
      "18px"
    )

    .attr(
      "font-weight",
      "bold"
    )

    .attr(
      "letter-spacing",
      "6px"
    )

    .attr(
      "opacity",
      ".8"
    )

    .text(
      "SOUTH CAROLINA"
    );


})();

</script>

Advertisement