Skip to content

Commit

Permalink
Merge pull request #1846 from CDCgov/test
Browse files Browse the repository at this point in the history
Test
  • Loading branch information
adamdoe authored Jan 16, 2025
2 parents 347414f + 9e9405e commit 2cb5636
Show file tree
Hide file tree
Showing 18 changed files with 175 additions and 340 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -233,12 +233,12 @@ export const BarChartVertical = () => {
const xPos = barX + (config.xAxis.type !== 'date-time' ? barWidth / 2 : 0)

const upperPos = yScale(
datum.dynamicData && datum.CI[bar.key]
datum.dynamicData && datum?.CI?.[bar.key]
? datum.CI[bar.key].upper
: datum[config.confidenceKeys.upper]
)
const lowerPos = yScale(
datum.dynamicData && datum.CI[bar.key]
datum.dynamicData && datum?.CI?.[bar.key]
? datum.CI[bar.key].lower
: datum[config.confidenceKeys.lower]
)
Expand Down
19 changes: 14 additions & 5 deletions packages/chart/src/components/LinearChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
useEffect(() => {
if (lastMaxValue.current === maxValue) return
lastMaxValue.current = maxValue

if (!yAxisAutoPadding) return
setYAxisAutoPadding(0)
}, [maxValue])
Expand All @@ -419,12 +420,20 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
const maxValueIsGreaterThanTopGridLine = maxValue > Math.max(...yScale.ticks(handleNumTicks))

if (!maxValueIsGreaterThanTopGridLine || !labelsOverflow) return

const tickGap = yScale.ticks(handleNumTicks)[1] - yScale.ticks(handleNumTicks)[0]
const ticks = yScale.ticks(handleNumTicks)
const tickGap = ticks.length === 1 ? ticks[0] : ticks[1] - ticks[0]
const nextTick = Math.max(...yScale.ticks(handleNumTicks)) + tickGap
const newPadding = minValue < 0 ? (nextTick - maxValue) / maxValue / 2 : (nextTick - maxValue) / maxValue
const divideBy = minValue < 0 ? maxValue / 2 : maxValue
const calculatedPadding = (nextTick - maxValue) / divideBy

// if auto padding is too close to next tick, add one more ticks worth of padding
const PADDING_THRESHOLD = 0.025
const newPadding =
calculatedPadding > PADDING_THRESHOLD ? calculatedPadding : calculatedPadding + tickGap / divideBy

setYAxisAutoPadding(newPadding * 100)
/* sometimes even though the padding is getting to the next tick exactly,
d3 still doesn't show the tick. we add 0.1 to ensure to tip it over the edge */
setYAxisAutoPadding(newPadding * 100 + 0.1)
}, [maxValue, labelsOverflow, yScale, handleNumTicks])

// Render Functions
Expand All @@ -433,7 +442,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p

const getTickPositions = (ticks, xScale) => {
if (!ticks.length) return false
// filterout first index
// filter out first index
const filteredTicks = ticks.filter(tick => tick.index !== 0)
const numberOfTicks = filteredTicks?.length
const xMaxHalf = xScale.range()[0] || xMax / 2
Expand Down
6 changes: 3 additions & 3 deletions packages/core/components/DataTable/DataTableStandAlone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import DataTableEditorPanel from './components/DataTableEditorPanel'
import Filters from '../Filters'
import { TableConfig } from './types/TableConfig'
import { filterVizData } from '../../helpers/filterVizData'
import { addValuesToFilters } from '../../helpers/addValuesToFilters'

type StandAloneProps = {
visualizationKey: string
Expand All @@ -28,9 +29,8 @@ const DataTableStandAlone: React.FC<StandAloneProps> = ({

useEffect(() => {
// when using editor changes to filter should update the data
setFilteredData(
filterVizData(config.filters, config?.formattedData?.length > 0 ? config.formattedData : config.data)
)
const filters = addValuesToFilters(config.filters, config.data)
setFilteredData(filterVizData(filters, config?.formattedData?.length > 0 ? config.formattedData : config.data))
}, [config.filters])

if (isEditor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,17 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
handleFilterOrder={(index1, index2) => handleFilterOrder(index1, index2, filterIndex)}
/>
)}
{filter.order === 'column' && (
<Select
value={filter.orderColumn}
fieldName='orderColumn'
label='Order Column'
updateField={(_section, _subSection, _field, value) =>
updateFilterProp('orderColumn', filterIndex, value)
}
options={dataColumns}
/>
)}
</>
) : (
<NestedDropdownEditor
Expand Down Expand Up @@ -274,6 +285,7 @@ const VizFilterEditor: React.FC<VizFilterProps> = ({ config, updateField, rawDat
updateFilterProp('parents', filterIndex, value)
}}
options={getParentFilterOptions(filterIndex)}
selected={config.filters[filterIndex].parents}
/>
</label>
</FieldSetWrapper>
Expand Down
53 changes: 26 additions & 27 deletions packages/core/components/Filters/Filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,25 @@ export const filterOrderOptions: { label: string; value: OrderBy }[] = [
{
label: 'Custom',
value: 'cust'
}
},
{ label: 'Order By Data Column', value: 'column' }
]

const hasStandardFilterBehavior = ['chart', 'table']

export const useFilters = props => {
const [showApplyButton, setShowApplyButton] = useState(false)

// Desconstructing: notice, adding more descriptive visualizationConfig name over config
// visualizationConfig feels more robust for all vis types so that its not confused with config/state/etc.
const { config: visualizationConfig, setConfig, filteredData, setFilteredData, excludedData, getUniqueValues } = props
const { type, data } = visualizationConfig
const {
config: visualizationConfig,
setConfig,
filteredData,
setFilteredData,
excludedData,
getUniqueValues,
standaloneMap
} = props
const { data } = visualizationConfig

/**
* Re-orders a filter based on two indices and updates the runtime filters array and filters state
Expand All @@ -72,9 +79,7 @@ export const useFilters = props => {
const [movedItem] = updatedValues.splice(idx1, 1)
updatedValues.splice(idx2, 0, movedItem)

const filtersCopy = hasStandardFilterBehavior.includes(visualizationConfig.type)
? [...visualizationConfig.filters]
: [...filteredData]
const filtersCopy = !standaloneMap ? [...visualizationConfig.filters] : [...filteredData]
const filterItem = { ...filtersCopy[filterIndex] }

// Overwrite filterItem.values since thats what we map through in the editor panel
Expand All @@ -86,15 +91,15 @@ export const useFilters = props => {
// Update the filters
filtersCopy[filterIndex] = filterItem

if (visualizationConfig.type === 'map') {
if (standaloneMap) {
setFilteredData(filtersCopy)
}

setConfig({ ...visualizationConfig, filters: filtersCopy })
}

const changeFilterActive = (index, value) => {
let newFilters = visualizationConfig.type === 'map' ? [...filteredData] : [...visualizationConfig.filters]
let newFilters = standaloneMap ? [...filteredData] : [...visualizationConfig.filters]

if (visualizationConfig.filterBehavior === 'Apply Button') {
newFilters[index].queuedActive = value
Expand All @@ -120,7 +125,7 @@ export const useFilters = props => {
queryParams[newFilter?.subGrouping?.setByQueryParameter] = newFilter.subGrouping.active
updateQueryString(queryParams)
}
setFilteredData(newFilters[index])
setFilteredData(newFilters)
}

if (!visualizationConfig.dynamicSeries) {
Expand All @@ -132,15 +137,12 @@ export const useFilters = props => {
}

// Used for setting active filter, fromHash breaks the filteredData functionality.
if (visualizationConfig.type === 'map' && visualizationConfig.filterBehavior === 'Filter Change') {
if (standaloneMap && visualizationConfig.filterBehavior === 'Filter Change') {
setFilteredData(newFilters)
}

// If we're on a chart and not using the apply button
if (
hasStandardFilterBehavior.includes(visualizationConfig.type) &&
visualizationConfig.filterBehavior === 'Filter Change'
) {
if (!standaloneMap && visualizationConfig.filterBehavior === 'Filter Change') {
const newFilteredData = filterVizData(newFilters, excludedData)
setFilteredData(newFilteredData)

Expand Down Expand Up @@ -204,11 +206,9 @@ export const useFilters = props => {

setConfig({ ...visualizationConfig, filters: newFilters })

if (type === 'map') {
if (standaloneMap) {
setFilteredData(newFilters, excludedData)
}

if (hasStandardFilterBehavior.includes(visualizationConfig.type)) {
} else {
setFilteredData(filterVizData(newFilters, excludedData))
}

Expand Down Expand Up @@ -240,7 +240,7 @@ export const useFilters = props => {

setConfig({ ...visualizationConfig, filters: newFilters })

if (type === 'map') {
if (standaloneMap) {
setFilteredData(newFilters, excludedData)
} else {
setFilteredData(filterVizData(newFilters, excludedData))
Expand Down Expand Up @@ -274,13 +274,12 @@ type FilterProps = {
setFilteredData: Function
// updating function for setting fitlerBehavior
setConfig: Function
// exclusions
exclusions: any[]
standaloneMap?: boolean
}

const Filters = (props: FilterProps) => {
const { config: visualizationConfig, filteredData, dimensions } = props
const { filters, type, general, theme, filterBehavior } = visualizationConfig
const { config: visualizationConfig, filteredData, dimensions, standaloneMap } = props
const { filters, general, theme, filterBehavior } = visualizationConfig
const [mobileFilterStyle, setMobileFilterStyle] = useState(false)
const [selectedFilter, setSelectedFilter] = useState<EventTarget>(null)
const id = useId()
Expand Down Expand Up @@ -363,7 +362,7 @@ const Filters = (props: FilterProps) => {

const vizFiltersWithValues = useMemo(() => {
// Here charts is using config.filters where maps is using a runtime value
let vizfilters = type === 'map' ? filteredData : filters
let vizfilters = standaloneMap ? filteredData : filters
if (!vizfilters) return []
if (vizfilters.fromHash) delete vizfilters.fromHash // support for Maps config
return addValuesToFilters(vizfilters as VizFilter[], visualizationConfig.data)
Expand Down Expand Up @@ -492,7 +491,7 @@ const Filters = (props: FilterProps) => {
const getClasses = () => {
const { visualizationType, legend } = visualizationConfig || {}
const baseClass = 'filters-section'
const conditionalClass = type === 'map' ? general.headerColor : visualizationType === 'Spark Line' ? null : theme
const conditionalClass = standaloneMap ? general.headerColor : visualizationType === 'Spark Line' ? null : theme
const legendClass = legend && !legend.hide && legend.position === 'top' ? 'mb-0' : null

return [baseClass, conditionalClass, legendClass].filter(Boolean)
Expand Down
5 changes: 5 additions & 0 deletions packages/core/components/Filters/helpers/handleSorting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ export const handleSorting = singleFilter => {
return singleFilter
}

if (singleFilter.order === 'column') {
// sorting is done in the generateValuesForFilter function
return singleFilter
}

const sort = (a, b) => {
const asc = singleFilter.order !== 'desc'
return String(asc ? a : b).localeCompare(String(asc ? b : a), 'en', { numeric: true })
Expand Down
30 changes: 22 additions & 8 deletions packages/core/helpers/addValuesToFilters.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import _ from 'lodash'
import { getQueryStringFilterValue } from '@cdc/core/helpers/queryStringUtils'
import { VizFilter } from '../types/VizFilter'
import { FILTER_STYLE } from '@cdc/dashboard/src/types/FilterStyles'

type Filter = {
columnName: string
Expand Down Expand Up @@ -28,13 +29,16 @@ const cleanLookup = (lookup: Record<string, { values: string[]; orderedValues?:
// Gets filter values from dataset
const generateValuesForFilter = (filter: VizFilter, data: any[] | MapData) => {
const columnName = filter.columnName
const orderColumn = filter.orderColumn
const values: string[] = []
const valuesWithOrders: [string, string][] = []
const subGroupingColumn = filter.subGrouping?.columnName
const subValues = cleanLookup(filter.subGrouping?.valuesLookup)
if (Array.isArray(data)) {
data.forEach(row => {
const value = row[columnName]
const value: string = row[columnName]
if (value !== undefined && !values.includes(value)) {
if (orderColumn) valuesWithOrders.push([value, row[orderColumn]])
values.push(value)
}
if (subGroupingColumn) {
Expand All @@ -57,12 +61,23 @@ const generateValuesForFilter = (filter: VizFilter, data: any[] | MapData) => {
rows.forEach(row => {
const value = row[columnName]
if (value !== undefined && !values.includes(value)) {
if (orderColumn) valuesWithOrders.push([value, row[orderColumn]])
values.push(value)
}
})
})
}
filter.values = values
if (orderColumn) {
filter.values = valuesWithOrders.sort((a, b) => a[1].localeCompare(b[1])).map(([value]) => value)
} else if (filter.order && filter.order !== 'cust') {
const sort = (a, b) => {
const asc = filter.order !== 'desc'
return String(asc ? a : b).localeCompare(String(asc ? b : a), 'en', { numeric: true })
}
filter.values = values.sort(sort)
} else {
filter.values = values
}
if (subGroupingColumn) {
filter.subGrouping.valuesLookup = subValues
}
Expand All @@ -72,7 +87,7 @@ const handleVizParents = (filter: VizFilter, data: any[] | MapData, filtersLooku
let filteredData = Array.isArray(data) ? data : Object.values(data).flat(1)
filter.parents.forEach(parentKey => {
const parent = filtersLookup[parentKey]
if (parent?.filterStyle === 'nested-dropdown') {
if (parent?.filterStyle === FILTER_STYLE.nestedDropdown) {
const { subGrouping } = parent as VizFilter
if (subGrouping?.active) {
filteredData = filteredData.filter(d => {
Expand Down Expand Up @@ -107,11 +122,11 @@ export const addValuesToFilters = (filters: VizFilter[], data: any[] | MapData):
filteredData = handleVizParents(filter as VizFilter, data, filtersLookup)
}
generateValuesForFilter(filterCopy, filteredData)
if (filterCopy.values.length > 0) {
if (filterCopy.values?.length > 0) {
const queryStringFilterValue = getQueryStringFilterValue(filterCopy)
if (queryStringFilterValue) {
filterCopy.active = queryStringFilterValue
} else if (filterCopy.filterStyle === 'multi-select') {
} else if (filterCopy.filterStyle === FILTER_STYLE.multiSelect) {
const defaultValues = filterCopy.values
const active = Array.isArray(filterCopy.active) ? filterCopy.active : [filterCopy.active]
filterCopy.active = active.filter(val => includes(defaultValues, val))
Expand All @@ -128,12 +143,11 @@ export const addValuesToFilters = (filters: VizFilter[], data: any[] | MapData):
values: filterCopy.subGrouping.valuesLookup[groupName].values
}
const queryStringFilterValue = getQueryStringFilterValue(subGroupingFilter)
const groupActive = filterCopy.active || filterCopy.values[0]
const groupActive = groupName || filterCopy.values[0]
const defaultValue = filterCopy.subGrouping.valuesLookup[groupActive as string].values[0]
// if the value doesn't exist in the subGrouping then return the default
const filteredLookupValues = Object.values(filterCopy.subGrouping.valuesLookup).flatMap(v => v.values)
const activeValue = queryStringFilterValue || filterCopy.subGrouping.active
filterCopy.subGrouping.active = filteredLookupValues.includes(activeValue) ? activeValue : defaultValue
filterCopy.subGrouping.active = activeValue || defaultValue
}
return filterCopy
})
Expand Down
2 changes: 1 addition & 1 deletion packages/core/helpers/coveUpdateWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const coveUpdateWorker = config => {
['4.24.5', update_4_24_5],
['4.24.7', update_4_24_7, true],
['4.24.9', update_4_24_9],
['4.24.10', update_4_24_10]
['4.24.10', update_4_24_10, true]
]

versions.forEach(([version, updateFunction, alwaysRun]: [string, UpdateFunction, boolean?]) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/helpers/filterVizData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ export const filterVizData = (filters: Filter[], data) => {
}
if (filter.filterStyle === 'nested-dropdown' && filter.subGrouping && add === true) {
const subGroupActive = filter.subGrouping.active
const value = row[filter.subGrouping.columnName]
const subGroupValue = row[filter.subGrouping.columnName]
if (subGroupActive === undefined) return
if (value != subGroupActive) {
if (subGroupValue != subGroupActive) {
add = false
}
}
Expand Down
Loading

0 comments on commit 2cb5636

Please sign in to comment.