Skip to content

Commit

Permalink
Release 8.0.1 (#190)
Browse files Browse the repository at this point in the history
## What's changed

* fix: cypress tests (#159)
* fix: vis is rendered with an invalid config
(#172)
* feat: add POSTGRES_PORT to get_default_postgres_url
(#181)
* chore(deps): bump cachetools from 5.3.1 to 5.3.2
(#147)
  • Loading branch information
puehringer authored Feb 21, 2024
2 parents 47e63bc + fbbf9b7 commit 12a01fc
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 109 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "visyn_core",
"description": "Core repository for datavisyn applications.",
"version": "8.0.0",
"version": "8.0.1",
"author": {
"name": "datavisyn GmbH",
"email": "[email protected]",
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# a2wsgi==1.6.0 # This WSIGMiddleware is not compatible with starlette_context
alembic==1.11.1
cachetools==5.3.1
cachetools==5.3.2
fastapi==0.101.1
Flask[async]>=2.1.0,<=2.2.2
json-cfg==0.4.2
Expand Down
160 changes: 61 additions & 99 deletions src/vis/EagerVis.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,76 +204,40 @@ export function EagerVis({

const { getVisByType } = useVisProvider();

// Each time you switch between vis config types, there is one render where the config is inconsistent with the type before the merge functions in the useEffect below can be called.
// To ensure that we never render an incosistent config, keep a consistent and a current in the config. Always render the consistent.
// eslint-disable-next-line @typescript-eslint/naming-convention
const [{ consistent: visConfig, current: inconsistentVisConfig }, _setVisConfig] = React.useState<{
consistent: BaseVisConfig;
current: BaseVisConfig;
}>(
externalConfig
? { consistent: null, current: externalConfig }
const [_visConfig, _setVisConfig] = useUncontrolled({
value: externalConfig?.type ? getVisByType(externalConfig?.type)?.mergeConfig(columns, externalConfig) : null,
defaultValue: externalConfig
? null
: columns.filter((c) => c.type === EColumnTypes.NUMERICAL).length > 1
? {
consistent: null,
current: {
type: ESupportedPlotlyVis.SCATTER,
numColumnsSelected: [],
color: null,
numColorScaleType: ENumericalColorScaleType.SEQUENTIAL,
shape: null,
dragMode: EScatterSelectSettings.RECTANGLE,
alphaSliderVal: 0.5,
} as BaseVisConfig,
}
: {
consistent: null,
current: {
type: ESupportedPlotlyVis.BAR,
multiples: null,
group: null,
direction: EBarDirection.HORIZONTAL,
display: EBarDisplayType.ABSOLUTE,
groupType: EBarGroupingType.STACK,
numColumnsSelected: [],
catColumnSelected: null,
aggregateColumn: null,
aggregateType: EAggregateTypes.COUNT,
} as BaseVisConfig,
},
);

const setExternalConfigRef = useSyncedRef(setExternalConfig);
useEffect(() => {
setExternalConfigRef.current?.(visConfig);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [JSON.stringify(visConfig), setExternalConfigRef]);

const setVisConfig = React.useCallback((newConfig: BaseVisConfig) => {
_setVisConfig((oldConfig) => {
return {
current: newConfig,
consistent: oldConfig.current.type !== newConfig.type ? oldConfig.consistent : newConfig,
};
});
}, []);

React.useEffect(() => {
const vis = getVisByType(inconsistentVisConfig?.type);
if (vis) {
const newConfig = vis.mergeConfig(columns, inconsistentVisConfig);
_setVisConfig({ current: newConfig, consistent: newConfig });
}

// DANGER:: this useEffect should only occur when the visConfig.type changes. adding visconfig into the dep array will cause an infinite loop.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [inconsistentVisConfig?.type, getVisByType]);
? ({
type: ESupportedPlotlyVis.SCATTER,
numColumnsSelected: [],
color: null,
numColorScaleType: ENumericalColorScaleType.SEQUENTIAL,
shape: null,
dragMode: EScatterSelectSettings.RECTANGLE,
alphaSliderVal: 0.5,
} as BaseVisConfig)
: ({
type: ESupportedPlotlyVis.BAR,
multiples: null,
group: null,
direction: EBarDirection.HORIZONTAL,
display: EBarDisplayType.ABSOLUTE,
groupType: EBarGroupingType.STACK,
numColumnsSelected: [],
catColumnSelected: null,
aggregateColumn: null,
aggregateType: EAggregateTypes.COUNT,
} as BaseVisConfig),
onChange: setExternalConfig,
});

useEffect(() => {
if (externalConfig) {
setVisConfig(externalConfig);
}
}, [externalConfig, setVisConfig]);
const setVisConfig = (v: BaseVisConfig) => {
const withDefaults = getVisByType(v.type)?.mergeConfig(columns, v);
_setVisConfig(withDefaults);
};

// Converting the selected list into a map, since searching through the list to find an item is common in the vis components.
const selectedMap: { [key: string]: boolean } = useMemo(() => {
Expand Down Expand Up @@ -309,17 +273,17 @@ export function EagerVis({
};
}, [colors]);

if (!visConfig) {
return <div className="tdp-busy" />;
}

const commonProps = {
showSidebar,
setShowSidebar,
enableSidebar,
};

const Renderer = getVisByType(visConfig?.type)?.renderer;
const Renderer = getVisByType(_visConfig?.type)?.renderer;

if (!_visConfig || !Renderer) {
return null;
}

return (
<Group
Expand All @@ -341,35 +305,33 @@ export function EagerVis({
{enableSidebar && !showSidebar ? <VisSidebarOpenButton onClick={() => setShowSidebar(!showSidebar)} /> : null}

<Stack gap={0} style={{ width: '100%', height: '100%', overflow: 'hidden' }} align="stretch" ref={ref}>
{Renderer ? (
<Renderer
config={visConfig}
dimensions={dimensions}
optionsConfig={{
color: {
enable: true,
},
}}
showDragModeOptions={showDragModeOptions}
shapes={shapes}
setConfig={setVisConfig}
filterCallback={filterCallback}
selectionCallback={selectionCallback}
selectedMap={selectedMap}
selectedList={selected}
columns={columns}
scales={scales}
showSidebar={showSidebar}
showCloseButton={showCloseButton}
closeButtonCallback={closeCallback}
scrollZoom={scrollZoom}
{...commonProps}
/>
) : null}
<Renderer
config={_visConfig}
dimensions={dimensions}
optionsConfig={{
color: {
enable: true,
},
}}
showDragModeOptions={showDragModeOptions}
shapes={shapes}
setConfig={setVisConfig}
filterCallback={filterCallback}
selectionCallback={selectionCallback}
selectedMap={selectedMap}
selectedList={selected}
columns={columns}
scales={scales}
showSidebar={showSidebar}
showCloseButton={showCloseButton}
closeButtonCallback={closeCallback}
scrollZoom={scrollZoom}
{...commonProps}
/>
</Stack>
{showSidebar ? (
<VisSidebarWrapper config={visConfig} setConfig={setVisConfig} onClick={() => setShowSidebar(false)}>
<VisSidebar config={visConfig} columns={columns} filterCallback={filterCallback} setConfig={setVisConfig} />
<VisSidebarWrapper config={_visConfig} setConfig={setVisConfig} onClick={() => setShowSidebar(false)}>
<VisSidebar config={_visConfig} columns={columns} filterCallback={filterCallback} setConfig={setVisConfig} />
</VisSidebarWrapper>
) : null}
</Group>
Expand Down
10 changes: 5 additions & 5 deletions src/vis/heatmap/HeatmapGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,8 @@ export function HeatmapGrid({

return (
<Stack align="center" justify="center" style={{ width: '100%', height: '100%' }} p="sm">
{status === 'pending' ? (
<Loader />
) : !hasAtLeast2CatCols ? (
<InvalidCols headerMessage="Invalid settings" bodyMessage="To create a heatmap chart, select at least 2 categorical columns." />
) : (
{status === 'pending' && <Loader />}
{status === 'success' && hasAtLeast2CatCols && (
<Heatmap
column1={allColumns.catColumn[0]}
column2={allColumns.catColumn[1]}
Expand All @@ -50,6 +47,9 @@ export function HeatmapGrid({
selectionCallback={selectionCallback}
/>
)}
{status === 'success' && !hasAtLeast2CatCols && (
<InvalidCols headerMessage="Invalid settings" bodyMessage="To create a heatmap chart, select at least 2 categorical columns." />
)}
</Stack>
);
}
2 changes: 1 addition & 1 deletion src/vis/heatmap/HeatmapText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function HeatmapText({
isImmediate: boolean;
}) {
const labelSpacing = useMemo(() => {
const maxLabelLength = d3.max(yScale.domain().map((m) => m.length));
const maxLabelLength = d3.max(yScale.domain().map((m) => m?.length));

return maxLabelLength > 5 ? 35 : maxLabelLength * 7;
}, [yScale]);
Expand Down
5 changes: 3 additions & 2 deletions visyn_core/settings/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ def get_default_postgres_url(
password: str = "admin",
host: str | None = os.getenv("POSTGRES_HOSTNAME"),
host_fallback: str = "localhost",
port: int = 5432,
port: int | str | None = os.getenv("POSTGRES_PORT"),
port_fallback: int | str = 5432,
database: str = "db",
) -> str:
"""
Returns a default postgres url, including the default values for `driver`, `user`, `password`, `host`, `port` and `database`.
"""
return f"{driver}://{user}:{password}@{host or host_fallback}:{port}/{database}"
return f"{driver}://{user}:{password}@{host or host_fallback}:{port or port_fallback}/{database}"

0 comments on commit 12a01fc

Please sign in to comment.