Skip to content

Commit

Permalink
Merge 00f3cbe into 739a0aa
Browse files Browse the repository at this point in the history
  • Loading branch information
macfarlandian committed Oct 30, 2020
2 parents 739a0aa + 00f3cbe commit 8036efd
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 76 deletions.
2 changes: 1 addition & 1 deletion public-dashboard-client/src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ 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?",
overTime: "How has the incarcerated population changed over time?",
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?",
Expand Down
78 changes: 75 additions & 3 deletions public-dashboard-client/src/page-prison/PagePrison.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
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";
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 = (
Expand All @@ -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 <Loading />;
}
Expand All @@ -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,
Expand Down Expand Up @@ -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: (
<>
<CohortSelect
options={cohortOptions}
onChange={setSelectedCohorts}
onHighlight={setHighlightedCohort}
/>
<DimensionControl
disabled={!singleCohortSelected}
onChange={setRecidivismDimension}
selectedId={recidivismDimension}
/>
</>
),
VizComponent: VizRecidivismRates,
vizData: {
dimension: recidivismDimension,
highlightedCohort,
recidivismRates: apiData.recidivism_rates_by_cohort_by_year,
selectedCohorts,
},
},
];

return (
Expand Down
74 changes: 3 additions & 71 deletions public-dashboard-client/src/page-sentencing/PageSentencing.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,57 +15,22 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =============================================================================

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 <Loading />;
}

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 = (
<>
Expand Down Expand Up @@ -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: (
<>
<CohortSelect
options={cohortOptions}
onChange={setSelectedCohorts}
onHighlight={setHighlightedCohort}
/>
<DimensionControl
disabled={!singleCohortSelected}
onChange={setRecidivismDimension}
selectedId={recidivismDimension}
/>
</>
),
VizComponent: VizRecidivismRates,
vizData: {
dimension: recidivismDimension,
highlightedCohort,
recidivismRates: apiData.recidivism_rates_by_cohort_by_year,
selectedCohorts,
},
},
];

return (
Expand Down
2 changes: 1 addition & 1 deletion spotlight-api/core/metricsApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
],
};

Expand Down

0 comments on commit 8036efd

Please sign in to comment.