Skip to content

Commit

Permalink
feat: Include missing tree values on server side
Browse files Browse the repository at this point in the history
  • Loading branch information
bprusinowski committed Nov 14, 2022
1 parent 0d898d6 commit b6a7d26
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 32 deletions.
17 changes: 1 addition & 16 deletions app/configurator/components/filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ import SvgIcClose from "@/icons/components/IcClose";
import SvgIcFormatting from "@/icons/components/IcFormatting";
import SvgIcRefresh from "@/icons/components/IcRefresh";
import { useLocale } from "@/locales/use-locale";
import { pruneTree } from "@/rdf/tree-utils";
import { dfs } from "@/utils/dfs";
import { getOptionsFromTree, joinParents, pruneTree } from "@/rdf/tree-utils";
import { valueComparator } from "@/utils/sorting-values";
import useEvent from "@/utils/use-event";

Expand Down Expand Up @@ -142,10 +141,6 @@ const useStyles = makeStyles((theme: Theme) => {
};
});

const joinParents = (parents?: HierarchyValue[]) => {
return parents?.map((x) => x.label).join(" > ") || "";
};

const explodeParents = (parents: string) => {
return parents ? parents.split(" > ") : [];
};
Expand All @@ -154,16 +149,6 @@ const groupByParent = (node: { parents: HierarchyValue[] }) => {
return joinParents(node?.parents);
};

const getOptionsFromTree = (tree: HierarchyValue[]) => {
return sortBy(
dfs(tree, (node, { parents }) => ({
...node,
parents,
})),
(node) => joinParents(node.parents)
);
};

const getColorConfig = (
config: ConfiguratorState,
colorConfigPath: string | undefined
Expand Down
91 changes: 75 additions & 16 deletions app/rdf/query-hierarchies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,66 @@ import {
HierarchyNode,
} from "@zazuko/cube-hierarchy-query/index";
import { AnyPointer } from "clownface";
import { ascending, descending } from "d3";
import { isGraphPointer } from "is-graph-pointer";
import { Cube } from "rdf-cube-view-query";
import rdf from "rdf-ext";
import { NamedNode } from "rdf-js";
import { StreamClient } from "sparql-http-client";
import { ParsingClient } from "sparql-http-client/ParsingClient";

import { HierarchyValue } from "@/graphql/resolver-types";
import { pragmas } from "@/rdf/create-source";

import * as ns from "./namespace";
import { pruneTree, mapTree } from "./tree-utils";

const queryDimensionValues = async (
dimension: string,
sparqlClient: ParsingClient
) => {
const query = SELECT.DISTINCT`?value`.WHERE`
?cube <https://cube.link/observationSet> ?observationSet .
?observationSet <https://cube.link/observation> ?observation .
?observation <${dimension}> ?value .
import { pruneTree, mapTree, sortTree, getOptionsFromTree } from "./tree-utils";

const queryDimensionValuesWithLabels = async ({
dimensionIri,
client,
locale,
}: {
dimensionIri: string;
client: ParsingClient;
locale: string;
}): Promise<{ value: string; label: string }[]> => {
const query = SELECT.DISTINCT`?value ?label`.WHERE`
?cube <https://cube.link/observationSet> ?observationSet .
?observationSet <https://cube.link/observation> ?observation .
?observation <${dimensionIri}> ?value .
OPTIONAL {
?value <http://schema.org/name> ?language_label .
FILTER (
LANGMATCHES(LANG(?language_label), "${locale}")
)
}
OPTIONAL {
?value <http://schema.org/name> ?no_language_label .
FILTER (
(LANG(?no_language_label) = "")
)
}
BIND(COALESCE(?language_label, ?no_language_label) AS ?label)
`.prologue`${pragmas}`;
const rows = await query.execute(sparqlClient.query);
return rows.map((r) => r.value.value);

const rows = (await query.execute(client.query)) as {
value: NamedNode;
label: NamedNode | undefined;
}[];

return rows
.filter((d) => d.label !== undefined)
.map((r) => ({
value: r.value.value,
label: r.label!.value,
}));
};

const getName = (pointer: AnyPointer, language: string) => {
let name = pointer.out(ns.schema.name, { language })?.value;
const name = pointer.out(ns.schema.name, { language })?.value;
if (name) {
return name;
}
Expand Down Expand Up @@ -95,17 +128,43 @@ export const queryHierarchy = async (
return null;
}

const dimensionValuesProm = queryDimensionValues(dimensionIri, sparqlClient);
const dimensionValuesWithLabelsProm = queryDimensionValuesWithLabels({
dimensionIri,
client: sparqlClient,
locale,
});
const results = await getHierarchy(hierarchy).execute(
// @ts-ignore
sparqlClientStream,
rdf
);

const tree = toTree(results, dimensionIri, locale);
const dimensionValues = new Set(await dimensionValuesProm);
return mapTree(
const treeValues = new Set(getOptionsFromTree(tree).map((d) => d.value));
const dimensionValuesWithLabels = await dimensionValuesWithLabelsProm;
const dimensionValues = new Set(
dimensionValuesWithLabels.map((d) => d.value)
);
const prunedTree = mapTree(
pruneTree(tree, (node) => dimensionValues.has(node.value)),
(node) => ({ ...node, hasValue: dimensionValues.has(node.value) })
);
const additionalTreeValues = dimensionValuesWithLabels
.filter((d) => !treeValues.has(d.value))
.map((d) => ({
label: d.label || "-",
value: d.value,
depth: -1,
children: [],
dimensionIri,
hasValue: true,
}));

return sortTree(
[...prunedTree, ...additionalTreeValues],
(a, b) =>
descending(a.depth, b.depth) ||
ascending(a.position ?? 0, b.position ?? 0) ||
ascending(a.label.toLowerCase(), b.label.toLowerCase())
);
};
27 changes: 27 additions & 0 deletions app/rdf/tree-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import sortBy from "lodash/sortBy";

import { HierarchyValue } from "@/graphql/resolver-types";
import { dfs } from "@/utils/dfs";

export const mapTree = (
tree: HierarchyValue[],
Expand All @@ -12,6 +15,16 @@ export const mapTree = (
});
};

export const sortTree = (
tree: HierarchyValue[],
sorter: (a: HierarchyValue, b: HierarchyValue) => number
): HierarchyValue[] => {
return [...tree].sort(sorter).map((d) => ({
...d,
children: d.children ? sortTree(d.children, sorter) : undefined,
}));
};

const filterTreeHelper = (
tree: HierarchyValue[],
predicate: (h: HierarchyValue) => boolean
Expand Down Expand Up @@ -143,3 +156,17 @@ export const makeTreeFromValues = (
children: [],
}));
};

export const getOptionsFromTree = (tree: HierarchyValue[]) => {
return sortBy(
dfs(tree, (node, { parents }) => ({
...node,
parents,
})),
(node) => joinParents(node.parents)
);
};

export const joinParents = (parents?: HierarchyValue[]) => {
return parents?.map((x) => x.label).join(" > ") || "";
};

0 comments on commit b6a7d26

Please sign in to comment.