Skip to content

Commit

Permalink
Merge fce98f5 into 915230b
Browse files Browse the repository at this point in the history
  • Loading branch information
nasaownsky committed Aug 30, 2021
2 parents 915230b + fce98f5 commit 86517fa
Show file tree
Hide file tree
Showing 20 changed files with 317 additions and 186 deletions.
22 changes: 2 additions & 20 deletions spotlight-client/src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,6 @@ describe("navigation", () => {
).toBeVisible();
});

test("tenant home", () => {
expect.hasAssertions();
const targetPath = "/us-nd";
const lookupArgs = ["heading", { name: /North Dakota/, level: 1 }] as const;

return verifyWithNavigation({ targetPath, lookupArgs });
});

test("single narrative page", () => {
expect.hasAssertions();
const targetPath = `/us-nd/${NarrativesSlug}/prison`;
Expand Down Expand Up @@ -128,7 +120,7 @@ describe("navigation", () => {
const homeLink = inNav.getByRole("link", { name: "Spotlight" });
const tenantLink = inNav.getByRole("link", { name: "North Dakota" });
const sentencingLink = await screen.findByRole("link", {
name: "Sentencing",
name: "Sentencing Data",
});

fireEvent.click(sentencingLink);
Expand All @@ -143,17 +135,7 @@ describe("navigation", () => {
fireEvent.click(tenantLink);
await waitFor(async () =>
expect(await screen.findByTestId("PageTitle")).toHaveTextContent(
"Explore correctional data from North Dakota."
)
);

const disparitiesLink = screen.getByRole("link", {
name: "Racial Disparities",
});
fireEvent.click(disparitiesLink);
await waitFor(async () =>
expect(await screen.findByTestId("PageTitle")).toHaveTextContent(
"Racial Disparities"
"Our mission is to transform lives, influence change, and strengthen community. Transparency is a critical element of our mission; sharing information builds greater accountability between the DOCR and the communities we serve."
)
);

Expand Down
20 changes: 14 additions & 6 deletions spotlight-client/src/MetricVizMapper/MetricVizMapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,29 @@ import ProgramParticipationCurrentMetric from "../contentModels/ProgramParticipa
import VizProgramParticipationCurrent from "../VizProgramParticipationCurrent";

type MetricVizMapperProps = {
metric: Metric<MetricRecord>;
metric: Metric<MetricRecord> | undefined;
preview?: boolean;
};

const MetricVizMapper: React.FC<MetricVizMapperProps> = ({ metric }) => {
const MetricVizMapper: React.FC<MetricVizMapperProps> = ({
metric,
preview,
}) => {
if (metric instanceof HistoricalPopulationBreakdownMetric) {
return <VizHistoricalPopulationBreakdown metric={metric} />;
return (
<VizHistoricalPopulationBreakdown preview={preview} metric={metric} />
);
}
if (metric instanceof PopulationBreakdownByLocationMetric) {
return <VizPopulationBreakdownByLocation metric={metric} />;
return (
<VizPopulationBreakdownByLocation preview={preview} metric={metric} />
);
}
if (metric instanceof DemographicsByCategoryMetric) {
if (metric.id === "PrisonStayLengthAggregate") {
return <VizPrisonStayLengths metric={metric} />;
}
return <VizDemographicsByCategory metric={metric} />;
return <VizDemographicsByCategory preview={preview} metric={metric} />;
}
if (metric instanceof RecidivismRateMetric) {
if (metric.id === "PrisonRecidivismRateSingleFollowupHistorical") {
Expand All @@ -65,7 +73,7 @@ const MetricVizMapper: React.FC<MetricVizMapperProps> = ({ metric }) => {
return <VizSupervisionSuccessRate metric={metric} />;
}
if (metric instanceof ProgramParticipationCurrentMetric) {
return <VizProgramParticipationCurrent metric={metric} />;
return <VizProgramParticipationCurrent preview={preview} metric={metric} />;
}

// there are no other metric types, so this should only be reached when developing new ones
Expand Down
41 changes: 34 additions & 7 deletions spotlight-client/src/OtherNarrativeLinks/OtherNarrativeLinks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import styled from "styled-components/macro";
import { track } from "../analytics";
import { TenantId } from "../contentApi/types";
import { Narrative } from "../contentModels/types";
import MetricVizMapper from "../MetricVizMapper";
import getUrlForResource from "../routerUtils/getUrlForResource";
import { useDataStore } from "../StoreProvider";
import { breakpoints, colors } from "../UiLibrary";
Expand All @@ -49,30 +50,32 @@ const LinkList = styled.ul`
const LinkListItem = styled.li`
/* creates gaps */
border: 0 solid transparent;
border-width: 0 ${rem(32)} ${rem(32)} 0;
border-width: 0 ${rem(32)} 0 0;
flex: 0 0 auto;
white-space: nowrap;
/* use width to create 1-4 columns, depending on screen size */
width: 100%;
@media (min-width: ${breakpoints.tablet[0]}px) {
width: calc(100% / 2);
width: calc(100% / 1);
}
@media (min-width: ${breakpoints.desktop[0]}px) {
width: calc(100% / 3);
width: calc(100% / 2);
}
@media (min-width: ${breakpoints.xl[0]}px) {
width: calc(100% / 4);
width: calc(100% / 2);
}
a {
border-top: 1px solid ${colors.rule};
border-bottom: 1px solid ${colors.rule};
color: ${colors.text};
display: block;
padding-right: ${rem(8)};
padding-top: ${rem(32)};
padding-top: ${rem(24)};
padding-bottom: ${rem(24)};
text-decoration: none;
width: 100%;
}
Expand All @@ -82,6 +85,14 @@ const LinkText = styled.span`
white-space: normal;
`;

const ChartTitle = styled.span`
font-size: ${rem(16)};
`;

const ChartPreview = styled.div`
padding-top: ${rem(16)};
`;

const NarrativeLink: React.FC<{
narrative: Narrative;
tenantId: TenantId;
Expand All @@ -91,6 +102,21 @@ const NarrativeLink: React.FC<{
from: { opacity: 0 },
}));

const renderChartPreview = () => {
if (narrative.preview)
return (
<MetricVizMapper
preview
metric={
narrative.sections.find(
(section) => section.metric.id === narrative.preview
)?.metric
}
/>
);
return null;
};

return (
<LinkListItem>
<Link
Expand All @@ -109,11 +135,13 @@ const NarrativeLink: React.FC<{
onMouseOut={() => setAnimationStyles({ opacity: 0 })}
onBlur={() => setAnimationStyles({ opacity: 0 })}
>
<LinkText>{narrative.title}</LinkText>&nbsp;
<LinkText>{narrative.title} Data</LinkText>&nbsp;
<animated.span style={animationStyles}>
<Arrow color={colors.link} direction="right" />
</animated.span>
</Link>
<ChartTitle>{narrative.subtitle}</ChartTitle>
<ChartPreview>{renderChartPreview()}</ChartPreview>
</LinkListItem>
);
});
Expand All @@ -132,7 +160,6 @@ const OtherNarrativeLinks = (): React.ReactElement | null => {

const narrativesToDisplay = [
...Object.values(tenant.systemNarratives),
tenant.racialDisparitiesNarrative,
].filter((narrative): narrative is Narrative => {
if (narrative === undefined) return false;
return narrative.id !== currentNarrativeTypeId;
Expand Down
15 changes: 5 additions & 10 deletions spotlight-client/src/PageTenant/PageTenant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import styled from "styled-components/macro";
import { NAV_BAR_HEIGHT } from "../constants";
import OtherNarrativeLinks from "../OtherNarrativeLinks";
import { useDataStore } from "../StoreProvider";
import { breakpoints, CopyBlock, PageSection, PageTitle } from "../UiLibrary";
import { breakpoints, PageSection, PageTitle } from "../UiLibrary";
import withRouteSync from "../withRouteSync";

const Introduction = styled(PageSection)`
Expand All @@ -35,6 +35,7 @@ const Introduction = styled(PageSection)`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
/* try to keep the links "above the fold" */
min-height: calc(100vh - ${rem(NAV_BAR_HEIGHT)} - ${rem(130)});
Expand All @@ -48,13 +49,8 @@ const Introduction = styled(PageSection)`
const Links = styled(PageSection)``;

const Title = styled(PageTitle)`
max-width: ${rem(760)};
`;

const Description = styled(CopyBlock)`
font-size: ${rem(20)};
line-height: 1.7;
max-width: ${rem(760)};
font-size: ${rem(40)};
max-width: ${rem(1100)};
`;

const PageTenant: React.FC<RouteComponentProps> = () => {
Expand All @@ -66,8 +62,7 @@ const PageTenant: React.FC<RouteComponentProps> = () => {
// tenant may be briefly undefined during initial page load
<article>
<Introduction>
<Title>{tenant.landingPageTitle}</Title>
<Description>{HTMLReactParser(tenant.description)}</Description>
<Title>{HTMLReactParser(tenant.description)}</Title>
</Introduction>
<Links>
<OtherNarrativeLinks />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,5 @@ test("renders charts", async () => {
const charts = await screen.findAllByRole("group", {
name: /\d+ bars in a bar chart/,
});
expect(charts.length).toBe(12);
expect(charts.length).toBe(24);
});
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ test("includes links to other narratives", () => {
const nav = screen.getByRole("navigation", { name: "data narratives" });

const otherLink = within(nav).getByRole("link", {
name: mockContentFixture.systemNarratives.Sentencing?.title,
name: `${mockContentFixture.systemNarratives.Sentencing?.title} Data`,
});

expect(otherLink).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ const content: TenantContent = {
systemNarratives: {
Parole: {
title: "test parole narrative",
subtitle: "test parole subtitle",
introduction: "test parole introduction",
sections: [
{
Expand All @@ -63,6 +64,7 @@ const content: TenantContent = {
},
Sentencing: {
title: "test sentencing narrative",
subtitle: "test sentencing subtitle",
introduction:
'test sentencing introduction <a href="https://example.com">intro link</a>',
sections: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ const CategoryBarWrapper = styled.div`

type VizDemographicsByCategoryProps = {
metric: DemographicsByCategoryMetric;
preview?: boolean;
};

const VizDemographicsByCategory: React.FC<VizDemographicsByCategoryProps> = ({
metric,
preview,
}) => {
const { highlighted, setHighlighted } = useHighlightedItem();

Expand All @@ -67,54 +69,61 @@ const VizDemographicsByCategory: React.FC<VizDemographicsByCategoryProps> = ({
);

if (dataSeries) {
return (
const viz = (
<AutoHeightTransition initialHeight={bubbleChartHeight}>
{chartTransitions.map(({ item, key, props }) => (
<ChartWrapper key={key}>
<animated.div style={props}>
{
// for type safety we have to check this again
// but it should always be defined if we've gotten this far
item.dataSeries &&
(item.demographicView === "total" ? (
<BubbleChart
height={bubbleChartHeight}
data={item.dataSeries[0].records}
preview={preview}
/>
) : (
item.dataSeries.map(
({ label, records }, index, categories) => (
<CategoryBarWrapper
key={label}
style={{
// prevents subsequent charts from covering up the tooltip for this one
zIndex: zIndex.base + categories.length - index,
}}
>
<ProportionalBar
data={records}
height={
barChartsHeight / categories.length -
barChartsGutter
}
title={label}
showLegend={index === categories.length - 1}
{...{ highlighted, setHighlighted }}
/>
</CategoryBarWrapper>
)
)
))
}
</animated.div>
</ChartWrapper>
))}
</AutoHeightTransition>
);

return preview ? (
viz
) : (
<>
<MetricVizControls
filters={[<DemographicFilterSelect metric={metric} />]}
metric={metric}
/>
<AutoHeightTransition initialHeight={bubbleChartHeight}>
{chartTransitions.map(({ item, key, props }) => (
<ChartWrapper key={key}>
<animated.div style={props}>
{
// for type safety we have to check this again
// but it should always be defined if we've gotten this far
item.dataSeries &&
(item.demographicView === "total" ? (
<BubbleChart
height={bubbleChartHeight}
data={item.dataSeries[0].records}
/>
) : (
item.dataSeries.map(
({ label, records }, index, categories) => (
<CategoryBarWrapper
key={label}
style={{
// prevents subsequent charts from covering up the tooltip for this one
zIndex: zIndex.base + categories.length - index,
}}
>
<ProportionalBar
data={records}
height={
barChartsHeight / categories.length -
barChartsGutter
}
title={label}
showLegend={index === categories.length - 1}
{...{ highlighted, setHighlighted }}
/>
</CategoryBarWrapper>
)
)
))
}
</animated.div>
</ChartWrapper>
))}
</AutoHeightTransition>
{viz}
<VizNotes smallData unknowns={unknowns} />
</>
);
Expand Down

0 comments on commit 86517fa

Please sign in to comment.