Skip to content

Commit

Permalink
Merge pull request #337 from visdesignlab/247-set-scale
Browse files Browse the repository at this point in the history
Ensure set scale updates when sets are added and removed
  • Loading branch information
NateLanza authored Apr 5, 2024
2 parents 31ac50b + 4cd304c commit c7dbe0f
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 2 deletions.
109 changes: 109 additions & 0 deletions e2e-tests/plot.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/* eslint-disable testing-library/prefer-screen-queries */
import { test, expect } from '@playwright/test';
import mockData from '../playwright/mock-data/simpsons/simpsons_data.json';
import mockAnnotations from '../playwright/mock-data/simpsons/simpsons_annotations.json';
import mockAltText from '../playwright/mock-data/simpsons/simpsons_alttxt.json';

test.beforeEach(async ({ page }) => {
await page.route('*/**/api/**', async (route) => {
const url = route.request().url();
let json;

if (url) {
if (url.includes('workspaces/Upset%20Examples/tables/simpsons/rows/?limit=9007199254740991')) {
json = mockData;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/tables/simpsons/annotations/')) {
json = mockAnnotations;
await route.fulfill({ json });
} else if (url.includes('alttxt')) {
json = mockAltText;
await route.fulfill({ json });
} else if (url.includes('workspaces/Upset%20Examples/sessions/table/193/state/')) {
await route.fulfill({ status: 200 });
} else {
await route.continue();
}
} else {
await route.abort();
}
});
});

/**
* Toggles the advanced scale slider. Must be awaited
* @param page page provided to test function
*/
async function toggleAdvancedScale(page) {
await page.getByText('Size', { exact: true }).click({
button: 'right',
force: true,
});
await page.getByRole('menuitem', { name: 'Toggle Advanced Scale' }).click();
}

/**
* Removes a visible set by name. Must be awaited
* @param page page provided to test
* @param setName name of set
*/
async function removeSetByName(page, setName: string) {
await page.locator('p').filter({ hasText: new RegExp('^' + setName + '$') }).click({ button: 'right' });
await page.getByRole('menuitem', { name: 'Remove Set: ' + setName }).click();
}

/**
* Adds an invisible set by name. Must be awaited
* @param page page provided to test
* @param setName name of set
*/
async function addSetByName(page, setName: string) {
await page.getByText(setName, { exact: true }).click({
button: 'right'
});
await page.getByRole('menuitem', { name: 'Add Set: ' + setName }).click();
}

/**
* Asserts that the max value of the size scale is equal to the given max value
* @param page page provided to test
* @param max max value to assert
*/
async function assertSizeScaleMax(page, max: number) {
await expect(page.locator('g.details-scale > g > g:last-child > text').nth(1))
.toHaveText(new RegExp('^' + max + '$'));
}

/**
* Tests that the size header resizes when sets are added/removed and the advanced scale slider works
*/
test('Size header', async ({ page }) => {
await page.goto('http://localhost:3000/?workspace=Upset+Examples&table=simpsons&sessionId=193');

// Ensure that the scale increases when necessary upon set removal
await assertSizeScaleMax(page, 3);
await removeSetByName(page, 'Blue Hair');
await assertSizeScaleMax(page, 5);

// Ensure that the scale decreases when necessary upon set removal
await removeSetByName(page, 'Male');
await assertSizeScaleMax(page, 8);

// Ensure that the scale updates upon set addition
await addSetByName(page, 'Male');
await assertSizeScaleMax(page, 5);

// Ensure that dragging the advanced slider works
await toggleAdvancedScale(page);
await page.locator('g').filter({ hasText: /^0055101015152020Size001122334455$/ }).locator('rect').nth(1).
dragTo(page.getByText('15', { exact: true }).nth(1), {force: true});
await assertSizeScaleMax(page, 15);

// Ensure that adding sets doesn't affect the advanced scale
await addSetByName(page, 'Blue Hair');
await assertSizeScaleMax(page, 15);

// Ensure that scale recalculates correctly when advanced is turned off
await toggleAdvancedScale(page);
await assertSizeScaleMax(page, 3);
});
4 changes: 4 additions & 0 deletions packages/upset/src/atoms/maxSizeAtom.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { atom } from 'recoil';

/**
* Max set size; used to set the size scale
* Either calculated automatically or manually set by the advanced scale slider
*/
export const maxSize = atom({
key: 'max-size',
default: -1,
Expand Down
8 changes: 6 additions & 2 deletions packages/upset/src/components/Header/SizeHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,19 @@ export const SizeHeader: FC = () => {
);
};

/**
* Updates the scale of the header based on the largest subset as long as the advanced scale slider hasn't taken
* control and set a value
*/
useEffect(() => {
if (maxC !== -1) return;
if (advancedScale) return;
const subs = Object.values(subsets.values);
if (subs.length === 0) return;

const sizes = subs.map((s) => s.size);
const maxS = Math.max(...sizes);
setMaxSize(maxS);
}, [subsets, maxSize]);
}, [subsets, maxSize, advancedScale]);

const globalScale = useScale([0, itemCount], [0, dimensions.attribute.width]);

Expand Down

0 comments on commit c7dbe0f

Please sign in to comment.