Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard tiles layout #1520

Merged
merged 23 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b32a807
feat: Implement tiles
ptbrowne May 16, 2024
d0717a2
fix: Show resize handles
ptbrowne May 17, 2024
43de2c4
feat: Dispatch change of layouts and save chart config with it
ptbrowne May 21, 2024
da8e5c7
refactor: Provide height in ChartObserver context
ptbrowne May 21, 2024
436dc59
feat: Change grid rows max h / min h
ptbrowne May 21, 2024
4eee9bd
feat: Change how aspect ratio is handled for columns
ptbrowne May 21, 2024
9ea3f1d
refactor: Change how aspect ratio is dealt with for columns chart
ptbrowne May 21, 2024
a34ba8f
refactor: Change how aspect ratio is dealt with for all charts
ptbrowne May 21, 2024
f888ca5
refactor: Make clearer the chart container hierarchy through useStyles
ptbrowne May 21, 2024
f156bec
fix: Correctly set provider initial value to undefined so that check …
ptbrowne May 21, 2024
7e53f1b
feat: Chart size observer observes only the part containing the plot …
ptbrowne May 21, 2024
a7e6e2a
feat: Way to set aspect ratio per chart
ptbrowne May 21, 2024
55f2f8b
feat: Performance of resizing in grid
ptbrowne May 21, 2024
d1253e8
chore: Lint
ptbrowne May 21, 2024
45bd129
feat: Initialize correctly tiles layout
ptbrowne May 21, 2024
37c28e5
fix: Correctly pass height
ptbrowne May 21, 2024
48a8bcc
refactor: Extract decoder function not to have io-ts code in the render
ptbrowne May 21, 2024
52b5190
refactor: Extract drag handle
ptbrowne May 21, 2024
510992c
fix: Drag handle accepts additional class name
ptbrowne May 21, 2024
e383ee5
feat: Can move charts only through the drag handle
ptbrowne May 21, 2024
2d11ccd
chore: Lint
ptbrowne May 21, 2024
93141d4
chore: Lint
ptbrowne May 21, 2024
4debb83
fix: Remove old test
ptbrowne May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/charts/chart-data-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const useStyles = makeStyles((theme: Theme) => ({
dataWrapper: {
position: "relative",
width: "100%",
height: "100%",
display: "flex",
flexDirection: "column",
},
Expand Down
9 changes: 8 additions & 1 deletion app/charts/shared/containers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { ReactNode, useEffect, useRef } from "react";

import { useChartState } from "@/charts/shared/chart-state";
import { CalculationToggle } from "@/charts/shared/interactive-filter-calculation-toggle";
import { useObserverRef } from "@/charts/shared/use-width";
import { chartPanelLayoutGridClasses } from "@/components/chart-panel-layout-grid";
import { useTransitionStore } from "@/stores/transition";

const useStyles = makeStyles(() => ({
Expand All @@ -13,11 +15,16 @@ const useStyles = makeStyles(() => ({
width: "100%",
overflow: "hidden",
flexGrow: 1,
aspectRatio: "5 / 2",

[`.${chartPanelLayoutGridClasses.root} &`]: {
aspectRatio: "auto",
},
},
}));

export const ChartContainer = ({ children }: { children: ReactNode }) => {
const ref = useRef<HTMLDivElement>(null);
const ref = useObserverRef();
const classes = useStyles();

return (
Expand Down
39 changes: 24 additions & 15 deletions app/charts/shared/use-width.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { makeStyles } from "@mui/styles";
import {
createContext,
ReactNode,
Expand Down Expand Up @@ -27,32 +26,29 @@ export type Bounds = {
aspectRatio: number;
};

const useStyles = makeStyles(() => ({
chartObserver: {
display: "flex",
minHeight: "100%",
},
}));

export const Observer = ({ children }: { children: ReactNode }) => {
const [ref, width, height] = useResizeObserver<HTMLDivElement>();
const prev = useTimedPrevious(width, 500);
const isResizing = prev !== width;
const setEnableTransition = useTransitionStore((state) => state.setEnable);
const classes = useStyles();
useEffect(
() => setEnableTransition(!isResizing),
[isResizing, setEnableTransition]
);

const size = useMemo(() => ({ width, height }), [width, height]);
const size = useMemo(
() => ({
width,
height,
ref,
}),
[width, height, ref]
);

return (
<div ref={ref} className={classes.chartObserver}>
<ChartObserverContext.Provider value={size}>
{children}
</ChartObserverContext.Provider>
</div>
<ChartObserverContext.Provider value={size}>
{children}
</ChartObserverContext.Provider>
);
};

Expand All @@ -62,6 +58,7 @@ const ChartObserverContext = createContext(
| {
width: number;
height: number;
ref: (node: HTMLDivElement) => void;
}
);

Expand All @@ -88,3 +85,15 @@ export const useHeight = () => {

return ctx.height;
};

export const useObserverRef = () => {
const ctx = useContext(ChartObserverContext);

if (ctx === undefined) {
throw Error(
"You need to wrap your component in <ChartObserverContextProvider /> to useWidth()"
);
}

return ctx.ref;
};
7 changes: 6 additions & 1 deletion app/components/chart-panel-layout-grid.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import clsx from "clsx";
import { fold } from "fp-ts/lib/Either";
import { pipe } from "fp-ts/lib/function";
import { useState } from "react";
Expand All @@ -9,6 +10,10 @@ import ChartGridLayout, { generateLayout } from "@/components/react-grid";
import { ReactGridLayoutsType, isLayouting } from "@/configurator";
import { useConfiguratorState } from "@/src";

export const chartPanelLayoutGridClasses = {
root: "chart-panel-grid-layout",
};

const ChartPanelLayoutGrid = (props: ChartPanelLayoutTypeProps) => {
const { chartConfigs } = props;
const [config, dispatch] = useConfiguratorState(isLayouting);
Expand Down Expand Up @@ -63,7 +68,7 @@ const ChartPanelLayoutGrid = (props: ChartPanelLayoutTypeProps) => {
return (
<>
<ChartGridLayout
className={"layout"}
className={clsx("layout", chartPanelLayoutGridClasses.root)}
layouts={layouts}
resize
onLayoutChange={(_l, allLayouts) => handleChangeLayouts(allLayouts)}
Expand Down
9 changes: 7 additions & 2 deletions app/components/chart-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Theme } from "@mui/material";
import { makeStyles } from "@mui/styles";

import { chartPanelLayoutGridClasses } from "@/components/chart-panel-layout-grid";

/** Generic styles shared between `ChartPreview` and `ChartPublished`. */
export const useChartStyles = makeStyles<Theme>((theme) => ({
root: {
Expand All @@ -14,7 +16,10 @@ export const useChartStyles = makeStyles<Theme>((theme) => ({
border: "1px solid",
borderColor: theme.palette.divider,
color: theme.palette.grey[800],
display: "flex",
flexDirection: "column",

[`.${chartPanelLayoutGridClasses.root} &`]: {
display: "flex",
flexDirection: "column",
},
},
}));
18 changes: 12 additions & 6 deletions app/utils/use-resize-observer.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ResizeObserver } from "@juggle/resize-observer";
import { useEffect, useState, useRef } from "react";
import { useEventCallback } from "@mui/material";
import { useEffect, useRef, useState } from "react";

export const useResizeObserver = <T extends Element>() => {
const roRef = useRef<ResizeObserver>();
const elRef = useRef<T>();
const [width, changeWidth] = useState(1);
const [height, changeHeight] = useState(1);

const handleRef = (node: T) => {
const handleRef = useEventCallback((node: T) => {
ptbrowne marked this conversation as resolved.
Show resolved Hide resolved
if (!node) {
return;
}
Expand All @@ -29,23 +30,28 @@ export const useResizeObserver = <T extends Element>() => {
// Prevent flickering when scrollbars appear and triggers another resize
// by only resizing when difference to current measurement is above a certain threshold
changeWidth((width) =>
Math.abs(newWidth - width) > 16 ? newWidth : width
Math.abs(newWidth - width) > 16 && newWidth > 0 ? newWidth : width
);
changeHeight((height) =>
Math.abs(newHeight - height) > 16 ? newHeight : height
Math.abs(newHeight - height) > 16 && newHeight > 0
? newHeight
: height
);
});
}

roRef.current.observe(elRef.current);
};
});

useEffect(() => {
if (elRef.current) {
handleRef(elRef.current);
}
return () => {
roRef.current?.disconnect();
roRef.current = undefined;
};
}, []);
}, [handleRef]);

return [handleRef, width, height] as const;
};