diff --git a/app/browser/dataset-preview.tsx b/app/browser/dataset-preview.tsx
index d1f2e53cc..b8466f682 100644
--- a/app/browser/dataset-preview.tsx
+++ b/app/browser/dataset-preview.tsx
@@ -8,7 +8,6 @@ import * as React from "react";
import { DataSetPreviewTable } from "@/browse/datatable";
import { useFootnotesStyles } from "@/components/chart-footnotes";
import { DataDownloadMenu, RunSparqlQuery } from "@/components/data-download";
-import DebugPanel from "@/components/debug-panel";
import Flex from "@/components/flex";
import { HintRed, Loading, LoadingDataError } from "@/components/hint";
import { DataSource } from "@/config-types";
@@ -194,7 +193,6 @@ export const DataSetPreview = ({
-
);
diff --git a/app/charts/index.spec.ts b/app/charts/index.spec.ts
index 2d0e0f1f5..47b385616 100644
--- a/app/charts/index.spec.ts
+++ b/app/charts/index.spec.ts
@@ -15,6 +15,7 @@ describe("initial config", () => {
it("should create an initial table config with column order based on dimension order", () => {
const config = getInitialConfig({
chartType: "table",
+ dataSet: "https://environment.ld.admin.ch/foen/nfi",
dimensions: forestAreaData.data.dataCubeByIri.dimensions as NonNullable<
ComponentsQuery["dataCubeByIri"]
>["dimensions"],
@@ -81,6 +82,7 @@ describe("chart type switch", () => {
key: "column",
version: "1.4.0",
chartType: "column",
+ dataSet: "https://environment.ld.admin.ch/foen/ubd0104",
filters: {},
meta: {
title: {
diff --git a/app/charts/index.ts b/app/charts/index.ts
index 556b34af5..b790c0775 100644
--- a/app/charts/index.ts
+++ b/app/charts/index.ts
@@ -327,6 +327,7 @@ const META: Meta = {
type GetInitialConfigOptions = {
key?: string;
+ dataSet: string;
chartType: ChartType;
dimensions: DataCubeMetadataWithHierarchies["dimensions"];
measures: DataCubeMetadataWithHierarchies["measures"];
@@ -335,16 +336,18 @@ type GetInitialConfigOptions = {
export const getInitialConfig = (
options: GetInitialConfigOptions
): ChartConfig => {
- const { key, chartType, dimensions, measures } = options;
+ const { key, dataSet, chartType, dimensions, measures } = options;
const genericConfigProps: {
key: string;
version: string;
meta: Meta;
+ dataSet: string;
activeField: string | undefined;
} = {
key: key ?? createChartId(),
version: CHART_CONFIG_VERSION,
meta: META,
+ dataSet,
activeField: undefined,
};
const numericalMeasures = measures.filter(isNumericalMeasure);
@@ -667,6 +670,7 @@ export const getChartConfigAdjustedToChartType = ({
const initialConfig = getInitialConfig({
key: chartConfig.key,
chartType: newChartType,
+ dataSet: chartConfig.dataSet,
dimensions,
measures,
});
diff --git a/app/charts/shared/legend-color.tsx b/app/charts/shared/legend-color.tsx
index 1659fb76a..87da7d3d9 100644
--- a/app/charts/shared/legend-color.tsx
+++ b/app/charts/shared/legend-color.tsx
@@ -171,9 +171,9 @@ const useLegendGroups = ({
const segmentValues =
segmentFilters?.type === "multi" ? segmentFilters.values : emptyObj;
- const { dataSet: dataset, dataSource } = configState;
+ const { dataSource } = configState;
const segmentDimension = useDimension({
- dataset,
+ dataset: chartConfig.dataSet,
dataSource,
locale,
dimensionIri: segmentField?.componentIri,
@@ -181,7 +181,7 @@ const useLegendGroups = ({
const [hierarchyResp] = useDimensionValuesQuery({
variables: {
- dataCubeIri: dataset,
+ dataCubeIri: chartConfig.dataSet,
dimensionIri: segmentDimension?.iri!,
sourceType: dataSource.type,
sourceUrl: dataSource.url,
diff --git a/app/charts/shared/use-sync-interactive-filters.spec.tsx b/app/charts/shared/use-sync-interactive-filters.spec.tsx
index 5c4b364c7..0d4fe1812 100644
--- a/app/charts/shared/use-sync-interactive-filters.spec.tsx
+++ b/app/charts/shared/use-sync-interactive-filters.spec.tsx
@@ -45,6 +45,7 @@ const chartConfig = migrateChartConfig(
{
migrationProps: {
meta: {},
+ dataSet: "foo",
},
}
) as ChartConfig;
diff --git a/app/components/chart-published.tsx b/app/components/chart-published.tsx
index c448d27ab..264a4eada 100644
--- a/app/components/chart-published.tsx
+++ b/app/components/chart-published.tsx
@@ -51,13 +51,12 @@ type ChartPublishedProps = {
export const ChartPublished = (props: ChartPublishedProps) => {
const { configKey } = props;
const [state] = useConfiguratorState(isPublished);
- const { dataSet, dataSource } = state;
+ const { dataSource } = state;
const chartConfig = getChartConfig(state);
return (
((theme) => ({
}));
type ChartPublishInnerProps = {
- dataSet: string;
dataSource: DataSource | undefined;
state: ConfiguratorStatePublished;
chartConfig: ChartConfig;
@@ -92,7 +90,6 @@ type ChartPublishInnerProps = {
const ChartPublishedInner = (props: ChartPublishInnerProps) => {
const {
- dataSet,
dataSource = DEFAULT_DATA_SOURCE,
state,
chartConfig,
@@ -136,7 +133,7 @@ const ChartPublishedInner = (props: ChartPublishInnerProps) => {
const locale = useLocale();
const isTrustedDataSource = useIsTrustedDataSource(dataSource);
const commonQueryVariables = {
- iri: dataSet,
+ iri: chartConfig.dataSet,
sourceType: dataSource.type,
sourceUrl: dataSource.url,
locale,
@@ -225,7 +222,7 @@ const ChartPublishedInner = (props: ChartPublishInnerProps) => {
{
{isTablePreview ? (
) : (
{
)}
{
const PublishChartButton = () => {
const locale = useLocale();
const [state, dispatch] = useConfiguratorState(hasChartConfigs);
- const { dataSet } = state;
+ const chartConfig = getChartConfig(state);
const variables = {
- iri: dataSet ?? "",
+ iri: chartConfig.dataSet,
sourceType: state.dataSource.type,
sourceUrl: state.dataSource.url,
locale,
};
- const [{ data: metadata }] = useDataCubeMetadataQuery({
- variables,
- pause: !dataSet,
- });
- const [{ data: components }] = useComponentsQuery({
- variables,
- pause: !dataSet,
- });
+ const [{ data: metadata }] = useDataCubeMetadataQuery({ variables });
+ const [{ data: components }] = useComponentsQuery({ variables });
const goNext = useEvent(() => {
if (metadata?.dataCubeByIri && components?.dataCubeByIri) {
dispatch({
diff --git a/app/components/debug-panel/DebugPanel.tsx b/app/components/debug-panel/DebugPanel.tsx
index f3b010e0c..f87bcf9f7 100644
--- a/app/components/debug-panel/DebugPanel.tsx
+++ b/app/components/debug-panel/DebugPanel.tsx
@@ -12,7 +12,11 @@ import {
import { useState } from "react";
import { Inspector } from "react-inspector";
-import { DataSource, useConfiguratorState } from "@/configurator";
+import {
+ DataSource,
+ getChartConfig,
+ useConfiguratorState,
+} from "@/configurator";
import { dataSourceToSparqlEditorUrl } from "@/domain/datasource";
import { useComponentsWithHierarchiesQuery } from "@/graphql/query-hooks";
import { Icon } from "@/icons";
@@ -86,6 +90,7 @@ const CubeMetadata = ({
const DebugConfigurator = () => {
const [configuratorState] = useConfiguratorState();
+ const chartConfig = getChartConfig(configuratorState);
const sparqlEditorUrl = dataSourceToSparqlEditorUrl(
configuratorState.dataSource
);
@@ -96,51 +101,43 @@ const DebugConfigurator = () => {
Cube Tools
- {configuratorState.dataSet ? (
- }
- >
- Open in Cube Viewer
-
- ) : (
- Please select a dataset first
- )}
- {
- }
+ >
+ Open in Cube Viewer
+
+
- }
- {configuratorState.dataSet ? (
-
- ) : null}
+DESCRIBE <${chartConfig.dataSet}>`
+ )}&requestMethod=POST`}
+ target="_blank"
+ rel="noopener noreferrer"
+ startIcon={}
+ >
+ Cube Metadata Query
+
+
;
const Config = t.type(
{
version: t.string,
- dataSet: t.string,
dataSource: DataSource,
meta: Meta,
chartConfigs: t.array(ChartConfig),
@@ -1097,7 +1097,6 @@ export const decodeConfig = (config: unknown) => {
const ConfiguratorStateInitial = t.type({
version: t.string,
state: t.literal("INITIAL"),
- dataSet: t.undefined,
dataSource: DataSource,
});
export type ConfiguratorStateInitial = t.TypeOf<
@@ -1107,7 +1106,6 @@ export type ConfiguratorStateInitial = t.TypeOf<
const ConfiguratorStateSelectingDataSet = t.type({
version: t.string,
state: t.literal("SELECTING_DATASET"),
- dataSet: t.union([t.string, t.undefined]),
dataSource: DataSource,
meta: Meta,
chartConfigs: t.undefined,
diff --git a/app/configurator/components/chart-configurator.tsx b/app/configurator/components/chart-configurator.tsx
index 74f753e27..6e576a39a 100644
--- a/app/configurator/components/chart-configurator.tsx
+++ b/app/configurator/components/chart-configurator.tsx
@@ -190,7 +190,7 @@ const useEnsurePossibleFilters = ({
.query(
PossibleFiltersDocument,
{
- iri: state.dataSet,
+ iri: chartConfig.dataSet,
sourceType: state.dataSource.type,
sourceUrl: state.dataSource.url,
filters: unmappedFilters,
@@ -234,7 +234,7 @@ const useEnsurePossibleFilters = ({
client,
dispatch,
chartConfig,
- state.dataSet,
+ chartConfig.dataSet,
state.dataSource.type,
state.dataSource.url,
]);
@@ -263,7 +263,7 @@ const useFilterReorder = ({
const variables = useMemo(() => {
const hasUnmappedFilters = Object.keys(unmappedFilters).length > 0;
const vars = {
- iri: state.dataSet,
+ iri: chartConfig.dataSet,
sourceType: state.dataSource.type,
sourceUrl: state.dataSource.url,
locale,
@@ -279,7 +279,7 @@ const useFilterReorder = ({
return omitBy(vars, (x) => x === undefined) as typeof vars;
}, [
- state.dataSet,
+ chartConfig.dataSet,
state.dataSource.type,
state.dataSource.url,
locale,
diff --git a/app/configurator/components/chart-options-selector.tsx b/app/configurator/components/chart-options-selector.tsx
index bc19333bd..fc1b6955e 100644
--- a/app/configurator/components/chart-options-selector.tsx
+++ b/app/configurator/components/chart-options-selector.tsx
@@ -93,31 +93,24 @@ export const ChartOptionsSelector = ({
state: ConfiguratorStateConfiguringChart;
}) => {
const chartConfig = getChartConfig(state);
- const { dataSet, dataSource } = state;
+ const { dataSource } = state;
const { activeField } = chartConfig;
const locale = useLocale();
+ const commonVariables = {
+ iri: chartConfig.dataSet,
+ sourceType: dataSource.type,
+ sourceUrl: dataSource.url,
+ locale,
+ };
const [{ data: metadataData }] = useDataCubeMetadataQuery({
- variables: {
- iri: dataSet,
- sourceType: dataSource.type,
- sourceUrl: dataSource.url,
- locale,
- },
+ variables: commonVariables,
});
const [{ data: componentsData }] = useComponentsWithHierarchiesQuery({
- variables: {
- iri: dataSet,
- sourceType: dataSource.type,
- sourceUrl: dataSource.url,
- locale,
- },
+ variables: commonVariables,
});
const [{ data: observationsData }] = useDataCubeObservationsQuery({
variables: {
- iri: dataSet,
- sourceType: dataSource.type,
- sourceUrl: dataSource.url,
- locale,
+ ...commonVariables,
filters: chartConfig.filters,
},
});
@@ -146,7 +139,6 @@ export const ChartOptionsSelector = ({
) : (
{
- const { state, metadata, chartConfig, observations } = props;
+ const { metadata, chartConfig, observations } = props;
const { dimensions, measures } = metadata;
const activeField = chartConfig.activeField as EncodingFieldType | undefined;
@@ -204,7 +195,6 @@ const ActiveFieldSwitch = (props: ActiveFieldSwitchProps) => {
return (
{
type EncodingOptionsPanelProps = {
encoding: EncodingSpec;
- state: ConfiguratorStateConfiguringChart;
chartConfig: ChartConfig;
field: EncodingFieldType;
component: DimensionMetadataFragment | undefined;
@@ -229,7 +218,6 @@ type EncodingOptionsPanelProps = {
const EncodingOptionsPanel = (props: EncodingOptionsPanelProps) => {
const {
encoding,
- state,
field,
chartConfig,
component,
@@ -409,7 +397,6 @@ const EncodingOptionsPanel = (props: EncodingOptionsPanelProps) => {
{encoding.options?.colorComponent && component && (
{
)}
{
};
const ChartFieldMultiFilter = ({
- state,
chartConfig,
component,
encoding,
@@ -1203,7 +1188,6 @@ const ChartFieldMultiFilter = ({
dimensions,
measures,
}: {
- state: ConfiguratorStateConfiguringChart;
chartConfig: ChartConfig;
component: DimensionMetadataFragment | undefined;
encoding: EncodingSpec;
@@ -1246,7 +1230,7 @@ const ChartFieldMultiFilter = ({
{
const {
- state,
chartConfig,
encoding,
component,
@@ -1660,7 +1642,7 @@ const ChartFieldColorComponent = (props: ChartFieldColorComponentProps) => {
colorComponentIri && component.iri !== colorComponentIri ? (
{
const locale = useLocale();
+ const chartConfig = getChartConfig(state);
const [{ data }] = useComponentsWithHierarchiesQuery({
variables: {
- iri: state.dataSet,
+ iri: chartConfig.dataSet,
sourceType: state.dataSource.type,
sourceUrl: state.dataSource.url,
locale,
diff --git a/app/configurator/components/configurator.tsx b/app/configurator/components/configurator.tsx
index efd0ed4c0..935eed748 100644
--- a/app/configurator/components/configurator.tsx
+++ b/app/configurator/components/configurator.tsx
@@ -70,6 +70,7 @@ const isAnnotationField = (field: string | undefined) => {
const ConfigureChartStep = () => {
const [state, dispatch] = useConfiguratorState();
+ const chartConfig = getChartConfig(state);
const { dataSource, setDataSource } = useDataSourceStore();
const handleClosePanel = useEvent(() => {
@@ -85,11 +86,12 @@ const ConfigureChartStep = () => {
if (state.state !== "CONFIGURING_CHART") {
return;
}
+
router.push(
{
pathname: `/browse`,
query: {
- dataset: state.dataSet,
+ dataset: chartConfig.dataSet,
},
},
undefined,
@@ -110,8 +112,6 @@ const ConfigureChartStep = () => {
return null;
}
- const chartConfig = getChartConfig(state);
-
return (
{
@@ -173,6 +173,7 @@ const ConfigureChartStep = () => {
const PublishStep = () => {
const [state] = useConfiguratorState();
+ const chartConfig = getChartConfig(state);
if (state.state !== "PUBLISHING") {
return null;
@@ -183,7 +184,7 @@ const PublishStep = () => {
diff --git a/app/configurator/config-form.tsx b/app/configurator/config-form.tsx
index fabdcfdab..5be4a01d3 100644
--- a/app/configurator/config-form.tsx
+++ b/app/configurator/config-form.tsx
@@ -95,6 +95,7 @@ export const useChartFieldField = ({
const unmountedRef = useRef(false);
const [fetching, setFetching] = useState(false);
const [state, dispatch] = useConfiguratorState();
+ const chartConfig = getChartConfig(state);
const client = useClient();
const locale = useLocale();
@@ -105,10 +106,6 @@ export const useChartFieldField = ({
}, []);
const handleChange = useEvent(async (e: SelectChangeEvent) => {
- if (!state.dataSet) {
- return;
- }
-
if (e.target.value !== FIELD_VALUE_NONE) {
setFetching(true);
const dimensionIri = e.target.value as string;
@@ -117,7 +114,7 @@ export const useChartFieldField = ({
DimensionHierarchyDocument,
{
locale,
- cubeIri: state.dataSet,
+ cubeIri: chartConfig.dataSet,
dimensionIri,
sourceUrl: state.dataSource.url,
sourceType: state.dataSource.type,
@@ -435,6 +432,10 @@ export const useChartType = (
value: {
chartConfig: getInitialConfig({
chartType,
+ dataSet:
+ state.state === "CONFIGURING_CHART"
+ ? getChartConfig(state, state.activeChartKey).dataSet
+ : chartConfig.dataSet,
dimensions,
measures,
}),
diff --git a/app/configurator/configurator-state.tsx b/app/configurator/configurator-state.tsx
index 7bf66cb1e..6a58b9c99 100644
--- a/app/configurator/configurator-state.tsx
+++ b/app/configurator/configurator-state.tsx
@@ -108,10 +108,6 @@ export type ConfiguratorStateAction =
"INITIAL" | "PUBLISHING" | "PUBLISHED"
>;
}
- | {
- type: "DATASET_SELECTED";
- dataSet: string | undefined;
- }
| {
type: "DATASOURCE_CHANGED";
value: DataSource;
@@ -329,14 +325,13 @@ const getStateWithCurrentDataSource = (state: ConfiguratorState) => {
return {
...state,
- dataSource: dataSource || DEFAULT_DATA_SOURCE,
+ dataSource: dataSource ?? DEFAULT_DATA_SOURCE,
};
};
const INITIAL_STATE: ConfiguratorState = {
version: CONFIGURATOR_STATE_VERSION,
state: "INITIAL",
- dataSet: undefined,
dataSource: DEFAULT_DATA_SOURCE,
};
@@ -344,7 +339,6 @@ const EMPTY_STATE: ConfiguratorStateSelectingDataSet = {
...INITIAL_STATE,
version: CONFIGURATOR_STATE_VERSION,
state: "SELECTING_DATASET",
- dataSet: undefined,
dataSource: DEFAULT_DATA_SOURCE,
chartConfigs: undefined,
meta: {
@@ -366,10 +360,11 @@ const EMPTY_STATE: ConfiguratorStateSelectingDataSet = {
const getCachedMetadata = (
draft: ConfiguratorStateConfiguringChart,
+ dataSet: string,
locale: Locale
): DataCubeMetadataWithHierarchies | null => {
const variables = {
- iri: draft.dataSet,
+ iri: dataSet,
locale,
sourceType: draft.dataSource.type,
sourceUrl: draft.dataSource.url,
@@ -610,11 +605,16 @@ export const applyNonTableDimensionToFilters = ({
const transitionStepNext = (
draft: ConfiguratorState,
- dataSetMetadata: DataCubeMetadataWithHierarchies
+ options: {
+ dataSet?: string;
+ dataSetMetadata: DataCubeMetadataWithHierarchies;
+ }
): ConfiguratorState => {
+ const { dataSet, dataSetMetadata } = options;
+
switch (draft.state) {
case "SELECTING_DATASET":
- if (draft.dataSet) {
+ if (dataSet) {
const possibleChartTypes = getPossibleChartTypes({
dimensions: dataSetMetadata.dimensions,
measures: dataSetMetadata.measures,
@@ -622,6 +622,7 @@ const transitionStepNext = (
const chartConfig = deriveFiltersFromFields(
getInitialConfig({
chartType: possibleChartTypes[0],
+ dataSet,
dimensions: dataSetMetadata.dimensions,
measures: dataSetMetadata.measures,
}),
@@ -631,7 +632,6 @@ const transitionStepNext = (
return {
version: CONFIGURATOR_STATE_VERSION,
state: "CONFIGURING_CHART",
- dataSet: draft.dataSet,
dataSource: draft.dataSource,
meta: draft.meta,
chartConfigs: [chartConfig],
@@ -773,7 +773,7 @@ export const handleChartFieldChanged = (
} = action.value;
const f = get(chartConfig.fields, field);
const { dimensions = [], measures = [] } =
- getCachedMetadata(draft, locale) ?? {};
+ getCachedMetadata(draft, chartConfig.dataSet, locale) ?? {};
const components = [...dimensions, ...measures];
const component = components.find((d) => d.iri === componentIri);
const selectedValues = actionSelectedValues ?? component?.values ?? [];
@@ -822,7 +822,7 @@ export const handleChartOptionChanged = (
const chartConfig = getChartConfig(draft);
const updatePath = field === null ? path : `fields["${field}"].${path}`;
const { dimensions = [], measures = [] } =
- getCachedMetadata(draft, locale) ?? {};
+ getCachedMetadata(draft, chartConfig.dataSet, locale) ?? {};
if (field) {
const sideEffect = getChartFieldOptionChangeSideEffect(
@@ -920,11 +920,6 @@ const reducer: Reducer = (
return action.value.state === "INITIAL"
? getStateWithCurrentDataSource(EMPTY_STATE)
: action.value;
- case "DATASET_SELECTED":
- if (draft.state === "SELECTING_DATASET") {
- draft.dataSet = action.dataSet;
- }
- return draft;
case "DATASOURCE_CHANGED":
draft.dataSource = action.value;
@@ -933,11 +928,11 @@ const reducer: Reducer = (
case "CHART_TYPE_CHANGED":
if (draft.state === "CONFIGURING_CHART") {
const { locale, chartKey, chartType } = action.value;
- const metadata = getCachedMetadata(draft, locale);
+ const chartConfig = getChartConfig(draft, chartKey);
+ const metadata = getCachedMetadata(draft, chartConfig.dataSet, locale);
if (metadata) {
const { dimensions, measures } = metadata;
- const chartConfig = getChartConfig(draft, chartKey);
const newConfig = deriveFiltersFromFields(
getChartConfigAdjustedToChartType({
chartConfig: current(chartConfig),
@@ -972,10 +967,12 @@ const reducer: Reducer = (
if (draft.state === "CONFIGURING_CHART") {
const chartConfig = getChartConfig(draft);
delete (chartConfig.fields as GenericFields)[action.value.field];
-
- const metadata = getCachedMetadata(draft, action.value.locale);
+ const metadata = getCachedMetadata(
+ draft,
+ chartConfig.dataSet,
+ action.value.locale
+ );
const dimensions = metadata?.dimensions ?? [];
-
deriveFiltersFromFields(chartConfig, dimensions);
if (
@@ -1243,7 +1240,9 @@ const reducer: Reducer = (
// State transitions
case "STEP_NEXT":
- return transitionStepNext(draft, action.dataSetMetadata);
+ return transitionStepNext(draft, {
+ dataSetMetadata: action.dataSetMetadata,
+ });
case "STEP_PREVIOUS":
return transitionStepPrevious(draft, action.to);
@@ -1260,7 +1259,12 @@ const reducer: Reducer = (
case "CHART_CONFIG_ADD":
if (draft.state === "CONFIGURING_CHART") {
- const metadata = getCachedMetadata(draft, action.value.locale);
+ const chartConfig = getChartConfig(draft);
+ const metadata = getCachedMetadata(
+ draft,
+ chartConfig.dataSet,
+ action.value.locale
+ );
if (metadata) {
draft.chartConfigs.push(
@@ -1374,10 +1378,13 @@ export const initChartStateFromCube = async (
.toPromise();
if (metadata?.dataCubeByIri && components?.dataCubeByIri) {
- return transitionStepNext(
- getStateWithCurrentDataSource({ ...EMPTY_STATE, dataSet: datasetIri }),
- { ...metadata.dataCubeByIri, ...components.dataCubeByIri }
- );
+ return transitionStepNext(getStateWithCurrentDataSource(EMPTY_STATE), {
+ dataSetMetadata: {
+ ...metadata.dataCubeByIri,
+ ...components.dataCubeByIri,
+ },
+ dataSet: datasetIri,
+ });
}
console.warn(`Could not fetch cube with iri ${datasetIri}`);
@@ -1391,27 +1398,30 @@ export const initChartStateFromLocalStorage = async (
chartId: string
): Promise => {
const storedState = window.localStorage.getItem(getLocalStorageKey(chartId));
- if (storedState) {
- let parsedState;
- try {
- const rawParsedState = JSON.parse(storedState);
- const migratedState = migrateConfiguratorState(rawParsedState);
- parsedState = decodeConfiguratorState(migratedState);
- } catch (e) {
- console.error("Error while parsing stored state", e);
- // Ignore errors since we are returning undefined and removing bad state from localStorage
- }
- if (parsedState) {
- return parsedState;
- }
+ if (!storedState) {
+ return;
+ }
- console.warn(
- "Attempted to restore invalid state. Removing from localStorage.",
- parsedState
- );
- window.localStorage.removeItem(getLocalStorageKey(chartId));
+ let parsedState;
+ try {
+ const rawParsedState = JSON.parse(storedState);
+ const migratedState = migrateConfiguratorState(rawParsedState);
+ parsedState = decodeConfiguratorState(migratedState);
+ } catch (e) {
+ console.error("Error while parsing stored state", e);
+ // Ignore errors since we are returning undefined and removing bad state from localStorage
+ }
+
+ if (parsedState) {
+ return parsedState;
}
+
+ console.warn(
+ "Attempted to restore invalid state. Removing from localStorage.",
+ parsedState
+ );
+ window.localStorage.removeItem(getLocalStorageKey(chartId));
};
const ConfiguratorStateProviderInternal = (
diff --git a/app/configurator/interactive-filters/interactive-filters-configurator.tsx b/app/configurator/interactive-filters/interactive-filters-configurator.tsx
index 9a7a77159..02e17e89e 100644
--- a/app/configurator/interactive-filters/interactive-filters-configurator.tsx
+++ b/app/configurator/interactive-filters/interactive-filters-configurator.tsx
@@ -31,13 +31,13 @@ export const InteractiveFiltersConfigurator = ({
}: {
state: ConfiguratorStateConfiguringChart;
}) => {
- const { dataSet, dataSource } = state;
+ const { dataSource } = state;
const chartConfig = getChartConfig(state);
const { fields } = chartConfig;
const locale = useLocale();
const [{ data }] = useComponentsQuery({
variables: {
- iri: dataSet,
+ iri: chartConfig.dataSet,
sourceType: dataSource.type,
sourceUrl: dataSource.url,
locale,
diff --git a/app/configurator/table/table-chart-configurator.tsx b/app/configurator/table/table-chart-configurator.tsx
index 9679f67a6..5cca10704 100644
--- a/app/configurator/table/table-chart-configurator.tsx
+++ b/app/configurator/table/table-chart-configurator.tsx
@@ -63,21 +63,17 @@ export const ChartConfiguratorTable = ({
state: ConfiguratorStateConfiguringChart;
}) => {
const locale = useLocale();
- const [{ data: metadata }] = useDataCubeMetadataQuery({
- variables: {
- iri: state.dataSet,
- sourceType: state.dataSource.type,
- sourceUrl: state.dataSource.url,
- locale,
- },
- });
+ const [, dispatch] = useConfiguratorState(isConfiguring);
+ const chartConfig = getChartConfig(state);
+ const variables = {
+ iri: chartConfig.dataSet,
+ sourceType: state.dataSource.type,
+ sourceUrl: state.dataSource.url,
+ locale,
+ };
+ const [{ data: metadata }] = useDataCubeMetadataQuery({ variables });
const [{ data: components }] = useComponentsWithHierarchiesQuery({
- variables: {
- iri: state.dataSet,
- sourceType: state.dataSource.type,
- sourceUrl: state.dataSource.url,
- locale,
- },
+ variables,
});
const metaData = useMemo(() => {
@@ -89,9 +85,6 @@ export const ChartConfiguratorTable = ({
: null;
}, [metadata?.dataCubeByIri, components?.dataCubeByIri]);
- const [, dispatch] = useConfiguratorState(isConfiguring);
- const chartConfig = getChartConfig(state);
-
const [currentDraggableId, setCurrentDraggableId] = useState(
null
);
diff --git a/app/db/config.ts b/app/db/config.ts
index 659619c47..9eb140c03 100644
--- a/app/db/config.ts
+++ b/app/db/config.ts
@@ -120,8 +120,9 @@ const parseDbConfig = (
...d,
data: {
...migratedData,
- dataSet: migrateDataSet(migratedData.dataSet),
- chartConfigs: migratedData.chartConfigs.map(ensureFiltersOrder),
+ chartConfigs: migratedData.chartConfigs
+ .map(ensureFiltersOrder)
+ .map((d: any) => ({ ...d, dataSet: migrateDataSet(d.dataSet) })),
},
};
};
diff --git a/app/docs/annotations.docs.tsx b/app/docs/annotations.docs.tsx
index 326cca3b2..cdc10cc1e 100644
--- a/app/docs/annotations.docs.tsx
+++ b/app/docs/annotations.docs.tsx
@@ -57,6 +57,7 @@ ${(
it: "",
},
},
+ dataSet: "",
chartType: "column",
fields,
interactiveFiltersConfig: {
@@ -221,6 +222,7 @@ ${(
it: "",
},
},
+ dataSet: "",
chartType: "column",
fields,
interactiveFiltersConfig: {
@@ -284,6 +286,7 @@ ${(
it: "",
},
},
+ dataSet: "",
chartType: "column",
fields,
interactiveFiltersConfig: {
diff --git a/app/docs/columns.docs.tsx b/app/docs/columns.docs.tsx
index 3f68e83ed..31cf05aa0 100644
--- a/app/docs/columns.docs.tsx
+++ b/app/docs/columns.docs.tsx
@@ -32,7 +32,6 @@ ${(
description: { en: "", de: "", fr: "", it: "" },
},
dataSource: { type: "sparql", url: "" },
- dataSet: "",
chartConfigs: [chartConfig],
activeChartKey: "scatterplot",
}}
@@ -94,6 +93,7 @@ const chartConfig: ColumnConfig = {
it: "",
},
},
+ dataSet: "",
filters: {},
fields: columnFields,
interactiveFiltersConfig: {
diff --git a/app/docs/fixtures.ts b/app/docs/fixtures.ts
index bd7e1108d..91772956b 100644
--- a/app/docs/fixtures.ts
+++ b/app/docs/fixtures.ts
@@ -8,7 +8,6 @@ export const states: ConfiguratorState[] = [
{
state: "SELECTING_DATASET",
version: CONFIGURATOR_STATE_VERSION,
- dataSet: undefined,
dataSource: DEFAULT_DATA_SOURCE,
chartConfigs: undefined,
meta: {
@@ -30,7 +29,6 @@ export const states: ConfiguratorState[] = [
{
state: "CONFIGURING_CHART",
version: CONFIGURATOR_STATE_VERSION,
- dataSet: "foo",
dataSource: DEFAULT_DATA_SOURCE,
chartConfigs: [
{
@@ -50,6 +48,7 @@ export const states: ConfiguratorState[] = [
it: "",
},
},
+ dataSet: "",
chartType: "column",
fields: {
x: {
@@ -827,6 +826,7 @@ export const tableConfig: TableConfig = {
it: "",
},
},
+ dataSet: "",
chartType: "table",
filters: {},
interactiveFiltersConfig: undefined,
diff --git a/app/docs/lines.docs.tsx b/app/docs/lines.docs.tsx
index 7576e541e..b13b58832 100644
--- a/app/docs/lines.docs.tsx
+++ b/app/docs/lines.docs.tsx
@@ -34,7 +34,6 @@ ${(
description: { en: "", de: "", fr: "", it: "" },
},
dataSource: { type: "sparql", url: "" },
- dataSet: "",
chartConfigs: [chartConfig],
activeChartKey: "line",
}}
@@ -144,6 +143,7 @@ const chartConfig: LineConfig = {
it: "",
},
},
+ dataSet: "",
chartType: "line",
interactiveFiltersConfig,
fields,
diff --git a/app/docs/scatterplot.docs.tsx b/app/docs/scatterplot.docs.tsx
index 5d20eac58..8fb2fa41f 100644
--- a/app/docs/scatterplot.docs.tsx
+++ b/app/docs/scatterplot.docs.tsx
@@ -37,7 +37,6 @@ ${(
description: { en: "", de: "", fr: "", it: "" },
},
dataSource: { type: "sparql", url: "" },
- dataSet: "",
chartConfigs: [chartConfig],
activeChartKey: "scatterplot",
}}
@@ -145,6 +144,7 @@ const chartConfig: ScatterPlotConfig = {
it: "",
},
},
+ dataSet: "",
chartType: "scatterplot",
filters: {},
interactiveFiltersConfig,
diff --git a/app/login/components/profile-tables.tsx b/app/login/components/profile-tables.tsx
index 1caa295ec..315b43066 100644
--- a/app/login/components/profile-tables.tsx
+++ b/app/login/components/profile-tables.tsx
@@ -166,16 +166,26 @@ type ProfileVisualizationsRowProps = {
const ProfileVisualizationsRow = (props: ProfileVisualizationsRowProps) => {
const { userId, config, onRemoveSuccess } = props;
- const { dataSet, dataSource } = config.data;
+ const { dataSource } = config.data;
+ const dataSets = Array.from(
+ new Set(config.data.chartConfigs.map((d) => d.dataSet))
+ );
+ const dataSet = dataSets.length === 1 ? dataSets[0] : null;
const locale = useLocale();
- const [{ data, fetching }] = useDataCubeMetadataQuery({
- variables: {
- iri: dataSet,
- sourceType: dataSource.type,
- sourceUrl: dataSource.url,
- locale,
- },
- });
+ const [{ data, fetching }] = useDataCubeMetadataQuery(
+ dataSet
+ ? {
+ variables: {
+ iri: dataSet,
+ sourceType: dataSource.type,
+ sourceUrl: dataSource.url,
+ locale,
+ },
+ }
+ : {
+ pause: true,
+ }
+ );
const actions = React.useMemo(() => {
const actions: ActionProps[] = [
{
@@ -260,11 +270,11 @@ const ProfileVisualizationsRow = (props: ProfileVisualizationsRowProps) => {
{fetching ? (
- ) : (
+ ) : dataSet ? (
@@ -274,6 +284,13 @@ const ProfileVisualizationsRow = (props: ProfileVisualizationsRowProps) => {
+ ) : (
+
+ {t({
+ id: "login.profile.my-visualizations.multiple-datasets",
+ message: "Multiple datasets",
+ })}
+
)}
diff --git a/app/utils/chart-config/api.ts b/app/utils/chart-config/api.ts
index cd15ded75..e39072be9 100644
--- a/app/utils/chart-config/api.ts
+++ b/app/utils/chart-config/api.ts
@@ -19,7 +19,6 @@ export const createConfig = async (state: ConfiguratorStatePublishing) => {
// used by a chart that has been published.
key: createChartId(),
version: state.version,
- dataSet: state.dataSet,
dataSource: state.dataSource,
meta: state.meta,
chartConfigs: state.chartConfigs,
@@ -51,7 +50,6 @@ export const updateConfig = async (
data: {
key,
version: state.version,
- dataSet: state.dataSet,
dataSource: state.dataSource,
meta: state.meta,
chartConfigs: state.chartConfigs,
diff --git a/app/utils/chart-config/versioning.spec.ts b/app/utils/chart-config/versioning.spec.ts
index f26cebba2..2fb16b846 100644
--- a/app/utils/chart-config/versioning.spec.ts
+++ b/app/utils/chart-config/versioning.spec.ts
@@ -22,6 +22,7 @@ const CONFIGURATOR_STATE = {
en: "",
},
},
+ dataSet: "foo",
} as unknown as ConfiguratorStateConfiguringChart;
describe("config migrations", () => {
diff --git a/app/utils/chart-config/versioning.ts b/app/utils/chart-config/versioning.ts
index 64d0257ad..dfb116b19 100644
--- a/app/utils/chart-config/versioning.ts
+++ b/app/utils/chart-config/versioning.ts
@@ -12,7 +12,7 @@ type Migration = {
down: (config: any, migrationProps?: any) => any;
};
-export const CHART_CONFIG_VERSION = "2.2.0";
+export const CHART_CONFIG_VERSION = "2.3.0";
const chartConfigMigrations: Migration[] = [
{
@@ -287,12 +287,15 @@ const chartConfigMigrations: Migration[] = [
...(colorScaleType === "discrete"
? {
scaleType: colorScaleType,
- interpolationType: colorScaleInterpolationType,
+ interpolationType:
+ colorScaleInterpolationType === "linear"
+ ? "quantize"
+ : colorScaleInterpolationType,
nbClass,
}
: {
scaleType: colorScaleType,
- interpolationType: colorScaleInterpolationType,
+ interpolationType: "linear",
}),
},
};
@@ -750,20 +753,42 @@ const chartConfigMigrations: Migration[] = [
});
},
},
+ {
+ description: `ALL {
+ + dataSet
+ }`,
+ from: "2.2.0",
+ to: "2.3.0",
+ up: (config, configuratorState) => {
+ const newConfig = { ...config, version: "2.3.0" };
+ const { dataSet } = configuratorState;
+
+ return produce(newConfig, (draft: any) => {
+ draft.dataSet = dataSet;
+ });
+ },
+ down: (config) => {
+ const newConfig = { ...config, version: "2.2.0" };
+
+ return produce(newConfig, (draft: any) => {
+ delete draft.dataSet;
+ });
+ },
+ },
];
export const migrateChartConfig = makeMigrate(chartConfigMigrations, {
defaultToVersion: CHART_CONFIG_VERSION,
});
-export const CONFIGURATOR_STATE_VERSION = "2.0.0";
+export const CONFIGURATOR_STATE_VERSION = "3.0.0";
const configuratorStateMigrations: Migration[] = [
{
- description: `ALL`,
+ description: "ALL",
from: "1.0.0",
to: "2.0.0",
- up: (config: any) => {
+ up: (config) => {
const newConfig = { ...config, version: "2.0.0" };
return produce(newConfig, (draft: any) => {
@@ -793,6 +818,58 @@ const configuratorStateMigrations: Migration[] = [
});
},
},
+ {
+ description: "ALL",
+ from: "2.0.0",
+ to: "3.0.0",
+ up: (config) => {
+ const newConfig = { ...config, version: "3.0.0" };
+
+ return produce(newConfig, (draft: any) => {
+ const chartConfigs: any[] = [];
+
+ for (const chartConfig of draft.chartConfigs) {
+ const migratedChartConfig = migrateChartConfig(chartConfig, {
+ migrationProps: draft,
+ toVersion: "2.3.0",
+ });
+ chartConfigs.push(migratedChartConfig);
+ }
+
+ delete draft.dataSet;
+ draft.chartConfigs = chartConfigs;
+ });
+ },
+ down: (config) => {
+ const newConfig = { ...config, version: "2.0.0" };
+
+ return produce(newConfig, (draft: any) => {
+ let dataSet: string | undefined;
+ const chartConfigs: any[] = [];
+
+ for (const chartConfig of draft.chartConfigs) {
+ if (!dataSet) {
+ dataSet = chartConfig.dataSet;
+ }
+
+ // Only migrate chartConfigs with the same dataSet as configuratorState.
+ if (chartConfig.dataSet === dataSet) {
+ const migratedChartConfig = migrateChartConfig(chartConfig, {
+ migrationProps: draft,
+ toVersion: "2.2.0",
+ });
+ chartConfigs.push(migratedChartConfig);
+ } else {
+ console.warn(
+ "Cannot migrate chartConfig dataSet to configuratorState dataSet because they are not the same."
+ );
+ }
+ }
+
+ draft.dataSet = dataSet;
+ });
+ },
+ },
];
export const migrateConfiguratorState = makeMigrate(