-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Split GroupTree into GroupTreePlot-component and settings (#1794)
Split previous `/package/group-tree` into a view-component, `/package/group-tree-plot`, which is independent of `redux` and `mui`. The old `GroupTree`-component placed in `python/src/components`, for usage in Dash, now has a lot of the code from the old `/package/group-tree` Thereby the new `group-tree-plot` can be used directly in Webviz NextGen. Removed package: `package/group-tree` New package: `package/group-tree-plot` ----- Closes: equinor/webviz#461
- Loading branch information
1 parent
513005b
commit ef07441
Showing
61 changed files
with
958 additions
and
3,463 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* eslint-disable react-hooks/exhaustive-deps */ // remove when ready to fix these. | ||
|
||
import type { PropsWithChildren, ReactNode } from "react"; | ||
import React, { useMemo } from "react"; | ||
import { Provider as ReduxProvider } from "react-redux"; | ||
import { createReduxStore } from "../redux/store"; | ||
import type { UISettings } from "../redux/types"; | ||
import type { | ||
DatedTree, | ||
EdgeMetadata, | ||
NodeMetadata, | ||
} from "@webviz/group-tree-plot"; | ||
|
||
export type DateTreesIndices = { | ||
treeIndex: number; | ||
dateIndex: number; | ||
}; | ||
|
||
interface DataProviderProps { | ||
id: string; | ||
data: DatedTree[]; | ||
edgeMetadataList: EdgeMetadata[]; | ||
nodeMetadataList: NodeMetadata[]; | ||
initialIndices: DateTreesIndices; | ||
children: ReactNode; | ||
} | ||
|
||
export const DataContext = React.createContext<DatedTree[]>([]); | ||
|
||
const DataProvider: React.FC<DataProviderProps> = ( | ||
props: PropsWithChildren<DataProviderProps> | ||
) => { | ||
const preloadedState = useMemo(() => { | ||
// Use "initialIndices" from previous data if it refers to a valid date otherwise use first date. | ||
const treeIdx = props.initialIndices.treeIndex; | ||
const dateIdx = props.initialIndices.dateIndex; | ||
const hasValidIndices = | ||
props.data.length > treeIdx && | ||
props.data[treeIdx].dates.length > dateIdx; | ||
const initialDateTime = hasValidIndices | ||
? props.data[treeIdx].dates[dateIdx] | ||
: props.data[0].dates[0]; | ||
|
||
const initialFlowRate = props.edgeMetadataList[0]?.key ?? ""; | ||
const initialNodeInfo = props.nodeMetadataList[0]?.key ?? ""; | ||
|
||
return { | ||
id: props.id, | ||
ui: { | ||
currentDateTime: initialDateTime, | ||
currentFlowRate: initialFlowRate, | ||
currentNodeInfo: initialNodeInfo, | ||
} as UISettings, | ||
}; | ||
}, [props.id, props.data]); // Shallow compare does not detect updated data? Will useMemo actually help? | ||
|
||
const store = useMemo( | ||
() => createReduxStore(preloadedState), | ||
[preloadedState] | ||
); | ||
|
||
return ( | ||
<DataContext.Provider value={props.data}> | ||
<ReduxProvider store={store}>{props.children}</ReduxProvider> | ||
</DataContext.Provider> | ||
); | ||
}; | ||
|
||
export default DataProvider; |
72 changes: 72 additions & 0 deletions
72
python/src/components/GroupTree/components/GroupTreeComponent.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import React, { useCallback, useState } from "react"; | ||
|
||
import DataProvider, { DateTreesIndices } from "./DataLoader"; | ||
import GroupTreeViewer from "./GroupTreeViewer"; | ||
import { DatedTree, EdgeMetadata, NodeMetadata } from "@webviz/group-tree-plot"; | ||
|
||
//TODO schema check | ||
export interface GroupTreeProps { | ||
/** | ||
* The ID of this component, used to identify dash components | ||
* in callbacks. The ID needs to be unique across all of the | ||
* components in an app. | ||
*/ | ||
id: string; | ||
/** | ||
* Array of JSON objects describing group tree data. | ||
*/ | ||
data: DatedTree[]; | ||
|
||
/** | ||
* Arrays of metadata. Used in drop down selectors and tree visualization. | ||
*/ | ||
edgeMetadataList: EdgeMetadata[]; | ||
nodeMetadataList: NodeMetadata[]; | ||
} | ||
|
||
const GroupTreeComponent: React.FC<GroupTreeProps> = React.memo( | ||
(props: GroupTreeProps) => { | ||
const [indices, setIndices] = useState<DateTreesIndices>({ | ||
treeIndex: 0, | ||
dateIndex: 0, | ||
}); | ||
|
||
const currentDateTimeChangedCallBack = useCallback( | ||
(currentDateTime: string) => { | ||
const newTreeIndex = props.data.findIndex((e) => { | ||
return e.dates.includes(currentDateTime); | ||
}); | ||
const newDateIndex = | ||
props.data[newTreeIndex].dates.indexOf(currentDateTime); | ||
|
||
setIndices({ | ||
treeIndex: newTreeIndex, | ||
dateIndex: newDateIndex, | ||
}); | ||
}, | ||
[props.data] | ||
); | ||
|
||
return ( | ||
<DataProvider | ||
id={props.id} | ||
data={props.data} | ||
edgeMetadataList={props.edgeMetadataList} | ||
nodeMetadataList={props.nodeMetadataList} | ||
initialIndices={indices} | ||
> | ||
<GroupTreeViewer | ||
id={props.id} | ||
edgeMetadataList={props.edgeMetadataList} | ||
nodeMetadataList={props.nodeMetadataList} | ||
currentDateTimeChangedCallBack={ | ||
currentDateTimeChangedCallBack | ||
} | ||
/> | ||
</DataProvider> | ||
); | ||
} | ||
); | ||
|
||
GroupTreeComponent.displayName = "GroupTreeComponent"; | ||
export default GroupTreeComponent; |
80 changes: 80 additions & 0 deletions
80
python/src/components/GroupTree/components/GroupTreeViewer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* eslint-disable react-hooks/exhaustive-deps */ // remove when ready to fix these. | ||
|
||
import { styled } from "@mui/material/styles"; | ||
import React, { useContext, useEffect } from "react"; | ||
import { useSelector } from "react-redux"; | ||
import type { GroupTreeState } from "../redux/store"; | ||
import { DataContext } from "./DataLoader"; | ||
import SettingsBar from "./Settings/SettingsBar"; | ||
|
||
import { | ||
GroupTreePlot, | ||
EdgeMetadata, | ||
NodeMetadata, | ||
} from "@webviz/group-tree-plot"; | ||
|
||
const PREFIX = "GroupTreeViewer"; | ||
|
||
const classes = { | ||
root: `${PREFIX}-root`, | ||
}; | ||
|
||
const Root = styled("div")(() => ({ | ||
[`&.${classes.root}`]: { | ||
position: "relative", | ||
display: "flex", | ||
flex: 1, | ||
flexDirection: "column", | ||
height: "90%", | ||
}, | ||
})); | ||
|
||
interface GroupTreeViewerProps { | ||
id: string; | ||
edgeMetadataList: EdgeMetadata[]; | ||
nodeMetadataList: NodeMetadata[]; | ||
currentDateTimeChangedCallBack: (currentDateTime: string) => void; | ||
} | ||
|
||
const GroupTreeViewer: React.FC<GroupTreeViewerProps> = ( | ||
props: GroupTreeViewerProps | ||
) => { | ||
const data = useContext(DataContext); | ||
|
||
const currentDateTime = useSelector( | ||
(state: GroupTreeState) => state.ui.currentDateTime | ||
); | ||
const currentFlowRateKey = useSelector( | ||
(state: GroupTreeState) => state.ui.currentFlowRate | ||
); | ||
const currentNodeKey = useSelector( | ||
(state: GroupTreeState) => state.ui.currentNodeInfo | ||
); | ||
|
||
useEffect(() => { | ||
if (typeof props.currentDateTimeChangedCallBack !== "undefined") { | ||
props.currentDateTimeChangedCallBack(currentDateTime); | ||
} | ||
}, [currentDateTime]); | ||
|
||
return ( | ||
<Root className={classes.root}> | ||
<SettingsBar | ||
edgeMetadataList={props.edgeMetadataList} | ||
nodeMetadataList={props.nodeMetadataList} | ||
/> | ||
<GroupTreePlot | ||
id={props.id} | ||
datedTrees={data} | ||
edgeMetadataList={props.edgeMetadataList} | ||
nodeMetadataList={props.nodeMetadataList} | ||
selectedEdgeKey={currentFlowRateKey} | ||
selectedNodeKey={currentNodeKey} | ||
selectedDateTime={currentDateTime} | ||
/> | ||
</Root> | ||
); | ||
}; | ||
|
||
GroupTreeViewer.displayName = "GroupTreeViewer"; | ||
export default GroupTreeViewer; |
Oops, something went wrong.