diff --git a/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx b/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx index a5805e264..ecc3d7f17 100644 --- a/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx +++ b/app/scripts/components/exploration/components/datasets/dataset-list-item.tsx @@ -367,14 +367,20 @@ function DatasetTrack(props: DatasetTrackProps) { }); }, [xScaled, dataset]); + const blocks = lumpBlocks({ + domain: domainToRender, + xScaled, + timeDensity: dataset.data.timeDensity + }); + return ( - {domainToRender.map((date) => ( + {blocks.map(([blockStart, blockEnd]) => ( ))} @@ -382,36 +388,74 @@ function DatasetTrack(props: DatasetTrackProps) { ); } +function lumpBlocks({ domain, xScaled, timeDensity }) { + const MIIIIN = 4; + + // How big would a block be? + const [start, end] = getBlockBoundaries(domain[0], timeDensity); + + const blockWidth = xScaled(end) - xScaled(start); + + if (blockWidth >= MIIIIN) { + return domain.map((d) => getBlockBoundaries(d, timeDensity)); + } + + let blocks: Date[][] = []; + let startBoundary = start; + let endBoundary = end; + + for (let i = 0; i < domain.length; i++) { + if (i === domain.length - 1) { + blocks = [...blocks, [startBoundary, endBoundary]]; + break; + } + + const nextDate = domain[i + 1]; + const [startNext, endNext] = getBlockBoundaries(nextDate, timeDensity); + + // Distance between the end of the current block and the start of the next. + const distance = xScaled(startNext) - xScaled(endBoundary); + + if (distance < MIIIIN / 2) { + endBoundary = endNext; + continue; + } + + blocks = [...blocks, [startBoundary, endBoundary]]; + startBoundary = startNext; + endBoundary = endNext; + } + + return blocks; +} + interface DatasetTrackBlockProps { xScaled: ScaleTime; - date: Date; - dataset: TimelineDatasetSuccess; + startDate: Date; + endDate: Date; isVisible: boolean; } function DatasetTrackBlock(props: DatasetTrackBlockProps) { - const { xScaled, date, dataset, isVisible } = props; + const { xScaled, startDate, endDate, isVisible } = props; const theme = useTheme(); - const [start, end] = getBlockBoundaries(date, dataset.data.timeDensity); - const s = xScaled(start); - const e = xScaled(end); + const s = xScaled(startDate); + const e = xScaled(endDate); const fill = isVisible ? theme.color?.['base-400'] : theme.color?.['base-200']; return ( - - - + ); } diff --git a/app/scripts/components/exploration/datasets-mock.tsx b/app/scripts/components/exploration/datasets-mock.tsx index b8f28a53c..11b096f3c 100644 --- a/app/scripts/components/exploration/datasets-mock.tsx +++ b/app/scripts/components/exploration/datasets-mock.tsx @@ -373,6 +373,7 @@ function makeDataset( analysis = makeAnalysis({}, {}) ) { return { + mocked: true, status, data, error: status === TimelineDatasetStatus.ERROR ? new Error('Mock error') : null, diff --git a/app/scripts/components/exploration/hooks/scales-hooks.ts b/app/scripts/components/exploration/hooks/scales-hooks.ts index 164da9643..c004ccbc6 100644 --- a/app/scripts/components/exploration/hooks/scales-hooks.ts +++ b/app/scripts/components/exploration/hooks/scales-hooks.ts @@ -25,7 +25,8 @@ export function useScaleFactors() { const domainDays = differenceInCalendarDays(dataDomain[1], dataDomain[0]); return { - k0: Math.max(1, DAY_SIZE_MIN / (contentWidth / domainDays)), + // k0: Math.max(1, DAY_SIZE_MIN / (contentWidth / domainDays)), + k0: 1, k1: DAY_SIZE_MAX / (contentWidth / domainDays) }; }, [contentWidth, dataDomain]); diff --git a/app/scripts/components/exploration/hooks/use-stac-metadata-datasets.ts b/app/scripts/components/exploration/hooks/use-stac-metadata-datasets.ts index 8e038e0ca..2d5ffa008 100644 --- a/app/scripts/components/exploration/hooks/use-stac-metadata-datasets.ts +++ b/app/scripts/components/exploration/hooks/use-stac-metadata-datasets.ts @@ -135,7 +135,9 @@ export function useStacMetadataOnDatasets() { const [datasets, setDatasets] = useAtom(timelineDatasetsAtom); const datasetsQueryData = useQueries({ - queries: datasets.map((dataset) => makeQueryObject(dataset)) + queries: datasets + .filter((d) => !(d as any).mocked) + .map((dataset) => makeQueryObject(dataset)) }); useEffectPrevious<[typeof datasetsQueryData, TimelineDataset[]]>( @@ -143,28 +145,33 @@ export function useStacMetadataOnDatasets() { const prevQueryData = prev[0]; if (!prevQueryData) return; - const { changed, data: updatedDatasets } = datasets.reduce<{ - changed: boolean; - data: TimelineDataset[]; - }>( - (acc, dataset, idx) => { - const curr = datasetsQueryData[idx]; - - if (didDataChange(curr, prevQueryData[idx])) { - // Changed - return { - changed: true, - data: [...acc.data, reconcileQueryDataWithDataset(curr, dataset)] - }; - } else { - return { - ...acc, - data: [...acc.data, dataset] - }; - } - }, - { changed: false, data: [] } - ); + const { changed, data: updatedDatasets } = datasets + .filter((d) => !(d as any).mocked) + .reduce<{ + changed: boolean; + data: TimelineDataset[]; + }>( + (acc, dataset, idx) => { + const curr = datasetsQueryData[idx]; + + if (didDataChange(curr, prevQueryData[idx])) { + // Changed + return { + changed: true, + data: [ + ...acc.data, + reconcileQueryDataWithDataset(curr, dataset) + ] + }; + } else { + return { + ...acc, + data: [...acc.data, dataset] + }; + } + }, + { changed: false, data: [] } + ); if (changed as boolean) { setDatasets(updatedDatasets);