Skip to content

Commit 14f8e10

Browse files
authored
Merge pull request #2280 from CDCgov/dev
Dev
2 parents 60326c1 + 1722e96 commit 14f8e10

File tree

98 files changed

+23480
-709
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+23480
-709
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ ehthumbs.db
88
Thumbs.db
99

1010
# IDE Specific
11+
.claude
12+
CLAUDE.local.md
1113
nbproject
1214
.~lock.*
1315
.buildpath

cove_events.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Analytics Events Documentation
2+
3+
## Overview
4+
5+
This system tracks user interactions across various data visualization components in the COVE (Data Visualization) platform. Events are categorized by visualization type, user action, and specific interaction patterns.
6+
7+
## Visualization Types
8+
The following visualization types are supported across various events
9+
```.ts
10+
export type COVE_VISUALIZATION_TYPES =
11+
| 'map'
12+
| 'chart'
13+
| 'data-table'
14+
| 'markup-include'
15+
| 'waffle-chart'
16+
| 'dashboard'
17+
| 'filtered-text'
18+
| 'table-filter'
19+
| 'data-bite'
20+
| 'unknown'
21+
```
22+
23+
## Event Actions
24+
```.ts
25+
export type ANALYTICS_EVENT_ACTIONS =
26+
| 'click'
27+
| 'drag'
28+
| 'toggle'
29+
| 'none'
30+
| 'keydown'
31+
| 'load'
32+
| 'submit'
33+
| 'change'
34+
| 'unknown'
35+
```
36+
37+
## Data Specific Events
38+
39+
| EventType | EventAction | EventLabel |
40+
| ------------------------------------------------------------------ | ------------------- | ----------- |
41+
| `data_downloaded` | `See Event Actions` | `configUrl` |
42+
| `data_table_toggled` | `See Event Actions` | .. |
43+
| `data_viewed` | `See Event Actions` | .. |
44+
| `data_table_sort_by\|${string}\|${'asc' \| 'desc' \| 'undefined'}` | `See Event Actions` | .. |
45+
| `link_to_data_table_click` | `See Event Actions` | .. |
46+
| | | |
47+
48+
## Visualization-Specific Events
49+
50+
| EventType | EventAction | EventLabel |
51+
| ----------------------------------------------- | ------------------- | ------------------------------------------- |
52+
| `${viz_type}_filter_reset` | `See Event Actions` | `configUrl` |
53+
| `${viz_type}_filter_applied` | `See Event Actions` | `configUrl|filter_val_1,filter_val2` |
54+
| `${viz_type}_filter_changed` | `See Event Actions` | `configUrl|key_filterKey|value_filterValue` |
55+
| `${viz_type}_image_downloaded` | `See Event Actions` | `configUrl` |
56+
| `${viz_type}_legend_item_toggled--${mode}-mode` | `See Event Actions` | `configUrl|legend-item-text` |
57+
| `${viz_type}_legend_reset` | `See Event Actions` | `configUrl` |
58+
| `${viz_type}_loaded` | `See Event Actions` | `configUrl` |
59+
| `${viz_type}_navigation_menu` | `See Event Actions` | `${configUrl}|${urlString}` |
60+
| `${viz_type}_panned` | `See Event Actions` | `configUrl` |
61+
| `${viz_type}_reset_zoom_level` | `See Event Actions` | `configUrl` |
62+
| `${viz_type}_zoomed_in` | `See Event Actions` | `configUrl|zoom_level|zoom_location` |
63+
| `${viz_type}_zoomed_out` | `See Event Actions` | `configUrl|zoom_level|zoom_location` |
64+
| | | |
65+
66+
67+
## Legend Toggle Modes
68+
- `highlight`
69+
- `isolate`
70+
71+
## Usage Example
72+
73+
```typescript
74+
publishAnalyticsEvent('data_downloaded', 'click', '/path/to/config.json')
75+
```

packages/chart/src/CdcChart.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,16 @@ interface CdcChartProps {
1414
isEditor?: boolean
1515
isDebug?: boolean
1616
config?: ChartConfig
17+
interactionLabel?: string
1718
}
1819

19-
const CdcChartWrapper: React.FC<CdcChartProps> = ({ configUrl, isEditor, isDebug, config: editorsConfig }) => {
20+
const CdcChartWrapper: React.FC<CdcChartProps> = ({
21+
configUrl,
22+
isEditor,
23+
isDebug,
24+
config: editorsConfig,
25+
interactionLabel = ''
26+
}) => {
2027
const editorContext = useContext(EditorContext)
2128
const [config, _setConfig] = useState<ChartConfig>({} as ChartConfig)
2229
const setConfig = newConfig => {
@@ -89,7 +96,7 @@ const CdcChartWrapper: React.FC<CdcChartProps> = ({ configUrl, isEditor, isDebug
8996

9097
if (isLoading) return <Loading />
9198

92-
return <CdcChart config={config} isEditor={isEditor} isDebug={isDebug} />
99+
return <CdcChart config={config} isEditor={isEditor} isDebug={isDebug} interactionLabel={interactionLabel} />
93100
}
94101

95102
export default CdcChartWrapper

packages/chart/src/CdcChartComponent.tsx

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ import { VizFilter } from '@cdc/core/types/VizFilter'
8282
import { getNewRuntime } from './helpers/getNewRuntime'
8383
import FootnotesStandAlone from '@cdc/core/components/Footnotes/FootnotesStandAlone'
8484
import { Datasets } from '@cdc/core/types/DataSet'
85+
import { publishAnalyticsEvent } from '@cdc/core/helpers/metrics/helpers'
8586

8687
interface CdcChartProps {
8788
config?: ChartConfig
@@ -96,6 +97,7 @@ interface CdcChartProps {
9697
setSharedFilterValue?: (value: any) => void
9798
dashboardConfig?: DashboardConfig
9899
datasets?: Datasets
100+
interactionLabel: string
99101
}
100102
const CdcChart: React.FC<CdcChartProps> = ({
101103
config: configObj,
@@ -108,7 +110,8 @@ const CdcChart: React.FC<CdcChartProps> = ({
108110
setSharedFilter,
109111
setSharedFilterValue,
110112
dashboardConfig,
111-
datasets
113+
datasets,
114+
interactionLabel
112115
}) => {
113116
const transform = new DataTransform()
114117
const initialState = getInitialState(configObj)
@@ -465,6 +468,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
465468
if (container && !isLoading && !_.isEmpty(config) && !coveLoadedEventRan) {
466469
publish('cove_loaded', { config: config })
467470
dispatch({ type: 'SET_LOADED_EVENT', payload: true })
471+
publishAnalyticsEvent('chart_loaded', 'load', interactionLabel, 'chart')
468472
}
469473
}, [container, config, isLoading]) // eslint-disable-line
470474

@@ -554,6 +558,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
554558
} catch (e) {
555559
console.error('COVE:', e.message)
556560
}
561+
publishAnalyticsEvent('chart_legend_reset', 'click', interactionLabel, 'chart')
557562
dispatch({ type: 'SET_SERIES_HIGHLIGHT', payload: [] })
558563
}
559564

@@ -907,6 +912,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
907912
setFilters={setFilters}
908913
excludedData={excludedData}
909914
dimensions={dimensions}
915+
interactionLabel={interactionLabel}
910916
/>
911917
)}
912918
<SkipTo skipId={handleChartTabbing(config, legendId)} skipMessage='Skip Over Chart Container' />
@@ -985,6 +991,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
985991
setFilters={setFilters}
986992
excludedData={excludedData}
987993
dimensions={dimensions}
994+
interactionLabel={interactionLabel}
988995
/>
989996
{config?.introText && (
990997
<section className='introText mb-4' style={{ padding: '0px 0 35px' }}>
@@ -1012,7 +1019,11 @@ const CdcChart: React.FC<CdcChartProps> = ({
10121019
{!config.legend.hide &&
10131020
config.visualizationType !== 'Spark Line' &&
10141021
config.visualizationType !== 'Sankey' && (
1015-
<Legend ref={legendRef} skipId={handleChartTabbing(config, legendId)} />
1022+
<Legend
1023+
ref={legendRef}
1024+
skipId={handleChartTabbing(config, legendId)}
1025+
interactionLabel={interactionLabel}
1026+
/>
10161027
)}
10171028
</LegendWrapper>
10181029
{/* Link */}
@@ -1034,6 +1045,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
10341045
type='image'
10351046
state={config}
10361047
elementToCapture={imageId}
1048+
interactionLabel={interactionLabel}
10371049
/>
10381050
)}
10391051
{config.table.showDownloadPdfButton && (
@@ -1043,6 +1055,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
10431055
type='pdf'
10441056
state={config}
10451057
elementToCapture={imageId}
1058+
interactionLabel={interactionLabel}
10461059
/>
10471060
)}
10481061
</MediaControls.Section>
@@ -1054,7 +1067,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
10541067
(config.visualizationType === 'Sankey' && config.table.show)) && (
10551068
<DataTable
10561069
/* changing the "key" will force the table to re-render
1057-
when the default sort changes while editing */
1070+
when the default sort changes while editing */
10581071
key={dataTableDefaultSortBy}
10591072
config={pivotDynamicSeries(config)}
10601073
rawData={
@@ -1076,6 +1089,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
10761089
viewport={currentViewport}
10771090
tabbingId={handleChartTabbing(config, legendId)}
10781091
colorScale={colorScale}
1092+
interactionLabel={interactionLabel}
10791093
/>
10801094
)}
10811095
{config?.annotations?.length > 0 && <Annotation.Dropdown />}

packages/chart/src/components/BarChart/components/BarChart.Horizontal.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,15 @@ export const BarChartHorizontal = () => {
115115
numbericBarHeight = 25
116116
}
117117
let barY = bar.value >= 0 && isNumber(bar.value) ? bar.y : yScale(scaleVal)
118-
const defaultBarWidth = Math.abs(xScale(bar.value) - xScale(scaleVal))
118+
let defaultBarWidth = Math.abs(xScale(bar.value) - xScale(scaleVal))
119119
const isPositiveBar = bar.value >= 0 && isNumber(bar.value)
120120

121+
const MINIMUM_BAR_HEIGHT = 3
122+
if (isPositiveBar && barGroup.bars.length === 1 && defaultBarWidth < MINIMUM_BAR_HEIGHT) {
123+
defaultBarWidth = MINIMUM_BAR_HEIGHT
124+
barY = yScale(0) - MINIMUM_BAR_HEIGHT
125+
}
126+
121127
const barX = bar.value < 0 ? Math.abs(xScale(bar.value)) : xScale(scaleVal)
122128
const yAxisValue = formatNumber(bar.value, 'left')
123129
const xAxisValue =
@@ -166,7 +172,7 @@ export const BarChartHorizontal = () => {
166172
</li></ul>`
167173

168174
// configure colors
169-
let labelColor = '#000000'
175+
let labelColor = APP_FONT_COLOR
170176
labelColor = HighLightedBarUtils.checkFontColor(yAxisValue, highlightedBarValues, labelColor) // Set if background is transparent'
171177
let barColor =
172178
config.runtime.seriesLabels && config.runtime.seriesLabels[bar.key]
@@ -184,7 +190,7 @@ export const BarChartHorizontal = () => {
184190
const borderColor = isHighlightedBar
185191
? highlightedBarColor
186192
: config.barHasBorder === 'true'
187-
? '#000'
193+
? APP_FONT_COLOR
188194
: 'transparent'
189195
const borderWidth = isHighlightedBar
190196
? highlightedBar.borderWidth
@@ -298,7 +304,7 @@ export const BarChartHorizontal = () => {
298304
: pd.symbol === 'Double Asterisk'
299305
? barHeight
300306
: barHeight / 1.5
301-
const fillColor = pd.displayGray ? '#8b8b8a' : '#000'
307+
const fillColor = pd.displayGray ? '#8b8b8a' : APP_FONT_COLOR
302308
return (
303309
<Text // prettier-ignore
304310
key={index}
@@ -366,7 +372,7 @@ export const BarChartHorizontal = () => {
366372
display={displayBar ? 'block' : 'none'}
367373
x={bar.y}
368374
y={0}
369-
fill={'#000000'}
375+
fill={APP_FONT_COLOR}
370376
dx={textPaddingLollipop}
371377
textAnchor={textAnchorLollipop}
372378
verticalAnchor='middle'

packages/chart/src/components/BarChart/components/BarChart.StackedHorizontal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ const BarChartStackedHorizontal = () => {
137137
<Text
138138
x={`${bar.x + (config.isLollipopChart ? 15 : 5)}`} // padding
139139
y={bar.y + bar.height * 1.2}
140-
fill={'#000000'}
140+
fill={APP_FONT_COLOR}
141141
textAnchor='start'
142142
verticalAnchor='start'
143143
>

0 commit comments

Comments
 (0)