Skip to content

Commit

Permalink
Merge pull request #832 from visualize-admin/fix/unique-values-hierar…
Browse files Browse the repository at this point in the history
…chies
  • Loading branch information
ptbrowne authored Nov 10, 2022
2 parents 1e1d89b + 42d5fe7 commit 7d86022
Show file tree
Hide file tree
Showing 3 changed files with 6,435 additions and 17 deletions.
22 changes: 22 additions & 0 deletions app/configurator/components/use-hierarchy-parents.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import hierarchy from "../../test/__fixtures/data/tarrifs-hierarchy.json";

import { groupByParents } from "./use-hierarchy-parents";

describe("grouping hierarchy by parents", () => {
it("should work", () => {
const archy = hierarchy as Parameters<typeof groupByParents>[0];
const groups = groupByParents(archy);
const iri =
"https://ld.admin.ch/cube/dimension/aussenhandel_warenkoerbe/1_listZT";
const ztGroups = groups.filter(
([parents]) =>
parents.length > 0 && parents[parents.length - 1].value === iri
)!;

expect(ztGroups.length).toBe(1);
const ztGroup = ztGroups[0]!;
const [parents, children] = ztGroup;
expect(parents.length).toBe(2);
expect(children.length).toBe(41);
});
});
73 changes: 56 additions & 17 deletions app/configurator/components/use-hierarchy-parents.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
import { groups } from "d3-array";
import uniqBy from "lodash/uniqBy";
import { useMemo } from "react";

import { DataSource } from "@/configurator/config-types";
import { useDimensionHierarchyQuery } from "@/graphql/query-hooks";
import {
DimensionHierarchyQuery,
useDimensionHierarchyQuery,
} from "@/graphql/query-hooks";
import { DataCubeMetadata } from "@/graphql/types";
import { dfs } from "@/utils/dfs";

type NN<T> = NonNullable<T>;
export type DimensionHierarchyQueryHierarchy = NN<
NN<
NN<DimensionHierarchyQuery["dataCubeByIri"]>["dimensionByIri"]
>["hierarchy"]
>;

export const groupByParents = (hierarchy: DimensionHierarchyQueryHierarchy) => {
const allHierarchyValues = [
...dfs(hierarchy, (node, { depth, parents }) => ({
node,
parents,
depth,
})),
];

return groups(allHierarchyValues, (v) => v.parents);
};

const useHierarchyParents = (
dataSet: string,
dataSource: DataSource,
Expand All @@ -30,22 +51,40 @@ const useHierarchyParents = (
if (!hierarchy) {
return;
}
const values = dimension.values;
const valueSet = new Set(values.map((v) => v.value));
const dimensionValues = uniqBy(
[
...dfs(hierarchy, (node, { depth, parents }) => ({
node,
parents,
depth,
})),
].filter(({ node }) => {
return valueSet.has(node.value);
}),
(x) => x.node.value
);
return groups(dimensionValues, (v) => v.parents);
const valueSet = new Set(dimension.values.map((x) => x.value));
return groupByParents(hierarchy)
.map(
([parents, values]) =>
[parents, values.filter((x) => valueSet.has(x.node.value))] as const
)
.filter(([_parents, values]) => values.length > 0);
}, [dimension.values, hierarchy]);
};

/**
* Can be used for debugging, pass a hierarchy, and copy the output
* to graphviz.
*
* @see https://dreampuf.github.io/GraphvizOnline/
*/
export const hierarchyToGraphviz = (
hierarchy: DimensionHierarchyQueryHierarchy
) => {
const lines = [] as string[];
dfs(hierarchy, (node, { parents }) => {
lines.push(`"${node.value}"[label="${node.label.replace(/"/g, "")}"]`);
if (parents.length > 0) {
const parent = parents[parents.length - 1];
lines.push(`"${parent.value}" -> "${node.value}"`);
}
});
return `
digraph G {
rankdir=LR
${lines.join("\n")}
}
`;
};

export default useHierarchyParents;
Loading

1 comment on commit 7d86022

@vercel
Copy link

@vercel vercel bot commented on 7d86022 Nov 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

visualization-tool – ./

visualization-tool-alpha.vercel.app
visualization-tool-git-main-ixt1.vercel.app
visualization-tool-ixt1.vercel.app

Please sign in to comment.