diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b068e4a9..715394b4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ You can also check the [release page](https://github.com/visualize-admin/visuali - Column order is based on the shacl:order defined in the data - For the dataset preview - For the table chart columns +- Default state for area chart uses the hierarchy and selects + bottommost children + ## [3.7.8] - 2022-08-22 diff --git a/app/charts/area/chart-area.tsx b/app/charts/area/chart-area.tsx index 1bfe8003f..d0a1b9610 100644 --- a/app/charts/area/chart-area.tsx +++ b/app/charts/area/chart-area.tsx @@ -31,7 +31,7 @@ import { import { isNumber } from "@/configurator/components/ui-helpers"; import { Observation } from "@/domain/data"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, useDataCubeObservationsQuery, } from "@/graphql/query-hooks"; import { useLocale } from "@/locales/use-locale"; @@ -102,8 +102,8 @@ export const ChartAreas = memo( interactiveFiltersConfig, }: { observations: Observation[]; - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; fields: AreaFields; interactiveFiltersConfig: InteractiveFiltersConfig; }) => { diff --git a/app/charts/bar/chart-bar.tsx b/app/charts/bar/chart-bar.tsx index 4c50045d0..4200ab178 100644 --- a/app/charts/bar/chart-bar.tsx +++ b/app/charts/bar/chart-bar.tsx @@ -29,7 +29,7 @@ import { import { isNumber } from "@/configurator/components/ui-helpers"; import { Observation } from "@/domain/data"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, useDataCubeObservationsQuery, } from "@/graphql/query-hooks"; import { useLocale } from "@/locales/use-locale"; @@ -100,8 +100,8 @@ export const ChartBars = memo( interactiveFiltersConfig, }: { observations: Observation[]; - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; fields: BarFields; interactiveFiltersConfig: InteractiveFiltersConfig; }) => { diff --git a/app/charts/column/chart-column.tsx b/app/charts/column/chart-column.tsx index 132f8c284..55f94bad4 100644 --- a/app/charts/column/chart-column.tsx +++ b/app/charts/column/chart-column.tsx @@ -41,7 +41,7 @@ import { import { isNumber } from "@/configurator/components/ui-helpers"; import { Observation } from "@/domain/data"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, useDataCubeObservationsQuery, } from "@/graphql/query-hooks"; import { useLocale } from "@/locales/use-locale"; @@ -112,8 +112,8 @@ export const ChartColumns = memo( interactiveFiltersConfig, }: { observations: Observation[]; - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; interactiveFiltersConfig: InteractiveFiltersConfig; fields: ColumnFields; }) => { diff --git a/app/charts/index.ts b/app/charts/index.ts index 7c1b1d504..e484fdb5d 100644 --- a/app/charts/index.ts +++ b/app/charts/index.ts @@ -23,6 +23,8 @@ import { TableFields, } from "@/configurator/config-types"; import { DEFAULT_PALETTE } from "@/configurator/configurator-state"; +import { HierarchyValue } from "@/graphql/resolver-types"; +import { visitHierarchy } from "@/rdf/tree-utils"; import { mapValueIrisToColor } from "../configurator/components/ui-helpers"; import { @@ -30,7 +32,7 @@ import { getGeoDimensions, getTimeDimensions, } from "../domain/data"; -import { DimensionMetaDataFragment } from "../graphql/query-hooks"; +import { DimensionMetadataFragment } from "../graphql/query-hooks"; import { DataCubeMetadata } from "../graphql/types"; import { unreachableError } from "../lib/unreachable"; @@ -53,7 +55,7 @@ export const enabledChartTypes: ChartType[] = [ */ export const findPreferredDimension = ( dimensions: DataCubeMetadata["dimensions"], - preferredType?: DimensionMetaDataFragment["__typename"] + preferredType?: DimensionMetadataFragment["__typename"] ) => { const dim = dimensions.find( @@ -756,21 +758,44 @@ const chartConfigsAdjusters: ChartConfigsAdjusters = { }, }, map: { - filters: ({ oldValue, newChartConfig }) => { + filters: ({ oldValue, newChartConfig, dimensions }) => { return produce(newChartConfig, (draft) => { - draft.filters = oldValue; + if (!oldValue) { + draft.filters = oldValue; + } }); }, fields: { areaLayer: { componentIri: ({ oldValue, newChartConfig, dimensions }) => { - const ok = dimensions.find( + const areaDimension = dimensions.find( (d) => d.__typename === "GeoShapesDimension" && d.iri === oldValue ); - if (ok) { + if (areaDimension) { return produce(newChartConfig, (draft) => { draft.fields.areaLayer.componentIri = oldValue; + + // Setting the filters so that bottomless areas are shown fist + if (areaDimension?.hierarchy) { + let leafs = [] as HierarchyValue[]; + visitHierarchy(areaDimension?.hierarchy, (node) => { + if ( + (!node.children || node.children.length === 0) && + node.hasValue + ) { + leafs.push(node); + } + }); + if (leafs.length > 0) { + draft.filters[oldValue] = { + type: "multi", + values: Object.fromEntries( + leafs.map((x) => [x.value, true]) + ), + }; + } + } }); } @@ -976,7 +1001,7 @@ const convertTableFieldsToSegmentField = ({ dimensionValues: ( dimensions.find( (d) => d.iri === componentIri - ) as DimensionMetaDataFragment + ) as DimensionMetadataFragment )?.values, }), }; diff --git a/app/charts/line/chart-lines.tsx b/app/charts/line/chart-lines.tsx index 87bb6f880..c6c423c42 100644 --- a/app/charts/line/chart-lines.tsx +++ b/app/charts/line/chart-lines.tsx @@ -33,7 +33,7 @@ import { import { isNumber } from "@/configurator/components/ui-helpers"; import { Observation } from "@/domain/data"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, useDataCubeObservationsQuery, } from "@/graphql/query-hooks"; import { useLocale } from "@/locales/use-locale"; @@ -104,8 +104,8 @@ export const ChartLines = memo(function ChartLines({ interactiveFiltersConfig, }: { observations: Observation[]; - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; fields: LineFields; interactiveFiltersConfig: InteractiveFiltersConfig; }) { diff --git a/app/charts/map/chart-map.tsx b/app/charts/map/chart-map.tsx index fa8f03f62..0911f013a 100644 --- a/app/charts/map/chart-map.tsx +++ b/app/charts/map/chart-map.tsx @@ -31,7 +31,7 @@ import { SymbolLayer, } from "@/domain/data"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, useDataCubeObservationsQuery, useGeoCoordinatesByDimensionIriQuery, useGeoShapesByDimensionIriQuery, @@ -238,8 +238,8 @@ export const ChartMap = memo( }: { features: GeoData; observations: Observation[]; - measures: DimensionMetaDataFragment[]; - dimensions: DimensionMetaDataFragment[]; + measures: DimensionMetadataFragment[]; + dimensions: DimensionMetadataFragment[]; fields: MapFields; baseLayer: BaseLayer; }) => { diff --git a/app/charts/map/map-state.tsx b/app/charts/map/map-state.tsx index 604790edd..a40c61793 100644 --- a/app/charts/map/map-state.tsx +++ b/app/charts/map/map-state.tsx @@ -48,7 +48,7 @@ import { Observation, ObservationValue, } from "@/domain/data"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; import { getBBox } from "./helpers"; @@ -68,8 +68,8 @@ export interface MapState { measureLabel: string; getLabel: (d: Observation) => string; getValue: (d: Observation) => number | null; - measureDimension?: DimensionMetaDataFragment; - errorDimension?: DimensionMetaDataFragment; + measureDimension?: DimensionMetadataFragment; + errorDimension?: DimensionMetadataFragment; getFormattedError: null | ((d: Observation) => string); getColor: (x: number | null) => number[]; colorScale: @@ -90,8 +90,8 @@ export interface MapState { measureLabel: string; getLabel: (d: Observation) => string; getValue: (d: Observation) => number | null; - errorDimension?: DimensionMetaDataFragment; - measureDimension?: DimensionMetaDataFragment; + errorDimension?: DimensionMetadataFragment; + measureDimension?: DimensionMetadataFragment; getFormattedError: null | ((d: Observation) => string); color: string; radiusScale: ScalePower; diff --git a/app/charts/pie/chart-pie.tsx b/app/charts/pie/chart-pie.tsx index a2ba80efb..14fc311ba 100644 --- a/app/charts/pie/chart-pie.tsx +++ b/app/charts/pie/chart-pie.tsx @@ -27,7 +27,7 @@ import { } from "@/configurator"; import { Observation } from "@/domain/data"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, useDataCubeObservationsQuery, } from "@/graphql/query-hooks"; import { useLocale } from "@/locales/use-locale"; @@ -101,8 +101,8 @@ export const ChartPie = memo( interactiveFiltersConfig, }: { observations: Observation[]; - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; fields: PieFields; interactiveFiltersConfig: InteractiveFiltersConfig; }) => { diff --git a/app/charts/scatterplot/chart-scatterplot.tsx b/app/charts/scatterplot/chart-scatterplot.tsx index d41e36068..9e29b3ffc 100644 --- a/app/charts/scatterplot/chart-scatterplot.tsx +++ b/app/charts/scatterplot/chart-scatterplot.tsx @@ -36,7 +36,7 @@ import { import { isNumber } from "@/configurator/components/ui-helpers"; import { Observation } from "@/domain/data"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, useDataCubeObservationsQuery, } from "@/graphql/query-hooks"; import { useLocale } from "@/locales/use-locale"; @@ -111,8 +111,8 @@ export const ChartScatterplot = memo( interactiveFiltersConfig, }: { observations: Observation[]; - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; fields: ScatterPlotFields; interactiveFiltersConfig: InteractiveFiltersConfig; }) => { diff --git a/app/charts/shared/a11y-table.tsx b/app/charts/shared/a11y-table.tsx index 0c91bf7fe..d8d08edcb 100644 --- a/app/charts/shared/a11y-table.tsx +++ b/app/charts/shared/a11y-table.tsx @@ -4,7 +4,7 @@ import { memo, useMemo } from "react"; import VisuallyHidden from "@/components/visually-hidden"; import { ChartFields } from "@/configurator"; import { Observation } from "@/domain/data"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; export const A11yTable = memo( ({ @@ -15,8 +15,8 @@ export const A11yTable = memo( observations, }: { title: string; - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; fields: ChartFields; observations: Observation[]; }) => { diff --git a/app/charts/shared/chart-helpers.tsx b/app/charts/shared/chart-helpers.tsx index 5a2c7d004..09e6d6598 100644 --- a/app/charts/shared/chart-helpers.tsx +++ b/app/charts/shared/chart-helpers.tsx @@ -20,7 +20,7 @@ import { } from "@/configurator/config-types"; import { FIELD_VALUE_NONE } from "@/configurator/constants"; import { Observation } from "@/domain/data"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; import truthy from "@/utils/truthy"; export type QueryFilters = Filters | FilterValueSingle; @@ -286,7 +286,7 @@ const SlugRe = /\W+/g; export const getSlugifiedIri = (iri: string) => iri.replace(SlugRe, "_"); export const getLabelWithUnit = ( - dimension: DimensionMetaDataFragment + dimension: DimensionMetadataFragment ): string => { return dimension.unit ? `${dimension.label} (${dimension.unit})` diff --git a/app/charts/shared/use-chart-state.tsx b/app/charts/shared/use-chart-state.tsx index 9abd28aa7..e25d82d40 100644 --- a/app/charts/shared/use-chart-state.tsx +++ b/app/charts/shared/use-chart-state.tsx @@ -13,15 +13,15 @@ import { ScatterplotState } from "@/charts/scatterplot/scatterplot-state"; import { TableChartState } from "@/charts/table/table-state"; import { ChartFields, InteractiveFiltersConfig } from "@/configurator"; import { Observation } from "@/domain/data"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; import { Has } from "@/lib/has"; export interface ChartProps { data: Observation[]; fields: ChartFields; interactiveFiltersConfig: InteractiveFiltersConfig; - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; } export type ChartState = diff --git a/app/charts/table/chart-table.tsx b/app/charts/table/chart-table.tsx index c30ee3b82..6d5c5e144 100644 --- a/app/charts/table/chart-table.tsx +++ b/app/charts/table/chart-table.tsx @@ -13,7 +13,7 @@ import { DataSource, TableConfig } from "@/configurator"; import { isNumber } from "@/configurator/components/ui-helpers"; import { Observation } from "@/domain/data"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, useDataCubeObservationsQuery, } from "@/graphql/query-hooks"; import { useLocale } from "@/locales/use-locale"; @@ -72,8 +72,8 @@ const ChartTable = memo(function ChartTable({ chartConfig, }: { observations: Observation[]; - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; chartConfig: TableConfig; }) { return ( diff --git a/app/charts/table/table-state.tsx b/app/charts/table/table-state.tsx index 6a1bddff5..8229a4d99 100644 --- a/app/charts/table/table-state.tsx +++ b/app/charts/table/table-state.tsx @@ -32,7 +32,7 @@ import { useOrderedTableColumns, } from "@/configurator/components/ui-helpers"; import { Observation } from "@/domain/data"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; import { estimateTextWidth } from "@/lib/estimate-text-width"; import { useTheme } from "@/themes"; @@ -250,7 +250,7 @@ const useTableState = ({ const { colorMapping } = columnStyle as ColumnStyleCategory; const dimension = dimensions.find( (d) => d.iri === iri - ) as DimensionMetaDataFragment; + ) as DimensionMetadataFragment; // Color scale (always from colorMappings) const colorScale = scaleOrdinal(); diff --git a/app/components/data-download.tsx b/app/components/data-download.tsx index a027afca6..16d35a8f2 100644 --- a/app/components/data-download.tsx +++ b/app/components/data-download.tsx @@ -35,7 +35,7 @@ import { DataCubeObservationsDocument, DataCubeObservationsQuery, DataCubeObservationsQueryVariables, - DimensionMetaDataFragment, + DimensionMetadataFragment, } from "../graphql/query-hooks"; import { Icon } from "../icons"; @@ -81,7 +81,7 @@ export const DataDownloadStateProvider = ({ const FILE_FORMATS = ["csv", "xlsx"] as const; export type FileFormat = typeof FILE_FORMATS[number]; -const makeColumnLabel = (dim: DimensionMetaDataFragment) => { +const makeColumnLabel = (dim: DimensionMetadataFragment) => { return `${dim.label}${dim.unit ? ` (${dim.unit})` : ""}`; }; const prepareData = ({ @@ -89,8 +89,8 @@ const prepareData = ({ measures, observations, }: { - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; observations: Observation[]; }) => { const columns = keyBy([...dimensions, ...measures], (d) => d.iri); diff --git a/app/configurator/components/chart-controls/color-palette.tsx b/app/configurator/components/chart-controls/color-palette.tsx index b7934d49a..a20e7c803 100644 --- a/app/configurator/components/chart-controls/color-palette.tsx +++ b/app/configurator/components/chart-controls/color-palette.tsx @@ -24,14 +24,14 @@ import { getPalette, mapValueIrisToColor, } from "@/configurator/components/ui-helpers"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; import useEvent from "@/lib/use-event"; type Props = { field: string; disabled?: boolean; colorConfigPath?: string; - component: DimensionMetaDataFragment | undefined; + component: DimensionMetadataFragment | undefined; }; const useStyles = makeStyles({ @@ -180,7 +180,7 @@ const ColorPaletteReset = ({ }: { field: string; colorConfigPath?: string; - component: DimensionMetaDataFragment; + component: DimensionMetadataFragment; state: ConfiguratorStateConfiguringChart; }) => { const [, dispatch] = useConfiguratorState(); diff --git a/app/configurator/components/chart-controls/control-tab.tsx b/app/configurator/components/chart-controls/control-tab.tsx index e980438c9..a97bb86c7 100644 --- a/app/configurator/components/chart-controls/control-tab.tsx +++ b/app/configurator/components/chart-controls/control-tab.tsx @@ -8,7 +8,7 @@ import { getFieldLabel, getIconName, } from "@/configurator/components/ui-helpers"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; import { Icon, IconName } from "@/icons"; export const ControlTab = ({ @@ -18,7 +18,7 @@ export const ControlTab = ({ checked, labelId, }: { - component?: DimensionMetaDataFragment; + component?: DimensionMetadataFragment; value: string; onClick: (x: string) => void; labelId: string; @@ -136,7 +136,7 @@ export const DraggableTab = ({ disabled, iconName, }: { - component: DimensionMetaDataFragment; + component: DimensionMetadataFragment; disabled?: boolean; onClick: (x: string) => void; value: string; diff --git a/app/configurator/components/chart-controls/drag-and-drop-tab.tsx b/app/configurator/components/chart-controls/drag-and-drop-tab.tsx index 1436ce318..b0ec39397 100644 --- a/app/configurator/components/chart-controls/drag-and-drop-tab.tsx +++ b/app/configurator/components/chart-controls/drag-and-drop-tab.tsx @@ -12,7 +12,7 @@ import { import { getIconName } from "@/configurator/components/ui-helpers"; import { useActiveFieldField } from "@/configurator/config-form"; import { TableColumn } from "@/configurator/config-types"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; import { DataCubeMetadata } from "@/graphql/types"; import { Icon } from "@/icons"; @@ -134,7 +134,7 @@ const DraggableTabField = ({ upperLabel, disabled, }: { - component: DimensionMetaDataFragment; + component: DimensionMetadataFragment; value: string; disabled?: boolean; isDragging: boolean; diff --git a/app/configurator/components/chart-options-selector.tsx b/app/configurator/components/chart-options-selector.tsx index 4a0edd439..c9d785f00 100644 --- a/app/configurator/components/chart-options-selector.tsx +++ b/app/configurator/components/chart-options-selector.tsx @@ -53,7 +53,7 @@ import { isStandardErrorDimension, } from "@/domain/data"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, useDataCubeObservationsQuery, } from "@/graphql/query-hooks"; import { DataCubeMetadata } from "@/graphql/types"; @@ -181,7 +181,7 @@ const EncodingOptionsPanel = ({ state: ConfiguratorStateConfiguringChart; field: string; chartType: ChartType; - component: DimensionMetaDataFragment | undefined; + component: DimensionMetadataFragment | undefined; metaData: DataCubeMetadata; imputationNeeded: boolean; }) => { diff --git a/app/configurator/components/datatable.tsx b/app/configurator/components/datatable.tsx index c1f3d2737..41f548298 100644 --- a/app/configurator/components/datatable.tsx +++ b/app/configurator/components/datatable.tsx @@ -17,7 +17,7 @@ import { Loading } from "@/components/hint"; import { ChartConfig, DataSource } from "@/configurator/config-types"; import { Observation } from "@/domain/data"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, useDataCubeObservationsQuery, useDataCubePreviewObservationsQuery, } from "@/graphql/query-hooks"; @@ -31,10 +31,10 @@ export const PreviewTable = ({ observations, }: { title: string; - headers: DimensionMetaDataFragment[]; + headers: DimensionMetadataFragment[]; observations: Observation[]; }) => { - const [sortBy, setSortBy] = useState(); + const [sortBy, setSortBy] = useState(); const [sortDirection, setSortDirection] = useState<"asc" | "desc">(); const formatters = useDimensionFormatters(headers); const sortedObservations = useMemo(() => { @@ -141,8 +141,8 @@ export const DataSetPreviewTable = ({ title: string; dataSetIri: string; dataSource: DataSource; - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; }) => { const locale = useLocale(); const [{ data, fetching }] = useDataCubePreviewObservationsQuery({ @@ -222,8 +222,8 @@ export const DataSetTable = ({ }; function getSortedHeaders( - dimensions: DimensionMetaDataFragment[], - measures: DimensionMetaDataFragment[] + dimensions: DimensionMetadataFragment[], + measures: DimensionMetadataFragment[] ) { const allDimensions = [...dimensions, ...measures]; allDimensions.sort((a, b) => diff --git a/app/configurator/components/field.tsx b/app/configurator/components/field.tsx index 2481a5741..d5351f8a8 100644 --- a/app/configurator/components/field.tsx +++ b/app/configurator/components/field.tsx @@ -44,7 +44,7 @@ import { } from "@/configurator/config-form"; import { useConfiguratorState } from "@/configurator/configurator-state"; import { FIELD_VALUE_NONE } from "@/configurator/constants"; -import { DimensionMetaDataFragment, TimeUnit } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment, TimeUnit } from "@/graphql/query-hooks"; import { DataCubeMetadata } from "@/graphql/types"; import { IconName } from "@/icons"; import truthy from "@/utils/truthy"; @@ -55,7 +55,7 @@ export const ControlTabField = ({ disabled, labelId, }: { - component?: DimensionMetaDataFragment; + component?: DimensionMetadataFragment; value: string; disabled?: boolean; labelId: string; diff --git a/app/configurator/components/ui-helpers.spec.ts b/app/configurator/components/ui-helpers.spec.ts index f75140e1b..65998ba5e 100644 --- a/app/configurator/components/ui-helpers.spec.ts +++ b/app/configurator/components/ui-helpers.spec.ts @@ -1,6 +1,6 @@ import { renderHook } from "@testing-library/react-hooks"; -import { DimensionMetaDataFragment, TimeUnit } from "../../graphql/query-hooks"; +import { DimensionMetadataFragment, TimeUnit } from "../../graphql/query-hooks"; import { getTimeIntervalFormattedSelectOptions, @@ -42,7 +42,7 @@ describe("useDimensionFormatters", () => { isNumerical: false, isKeyDimension: false, __typename: "TemporalDimension", - } as DimensionMetaDataFragment, + } as DimensionMetadataFragment, { iri: "iri-yearly", timeFormat: "%Y", @@ -50,12 +50,12 @@ describe("useDimensionFormatters", () => { isNumerical: false, isKeyDimension: false, __typename: "TemporalDimension", - } as DimensionMetaDataFragment, + } as DimensionMetadataFragment, { iri: "iri-number", isNumerical: true, isKeyDimension: false, - } as DimensionMetaDataFragment, + } as DimensionMetadataFragment, { iri: "iri-currency", isNumerical: true, @@ -63,7 +63,7 @@ describe("useDimensionFormatters", () => { isCurrency: true, currencyExponent: 1, __typename: "Measure", - } as DimensionMetaDataFragment, + } as DimensionMetadataFragment, ]) ); return { formatters }; diff --git a/app/configurator/components/ui-helpers.ts b/app/configurator/components/ui-helpers.ts index c4027242a..d50dbbf4e 100644 --- a/app/configurator/components/ui-helpers.ts +++ b/app/configurator/components/ui-helpers.ts @@ -50,7 +50,7 @@ import { useMemo } from "react"; import { ChartProps } from "../../charts/shared/use-chart-state"; import { Observation } from "../../domain/data"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, Measure, TemporalDimension, TimeUnit, @@ -138,12 +138,12 @@ const formatIdentity = (x: string | Date | null) => { return `${x}`; }; -const isNamedNodeDimension = (d: DimensionMetaDataFragment) => { +const isNamedNodeDimension = (d: DimensionMetadataFragment) => { const first = d.values?.[0]; return first && first.label !== first.value; }; -const namedNodeFormatter = (d: DimensionMetaDataFragment) => { +const namedNodeFormatter = (d: DimensionMetadataFragment) => { const valuesByIri = keyBy(d.values, (x) => x.value); return (v: string) => { return valuesByIri[v]?.label || v; @@ -157,7 +157,7 @@ const currencyFormatter = (d: Measure, locale: string) => { }; export const useDimensionFormatters = ( - dimensions: DimensionMetaDataFragment[] + dimensions: DimensionMetadataFragment[] ) => { const locale = useLocale(); const formatNumber = useFormatNumber() as unknown as ( @@ -423,7 +423,7 @@ export const useErrorMeasure = ( }, [dimensions, measures, valueIri]); }; -export const useErrorVariable = (errorMeasure?: DimensionMetaDataFragment) => { +export const useErrorVariable = (errorMeasure?: DimensionMetadataFragment) => { return useMemo(() => { return errorMeasure ? (d: Observation) => { @@ -434,7 +434,7 @@ export const useErrorVariable = (errorMeasure?: DimensionMetaDataFragment) => { }; export const useErrorRange = ( - errorMeasure: DimensionMetaDataFragment | undefined, + errorMeasure: DimensionMetadataFragment | undefined, valueGetter: (d: Observation) => number | null ) => { return useMemo(() => { @@ -1002,7 +1002,7 @@ export const mapValueIrisToColor = ({ random, }: { palette: string; - dimensionValues: DimensionMetaDataFragment["values"]; + dimensionValues: DimensionMetadataFragment["values"]; random?: boolean; }) => { if (!dimensionValues) { diff --git a/app/configurator/configurator-state.spec.tsx b/app/configurator/configurator-state.spec.tsx index 312260eb4..a1ce8b59f 100644 --- a/app/configurator/configurator-state.spec.tsx +++ b/app/configurator/configurator-state.spec.tsx @@ -21,7 +21,7 @@ import { initChartStateFromLocalStorage, moveFilterField, } from "@/configurator/configurator-state"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; import { DataCubeMetadata } from "@/graphql/types"; import covid19ColumnChartConfig from "@/test/__fixtures/config/dev/chartConfig-column-covid19.json"; import covid19TableChartConfig from "@/test/__fixtures/config/dev/chartConfig-table-covid19.json"; @@ -132,7 +132,7 @@ describe("applyDimensionToFilters", () => { ], unit: null, __typename: "NominalDimension", - } as DimensionMetaDataFragment; + } as DimensionMetadataFragment; const optionalDimension = { iri: "https://environment.ld.admin.ch/foen/ubd0104/parametertype", @@ -144,7 +144,7 @@ describe("applyDimensionToFilters", () => { ], unit: null, __typename: "NominalDimension", - } as DimensionMetaDataFragment; + } as DimensionMetadataFragment; describe("applyNonTableDimensionToFilters", () => { it("should remove single value filter when a keyDimension is used as a field", () => { diff --git a/app/configurator/configurator-state.tsx b/app/configurator/configurator-state.tsx index 8658649d1..66c7a8d75 100644 --- a/app/configurator/configurator-state.tsx +++ b/app/configurator/configurator-state.tsx @@ -52,7 +52,7 @@ import { DataCubeMetadataWithComponentValuesDocument, DataCubeMetadataWithComponentValuesQuery, DataCubeMetadataWithComponentValuesQueryVariables, - DimensionMetaDataFragment, + DimensionMetadataFragment, } from "@/graphql/query-hooks"; import { DataCubeMetadata } from "@/graphql/types"; import { createChartId } from "@/lib/create-chart-id"; @@ -358,7 +358,7 @@ export const applyTableDimensionToFilters = ({ isGrouped, }: { filters: Filters; - dimension: DimensionMetaDataFragment; + dimension: DimensionMetadataFragment; isHidden: boolean; isGrouped: boolean; }) => { @@ -409,7 +409,7 @@ export const applyNonTableDimensionToFilters = ({ isField, }: { filters: Filters; - dimension: DimensionMetaDataFragment; + dimension: DimensionMetadataFragment; isField: boolean; }) => { const currentFilter = filters[dimension.iri]; @@ -1390,7 +1390,7 @@ export const useReadOnlyConfiguratorState = ( ); } - const [state, dispatch] = ctx; + const [state] = ctx; if (predicate && !predicate(state)) { throw new Error("State does not respect type guard"); diff --git a/app/configurator/interactive-filters/interactive-filters-config-actions.tsx b/app/configurator/interactive-filters/interactive-filters-config-actions.tsx index 761d33173..7312c190b 100644 --- a/app/configurator/interactive-filters/interactive-filters-config-actions.tsx +++ b/app/configurator/interactive-filters/interactive-filters-config-actions.tsx @@ -9,7 +9,7 @@ import { toggleInteractiveTimeFilter, } from "@/configurator/interactive-filters/interactive-filters-config-state"; import { InteractiveFilterType } from "@/configurator/interactive-filters/interactive-filters-configurator"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; export const useInteractiveFiltersToggle = ({ path, @@ -90,7 +90,7 @@ export const useInteractiveDataFiltersToggle = ({ dimensions, }: { path: "dataFilters"; - dimensions: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; }) => { const [state, dispatch] = useConfiguratorState(); diff --git a/app/configurator/interactive-filters/interactive-filters-config-options.tsx b/app/configurator/interactive-filters/interactive-filters-config-options.tsx index 6f4834237..cb81c91ed 100644 --- a/app/configurator/interactive-filters/interactive-filters-config-options.tsx +++ b/app/configurator/interactive-filters/interactive-filters-config-options.tsx @@ -26,7 +26,7 @@ import { import { toggleInteractiveFilterDataDimension } from "@/configurator/interactive-filters/interactive-filters-config-state"; import { InteractiveFilterType } from "@/configurator/interactive-filters/interactive-filters-configurator"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, TimeUnit, useDataCubeMetadataWithComponentValuesQuery, } from "@/graphql/query-hooks"; @@ -234,7 +234,7 @@ const InteractiveDataFiltersToggle = ({ path: "dataFilters"; defaultChecked?: boolean; disabled?: boolean; - dimensions: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; }) => { const fieldProps = useInteractiveDataFiltersToggle({ path, diff --git a/app/configurator/interactive-filters/interactive-filters-config-state.tsx b/app/configurator/interactive-filters/interactive-filters-config-state.tsx index 5d56762d3..53334bd1a 100644 --- a/app/configurator/interactive-filters/interactive-filters-config-state.tsx +++ b/app/configurator/interactive-filters/interactive-filters-config-state.tsx @@ -2,7 +2,7 @@ import produce from "immer"; import { InteractiveFiltersConfig } from "@/configurator/config-types"; import { InteractiveFilterType } from "@/configurator/interactive-filters/interactive-filters-configurator"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; export const toggleInteractiveFilter = produce( ( @@ -79,7 +79,7 @@ export const toggleInteractiveDataFilter = produce( }: { path: "dataFilters"; value: boolean; - dimensions: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; } ): InteractiveFiltersConfig => { if (!IFConfig?.[path]) { diff --git a/app/configurator/table/table-chart-options.tsx b/app/configurator/table/table-chart-options.tsx index 3407158db..2da4df682 100644 --- a/app/configurator/table/table-chart-options.tsx +++ b/app/configurator/table/table-chart-options.tsx @@ -40,7 +40,7 @@ import { updateIsHidden, } from "@/configurator/table/table-config-state"; import { canDimensionBeMultiFiltered } from "@/domain/data"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; import { DataCubeMetadata } from "@/graphql/types"; const useTableColumnGroupHiddenField = ({ @@ -263,7 +263,7 @@ export const TableColumnOptions = ({ colorMapping: mapValueIrisToColor({ palette: getDefaultCategoricalPalette().value, dimensionValues: ( - component as DimensionMetaDataFragment + component as DimensionMetadataFragment )?.values, }), }; @@ -296,7 +296,7 @@ export const TableColumnOptions = ({ @@ -366,7 +366,7 @@ const ColumnStyleSubOptions = ({ }: { chartConfig: TableConfig; activeField: string; - component: DimensionMetaDataFragment; + component: DimensionMetadataFragment; }) => { const type = chartConfig.fields[activeField].columnStyle.type; return ( diff --git a/app/docs/columns.docs.tsx b/app/docs/columns.docs.tsx index 9b7ffd553..2e5bb0eda 100644 --- a/app/docs/columns.docs.tsx +++ b/app/docs/columns.docs.tsx @@ -11,7 +11,7 @@ import { import { ChartContainer, ChartSvg } from "@/charts/shared/containers"; import { Tooltip } from "@/charts/shared/interaction/tooltip"; import { InteractiveFiltersProvider } from "@/charts/shared/use-interactive-filters"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; export const Docs = () => markdown` @@ -194,7 +194,7 @@ const columnMeasures = [ ], __typename: "Measure", }, -] as DimensionMetaDataFragment[]; +] as DimensionMetadataFragment[]; const columnDimensions = [ { @@ -488,7 +488,7 @@ const columnDimensions = [ ], __typename: "NominalDimension", }, -] as unknown as DimensionMetaDataFragment[]; +] as unknown as DimensionMetadataFragment[]; const columnObservations = [ { "http://environment.ld.admin.ch/foen/px/0703010000_103/dimension/1": diff --git a/app/docs/data-table.docs.tsx b/app/docs/data-table.docs.tsx index 231d1f02b..ade245761 100644 --- a/app/docs/data-table.docs.tsx +++ b/app/docs/data-table.docs.tsx @@ -10,7 +10,7 @@ import { tableMeasures, tableObservations, } from "@/docs/fixtures"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; export const Docs = () => markdown` @@ -20,8 +20,8 @@ ${( diff --git a/app/docs/fixtures.ts b/app/docs/fixtures.ts index 832bc07f6..dc087991c 100644 --- a/app/docs/fixtures.ts +++ b/app/docs/fixtures.ts @@ -1,7 +1,7 @@ import { DEFAULT_DATA_SOURCE } from "@/domain/datasource"; import { ColumnFields, ConfiguratorState, TableConfig } from "../configurator"; -import { DimensionMetaDataFragment, TimeUnit } from "../graphql/query-hooks"; +import { DimensionMetadataFragment, TimeUnit } from "../graphql/query-hooks"; export const states: ConfiguratorState[] = [ { @@ -114,7 +114,7 @@ export const fields: ColumnFields = { }, }; -export const dimensions: DimensionMetaDataFragment[] = [ +export const dimensions: DimensionMetadataFragment[] = [ { iri: "http://environment.ld.admin.ch/foen/px/0703030000_124/dimension/0", label: "Jahr", @@ -145,7 +145,7 @@ export const dimensions: DimensionMetaDataFragment[] = [ values: [], }, ]; -export const measures: DimensionMetaDataFragment[] = [ +export const measures: DimensionMetadataFragment[] = [ { iri: "http://environment.ld.admin.ch/foen/px/0703030000_124/measure/0", label: "Investitionen: Einnahmen - Total", diff --git a/app/docs/lines.docs.tsx b/app/docs/lines.docs.tsx index 90293a147..76a521b9a 100644 --- a/app/docs/lines.docs.tsx +++ b/app/docs/lines.docs.tsx @@ -9,7 +9,7 @@ import { BrushTime } from "@/charts/shared/brush"; import { ChartContainer, ChartSvg } from "@/charts/shared/containers"; import { InteractiveLegendColor } from "@/charts/shared/legend-color"; import { InteractiveFiltersProvider } from "@/charts/shared/use-interactive-filters"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; export const Docs = () => markdown` @@ -173,7 +173,7 @@ const measures = [ label: "Übrige Sortimente in m3", __typename: "Measure", }, -] as DimensionMetaDataFragment[]; +] as DimensionMetadataFragment[]; const dimensions = [ { @@ -461,7 +461,7 @@ const dimensions = [ ], __typename: "NominalDimension", }, -] as unknown as DimensionMetaDataFragment[]; +] as unknown as DimensionMetadataFragment[]; const observations = [ { "http://environment.ld.admin.ch/foen/px/0703010000_103/dimension/1": diff --git a/app/docs/scatterplot.docs.tsx b/app/docs/scatterplot.docs.tsx index 013dcf41a..b27be776d 100644 --- a/app/docs/scatterplot.docs.tsx +++ b/app/docs/scatterplot.docs.tsx @@ -16,7 +16,7 @@ import { Tooltip } from "@/charts/shared/interaction/tooltip"; import { InteractiveLegendColor } from "@/charts/shared/legend-color"; import { InteractionVoronoi } from "@/charts/shared/overlay-voronoi"; import { InteractiveFiltersProvider } from "@/charts/shared/use-interactive-filters"; -import { DimensionMetaDataFragment } from "@/graphql/query-hooks"; +import { DimensionMetadataFragment } from "@/graphql/query-hooks"; export const Docs = () => markdown` @@ -178,7 +178,7 @@ const scatterplotMeasures = [ label: "Übrige Sortimente in m3", __typename: "Measure", }, -] as DimensionMetaDataFragment[]; +] as DimensionMetadataFragment[]; const scatterplotDimensions = [ { @@ -466,7 +466,7 @@ const scatterplotDimensions = [ ], __typename: "NominalDimension", }, -] as unknown as DimensionMetaDataFragment[]; +] as unknown as DimensionMetadataFragment[]; const scatterplotObservations = [ { "http://environment.ld.admin.ch/foen/px/0703010000_103/dimension/1": diff --git a/app/domain/data.ts b/app/domain/data.ts index 0bfaacf0e..8f8ada78c 100644 --- a/app/domain/data.ts +++ b/app/domain/data.ts @@ -2,7 +2,7 @@ import { Literal, NamedNode } from "rdf-js"; import { DimensionType } from "../charts/chart-config-ui-options"; import { - DimensionMetaDataFragment, + DimensionMetadataFragment, GeoCoordinatesDimension, GeoShapesDimension, NominalDimension, @@ -130,16 +130,16 @@ export const parseObservationValue = ({ /** * @fixme use metadata to filter time dimension! */ -export const getTimeDimensions = (dimensions: DimensionMetaDataFragment[]) => +export const getTimeDimensions = (dimensions: DimensionMetadataFragment[]) => dimensions.filter((d) => d.__typename === "TemporalDimension"); export const isCategoricalDimension = ( - d: DimensionMetaDataFragment + d: DimensionMetadataFragment ): d is NominalDimension | OrdinalDimension => { return isNominalDimension(d) || isOrdinalDimension(d); }; -export const canDimensionBeMultiFiltered = (d: DimensionMetaDataFragment) => { +export const canDimensionBeMultiFiltered = (d: DimensionMetadataFragment) => { return ( isNominalDimension(d) || isOrdinalDimension(d) || @@ -152,18 +152,18 @@ export const canDimensionBeMultiFiltered = (d: DimensionMetaDataFragment) => { * @fixme use metadata to filter categorical dimension! */ export const getCategoricalDimensions = ( - dimensions: DimensionMetaDataFragment[] + dimensions: DimensionMetadataFragment[] ) => dimensions.filter(isCategoricalDimension); export const getGeoCoordinatesDimensions = ( - dimensions: DimensionMetaDataFragment[] + dimensions: DimensionMetadataFragment[] ) => dimensions.filter((d) => d.__typename === "GeoCoordinatesDimension"); export const getGeoShapesDimensions = ( - dimensions: DimensionMetaDataFragment[] + dimensions: DimensionMetadataFragment[] ) => dimensions.filter((d) => d.__typename === "GeoShapesDimension"); -export const getGeoDimensions = (dimensions: DimensionMetaDataFragment[]) => +export const getGeoDimensions = (dimensions: DimensionMetadataFragment[]) => dimensions.filter((d) => ["GeoCoordinatesDimension", "GeoShapesDimension"].includes(d.__typename) ); @@ -174,33 +174,33 @@ export const getDimensionsByDimensionType = ({ measures, }: { dimensionTypes: DimensionType[]; - dimensions: DimensionMetaDataFragment[]; - measures: DimensionMetaDataFragment[]; + dimensions: DimensionMetadataFragment[]; + measures: DimensionMetadataFragment[]; }) => [...measures, ...dimensions].filter((component) => dimensionTypes.includes(component.__typename) ); export const isNominalDimension = ( - dimension?: DimensionMetaDataFragment + dimension?: DimensionMetadataFragment ): dimension is GeoCoordinatesDimension => { return dimension?.__typename === "NominalDimension"; }; export const isOrdinalDimension = ( - dimension?: DimensionMetaDataFragment + dimension?: DimensionMetadataFragment ): dimension is GeoCoordinatesDimension => { return dimension?.__typename === "OrdinalDimension"; }; export const isGeoCoordinatesDimension = ( - dimension?: DimensionMetaDataFragment + dimension?: DimensionMetadataFragment ): dimension is GeoCoordinatesDimension => { return dimension?.__typename === "GeoCoordinatesDimension"; }; export const isGeoShapesDimension = ( - dimension?: DimensionMetaDataFragment + dimension?: DimensionMetadataFragment ): dimension is GeoShapesDimension => { return dimension?.__typename === "GeoShapesDimension"; }; @@ -209,13 +209,13 @@ export const isStandardErrorResolvedDimension = (dim: ResolvedDimension) => { return dim.data?.related.some((x) => x.type === "StandardError"); }; -export const isStandardErrorDimension = (dim: DimensionMetaDataFragment) => { +export const isStandardErrorDimension = (dim: DimensionMetadataFragment) => { return dim?.related?.some((r) => r.type === "StandardError"); }; export const findRelatedErrorDimension = ( dimIri: string, - dimensions: DimensionMetaDataFragment[] + dimensions: DimensionMetadataFragment[] ) => { return dimensions.find((x) => x.related?.some((r) => r.iri === dimIri && r.type === "StandardError") diff --git a/app/graphql/queries/data-cubes.graphql b/app/graphql/queries/data-cubes.graphql index f6a0ae820..4adad9c84 100644 --- a/app/graphql/queries/data-cubes.graphql +++ b/app/graphql/queries/data-cubes.graphql @@ -37,7 +37,7 @@ query DataCubes( } } -fragment dimensionMetaData on Dimension { +fragment dimensionMetadata on Dimension { iri label isNumerical @@ -79,10 +79,10 @@ query DataCubePreview( description publicationStatus dimensions(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata } measures(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata } } } @@ -177,10 +177,27 @@ query DataCubeMetadataWithComponentValues( } landingPage dimensions(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata + ...hierarchyMetadata } measures(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata + ...hierarchyMetadata + } + } +} + +fragment hierarchyMetadata on Dimension { + hierarchy(sourceType: $sourceType, sourceUrl: $sourceUrl) { + ...hierarchyValueFields + children { + ...hierarchyValueFields + children { + ...hierarchyValueFields + children { + ...hierarchyValueFields + } + } } } } @@ -206,7 +223,7 @@ query DimensionValues( sourceType: $sourceType sourceUrl: $sourceUrl ) { - ...dimensionMetaData + ...dimensionMetadata } } } @@ -292,7 +309,7 @@ query TemporalDimensionValues( sourceUrl: $sourceUrl ) { ... on TemporalDimension { - ...dimensionMetaData + ...dimensionMetadata timeUnit timeFormat } @@ -321,10 +338,10 @@ query DataCubeObservations( title description dimensions(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata } measures(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata } observations( sourceType: $sourceType @@ -422,18 +439,7 @@ query DimensionHierarchy( sourceType: $sourceType sourceUrl: $sourceUrl ) { - hierarchy(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...hierarchyValueFields - children { - ...hierarchyValueFields - children { - ...hierarchyValueFields - children { - ...hierarchyValueFields - } - } - } - } + ...hierarchyMetadata } } } diff --git a/app/graphql/query-hooks.ts b/app/graphql/query-hooks.ts index ebf3d5c0b..1504b6f2d 100644 --- a/app/graphql/query-hooks.ts +++ b/app/graphql/query-hooks.ts @@ -451,19 +451,19 @@ export type DataCubesQueryVariables = Exact<{ export type DataCubesQuery = { __typename: 'Query', dataCubes: Array<{ __typename: 'DataCubeResult', highlightedTitle?: Maybe, highlightedDescription?: Maybe, dataCube: { __typename: 'DataCube', iri: string, title: string, workExamples?: Maybe>>, description?: Maybe, publicationStatus: DataCubePublicationStatus, datePublished?: Maybe, creator?: Maybe<{ __typename: 'DataCubeOrganization', iri: string, label?: Maybe }>, themes: Array<{ __typename: 'DataCubeTheme', iri: string, label?: Maybe }> } }> }; -type DimensionMetaData_GeoCoordinatesDimension_Fragment = { __typename: 'GeoCoordinatesDimension', iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; +type DimensionMetadata_GeoCoordinatesDimension_Fragment = { __typename: 'GeoCoordinatesDimension', iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; -type DimensionMetaData_GeoShapesDimension_Fragment = { __typename: 'GeoShapesDimension', iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; +type DimensionMetadata_GeoShapesDimension_Fragment = { __typename: 'GeoShapesDimension', iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; -type DimensionMetaData_Measure_Fragment = { __typename: 'Measure', isCurrency?: Maybe, currencyExponent?: Maybe, iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; +type DimensionMetadata_Measure_Fragment = { __typename: 'Measure', isCurrency?: Maybe, currencyExponent?: Maybe, iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; -type DimensionMetaData_NominalDimension_Fragment = { __typename: 'NominalDimension', iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; +type DimensionMetadata_NominalDimension_Fragment = { __typename: 'NominalDimension', iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; -type DimensionMetaData_OrdinalDimension_Fragment = { __typename: 'OrdinalDimension', iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; +type DimensionMetadata_OrdinalDimension_Fragment = { __typename: 'OrdinalDimension', iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; -type DimensionMetaData_TemporalDimension_Fragment = { __typename: 'TemporalDimension', timeUnit: TimeUnit, timeFormat: string, iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; +type DimensionMetadata_TemporalDimension_Fragment = { __typename: 'TemporalDimension', timeUnit: TimeUnit, timeFormat: string, iri: string, label: string, isNumerical: boolean, isKeyDimension: boolean, order?: Maybe, values: Array, unit?: Maybe, related?: Maybe> }; -export type DimensionMetaDataFragment = DimensionMetaData_GeoCoordinatesDimension_Fragment | DimensionMetaData_GeoShapesDimension_Fragment | DimensionMetaData_Measure_Fragment | DimensionMetaData_NominalDimension_Fragment | DimensionMetaData_OrdinalDimension_Fragment | DimensionMetaData_TemporalDimension_Fragment; +export type DimensionMetadataFragment = DimensionMetadata_GeoCoordinatesDimension_Fragment | DimensionMetadata_GeoShapesDimension_Fragment | DimensionMetadata_Measure_Fragment | DimensionMetadata_NominalDimension_Fragment | DimensionMetadata_OrdinalDimension_Fragment | DimensionMetadata_TemporalDimension_Fragment; export type DataCubePreviewQueryVariables = Exact<{ iri: Scalars['String']; @@ -477,25 +477,25 @@ export type DataCubePreviewQueryVariables = Exact<{ export type DataCubePreviewQuery = { __typename: 'Query', dataCubeByIri?: Maybe<{ __typename: 'DataCube', iri: string, title: string, description?: Maybe, publicationStatus: DataCubePublicationStatus, dimensions: Array<( { __typename: 'GeoCoordinatesDimension' } - & DimensionMetaData_GeoCoordinatesDimension_Fragment + & DimensionMetadata_GeoCoordinatesDimension_Fragment ) | ( { __typename: 'GeoShapesDimension' } - & DimensionMetaData_GeoShapesDimension_Fragment + & DimensionMetadata_GeoShapesDimension_Fragment ) | ( { __typename: 'Measure' } - & DimensionMetaData_Measure_Fragment + & DimensionMetadata_Measure_Fragment ) | ( { __typename: 'NominalDimension' } - & DimensionMetaData_NominalDimension_Fragment + & DimensionMetadata_NominalDimension_Fragment ) | ( { __typename: 'OrdinalDimension' } - & DimensionMetaData_OrdinalDimension_Fragment + & DimensionMetadata_OrdinalDimension_Fragment ) | ( { __typename: 'TemporalDimension' } - & DimensionMetaData_TemporalDimension_Fragment + & DimensionMetadata_TemporalDimension_Fragment )>, measures: Array<( { __typename: 'Measure' } - & DimensionMetaData_Measure_Fragment + & DimensionMetadata_Measure_Fragment )> }> }; export type DataCubePreviewObservationsQueryVariables = Exact<{ @@ -533,27 +533,120 @@ export type DataCubeMetadataWithComponentValuesQueryVariables = Exact<{ export type DataCubeMetadataWithComponentValuesQuery = { __typename: 'Query', dataCubeByIri?: Maybe<{ __typename: 'DataCube', iri: string, title: string, publisher?: Maybe, identifier?: Maybe, workExamples?: Maybe>>, landingPage?: Maybe, creator?: Maybe<{ __typename: 'DataCubeOrganization', iri: string }>, dimensions: Array<( { __typename: 'GeoCoordinatesDimension' } - & DimensionMetaData_GeoCoordinatesDimension_Fragment + & DimensionMetadata_GeoCoordinatesDimension_Fragment + & HierarchyMetadata_GeoCoordinatesDimension_Fragment ) | ( { __typename: 'GeoShapesDimension' } - & DimensionMetaData_GeoShapesDimension_Fragment + & DimensionMetadata_GeoShapesDimension_Fragment + & HierarchyMetadata_GeoShapesDimension_Fragment ) | ( { __typename: 'Measure' } - & DimensionMetaData_Measure_Fragment + & DimensionMetadata_Measure_Fragment + & HierarchyMetadata_Measure_Fragment ) | ( { __typename: 'NominalDimension' } - & DimensionMetaData_NominalDimension_Fragment + & DimensionMetadata_NominalDimension_Fragment + & HierarchyMetadata_NominalDimension_Fragment ) | ( { __typename: 'OrdinalDimension' } - & DimensionMetaData_OrdinalDimension_Fragment + & DimensionMetadata_OrdinalDimension_Fragment + & HierarchyMetadata_OrdinalDimension_Fragment ) | ( { __typename: 'TemporalDimension' } - & DimensionMetaData_TemporalDimension_Fragment + & DimensionMetadata_TemporalDimension_Fragment + & HierarchyMetadata_TemporalDimension_Fragment )>, measures: Array<( { __typename: 'Measure' } - & DimensionMetaData_Measure_Fragment + & DimensionMetadata_Measure_Fragment + & HierarchyMetadata_Measure_Fragment )> }> }; +type HierarchyMetadata_GeoCoordinatesDimension_Fragment = { __typename: 'GeoCoordinatesDimension', hierarchy?: Maybe> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> }; + +type HierarchyMetadata_GeoShapesDimension_Fragment = { __typename: 'GeoShapesDimension', hierarchy?: Maybe> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> }; + +type HierarchyMetadata_Measure_Fragment = { __typename: 'Measure', hierarchy?: Maybe> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> }; + +type HierarchyMetadata_NominalDimension_Fragment = { __typename: 'NominalDimension', hierarchy?: Maybe> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> }; + +type HierarchyMetadata_OrdinalDimension_Fragment = { __typename: 'OrdinalDimension', hierarchy?: Maybe> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> }; + +type HierarchyMetadata_TemporalDimension_Fragment = { __typename: 'TemporalDimension', hierarchy?: Maybe> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> } + & HierarchyValueFieldsFragment + )>> }; + +export type HierarchyMetadataFragment = HierarchyMetadata_GeoCoordinatesDimension_Fragment | HierarchyMetadata_GeoShapesDimension_Fragment | HierarchyMetadata_Measure_Fragment | HierarchyMetadata_NominalDimension_Fragment | HierarchyMetadata_OrdinalDimension_Fragment | HierarchyMetadata_TemporalDimension_Fragment; + export type DimensionValuesQueryVariables = Exact<{ dataCubeIri: Scalars['String']; dimensionIri: Scalars['String']; @@ -567,22 +660,22 @@ export type DimensionValuesQueryVariables = Exact<{ export type DimensionValuesQuery = { __typename: 'Query', dataCubeByIri?: Maybe<{ __typename: 'DataCube', dimensionByIri?: Maybe<( { __typename: 'GeoCoordinatesDimension' } - & DimensionMetaData_GeoCoordinatesDimension_Fragment + & DimensionMetadata_GeoCoordinatesDimension_Fragment ) | ( { __typename: 'GeoShapesDimension' } - & DimensionMetaData_GeoShapesDimension_Fragment + & DimensionMetadata_GeoShapesDimension_Fragment ) | ( { __typename: 'Measure' } - & DimensionMetaData_Measure_Fragment + & DimensionMetadata_Measure_Fragment ) | ( { __typename: 'NominalDimension' } - & DimensionMetaData_NominalDimension_Fragment + & DimensionMetadata_NominalDimension_Fragment ) | ( { __typename: 'OrdinalDimension' } - & DimensionMetaData_OrdinalDimension_Fragment + & DimensionMetadata_OrdinalDimension_Fragment ) | ( { __typename: 'TemporalDimension' } - & DimensionMetaData_TemporalDimension_Fragment + & DimensionMetadata_TemporalDimension_Fragment )> }> }; export type GeoCoordinatesByDimensionIriQueryVariables = Exact<{ @@ -622,7 +715,7 @@ export type TemporalDimensionValuesQueryVariables = Exact<{ export type TemporalDimensionValuesQuery = { __typename: 'Query', dataCubeByIri?: Maybe<{ __typename: 'DataCube', dimensionByIri?: Maybe<{ __typename: 'GeoCoordinatesDimension' } | { __typename: 'GeoShapesDimension' } | { __typename: 'Measure' } | { __typename: 'NominalDimension' } | { __typename: 'OrdinalDimension' } | ( { __typename: 'TemporalDimension', timeUnit: TimeUnit, timeFormat: string } - & DimensionMetaData_TemporalDimension_Fragment + & DimensionMetadata_TemporalDimension_Fragment )> }> }; export type DataCubeObservationsQueryVariables = Exact<{ @@ -639,25 +732,25 @@ export type DataCubeObservationsQueryVariables = Exact<{ export type DataCubeObservationsQuery = { __typename: 'Query', dataCubeByIri?: Maybe<{ __typename: 'DataCube', iri: string, title: string, description?: Maybe, dimensions: Array<( { __typename: 'GeoCoordinatesDimension' } - & DimensionMetaData_GeoCoordinatesDimension_Fragment + & DimensionMetadata_GeoCoordinatesDimension_Fragment ) | ( { __typename: 'GeoShapesDimension' } - & DimensionMetaData_GeoShapesDimension_Fragment + & DimensionMetadata_GeoShapesDimension_Fragment ) | ( { __typename: 'Measure' } - & DimensionMetaData_Measure_Fragment + & DimensionMetadata_Measure_Fragment ) | ( { __typename: 'NominalDimension' } - & DimensionMetaData_NominalDimension_Fragment + & DimensionMetadata_NominalDimension_Fragment ) | ( { __typename: 'OrdinalDimension' } - & DimensionMetaData_OrdinalDimension_Fragment + & DimensionMetadata_OrdinalDimension_Fragment ) | ( { __typename: 'TemporalDimension' } - & DimensionMetaData_TemporalDimension_Fragment + & DimensionMetadata_TemporalDimension_Fragment )>, measures: Array<( { __typename: 'Measure' } - & DimensionMetaData_Measure_Fragment + & DimensionMetadata_Measure_Fragment )>, observations: { __typename: 'ObservationsQuery', data: Array, sparqlEditorUrl?: Maybe } }> }; export type PossibleFiltersQueryVariables = Exact<{ @@ -709,79 +802,25 @@ export type DimensionHierarchyQueryVariables = Exact<{ }>; -export type DimensionHierarchyQuery = { __typename: 'Query', dataCubeByIri?: Maybe<{ __typename: 'DataCube', dimensionByIri?: Maybe<{ __typename: 'GeoCoordinatesDimension', hierarchy?: Maybe> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> } | { __typename: 'GeoShapesDimension', hierarchy?: Maybe> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> } | { __typename: 'Measure', hierarchy?: Maybe> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> } | { __typename: 'NominalDimension', hierarchy?: Maybe> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> } | { __typename: 'OrdinalDimension', hierarchy?: Maybe> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> } | { __typename: 'TemporalDimension', hierarchy?: Maybe> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> } - & HierarchyValueFieldsFragment - )>> }> }> }; +export type DimensionHierarchyQuery = { __typename: 'Query', dataCubeByIri?: Maybe<{ __typename: 'DataCube', dimensionByIri?: Maybe<( + { __typename: 'GeoCoordinatesDimension' } + & HierarchyMetadata_GeoCoordinatesDimension_Fragment + ) | ( + { __typename: 'GeoShapesDimension' } + & HierarchyMetadata_GeoShapesDimension_Fragment + ) | ( + { __typename: 'Measure' } + & HierarchyMetadata_Measure_Fragment + ) | ( + { __typename: 'NominalDimension' } + & HierarchyMetadata_NominalDimension_Fragment + ) | ( + { __typename: 'OrdinalDimension' } + & HierarchyMetadata_OrdinalDimension_Fragment + ) | ( + { __typename: 'TemporalDimension' } + & HierarchyMetadata_TemporalDimension_Fragment + )> }> }; export type DatasetCountQueryVariables = Exact<{ sourceType: Scalars['String']; @@ -795,8 +834,8 @@ export type DatasetCountQueryVariables = Exact<{ export type DatasetCountQuery = { __typename: 'Query', datasetcount?: Maybe> }; -export const DimensionMetaDataFragmentDoc = gql` - fragment dimensionMetaData on Dimension { +export const DimensionMetadataFragmentDoc = gql` + fragment dimensionMetadata on Dimension { iri label isNumerical @@ -827,6 +866,22 @@ export const HierarchyValueFieldsFragmentDoc = gql` hasValue } `; +export const HierarchyMetadataFragmentDoc = gql` + fragment hierarchyMetadata on Dimension { + hierarchy(sourceType: $sourceType, sourceUrl: $sourceUrl) { + ...hierarchyValueFields + children { + ...hierarchyValueFields + children { + ...hierarchyValueFields + children { + ...hierarchyValueFields + } + } + } + } +} + ${HierarchyValueFieldsFragmentDoc}`; export const DataCubesDocument = gql` query DataCubes($sourceType: String!, $sourceUrl: String!, $locale: String!, $query: String, $order: DataCubeResultOrder, $includeDrafts: Boolean, $filters: [DataCubeSearchFilter!]) { dataCubes( @@ -877,14 +932,14 @@ export const DataCubePreviewDocument = gql` description publicationStatus dimensions(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata } measures(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata } } } - ${DimensionMetaDataFragmentDoc}`; + ${DimensionMetadataFragmentDoc}`; export function useDataCubePreviewQuery(options: Omit, 'query'> = {}) { return Urql.useQuery({ query: DataCubePreviewDocument, ...options }); @@ -970,14 +1025,17 @@ export const DataCubeMetadataWithComponentValuesDocument = gql` } landingPage dimensions(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata + ...hierarchyMetadata } measures(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata + ...hierarchyMetadata } } } - ${DimensionMetaDataFragmentDoc}`; + ${DimensionMetadataFragmentDoc} +${HierarchyMetadataFragmentDoc}`; export function useDataCubeMetadataWithComponentValuesQuery(options: Omit, 'query'> = {}) { return Urql.useQuery({ query: DataCubeMetadataWithComponentValuesDocument, ...options }); @@ -996,11 +1054,11 @@ export const DimensionValuesDocument = gql` sourceType: $sourceType sourceUrl: $sourceUrl ) { - ...dimensionMetaData + ...dimensionMetadata } } } - ${DimensionMetaDataFragmentDoc}`; + ${DimensionMetadataFragmentDoc}`; export function useDimensionValuesQuery(options: Omit, 'query'> = {}) { return Urql.useQuery({ query: DimensionValuesDocument, ...options }); @@ -1075,14 +1133,14 @@ export const TemporalDimensionValuesDocument = gql` sourceUrl: $sourceUrl ) { ... on TemporalDimension { - ...dimensionMetaData + ...dimensionMetadata timeUnit timeFormat } } } } - ${DimensionMetaDataFragmentDoc}`; + ${DimensionMetadataFragmentDoc}`; export function useTemporalDimensionValuesQuery(options: Omit, 'query'> = {}) { return Urql.useQuery({ query: TemporalDimensionValuesDocument, ...options }); @@ -1100,10 +1158,10 @@ export const DataCubeObservationsDocument = gql` title description dimensions(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata } measures(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...dimensionMetaData + ...dimensionMetadata } observations( sourceType: $sourceType @@ -1117,7 +1175,7 @@ export const DataCubeObservationsDocument = gql` } } } - ${DimensionMetaDataFragmentDoc}`; + ${DimensionMetadataFragmentDoc}`; export function useDataCubeObservationsQuery(options: Omit, 'query'> = {}) { return Urql.useQuery({ query: DataCubeObservationsDocument, ...options }); @@ -1194,22 +1252,11 @@ export const DimensionHierarchyDocument = gql` sourceType: $sourceType sourceUrl: $sourceUrl ) { - hierarchy(sourceType: $sourceType, sourceUrl: $sourceUrl) { - ...hierarchyValueFields - children { - ...hierarchyValueFields - children { - ...hierarchyValueFields - children { - ...hierarchyValueFields - } - } - } - } + ...hierarchyMetadata } } } - ${HierarchyValueFieldsFragmentDoc}`; + ${HierarchyMetadataFragmentDoc}`; export function useDimensionHierarchyQuery(options: Omit, 'query'> = {}) { return Urql.useQuery({ query: DimensionHierarchyDocument, ...options }); diff --git a/app/rdf/query-hierarchies.ts b/app/rdf/query-hierarchies.ts index 138cd7fb9..12ea8e280 100644 --- a/app/rdf/query-hierarchies.ts +++ b/app/rdf/query-hierarchies.ts @@ -87,7 +87,7 @@ export const queryHierarchy = async ( locale: string, sparqlClient: ParsingClient, sparqlClientStream: StreamClient -): Promise => { +): Promise => { const source = createSource({ endpointUrl: sourceUrl }); const cubeQuery = SELECT`?cube`.WHERE` @@ -111,7 +111,7 @@ export const queryHierarchy = async ( // @ts-ignore if (!isGraphPointer(hierarchy)) { - throw new Error(`Hierarchy not found ${dimensionIri}`); + return null; } const dimensionValuesProm = queryDimensionValues(dimensionIri, sparqlClient); diff --git a/app/rdf/tree-utils.ts b/app/rdf/tree-utils.ts index 1fcdb09b0..acc046947 100644 --- a/app/rdf/tree-utils.ts +++ b/app/rdf/tree-utils.ts @@ -90,7 +90,7 @@ export const getCheckboxStates = ( return res; }; -const visitTree = ( +export const visitHierarchy = ( tree: HierarchyValue[], cb: (node: HierarchyValue) => void ) => { @@ -147,7 +147,7 @@ export const toggleCheckbox = ( } } - visitTree(children, (child) => { + visitHierarchy(children, (child) => { act( child, (state === "indeterminate" && hasValue) || state === "unchecked" @@ -160,7 +160,7 @@ export const toggleCheckbox = ( const buildIndex = (tree: HierarchyValue[]) => { const index = new Map(); - visitTree(tree, (x) => index.set(x.value, x)); + visitHierarchy(tree, (x) => index.set(x.value, x)); return index; };