Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
50 changes: 26 additions & 24 deletions dev-portal/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,17 @@
// Expand the package folder
expandedFolders[packageName] = true

// Also expand any subdirectory containing this config
// e.g., /examples/feature/bar.json -> expand "chart/feature"
// Expand all parent directories containing this config
// e.g., /examples/foo/bar/baz/file.json -> expand all parent paths
const pathWithinExamples = configPath.replace('/examples/', '')
const parts = pathWithinExamples.split('/')
if (parts.length > 1) {
// Has a subdirectory - expand it
expandedFolders[`${packageName}/${parts[0]}`] = true
// Build up path progressively and expand each directory level
let currentPath = '/examples/'
for (let i = 0; i < parts.length - 1; i++) {
currentPath += parts[i] + '/'
expandedFolders[`${packageName}:${currentPath}`] = true
}
}

// Update URL for shareable links (skip during popstate handling)
Expand All @@ -234,8 +238,8 @@

const caseInsensitiveSort = (a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' })

// Group files by directory (same logic as standalone sidebar)
function groupByDirectory(files) {
// Build a recursive tree structure for arbitrary nesting depth
function buildTree(files) {
const tree = { files: [], dirs: {} }
files.forEach(file => {
const parts = file.split('/')
Expand All @@ -247,38 +251,36 @@
tree.dirs[dir].push(parts.slice(1).join('/'))
}
})
// Recursively build subtrees for each directory
Object.keys(tree.dirs).forEach(dir => {
tree.dirs[dir] = buildTree(tree.dirs[dir])
})
return tree
}

// Render tree HTML for a package's examples
function renderPackageTree(packageName, tree) {
// Recursive function to render tree at any depth
function renderPackageTree(packageName, node, pathPrefix) {
let html = ''

// Root files
tree.files.sort(caseInsensitiveSort).forEach(file => {
const configPath = '/examples/' + file
// Render files at this level
node.files.sort(caseInsensitiveSort).forEach(file => {
const configPath = pathPrefix + file
const isActive = currentSelection?.packageName === packageName && currentSelection?.configPath === configPath
html += `<button class="dev-sidebar-item${
isActive ? ' active' : ''
}" data-package="${packageName}" data-config="${configPath}">${file}</button>`
})

// Subdirectories
Object.keys(tree.dirs)
// Render subdirectories recursively
Object.keys(node.dirs)
.sort(caseInsensitiveSort)
.forEach(dir => {
const folderId = `${packageName}/${dir}`
const dirPath = pathPrefix + dir + '/'
const folderId = `${packageName}:${dirPath}`
const isOpen = expandedFolders[folderId] ? ' open' : ''
html += `<div class="dev-sidebar-folder${isOpen}" data-folder-id="${folderId}">${dir}</div>`
html += `<div class="dev-sidebar-folder-contents">`
tree.dirs[dir].sort(caseInsensitiveSort).forEach(file => {
const configPath = '/examples/' + dir + '/' + file
const isActive =
currentSelection?.packageName === packageName && currentSelection?.configPath === configPath
html += `<button class="dev-sidebar-item${
isActive ? ' active' : ''
}" data-package="${packageName}" data-config="${configPath}">${file}</button>`
})
html += renderPackageTree(packageName, node.dirs[dir], dirPath)
html += '</div>'
})

Expand All @@ -291,10 +293,10 @@
const isOpen = expandedFolders[folderId] ? ' open' : ''

if (isOnline && examples) {
const tree = groupByDirectory(examples)
const tree = buildTree(examples)
let html = `<div class="dev-sidebar-folder dev-sidebar-package${isOpen}" data-folder-id="${folderId}" data-package="${packageName}">${packageName}</div>`
html += `<div class="dev-sidebar-folder-contents">`
html += renderPackageTree(packageName, tree)
html += renderPackageTree(packageName, tree, '/examples/')
html += '</div>'
return html
} else {
Expand Down
9 changes: 3 additions & 6 deletions packages/chart/examples/feature/annotations/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@
"dx": -46,
"dy": -50,
"opacity": "100",
"savedDimensions": [
498.59,
560.1875
],
"savedDimensions": [498.59, 560.1875],
"connectionType": "line",
"originalX": 295.8788908060575,
"originalDX": -46,
Expand Down Expand Up @@ -84,7 +81,7 @@
"hideLabel": false,
"hideTicks": false,
"size": "75",
"gridLines": false,
"gridLines": true,
"enablePadding": false,
"min": "",
"max": "",
Expand Down Expand Up @@ -539,4 +536,4 @@
},
"dynamicMarginTop": 0,
"version": "4.24.4"
}
}
16 changes: 12 additions & 4 deletions packages/chart/src/CdcChartComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import Loading from '@cdc/core/components/Loading'
import Filters from '@cdc/core/components/Filters'
import MediaControls from '@cdc/core/components/MediaControls'
import Annotation from './components/Annotations'
import { getVisibleAnnotations } from './components/Annotations/helpers/getVisibleAnnotations'
// Core Helpers
import { DataTransform } from '@cdc/core/helpers/DataTransform'
import { isLegendWrapViewport } from '@cdc/core/helpers/viewports'
Expand Down Expand Up @@ -1096,6 +1097,12 @@ const CdcChart: React.FC<CdcChartProps> = ({
return tableConfig
}

// Transform and clean data for chart rendering
const transformedData = getTransformedData({ brushData: state.brushData, filteredData, excludedData, clean })

// Filter annotations to only those visible in current data view
const visibleAnnotations = getVisibleAnnotations(config.annotations, transformedData, config.xAxis?.dataKey)

// Prevent render if loading
let body = <Loading />

Expand Down Expand Up @@ -1187,7 +1194,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
/>
)}
<SkipTo skipId={handleChartTabbing(config, legendId)} skipMessage='Skip Over Chart Container' />
{config.annotations?.length > 0 && (
{visibleAnnotations.length > 0 && (
<SkipTo
skipId={handleChartTabbing(config, legendId)}
skipMessage={`Skip over annotations`}
Expand Down Expand Up @@ -1410,7 +1417,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
</MediaControls.Section>
</div>
)}
{config?.annotations?.length > 0 && <Annotation.Dropdown />}
{visibleAnnotations.length > 0 && <Annotation.Dropdown />}
{/* show pdf or image button */}
{processedLegacyFootnotes && (
<section className='footnotes pt-2 mt-4'>{parse(processedLegacyFootnotes)}</section>
Expand Down Expand Up @@ -1483,10 +1490,11 @@ const CdcChart: React.FC<CdcChartProps> = ({
setSharedFilterValue,
svgRef,
tableData: filteredData || excludedData,
transformedData: getTransformedData({ brushData: state.brushData, filteredData, excludedData, clean }),
transformedData,
twoColorPalette,
unfilteredData: stateData,
updateConfig
updateConfig,
visibleAnnotations
}

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
.cdc-open-viz-module .annotation__desktop-label {
display: none;
line-height: 1.1rem;
font-size: 16px;
}

.cdc-open-viz-module {
.annotation__mobile-label-circle {
stroke-width: 2;
stroke-width: 1;
}

.annotation__has-dropdown-number {
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
padding: 8px;
width: 16px;
height: 16px;
border: 2px solid #666;
width: 24px;
height: 24px;
min-width: 24px;
min-height: 24px;
border: 1px solid #666;
text-align: center;
font-size: 14px;
}
}

@container content (min-width: 700px) {
.cdc-open-viz-module .annotation__mobile-label {
display: none;
}
.cdc-open-viz-module .annotation__desktop-label {
display: block;
box-sizing: border-box;
}
}
Loading