From 07a66d5721f73d639f7371008b0ad5f93288ffff Mon Sep 17 00:00:00 2001 From: Ian MacFarland Date: Fri, 30 Oct 2020 15:13:17 -0700 Subject: [PATCH] move recidivism section to the Prison page (#245) --- public-dashboard-client/src/constants.js | 2 +- .../src/page-prison/PagePrison.js | 78 ++++++++++++++++++- .../src/page-sentencing/PageSentencing.js | 74 +----------------- spotlight-api/core/metricsApi.js | 2 +- 4 files changed, 80 insertions(+), 76 deletions(-) diff --git a/public-dashboard-client/src/constants.js b/public-dashboard-client/src/constants.js index 021f44d7..c278db20 100644 --- a/public-dashboard-client/src/constants.js +++ b/public-dashboard-client/src/constants.js @@ -38,7 +38,6 @@ export const SECTION_TITLES = { [PATHS.sentencing]: { population: "Who is being sentenced?", types: "What types of sentences do people receive?", - recidivism: "How many people end up back in prison?", }, [PATHS.prison]: { population: "Who is in custody?", @@ -46,6 +45,7 @@ export const SECTION_TITLES = { reasons: "How did they get there?", terms: "How long are they there?", releases: "Where do they go from there?", + recidivism: "How many people end up back in prison?", }, [PATHS.probation]: { population: "Who is on probation?", diff --git a/public-dashboard-client/src/page-prison/PagePrison.js b/public-dashboard-client/src/page-prison/PagePrison.js index 0b407b28..e2b4c38f 100644 --- a/public-dashboard-client/src/page-prison/PagePrison.js +++ b/public-dashboard-client/src/page-prison/PagePrison.js @@ -1,7 +1,11 @@ -import React from "react"; +import React, { useMemo, useState } from "react"; import DetailPage from "../detail-page"; -import { PATHS, ALL_PAGES, SECTION_TITLES } from "../constants"; -import { formatLocation, recordIsMetricPeriodMonths } from "../utils"; +import { PATHS, ALL_PAGES, SECTION_TITLES, DIMENSION_KEYS } from "../constants"; +import { + assignOrderedDatavizColor, + formatLocation, + recordIsMetricPeriodMonths, +} from "../utils"; import useChartData from "../hooks/useChartData"; import Loading from "../loading"; import VizPopulationOverTime from "../viz-population-over-time"; @@ -9,6 +13,8 @@ import VizPrisonPopulation from "../viz-prison-population"; import VizPrisonReleases from "../viz-prison-releases"; import VizPrisonReasons from "../viz-prison-reasons"; import VizSentenceLengths from "../viz-sentence-lengths"; +import { CohortSelect, DimensionControl } from "../controls"; +import VizRecidivismRates from "../viz-recidivism-rates"; const TITLE = ALL_PAGES.get(PATHS.prison); const DESCRIPTION = ( @@ -20,9 +26,33 @@ const DESCRIPTION = ( ); +function getCohortOptions(data) { + const cohortsFromData = new Set(data.map((d) => d.release_cohort)); + return [...cohortsFromData] + .map((cohort) => ({ + id: cohort, + label: cohort, + })) + .map(assignOrderedDatavizColor); +} + export default function PagePrison() { const { apiData, isLoading } = useChartData("us_nd/prison"); + // lifted state for the recidivism section + const cohortOptions = useMemo( + () => + isLoading + ? [] + : getCohortOptions(apiData.recidivism_rates_by_cohort_by_year), + [apiData.recidivism_rates_by_cohort_by_year, isLoading] + ); + const [selectedCohorts, setSelectedCohorts] = useState([]); + const [highlightedCohort, setHighlightedCohort] = useState(); + const [recidivismDimension, setRecidivismDimension] = useState( + DIMENSION_KEYS.total + ); + if (isLoading) { return ; } @@ -33,6 +63,15 @@ export default function PagePrison() { labelFn: (record) => record.name, }); + const singleCohortSelected = selectedCohorts.length === 1; + + // doing this inside the render loop rather than in an effect + // to prevent an intermediate state from flashing on the chart; + // the current value check avoids an infinite render loop + if (!singleCohortSelected && recidivismDimension !== DIMENSION_KEYS.total) { + setRecidivismDimension(DIMENSION_KEYS.total); + } + const SECTIONS = [ { title: SECTION_TITLES[PATHS.prison].population, @@ -125,6 +164,39 @@ export default function PagePrison() { ), }, }, + { + title: SECTION_TITLES[PATHS.prison].recidivism, + description: ( + <> + After release from prison, a significant proportion of formerly + incarcerated folks end up back in prison. This is typically termed + “recidivism.” The below graph shows recidivism as reincarceration; + that is, the proportion of individuals who are incarcerated again at + some point after their release. + + ), + otherControls: ( + <> + + + + ), + VizComponent: VizRecidivismRates, + vizData: { + dimension: recidivismDimension, + highlightedCohort, + recidivismRates: apiData.recidivism_rates_by_cohort_by_year, + selectedCohorts, + }, + }, ]; return ( diff --git a/public-dashboard-client/src/page-sentencing/PageSentencing.js b/public-dashboard-client/src/page-sentencing/PageSentencing.js index be6248c8..4479a307 100644 --- a/public-dashboard-client/src/page-sentencing/PageSentencing.js +++ b/public-dashboard-client/src/page-sentencing/PageSentencing.js @@ -15,57 +15,22 @@ // along with this program. If not, see . // ============================================================================= -import React, { useMemo, useState } from "react"; +import React from "react"; import DetailPage from "../detail-page"; import useChartData from "../hooks/useChartData"; import Loading from "../loading"; -import VizRecidivismRates from "../viz-recidivism-rates"; + import VizSentencePopulation from "../viz-sentence-population"; import VizSentenceTypes from "../viz-sentence-types"; -import { PATHS, ALL_PAGES, SECTION_TITLES, DIMENSION_KEYS } from "../constants"; -import { CohortSelect, DimensionControl } from "../controls"; -import { assignOrderedDatavizColor } from "../utils"; - -function getCohortOptions(data) { - const cohortsFromData = new Set(data.map((d) => d.release_cohort)); - return [...cohortsFromData] - .map((cohort) => ({ - id: cohort, - label: cohort, - })) - .map(assignOrderedDatavizColor); -} +import { PATHS, ALL_PAGES, SECTION_TITLES } from "../constants"; export default function PageSentencing() { const { apiData, isLoading } = useChartData("us_nd/sentencing"); - // lifted state for the recidivism section - const cohortOptions = useMemo( - () => - isLoading - ? [] - : getCohortOptions(apiData.recidivism_rates_by_cohort_by_year), - [apiData.recidivism_rates_by_cohort_by_year, isLoading] - ); - const [selectedCohorts, setSelectedCohorts] = useState([]); - const [highlightedCohort, setHighlightedCohort] = useState(); - const [recidivismDimension, setRecidivismDimension] = useState( - DIMENSION_KEYS.total - ); - if (isLoading) { return ; } - const singleCohortSelected = selectedCohorts.length === 1; - - // doing this inside the render loop rather than in an effect - // to prevent an intermediate state from flashing on the chart; - // the current value check avoids an infinite render loop - if (!singleCohortSelected && recidivismDimension !== DIMENSION_KEYS.total) { - setRecidivismDimension(DIMENSION_KEYS.total); - } - const TITLE = ALL_PAGES.get(PATHS.sentencing); const DESCRIPTION = ( <> @@ -116,39 +81,6 @@ export default function PageSentencing() { locations: apiData.judicial_districts, }, }, - { - title: SECTION_TITLES[PATHS.sentencing].recidivism, - description: ( - <> - After release from prison, a significant proportion of formerly - incarcerated folks end up back in prison. This is typically termed - “recidivism.” The below graph shows recidivism as reincarceration; - that is, the proportion of individuals who are incarcerated again at - some point after their release. - - ), - otherControls: ( - <> - - - - ), - VizComponent: VizRecidivismRates, - vizData: { - dimension: recidivismDimension, - highlightedCohort, - recidivismRates: apiData.recidivism_rates_by_cohort_by_year, - selectedCohorts, - }, - }, ]; return ( diff --git a/spotlight-api/core/metricsApi.js b/spotlight-api/core/metricsApi.js index e339d429..8bf70117 100644 --- a/spotlight-api/core/metricsApi.js +++ b/spotlight-api/core/metricsApi.js @@ -59,6 +59,7 @@ const FILES_BY_METRIC_TYPE = { "incarceration_releases_by_type_by_period.json", "incarceration_lengths_by_demographics.json", "incarceration_population_by_month_by_demographics.json", + "recidivism_rates_by_cohort_by_year.json", ], probation: [ "active_program_participation_by_region.json", @@ -73,7 +74,6 @@ const FILES_BY_METRIC_TYPE = { sentencing: [ "judicial_districts.json", "sentence_type_by_district_by_demographics.json", - "recidivism_rates_by_cohort_by_year.json", ], };