Show page labels + default mapping to 1

This commit is contained in:
Johannes Zillmann 2021-03-29 08:47:04 +02:00
parent 98972d67a8
commit 71ef84153c
22 changed files with 58 additions and 28 deletions

View File

@ -2,7 +2,7 @@
* Holds the information which (zero based) page index maps to a page number. * Holds the information which (zero based) page index maps to a page number.
*/ */
export default class PageMapping { export default class PageMapping {
constructor(public pageFactor: number, public detectedOnPage: boolean) {} constructor(public pageFactor: number = 1, public detectedOnPage: boolean = false) {}
/** /**
* Translates a given page index to a page number label as printed on the page. E.g [0,1,2,3,4] could become [I, II, 1, 2]. * Translates a given page index to a page number label as printed on the page. E.g [0,1,2,3,4] could become [I, II, 1, 2].
@ -10,10 +10,14 @@ export default class PageMapping {
*/ */
pageLabel(pageIndex: number) { pageLabel(pageIndex: number) {
const pageNumber = pageIndex + this.pageFactor; const pageNumber = pageIndex + this.pageFactor;
if (pageNumber < 0) { if (pageNumber < 1) {
return romanize(pageNumber - this.pageFactor + 1); return romanize(Math.abs(pageNumber - this.pageFactor) + 1);
} }
return `${pageNumber + 1}`; return `${pageNumber}`;
}
shifted(): boolean {
return this.pageFactor != 1;
} }
} }

View File

@ -73,7 +73,6 @@ export default class CalculateStatistics extends ItemTransformer {
const groupedByPage = groupByPage(items); const groupedByPage = groupByPage(items);
const pageMapping = parsePageMapping(groupedByPage, minX, maxX, minY, maxY); const pageMapping = parsePageMapping(groupedByPage, minX, maxX, minY, maxY);
console.log(pageMapping);
// Parse line distances // Parse line distances
const distanceToOccurrence = {}; const distanceToOccurrence = {};
@ -165,7 +164,7 @@ function parsePageMapping(
}), }),
{ sampleCount: 20, minFulfillment: 0.8 }, { sampleCount: 20, minFulfillment: 0.8 },
); );
return typeof pageFactor === 'undefined' ? new PageMapping(0, false) : new PageMapping(pageFactor, true); return typeof pageFactor === 'undefined' ? new PageMapping() : new PageMapping(pageFactor, true);
} }
function getMostUsedKey(keyToOccurrence): any { function getMostUsedKey(keyToOccurrence): any {

View File

@ -25,6 +25,10 @@ export default class Globals {
return element; return element;
} }
getOptional<T>(definition: GlobalDefinition<T>): T | undefined {
return this.map.get(definition.key) as T;
}
set<T>(definition: GlobalDefinition<T>, value: T) { set<T>(definition: GlobalDefinition<T>, value: T) {
assertNot(this.isDefined(definition), `Global with key '${definition.key}' already registered.`); assertNot(this.isDefined(definition), `Global with key '${definition.key}' already registered.`);
this.map.set(definition.key, value); this.map.set(definition.key, value);

View File

@ -1,12 +1,17 @@
import PageMapping from 'src/PageMapping'; import PageMapping from 'src/PageMapping';
test('1-to-1', async () => { test('1-to-1', async () => {
const mapping = new PageMapping(0, false); const mapping = new PageMapping(1, false);
expect(mapping.pageFactor).toEqual(0); expect(mapping.pageFactor).toEqual(1);
expect([...Array(3).keys()].map((i) => mapping.pageLabel(i))).toEqual(['1', '2', '3']); expect([...Array(3).keys()].map((i) => mapping.pageLabel(i))).toEqual(['1', '2', '3']);
}); });
test('lame start', async () => { test('one starter page', async () => {
const mapping = new PageMapping(-3, true); const mapping = new PageMapping(0, true);
expect([...Array(5).keys()].map((i) => mapping.pageLabel(i))).toEqual(['I', '1', '2', '3', '4']);
});
test('three starter pages', async () => {
const mapping = new PageMapping(-2, true);
expect([...Array(5).keys()].map((i) => mapping.pageLabel(i))).toEqual(['I', 'II', 'III', '1', '2']); expect([...Array(5).keys()].map((i) => mapping.pageLabel(i))).toEqual(['I', 'II', 'III', '1', '2']);
}); });

View File

@ -8,6 +8,7 @@ test('not set', async () => {
const globals = new Globals(); const globals = new Globals();
globals.set(MyGlobalString, '23'); globals.set(MyGlobalString, '23');
expect(globals.isDefined(MyGlobalNumber)).toBeFalsy(); expect(globals.isDefined(MyGlobalNumber)).toBeFalsy();
expect(globals.getOptional(MyGlobalNumber)).toBeUndefined();
expect(() => globals.get(MyGlobalNumber)).toThrow( expect(() => globals.get(MyGlobalNumber)).toThrow(
`No global with key '${MyGlobalNumber.key}' registered. Only [${MyGlobalString.key}]`, `No global with key '${MyGlobalNumber.key}' registered. Only [${MyGlobalString.key}]`,
); );
@ -19,6 +20,7 @@ test('set', async () => {
expect(globals.isDefined(MyGlobalNumber)).toBeTruthy(); expect(globals.isDefined(MyGlobalNumber)).toBeTruthy();
expect(globals.get(MyGlobalNumber)).toEqual(24); expect(globals.get(MyGlobalNumber)).toEqual(24);
expect(globals.getOptional(MyGlobalNumber)).toEqual(24);
expect(globals.keys()).toEqual([MyGlobalNumber.key]); expect(globals.keys()).toEqual([MyGlobalNumber.key]);
}); });

View File

@ -33,7 +33,7 @@
"minY": 36.1763, "minY": 36.1763,
"maxY": 811.1348, "maxY": 811.1348,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -37,7 +37,7 @@
"minY": 36.1763, "minY": 36.1763,
"maxY": 811.1348, "maxY": 811.1348,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -36,7 +36,7 @@
"minY": 36.1763, "minY": 36.1763,
"maxY": 811.1348, "maxY": 811.1348,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -36,7 +36,7 @@
"minY": 36.1763, "minY": 36.1763,
"maxY": 811.1348, "maxY": 811.1348,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -33,7 +33,7 @@
"minY": 75.60000000000002, "minY": 75.60000000000002,
"maxY": 712.8, "maxY": 712.8,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -37,7 +37,7 @@
"minY": 75.60000000000002, "minY": 75.60000000000002,
"maxY": 712.8, "maxY": 712.8,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -36,7 +36,7 @@
"minY": 75.60000000000002, "minY": 75.60000000000002,
"maxY": 712.8, "maxY": 712.8,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -36,7 +36,7 @@
"minY": 75.60000000000002, "minY": 75.60000000000002,
"maxY": 712.8, "maxY": 712.8,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -33,7 +33,7 @@
"minY": 75.025, "minY": 75.025,
"maxY": 747.22, "maxY": 747.22,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -37,7 +37,7 @@
"minY": 75.025, "minY": 75.025,
"maxY": 747.22, "maxY": 747.22,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -36,7 +36,7 @@
"minY": 75.025, "minY": 75.025,
"maxY": 747.22, "maxY": 747.22,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -36,7 +36,7 @@
"minY": 75.025, "minY": 75.025,
"maxY": 747.22, "maxY": 747.22,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -36,7 +36,7 @@
"minY": 68.44329999999982, "minY": 68.44329999999982,
"maxY": 713.7734000000003, "maxY": 713.7734000000003,
"pageMapping": { "pageMapping": {
"pageFactor": 0, "pageFactor": 1,
"detectedOnPage": false "detectedOnPage": false
} }
} }

View File

@ -11,7 +11,7 @@
export let pageControl: PageControl; export let pageControl: PageControl;
export let pageIndex: number; export let pageIndex: number;
let { pagePinned, canPrev, canNext } = pageControl; let { pagePinned, canPrev, canNext, pageMapping } = pageControl;
</script> </script>
<div class="flex items-center space-x-1"> <div class="flex items-center space-x-1">
@ -20,7 +20,13 @@
<Icon class="text-xs hover:text-select hover:opacity-25 cursor-pointer opacity-75" icon={pin} /> <Icon class="text-xs hover:text-select hover:opacity-25 cursor-pointer opacity-75" icon={pin} />
</span> </span>
{/if} {/if}
<div>Page {pageIndex + 1} {$pagePinned ? '' : ' / ' + pageControl.totalPages}</div> <div>
Page
{$pageMapping.pageLabel(pageIndex)}
{#if $pageMapping.shifted()}
<span class="font-light"> ({pageIndex + 1}/{pageControl.totalPages}) </span>
{:else}/ {pageControl.totalPages + $pageMapping.pageFactor - 1}{/if}
</div>
</div> </div>
{#if $pagePinned} {#if $pagePinned}
<div class="absolute flex ml-4 space-x-2"> <div class="absolute flex ml-4 space-x-2">

View File

@ -3,6 +3,7 @@
import { flip } from 'svelte/animate'; import { flip } from 'svelte/animate';
import type Debugger from '@core/Debugger'; import type Debugger from '@core/Debugger';
import { PAGE_MAPPING } from '../../../core/src/transformer/CacluclateStatistics';
import { debugStage } from '../config'; import { debugStage } from '../config';
import ControlBar from './ControlBar.svelte'; import ControlBar from './ControlBar.svelte';
@ -19,6 +20,7 @@
let onlyRelevantItems = true; let onlyRelevantItems = true;
$: stageResult = debug.stageResult($debugStage); $: stageResult = debug.stageResult($debugStage);
$: pageControl.updateMapping(stageResult.globals.getOptional(PAGE_MAPPING));
$: supportsGrouping = !!stageResult.descriptor?.debug?.itemMerger; $: supportsGrouping = !!stageResult.descriptor?.debug?.itemMerger;
$: supportsRelevanceFiltering = !stageResult.descriptor?.debug?.showAll; $: supportsRelevanceFiltering = !stageResult.descriptor?.debug?.showAll;
$: visiblePages = pageControl.selectPages(stageResult, onlyRelevantItems, groupingEnabled, $pinnedPageIndex); $: visiblePages = pageControl.selectPages(stageResult, onlyRelevantItems, groupingEnabled, $pinnedPageIndex);

View File

@ -1,5 +1,5 @@
import Page from '@core/debug/Page';
import StageResult from '@core/debug/StageResult'; import StageResult from '@core/debug/StageResult';
import PageMapping from '../../../core/src/PageMapping';
import { Writable, writable, get, Readable, derived } from 'svelte/store'; import { Writable, writable, get, Readable, derived } from 'svelte/store';
export default class PageControl { export default class PageControl {
@ -8,6 +8,7 @@ export default class PageControl {
canPrev: Readable<boolean>; canPrev: Readable<boolean>;
canNext: Readable<boolean>; canNext: Readable<boolean>;
pagesWithItems: Set<number> = new Set(); pagesWithItems: Set<number> = new Set();
pageMapping: Writable<PageMapping> = writable(new PageMapping());
constructor(public totalPages: number) { constructor(public totalPages: number) {
this.pinnedPageIndex = writable(undefined); this.pinnedPageIndex = writable(undefined);
@ -22,6 +23,12 @@ export default class PageControl {
this.unpinPage.bind(this); this.unpinPage.bind(this);
} }
updateMapping(pageMapping: PageMapping | undefined) {
if (pageMapping) {
this.pageMapping.set(pageMapping);
}
}
selectPages(stageResult: StageResult, relevantChangesOnly: boolean, groupItems: boolean, pinnedPage?: number) { selectPages(stageResult: StageResult, relevantChangesOnly: boolean, groupItems: boolean, pinnedPage?: number) {
const allRelevantPages = stageResult.selectPages(relevantChangesOnly, groupItems); const allRelevantPages = stageResult.selectPages(relevantChangesOnly, groupItems);
this.pagesWithItems = new Set( this.pagesWithItems = new Set(

View File

@ -8,7 +8,8 @@
export let pageControl: PageControl; export let pageControl: PageControl;
let { pinnedPageIndex, pagePinned } = pageControl; let { pinnedPageIndex, pagePinned, pageMapping } = pageControl;
let showIndex = false;
const popupOpened: Writable<boolean> = getContext('popupOpened'); const popupOpened: Writable<boolean> = getContext('popupOpened');
@ -34,7 +35,7 @@
<div <div
on:click={() => pageControl.pageHasItems(idx) && pinPage(idx)} on:click={() => pageControl.pageHasItems(idx) && pinPage(idx)}
class="px-2 border border-gray-300 rounded-full text-center {pageControl.pageHasItems(idx) ? ($pinnedPageIndex === idx ? 'bg-select' : 'hover:text-select hover:border-select cursor-pointer') : 'opacity-50'}"> class="px-2 border border-gray-300 rounded-full text-center {pageControl.pageHasItems(idx) ? ($pinnedPageIndex === idx ? 'bg-select' : 'hover:text-select hover:border-select cursor-pointer') : 'opacity-50'}">
{idx + 1} {#if showIndex}{idx}{:else}{$pageMapping.pageLabel(idx)}{/if}
</div> </div>
{/each} {/each}
</div> </div>