Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

418 element view UI #433

Merged
merged 7 commits into from
Dec 3, 2024
Merged
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
1 change: 0 additions & 1 deletion e2e-tests/elementView.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ test('Query Selection', async ({ page }) => {
await page.goto('http://localhost:3000/?workspace=Upset+Examples&table=simpsons&sessionId=193');
await page.getByLabel('Element View Sidebar Toggle').click();
await page.locator('[id="Subset_School\\~\\&\\~Male"] g').filter({ hasText: /^Blue Hair$/ }).locator('circle').click();
await page.getByLabel('Selected intersection School').click();

// Selected elements for testing
const ralphCell = page.getByRole('cell', { name: 'Ralph' });
Expand Down
2 changes: 2 additions & 0 deletions packages/upset/src/components/ElementView/BookmarkChips.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export const BookmarkChips = () => {
});
}
}}
onClick={() => actions.setSelected(null)}
label={`${currentIntersectionDisplayName} - ${currentIntersection.size}`}
onDelete={() => {
actions.addBookmark<BookmarkedIntersection>({
Expand Down Expand Up @@ -144,6 +145,7 @@ export const BookmarkChips = () => {
actions.addBookmark(structuredClone(currentSelection));
}
}}
onClick={() => actions.setElementSelection(null)}
label={`${currentSelection.label}`}
onDelete={() => {
actions.addBookmark(structuredClone(currentSelection));
Expand Down
38 changes: 27 additions & 11 deletions packages/upset/src/components/ElementView/ElementSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { ElementVisualization } from './ElementVisualization';
import { UpsetActions } from '../../provenance';
import { ProvenanceContext } from '../Root';
import { QueryInterface } from './QueryInterface';
import { bookmarkSelector, currentIntersectionSelector } from '../../atoms/config/currentIntersectionAtom';

/**
* Props for the ElementSidebar component
Expand All @@ -33,8 +34,14 @@ type Props = {
close: () => void
}

const initialDrawerWidth = 450;
const minDrawerWidth = 100;
/**
* The *exact* width at which we don't get a horizontal scrollbar in the table controls
*/
const initialDrawerWidth = 462;
/**
* The *exact* width at which the 'apply' button in the element query controls is forced onto a new line
*/
const minDrawerWidth = 368;

/**
* Immediately downloads a csv containing items with the given columns
Expand Down Expand Up @@ -80,12 +87,14 @@ function downloadElementsAsCSV(items: Item[], columns: string[], name: string) {
export const ElementSidebar = ({ open, close }: Props) => {
const [fullWidth, setFullWidth] = useState(false);
const [drawerWidth, setDrawerWidth] = useState(initialDrawerWidth);
const currentSelection = useRecoilValue(selectedElementSelector);
const currentElementSelection = useRecoilValue(selectedElementSelector);
const selectedItems = useRecoilValue(selectedItemsSelector);
const itemCount = useRecoilValue(selectedItemsCounter);
const columns = useRecoilValue(columnsAtom);
const [hideElementSidebar, setHideElementSidebar] = useState(!open);
const { actions }: {actions: UpsetActions} = useContext(ProvenanceContext);
const bookmarked = useRecoilValue(bookmarkSelector);
const currentIntersection = useRecoilValue(currentIntersectionSelector);

/**
* Effects
Expand Down Expand Up @@ -156,6 +165,9 @@ export const ElementSidebar = ({ open, close }: Props) => {
left: 0,
zIndex: 100,
backgroundColor: '#f4f7f9',
// I cannot comprehend why this is the value that works. It is.
// The 'rows per page' controls overflow otherwise (:
paddingBottom: '1625px',
Comment on lines +168 to +170
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried to figure this out and I agree. Somewhat of a mystery...

}}
onMouseDown={(e) => handleMouseDown(e)}
/>
Expand Down Expand Up @@ -189,7 +201,7 @@ export const ElementSidebar = ({ open, close }: Props) => {
<IconButton
onClick={() => {
setHideElementSidebar(true);
actions.setElementSelection(currentSelection);
actions.setElementSelection(currentElementSelection);
close();
}}
aria-label="Close the sidebar"
Expand All @@ -198,16 +210,20 @@ export const ElementSidebar = ({ open, close }: Props) => {
</IconButton>
</div>
<div style={{ marginBottom: '1em' }}>
<Typography variant="h2" fontSize="1.2em" fontWeight="inherit" gutterBottom>
<Typography variant="h2" fontSize="1.4em" fontWeight="inherit" gutterBottom>
Element View
</Typography>
<Divider />
</div>
<Typography variant="h3" fontSize="1.2em">
Bookmarked Queries
</Typography>
<Divider />
<BookmarkChips />
{(bookmarked.length > 0 || currentIntersection || currentElementSelection) && (
<>
<Typography variant="h3" fontSize="1.2em">
Bookmarked Queries
</Typography>
<Divider />
<BookmarkChips />
</>
)}
<Typography variant="h3" fontSize="1.2em">
Element Visualization
</Typography>
Expand All @@ -226,7 +242,7 @@ export const ElementSidebar = ({ open, close }: Props) => {
downloadElementsAsCSV(
selectedItems,
columns,
currentSelection?.label ?? 'upset_elements',
currentElementSelection?.label ?? 'upset_elements',
);
}}
>
Expand Down
6 changes: 4 additions & 2 deletions packages/upset/src/components/Header/AttributeButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useContext } from 'react';
import React, { FC, useContext } from 'react';
import { useSetRecoilState, useRecoilValue } from 'recoil';
import { SortByOrder, AttributePlotType } from '@visdesignlab/upset2-core';

Expand Down Expand Up @@ -63,12 +63,14 @@ export const AttributeButton: FC<Props> = ({ label, tooltip }) => {
* If the attribute is not currently sorted, it sorts it in ascending order.
* If the attribute is already sorted, it toggles between ascending and descending order.
*/
const handleOnClick = () => {
const handleOnClick = (e: React.MouseEvent<SVGElement>) => {
if (sortBy !== label) {
sortByHeader('Ascending');
} else {
sortByHeader(sortByOrder === 'Ascending' ? 'Descending' : 'Ascending');
}
// To prevent the handler on SvgBase that deselects the current intersection
e.stopPropagation();
};

/**
Expand Down
6 changes: 4 additions & 2 deletions packages/upset/src/components/Header/DegreeHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { css } from '@emotion/react';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useContext } from 'react';
import React, { useContext } from 'react';
import { Tooltip } from '@mui/material';
import { sortByOrderSelector, sortBySelector } from '../../atoms/config/sortByAtom';
import translate from '../../utils/transform';
Expand All @@ -23,12 +23,14 @@ export const DegreeHeader = () => {
actions.sortBy('Degree', order);
};

const handleOnClick = () => {
const handleOnClick = (e: React.MouseEvent<SVGElement>) => {
if (sortBy !== 'Degree') {
sortByDegree('Ascending');
} else {
sortByDegree(sortByOrder === 'Ascending' ? 'Descending' : 'Ascending');
}
// To prevent the handler on SvgBase that deselects the current intersection
e.stopPropagation();
};

const handleContextMenuClose = () => {
Expand Down
6 changes: 4 additions & 2 deletions packages/upset/src/components/Header/SizeHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { css } from '@emotion/react';
import { drag } from 'd3-drag';
import { select } from 'd3-selection';
import {
import React, {
FC, useContext, useEffect, useRef, useState,
} from 'react';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
Expand Down Expand Up @@ -51,12 +51,14 @@ export const SizeHeader: FC = () => {
actions.sortBy('Size', order);
};

const handleOnClick = () => {
const handleOnClick = (e: React.MouseEvent<SVGElement>) => {
if (sortBy !== 'Size') {
sortBySize('Ascending');
} else {
sortBySize(sortByOrder === 'Ascending' ? 'Descending' : 'Ascending');
}
// To prevent the handler on SvgBase that deselects the current intersection
e.stopPropagation();
};

const handleContextMenuClose = () => {
Expand Down
9 changes: 8 additions & 1 deletion packages/upset/src/components/SvgBase.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { css } from '@emotion/react';
import { FC } from 'react';
import { FC, useContext } from 'react';
import { useRecoilValue } from 'recoil';

import translate from '../utils/transform';
import { dimensionsSelector } from '../atoms/dimensionsAtom';
import { ProvenanceContext } from './Root';
import { currentIntersectionSelector } from '../atoms/config/currentIntersectionAtom';

/** @jsxImportSource @emotion/react */
type SvgBaseSettings = {
Expand All @@ -18,13 +20,18 @@ type Props = {

export const SvgBase: FC<Props> = ({ children, defaultSettings }) => {
const { height, width, margin } = defaultSettings || useRecoilValue(dimensionsSelector);
const { actions } = useContext(ProvenanceContext);
const selectedIntersection = useRecoilValue(currentIntersectionSelector);

return (
// These rules are for accessibility; unnecessary here as the plot is not accessible anyway.
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
<div
css={css`
height: 100%;
width: 100%;
`}
onClick={() => { if (selectedIntersection != null) actions.setSelected(null); }}
>
<svg id="upset-svg" height={height + 50 * margin} width={width + 2 * margin} xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="full" fontFamily="Roboto, Arial">
<g transform={translate(margin)}>
Expand Down
Loading