Skip to content

Commit

Permalink
Lump dataset blocks together when zooming out
Browse files Browse the repository at this point in the history
  • Loading branch information
danielfdsilva committed Sep 8, 2023
1 parent 4d341ed commit 982e217
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -367,51 +367,95 @@ function DatasetTrack(props: DatasetTrackProps) {
});
}, [xScaled, dataset]);

const blocks = lumpBlocks({
domain: domainToRender,
xScaled,
timeDensity: dataset.data.timeDensity
});

return (
<svg width={width} height={DATASET_TRACK_BLOCK_HEIGHT}>
{domainToRender.map((date) => (
{blocks.map(([blockStart, blockEnd]) => (
<DatasetTrackBlock
key={date.getTime()}
key={blockStart.getTime()}
xScaled={xScaled}
date={date}
dataset={dataset}
startDate={blockStart}
endDate={blockEnd}
isVisible={isVisible}
/>
))}
</svg>
);
}

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<number, number>;
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 (
<React.Fragment key={date.getTime()}>
<rect
fill={fill}
y={0}
height={DATASET_TRACK_BLOCK_HEIGHT}
x={s}
width={e - s}
rx={4}
/>
</React.Fragment>
<rect
fill={fill}
y={0}
height={DATASET_TRACK_BLOCK_HEIGHT}
x={s}
width={e - s}
rx={4}
/>
);
}
1 change: 1 addition & 0 deletions app/scripts/components/exploration/datasets-mock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ function makeDataset(
analysis = makeAnalysis({}, {})
) {
return {
mocked: true,
status,
data,
error: status === TimelineDatasetStatus.ERROR ? new Error('Mock error') : null,
Expand Down
3 changes: 2 additions & 1 deletion app/scripts/components/exploration/hooks/scales-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,36 +135,43 @@ 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[]]>(
(prev) => {
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);
Expand Down

0 comments on commit 982e217

Please sign in to comment.