grid scroll bars

This commit is contained in:
Jan Prochazka
2021-02-25 10:25:34 +01:00
parent ef910f43a6
commit 2ffd729465
8 changed files with 139 additions and 14 deletions

View File

@@ -1,15 +1,36 @@
<script lang="ts">
import FontIcon from '../icons/FontIcon.svelte';
import DropDownButton from '../widgets/DropDownButton.svelte';
import ColumnLabel from './ColumnLabel.svelte';
export let column;
export let conid = undefined;
export let database = undefined;
export let column;
export let grouping = undefined;
export let order = undefined;
</script>
<div class="header">
<div class="label">
{#if grouping}
<span class="grouping">
{grouping == 'COUNT DISTINCT' ? 'distinct' : grouping.toLowerCase()}
</span>
{/if}
<ColumnLabel {...column} />
</div>
{#if order == 'ASC'}
<span class="icon">
<FontIcon icon="img sort-asc" />
</span>
{/if}
{#if order == 'DESC'}
<span class="icon">
<FontIcon icon="img sort-desc" />
</span>
{/if}
<DropDownButton />
</div>
<style>

View File

@@ -79,7 +79,7 @@
{value.toString()}
{/if}
{#if hintFieldsAllowed && hintFieldsAllowed.includes(col.uniqueName)}
{#if hintFieldsAllowed && hintFieldsAllowed.includes(col.uniqueName) && rowData}
<span class="hint">{rowData[col.hintColumnName]}</span>
{/if}
</td>

View File

@@ -4,6 +4,8 @@
import ColumnHeaderControl from './ColumnHeaderControl.svelte';
import DataGridRow from './DataGridRow.svelte';
import { countColumnSizes, countVisibleRealColumns } from './gridutil';
import HorizontalScrollBar from './HorizontalScrollBar.svelte';
import VerticalScrollBar from './VerticalScrollBar.svelte';
export let loadNextData = undefined;
export let grider = undefined;
@@ -17,7 +19,7 @@
let firstVisibleRowScrollIndex = 0;
let firstVisibleColumnScrollIndex = 0;
// $: firstVisibleRowScrollIndex = 0;
$: visibleRowCountUpperBound = 25;
// $: visibleRowCountUpperBound = 25;
// $: console.log('grider', grider);
$: columns = display.allColumns;
@@ -29,6 +31,9 @@
$: gridScrollAreaHeight = containerHeight - 2 * rowHeight;
$: gridScrollAreaWidth = containerWidth - columnSizes.frozenSize - headerColWidth - 32;
$: visibleRowCountUpperBound = Math.ceil(gridScrollAreaHeight / Math.floor(Math.max(1, rowHeight)));
$: visibleRowCountLowerBound = Math.floor(gridScrollAreaHeight / Math.ceil(Math.max(1, rowHeight)));
$: visibleRealColumns = countVisibleRealColumns(
columnSizes,
firstVisibleColumnScrollIndex,
@@ -36,12 +41,17 @@
columns
);
$: console.log('visibleRealColumns', visibleRealColumns);
// $: console.log('visibleRealColumns', visibleRealColumns);
$: console.log('visibleRowCountUpperBound', visibleRowCountUpperBound);
$: console.log('rowHeight', rowHeight);
$: console.log('containerHeight', containerHeight);
$: realColumnUniqueNames = _.range(columnSizes.realCount).map(
realIndex => (columns[columnSizes.realToModel(realIndex)] || {}).uniqueName
);
$: maxScrollColumn = columnSizes.scrollInView(0, columns.length - 1 - columnSizes.frozenCount, gridScrollAreaWidth);
$: {
if (loadNextData && firstVisibleRowScrollIndex + visibleRowCountUpperBound >= grider.rowCount) {
loadNextData();
@@ -54,7 +64,7 @@
<table class="table">
<thead>
<tr>
<td class="header-cell" data-row="header" data-col="header" />
<td class="header-cell" data-row="header" data-col="header" bind:clientHeight={rowHeight} />
{#each visibleRealColumns as col (col.uniqueName)}
<td
class="header-cell"
@@ -69,10 +79,22 @@
</thead>
<tbody>
{#each _.range(firstVisibleRowScrollIndex, firstVisibleRowScrollIndex + visibleRowCountUpperBound) as rowIndex (rowIndex)}
<DataGridRow {rowIndex} {grider} {visibleRealColumns} />
<DataGridRow {rowIndex} {grider} {visibleRealColumns} {rowHeight} />
{/each}
</tbody>
</table>
<HorizontalScrollBar
minimum={0}
maximum={maxScrollColumn}
viewportRatio={gridScrollAreaWidth / columnSizes.getVisibleScrollSizeSum()}
on:scroll={e => (firstVisibleColumnScrollIndex = e.detail)}
/>
<VerticalScrollBar
minimum={0}
maximum={grider.rowCount - visibleRowCountUpperBound + 2}
viewportRatio={visibleRowCountUpperBound / grider.rowCount}
on:scroll={e => (firstVisibleRowScrollIndex = e.detail)}
/>
</div>
<style>
@@ -98,7 +120,7 @@
text-align: left;
padding: 0;
margin: 0;
background-color: var(--theme-bg-2);
background-color: var(--theme-bg-1);
overflow: hidden;
}
.filter-cell {

View File

@@ -20,7 +20,7 @@
.map(col => col.uniqueName);
</script>
<tr>
<tr style={`height: ${rowHeight}px`}>
<RowHeaderCell {rowIndex} />
{#each visibleRealColumns as col (col.uniqueName)}
<DataGridCell {rowIndex} {rowData} {col} {hintFieldsAllowed} />

View File

@@ -0,0 +1,35 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
export let viewportRatio = 0.5;
export let minimum;
export let maximum;
const dispatch = createEventDispatcher();
let width;
let node;
$: contentSize = Math.round(width / viewportRatio);
function handleScroll() {
const position = node.scrollLeft;
const ratio = position / (contentSize - width);
if (ratio < 0) return 0;
const res = ratio * (maximum - minimum + 1) + minimum;
dispatch('scroll', Math.floor(res + 0.3));
}
</script>
<div bind:clientWidth={width} bind:this={node} on:scroll={handleScroll} class="main">
<div style={`width: ${contentSize}px`}>&nbsp;</div>
</div>
<style>
.main {
overflow-x: scroll;
height: 16px;
position: absolute;
bottom: 0;
right: 0;
left: 0;
}
</style>

View File

@@ -0,0 +1,36 @@
<script lang="ts">
import { createEventDispatcher } from 'svelte';
export let viewportRatio = 0.5;
export let minimum;
export let maximum;
const dispatch = createEventDispatcher();
let height;
let node;
$: contentSize = Math.round(height / viewportRatio);
function handleScroll() {
const position = node.scrollTop;
const ratio = position / (contentSize - height);
if (ratio < 0) return 0;
let res = ratio * (maximum - minimum + 1) + minimum;
dispatch('scroll', Math.floor(res + 0.3));
}
</script>
<div bind:clientHeight={height} bind:this={node} on:scroll={handleScroll} class="main">
<div style={`height: ${contentSize}px`}>&nbsp;</div>
</div>
<style>
.main {
overflow-y: scroll;
width: 20px;
position: absolute;
right: 0px;
width: 20px;
bottom: 16px;
top: 0;
}
</style>

View File

@@ -0,0 +1,8 @@
<script>
import FontIcon from '../icons/FontIcon.svelte';
import InlineButton from './InlineButton.svelte';
</script>
<InlineButton square>
<FontIcon icon="icon chevron-down" />
</InlineButton>

View File

@@ -11,9 +11,12 @@
<style>
.outer {
background: linear-gradient(to bottom, var(--theme-bg-2) 5%, var(--theme-bg-3) 100%);
background-color: var(--theme-bg-2);
border: 1px solid var(--theme-bg-3);
--bg-1: var(--theme-bg-1);
--bg-2: var(--theme-bg-3);
background: linear-gradient(to bottom, var(--bg-1) 5%, var(--bg-2) 100%);
background-color: var(--bg-1);
border: 1px solid var(--bg-2);
display: inline-block;
cursor: pointer;
vertical-align: middle;
@@ -30,9 +33,9 @@
}
.outer:hover:not(.disabled) {
border: 1px solid var(--theme-bg-2);
background: linear-gradient(to bottom, var(--theme-bg-3) 5%, var(--theme-bg-2) 100%);
background-color: var(--theme-bg-3);
border: 1px solid var(--bg-1);
background: linear-gradient(to bottom, var(--bg-2) 5%, var(--bg-1) 100%);
background-color: var(--bg-2);
}
.inner {