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

Demo tweaks #122

Merged
merged 11 commits into from
Jan 21, 2025
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: 1 addition & 0 deletions texture/database/preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def construct_schema_and_tables(
.explode()
.reset_index()
.rename(columns={"index": C_ID})
.dropna(subset=[col_name])
)

# NOTE: assumed these are non-segment lists so the spans are array index
Expand Down
Empty file added texture/extra/__init__.py
Empty file.
2 changes: 1 addition & 1 deletion texturefrontend/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

$showBackgroundDistMap = $datasetSchema.columns.reduce(
(acc: Record<string, boolean>, col) => {
acc[col.name] = col.name !== "word";
acc[col.name] = false;

return acc;
},
Expand Down
10 changes: 6 additions & 4 deletions texturefrontend/src/components/ColumnProfile.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

<p
class:font-medium={active}
class="max-w-sm overflow-hidden text-ellipsis text-left"
class="overflow-hidden text-ellipsis text-left grow"
>
{displayCol.name}
</p>
Expand All @@ -55,8 +55,6 @@
</div>
{/if}

<div class="grow" />

{#if colSummary?.cardinality !== undefined}
<CardinalityDisplay cardinality={colSummary.cardinality} />
{/if}
Expand All @@ -82,6 +80,8 @@
$datasetSchema.name}
columnName={displayCol.name}
showBackground={$showBackgroundDistMap[displayCol.name]}
shouldBin={colSummary?.cardinality == undefined ||
colSummary.cardinality >= 10}
/>
{:else if displayCol.type === "categorical"}
<CategoricalChart
Expand Down Expand Up @@ -134,7 +134,9 @@
bind:checked={$showBackgroundDistMap[displayCol.name]}
/>

<span class="text-sm text-gray-500"> Show original distribution </span>
<span class="text-sm text-gray-500">
Show background distribution
</span>
</div>
{/if}
</div>
Expand Down
61 changes: 46 additions & 15 deletions texturefrontend/src/components/ProjectionOverview.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,67 @@
import { Select } from "flowbite-svelte";
import { projectionColorColumn } from "../stores";
import Toggle from "./Toggle.svelte";
import { CogOutline } from "flowbite-svelte-icons";

export let colorCols: Column[] = [];
let showSettings = false;
let plotOpacity = 0.4;
</script>

<Toggle active={$datasetSchema.has_projection}>
<div slot="title">Dataset Overview</div>
<div slot="body">
{#if $datasetSchema.has_projection}
<div class="flex flex-col">
{#if colorCols.length > 0}
<Select
class="max-w-40 py-1 self-end"
size="sm"
items={[
{ value: undefined, name: "No color" },
...colorCols.map((col) => ({
value: col.name,
name: col.name,
})),
]}
bind:value={$projectionColorColumn}
placeholder="Color by..."
/>
{/if}
<div class="flex justify-end">
{#if colorCols.length > 0}
<Select
class="max-w-40 py-1 self-end"
size="sm"
items={[
{ value: undefined, name: "No color" },
...colorCols.map((col) => ({
value: col.name,
name: col.name,
})),
]}
bind:value={$projectionColorColumn}
placeholder="Color by..."
/>
{/if}
<button
class="hover:bg-secondary-200 text-gray-500 p-1 rounded inline"
on:click={() => {
showSettings = !showSettings;
}}
>
<CogOutline size="xs" />
</button>
</div>

{#if showSettings}
<div
class="px-4 py-2 mx-2 mt-2 rounded bg-gray-100 flex gap-2 items-center"
>
<input
type="range"
min={0}
max={1}
step={0.1}
class="bg-gray-100 border-gray-300 dark:ring-offset-gray-800 me-2 dark:bg-gray-700 dark:border-gray-600 rounded text-primary-600"
bind:value={plotOpacity}
/>
<span class="text-sm text-gray-500">
Opacity value is {plotOpacity}
</span>
</div>
{/if}
<ScatterProjection
mainDatasetName={$datasetSchema.name}
columnX="umap_x"
columnY="umap_y"
colorColName={$projectionColorColumn}
opacity={plotOpacity}
/>
</div>
{:else}
Expand Down
21 changes: 5 additions & 16 deletions texturefrontend/src/components/Search.svelte
Original file line number Diff line number Diff line change
@@ -1,24 +1,15 @@
<script lang="ts">
import * as vg from "@uwdata/vgplot";
import { onDestroy } from "svelte";
import { SearchOutline } from "flowbite-svelte-icons";
import { mosaicSelection, clearColumnSelections } from "../stores";
import { isSelection } from "@uwdata/mosaic-core";
import {
regexp_matches,
contains,
prefix,
suffix,
literal,
eq,
} from "@uwdata/mosaic-sql";
import { literal, eq } from "@uwdata/mosaic-sql";
import { getUUID } from "../shared/utils";
import type { Column } from "../backendapi/models/Column";

const FUNCTIONS = { contains, prefix, suffix, regexp: regexp_matches };

export let column: Column;
export let tableName: string;
export let type = "contains";
let currentQuery: string | undefined;
let uuid = getUUID();

Expand All @@ -38,13 +29,11 @@
function publishUpdate() {
if (isSelection($mosaicSelection) && column != undefined) {
let pred = null;
let cleanedQuery = currentQuery?.replaceAll("'", "''");

// TODO: support case-insensitive search
let cleanedQuery = currentQuery?.replaceAll("'", "''"); //.toLowerCase();

if (cleanedQuery) {
if (column.type === "text" || column.type === "categorical") {
pred = FUNCTIONS[type](column.name, literal(cleanedQuery));
pred = vg.sql`${vg.column(column.name)} ILIKE '%${cleanedQuery}%'`;
} else if (column.type === "number") {
pred = eq(column.name, literal(Number(cleanedQuery)));
} else if (column.type === "date") {
Expand All @@ -54,7 +43,7 @@

let updateInfo = {
source: `${column.name}_search_${uuid}`,
schema: { type },
schema: { type: "contains" }, // idk what this does
value: cleanedQuery,
predicate: pred,
clients: new Set().add({ source: { table: tableName } }),
Expand Down
2 changes: 1 addition & 1 deletion texturefrontend/src/components/Toggle.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<div>
<button
class="flex gap-2 h-9 w-full items-center px-2 hover:bg-gray-200 border-t-2 border-secondary-200"
class="flex gap-2 min-h-9 w-full items-center px-2 hover:bg-gray-200 border-t-2 border-secondary-200"
on:click={() => {
active = !active;
}}
Expand Down
102 changes: 36 additions & 66 deletions texturefrontend/src/components/charts/CategoricalChart.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -57,83 +57,53 @@
columnName,
);

const plotDirectives = [
vg.barX(vg.from(table, { filterBy: $mosaicSelection }), {
x: vg.count(),
y: col,
fill: colorColName ?? "steelblue",
sort: { y: "-x", limit },
}),
vg.highlight({ by: selection }),
vg.toggleY({ as: selection }),
vg.toggleY({ as: $mosaicSelection }),
vg.text(vg.from(table, { filterBy: $mosaicSelection }), {
x: 0,
y: col,
sort: { y: "-x", limit },
text: vg.count(),
dx: -3,
textAnchor: "end",
textOverflow: "ellipsis",
fill: "black",
}),
vg.margins({ left: 250, bottom: 0, top: 0, right: 0 }),
vg.width(400),
vg.axis(null),
vg.axisY({
textOverflow: "ellipsis",
lineWidth: 15,
label: null,
textAnchor: "start",
dx: -220,
fontSize: 14,
tickSize: 0,
}),
];

if (showBackground) {
plotWrapper = getPlot(
plotDirectives.unshift(
vg.barX(vg.from(table), {
x: vg.count(),
y: col,
fill: "#ccc",
fillOpacity: 0.4,
sort: { y: "-x", limit },
}),
vg.barX(vg.from(table, { filterBy: $mosaicSelection }), {
x: vg.count(),
y: col,
fill: colorColName ?? "steelblue",
sort: { y: "-x", limit },
}),
vg.highlight({ by: selection }),
vg.toggleY({ as: selection }),
vg.toggleY({ as: $mosaicSelection }),
vg.text(vg.from(table, { filterBy: $mosaicSelection }), {
x: 0,
y: col,
sort: { y: "-x", limit },
text: vg.count(),
dx: -3,
textAnchor: "end",
textOverflow: "ellipsis",
fill: "black",
}),
vg.margins({ left: 250, bottom: 0, top: 0, right: 0 }),
vg.width(400),
vg.axis(null),
vg.axisY({
textOverflow: "ellipsis",
lineWidth: 15,
label: null,
textAnchor: "start",
dx: -220,
fontSize: 14,
tickSize: 0,
}),
);
} else {
plotWrapper = getPlot(
vg.barX(vg.from(table, { filterBy: $mosaicSelection }), {
x: vg.count(),
y: col,
fill: colorColName ?? "steelblue",
sort: { y: "-x", limit },
}),
vg.highlight({ by: selection }),
vg.toggleY({ as: selection }),
vg.toggleY({ as: $mosaicSelection }),
vg.text(vg.from(table, { filterBy: $mosaicSelection }), {
x: 0,
y: col,
sort: { y: "-x", limit },
text: vg.count(),
dx: -3,
textAnchor: "end",
textOverflow: "ellipsis",
fill: "black",
}),
vg.margins({ left: 250, bottom: 0, top: 0, right: 0 }),
vg.width(400),
vg.axis(null),
vg.axisY({
textOverflow: "ellipsis",
lineWidth: 15,
label: null,
textAnchor: "start",
dx: -220,
fontSize: 14,
tickSize: 0,
}),
);
}

plotWrapper = getPlot(...plotDirectives);
el.replaceChildren(plotWrapper.element);
}

Expand Down
Loading