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

Include Position for Ordinal Dimensions #262

Merged
merged 17 commits into from
Jan 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
ab18859
feat: Resolve ordinal dimensions correctly and add position to dimens…
jstcki Dec 8, 2021
44c9659
refactor: Extract batch loading into function
ptbrowne Jan 28, 2022
808ce36
feat: Load positions for ordinal dimensions
ptbrowne Jan 28, 2022
a057816
chore: Cleanup
ptbrowne Jan 28, 2022
2d70032
feat: Sort ordinal dimension values by position in left panel select
ptbrowne Jan 28, 2022
ebaee9e
feat: Checkboxes are sorted by value order in the right panel
ptbrowne Jan 28, 2022
bbe6f20
refactor: Use simpler function for easier composition for ordinal sorter
ptbrowne Jan 28, 2022
3c49afc
refactor: Use same renderer for chart preview/published
ptbrowne Jan 28, 2022
15d9cfd
refactor: Lazy get of sorted segments depending on sort method
ptbrowne Jan 28, 2022
dcafc60
refactor: Use generic type to filter out types that do not have colors
ptbrowne Jan 28, 2022
5fafb9a
refactor: Use useMemo for segments sorting in bars state
ptbrowne Jan 28, 2022
58f568d
refactor: Use useMemo for segments sorting in lines state
ptbrowne Jan 28, 2022
c581b5b
refactor: Use useMemo for segments sorting in areas state
ptbrowne Jan 28, 2022
1c140ea
feat: Order segments by position for ordinal dimensions in columns st…
ptbrowne Jan 28, 2022
a397b46
feat: Order segments by position for ordinal dimensions in columns chart
ptbrowne Jan 28, 2022
794a28d
feat: Order segments by position for ordinal dimensions in lines chart
ptbrowne Jan 28, 2022
d00ccd0
feat: Order segments by position for ordinal dimensions in area chart
ptbrowne Jan 28, 2022
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
4 changes: 2 additions & 2 deletions app/.env.development
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
DATABASE_URL=postgres://postgres:password@localhost:5432/visualization_tool
SPARQL_ENDPOINT=https://lindas.admin.ch/query
SPARQL_GEO_ENDPOINT=https://geo.ld.admin.ch/query
SPARQL_EDITOR=https://lindas.admin.ch/sparql/
SPARQL_ENDPOINT=https://int.lindas.admin.ch/query
SPARQL_EDITOR=https://int.lindas.admin.ch/sparql/
GRAPHQL_ENDPOINT=/api/graphql
77 changes: 52 additions & 25 deletions app/charts/area/areas-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
stackOrderReverse,
sum,
} from "d3";
import { sortBy } from "lodash";
import { ReactNode, useMemo } from "react";
import { AreaFields } from "../../configurator";
import {
Expand All @@ -29,6 +30,7 @@ import { Observation } from "../../domain/data";
import { sortByIndex } from "../../lib/array";
import { estimateTextWidth } from "../../lib/estimate-text-width";
import { useLocale } from "../../locales/use-locale";
import { makeOrdinalDimensionSorter } from "../../utils/sorting-values";
import { BRUSH_BOTTOM_SPACE } from "../shared/brush";
import {
getLabelWithUnit,
Expand Down Expand Up @@ -184,32 +186,57 @@ const useAreasState = ({
const segmentSortingType = fields.segment?.sorting?.sortingType;
const segmentSortingOrder = fields.segment?.sorting?.sortingOrder;

const segmentsOrderedByName = Array.from(
new Set(sortedData.map((d) => getSegment(d)))
).sort((a, b) =>
segmentSortingOrder === "asc"
? a.localeCompare(b, locale)
: b.localeCompare(a, locale)
);
const segments = useMemo(() => {
const getSegmentsOrderedByName = () =>
Array.from(new Set(sortedData.map((d) => getSegment(d)))).sort((a, b) =>
segmentSortingOrder === "asc"
? a.localeCompare(b, locale)
: b.localeCompare(a, locale)
);

const getSegmentsOrderedByTotalValue = () =>
[
...rollup(
sortedData,
(v) => sum(v, (x) => getY(x)),
(x) => getSegment(x)
),
]
.sort((a, b) =>
segmentSortingOrder === "asc"
? ascending(a[1], b[1])
: descending(a[1], b[1])
)
.map((d) => d[0]);

const getSegmentsOrderedByPosition = () => {
const segments = Array.from(
new Set(sortedData.map((d) => getSegment(d)))
);
const sorter = dimension ? makeOrdinalDimensionSorter(dimension) : null;
return sorter ? sortBy(segments, sorter) : segments;
};

const segmentsOrderedByTotalValue = [
...rollup(
sortedData,
(v) => sum(v, (x) => getY(x)),
(x) => getSegment(x)
),
]
.sort((a, b) =>
segmentSortingOrder === "asc"
? ascending(a[1], b[1])
: descending(a[1], b[1])
)
.map((d) => d[0]);

const segments =
segmentSortingType === "byDimensionLabel"
? segmentsOrderedByName
: segmentsOrderedByTotalValue;
const dimension = dimensions.find(
(dim) => dim.iri === fields.segment?.componentIri
);
if (dimension?.__typename === "OrdinalDimension") {
return getSegmentsOrderedByPosition();
}

return segmentSortingType === "byDimensionLabel"
? getSegmentsOrderedByName()
: getSegmentsOrderedByTotalValue();
}, [
dimensions,
fields.segment?.componentIri,
getSegment,
getY,
locale,
segmentSortingOrder,
segmentSortingType,
sortedData,
]);

// Stack order
const stackOrder =
Expand Down
5 changes: 4 additions & 1 deletion app/charts/bar/bars-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,10 @@ const useBarsState = ({
}, [data, getX, getY, sortingType, sortingOrder]);

// segments
const segments = [...new Set(sortedData.map((d) => getSegment(d)))];
const segments = useMemo(
() => [...new Set(sortedData.map((d) => getSegment(d)))],
[getSegment, sortedData]
);
const colors = scaleOrdinal(getPalette(fields.segment?.palette)).domain(
segments
);
Expand Down
76 changes: 52 additions & 24 deletions app/charts/column/columns-grouped-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
ScaleTime,
sum,
} from "d3";
import { sortBy } from "lodash";
import React, { ReactNode, useMemo } from "react";
import { ColumnFields, SortingOrder, SortingType } from "../../configurator";
import {
Expand All @@ -26,6 +27,7 @@ import {
import { Observation } from "../../domain/data";
import { sortByIndex } from "../../lib/array";
import { useLocale } from "../../locales/use-locale";
import { makeOrdinalDimensionSorter } from "../../utils/sorting-values";
import {
getLabelWithUnit,
useOptionalNumericVariable,
Expand Down Expand Up @@ -143,32 +145,58 @@ const useGroupedColumnsState = ({
// segments
const segmentSortingType = fields.segment?.sorting?.sortingType;
const segmentSortingOrder = fields.segment?.sorting?.sortingOrder;
const segmentsOrderedByName = Array.from(
new Set(sortedData.map((d) => getSegment(d)))
).sort((a, b) =>
segmentSortingOrder === "asc"
? a.localeCompare(b, locale)
: b.localeCompare(a, locale)
);

const segmentsOrderedByTotalValue = [
...rollup(
sortedData,
(v) => sum(v, (x) => getY(x)),
(x) => getSegment(x)
),
]
.sort((a, b) =>
segmentSortingOrder === "asc"
? ascending(a[1], b[1])
: descending(a[1], b[1])
)
.map((d) => d[0]);
const segments = useMemo(() => {
const getSegmentsOrderedByName = () =>
Array.from(new Set(sortedData.map((d) => getSegment(d)))).sort((a, b) =>
segmentSortingOrder === "asc"
? a.localeCompare(b, locale)
: b.localeCompare(a, locale)
);

const dimension = dimensions.find(
(d) => d.iri === fields.segment?.componentIri
);

const getSegmentsOrderedByPosition = () => {
const segments = Array.from(
new Set(sortedData.map((d) => getSegment(d)))
);
if (!dimension) {
return segments;
}
const sorter = makeOrdinalDimensionSorter(dimension);
return sortBy(segments, sorter);
};

const segments =
segmentSortingType === "byDimensionLabel"
? segmentsOrderedByName
: segmentsOrderedByTotalValue;
const getSegmentsOrderedByTotalValue = () =>
[
...rollup(
sortedData,
(v) => sum(v, (x) => getY(x)),
(x) => getSegment(x)
),
]
.sort((a, b) =>
segmentSortingOrder === "asc"
? ascending(a[1], b[1])
: descending(a[1], b[1])
)
.map((d) => d[0]);
if (dimension?.__typename === "OrdinalDimension") {
return getSegmentsOrderedByPosition();
}
return segmentSortingType === "byDimensionLabel"
? getSegmentsOrderedByName()
: getSegmentsOrderedByTotalValue();
}, [
getSegment,
getY,
locale,
segmentSortingOrder,
segmentSortingType,
sortedData,
]);

// Map ordered segments to colors
const colors = scaleOrdinal<string, string>();
Expand Down
68 changes: 45 additions & 23 deletions app/charts/column/columns-stacked-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
stackOrderReverse,
sum,
} from "d3";
import { keyBy } from "lodash";
import { keyBy, sortBy } from "lodash";
import React, { ReactNode, useCallback, useMemo } from "react";
import { ColumnFields, SortingOrder, SortingType } from "../../configurator";
import {
Expand All @@ -32,6 +32,7 @@ import { Observation } from "../../domain/data";
import { DimensionMetaDataFragment } from "../../graphql/query-hooks";
import { sortByIndex } from "../../lib/array";
import { useLocale } from "../../locales/use-locale";
import { makeOrdinalDimensionSorter } from "../../utils/sorting-values";
import {
getLabelWithUnit,
getWideData,
Expand Down Expand Up @@ -176,36 +177,57 @@ const useColumnsStackedState = ({
const segmentSortingOrder = fields.segment?.sorting?.sortingOrder;

const segments = useMemo(() => {
const segmentsOrderedByName = Array.from(
new Set(sortedData.map((d) => getSegment(d)))
).sort((a, b) =>
segmentSortingOrder === "asc"
? a.localeCompare(b, locale)
: b.localeCompare(a, locale)
const getSegmentsOrderedByName = () =>
Array.from(new Set(sortedData.map((d) => getSegment(d)))).sort((a, b) =>
segmentSortingOrder === "asc"
? a.localeCompare(b, locale)
: b.localeCompare(a, locale)
);

const dimension = dimensions.find(
(d) => d.iri === fields.segment?.componentIri
);
const getSegmentsOrderedByPosition = () => {
const segments = Array.from(
new Set(sortedData.map((d) => getSegment(d)))
);
if (!dimension) {
return segments;
}
const sorter = makeOrdinalDimensionSorter(dimension);
return sortBy(segments, sorter);
};

const getSegmentsOrderedByTotalValue = () =>
[
...rollup(
sortedData,
(v) => sum(v, (x) => getY(x)),
(x) => getSegment(x)
),
]
.sort((a, b) =>
segmentSortingOrder === "asc"
? ascending(a[1], b[1])
: descending(a[1], b[1])
)
.map((d) => d[0]);

if (dimension?.__typename === "OrdinalDimension") {
return getSegmentsOrderedByPosition();
}

const segmentsOrderedByTotalValue = [
...rollup(
sortedData,
(v) => sum(v, (x) => getY(x)),
(x) => getSegment(x)
),
]
.sort((a, b) =>
segmentSortingOrder === "asc"
? ascending(a[1], b[1])
: descending(a[1], b[1])
)
.map((d) => d[0]);
return segmentSortingType === "byDimensionLabel"
? segmentsOrderedByName
: segmentsOrderedByTotalValue;
? getSegmentsOrderedByName()
: getSegmentsOrderedByTotalValue();
}, [
sortedData,
dimensions,
segmentSortingType,
sortedData,
getSegment,
segmentSortingOrder,
locale,
fields.segment?.componentIri,
getY,
]);

Expand Down
21 changes: 17 additions & 4 deletions app/charts/column/columns-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
scaleTime,
ScaleTime,
} from "d3";
import { sortBy } from "lodash";
import { ReactNode, useMemo } from "react";
import { ColumnFields, SortingOrder, SortingType } from "../../configurator";
import {
Expand All @@ -23,6 +24,7 @@ import {
} from "../../configurator/components/ui-helpers";
import { Observation } from "../../domain/data";
import { TimeUnit } from "../../graphql/query-hooks";
import { makeOrdinalDimensionSorter } from "../../utils/sorting-values";
import {
getLabelWithUnit,
useOptionalNumericVariable,
Expand Down Expand Up @@ -184,10 +186,21 @@ const useColumnsState = ({
yScale.range([chartHeight, 0]);

// segments
const segments = Array.from(new Set(sortedData.map((d) => getSegment(d))));
const colors = scaleOrdinal(getPalette(fields.segment?.palette)).domain(
segments
);
const segments = useMemo(() => {
return Array.from(new Set(sortedData.map(getSegment)));
}, [getSegment, sortedData]);
const sortedSegments = useMemo(() => {
const rawSegments = getPalette(fields.segment?.palette);
const segmentDimension = dimensions.find(
(d) => d.iri === fields.segment?.componentIri
);
const sorter =
segmentDimension?.__typename === "OrdinalDimension"
? makeOrdinalDimensionSorter(segmentDimension)
: null;
return sorter ? sortBy(rawSegments, sorter) : rawSegments;
}, [fields.segment?.palette, fields.segment?.componentIri, dimensions]);
const colors = scaleOrdinal(sortedSegments).domain(segments);

// Tooltip
const getAnnotationInfo = (datum: Observation): TooltipInfo => {
Expand Down
19 changes: 16 additions & 3 deletions app/charts/line/lines-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ScaleTime,
scaleTime,
} from "d3";
import { sortBy } from "lodash";
import { ReactNode, useMemo } from "react";
import { LineFields } from "../../configurator";
import {
Expand All @@ -22,6 +23,7 @@ import { Observation } from "../../domain/data";
import { sortByIndex } from "../../lib/array";
import { estimateTextWidth } from "../../lib/estimate-text-width";
import { useTheme } from "../../themes";
import { makeOrdinalDimensionSorter } from "../../utils/sorting-values";
import { BRUSH_BOTTOM_SPACE } from "../shared/brush";
import {
getLabelWithUnit,
Expand Down Expand Up @@ -173,9 +175,20 @@ const useLinesState = ({
const yAxisLabel = getLabelWithUnit(yMeasure);

// segments
const segments = [...new Set(sortedData.map(getSegment))].sort((a, b) =>
ascending(a, b)
);
const segments = useMemo(() => {
const segments = [...new Set(sortedData.map(getSegment))].sort((a, b) =>
ascending(a, b)
);
const dimension = dimensions.find(
(d) => d.iri === fields?.segment?.componentIri
);
if (dimension?.__typename === "OrdinalDimension") {
const sorter = makeOrdinalDimensionSorter(dimension);
return sortBy(segments, sorter);
}
return segments;
}, [dimensions, fields?.segment?.componentIri, getSegment, sortedData]);

// Map ordered segments to colors
const colors = scaleOrdinal<string, string>();
const segmentDimension = dimensions.find(
Expand Down
Loading