Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontend: Refactors Rate bar chart to D3 #3713

Merged
merged 28 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e97ed69
check in converted csv files
benhammondmusic Aug 13, 2024
be9a61d
rm zip
benhammondmusic Aug 13, 2024
15ea97d
comment
benhammondmusic Sep 16, 2024
3bab247
hm
benhammondmusic Sep 16, 2024
ab98ec5
biome
benhammondmusic Sep 16, 2024
0c4bc4d
adds d3 bar chart component
benhammondmusic Oct 9, 2024
2c8618d
Merge branch 'main' of https://github.com/SatcherInstitute/health-equ…
benhammondmusic Oct 9, 2024
13848a2
looking good
benhammondmusic Oct 9, 2024
abdee16
tweaks intersectional all
benhammondmusic Oct 10, 2024
55dcdf2
adds hover tooltip
benhammondmusic Oct 10, 2024
1fef735
mobile tap
benhammondmusic Oct 10, 2024
f67a395
handle mobile tooltip; swap sides
benhammondmusic Oct 10, 2024
ec6fb4c
rm warnings; unneeded string formatting
benhammondmusic Oct 10, 2024
123e208
rn
benhammondmusic Oct 10, 2024
bf05f2a
ready
benhammondmusic Oct 10, 2024
48d99b8
split files
benhammondmusic Oct 10, 2024
6451fc8
extract hook and gridlines component
benhammondmusic Oct 10, 2024
55f75a6
extract labels and axis
benhammondmusic Oct 10, 2024
7886dc8
updates
benhammondmusic Oct 10, 2024
f638731
adds helper tests
benhammondmusic Oct 10, 2024
ef203ab
only add 100k to bar label if not tiny screen
benhammondmusic Oct 11, 2024
942cb93
fix hook
benhammondmusic Oct 11, 2024
516a6b2
a11y
benhammondmusic Oct 11, 2024
7a0819e
more aria
benhammondmusic Oct 11, 2024
5626434
a11y match old tests
benhammondmusic Oct 11, 2024
1d2f4b3
e2e
benhammondmusic Oct 11, 2024
8ead7c4
merge in pre-sorting pr
benhammondmusic Oct 11, 2024
22e16ae
extract more components
benhammondmusic Oct 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 44 additions & 15 deletions frontend/playwright-tests/depression.nightly.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,55 @@ import { test } from '@playwright/test'
test('Depression Flow', async ({ page }) => {
await page.goto('/exploredata?mls=1.depression-3.00&group1=All')
await page
.getByLabel(
'Map showing Depression in the United States : including data from 50 states/territories'
)
.getByRole('img')
await page.getByRole('button', { name: 'Expand state/territory rate' }).click();
.locator('#rate-map')
.getByRole('heading', { name: 'Depression in the United' })
.click()
await page
.locator('#rate-map')
.getByRole('heading', { name: 'Ages 18+' })
.click()
await page
.getByRole('button', { name: 'Rates over time', exact: true })
.click()
await page
.getByRole('heading', { name: 'Depression cases over time in' })
.click()
await page
.getByLabel(
'Bar Chart showing Depression in the United States, by Race and Ethnicity'
)
.getByRole('img')
.locator('#rates-over-time')
.getByRole('heading', { name: 'Ages 18+' })
.click()
await page.getByText('cases per 100k adults →').click()
await page.getByText('time →').click()
await page
.locator('#rates-over-time')
.getByText('Note. (NH) indicates ‘Non-')
.click()
await page.getByRole('button', { name: 'Rate chart' }).click()
await page
.locator('#rate-chart')
.getByRole('heading', { name: 'Depression in the United' })
.click()
await page
.locator('#rate-chart')
.getByRole('heading', { name: 'Ages 18+' })
.click()
await page.locator('#rate-chart').getByText('All').click()
await page.locator('#rate-chart').getByText('race and ethnicity').click()
await page.locator('#rate-chart').getByText('cases per 100k adults').click()
await page.getByRole('button', { name: 'Unknown demographic map' }).click()
await page.getByText('No unknown values for race').click()
await page.getByRole('button', { name: 'Data table' }).click()
await page
.getByRole('heading', { name: 'Summary for depression in the' })
.click()
await page
.getByRole('heading', {
name: 'Share of total adult depression cases with unknown race and ethnicity in the United States',
})
.getByRole('figure', { name: 'Summary for depression in the' })
.locator('h4')
.click()
await page.getByRole('columnheader', { name: 'Race and Ethnicity' }).click()
await page
.getByText(
'No unknown values for race and ethnicity reported in this dataset at the state/t'
)
.getByRole('columnheader', { name: 'Cases of depression per 100k' })
.click()
await page.getByRole('columnheader', { name: 'Share of total adult' }).click()
await page.getByRole('columnheader', { name: 'Population share' }).click()
})
2 changes: 1 addition & 1 deletion frontend/playwright-tests/diabetes.ci.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ test('Diabetes County', async ({ page }) => {
.locator('#rate-map')
.getByRole('heading', { name: 'Ages 18+' })
.click()
await page.getByLabel('Legend for rate map').getByRole('img').click()
await page.getByLabel('Legend for rate map').click()
await page.locator('li').filter({ hasText: 'Denver County' }).click()
await page
.locator('#rate-chart')
Expand Down
33 changes: 19 additions & 14 deletions frontend/playwright-tests/modals.ci.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { test, expect } from '@playwright/test'

test.setTimeout(120000);
test.setTimeout(120000)

test('Topic Info Modal from Sidebar', async ({ page }) => {
// Compare Topics Page Loads
await page.goto(
'/exploredata?mls=1.incarceration-3.poverty-5.13&mlp=comparevars&dt1=prison',
{ waitUntil: 'commit' }
{ waitUntil: 'commit' },
)

// Clicking topic info modal button launched modal
Expand All @@ -27,24 +27,29 @@ test('Topic Info Modal from Sidebar', async ({ page }) => {

test.describe('Topic Info Modal from Map Legend', () => {
test('Topic Info Modal from Map Legend', async ({ page }) => {
await page.goto('/', { waitUntil: 'commit' });
await page.locator('#landingPageCTA').click();
const reportSection = await page.getByRole('heading', { name: 'Uninsurance in FL' }).locator('..');
await reportSection.locator('text=Explore this report').click();
await page.locator('#rate-map').getByRole('button', { name: 'Click for more info on uninsured people' }).click();
});
});
await page.goto('/', { waitUntil: 'commit' })
await page.locator('#landingPageCTA').click()
const reportSection = await page
.getByRole('heading', { name: 'Uninsurance in FL' })
.locator('..')
await reportSection.locator('text=Explore this report').click()
await page
.locator('#rate-map')
.getByRole('button', { name: 'Click for more info on uninsured people' })
.click()
})
})

test('Multiple Maps 1 (Left Side)', async ({ page }) => {
// Compare Topics Page With Multimap Open Loads
await page.goto(
'/exploredata?mls=1.incarceration-3.poverty-5.13&mlp=comparevars&dt1=prison&multiple-maps=true',
{ waitUntil: 'commit' }
{ waitUntil: 'commit' },
)
await expect(
page.getByRole('heading', {
name: 'Prison incarceration in Georgia across all race and ethnicity groups',
})
}),
).toBeVisible()

// CLOSE IT
Expand All @@ -56,21 +61,21 @@ test('Multiple Maps 2 (Right Side)', async ({ page }) => {
// Compare Topics Page Loads
await page.goto(
'/exploredata?mls=1.incarceration-3.poverty-5.13&mlp=comparevars&dt1=prison',
{ waitUntil: 'commit' }
{ waitUntil: 'commit' },
)

// Clicking right side multiple maps button launches POVERTY multimap modal
await page
.locator('#rate-map2')
.getByLabel(
'Launch multiple maps view with side-by-side maps of each race and ethnicity group'
'Launch multiple maps view with side-by-side maps of each race and ethnicity group',
)
.click()
await expect(page).toHaveURL(/.*multiple-maps2=true/)
await expect(
page.getByRole('heading', {
name: 'People below the poverty line in Georgia across all race and ethnicity groups',
})
}),
).toBeVisible()

// CLOSE IT
Expand Down
2 changes: 1 addition & 1 deletion frontend/playwright-tests/voter_participation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ test('Voter Participation Flow', async ({ page }) => {
.locator('#rate-chart')
.getByRole('heading', { name: 'U.S. citizens, Ages 18+' })
.click()
await page.getByLabel('Bar Chart showing Voter').getByRole('img').click()
await page.getByLabel('Bar Chart showing Voter').click()
await page.getByRole('heading', { name: 'Share of all voter' }).click()
await page.getByText('No unknown values for race').click()
await page
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { addComparisonAllsRowToIntersectionalData } from '../charts/simpleBarHelperFunctions'
import { SimpleHorizontalBarChart } from '../charts/SimpleHorizontalBarChart'
import { addComparisonAllsRowToIntersectionalData } from '../charts/rateBarChart/helpers'
import { RateBarChart } from '../charts/rateBarChart/Index'
import { generateChartTitle, generateSubtitle } from '../charts/utils'
import type { DataTypeConfig, MetricId } from '../data/config/MetricConfigTypes'
import { isPctType } from '../data/config/MetricConfigUtils'
Expand Down Expand Up @@ -35,8 +35,7 @@ import MissingDataAlert from './ui/MissingDataAlert'
/* minimize layout shift */
const PRELOAD_HEIGHT = 668

interface SimpleBarChartCardProps {
key?: string
interface RateBarChartCardProps {
demographicType: DemographicType
dataTypeConfig: DataTypeConfig
fips: Fips
Expand All @@ -46,16 +45,7 @@ interface SimpleBarChartCardProps {

// This wrapper ensures the proper key is set to create a new instance when
// required rather than relying on the card caller.
export default function SimpleBarChartCard(props: SimpleBarChartCardProps) {
return (
<SimpleBarChartCardWithKey
key={props.dataTypeConfig.dataTypeId + props.demographicType}
{...props}
/>
)
}

function SimpleBarChartCardWithKey(props: SimpleBarChartCardProps) {
export default function RateBarChartCard(props: RateBarChartCardProps) {
const rateConfig =
props.dataTypeConfig.metrics?.per100k ??
props.dataTypeConfig.metrics?.pct_rate ??
Expand Down Expand Up @@ -185,11 +175,10 @@ function SimpleBarChartCardWithKey(props: SimpleBarChartCardProps) {
) : (
<>
<ChartTitle title={chartTitle} subtitle={subtitle} />

<SimpleHorizontalBarChart
<RateBarChart
data={data}
demographicType={props.demographicType}
metric={rateConfig}
metricConfig={rateConfig}
filename={filename}
usePercentSuffix={isPctType(rateConfig.type)}
fips={props.fips}
Expand Down
86 changes: 0 additions & 86 deletions frontend/src/charts/SimpleHorizontalBarChart.tsx

This file was deleted.

28 changes: 28 additions & 0 deletions frontend/src/charts/rateBarChart/BarChartTooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export interface BarChartTooltipData {
x: number
y: number
content: string
}

interface BarChartTooltipProps {
data: BarChartTooltipData | null
}

export default function BarChartTooltip({ data }: BarChartTooltipProps) {
if (!data) return null
const clickIsLeftHalfOfScreen = data.x < window.innerWidth / 2
return (
<div
className='bg-white text-altBlack rounded-sm p-3 text-title absolute cursor-help z-top shadow-raised opacity-95 smMd:whitespace-nowrap'
style={{
left: `${data.x}px`,
top: `${data.y}px`,
transform: clickIsLeftHalfOfScreen
? 'translate(0, 5%)'
: 'translate(-100%, 5%)',
}}
>
{data.content}
</div>
)
}
32 changes: 32 additions & 0 deletions frontend/src/charts/rateBarChart/EndOfBarLabel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { MetricConfig } from '../../data/config/MetricConfigTypes'
import { formatValue } from './helpers'

interface EndOfBarLabelProps {
metricConfig: MetricConfig
d: Record<string, any>
shouldLabelBeInside: boolean
barWidth: number
yScale: any
benhammondmusic marked this conversation as resolved.
Show resolved Hide resolved
barLabelColor: string
isTinyAndUp: boolean
}

export default function EndOfBarLabel(props: EndOfBarLabelProps) {
return (
<text
x={props.shouldLabelBeInside ? props.barWidth - 5 : props.barWidth + 5}
y={props.yScale.bandwidth() / 2}
dy='1.3em'
textAnchor={props.shouldLabelBeInside ? 'end' : 'start'}
className={`text-smallest ${props.barLabelColor}`}
aria-hidden='true'
tabIndex={-1}
>
{formatValue(
props.d[props.metricConfig.metricId],
props.metricConfig,
props.isTinyAndUp,
)}
</text>
)
}
Loading
Loading