From 102abd7aa04f23c377872f94e7c4d8708192700b Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Wed, 22 Nov 2023 16:22:53 +0100 Subject: [PATCH 01/20] Backup of initial splitting --- .../group-tree/src/components/DataLoader.tsx | 15 ++-- .../src/components/GroupTreeComponent.tsx | 13 +-- .../src/components/GroupTreeViewer.tsx | 72 ++++++----------- .../components/Settings/FlowRateSelector.tsx | 6 +- .../components/Settings/NodeInfoSelector.tsx | 6 +- .../src/components/Settings/SettingsBar.tsx | 6 +- .../group-tree-plot/src/GroupTreePlot.tsx | 80 +++++++++++++++++++ .../src}/Plot/dynamic_tree.css | 0 .../src}/Plot/group_tree.js | 0 .../components/group-tree-plot/src/types.ts | 24 ++++++ .../packages/group-tree/src/redux/types.ts | 21 ----- 11 files changed, 153 insertions(+), 90 deletions(-) create mode 100644 typescript/packages/group-tree/src/components/group-tree-plot/src/GroupTreePlot.tsx rename typescript/packages/group-tree/src/components/{ => group-tree-plot/src}/Plot/dynamic_tree.css (100%) rename typescript/packages/group-tree/src/components/{ => group-tree-plot/src}/Plot/group_tree.js (100%) create mode 100644 typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts diff --git a/typescript/packages/group-tree/src/components/DataLoader.tsx b/typescript/packages/group-tree/src/components/DataLoader.tsx index 537473fe5..5bcd892ab 100644 --- a/typescript/packages/group-tree/src/components/DataLoader.tsx +++ b/typescript/packages/group-tree/src/components/DataLoader.tsx @@ -4,18 +4,23 @@ 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 { Data, DataInfos, UISettings } from "../redux/types"; +import type { UISettings } from "../redux/types"; +import type { + DatedTrees, + EdgeInfo, + NodeInfo, +} from "./group-tree-plot/src/types"; interface Props { id: string; - data: Data; - edge_options: DataInfos; - node_options: DataInfos; + data: DatedTrees; + edge_options: EdgeInfo[]; + node_options: NodeInfo[]; initial_index: [number, number]; children: ReactNode; } -export const DataContext = React.createContext([]); +export const DataContext = React.createContext([]); const DataProvider: React.FC = ({ children, diff --git a/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx b/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx index cbe6b6d3b..1fb63c896 100644 --- a/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx +++ b/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx @@ -1,7 +1,8 @@ import React, { useCallback, useState } from "react"; -import type { Data, DataInfos } from "../redux/types"; + import DataProvider from "./DataLoader"; import GroupTreeViewer from "./GroupTreeViewer"; +import { DatedTrees, EdgeInfo, NodeInfo } from "./group-tree-plot/src/types"; //TODO schema check export interface GroupTreeProps { @@ -14,13 +15,13 @@ export interface GroupTreeProps { /** * Array of JSON objects describing group tree data. */ - data: Data; + data: DatedTrees; /** * Arrays of options. Used in drop down selectors. */ - edgeOptions: DataInfos; - nodeOptions: DataInfos; + edgeOptions: EdgeInfo[]; + nodeOptions: NodeInfo[]; } const GroupTreeComponent: React.FC = React.memo( @@ -50,8 +51,8 @@ const GroupTreeComponent: React.FC = React.memo( > ({ }, })); -interface Props { +interface GroupTreeViewerProps { id: string; - edge_options: DataInfos; - node_options: DataInfos; + edgeOptions: EdgeInfo[]; + nodeOptions: NodeInfo[]; currentDateTimeChangedCallBack: (currentDateTime: string) => void; } -const GroupTreeViewer: React.FC = ({ - id, - edge_options, - node_options, - currentDateTimeChangedCallBack, -}: Props) => { - const divRef = useRef(null); +const GroupTreeViewer: React.FC = ( + props: GroupTreeViewerProps +) => { const data = useContext(DataContext); - const renderer = useRef(); - const currentDateTime = useSelector( (state: GroupTreeState) => state.ui.currentDateTime ); @@ -56,45 +49,26 @@ const GroupTreeViewer: React.FC = ({ ); useEffect(() => { - renderer.current = new GroupTree( - id, - cloneDeep(data), - currentFlowRate, - currentNodeInfo, - currentDateTime, - edge_options, - node_options - ); - }, [data]); - - useEffect(() => { - if (!renderer.current) return; - - renderer.current.update(currentDateTime); - - if (typeof currentDateTimeChangedCallBack !== "undefined") { - currentDateTimeChangedCallBack(currentDateTime); + if (typeof props.currentDateTimeChangedCallBack !== "undefined") { + props.currentDateTimeChangedCallBack(currentDateTime); } }, [currentDateTime]); - useEffect(() => { - if (!renderer.current) return; - renderer.current.flowrate = currentFlowRate; - }, [currentFlowRate]); - - useEffect(() => { - if (!renderer.current) return; - renderer.current.nodeinfo = currentNodeInfo; - }, [currentNodeInfo]); - return ( + -
- {/* */} ); }; diff --git a/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx b/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx index 8c8d170d4..9b131e2f2 100644 --- a/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx +++ b/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx @@ -4,7 +4,7 @@ import React, { useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { updateCurrentFlowRate } from "../../redux/actions"; import type { GroupTreeState } from "../../redux/store"; -import type { DataInfos, DataInfo } from "../../redux/types"; +import { EdgeInfo } from "../group-tree-plot/src/types"; const PREFIX = "FlowRateSelector"; @@ -20,7 +20,7 @@ const StyledNativeSelect = styled(NativeSelect)(({ theme }) => ({ })); interface Props { - edge_options: DataInfos; + edge_options: EdgeInfo[]; } const FlowRateSelector: React.FC = React.memo( @@ -46,7 +46,7 @@ const FlowRateSelector: React.FC = React.memo( value={currentFlowRate} onChange={handleSelectedItemChange} > - {edge_options.map((key: DataInfo) => ( + {edge_options.map((key: EdgeInfo) => ( diff --git a/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx b/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx index 4837ded65..4b055290c 100644 --- a/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx +++ b/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx @@ -4,7 +4,7 @@ import React, { useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { updateCurrentNodeInfo } from "../../redux/actions"; import type { GroupTreeState } from "../../redux/store"; -import type { DataInfos, DataInfo } from "../../redux/types"; +import { NodeInfo } from "../group-tree-plot/src/types"; const PREFIX = "NodeInfoSelector"; @@ -20,7 +20,7 @@ const StyledNativeSelect = styled(NativeSelect)(({ theme }) => ({ })); interface Props { - node_options: DataInfos; + node_options: NodeInfo[]; } const NodeInfoSelector: React.FC = React.memo( @@ -46,7 +46,7 @@ const NodeInfoSelector: React.FC = React.memo( value={currentNodeInfo} onChange={handleSelectedItemChange} > - {node_options.map((key: DataInfo) => ( + {node_options.map((key: NodeInfo) => ( diff --git a/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx b/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx index 49e7c7d7c..6598920fc 100644 --- a/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx +++ b/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx @@ -4,7 +4,7 @@ import React from "react"; import DateTimeSlider from "./DateTimeSlider"; import FlowRateSelector from "./FlowRateSelector"; import NodeInfoSelector from "./NodeInfoSelector"; -import type { DataInfos } from "../../redux/types"; +import { EdgeInfo, NodeInfo } from "../group-tree-plot/src/types"; const PREFIX = "SettingsBar"; @@ -26,8 +26,8 @@ const StyledTopBar = styled(TopBar)(() => ({ })); interface Props { - edge_options: DataInfos; - node_options: DataInfos; + edge_options: EdgeInfo[]; + node_options: NodeInfo[]; } const SettingsBar: React.FC = React.memo( diff --git a/typescript/packages/group-tree/src/components/group-tree-plot/src/GroupTreePlot.tsx b/typescript/packages/group-tree/src/components/group-tree-plot/src/GroupTreePlot.tsx new file mode 100644 index 000000000..1ac0ef876 --- /dev/null +++ b/typescript/packages/group-tree/src/components/group-tree-plot/src/GroupTreePlot.tsx @@ -0,0 +1,80 @@ +import React from "react"; + +import GroupTree from "./Plot/group_tree"; +import { DatedTrees, EdgeInfo, NodeInfo } from "./types"; +import { cloneDeep, isEqual } from "lodash"; + +interface GroupTreePlotProps { + id: string; + edgeInfoList: EdgeInfo[]; + nodeInfoList: NodeInfo[]; + datedTrees: DatedTrees; + selectedEdgeName: string; + selectedNodeName: string; + selectedDateTime: string; +} + +export const GroupTreePlot: React.FC = ( + props: GroupTreePlotProps +) => { + const divRef = React.useRef(null); + const groupTreeRef = React.useRef(); + + const [isMounted, setIsMounted] = React.useState(false); + + const [prevId, setPrevId] = React.useState(null); + const [prevDatedTrees, setPrevDatedTrees] = + React.useState(null); + + const [prevSelectedEdgeName, setPrevSelectedEdgeName] = + React.useState(props.selectedEdgeName); + const [prevSelectedNodeName, setPrevSelectedNodeName] = + React.useState(props.selectedNodeName); + const [prevSelectedDateTime, setPrevSelectedDateTime] = + React.useState(props.selectedDateTime); + + React.useEffect(function initialRender() { + setIsMounted(true); + }, []); + + if ( + isMounted && + // divRef.current && + (!isEqual(prevDatedTrees, props.datedTrees) || prevId !== props.id) + ) { + setPrevDatedTrees(props.datedTrees); + setPrevId(props.id); + groupTreeRef.current = new GroupTree( + props.id, + cloneDeep(props.datedTrees), + props.selectedEdgeName, + props.selectedNodeName, + props.selectedDateTime, + props.edgeInfoList, + props.nodeInfoList + ); + } + + if (prevSelectedEdgeName !== props.selectedEdgeName) { + setPrevSelectedEdgeName(props.selectedEdgeName); + if (!groupTreeRef.current) return; + + groupTreeRef.current.flowrate = props.selectedEdgeName; + } + + if (prevSelectedNodeName !== props.selectedNodeName) { + setPrevSelectedNodeName(props.selectedNodeName); + if (!groupTreeRef.current) return; + + groupTreeRef.current.nodeinfo = props.selectedNodeName; + } + + if (prevSelectedDateTime !== props.selectedDateTime) { + setPrevSelectedDateTime(props.selectedDateTime); + if (!groupTreeRef.current) return; + + groupTreeRef.current.update(props.selectedDateTime); + } + + return
; +}; diff --git a/typescript/packages/group-tree/src/components/Plot/dynamic_tree.css b/typescript/packages/group-tree/src/components/group-tree-plot/src/Plot/dynamic_tree.css similarity index 100% rename from typescript/packages/group-tree/src/components/Plot/dynamic_tree.css rename to typescript/packages/group-tree/src/components/group-tree-plot/src/Plot/dynamic_tree.css diff --git a/typescript/packages/group-tree/src/components/Plot/group_tree.js b/typescript/packages/group-tree/src/components/group-tree-plot/src/Plot/group_tree.js similarity index 100% rename from typescript/packages/group-tree/src/components/Plot/group_tree.js rename to typescript/packages/group-tree/src/components/group-tree-plot/src/Plot/group_tree.js diff --git a/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts b/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts new file mode 100644 index 000000000..9ec4e5e26 --- /dev/null +++ b/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts @@ -0,0 +1,24 @@ +export type NameLabelAndUnit = { + name: string; // key? + label: string; // Displayed name + unit?: string; // Optional unit +}; + +export type EdgeInfo = NameLabelAndUnit; +export type NodeInfo = NameLabelAndUnit; + +export interface Node { + nodeType: "Group" | "Well"; + nodeLabel: string; + edgeLabel: string; + // nodeOption: NodeOption; + // edgeOption: EdgeOption; + children: Node[]; +} + +export interface DatedTree { + dates: [string]; + tree: Node; +} + +export type DatedTrees = DatedTree[]; diff --git a/typescript/packages/group-tree/src/redux/types.ts b/typescript/packages/group-tree/src/redux/types.ts index 48c2f2bd7..77a1a8cfe 100644 --- a/typescript/packages/group-tree/src/redux/types.ts +++ b/typescript/packages/group-tree/src/redux/types.ts @@ -1,24 +1,3 @@ -export type DatedTree = { - dates: [string]; - tree: Node; -}; -export type Data = DatedTree[]; - -export interface Node { - node_label: string; - node_type: "Group" | "Well"; - //node_data - edge_label: string; - //edge_data - children: Node[]; -} - -export interface DataInfo { - name: string; - label: string; -} -export type DataInfos = DataInfo[]; - export interface UISettings { currentDateTime: string; currentFlowRate: string; From af06af95c4c1fcc952d284971ca2bc02ecdc99e8 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Thu, 23 Nov 2023 15:32:32 +0100 Subject: [PATCH 02/20] Next iteration - WIP --- .../group-tree/src/GroupTree.test.tsx | 20 +++--- .../packages/group-tree/src/GroupTree.tsx | 11 ++-- .../group-tree/src/components/DataLoader.tsx | 66 +++++++++++-------- .../src/components/GroupTreeComponent.tsx | 50 ++++++++------ .../src/components/GroupTreeViewer.tsx | 22 +++---- .../components/Settings/DateTimeSlider.tsx | 5 +- .../components/Settings/FlowRateSelector.tsx | 16 ++--- .../components/Settings/NodeInfoSelector.tsx | 16 ++--- .../src/components/Settings/SettingsBar.tsx | 20 +++--- .../group-tree-plot/src/GroupTreePlot.tsx | 45 +++++++------ .../components/group-tree-plot/src/types.ts | 46 ++++++++----- .../storybook/GroupTreeComponent.stories.tsx | 28 ++++---- .../components/DateTimeSlider.stories.tsx | 8 ++- .../components/FlowRateSelector.stories.tsx | 28 +++++--- .../components/GroupTreeViewer.stories.tsx | 40 +++++++---- .../components/SettingsBar.stories.tsx | 39 +++++++---- 16 files changed, 274 insertions(+), 186 deletions(-) diff --git a/typescript/packages/group-tree/src/GroupTree.test.tsx b/typescript/packages/group-tree/src/GroupTree.test.tsx index d24551ade..6eee62a2b 100644 --- a/typescript/packages/group-tree/src/GroupTree.test.tsx +++ b/typescript/packages/group-tree/src/GroupTree.test.tsx @@ -14,36 +14,36 @@ describe.skip("Test GroupTree Default Component", () => { children: ( { ); }; @@ -32,8 +32,11 @@ GroupTree.propTypes = { */ data: PropTypes.arrayOf(PropTypes.object), - edgeOptions: PropTypes.arrayOf(PropTypes.object), - nodeOptions: PropTypes.arrayOf(PropTypes.object), + /** + * Arrays of metadata. Used in drop down selectors and tree visualization. + */ + edgeMetadataList: PropTypes.arrayOf(PropTypes.object), + nodeMetadataList: PropTypes.arrayOf(PropTypes.object), }; export type { GroupTreeProps }; diff --git a/typescript/packages/group-tree/src/components/DataLoader.tsx b/typescript/packages/group-tree/src/components/DataLoader.tsx index 5bcd892ab..99a6a59cc 100644 --- a/typescript/packages/group-tree/src/components/DataLoader.tsx +++ b/typescript/packages/group-tree/src/components/DataLoader.tsx @@ -7,53 +7,61 @@ import { createReduxStore } from "../redux/store"; import type { UISettings } from "../redux/types"; import type { DatedTrees, - EdgeInfo, - NodeInfo, + EdgeMetadata, + NodeMetadata, } from "./group-tree-plot/src/types"; -interface Props { +export type DateTreesIndices = { + treeIndex: number; + dateIndex: number; +}; + +interface DataProviderProps { id: string; data: DatedTrees; - edge_options: EdgeInfo[]; - node_options: NodeInfo[]; - initial_index: [number, number]; + edgeMetadataList: EdgeMetadata[]; + nodeMetadataList: NodeMetadata[]; + initialIndices: DateTreesIndices; children: ReactNode; } export const DataContext = React.createContext([]); -const DataProvider: React.FC = ({ - children, - id, - data, - edge_options, - node_options, - initial_index, -}: PropsWithChildren) => { +const DataProvider: React.FC = ( + props: PropsWithChildren +) => { const preloadedState = useMemo(() => { - // Use "initial_index" from previous data if it refers to a valid date otherwise use first date. - const idx1 = initial_index?.[0]; - const idx2 = initial_index?.[1]; - const initialDateTime = - data.length > idx1 && data[idx1].dates.length > idx2 - ? data[idx1].dates[idx2] - : data[0].dates[0]; + // 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 ?? ""; const initialFlowRate = - edge_options?.length > 0 ? edge_options[0].name : ""; + props.edgeMetadataList?.length > 0 + ? props.edgeMetadataList[0].key + : ""; - const intialNodeInfo = - node_options?.length > 0 ? node_options[0].name : ""; + const initialNodeInfo = + props.nodeMetadataList?.length > 0 + ? props.nodeMetadataList[0].key + : ""; return { - id: id, + id: props.id, ui: { currentDateTime: initialDateTime, currentFlowRate: initialFlowRate, - currentNodeInfo: intialNodeInfo, + currentNodeInfo: initialNodeInfo, } as UISettings, }; - }, [id, data]); + }, [props.id, props.data]); // Shallow compare does not detect updated data? Will useMemo actually help? const store = useMemo( () => createReduxStore(preloadedState), @@ -61,8 +69,8 @@ const DataProvider: React.FC = ({ ); return ( - - {children} + + {props.children} ); }; diff --git a/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx b/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx index 1fb63c896..47a00fb29 100644 --- a/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx +++ b/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx @@ -1,8 +1,12 @@ import React, { useCallback, useState } from "react"; -import DataProvider from "./DataLoader"; +import DataProvider, { DateTreesIndices } from "./DataLoader"; import GroupTreeViewer from "./GroupTreeViewer"; -import { DatedTrees, EdgeInfo, NodeInfo } from "./group-tree-plot/src/types"; +import { + DatedTrees, + EdgeMetadata, + NodeMetadata, +} from "./group-tree-plot/src/types"; //TODO schema check export interface GroupTreeProps { @@ -18,41 +22,47 @@ export interface GroupTreeProps { data: DatedTrees; /** - * Arrays of options. Used in drop down selectors. + * Arrays of metadata. Used in drop down selectors and tree visualization. */ - edgeOptions: EdgeInfo[]; - nodeOptions: NodeInfo[]; + edgeMetadataList: EdgeMetadata[]; + nodeMetadataList: NodeMetadata[]; } const GroupTreeComponent: React.FC = React.memo( - ({ id, data, edgeOptions, nodeOptions }: GroupTreeProps) => { - const [index, setIndex] = useState([0, 0] as [number, number]); + (props: GroupTreeProps) => { + const [indices, setIndices] = useState({ + treeIndex: 0, + dateIndex: 0, + }); const currentDateTimeChangedCallBack = useCallback( (currentDateTime: string) => { - const current_tree_index = data.findIndex((e) => { + const newTreeIndex = props.data.findIndex((e) => { return e.dates.includes(currentDateTime); }); - const date_index = - data[current_tree_index].dates.indexOf(currentDateTime); + const newDateIndex = + props.data[newTreeIndex].dates.indexOf(currentDateTime); - setIndex([current_tree_index, date_index]); + setIndices({ + treeIndex: newTreeIndex, + dateIndex: newDateIndex, + }); }, - [data] + [props.data] ); return ( ({ interface GroupTreeViewerProps { id: string; - edgeOptions: EdgeInfo[]; - nodeOptions: NodeInfo[]; + edgeMetadataList: EdgeMetadata[]; + nodeMetadataList: NodeMetadata[]; currentDateTimeChangedCallBack: (currentDateTime: string) => void; } @@ -41,10 +41,10 @@ const GroupTreeViewer: React.FC = ( const currentDateTime = useSelector( (state: GroupTreeState) => state.ui.currentDateTime ); - const currentFlowRate = useSelector( + const currentFlowRateKey = useSelector( (state: GroupTreeState) => state.ui.currentFlowRate ); - const currentNodeInfo = useSelector( + const currentNodeKey = useSelector( (state: GroupTreeState) => state.ui.currentNodeInfo ); @@ -57,16 +57,16 @@ const GroupTreeViewer: React.FC = ( return ( diff --git a/typescript/packages/group-tree/src/components/Settings/DateTimeSlider.tsx b/typescript/packages/group-tree/src/components/Settings/DateTimeSlider.tsx index 9e04fa805..5da83f330 100644 --- a/typescript/packages/group-tree/src/components/Settings/DateTimeSlider.tsx +++ b/typescript/packages/group-tree/src/components/Settings/DateTimeSlider.tsx @@ -4,9 +4,10 @@ import React, { useCallback, useContext, useMemo } from "react"; import { useDispatch, useSelector } from "react-redux"; import { updateCurrentDateTime } from "../../redux/actions"; import type { GroupTreeState } from "../../redux/store"; -import type { Data, DatedTree } from "../../redux/types"; import { DataContext } from "../DataLoader"; +import { DatedTree, DatedTrees } from "../group-tree-plot/src/types"; + const classes = { root: "DateTimeSlider-root", }; @@ -32,7 +33,7 @@ const EdsSlider = styled(Slider)(() => ({ })); const DateTimeSlider: React.FC = React.memo(() => { - const data: Data = useContext(DataContext); + const data: DatedTrees = useContext(DataContext); // Redux const dispatch = useDispatch(); diff --git a/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx b/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx index 9b131e2f2..f8b28f4fc 100644 --- a/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx +++ b/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx @@ -4,7 +4,7 @@ import React, { useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { updateCurrentFlowRate } from "../../redux/actions"; import type { GroupTreeState } from "../../redux/store"; -import { EdgeInfo } from "../group-tree-plot/src/types"; +import { EdgeMetadata } from "../group-tree-plot/src/types"; const PREFIX = "FlowRateSelector"; @@ -19,12 +19,12 @@ const StyledNativeSelect = styled(NativeSelect)(({ theme }) => ({ }, })); -interface Props { - edge_options: EdgeInfo[]; +interface FlowRateSelectorProps { + edgeMetadataList: EdgeMetadata[]; } -const FlowRateSelector: React.FC = React.memo( - ({ edge_options }: Props) => { +const FlowRateSelector: React.FC = React.memo( + (props: FlowRateSelectorProps) => { // Redux const dispatch = useDispatch(); const currentFlowRate = useSelector( @@ -46,9 +46,9 @@ const FlowRateSelector: React.FC = React.memo( value={currentFlowRate} onChange={handleSelectedItemChange} > - {edge_options.map((key: EdgeInfo) => ( - ))} diff --git a/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx b/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx index 4b055290c..feeac74b6 100644 --- a/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx +++ b/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx @@ -4,7 +4,7 @@ import React, { useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { updateCurrentNodeInfo } from "../../redux/actions"; import type { GroupTreeState } from "../../redux/store"; -import { NodeInfo } from "../group-tree-plot/src/types"; +import { NodeMetadata } from "../group-tree-plot/src/types"; const PREFIX = "NodeInfoSelector"; @@ -19,12 +19,12 @@ const StyledNativeSelect = styled(NativeSelect)(({ theme }) => ({ }, })); -interface Props { - node_options: NodeInfo[]; +interface NodeInfoSelectorProps { + nodeMetadataList: NodeMetadata[]; } -const NodeInfoSelector: React.FC = React.memo( - ({ node_options }: Props) => { +const NodeInfoSelector: React.FC = React.memo( + (props: NodeInfoSelectorProps) => { // Redux const dispatch = useDispatch(); const currentNodeInfo = useSelector( @@ -46,9 +46,9 @@ const NodeInfoSelector: React.FC = React.memo( value={currentNodeInfo} onChange={handleSelectedItemChange} > - {node_options.map((key: NodeInfo) => ( - ))} diff --git a/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx b/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx index 6598920fc..55b524aaf 100644 --- a/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx +++ b/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx @@ -4,7 +4,7 @@ import React from "react"; import DateTimeSlider from "./DateTimeSlider"; import FlowRateSelector from "./FlowRateSelector"; import NodeInfoSelector from "./NodeInfoSelector"; -import { EdgeInfo, NodeInfo } from "../group-tree-plot/src/types"; +import { EdgeMetadata, NodeMetadata } from "../group-tree-plot/src/types"; const PREFIX = "SettingsBar"; @@ -25,18 +25,22 @@ const StyledTopBar = styled(TopBar)(() => ({ }, })); -interface Props { - edge_options: EdgeInfo[]; - node_options: NodeInfo[]; +interface SettingsBarProps { + edgeMetadataList: EdgeMetadata[]; + nodeMetadataList: NodeMetadata[]; } -const SettingsBar: React.FC = React.memo( - ({ edge_options, node_options }: Props) => { +const SettingsBar: React.FC = React.memo( + (props: SettingsBarProps) => { return ( - - + + diff --git a/typescript/packages/group-tree/src/components/group-tree-plot/src/GroupTreePlot.tsx b/typescript/packages/group-tree/src/components/group-tree-plot/src/GroupTreePlot.tsx index 1ac0ef876..3380a8196 100644 --- a/typescript/packages/group-tree/src/components/group-tree-plot/src/GroupTreePlot.tsx +++ b/typescript/packages/group-tree/src/components/group-tree-plot/src/GroupTreePlot.tsx @@ -1,16 +1,16 @@ import React from "react"; import GroupTree from "./Plot/group_tree"; -import { DatedTrees, EdgeInfo, NodeInfo } from "./types"; -import { cloneDeep, isEqual } from "lodash"; +import { DatedTrees, EdgeMetadata, NodeMetadata } from "./types"; +import { isEqual } from "lodash"; interface GroupTreePlotProps { id: string; - edgeInfoList: EdgeInfo[]; - nodeInfoList: NodeInfo[]; + edgeMetadataList: EdgeMetadata[]; + nodeMetadataList: NodeMetadata[]; datedTrees: DatedTrees; - selectedEdgeName: string; - selectedNodeName: string; + selectedEdgeKey: string; + selectedNodeKey: string; selectedDateTime: string; } @@ -20,16 +20,19 @@ export const GroupTreePlot: React.FC = ( const divRef = React.useRef(null); const groupTreeRef = React.useRef(); + // State to ensure divRef is defined before creating GroupTree const [isMounted, setIsMounted] = React.useState(false); + // Remove when typescript version is implemented using ref const [prevId, setPrevId] = React.useState(null); + const [prevDatedTrees, setPrevDatedTrees] = React.useState(null); - const [prevSelectedEdgeName, setPrevSelectedEdgeName] = - React.useState(props.selectedEdgeName); - const [prevSelectedNodeName, setPrevSelectedNodeName] = - React.useState(props.selectedNodeName); + const [prevSelectedEdgeKey, setPrevSelectedEdgeKey] = + React.useState(props.selectedEdgeKey); + const [prevSelectedNodeKey, setPrevSelectedNodeKey] = + React.useState(props.selectedNodeKey); const [prevSelectedDateTime, setPrevSelectedDateTime] = React.useState(props.selectedDateTime); @@ -46,27 +49,27 @@ export const GroupTreePlot: React.FC = ( setPrevId(props.id); groupTreeRef.current = new GroupTree( props.id, - cloneDeep(props.datedTrees), - props.selectedEdgeName, - props.selectedNodeName, + props.datedTrees, + props.selectedEdgeKey, + props.selectedNodeKey, props.selectedDateTime, - props.edgeInfoList, - props.nodeInfoList + props.edgeMetadataList, + props.nodeMetadataList ); } - if (prevSelectedEdgeName !== props.selectedEdgeName) { - setPrevSelectedEdgeName(props.selectedEdgeName); + if (prevSelectedEdgeKey !== props.selectedEdgeKey) { + setPrevSelectedEdgeKey(props.selectedEdgeKey); if (!groupTreeRef.current) return; - groupTreeRef.current.flowrate = props.selectedEdgeName; + groupTreeRef.current.flowrate = props.selectedEdgeKey; } - if (prevSelectedNodeName !== props.selectedNodeName) { - setPrevSelectedNodeName(props.selectedNodeName); + if (prevSelectedNodeKey !== props.selectedNodeKey) { + setPrevSelectedNodeKey(props.selectedNodeKey); if (!groupTreeRef.current) return; - groupTreeRef.current.nodeinfo = props.selectedNodeName; + groupTreeRef.current.nodeinfo = props.selectedNodeKey; } if (prevSelectedDateTime !== props.selectedDateTime) { diff --git a/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts b/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts index 9ec4e5e26..db57df294 100644 --- a/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts +++ b/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts @@ -1,24 +1,40 @@ -export type NameLabelAndUnit = { - name: string; // key? - label: string; // Displayed name - unit?: string; // Optional unit -}; +// Node key and values map +export interface NodeData { + [key: string]: number[]; +} +// Node key and metadata +export interface NodeMetadata { + key: string; + label: string; + unit?: string; +} -export type EdgeInfo = NameLabelAndUnit; -export type NodeInfo = NameLabelAndUnit; +// Edge key and values map +export interface EdgeData { + [key: string]: number[]; +} +// Edge key and metadata +export interface EdgeMetadata { + key: string; + label: string; + unit?: string; +} -export interface Node { - nodeType: "Group" | "Well"; - nodeLabel: string; - edgeLabel: string; - // nodeOption: NodeOption; - // edgeOption: EdgeOption; - children: Node[]; +// Recursively defined tree node +export interface RecursiveTreeNode { + node_type: "Group" | "Well"; + node_label: string; + edge_label: string; + node_data: NodeData; + edge_data: EdgeData; + children: RecursiveTreeNode[]; } +// Collection of trees with a dates export interface DatedTree { dates: [string]; - tree: Node; + tree: RecursiveTreeNode; } +// List of dated trees export type DatedTrees = DatedTree[]; diff --git a/typescript/packages/group-tree/src/storybook/GroupTreeComponent.stories.tsx b/typescript/packages/group-tree/src/storybook/GroupTreeComponent.stories.tsx index d9934931e..9871b40e5 100644 --- a/typescript/packages/group-tree/src/storybook/GroupTreeComponent.stories.tsx +++ b/typescript/packages/group-tree/src/storybook/GroupTreeComponent.stories.tsx @@ -1,22 +1,28 @@ import React from "react"; import GroupTreeComponent from "../components/GroupTreeComponent"; +import { + EdgeMetadata, + NodeMetadata, +} from "../components/group-tree-plot/src/types"; + export default { component: GroupTreeComponent, title: "GroupTree", }; -const edge_options = [ - { name: "waterrate", label: "Water Rate", unit: "m3/s" }, - { name: "oilrate", label: "Oil Rate", unit: "m3/s" }, - { name: "gasrate", label: "Gas Rate", unit: "m3/s" }, - { name: "waterinjrate", label: "Water Injection Rate", unit: "m3/s" }, - { name: "gasinjrate", label: "Gas Injection Rate", unit: "m3/s" }, +const edgeMetadataList: EdgeMetadata[] = [ + { key: "waterrate", label: "Water Rate", unit: "m3/s" }, + { key: "oilrate", label: "Oil Rate", unit: "m3/s" }, + { key: "gasrate", label: "Gas Rate", unit: "m3/s" }, + { key: "waterinjrate", label: "Water Injection Rate", unit: "m3/s" }, + { key: "gasinjrate", label: "Gas Injection Rate", unit: "m3/s" }, ]; -const node_options = [ - { name: "pressure", label: "Pressure", unit: "Bar" }, - { name: "bhp", label: "Bottom Hole Pressure", unit: "N/m2" }, +const nodeMetadataList: NodeMetadata[] = [ + { key: "pressure", label: "Pressure", unit: "Bar" }, + { key: "bhp", label: "Bottom Hole Pressure", unit: "N/m2" }, + { key: "wmctl", label: "Missing label" }, ]; const Template = (args) => { @@ -27,6 +33,6 @@ export const Default = Template.bind({}); Default.args = { id: "grouptree", data: require("../../../../../example-data/group-tree.json"), - edgeOptions: edge_options, - nodeOptions: node_options, + edgeMetadataList: edgeMetadataList, + nodeMetadataList: nodeMetadataList, }; diff --git a/typescript/packages/group-tree/src/storybook/components/DateTimeSlider.stories.tsx b/typescript/packages/group-tree/src/storybook/components/DateTimeSlider.stories.tsx index 219ae5391..6ab291962 100644 --- a/typescript/packages/group-tree/src/storybook/components/DateTimeSlider.stories.tsx +++ b/typescript/packages/group-tree/src/storybook/components/DateTimeSlider.stories.tsx @@ -18,7 +18,13 @@ export default { const Template = (args) => { return ( - + ); diff --git a/typescript/packages/group-tree/src/storybook/components/FlowRateSelector.stories.tsx b/typescript/packages/group-tree/src/storybook/components/FlowRateSelector.stories.tsx index 74e7fe0b6..b84af2042 100644 --- a/typescript/packages/group-tree/src/storybook/components/FlowRateSelector.stories.tsx +++ b/typescript/packages/group-tree/src/storybook/components/FlowRateSelector.stories.tsx @@ -2,17 +2,19 @@ import React from "react"; import DataProvider from "../../components/DataLoader"; import FlowRateSelector from "../../components/Settings/FlowRateSelector"; -const edge_options = [ - { name: "waterrate", label: "Water Rate" }, - { name: "oilrate", label: "Oil Rate" }, - { name: "gasrate", label: "Gas Rate" }, - { name: "waterinjrate", label: "Water Injection Rate" }, - { name: "gasinjrate", label: "Gas Injection Rate" }, +import { EdgeMetadata } from "../../components/group-tree-plot/src/types"; + +const edgeMetadataList: EdgeMetadata[] = [ + { key: "waterrate", label: "Water Rate" }, + { key: "oilrate", label: "Oil Rate" }, + { key: "gasrate", label: "Gas Rate" }, + { key: "waterinjrate", label: "Water Injection Rate" }, + { key: "gasinjrate", label: "Gas Injection Rate" }, ]; export default { component: FlowRateSelector, - title: "GroupTree/Components/Settings/FLowRateSelector", + title: "GroupTree/Components/Settings/FlowRateSelector", argTypes: { id: { description: @@ -26,8 +28,14 @@ export default { const Template = (args) => { return ( - - + + ); }; @@ -36,5 +44,5 @@ export const Default = Template.bind({}); Default.args = { id: "grouptree", data: require("../../../../../../example-data/group-tree.json"), - edge_options, + edgeMetadataList, }; diff --git a/typescript/packages/group-tree/src/storybook/components/GroupTreeViewer.stories.tsx b/typescript/packages/group-tree/src/storybook/components/GroupTreeViewer.stories.tsx index f513e377d..fb5de4544 100644 --- a/typescript/packages/group-tree/src/storybook/components/GroupTreeViewer.stories.tsx +++ b/typescript/packages/group-tree/src/storybook/components/GroupTreeViewer.stories.tsx @@ -2,17 +2,22 @@ import React from "react"; import DataProvider from "../../components/DataLoader"; import GroupTreeViewer from "../../components/GroupTreeViewer"; -const edge_options = [ - { name: "waterrate", label: "Water Rate" }, - { name: "oilrate", label: "Oil Rate" }, - { name: "gasrate", label: "Gas Rate" }, - { name: "waterinjrate", label: "Water Injection Rate" }, - { name: "gasinjrate", label: "Gas Injection Rate" }, +import { + EdgeMetadata, + NodeMetadata, +} from "../../components/group-tree-plot/src/types"; + +const edgeMetadataList: EdgeMetadata[] = [ + { key: "waterrate", label: "Water Rate" }, + { key: "oilrate", label: "Oil Rate" }, + { key: "gasrate", label: "Gas Rate" }, + { key: "waterinjrate", label: "Water Injection Rate" }, + { key: "gasinjrate", label: "Gas Injection Rate" }, ]; -const node_options = [ - { name: "pressure", label: "Pressure" }, - { name: "bhp", label: "Bottom Hole Pressure" }, +const nodeMetadataList: NodeMetadata[] = [ + { key: "pressure", label: "Pressure" }, + { key: "bhp", label: "Bottom Hole Pressure" }, ]; export default { @@ -31,11 +36,18 @@ export default { const Template = (args) => { return ( - + {}} /> ); @@ -45,6 +57,6 @@ export const Default = Template.bind({}); Default.args = { id: "grouptree", data: require("../../../../../../example-data/group-tree.json"), - edge_options, - node_options, + edgeMetadataList, + nodeMetadataList, }; diff --git a/typescript/packages/group-tree/src/storybook/components/SettingsBar.stories.tsx b/typescript/packages/group-tree/src/storybook/components/SettingsBar.stories.tsx index b9100180d..95cd33e8c 100644 --- a/typescript/packages/group-tree/src/storybook/components/SettingsBar.stories.tsx +++ b/typescript/packages/group-tree/src/storybook/components/SettingsBar.stories.tsx @@ -2,17 +2,22 @@ import React from "react"; import DataProvider from "../../components/DataLoader"; import SettingsBar from "../../components/Settings/SettingsBar"; -const edge_options = [ - { name: "waterrate", label: "Water Rate" }, - { name: "oilrate", label: "Oil Rate" }, - { name: "gasrate", label: "Gas Rate" }, - { name: "waterinjrate", label: "Water Injection Rate" }, - { name: "gasinjrate", label: "Gas Injection Rate" }, +import { + EdgeMetadata, + NodeMetadata, +} from "../../components/group-tree-plot/src/types"; + +const edgeMetadataList: EdgeMetadata[] = [ + { key: "waterrate", label: "Water Rate" }, + { key: "oilrate", label: "Oil Rate" }, + { key: "gasrate", label: "Gas Rate" }, + { key: "waterinjrate", label: "Water Injection Rate" }, + { key: "gasinjrate", label: "Gas Injection Rate" }, ]; -const node_options = [ - { name: "pressure", label: "Pressure" }, - { name: "bhp", label: "Bottom Hole Pressure" }, +const nodeMetadataList: NodeMetadata[] = [ + { key: "pressure", label: "Pressure" }, + { key: "bhp", label: "Bottom Hole Pressure" }, ]; export default { @@ -31,10 +36,16 @@ export default { const Template = (args) => { return ( - + ); @@ -44,6 +55,6 @@ export const Default = Template.bind({}); Default.args = { id: "grouptree", data: require("../../../../../../example-data/group-tree.json"), - edge_options, - node_options, + edgeMetadataList, + nodeMetadataList, }; From ef90e96ae9fd9e3b0386c5e7ec703d363587557e Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Fri, 24 Nov 2023 15:03:41 +0100 Subject: [PATCH 03/20] Update types --- .../src/components/group-tree-plot/src/types.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts b/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts index db57df294..e91f965c2 100644 --- a/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts +++ b/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts @@ -1,4 +1,4 @@ -// Node key and values map +// Node key and values map - one value per date in DatedTree export interface NodeData { [key: string]: number[]; } @@ -9,7 +9,7 @@ export interface NodeMetadata { unit?: string; } -// Edge key and values map +// Edge key and values map - value per date in DatedTree export interface EdgeData { [key: string]: number[]; } @@ -27,12 +27,12 @@ export interface RecursiveTreeNode { edge_label: string; node_data: NodeData; edge_data: EdgeData; - children: RecursiveTreeNode[]; + children?: RecursiveTreeNode[]; } // Collection of trees with a dates export interface DatedTree { - dates: [string]; + dates: string[]; tree: RecursiveTreeNode; } From 42f1f47cd5c78bca2bb089958e6f42e5cab2f53b Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Mon, 27 Nov 2023 12:05:59 +0100 Subject: [PATCH 04/20] Backup of moving files --- .../packages/group-tree-plot/jest.config.js | 7 + .../packages/group-tree-plot/package.json | 34 +++ .../packages/group-tree-plot/project.json | 7 + .../groupTreeAssembler.d.ts | 60 ++++++ .../GroupTreeAssembler/groupTreeAssembler.js} | 53 +++-- .../src/GroupTreeAssembler/group_tree.css | 59 +++++ .../group-tree-plot/src/GroupTreePlot.tsx | 21 +- .../packages/group-tree-plot/src/index.ts | 13 ++ .../group-tree-plot/src/types.ts | 0 .../packages/group-tree-plot/tsconfig.json | 14 ++ .../group-tree/src/components/DataLoader.tsx | 22 +- .../src/components/GroupTreeComponent.tsx | 2 +- .../src/components/GroupTreeViewer.tsx | 8 +- .../components/Settings/DateTimeSlider.tsx | 4 +- .../components/Settings/FlowRateSelector.tsx | 2 +- .../components/Settings/NodeInfoSelector.tsx | 4 +- .../src/components/Settings/SettingsBar.tsx | 5 +- .../components/Settings/date_time_slider.css | 30 +++ .../group-tree-plot/src/Plot/dynamic_tree.css | 201 ------------------ .../storybook/GroupTreeComponent.stories.tsx | 5 +- .../components/FlowRateSelector.stories.tsx | 2 +- .../components/GroupTreeViewer.stories.tsx | 2 +- .../components/SettingsBar.stories.tsx | 2 +- typescript/packages/group-tree/tsconfig.json | 2 +- 24 files changed, 296 insertions(+), 263 deletions(-) create mode 100644 typescript/packages/group-tree-plot/jest.config.js create mode 100644 typescript/packages/group-tree-plot/package.json create mode 100644 typescript/packages/group-tree-plot/project.json create mode 100644 typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.d.ts rename typescript/packages/{group-tree/src/components/group-tree-plot/src/Plot/group_tree.js => group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js} (92%) create mode 100644 typescript/packages/group-tree-plot/src/GroupTreeAssembler/group_tree.css rename typescript/packages/{group-tree/src/components => }/group-tree-plot/src/GroupTreePlot.tsx (77%) create mode 100644 typescript/packages/group-tree-plot/src/index.ts rename typescript/packages/{group-tree/src/components => }/group-tree-plot/src/types.ts (100%) create mode 100644 typescript/packages/group-tree-plot/tsconfig.json create mode 100644 typescript/packages/group-tree/src/components/Settings/date_time_slider.css delete mode 100644 typescript/packages/group-tree/src/components/group-tree-plot/src/Plot/dynamic_tree.css diff --git a/typescript/packages/group-tree-plot/jest.config.js b/typescript/packages/group-tree-plot/jest.config.js new file mode 100644 index 000000000..52c5e0f33 --- /dev/null +++ b/typescript/packages/group-tree-plot/jest.config.js @@ -0,0 +1,7 @@ +/** @type {import('jest').Config} */ + +const config = { + preset: "../../jest.config.js", +}; + +module.exports = config; diff --git a/typescript/packages/group-tree-plot/package.json b/typescript/packages/group-tree-plot/package.json new file mode 100644 index 000000000..e9e19e82b --- /dev/null +++ b/typescript/packages/group-tree-plot/package.json @@ -0,0 +1,34 @@ +{ + "name": "@webviz/group-tree-plot", + "version": "0.0.1", + "description": "", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "/dist" + ], + "scripts": { + "transpile": "tsc --project ./tsconfig.json", + "copy-files": "copyfiles --up 1 \"src/**/*.css\" dist/", + "build": "git clean -xdff dist && npm run transpile && npm run copy-files", + "test_perf": "jest _performance", + "test_correctness": "jest --coverage --testPathIgnorePatterns='_performance'", + "test": "jest --coverage", + "test:update": "npm test -- --u", + "test:watch": "npm test -- --watch", + "doc": "git clean -xdff docs && typedoc src" + }, + "author": "Equinor ", + "license": "MPL-2.0", + "dependencies": { + "d3": "^7.8.2", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": "^17 || ^18", + "react-dom": "^17 || ^18" + }, + "volta": { + "node": "18.17.0" + } +} diff --git a/typescript/packages/group-tree-plot/project.json b/typescript/packages/group-tree-plot/project.json new file mode 100644 index 000000000..b882678be --- /dev/null +++ b/typescript/packages/group-tree-plot/project.json @@ -0,0 +1,7 @@ +{ + "targets": { + "semantic-release": { + "executor": "@theunderscorer/nx-semantic-release:semantic-release" + } + } +} diff --git a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.d.ts b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.d.ts new file mode 100644 index 000000000..71263bbed --- /dev/null +++ b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.d.ts @@ -0,0 +1,60 @@ +/** + * Class to assemble Group tree visualization. Creates an _svg, and appends to the + * assigned HTML element. Draws the tree provided as tree_data with the current flow rate, + * node info and date time. + * + * Provides methods to update selected date time, and change flow rate and node info. * + */ +export default class GroupTreeAssembler { + /** + * Initialize all trees in the group tree datastructure, once for the entire visualization. + * + */ + static initHierarchies(tree_data: any, height: any): any; + /** + * + * @param dom_element_id - id of the HTML element to append the _svg to + * @param {DatedTrees} datedTrees - List of dated tree data structure containing the trees to visualize + * @param initialFlowRate - key identifying the initial selected flow rate for the tree edges + * @param initialNodeInfo - key identifying the initial selected node info for the tree nodes + * @param currentDateTime - the initial/current date time + * @param edgeMetadataList - List of metadata for the edge keys in the tree data structure + * @param nodeMetadataList - List of metadata for the node keys in the tree data structure + */ + constructor(dom_element_id: any, datedTrees: DatedTrees, initialFlowRate: any, initialNodeInfo: any, currentDateTime: any, edgeMetadataList: any, nodeMetadataList: any); + _propertyToLabelMap: Map; + _currentFlowRate: any; + _currentNodeInfo: any; + _currentDateTime: any; + _transitionTime: number; + _path_scale: Map; + _width: number; + _svg: d3.Selection; + _textpaths: d3.Selection; + _renderTree: d3.TreeLayout; + _data: any; + _currentTree: {}; + /** + * @returns {*} -The initialized hierarchical group tree data structure + */ + get data(): any; + /** + * Set the flowrate and update display of all edges accordingly. + * + * @param flowrate - key identifying the flowrate of the incoming edge + */ + set flowrate(arg: any); + get flowrate(): any; + set nodeinfo(arg: any); + get nodeinfo(): any; + getEdgeStrokeWidth(key: any, val: any): string; + /** + * Sets the state of the current tree, and updates the tree visualization accordingly. + * The state is changed either due to a branch open/close, or that the tree is entirely changed + * when moving back and fourth in time. + * + * @param root + */ + update(newDateTime: any): void; +} +import * as d3 from "d3"; diff --git a/typescript/packages/group-tree/src/components/group-tree-plot/src/Plot/group_tree.js b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js similarity index 92% rename from typescript/packages/group-tree/src/components/group-tree-plot/src/Plot/group_tree.js rename to typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js index 837e3237b..0cd29d37e 100644 --- a/typescript/packages/group-tree/src/components/group-tree-plot/src/Plot/group_tree.js +++ b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js @@ -5,6 +5,8 @@ * 9 july 2021: refactored to use new format. */ import * as d3 from "d3"; +import "./Plot/group_tree.css"; + /* eslint camelcase: "off" */ /* eslint array-callback-return: "off" */ /* eslint no-return-assign: "off" */ @@ -13,26 +15,31 @@ import * as d3 from "d3"; /* Fix this lint when rewriting the whole file */ /** - * Group tree visualization. Creates an _svg, and appends to the assigned element. - * Draws the tree provided as tree_data - - * @constructor + * Class to assemble Group tree visualization. Creates an _svg, and appends to the + * assigned HTML element. Draws the tree provided as tree_data with the current flow rate, + * node info and date time. + * + * Provides methods to update selected date time, and change flow rate and node info. * */ -export default class GroupTree { +export default class GroupTreeAssembler { /** * - * @param dom_element_id - * @param {group-tree-data} tree_data - * @param defaultFlowrate + * @param dom_element_id - id of the HTML element to append the _svg to + * @param {DatedTrees} datedTrees - List of dated tree data structure containing the trees to visualize + * @param initialFlowRate - key identifying the initial selected flow rate for the tree edges + * @param initialNodeInfo - key identifying the initial selected node info for the tree nodes + * @param currentDateTime - the initial/current date time + * @param edgeMetadataList - List of metadata for the edge keys in the tree data structure + * @param nodeMetadataList - List of metadata for the node keys in the tree data structure */ constructor( dom_element_id, - tree_data, - defaultFlowrate, - defaultNodeInfo, + datedTrees, + initialFlowRate, + initialNodeInfo, currentDateTime, - edge_options, - node_options + edgeMetadataList, + nodeMetadataList ) { // Add "#" if missing. if (dom_element_id.charAt(0) !== "#") { @@ -40,9 +47,9 @@ export default class GroupTree { } // Map from property to [label/name, unit] - const options = [...edge_options, ...node_options]; + const metadataList = [...edgeMetadataList, ...nodeMetadataList]; this._propertyToLabelMap = new Map(); - options.forEach((key) => { + metadataList.forEach((key) => { this._propertyToLabelMap.set(key.name, [ key.label ?? "", key.unit ?? "", @@ -50,9 +57,9 @@ export default class GroupTree { }); // Represent possible empty data by single empty node. - if (tree_data.length === 0) { + if (datedTrees.length === 0) { currentDateTime = ""; - tree_data = [ + datedTrees = [ { dates: [currentDateTime], tree: { @@ -65,15 +72,15 @@ export default class GroupTree { ]; } - this._currentFlowrate = defaultFlowrate; - this._currentNodeInfo = defaultNodeInfo; + this._currentFlowRate = initialFlowRate; + this._currentNodeInfo = initialNodeInfo; this._currentDateTime = currentDateTime; this._transitionTime = 200; const tree_values = {}; - tree_data.map((datedTree) => { + datedTrees.map((datedTree) => { let tree = datedTree.tree; d3.hierarchy(tree, (d) => d.children).each((node) => { // edge_data @@ -123,7 +130,7 @@ export default class GroupTree { this._renderTree = d3.tree().size([height, this._width]); - this._data = GroupTree.initHierarchies(tree_data, height); + this._data = GroupTreeAssembler.initHierarchies(datedTrees, height); this._currentTree = {}; @@ -166,7 +173,7 @@ export default class GroupTree { * @param flowrate - key identifying the flowrate of the incoming edge */ set flowrate(flowrate) { - this._currentFlowrate = flowrate; + this._currentFlowRate = flowrate; const current_tree_index = this._data.findIndex((e) => { return e.dates.includes(this._currentDateTime); @@ -198,7 +205,7 @@ export default class GroupTree { } get flowrate() { - return this._currentFlowrate; + return this._currentFlowRate; } set nodeinfo(nodeinfo) { diff --git a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/group_tree.css b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/group_tree.css new file mode 100644 index 000000000..68b74425d --- /dev/null +++ b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/group_tree.css @@ -0,0 +1,59 @@ +.link { + fill: none; + stroke: #5c5c5c; + opacity: 1; +} + +.grouptree_link { + opacity: 0.3; +} + +.grouptree_link__oilrate { + stroke: #60be6c; +} + +.grouptree_link__waterrate { + stroke: #0d1b9e; +} + +.grouptree_link__gasrate { + stroke: #c5221c; +} + +.grouptree_link__waterinjrate { + stroke: #00c3ff; +} + +.grouptree_link__gasinjrate { + stroke: #d6397a; +} + +.grouptree__node { + fill: #fff; + stroke: #60be6c; + stroke-width: 1px; + cursor: default; +} + +.grouptree__nodelabel { + font-size: 10px; + font-family: sans-serif; +} + +.grouptree__pressurelabel { + font-size: 10px; + font-family: "Statoil Sans Light", Lucida, Arial, Helvetica, sans-serif; +} + +.grouptree__pressureunit { + font-size: 9px; +} + +.grouptree__grupnet_text { + font-size: 12px; +} + +.grouptree__node--withchildren { + stroke-width: 2.5px; + cursor: pointer; +} diff --git a/typescript/packages/group-tree/src/components/group-tree-plot/src/GroupTreePlot.tsx b/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx similarity index 77% rename from typescript/packages/group-tree/src/components/group-tree-plot/src/GroupTreePlot.tsx rename to typescript/packages/group-tree-plot/src/GroupTreePlot.tsx index 3380a8196..458610917 100644 --- a/typescript/packages/group-tree/src/components/group-tree-plot/src/GroupTreePlot.tsx +++ b/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx @@ -1,10 +1,10 @@ import React from "react"; -import GroupTree from "./Plot/group_tree"; +import GroupTreeAssembler from "./GroupTreeAssembler/groupTreeAssembler"; import { DatedTrees, EdgeMetadata, NodeMetadata } from "./types"; import { isEqual } from "lodash"; -interface GroupTreePlotProps { +export interface GroupTreePlotProps { id: string; edgeMetadataList: EdgeMetadata[]; nodeMetadataList: NodeMetadata[]; @@ -18,7 +18,7 @@ export const GroupTreePlot: React.FC = ( props: GroupTreePlotProps ) => { const divRef = React.useRef(null); - const groupTreeRef = React.useRef(); + const groupTreeAssemblerRef = React.useRef(); // State to ensure divRef is defined before creating GroupTree const [isMounted, setIsMounted] = React.useState(false); @@ -42,12 +42,11 @@ export const GroupTreePlot: React.FC = ( if ( isMounted && - // divRef.current && (!isEqual(prevDatedTrees, props.datedTrees) || prevId !== props.id) ) { setPrevDatedTrees(props.datedTrees); setPrevId(props.id); - groupTreeRef.current = new GroupTree( + groupTreeAssemblerRef.current = new GroupTreeAssembler( props.id, props.datedTrees, props.selectedEdgeKey, @@ -60,23 +59,23 @@ export const GroupTreePlot: React.FC = ( if (prevSelectedEdgeKey !== props.selectedEdgeKey) { setPrevSelectedEdgeKey(props.selectedEdgeKey); - if (!groupTreeRef.current) return; + if (!groupTreeAssemblerRef.current) return; - groupTreeRef.current.flowrate = props.selectedEdgeKey; + groupTreeAssemblerRef.current.flowrate = props.selectedEdgeKey; } if (prevSelectedNodeKey !== props.selectedNodeKey) { setPrevSelectedNodeKey(props.selectedNodeKey); - if (!groupTreeRef.current) return; + if (!groupTreeAssemblerRef.current) return; - groupTreeRef.current.nodeinfo = props.selectedNodeKey; + groupTreeAssemblerRef.current.nodeinfo = props.selectedNodeKey; } if (prevSelectedDateTime !== props.selectedDateTime) { setPrevSelectedDateTime(props.selectedDateTime); - if (!groupTreeRef.current) return; + if (!groupTreeAssemblerRef.current) return; - groupTreeRef.current.update(props.selectedDateTime); + groupTreeAssemblerRef.current.update(props.selectedDateTime); } return
; diff --git a/typescript/packages/group-tree-plot/src/index.ts b/typescript/packages/group-tree-plot/src/index.ts new file mode 100644 index 000000000..8dcffcbf8 --- /dev/null +++ b/typescript/packages/group-tree-plot/src/index.ts @@ -0,0 +1,13 @@ +export { GroupTreePlot } from "./GroupTreePlot"; + +// Export types +export type { GroupTreePlotProps } from "./GroupTreePlot"; +export type { + NodeData, + NodeMetadata, + EdgeData, + EdgeMetadata, + RecursiveTreeNode, + DatedTree, + DatedTrees, +} from "./types"; diff --git a/typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts b/typescript/packages/group-tree-plot/src/types.ts similarity index 100% rename from typescript/packages/group-tree/src/components/group-tree-plot/src/types.ts rename to typescript/packages/group-tree-plot/src/types.ts diff --git a/typescript/packages/group-tree-plot/tsconfig.json b/typescript/packages/group-tree-plot/tsconfig.json new file mode 100644 index 000000000..609cb7acb --- /dev/null +++ b/typescript/packages/group-tree-plot/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/"], + "exclude": [ + "src/test", + "./**/*.test.tsx", + "./**/*.stories.tsx", + "./**/*.stories.jsx" + ] +} diff --git a/typescript/packages/group-tree/src/components/DataLoader.tsx b/typescript/packages/group-tree/src/components/DataLoader.tsx index 99a6a59cc..17d048e4c 100644 --- a/typescript/packages/group-tree/src/components/DataLoader.tsx +++ b/typescript/packages/group-tree/src/components/DataLoader.tsx @@ -9,7 +9,7 @@ import type { DatedTrees, EdgeMetadata, NodeMetadata, -} from "./group-tree-plot/src/types"; +} from "../../../group-tree-plot/src/types"; export type DateTreesIndices = { treeIndex: number; @@ -41,17 +41,17 @@ const DataProvider: React.FC = ( ? props.data[treeIdx].dates[dateIdx] : props.data[0].dates[0]; - // const initialFlowRate = props.edgeMetadataList[0]?.key ?? ""; - // const initialNodeInfo = props.nodeMetadataList[0]?.key ?? ""; - const initialFlowRate = - props.edgeMetadataList?.length > 0 - ? props.edgeMetadataList[0].key - : ""; + const initialFlowRate = props.edgeMetadataList[0]?.key ?? ""; + const initialNodeInfo = props.nodeMetadataList[0]?.key ?? ""; + // const initialFlowRate = + // props.edgeMetadataList?.length > 0 + // ? props.edgeMetadataList[0].key + // : ""; - const initialNodeInfo = - props.nodeMetadataList?.length > 0 - ? props.nodeMetadataList[0].key - : ""; + // const initialNodeInfo = + // props.nodeMetadataList?.length > 0 + // ? props.nodeMetadataList[0].key + // : ""; return { id: props.id, diff --git a/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx b/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx index 47a00fb29..4e9aac6bc 100644 --- a/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx +++ b/typescript/packages/group-tree/src/components/GroupTreeComponent.tsx @@ -6,7 +6,7 @@ import { DatedTrees, EdgeMetadata, NodeMetadata, -} from "./group-tree-plot/src/types"; +} from "../../../group-tree-plot/src/types"; //TODO schema check export interface GroupTreeProps { diff --git a/typescript/packages/group-tree/src/components/GroupTreeViewer.tsx b/typescript/packages/group-tree/src/components/GroupTreeViewer.tsx index a3d6e5e3b..21c689fd7 100644 --- a/typescript/packages/group-tree/src/components/GroupTreeViewer.tsx +++ b/typescript/packages/group-tree/src/components/GroupTreeViewer.tsx @@ -5,10 +5,12 @@ import React, { useContext, useEffect } from "react"; import { useSelector } from "react-redux"; import type { GroupTreeState } from "../redux/store"; import { DataContext } from "./DataLoader"; -import "./group-tree-plot/src/Plot/dynamic_tree.css"; import SettingsBar from "./Settings/SettingsBar"; -import { GroupTreePlot } from "./group-tree-plot/src/GroupTreePlot"; -import { EdgeMetadata, NodeMetadata } from "./group-tree-plot/src/types"; +// import { GroupTreePlot } from "../../../group-tree-plot/src/GroupTreePlot"; +import { EdgeMetadata, NodeMetadata } from "../../../group-tree-plot/src/types"; + +import { GroupTreePlot } from "../../../group-tree-plot/src/GroupTreePlot"; +import "./Settings/components_styles.css"; const PREFIX = "GroupTreeViewer"; diff --git a/typescript/packages/group-tree/src/components/Settings/DateTimeSlider.tsx b/typescript/packages/group-tree/src/components/Settings/DateTimeSlider.tsx index 5da83f330..9370a3d7f 100644 --- a/typescript/packages/group-tree/src/components/Settings/DateTimeSlider.tsx +++ b/typescript/packages/group-tree/src/components/Settings/DateTimeSlider.tsx @@ -6,7 +6,9 @@ import { updateCurrentDateTime } from "../../redux/actions"; import type { GroupTreeState } from "../../redux/store"; import { DataContext } from "../DataLoader"; -import { DatedTree, DatedTrees } from "../group-tree-plot/src/types"; +import { DatedTree, DatedTrees } from "../../../../group-tree-plot/src/types"; + +import "./date_time_slider.css"; const classes = { root: "DateTimeSlider-root", diff --git a/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx b/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx index f8b28f4fc..0e2dc28a5 100644 --- a/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx +++ b/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx @@ -4,7 +4,7 @@ import React, { useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { updateCurrentFlowRate } from "../../redux/actions"; import type { GroupTreeState } from "../../redux/store"; -import { EdgeMetadata } from "../group-tree-plot/src/types"; +import { EdgeMetadata } from "../../../../group-tree-plot/src/types"; const PREFIX = "FlowRateSelector"; diff --git a/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx b/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx index feeac74b6..6cc14f8cf 100644 --- a/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx +++ b/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx @@ -4,7 +4,7 @@ import React, { useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { updateCurrentNodeInfo } from "../../redux/actions"; import type { GroupTreeState } from "../../redux/store"; -import { NodeMetadata } from "../group-tree-plot/src/types"; +import { NodeMetadata } from "../../../../group-tree-plot/src/types"; const PREFIX = "NodeInfoSelector"; @@ -32,7 +32,7 @@ const NodeInfoSelector: React.FC = React.memo( ); // handlers const handleSelectedItemChange = useCallback( - (event: { target: { value: unknown } }) => { + (event: React.ChangeEvent) => { dispatch(updateCurrentNodeInfo(event.target.value as string)); }, [dispatch] diff --git a/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx b/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx index 55b524aaf..b698c740e 100644 --- a/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx +++ b/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx @@ -4,7 +4,10 @@ import React from "react"; import DateTimeSlider from "./DateTimeSlider"; import FlowRateSelector from "./FlowRateSelector"; import NodeInfoSelector from "./NodeInfoSelector"; -import { EdgeMetadata, NodeMetadata } from "../group-tree-plot/src/types"; +import { + EdgeMetadata, + NodeMetadata, +} from "../../../../group-tree-plot/src/types"; const PREFIX = "SettingsBar"; diff --git a/typescript/packages/group-tree/src/components/Settings/date_time_slider.css b/typescript/packages/group-tree/src/components/Settings/date_time_slider.css new file mode 100644 index 000000000..05c5d65e2 --- /dev/null +++ b/typescript/packages/group-tree/src/components/Settings/date_time_slider.css @@ -0,0 +1,30 @@ +/* +This css is to override default slider css styling for the date time slider +*/ + +.slider, +.slider-inset, +.slider-overlay { + stroke-linecap: round; +} + +.slider { + stroke-width: 8px; +} + +.slider-inset { + stroke: #b20276; + stroke-width: 8px; +} + +.slider-overlay { + pointer-events: stroke; + cursor: pointer; +} + +.handle { + fill: #fff; + stroke: #b20276; + stroke-opacity: 0.5; + stroke-width: 1.25px; +} diff --git a/typescript/packages/group-tree/src/components/group-tree-plot/src/Plot/dynamic_tree.css b/typescript/packages/group-tree/src/components/group-tree-plot/src/Plot/dynamic_tree.css deleted file mode 100644 index eb7274026..000000000 --- a/typescript/packages/group-tree/src/components/group-tree-plot/src/Plot/dynamic_tree.css +++ /dev/null @@ -1,201 +0,0 @@ -.slider, -.slider-inset, -.slider-overlay { - stroke-linecap: round; -} - -.slider { - stroke-width: 8px; -} - -.slider-inset { - stroke: #b20276; - stroke-width: 8px; -} - -.slider-overlay { - pointer-events: stroke; - cursor: pointer; -} - -.handle { - fill: #fff; - stroke: #b20276; - stroke-opacity: 0.5; - stroke-width: 1.25px; -} - -#sensitivity-slider-plot { - position: relative; -} - -.sensitivity-slider-plot__graph-area { - fill: steelblue; - fill-opacity: 0.4 -} - -.sensitivity-slider-plot__graph-line { - stroke: steelblue; - stroke-width: 1; - fill: none -} - -.sensitivity-slider-plot__graph-overlay { - fill: none; - pointer-events: all; -} - -.sensitivity-slider-plot__graph-container { - background-color: white; - z-index: 1; -} - -.sensitivity-slider-plot__slider-container { - background-color: white; - padding: 0; -} - -.sensitivity-slider-plot__graph-focus-circle { - fill: none; - stroke: black; - r: 4.5 -} - -.sensitivity-slider-plot__graph-focus-line { - fill: none; - stroke: black; - stroke-width: 1.5px; - stroke-dasharray: 3 3; -} - -.sensitivity-slider-plot__graph-focus-text { - /*x: 9px;*/ - /*dy: -0.35em;*/ - font-size: 12px; -} - -.sensitivity-slider-plot__slider-cell { - fill: none; -} - -.sensitivity-slider-plot__slider-col-header { - /*fill: none;*/ -} - -.sensitivity-slider-plot__slider-row-header { - /*fill: none;*/ -} - -.sensitivity-slider-plot__slider-col-header-label { - text-anchor: middle; - alignment-baseline: hanging; - font-size: 30px; - fill: black; -} - -.sensitivity-slider-plot__slider-row-header-label { - text-anchor: end; - alignment-baseline: central; - font-size: 10px; - fill: black; -} - -.sensitivity-slider-plot__slide-bar-label { - text-anchor: end; - alignment-baseline: central; - font-size: 12px; - fill: black; -} - -.sensitivity-slider-plot__slider-bar-background { - fill: grey; - stroke: black; - stroke-width: 0.5px; - rx: 4; - ry: 4; -} - -.sensitivity-slider-plot__slider-bar-main { - fill: rgb(210, 15, 140); - stroke: black; - stroke-width: 0.5px; - rx: 4; - ry: 4; -} - -.sensitivity-slider-plot__slider-bar-interaction { - fill: rgb(250, 150, 0); - stroke: black; - stroke-width: 0.5px; - rx: 4; - ry: 4; -} - -.affix { - top: 0; -} - -.sensitivity-slider-plot__description.mfp-wrap { - z-index: initial; -} - -.link { - fill: none; - stroke: #5c5c5c; - opacity: 1; -} - -.grouptree_link { - opacity: 0.3; -} - -.grouptree_link__oilrate { - stroke: #60be6c; -} - -.grouptree_link__waterrate { - stroke: #0d1b9e; -} - -.grouptree_link__gasrate { - stroke: #c5221c; -} - -.grouptree_link__waterinjrate { - stroke: #00c3ff; -} - -.grouptree_link__gasinjrate { - stroke: #d6397a; -} - -.grouptree__node { - fill: #fff; - stroke: #60be6c; - stroke-width: 1px; - cursor: default; -} - -.grouptree__nodelabel { - font-size: 10px; - font-family: sans-serif; -} - -.grouptree__pressurelabel { - font-size: 10px; - font-family: "Statoil Sans Light", Lucida, Arial, Helvetica, sans-serif; -} - -.grouptree__pressureunit{ - font-size: 9px; -} - -.grouptree__grupnet_text{ - font-size: 12px; -} - -.grouptree__node--withchildren { - stroke-width: 2.5px; - cursor: pointer; - -} diff --git a/typescript/packages/group-tree/src/storybook/GroupTreeComponent.stories.tsx b/typescript/packages/group-tree/src/storybook/GroupTreeComponent.stories.tsx index 9871b40e5..751c94691 100644 --- a/typescript/packages/group-tree/src/storybook/GroupTreeComponent.stories.tsx +++ b/typescript/packages/group-tree/src/storybook/GroupTreeComponent.stories.tsx @@ -1,10 +1,7 @@ import React from "react"; import GroupTreeComponent from "../components/GroupTreeComponent"; -import { - EdgeMetadata, - NodeMetadata, -} from "../components/group-tree-plot/src/types"; +import { EdgeMetadata, NodeMetadata } from "../../../group-tree-plot/src/types"; export default { component: GroupTreeComponent, diff --git a/typescript/packages/group-tree/src/storybook/components/FlowRateSelector.stories.tsx b/typescript/packages/group-tree/src/storybook/components/FlowRateSelector.stories.tsx index b84af2042..d990142db 100644 --- a/typescript/packages/group-tree/src/storybook/components/FlowRateSelector.stories.tsx +++ b/typescript/packages/group-tree/src/storybook/components/FlowRateSelector.stories.tsx @@ -2,7 +2,7 @@ import React from "react"; import DataProvider from "../../components/DataLoader"; import FlowRateSelector from "../../components/Settings/FlowRateSelector"; -import { EdgeMetadata } from "../../components/group-tree-plot/src/types"; +import { EdgeMetadata } from "../../../../group-tree-plot/src/types"; const edgeMetadataList: EdgeMetadata[] = [ { key: "waterrate", label: "Water Rate" }, diff --git a/typescript/packages/group-tree/src/storybook/components/GroupTreeViewer.stories.tsx b/typescript/packages/group-tree/src/storybook/components/GroupTreeViewer.stories.tsx index fb5de4544..dbf13a25d 100644 --- a/typescript/packages/group-tree/src/storybook/components/GroupTreeViewer.stories.tsx +++ b/typescript/packages/group-tree/src/storybook/components/GroupTreeViewer.stories.tsx @@ -5,7 +5,7 @@ import GroupTreeViewer from "../../components/GroupTreeViewer"; import { EdgeMetadata, NodeMetadata, -} from "../../components/group-tree-plot/src/types"; +} from "../../../../group-tree-plot/src/types"; const edgeMetadataList: EdgeMetadata[] = [ { key: "waterrate", label: "Water Rate" }, diff --git a/typescript/packages/group-tree/src/storybook/components/SettingsBar.stories.tsx b/typescript/packages/group-tree/src/storybook/components/SettingsBar.stories.tsx index 95cd33e8c..9662daa0d 100644 --- a/typescript/packages/group-tree/src/storybook/components/SettingsBar.stories.tsx +++ b/typescript/packages/group-tree/src/storybook/components/SettingsBar.stories.tsx @@ -5,7 +5,7 @@ import SettingsBar from "../../components/Settings/SettingsBar"; import { EdgeMetadata, NodeMetadata, -} from "../../components/group-tree-plot/src/types"; +} from "../../../../group-tree-plot/src/types"; const edgeMetadataList: EdgeMetadata[] = [ { key: "waterrate", label: "Water Rate" }, diff --git a/typescript/packages/group-tree/tsconfig.json b/typescript/packages/group-tree/tsconfig.json index 2dba43075..2dc7e60c2 100644 --- a/typescript/packages/group-tree/tsconfig.json +++ b/typescript/packages/group-tree/tsconfig.json @@ -4,7 +4,7 @@ "outDir": "./dist", "rootDir": "./src" }, - "include": ["src/"], + "include": ["src/", "../group-tree-plot"], "exclude": [ "src/storybook", "src/test", From 764f98bcdfd0a5fbe17a313fcd5ec792afeb5228 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Mon, 27 Nov 2023 15:22:51 +0100 Subject: [PATCH 05/20] Moved group-tree to python folder, have group-tree-plot as package Split group-tree and group-tree-plot. - Group-tree into python folder - Have group-tree-plot as a package --- python/package-lock.json | 34 ++++++++---- python/package.json | 2 +- python/src/components/GroupTree/GroupTree.jsx | 43 --------------- .../components/GroupTree}/GroupTree.test.tsx | 0 .../src/components/GroupTree}/GroupTree.tsx | 19 ++++--- .../GroupTree}/GroupTree_performance.test.tsx | 0 .../__snapshots__/GroupTree.test.tsx.snap | 0 .../GroupTree}/components/DataLoader.tsx | 2 +- .../components/GroupTreeComponent.test.tsx | 21 ++++--- .../components/GroupTreeComponent.tsx | 2 +- .../components/GroupTreeViewer.test.tsx | 18 +++--- .../GroupTree}/components/GroupTreeViewer.tsx | 9 +-- .../Settings/DateTimeSlider.test.tsx | 0 .../components/Settings/DateTimeSlider.tsx | 2 +- .../Settings/FlowRateSelector.test.tsx | 19 ++++--- .../components/Settings/FlowRateSelector.tsx | 2 +- .../Settings/NodeInfoSelector.test.tsx | 0 .../components/Settings/NodeInfoSelector.tsx | 2 +- .../components/Settings/SettingsBar.test.tsx | 37 +++++++++++++ .../components/Settings/SettingsBar.tsx | 5 +- .../DateTimeSlider.test.tsx.snap | 0 .../FlowRateSelector.test.tsx.snap | 0 .../NodeInfoSelector.test.tsx.snap | 0 .../__snapshots__/SettingsBar.test.tsx.snap | 0 .../components/Settings/date_time_slider.css | 0 .../GroupTreeComponent.test.tsx.snap | 0 .../GroupTreeViewer.test.tsx.snap | 0 python/src/components/GroupTree/index.ts | 1 + .../components/GroupTree}/redux/actions.ts | 0 .../components/GroupTree}/redux/reducer.ts | 0 .../src/components/GroupTree}/redux/store.ts | 0 .../src/components/GroupTree}/redux/types.ts | 0 .../storybook/GroupTreeComponent.stories.tsx | 2 +- .../components/DateTimeSlider.stories.tsx | 0 .../components/FlowRateSelector.stories.tsx | 2 +- .../components/GroupTreeViewer.stories.tsx | 5 +- .../components/SettingsBar.stories.tsx | 5 +- .../GroupTree}/test/TestWrapper.tsx | 3 +- .../GroupTree}/test/performanceMetrics.ts | 0 .../GroupTree}/test/testReduxState.ts | 0 typescript/package-lock.json | 16 ++++++ .../GroupTreeAssembler/groupTreeAssembler.js | 2 +- .../group-tree-plot/src/GroupTreePlot.tsx | 22 ++++---- .../packages/group-tree-plot/src/index.ts | 3 +- .../packages/group-tree-plot/src/types.ts | 50 +++++++++++++++++ typescript/packages/group-tree/CHANGELOG.md | 55 ------------------- typescript/packages/group-tree/jest.config.js | 7 --- typescript/packages/group-tree/package.json | 38 ------------- typescript/packages/group-tree/project.json | 7 --- .../components/Settings/SettingsBar.test.tsx | 35 ------------ typescript/packages/group-tree/src/index.ts | 2 - typescript/packages/group-tree/tsconfig.json | 15 ----- 52 files changed, 201 insertions(+), 286 deletions(-) delete mode 100644 python/src/components/GroupTree/GroupTree.jsx rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/GroupTree.test.tsx (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/GroupTree.tsx (76%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/GroupTree_performance.test.tsx (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/__snapshots__/GroupTree.test.tsx.snap (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/DataLoader.tsx (98%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/GroupTreeComponent.test.tsx (74%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/GroupTreeComponent.tsx (98%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/GroupTreeViewer.test.tsx (79%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/GroupTreeViewer.tsx (88%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/DateTimeSlider.test.tsx (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/DateTimeSlider.tsx (96%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/FlowRateSelector.test.tsx (67%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/FlowRateSelector.tsx (96%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/NodeInfoSelector.test.tsx (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/NodeInfoSelector.tsx (96%) create mode 100644 python/src/components/GroupTree/components/Settings/SettingsBar.test.tsx rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/SettingsBar.tsx (94%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/__snapshots__/DateTimeSlider.test.tsx.snap (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/__snapshots__/FlowRateSelector.test.tsx.snap (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/__snapshots__/NodeInfoSelector.test.tsx.snap (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/__snapshots__/SettingsBar.test.tsx.snap (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/Settings/date_time_slider.css (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/__snapshots__/GroupTreeComponent.test.tsx.snap (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/components/__snapshots__/GroupTreeViewer.test.tsx.snap (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/redux/actions.ts (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/redux/reducer.ts (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/redux/store.ts (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/redux/types.ts (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/storybook/GroupTreeComponent.stories.tsx (92%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/storybook/components/DateTimeSlider.stories.tsx (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/storybook/components/FlowRateSelector.stories.tsx (95%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/storybook/components/GroupTreeViewer.stories.tsx (95%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/storybook/components/SettingsBar.stories.tsx (94%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/test/TestWrapper.tsx (84%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/test/performanceMetrics.ts (100%) rename {typescript/packages/group-tree/src => python/src/components/GroupTree}/test/testReduxState.ts (100%) delete mode 100644 typescript/packages/group-tree/CHANGELOG.md delete mode 100644 typescript/packages/group-tree/jest.config.js delete mode 100644 typescript/packages/group-tree/package.json delete mode 100644 typescript/packages/group-tree/project.json delete mode 100644 typescript/packages/group-tree/src/components/Settings/SettingsBar.test.tsx delete mode 100644 typescript/packages/group-tree/src/index.ts delete mode 100644 typescript/packages/group-tree/tsconfig.json diff --git a/python/package-lock.json b/python/package-lock.json index 4463276e1..0fbe15d3e 100644 --- a/python/package-lock.json +++ b/python/package-lock.json @@ -17,7 +17,7 @@ "@mui/material": "^5.11", "@reduxjs/toolkit": "^1.7.2", "@webviz/core-components": "^0.6.2", - "@webviz/group-tree": "file:../typescript/packages/group-tree", + "@webviz/group-tree-plot": "file:../typescript/packages/group-tree-plot", "@webviz/subsurface-viewer": "file:../typescript/packages/subsurface-viewer", "@webviz/well-completions-plot": "file:../typescript/packages/well-completions-plot", "@webviz/well-log-viewer": "file:../typescript/packages/well-log-viewer", @@ -75,6 +75,7 @@ "../typescript/packages/group-tree": { "name": "@webviz/group-tree", "version": "1.0.1", + "extraneous": true, "license": "MPL-2.0", "dependencies": { "@equinor/eds-core-react": "^0.33.0", @@ -89,16 +90,29 @@ "react-dom": "^17 || ^18" } }, + "../typescript/packages/group-tree-plot": { + "name": "@webviz/group-tree-plot", + "version": "0.0.1", + "license": "MPL-2.0", + "dependencies": { + "d3": "^7.8.2", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": "^17 || ^18", + "react-dom": "^17 || ^18" + } + }, "../typescript/packages/group-tree/dist": { "extraneous": true }, "../typescript/packages/subsurface-viewer": { "name": "@webviz/subsurface-viewer", - "version": "0.3.3", + "version": "0.7.0", "license": "MPL-2.0", "dependencies": { - "@deck.gl/core": "^8.8.25", - "@emerson-eps/color-tables": "^0.4.61", + "@deck.gl/core": "^8.9.32", + "@emerson-eps/color-tables": "^0.4.71", "@equinor/eds-core-react": "^0.33.0", "@equinor/eds-icons": "^0.19.1", "@nebula.gl/layers": "^1.0.4", @@ -129,7 +143,7 @@ }, "../typescript/packages/well-completions-plot": { "name": "@webviz/well-completions-plot", - "version": "1.0.1", + "version": "1.0.5", "license": "MPL-2.0", "dependencies": { "react-resize-detector": "^9.1.0", @@ -141,10 +155,10 @@ }, "../typescript/packages/well-log-viewer": { "name": "@webviz/well-log-viewer", - "version": "1.1.1", + "version": "1.1.5", "license": "MPL-2.0", "dependencies": { - "@emerson-eps/color-tables": "^0.4.61", + "@emerson-eps/color-tables": "^0.4.71", "@equinor/videx-wellog": "^0.8.0", "@webviz/wsc-common": "*", "convert-units": "^2.3.4", @@ -161,7 +175,7 @@ }, "../typescript/packages/wsc-common": { "name": "@webviz/wsc-common", - "version": "0.2.1", + "version": "0.2.5", "license": "MPL-2.0", "dependencies": { "ajv": "^7.2.1" @@ -3270,8 +3284,8 @@ "object-assign": "^4.1.1" } }, - "node_modules/@webviz/group-tree": { - "resolved": "../typescript/packages/group-tree", + "node_modules/@webviz/group-tree-plot": { + "resolved": "../typescript/packages/group-tree-plot", "link": true }, "node_modules/@webviz/subsurface-viewer": { diff --git a/python/package.json b/python/package.json index 15e2e6f70..86aa14fd7 100644 --- a/python/package.json +++ b/python/package.json @@ -35,7 +35,7 @@ "@mui/material": "^5.11", "@reduxjs/toolkit": "^1.7.2", "@webviz/core-components": "^0.6.2", - "@webviz/group-tree": "file:../typescript/packages/group-tree", + "@webviz/group-tree-plot": "file:../typescript/packages/group-tree-plot", "@webviz/subsurface-viewer": "file:../typescript/packages/subsurface-viewer", "@webviz/well-completions-plot": "file:../typescript/packages/well-completions-plot", "@webviz/well-log-viewer": "file:../typescript/packages/well-log-viewer", diff --git a/python/src/components/GroupTree/GroupTree.jsx b/python/src/components/GroupTree/GroupTree.jsx deleted file mode 100644 index 4a9d70a84..000000000 --- a/python/src/components/GroupTree/GroupTree.jsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; - -const GroupTreeComponent = React.lazy(() => - import(/* webpackChunkName: "webviz-group-tree" */ "@webviz/group-tree") -); - -const GroupTree = (props) => { - const { - edge_options: edgeOptions, - node_options: nodeOptions, - ...rest - } = props; - return ( - Loading...
}> - - - ); -}; - -GroupTree.propTypes = { - /** - * 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: PropTypes.string.isRequired, - /** - * Array of JSON objects describing group tree data. - */ - data: PropTypes.arrayOf(PropTypes.object), - - edge_options: PropTypes.arrayOf(PropTypes.object), - node_options: PropTypes.arrayOf(PropTypes.object), -}; - -GroupTree.displayName = "GroupTree"; - -export default GroupTree; diff --git a/typescript/packages/group-tree/src/GroupTree.test.tsx b/python/src/components/GroupTree/GroupTree.test.tsx similarity index 100% rename from typescript/packages/group-tree/src/GroupTree.test.tsx rename to python/src/components/GroupTree/GroupTree.test.tsx diff --git a/typescript/packages/group-tree/src/GroupTree.tsx b/python/src/components/GroupTree/GroupTree.tsx similarity index 76% rename from typescript/packages/group-tree/src/GroupTree.tsx rename to python/src/components/GroupTree/GroupTree.tsx index f8e9816d1..4b5b03d2c 100644 --- a/typescript/packages/group-tree/src/GroupTree.tsx +++ b/python/src/components/GroupTree/GroupTree.tsx @@ -4,19 +4,22 @@ * https://github.com/plotly/dash/issues/719 */ -import PropTypes from "prop-types"; import React from "react"; +import PropTypes from "prop-types"; + import type { GroupTreeProps } from "./components/GroupTreeComponent"; import GroupTreeComponent from "./components/GroupTreeComponent"; const GroupTree = (props: GroupTreeProps) => { return ( - + Loading...
}> + + ); }; @@ -39,5 +42,7 @@ GroupTree.propTypes = { nodeMetadataList: PropTypes.arrayOf(PropTypes.object), }; +GroupTree.displayName = "GroupTree"; + export type { GroupTreeProps }; export default GroupTree; diff --git a/typescript/packages/group-tree/src/GroupTree_performance.test.tsx b/python/src/components/GroupTree/GroupTree_performance.test.tsx similarity index 100% rename from typescript/packages/group-tree/src/GroupTree_performance.test.tsx rename to python/src/components/GroupTree/GroupTree_performance.test.tsx diff --git a/typescript/packages/group-tree/src/__snapshots__/GroupTree.test.tsx.snap b/python/src/components/GroupTree/__snapshots__/GroupTree.test.tsx.snap similarity index 100% rename from typescript/packages/group-tree/src/__snapshots__/GroupTree.test.tsx.snap rename to python/src/components/GroupTree/__snapshots__/GroupTree.test.tsx.snap diff --git a/typescript/packages/group-tree/src/components/DataLoader.tsx b/python/src/components/GroupTree/components/DataLoader.tsx similarity index 98% rename from typescript/packages/group-tree/src/components/DataLoader.tsx rename to python/src/components/GroupTree/components/DataLoader.tsx index 17d048e4c..3594943b4 100644 --- a/typescript/packages/group-tree/src/components/DataLoader.tsx +++ b/python/src/components/GroupTree/components/DataLoader.tsx @@ -9,7 +9,7 @@ import type { DatedTrees, EdgeMetadata, NodeMetadata, -} from "../../../group-tree-plot/src/types"; +} from "@webviz/group-tree-plot"; export type DateTreesIndices = { treeIndex: number; diff --git a/typescript/packages/group-tree/src/components/GroupTreeComponent.test.tsx b/python/src/components/GroupTree/components/GroupTreeComponent.test.tsx similarity index 74% rename from typescript/packages/group-tree/src/components/GroupTreeComponent.test.tsx rename to python/src/components/GroupTree/components/GroupTreeComponent.test.tsx index 17cfe2dbc..48f240786 100644 --- a/typescript/packages/group-tree/src/components/GroupTreeComponent.test.tsx +++ b/python/src/components/GroupTree/components/GroupTreeComponent.test.tsx @@ -4,7 +4,6 @@ import "jest-styled-components"; import React from "react"; import { Wrapper } from "./../test/TestWrapper"; import GroupTreeComponent from "./GroupTreeComponent"; -import type { Data } from "../redux/types"; import exampleData from "../../../../../example-data/group-tree.json"; @@ -15,36 +14,36 @@ describe.skip("Test GroupTree Component", () => { children: ( { children: ( { it("snapshot test", () => { const { container } = render( Wrapper({ - children: , + children: , }) ); expect(container.firstChild).toMatchSnapshot(); @@ -26,7 +29,7 @@ describe("Test flow rate selector component", () => { it("select 'water rate' option to dispatch redux action", async () => { render( Wrapper({ - children: , + children: , }) ); userEvent.selectOptions( diff --git a/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx b/python/src/components/GroupTree/components/Settings/FlowRateSelector.tsx similarity index 96% rename from typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx rename to python/src/components/GroupTree/components/Settings/FlowRateSelector.tsx index 0e2dc28a5..4bec54b3a 100644 --- a/typescript/packages/group-tree/src/components/Settings/FlowRateSelector.tsx +++ b/python/src/components/GroupTree/components/Settings/FlowRateSelector.tsx @@ -4,7 +4,7 @@ import React, { useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { updateCurrentFlowRate } from "../../redux/actions"; import type { GroupTreeState } from "../../redux/store"; -import { EdgeMetadata } from "../../../../group-tree-plot/src/types"; +import { EdgeMetadata } from "@webviz/group-tree-plot"; const PREFIX = "FlowRateSelector"; diff --git a/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.test.tsx b/python/src/components/GroupTree/components/Settings/NodeInfoSelector.test.tsx similarity index 100% rename from typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.test.tsx rename to python/src/components/GroupTree/components/Settings/NodeInfoSelector.test.tsx diff --git a/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx b/python/src/components/GroupTree/components/Settings/NodeInfoSelector.tsx similarity index 96% rename from typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx rename to python/src/components/GroupTree/components/Settings/NodeInfoSelector.tsx index 6cc14f8cf..ec07a697b 100644 --- a/typescript/packages/group-tree/src/components/Settings/NodeInfoSelector.tsx +++ b/python/src/components/GroupTree/components/Settings/NodeInfoSelector.tsx @@ -4,7 +4,7 @@ import React, { useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { updateCurrentNodeInfo } from "../../redux/actions"; import type { GroupTreeState } from "../../redux/store"; -import { NodeMetadata } from "../../../../group-tree-plot/src/types"; +import { NodeMetadata } from "@webviz/group-tree-plot"; const PREFIX = "NodeInfoSelector"; diff --git a/python/src/components/GroupTree/components/Settings/SettingsBar.test.tsx b/python/src/components/GroupTree/components/Settings/SettingsBar.test.tsx new file mode 100644 index 000000000..5a0bceaf3 --- /dev/null +++ b/python/src/components/GroupTree/components/Settings/SettingsBar.test.tsx @@ -0,0 +1,37 @@ +import "@testing-library/jest-dom/extend-expect"; +import { render } from "@testing-library/react"; +import "jest-styled-components"; +import React from "react"; +import { Wrapper } from "../../test/TestWrapper"; +import SettingsBar from "./SettingsBar"; + +import { EdgeMetadata, NodeMetadata } from "@webviz/group-tree-plot"; + +const edgeMetadataList: EdgeMetadata[] = [ + { key: "waterrate", label: "Water Rate" }, + { key: "oilrate", label: "Oil Rate" }, + { key: "gasrate", label: "Gas Rate" }, + { key: "waterinjrate", label: "Water Injection Rate" }, + { key: "gasinjrate", label: "Gas Injection Rate" }, +]; + +const nodeMetadataList: NodeMetadata[] = [ + { key: "pressure", label: "Pressure" }, + { key: "bhp", label: "Bottom Hole Pressure" }, +]; + +describe("Test Settins Bar component", () => { + it("snapshot test", () => { + const { container } = render( + Wrapper({ + children: ( + + ), + }) + ); + expect(container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx b/python/src/components/GroupTree/components/Settings/SettingsBar.tsx similarity index 94% rename from typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx rename to python/src/components/GroupTree/components/Settings/SettingsBar.tsx index b698c740e..fdfa814e6 100644 --- a/typescript/packages/group-tree/src/components/Settings/SettingsBar.tsx +++ b/python/src/components/GroupTree/components/Settings/SettingsBar.tsx @@ -4,10 +4,7 @@ import React from "react"; import DateTimeSlider from "./DateTimeSlider"; import FlowRateSelector from "./FlowRateSelector"; import NodeInfoSelector from "./NodeInfoSelector"; -import { - EdgeMetadata, - NodeMetadata, -} from "../../../../group-tree-plot/src/types"; +import { EdgeMetadata, NodeMetadata } from "@webviz/group-tree-plot"; const PREFIX = "SettingsBar"; diff --git a/typescript/packages/group-tree/src/components/Settings/__snapshots__/DateTimeSlider.test.tsx.snap b/python/src/components/GroupTree/components/Settings/__snapshots__/DateTimeSlider.test.tsx.snap similarity index 100% rename from typescript/packages/group-tree/src/components/Settings/__snapshots__/DateTimeSlider.test.tsx.snap rename to python/src/components/GroupTree/components/Settings/__snapshots__/DateTimeSlider.test.tsx.snap diff --git a/typescript/packages/group-tree/src/components/Settings/__snapshots__/FlowRateSelector.test.tsx.snap b/python/src/components/GroupTree/components/Settings/__snapshots__/FlowRateSelector.test.tsx.snap similarity index 100% rename from typescript/packages/group-tree/src/components/Settings/__snapshots__/FlowRateSelector.test.tsx.snap rename to python/src/components/GroupTree/components/Settings/__snapshots__/FlowRateSelector.test.tsx.snap diff --git a/typescript/packages/group-tree/src/components/Settings/__snapshots__/NodeInfoSelector.test.tsx.snap b/python/src/components/GroupTree/components/Settings/__snapshots__/NodeInfoSelector.test.tsx.snap similarity index 100% rename from typescript/packages/group-tree/src/components/Settings/__snapshots__/NodeInfoSelector.test.tsx.snap rename to python/src/components/GroupTree/components/Settings/__snapshots__/NodeInfoSelector.test.tsx.snap diff --git a/typescript/packages/group-tree/src/components/Settings/__snapshots__/SettingsBar.test.tsx.snap b/python/src/components/GroupTree/components/Settings/__snapshots__/SettingsBar.test.tsx.snap similarity index 100% rename from typescript/packages/group-tree/src/components/Settings/__snapshots__/SettingsBar.test.tsx.snap rename to python/src/components/GroupTree/components/Settings/__snapshots__/SettingsBar.test.tsx.snap diff --git a/typescript/packages/group-tree/src/components/Settings/date_time_slider.css b/python/src/components/GroupTree/components/Settings/date_time_slider.css similarity index 100% rename from typescript/packages/group-tree/src/components/Settings/date_time_slider.css rename to python/src/components/GroupTree/components/Settings/date_time_slider.css diff --git a/typescript/packages/group-tree/src/components/__snapshots__/GroupTreeComponent.test.tsx.snap b/python/src/components/GroupTree/components/__snapshots__/GroupTreeComponent.test.tsx.snap similarity index 100% rename from typescript/packages/group-tree/src/components/__snapshots__/GroupTreeComponent.test.tsx.snap rename to python/src/components/GroupTree/components/__snapshots__/GroupTreeComponent.test.tsx.snap diff --git a/typescript/packages/group-tree/src/components/__snapshots__/GroupTreeViewer.test.tsx.snap b/python/src/components/GroupTree/components/__snapshots__/GroupTreeViewer.test.tsx.snap similarity index 100% rename from typescript/packages/group-tree/src/components/__snapshots__/GroupTreeViewer.test.tsx.snap rename to python/src/components/GroupTree/components/__snapshots__/GroupTreeViewer.test.tsx.snap diff --git a/python/src/components/GroupTree/index.ts b/python/src/components/GroupTree/index.ts index 5e582260b..a1e057646 100644 --- a/python/src/components/GroupTree/index.ts +++ b/python/src/components/GroupTree/index.ts @@ -1 +1,2 @@ export { default } from "./GroupTree"; +export type { GroupTreeProps } from "./GroupTree"; diff --git a/typescript/packages/group-tree/src/redux/actions.ts b/python/src/components/GroupTree/redux/actions.ts similarity index 100% rename from typescript/packages/group-tree/src/redux/actions.ts rename to python/src/components/GroupTree/redux/actions.ts diff --git a/typescript/packages/group-tree/src/redux/reducer.ts b/python/src/components/GroupTree/redux/reducer.ts similarity index 100% rename from typescript/packages/group-tree/src/redux/reducer.ts rename to python/src/components/GroupTree/redux/reducer.ts diff --git a/typescript/packages/group-tree/src/redux/store.ts b/python/src/components/GroupTree/redux/store.ts similarity index 100% rename from typescript/packages/group-tree/src/redux/store.ts rename to python/src/components/GroupTree/redux/store.ts diff --git a/typescript/packages/group-tree/src/redux/types.ts b/python/src/components/GroupTree/redux/types.ts similarity index 100% rename from typescript/packages/group-tree/src/redux/types.ts rename to python/src/components/GroupTree/redux/types.ts diff --git a/typescript/packages/group-tree/src/storybook/GroupTreeComponent.stories.tsx b/python/src/components/GroupTree/storybook/GroupTreeComponent.stories.tsx similarity index 92% rename from typescript/packages/group-tree/src/storybook/GroupTreeComponent.stories.tsx rename to python/src/components/GroupTree/storybook/GroupTreeComponent.stories.tsx index 751c94691..ee5458171 100644 --- a/typescript/packages/group-tree/src/storybook/GroupTreeComponent.stories.tsx +++ b/python/src/components/GroupTree/storybook/GroupTreeComponent.stories.tsx @@ -1,7 +1,7 @@ import React from "react"; import GroupTreeComponent from "../components/GroupTreeComponent"; -import { EdgeMetadata, NodeMetadata } from "../../../group-tree-plot/src/types"; +import { EdgeMetadata, NodeMetadata } from "@webviz/group-tree-plot/src/types"; export default { component: GroupTreeComponent, diff --git a/typescript/packages/group-tree/src/storybook/components/DateTimeSlider.stories.tsx b/python/src/components/GroupTree/storybook/components/DateTimeSlider.stories.tsx similarity index 100% rename from typescript/packages/group-tree/src/storybook/components/DateTimeSlider.stories.tsx rename to python/src/components/GroupTree/storybook/components/DateTimeSlider.stories.tsx diff --git a/typescript/packages/group-tree/src/storybook/components/FlowRateSelector.stories.tsx b/python/src/components/GroupTree/storybook/components/FlowRateSelector.stories.tsx similarity index 95% rename from typescript/packages/group-tree/src/storybook/components/FlowRateSelector.stories.tsx rename to python/src/components/GroupTree/storybook/components/FlowRateSelector.stories.tsx index d990142db..a8b83ed47 100644 --- a/typescript/packages/group-tree/src/storybook/components/FlowRateSelector.stories.tsx +++ b/python/src/components/GroupTree/storybook/components/FlowRateSelector.stories.tsx @@ -2,7 +2,7 @@ import React from "react"; import DataProvider from "../../components/DataLoader"; import FlowRateSelector from "../../components/Settings/FlowRateSelector"; -import { EdgeMetadata } from "../../../../group-tree-plot/src/types"; +import { EdgeMetadata } from "@webviz/group-tree-plot"; const edgeMetadataList: EdgeMetadata[] = [ { key: "waterrate", label: "Water Rate" }, diff --git a/typescript/packages/group-tree/src/storybook/components/GroupTreeViewer.stories.tsx b/python/src/components/GroupTree/storybook/components/GroupTreeViewer.stories.tsx similarity index 95% rename from typescript/packages/group-tree/src/storybook/components/GroupTreeViewer.stories.tsx rename to python/src/components/GroupTree/storybook/components/GroupTreeViewer.stories.tsx index dbf13a25d..fa90ccf49 100644 --- a/typescript/packages/group-tree/src/storybook/components/GroupTreeViewer.stories.tsx +++ b/python/src/components/GroupTree/storybook/components/GroupTreeViewer.stories.tsx @@ -2,10 +2,7 @@ import React from "react"; import DataProvider from "../../components/DataLoader"; import GroupTreeViewer from "../../components/GroupTreeViewer"; -import { - EdgeMetadata, - NodeMetadata, -} from "../../../../group-tree-plot/src/types"; +import { EdgeMetadata, NodeMetadata } from "@webviz/group-tree-plot"; const edgeMetadataList: EdgeMetadata[] = [ { key: "waterrate", label: "Water Rate" }, diff --git a/typescript/packages/group-tree/src/storybook/components/SettingsBar.stories.tsx b/python/src/components/GroupTree/storybook/components/SettingsBar.stories.tsx similarity index 94% rename from typescript/packages/group-tree/src/storybook/components/SettingsBar.stories.tsx rename to python/src/components/GroupTree/storybook/components/SettingsBar.stories.tsx index 9662daa0d..563da6064 100644 --- a/typescript/packages/group-tree/src/storybook/components/SettingsBar.stories.tsx +++ b/python/src/components/GroupTree/storybook/components/SettingsBar.stories.tsx @@ -2,10 +2,7 @@ import React from "react"; import DataProvider from "../../components/DataLoader"; import SettingsBar from "../../components/Settings/SettingsBar"; -import { - EdgeMetadata, - NodeMetadata, -} from "../../../../group-tree-plot/src/types"; +import { EdgeMetadata, NodeMetadata } from "@webviz/group-tree-plot"; const edgeMetadataList: EdgeMetadata[] = [ { key: "waterrate", label: "Water Rate" }, diff --git a/typescript/packages/group-tree/src/test/TestWrapper.tsx b/python/src/components/GroupTree/test/TestWrapper.tsx similarity index 84% rename from typescript/packages/group-tree/src/test/TestWrapper.tsx rename to python/src/components/GroupTree/test/TestWrapper.tsx index 642466018..6195f4934 100644 --- a/typescript/packages/group-tree/src/test/TestWrapper.tsx +++ b/python/src/components/GroupTree/test/TestWrapper.tsx @@ -3,7 +3,6 @@ import { Provider } from "react-redux"; import { DataContext } from "../components/DataLoader"; import { createReduxStore } from "../redux/store"; import { testState } from "./testReduxState"; -import type { Data } from "../redux/types"; import exampleData from "../../../../../example-data/group-tree.json"; @@ -17,7 +16,7 @@ export const Wrapper = ({ children: JSX.Element; }): JSX.Element => { return ( - + {children} ); diff --git a/typescript/packages/group-tree/src/test/performanceMetrics.ts b/python/src/components/GroupTree/test/performanceMetrics.ts similarity index 100% rename from typescript/packages/group-tree/src/test/performanceMetrics.ts rename to python/src/components/GroupTree/test/performanceMetrics.ts diff --git a/typescript/packages/group-tree/src/test/testReduxState.ts b/python/src/components/GroupTree/test/testReduxState.ts similarity index 100% rename from typescript/packages/group-tree/src/test/testReduxState.ts rename to python/src/components/GroupTree/test/testReduxState.ts diff --git a/typescript/package-lock.json b/typescript/package-lock.json index c181e4c38..5da719d7f 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -13609,6 +13609,10 @@ "resolved": "packages/group-tree", "link": true }, + "node_modules/@webviz/group-tree-plot": { + "resolved": "packages/group-tree-plot", + "link": true + }, "node_modules/@webviz/subsurface-viewer": { "resolved": "packages/subsurface-viewer", "link": true @@ -40299,6 +40303,18 @@ "react-dom": "^17 || ^18" } }, + "packages/group-tree-plot": { + "version": "0.0.1", + "license": "MPL-2.0", + "dependencies": { + "d3": "^7.8.2", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": "^17 || ^18", + "react-dom": "^17 || ^18" + } + }, "packages/subsurface-viewer": { "name": "@webviz/subsurface-viewer", "version": "0.8.1", diff --git a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js index 0cd29d37e..511016d2d 100644 --- a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js +++ b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js @@ -5,7 +5,7 @@ * 9 july 2021: refactored to use new format. */ import * as d3 from "d3"; -import "./Plot/group_tree.css"; +import "./group_tree.css"; /* eslint camelcase: "off" */ /* eslint array-callback-return: "off" */ diff --git a/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx b/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx index 458610917..21f00cb33 100644 --- a/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx +++ b/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx @@ -1,7 +1,7 @@ import React from "react"; import GroupTreeAssembler from "./GroupTreeAssembler/groupTreeAssembler"; -import { DatedTrees, EdgeMetadata, NodeMetadata } from "./types"; +import type { DatedTrees, EdgeMetadata, NodeMetadata } from "./types"; import { isEqual } from "lodash"; export interface GroupTreePlotProps { @@ -59,24 +59,26 @@ export const GroupTreePlot: React.FC = ( if (prevSelectedEdgeKey !== props.selectedEdgeKey) { setPrevSelectedEdgeKey(props.selectedEdgeKey); - if (!groupTreeAssemblerRef.current) return; - - groupTreeAssemblerRef.current.flowrate = props.selectedEdgeKey; + if (groupTreeAssemblerRef.current) { + groupTreeAssemblerRef.current.flowrate = props.selectedEdgeKey; + } } if (prevSelectedNodeKey !== props.selectedNodeKey) { setPrevSelectedNodeKey(props.selectedNodeKey); - if (!groupTreeAssemblerRef.current) return; - - groupTreeAssemblerRef.current.nodeinfo = props.selectedNodeKey; + if (groupTreeAssemblerRef.current) { + groupTreeAssemblerRef.current.nodeinfo = props.selectedNodeKey; + } } if (prevSelectedDateTime !== props.selectedDateTime) { setPrevSelectedDateTime(props.selectedDateTime); - if (!groupTreeAssemblerRef.current) return; - - groupTreeAssemblerRef.current.update(props.selectedDateTime); + if (groupTreeAssemblerRef.current) { + groupTreeAssemblerRef.current.update(props.selectedDateTime); + } } return
; }; + +GroupTreePlot.displayName = "GroupTreePlot"; diff --git a/typescript/packages/group-tree-plot/src/index.ts b/typescript/packages/group-tree-plot/src/index.ts index 8dcffcbf8..31e6a692b 100644 --- a/typescript/packages/group-tree-plot/src/index.ts +++ b/typescript/packages/group-tree-plot/src/index.ts @@ -1,7 +1,6 @@ -export { GroupTreePlot } from "./GroupTreePlot"; +export { GroupTreePlot, GroupTreePlotProps } from "./GroupTreePlot"; // Export types -export type { GroupTreePlotProps } from "./GroupTreePlot"; export type { NodeData, NodeMetadata, diff --git a/typescript/packages/group-tree-plot/src/types.ts b/typescript/packages/group-tree-plot/src/types.ts index e91f965c2..4e0bb6b90 100644 --- a/typescript/packages/group-tree-plot/src/types.ts +++ b/typescript/packages/group-tree-plot/src/types.ts @@ -1,3 +1,5 @@ +import PropTypes from "prop-types"; + // Node key and values map - one value per date in DatedTree export interface NodeData { [key: string]: number[]; @@ -38,3 +40,51 @@ export interface DatedTree { // List of dated trees export type DatedTrees = DatedTree[]; + +// --------------------------- PropTypes --------------------------------------- + +export const NodeDataPropTypes = PropTypes.objectOf( + PropTypes.arrayOf(PropTypes.number.isRequired).isRequired +); +export const NodeMetadataPropTypes = PropTypes.shape({ + key: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + unit: PropTypes.string, +}); + +export const EdgeDataPropTypes = PropTypes.objectOf( + PropTypes.arrayOf(PropTypes.number.isRequired).isRequired +); +export const EdgeMetadataPropTypes = PropTypes.shape({ + key: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + unit: PropTypes.string, +}); + +// Note: This is a solution for recursive definition for RecursiveTreeNode, as children is an optional array of RecursiveTreeNode. +// - Object.assign() resolves the issue of children being optional. +// - PropTypes.arrayOf(PropTypes.shape(RecursiveTreeNode).isRequired) resolves the issue of children being recursive. +const RecursiveTreeNodeShape: React.WeakValidationMap = { + node_label: PropTypes.string.isRequired, + edge_label: PropTypes.string.isRequired, + node_data: NodeDataPropTypes.isRequired, + edge_data: EdgeDataPropTypes.isRequired, +}; +Object.assign(RecursiveTreeNodeShape, { + node_type: PropTypes.oneOf(["Group", "Well"]).isRequired, + children: PropTypes.arrayOf( + PropTypes.shape(RecursiveTreeNodeShape).isRequired + ), +}); +export const RecursiveTreeNodePropTypes = PropTypes.shape( + RecursiveTreeNodeShape +).isRequired; + +// Collection of trees with dates +export const DatedTreePropTypes = PropTypes.shape({ + dates: PropTypes.arrayOf(PropTypes.string).isRequired, + tree: RecursiveTreeNodePropTypes, +}); + +// List of dated trees +export const DatedTreesPropTypes = PropTypes.arrayOf(DatedTreePropTypes); diff --git a/typescript/packages/group-tree/CHANGELOG.md b/typescript/packages/group-tree/CHANGELOG.md deleted file mode 100644 index 09c4682e7..000000000 --- a/typescript/packages/group-tree/CHANGELOG.md +++ /dev/null @@ -1,55 +0,0 @@ -## [1.0.7](https://github.com/equinor/webviz-subsurface-components/compare/group-tree@1.0.6...group-tree@1.0.7) (2023-12-04) - - -### Bug Fixes - -* bump @equinor/videx-wellog from 0.8.0 to 0.8.1 in /typescript ([#1811](https://github.com/equinor/webviz-subsurface-components/issues/1811)) ([0e6a423](https://github.com/equinor/webviz-subsurface-components/commit/0e6a423b32bdcb1ac78597932ec0821687851dde)) - -## [1.0.6](https://github.com/equinor/webviz-subsurface-components/compare/group-tree@1.0.5...group-tree@1.0.6) (2023-11-30) - - -### Bug Fixes - -* bump deck.gl from 8.9.31 to 8.9.32 in /typescript ([#1800](https://github.com/equinor/webviz-subsurface-components/issues/1800)) ([393230c](https://github.com/equinor/webviz-subsurface-components/commit/393230c28e4946d9d210ed4a7e33c893fee87bf0)) - -## [1.0.5](https://github.com/equinor/webviz-subsurface-components/compare/group-tree@1.0.4...group-tree@1.0.5) (2023-11-13) - - -### Bug Fixes - -* bump to latest @emerson-eps/color-tables ([#1770](https://github.com/equinor/webviz-subsurface-components/issues/1770)) ([e67a285](https://github.com/equinor/webviz-subsurface-components/commit/e67a2856eced8f987bc61fa4a0a924b5a4886992)) - -## [1.0.4](https://github.com/equinor/webviz-subsurface-components/compare/group-tree@1.0.3...group-tree@1.0.4) (2023-11-09) - - -### Bug Fixes - -* bump [@deck](https://github.com/deck).gl/core from 8.9.31 to 8.9.32 in /typescript ([#1764](https://github.com/equinor/webviz-subsurface-components/issues/1764)) ([5ab32b0](https://github.com/equinor/webviz-subsurface-components/commit/5ab32b0db7cac16d027624643604df2ee7402918)) - -## [1.0.3](https://github.com/equinor/webviz-subsurface-components/compare/group-tree@1.0.2...group-tree@1.0.3) (2023-10-17) - - -### Bug Fixes - -* bump @equinor/eds-core-react from 0.32.x to 0.33.0 ([#1704](https://github.com/equinor/webviz-subsurface-components/issues/1704)) ([75c5de8](https://github.com/equinor/webviz-subsurface-components/commit/75c5de8cd069a6c0d1d87b54307e23cf5be1b4b3)) - -## [1.0.2](https://github.com/equinor/webviz-subsurface-components/compare/group-tree@1.0.1...group-tree@1.0.2) (2023-10-17) - - -### Bug Fixes - -* audit fix prod dependencies ([#1707](https://github.com/equinor/webviz-subsurface-components/issues/1707)) ([b5dbcf8](https://github.com/equinor/webviz-subsurface-components/commit/b5dbcf8677d0f0424cfdf4c2d237b378de867e12)) - -## [1.0.1](https://github.com/equinor/webviz-subsurface-components/compare/group-tree@1.0.0...group-tree@1.0.1) (2023-10-13) - - -### Bug Fixes - -* bump d3-format from 1.4.5 to 3.1.0 in /typescript ([#1680](https://github.com/equinor/webviz-subsurface-components/issues/1680)) ([91f42d1](https://github.com/equinor/webviz-subsurface-components/commit/91f42d1b47c8c423ae8e4d720daf44f2b24730e4)) - -# 1.0.0 (2023-09-22) - - -### Features - -* New wellsLayer property: "simplifiedRendering". Default false. ([#1653](https://github.com/equinor/webviz-subsurface-components/issues/1653)) ([baffae1](https://github.com/equinor/webviz-subsurface-components/commit/baffae183456c027c6312a44e56071baec7c0ca3)) diff --git a/typescript/packages/group-tree/jest.config.js b/typescript/packages/group-tree/jest.config.js deleted file mode 100644 index 52c5e0f33..000000000 --- a/typescript/packages/group-tree/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import('jest').Config} */ - -const config = { - preset: "../../jest.config.js", -}; - -module.exports = config; diff --git a/typescript/packages/group-tree/package.json b/typescript/packages/group-tree/package.json deleted file mode 100644 index 6abb4a959..000000000 --- a/typescript/packages/group-tree/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "@webviz/group-tree", - "version": "1.0.7", - "description": "", - "main": "dist/index.js", - "types": "dist/index.d.ts", - "files": [ - "dist" - ], - "scripts": { - "transpile": "tsc --project ./tsconfig.json", - "copy-files": "copyfiles --up 1 \"src/**/*.css\" dist/", - "build": "git clean -xdff dist && npm run transpile && npm run copy-files", - "test_perf": "jest _performance", - "test_correctness": "jest --coverage --testPathIgnorePatterns='_performance'", - "test": "jest --coverage", - "test:update": "npm test -- --u", - "test:watch": "npm test -- --watch", - "doc": "git clean -xdff docs && typedoc src" - }, - "author": "Equinor ", - "license": "MPL-2.0", - "dependencies": { - "@equinor/eds-core-react": "^0.33.0", - "@reduxjs/toolkit": "^1.7.2", - "d3": "^7.8.2", - "lodash": "^4.17.21", - "react-redux": "^8.1.1" - }, - "peerDependencies": { - "@mui/material": "^5.11", - "react": "^17 || ^18", - "react-dom": "^17 || ^18" - }, - "volta": { - "node": "18.17.0" - } -} diff --git a/typescript/packages/group-tree/project.json b/typescript/packages/group-tree/project.json deleted file mode 100644 index b882678be..000000000 --- a/typescript/packages/group-tree/project.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "targets": { - "semantic-release": { - "executor": "@theunderscorer/nx-semantic-release:semantic-release" - } - } -} diff --git a/typescript/packages/group-tree/src/components/Settings/SettingsBar.test.tsx b/typescript/packages/group-tree/src/components/Settings/SettingsBar.test.tsx deleted file mode 100644 index 5ee98e223..000000000 --- a/typescript/packages/group-tree/src/components/Settings/SettingsBar.test.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import "@testing-library/jest-dom/extend-expect"; -import { render } from "@testing-library/react"; -import "jest-styled-components"; -import React from "react"; -import { Wrapper } from "../../test/TestWrapper"; -import SettingsBar from "./SettingsBar"; - -const edge_options = [ - { name: "waterrate", label: "Water Rate" }, - { name: "oilrate", label: "Oil Rate" }, - { name: "gasrate", label: "Gas Rate" }, - { name: "waterinjrate", label: "Water Injection Rate" }, - { name: "gasinjrate", label: "Gas Injection Rate" }, -]; - -const node_options = [ - { name: "pressure", label: "Pressure" }, - { name: "bhp", label: "Bottom Hole Pressure" }, -]; - -describe("Test Settins Bar component", () => { - it("snapshot test", () => { - const { container } = render( - Wrapper({ - children: ( - - ), - }) - ); - expect(container.firstChild).toMatchSnapshot(); - }); -}); diff --git a/typescript/packages/group-tree/src/index.ts b/typescript/packages/group-tree/src/index.ts deleted file mode 100644 index a1e057646..000000000 --- a/typescript/packages/group-tree/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default } from "./GroupTree"; -export type { GroupTreeProps } from "./GroupTree"; diff --git a/typescript/packages/group-tree/tsconfig.json b/typescript/packages/group-tree/tsconfig.json deleted file mode 100644 index 2dc7e60c2..000000000 --- a/typescript/packages/group-tree/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "./dist", - "rootDir": "./src" - }, - "include": ["src/", "../group-tree-plot"], - "exclude": [ - "src/storybook", - "src/test", - "./**/*.test.tsx", - "./**/*.stories.tsx", - "./storybook" - ] -} From 3047348fb290e2859a1f78090720bce3dce04f74 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Tue, 28 Nov 2023 15:21:02 +0100 Subject: [PATCH 06/20] Convert tsx -> jsx due to dash generate component issue --- python/src/components/GroupTree/GroupTree.jsx | 49 +++++++++++++++++++ .../components/GroupTree/GroupTree.test.tsx | 6 +-- python/src/components/GroupTree/GroupTree.tsx | 48 ------------------ .../GroupTree/GroupTree_performance.test.tsx | 6 +-- python/src/components/GroupTree/index.ts | 3 +- python/src/index.ts | 2 +- .../packages/group-tree-plot/src/index.ts | 11 ++++- 7 files changed, 67 insertions(+), 58 deletions(-) create mode 100644 python/src/components/GroupTree/GroupTree.jsx delete mode 100644 python/src/components/GroupTree/GroupTree.tsx diff --git a/python/src/components/GroupTree/GroupTree.jsx b/python/src/components/GroupTree/GroupTree.jsx new file mode 100644 index 000000000..119101dde --- /dev/null +++ b/python/src/components/GroupTree/GroupTree.jsx @@ -0,0 +1,49 @@ +import React from "react"; +import PropTypes from "prop-types"; + +import { + DatedTreesPropTypes, + EdgeMetadataPropTypes, + NodeMetadataPropTypes, +} from "@webviz/group-tree-plot"; + +const GroupTreeComponent = React.lazy(() => + import( + /* webpackChunkName: "webviz-group-tree" */ "./components/GroupTreeComponent" + ) +); + +export const GroupTree = (props) => { + return ( + Loading...
}> + + + ); +}; + +GroupTree.propTypes = { + /** + * 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: PropTypes.string.isRequired, + + /** + * Array of JSON objects describing group tree data. + */ + data: DatedTreesPropTypes, + + /** + * Arrays of metadata. Used in drop down selectors and tree visualization. + */ + edge_metadata_list: EdgeMetadataPropTypes, + node_metadata_list: NodeMetadataPropTypes, +}; + +GroupTree.displayName = "GroupTree"; diff --git a/python/src/components/GroupTree/GroupTree.test.tsx b/python/src/components/GroupTree/GroupTree.test.tsx index 6eee62a2b..3ef7a1613 100644 --- a/python/src/components/GroupTree/GroupTree.test.tsx +++ b/python/src/components/GroupTree/GroupTree.test.tsx @@ -3,7 +3,7 @@ import { render } from "@testing-library/react"; import "jest-styled-components"; import React from "react"; import { Wrapper } from "./test/TestWrapper"; -import GroupTree from "./GroupTree"; +import { GroupTree } from "./GroupTree"; import exampleData from "../../../../example-data/group-tree.json"; @@ -15,7 +15,7 @@ describe.skip("Test GroupTree Default Component", () => { { label: "Gas Injection Rate", }, ]} - nodeMetadataList={[ + node_metadata_list={[ { key: "pressure", label: "Pressure", diff --git a/python/src/components/GroupTree/GroupTree.tsx b/python/src/components/GroupTree/GroupTree.tsx deleted file mode 100644 index 4b5b03d2c..000000000 --- a/python/src/components/GroupTree/GroupTree.tsx +++ /dev/null @@ -1,48 +0,0 @@ -/** - * This file is created in order to let dash-generate-components extract metadata. - * At the moment, the library does not support generating components from typescript directly - * https://github.com/plotly/dash/issues/719 - */ - -import React from "react"; -import PropTypes from "prop-types"; - -import type { GroupTreeProps } from "./components/GroupTreeComponent"; -import GroupTreeComponent from "./components/GroupTreeComponent"; - -const GroupTree = (props: GroupTreeProps) => { - return ( - Loading...
}> - - - ); -}; - -GroupTree.propTypes = { - /** - * 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: PropTypes.string.isRequired, - /** - * Array of JSON objects describing group tree data. - */ - data: PropTypes.arrayOf(PropTypes.object), - - /** - * Arrays of metadata. Used in drop down selectors and tree visualization. - */ - edgeMetadataList: PropTypes.arrayOf(PropTypes.object), - nodeMetadataList: PropTypes.arrayOf(PropTypes.object), -}; - -GroupTree.displayName = "GroupTree"; - -export type { GroupTreeProps }; -export default GroupTree; diff --git a/python/src/components/GroupTree/GroupTree_performance.test.tsx b/python/src/components/GroupTree/GroupTree_performance.test.tsx index 70385f09a..9f720d65d 100644 --- a/python/src/components/GroupTree/GroupTree_performance.test.tsx +++ b/python/src/components/GroupTree/GroupTree_performance.test.tsx @@ -3,7 +3,7 @@ import { render } from "@testing-library/react"; import "jest-styled-components"; import React, { Profiler } from "react"; import * as core from "@actions/core"; -import GroupTree from "./GroupTree"; +import { GroupTree } from "./GroupTree"; import { Wrapper } from "./test/TestWrapper"; import logTimes, { obj } from "./test/performanceMetrics"; @@ -18,7 +18,7 @@ describe("Test GroupTree perfomance", () => { { label: "Gas Injection Rate", }, ]} - node_options={[ + node_metadata_list={[ { name: "pressure", label: "Pressure", diff --git a/python/src/components/GroupTree/index.ts b/python/src/components/GroupTree/index.ts index a1e057646..e32e28507 100644 --- a/python/src/components/GroupTree/index.ts +++ b/python/src/components/GroupTree/index.ts @@ -1,2 +1 @@ -export { default } from "./GroupTree"; -export type { GroupTreeProps } from "./GroupTree"; +export { GroupTree } from "./GroupTree"; diff --git a/python/src/index.ts b/python/src/index.ts index 95a93372e..0fe54b80a 100644 --- a/python/src/index.ts +++ b/python/src/index.ts @@ -1,6 +1,6 @@ import DashSubsurfaceViewer from "./components/DashSubsurfaceViewer"; import SubsurfaceViewer from "./components/SubsurfaceViewer"; -import GroupTree from "./components/GroupTree"; +import { GroupTree } from "./components/GroupTree"; import HistoryMatch from "./components/HistoryMatch"; import LeafletMap from "./components/LeafletMap"; import Map from "./components/Map"; diff --git a/typescript/packages/group-tree-plot/src/index.ts b/typescript/packages/group-tree-plot/src/index.ts index 31e6a692b..91b388841 100644 --- a/typescript/packages/group-tree-plot/src/index.ts +++ b/typescript/packages/group-tree-plot/src/index.ts @@ -1,12 +1,21 @@ -export { GroupTreePlot, GroupTreePlotProps } from "./GroupTreePlot"; +export { GroupTreePlot } from "./GroupTreePlot"; + +export type { GroupTreePlotProps } from "./GroupTreePlot"; // Export types export type { NodeData, + NodeDataPropTypes, NodeMetadata, + NodeMetadataPropTypes, EdgeData, + EdgeDataPropTypes, EdgeMetadata, + EdgeMetadataPropTypes, RecursiveTreeNode, + RecursiveTreeNodePropTypes, DatedTree, + DatedTreePropTypes, DatedTrees, + DatedTreesPropTypes, } from "./types"; From a92132b565f168abf1547cbe5c21ceac90da1d73 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Wed, 29 Nov 2023 10:13:55 +0100 Subject: [PATCH 07/20] Remove tests+stories in /python. Add story in /typscript/package - WIP - Remove tests and storybooks from dash-component in /python-folder. - Add storybook for group-tree-plot component in new package --- .../components/GroupTree/GroupTree.test.tsx | 56 -- .../GroupTree/GroupTree_performance.test.tsx | 80 --- .../__snapshots__/GroupTree.test.tsx.snap | 492 ------------------ .../components/GroupTreeComponent.test.tsx | 56 -- .../components/GroupTreeViewer.test.tsx | 56 -- .../Settings/DateTimeSlider.test.tsx | 24 - .../Settings/FlowRateSelector.test.tsx | 45 -- .../Settings/NodeInfoSelector.test.tsx | 39 -- .../components/Settings/SettingsBar.test.tsx | 37 -- .../DateTimeSlider.test.tsx.snap | 76 --- .../FlowRateSelector.test.tsx.snap | 134 ----- .../NodeInfoSelector.test.tsx.snap | 119 ----- .../__snapshots__/SettingsBar.test.tsx.snap | 310 ----------- .../GroupTreeComponent.test.tsx.snap | 492 ------------------ .../GroupTreeViewer.test.tsx.snap | 492 ------------------ .../components/DateTimeSlider.stories.tsx | 37 -- .../components/FlowRateSelector.stories.tsx | 48 -- .../components/GroupTreeViewer.stories.tsx | 59 --- .../components/SettingsBar.stories.tsx | 57 -- .../components/GroupTree/test/TestWrapper.tsx | 23 - .../GroupTree/test/performanceMetrics.ts | 20 - .../GroupTree/test/testReduxState.ts | 10 - .../example-data/dated-trees.ts | 153 ++++++ .../src/storybook/GroupTreePlot.stories.tsx | 29 +- .../packages/group-tree-plot/src/types.ts | 1 + 25 files changed, 176 insertions(+), 2769 deletions(-) delete mode 100644 python/src/components/GroupTree/GroupTree.test.tsx delete mode 100644 python/src/components/GroupTree/GroupTree_performance.test.tsx delete mode 100644 python/src/components/GroupTree/__snapshots__/GroupTree.test.tsx.snap delete mode 100644 python/src/components/GroupTree/components/GroupTreeComponent.test.tsx delete mode 100644 python/src/components/GroupTree/components/GroupTreeViewer.test.tsx delete mode 100644 python/src/components/GroupTree/components/Settings/DateTimeSlider.test.tsx delete mode 100644 python/src/components/GroupTree/components/Settings/FlowRateSelector.test.tsx delete mode 100644 python/src/components/GroupTree/components/Settings/NodeInfoSelector.test.tsx delete mode 100644 python/src/components/GroupTree/components/Settings/SettingsBar.test.tsx delete mode 100644 python/src/components/GroupTree/components/Settings/__snapshots__/DateTimeSlider.test.tsx.snap delete mode 100644 python/src/components/GroupTree/components/Settings/__snapshots__/FlowRateSelector.test.tsx.snap delete mode 100644 python/src/components/GroupTree/components/Settings/__snapshots__/NodeInfoSelector.test.tsx.snap delete mode 100644 python/src/components/GroupTree/components/Settings/__snapshots__/SettingsBar.test.tsx.snap delete mode 100644 python/src/components/GroupTree/components/__snapshots__/GroupTreeComponent.test.tsx.snap delete mode 100644 python/src/components/GroupTree/components/__snapshots__/GroupTreeViewer.test.tsx.snap delete mode 100644 python/src/components/GroupTree/storybook/components/DateTimeSlider.stories.tsx delete mode 100644 python/src/components/GroupTree/storybook/components/FlowRateSelector.stories.tsx delete mode 100644 python/src/components/GroupTree/storybook/components/GroupTreeViewer.stories.tsx delete mode 100644 python/src/components/GroupTree/storybook/components/SettingsBar.stories.tsx delete mode 100644 python/src/components/GroupTree/test/TestWrapper.tsx delete mode 100644 python/src/components/GroupTree/test/performanceMetrics.ts delete mode 100644 python/src/components/GroupTree/test/testReduxState.ts create mode 100644 typescript/packages/group-tree-plot/example-data/dated-trees.ts rename python/src/components/GroupTree/storybook/GroupTreeComponent.stories.tsx => typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx (50%) diff --git a/python/src/components/GroupTree/GroupTree.test.tsx b/python/src/components/GroupTree/GroupTree.test.tsx deleted file mode 100644 index 3ef7a1613..000000000 --- a/python/src/components/GroupTree/GroupTree.test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import "@testing-library/jest-dom/extend-expect"; -import { render } from "@testing-library/react"; -import "jest-styled-components"; -import React from "react"; -import { Wrapper } from "./test/TestWrapper"; -import { GroupTree } from "./GroupTree"; - -import exampleData from "../../../../example-data/group-tree.json"; - -describe.skip("Test GroupTree Default Component", () => { - it("snapshot test", () => { - const { container } = render( - Wrapper({ - children: ( - - ), - }) - ); - expect(container.firstChild).toMatchSnapshot(); - }); -}); diff --git a/python/src/components/GroupTree/GroupTree_performance.test.tsx b/python/src/components/GroupTree/GroupTree_performance.test.tsx deleted file mode 100644 index 9f720d65d..000000000 --- a/python/src/components/GroupTree/GroupTree_performance.test.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import "@testing-library/jest-dom/extend-expect"; -import { render } from "@testing-library/react"; -import "jest-styled-components"; -import React, { Profiler } from "react"; -import * as core from "@actions/core"; -import { GroupTree } from "./GroupTree"; -import { Wrapper } from "./test/TestWrapper"; -import logTimes, { obj } from "./test/performanceMetrics"; - -import exampleData from "../../../../example-data/group-tree.json"; - -describe("Test GroupTree perfomance", () => { - it("initial performance test", () => { - render( - Wrapper({ - children: ( - - - - ), - }) - ); - }); - - const no_of_renders = obj.perf_metrics.length; - if (no_of_renders > 2) { - core.setFailed( - "GroupTree Component seems to have performance issues. Actual number of renders = " + - no_of_renders + - " .Expected number of renders <= 2 " - ); - } - for (let i = 0; i < no_of_renders; i++) { - core.info( - "Render number: " + (i + 1) + " | Metrics: " + obj.perf_metrics[i] - ); - if (obj.perf_metrics[i][2] > 100) { - core.setFailed( - "GroupTree Component seems to have performance issues. Actual render time:" + - obj.perf_metrics[i][2] + - " Expected render time - less than 100ms" - ); - } - } -}); diff --git a/python/src/components/GroupTree/__snapshots__/GroupTree.test.tsx.snap b/python/src/components/GroupTree/__snapshots__/GroupTree.test.tsx.snap deleted file mode 100644 index 337a07529..000000000 --- a/python/src/components/GroupTree/__snapshots__/GroupTree.test.tsx.snap +++ /dev/null @@ -1,492 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Test GroupTree Default Component snapshot test 1`] = ` -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - position: relative; - margin: 0; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - font-family: Equinor; - font-size: 0.750rem; - font-weight: 500; - line-height: 1.333em; - text-align: left; - margin-left: 8px; - margin-right: 8px; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); -} - -.c4 { - margin: 0; -} - -.c0 { - height: 64px; - top: 0; - position: -webkit-sticky; - position: sticky; - background: var(--eds_ui_background__default,rgba(255,255,255,1)); - box-sizing: border-box; - z-index: 250; - display: grid; - grid-column-gap: 40px; - grid-template-columns: auto 1fr auto; - grid-template-areas: 'left center right'; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border-bottom: 2px var(--eds_ui_background__light,rgba(247,247,247,1)); - padding-left: 40px; - padding-top: 8px; - padding-right: 40px; - padding-bottom: 8px; - margin: 0; - color: rgba(61,61,61,1); - font-family: Equinor; - font-size: 1.000rem; - font-weight: 400; - line-height: 1.000em; - -webkit-letter-spacing: 0.013em; - -moz-letter-spacing: 0.013em; - -ms-letter-spacing: 0.013em; - letter-spacing: 0.013em; - text-align: left; -} - -.c6 { - grid-area: right; - text-align: right; -} - -.c1 { - grid-area: left; - display: grid; - grid-template-columns: auto auto; - grid-gap: 24px; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.c5 { - border: none; - border-radius: 0; - box-shadow: inset 0 -1px 0 0 var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - padding-left: 8px; - padding-top: 6px; - padding-right: 8px; - padding-bottom: 6px; - margin: 0; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - font-family: Equinor; - font-size: 1.000rem; - font-weight: 400; - line-height: 1.500em; - -webkit-letter-spacing: 0.025em; - -moz-letter-spacing: 0.025em; - -ms-letter-spacing: 0.025em; - letter-spacing: 0.025em; - text-align: left; - padding-right: calc(8px *2 + 24px); - display: block; - margin: 0; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%236f6f6f' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"), linear-gradient( to bottom, var(--eds_ui_background__light,rgba(247,247,247,1)) 0%, var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - background-repeat: no-repeat,repeat; - background-position: right 8px top 50%; - width: 100%; -} - -.c5:active, -.c5:focus { - box-shadow: none; - outline: 2px solid var(--eds_interactive_primary__resting,rgba(0,112,121,1)); - outline-offset: 0px; -} - -.c5:disabled { - color: var(--eds_interactive__disabled__text,rgba(190,190,190,1)); - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23bebebe' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"), linear-gradient( to bottom, var(--eds_ui_background__light,rgba(247,247,247,1)) 0%, var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - cursor: not-allowed; - box-shadow: none; - outline: none; -} - -.c5:disabled .arrow-icon { - fill: red; -} - -.c5:disabled:focus, -.c5:disabled:active { - outline: none; -} - -.c2 { - min-width: 100px; - width: 100%; -} - -
-
-
-
- - -
-
- - -
-
-
-
- - Time Steps - - - - - - - - - - - - - -
-
-
-
- - - - - Water Rate 20 -Oil Rate 30 -Gas Rate 40 -Water Injection Rate 50 -Gas Injection Rate 60 - - - - - - Water Rate 25 -Oil Rate 35 -Gas Rate 45 -Water Injection Rate 55 -Gas Injection Rate 65 - - - - - - - - - - - - - - - TRE_1 - - - 5 - - - - Pressure 5 - - - - - - - TRE_1_1 - - - 20 - - - - Pressure 20 -Bottom Hole Pressure 11 -wmctl 12 - - - - - - - TRE_1_2 - - - 22 - - - - Pressure 22 -wmctl 10 - - - - - -
-
-`; diff --git a/python/src/components/GroupTree/components/GroupTreeComponent.test.tsx b/python/src/components/GroupTree/components/GroupTreeComponent.test.tsx deleted file mode 100644 index 48f240786..000000000 --- a/python/src/components/GroupTree/components/GroupTreeComponent.test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import "@testing-library/jest-dom/extend-expect"; -import { render } from "@testing-library/react"; -import "jest-styled-components"; -import React from "react"; -import { Wrapper } from "./../test/TestWrapper"; -import GroupTreeComponent from "./GroupTreeComponent"; - -import exampleData from "../../../../../example-data/group-tree.json"; - -describe.skip("Test GroupTree Component", () => { - it("snapshot test", () => { - const { container } = render( - Wrapper({ - children: ( - - ), - }) - ); - expect(container.firstChild).toMatchSnapshot(); - }); -}); diff --git a/python/src/components/GroupTree/components/GroupTreeViewer.test.tsx b/python/src/components/GroupTree/components/GroupTreeViewer.test.tsx deleted file mode 100644 index ebb0f5eaa..000000000 --- a/python/src/components/GroupTree/components/GroupTreeViewer.test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import "@testing-library/jest-dom/extend-expect"; -import { render } from "@testing-library/react"; -import "jest-styled-components"; -import React from "react"; -import { Wrapper } from "../test/TestWrapper"; -import GroupTreeViewer from "./GroupTreeViewer"; - -describe.skip("Test GroupTreeViewer", () => { - it("snapshot test", () => { - const { container } = render( - Wrapper({ - children: ( - currentDateTime} - /> - ), - }) - ); - expect(container.firstChild).toMatchSnapshot(); - }); -}); diff --git a/python/src/components/GroupTree/components/Settings/DateTimeSlider.test.tsx b/python/src/components/GroupTree/components/Settings/DateTimeSlider.test.tsx deleted file mode 100644 index ce9da3d53..000000000 --- a/python/src/components/GroupTree/components/Settings/DateTimeSlider.test.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import "@testing-library/jest-dom/extend-expect"; -import { render, screen } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import "jest-styled-components"; -import React from "react"; -import { testStore, Wrapper } from "../../test/TestWrapper"; -import DateTimeSlider from "./DateTimeSlider"; - -describe("Test Date-Time Slider", () => { - it("snapshot test", () => { - const { container } = render(Wrapper({ children: })); - render(Wrapper({ children: })); - expect(container.firstChild).toMatchSnapshot(); - }); - it("test slider", async () => { - render(Wrapper({ children: })); - userEvent.type(screen.getByRole("slider"), "{arrowright}"); - expect(testStore.dispatch).toHaveBeenCalledTimes(1); - expect(testStore.dispatch).toHaveBeenNthCalledWith(1, { - payload: undefined, - type: "ui/updateCurrentDateTime", - }); - }); -}); diff --git a/python/src/components/GroupTree/components/Settings/FlowRateSelector.test.tsx b/python/src/components/GroupTree/components/Settings/FlowRateSelector.test.tsx deleted file mode 100644 index 59c5c98fb..000000000 --- a/python/src/components/GroupTree/components/Settings/FlowRateSelector.test.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import "@testing-library/jest-dom/extend-expect"; -import { render, screen } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import "jest-styled-components"; -import React from "react"; -import { testStore, Wrapper } from "../../test/TestWrapper"; -import FlowRateSelector from "./FlowRateSelector"; - -import { EdgeMetadata } from "@webviz/group-tree-plot"; - -const edgeMetadataList: EdgeMetadata[] = [ - { key: "waterrate", label: "Water Rate" }, - { key: "oilrate", label: "Oil Rate" }, - { key: "gasrate", label: "Gas Rate" }, - { key: "waterinjrate", label: "Water Injection Rate" }, - { key: "gasinjrate", label: "Gas Injection Rate" }, -]; -]; - -describe("Test flow rate selector component", () => { - it("snapshot test", () => { - const { container } = render( - Wrapper({ - children: , - }) - ); - expect(container.firstChild).toMatchSnapshot(); - }); - it("select 'water rate' option to dispatch redux action", async () => { - render( - Wrapper({ - children: , - }) - ); - userEvent.selectOptions( - screen.getByRole("combobox", { name: "Flow Rate" }), - "waterrate" - ); - expect(testStore.dispatch).toHaveBeenCalledTimes(1); - expect(testStore.dispatch).toHaveBeenCalledWith({ - payload: "waterrate", - type: "ui/updateCurrentFlowRate", - }); - }); -}); diff --git a/python/src/components/GroupTree/components/Settings/NodeInfoSelector.test.tsx b/python/src/components/GroupTree/components/Settings/NodeInfoSelector.test.tsx deleted file mode 100644 index 76524f860..000000000 --- a/python/src/components/GroupTree/components/Settings/NodeInfoSelector.test.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import "@testing-library/jest-dom/extend-expect"; -import { render, screen } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import "jest-styled-components"; -import React from "react"; -import { testStore, Wrapper } from "../../test/TestWrapper"; -import NodeInfoSelector from "./NodeInfoSelector"; - -const node_options = [ - { name: "pressure", label: "Pressure" }, - { name: "bhp", label: "Bottom Hole Pressure" }, -]; - -describe("Test flow rate selector component", () => { - it("snapshot test", () => { - const { container } = render( - Wrapper({ - children: , - }) - ); - expect(container.firstChild).toMatchSnapshot(); - }); - it("select 'Pressure' option to dispatch redux action", async () => { - render( - Wrapper({ - children: , - }) - ); - userEvent.selectOptions( - screen.getByRole("combobox", { name: "Node Data" }), - "pressure" - ); - expect(testStore.dispatch).toHaveBeenCalledTimes(1); - expect(testStore.dispatch).toHaveBeenCalledWith({ - payload: "pressure", - type: "ui/updateCurrentNodeInfo", - }); - }); -}); diff --git a/python/src/components/GroupTree/components/Settings/SettingsBar.test.tsx b/python/src/components/GroupTree/components/Settings/SettingsBar.test.tsx deleted file mode 100644 index 5a0bceaf3..000000000 --- a/python/src/components/GroupTree/components/Settings/SettingsBar.test.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import "@testing-library/jest-dom/extend-expect"; -import { render } from "@testing-library/react"; -import "jest-styled-components"; -import React from "react"; -import { Wrapper } from "../../test/TestWrapper"; -import SettingsBar from "./SettingsBar"; - -import { EdgeMetadata, NodeMetadata } from "@webviz/group-tree-plot"; - -const edgeMetadataList: EdgeMetadata[] = [ - { key: "waterrate", label: "Water Rate" }, - { key: "oilrate", label: "Oil Rate" }, - { key: "gasrate", label: "Gas Rate" }, - { key: "waterinjrate", label: "Water Injection Rate" }, - { key: "gasinjrate", label: "Gas Injection Rate" }, -]; - -const nodeMetadataList: NodeMetadata[] = [ - { key: "pressure", label: "Pressure" }, - { key: "bhp", label: "Bottom Hole Pressure" }, -]; - -describe("Test Settins Bar component", () => { - it("snapshot test", () => { - const { container } = render( - Wrapper({ - children: ( - - ), - }) - ); - expect(container.firstChild).toMatchSnapshot(); - }); -}); diff --git a/python/src/components/GroupTree/components/Settings/__snapshots__/DateTimeSlider.test.tsx.snap b/python/src/components/GroupTree/components/Settings/__snapshots__/DateTimeSlider.test.tsx.snap deleted file mode 100644 index 1cebc98cd..000000000 --- a/python/src/components/GroupTree/components/Settings/__snapshots__/DateTimeSlider.test.tsx.snap +++ /dev/null @@ -1,76 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Test Date-Time Slider snapshot test 1`] = ` -
- - Time Steps - - - - - - - - - - - - - -
-`; diff --git a/python/src/components/GroupTree/components/Settings/__snapshots__/FlowRateSelector.test.tsx.snap b/python/src/components/GroupTree/components/Settings/__snapshots__/FlowRateSelector.test.tsx.snap deleted file mode 100644 index e9f903aa1..000000000 --- a/python/src/components/GroupTree/components/Settings/__snapshots__/FlowRateSelector.test.tsx.snap +++ /dev/null @@ -1,134 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Test flow rate selector component snapshot test 1`] = ` -.c1 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - position: relative; - margin: 0; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - font-family: Equinor; - font-size: 0.750rem; - font-weight: 500; - line-height: 1.333em; - text-align: left; - margin-left: 8px; - margin-right: 8px; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); -} - -.c2 { - margin: 0; -} - -.c0 { - min-width: 100px; - width: 100%; -} - -.c3 { - border: none; - border-radius: 0; - box-shadow: inset 0 -1px 0 0 var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - margin: 0; - color: var(--eds_text__static_icons__default,rgba(61,61,61,1)); - font-family: Equinor; - font-size: 1.000rem; - font-weight: 400; - line-height: 1.500em; - -webkit-letter-spacing: 0.025em; - -moz-letter-spacing: 0.025em; - -ms-letter-spacing: 0.025em; - letter-spacing: 0.025em; - text-align: left; - padding-left: 8px; - padding-top: 6px; - padding-right: 8px; - padding-bottom: 6px; - padding-right: calc(8px *2 + 24px); - display: block; - margin: 0; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%236f6f6f' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"),linear-gradient( to bottom,var(--eds_ui_background__light,rgba(247,247,247,1)) 0%,var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - background-repeat: no-repeat,repeat; - background-position: right 8px top 50%; - width: 100%; -} - -.c3:active, -.c3:focus { - box-shadow: none; - outline: 2px solid var(--eds_interactive_primary__resting,rgba(0,112,121,1)); - outline-offset: 0px; -} - -.c3:disabled { - color: var(--eds_interactive__disabled__text,rgba(190,190,190,1)); - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23bebebe' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"),linear-gradient( to bottom,var(--eds_ui_background__light,rgba(247,247,247,1)) 0%,var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - cursor: not-allowed; - box-shadow: none; - outline: none; -} - -.c3:disabled .arrow-icon { - fill: red; -} - -.c3:disabled:focus, -.c3:disabled:active { - outline: none; -} - -
- - -
-`; diff --git a/python/src/components/GroupTree/components/Settings/__snapshots__/NodeInfoSelector.test.tsx.snap b/python/src/components/GroupTree/components/Settings/__snapshots__/NodeInfoSelector.test.tsx.snap deleted file mode 100644 index 3925b007b..000000000 --- a/python/src/components/GroupTree/components/Settings/__snapshots__/NodeInfoSelector.test.tsx.snap +++ /dev/null @@ -1,119 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Test flow rate selector component snapshot test 1`] = ` -.c1 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - position: relative; - margin: 0; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - font-family: Equinor; - font-size: 0.750rem; - font-weight: 500; - line-height: 1.333em; - text-align: left; - margin-left: 8px; - margin-right: 8px; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); -} - -.c2 { - margin: 0; -} - -.c0 { - min-width: 100px; - width: 100%; -} - -.c3 { - border: none; - border-radius: 0; - box-shadow: inset 0 -1px 0 0 var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - margin: 0; - color: var(--eds_text__static_icons__default,rgba(61,61,61,1)); - font-family: Equinor; - font-size: 1.000rem; - font-weight: 400; - line-height: 1.500em; - -webkit-letter-spacing: 0.025em; - -moz-letter-spacing: 0.025em; - -ms-letter-spacing: 0.025em; - letter-spacing: 0.025em; - text-align: left; - padding-left: 8px; - padding-top: 6px; - padding-right: 8px; - padding-bottom: 6px; - padding-right: calc(8px *2 + 24px); - display: block; - margin: 0; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%236f6f6f' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"),linear-gradient( to bottom,var(--eds_ui_background__light,rgba(247,247,247,1)) 0%,var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - background-repeat: no-repeat,repeat; - background-position: right 8px top 50%; - width: 100%; -} - -.c3:active, -.c3:focus { - box-shadow: none; - outline: 2px solid var(--eds_interactive_primary__resting,rgba(0,112,121,1)); - outline-offset: 0px; -} - -.c3:disabled { - color: var(--eds_interactive__disabled__text,rgba(190,190,190,1)); - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23bebebe' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"),linear-gradient( to bottom,var(--eds_ui_background__light,rgba(247,247,247,1)) 0%,var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - cursor: not-allowed; - box-shadow: none; - outline: none; -} - -.c3:disabled .arrow-icon { - fill: red; -} - -.c3:disabled:focus, -.c3:disabled:active { - outline: none; -} - -
- - -
-`; diff --git a/python/src/components/GroupTree/components/Settings/__snapshots__/SettingsBar.test.tsx.snap b/python/src/components/GroupTree/components/Settings/__snapshots__/SettingsBar.test.tsx.snap deleted file mode 100644 index 313ae5727..000000000 --- a/python/src/components/GroupTree/components/Settings/__snapshots__/SettingsBar.test.tsx.snap +++ /dev/null @@ -1,310 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Test Settins Bar component snapshot test 1`] = ` -.c4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - position: relative; - margin: 0; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - font-family: Equinor; - font-size: 0.750rem; - font-weight: 500; - line-height: 1.333em; - text-align: left; - margin-left: 8px; - margin-right: 8px; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); -} - -.c5 { - margin: 0; -} - -.c0 { - background: var(--eds_ui_background__default,rgba(255,255,255,1)); - box-shadow: 0 0 1px rgba(0,0,0,0.14); -} - -.c1 { - height: 64px; - background: var(--eds_ui_background__default,rgba(255,255,255,1)); - box-sizing: border-box; - display: grid; - grid-column-gap: 24px; - grid-template-columns: auto 1fr auto; - grid-template-areas: 'left center right'; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border-bottom: 2px solid var(--eds_ui_background__light,rgba(247,247,247,1)); - padding-left: 24px; - padding-top: 8px; - padding-right: 24px; - padding-bottom: 8px; - margin: 0; - color: var(--eds_navigation__menu_title_color,rgba(61,61,61,1)); - font-family: Equinor; - font-size: 1.000rem; - font-weight: 400; - line-height: 1.000em; - -webkit-letter-spacing: 0.013em; - -moz-letter-spacing: 0.013em; - -ms-letter-spacing: 0.013em; - letter-spacing: 0.013em; - text-align: left; - position: -webkit-sticky; - position: sticky; - top: 0; - z-index: 1100; -} - -.c7 { - grid-area: right; - text-align: right; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; -} - -.c2 { - grid-area: left; - display: grid; - grid-template-columns: auto auto; - grid-gap: 12px; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.c3 { - min-width: 100px; - width: 100%; -} - -.c6 { - border: none; - border-radius: 0; - box-shadow: inset 0 -1px 0 0 var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - margin: 0; - color: var(--eds_text__static_icons__default,rgba(61,61,61,1)); - font-family: Equinor; - font-size: 1.000rem; - font-weight: 400; - line-height: 1.500em; - -webkit-letter-spacing: 0.025em; - -moz-letter-spacing: 0.025em; - -ms-letter-spacing: 0.025em; - letter-spacing: 0.025em; - text-align: left; - padding-left: 8px; - padding-top: 6px; - padding-right: 8px; - padding-bottom: 6px; - padding-right: calc(8px *2 + 24px); - display: block; - margin: 0; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%236f6f6f' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"),linear-gradient( to bottom,var(--eds_ui_background__light,rgba(247,247,247,1)) 0%,var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - background-repeat: no-repeat,repeat; - background-position: right 8px top 50%; - width: 100%; -} - -.c6:active, -.c6:focus { - box-shadow: none; - outline: 2px solid var(--eds_interactive_primary__resting,rgba(0,112,121,1)); - outline-offset: 0px; -} - -.c6:disabled { - color: var(--eds_interactive__disabled__text,rgba(190,190,190,1)); - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23bebebe' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"),linear-gradient( to bottom,var(--eds_ui_background__light,rgba(247,247,247,1)) 0%,var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - cursor: not-allowed; - box-shadow: none; - outline: none; -} - -.c6:disabled .arrow-icon { - fill: red; -} - -.c6:disabled:focus, -.c6:disabled:active { - outline: none; -} - -
-
-
- - -
-
- - -
-
-
-
- - Time Steps - - - - - - - - - - - - - -
-
-
-`; diff --git a/python/src/components/GroupTree/components/__snapshots__/GroupTreeComponent.test.tsx.snap b/python/src/components/GroupTree/components/__snapshots__/GroupTreeComponent.test.tsx.snap deleted file mode 100644 index dc10f888e..000000000 --- a/python/src/components/GroupTree/components/__snapshots__/GroupTreeComponent.test.tsx.snap +++ /dev/null @@ -1,492 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Test GroupTree Component snapshot test 1`] = ` -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - position: relative; - margin: 0; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - font-family: Equinor; - font-size: 0.750rem; - font-weight: 500; - line-height: 1.333em; - text-align: left; - margin-left: 8px; - margin-right: 8px; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); -} - -.c4 { - margin: 0; -} - -.c0 { - height: 64px; - top: 0; - position: -webkit-sticky; - position: sticky; - background: var(--eds_ui_background__default,rgba(255,255,255,1)); - box-sizing: border-box; - z-index: 250; - display: grid; - grid-column-gap: 40px; - grid-template-columns: auto 1fr auto; - grid-template-areas: 'left center right'; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border-bottom: 2px var(--eds_ui_background__light,rgba(247,247,247,1)); - padding-left: 40px; - padding-top: 8px; - padding-right: 40px; - padding-bottom: 8px; - margin: 0; - color: rgba(61,61,61,1); - font-family: Equinor; - font-size: 1.000rem; - font-weight: 400; - line-height: 1.000em; - -webkit-letter-spacing: 0.013em; - -moz-letter-spacing: 0.013em; - -ms-letter-spacing: 0.013em; - letter-spacing: 0.013em; - text-align: left; -} - -.c6 { - grid-area: right; - text-align: right; -} - -.c1 { - grid-area: left; - display: grid; - grid-template-columns: auto auto; - grid-gap: 24px; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.c5 { - border: none; - border-radius: 0; - box-shadow: inset 0 -1px 0 0 var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - padding-left: 8px; - padding-top: 6px; - padding-right: 8px; - padding-bottom: 6px; - margin: 0; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - font-family: Equinor; - font-size: 1.000rem; - font-weight: 400; - line-height: 1.500em; - -webkit-letter-spacing: 0.025em; - -moz-letter-spacing: 0.025em; - -ms-letter-spacing: 0.025em; - letter-spacing: 0.025em; - text-align: left; - padding-right: calc(8px *2 + 24px); - display: block; - margin: 0; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%236f6f6f' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"), linear-gradient( to bottom, var(--eds_ui_background__light,rgba(247,247,247,1)) 0%, var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - background-repeat: no-repeat,repeat; - background-position: right 8px top 50%; - width: 100%; -} - -.c5:active, -.c5:focus { - box-shadow: none; - outline: 2px solid var(--eds_interactive_primary__resting,rgba(0,112,121,1)); - outline-offset: 0px; -} - -.c5:disabled { - color: var(--eds_interactive__disabled__text,rgba(190,190,190,1)); - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23bebebe' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"), linear-gradient( to bottom, var(--eds_ui_background__light,rgba(247,247,247,1)) 0%, var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - cursor: not-allowed; - box-shadow: none; - outline: none; -} - -.c5:disabled .arrow-icon { - fill: red; -} - -.c5:disabled:focus, -.c5:disabled:active { - outline: none; -} - -.c2 { - min-width: 100px; - width: 100%; -} - -
-
-
-
- - -
-
- - -
-
-
-
- - Time Steps - - - - - - - - - - - - - -
-
-
-
- - - - - Water Rate 20 -Oil Rate 30 -Gas Rate 40 -Water Injection Rate 50 -Gas Injection Rate 60 - - - - - - Water Rate 25 -Oil Rate 35 -Gas Rate 45 -Water Injection Rate 55 -Gas Injection Rate 65 - - - - - - - - - - - - - - - TRE_1 - - - 5 - - - - Pressure 5 - - - - - - - TRE_1_1 - - - 20 - - - - Pressure 20 -Bottom Hole Pressure 11 -wmctl 12 - - - - - - - TRE_1_2 - - - 22 - - - - Pressure 22 -wmctl 10 - - - - - -
-
-`; diff --git a/python/src/components/GroupTree/components/__snapshots__/GroupTreeViewer.test.tsx.snap b/python/src/components/GroupTree/components/__snapshots__/GroupTreeViewer.test.tsx.snap deleted file mode 100644 index d0082affa..000000000 --- a/python/src/components/GroupTree/components/__snapshots__/GroupTreeViewer.test.tsx.snap +++ /dev/null @@ -1,492 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Test GroupTreeViewer snapshot test 1`] = ` -.c3 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - position: relative; - margin: 0; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - font-family: Equinor; - font-size: 0.750rem; - font-weight: 500; - line-height: 1.333em; - text-align: left; - margin-left: 8px; - margin-right: 8px; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); -} - -.c4 { - margin: 0; -} - -.c0 { - height: 64px; - top: 0; - position: -webkit-sticky; - position: sticky; - background: var(--eds_ui_background__default,rgba(255,255,255,1)); - box-sizing: border-box; - z-index: 250; - display: grid; - grid-column-gap: 40px; - grid-template-columns: auto 1fr auto; - grid-template-areas: 'left center right'; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border-bottom: 2px var(--eds_ui_background__light,rgba(247,247,247,1)); - padding-left: 40px; - padding-top: 8px; - padding-right: 40px; - padding-bottom: 8px; - margin: 0; - color: rgba(61,61,61,1); - font-family: Equinor; - font-size: 1.000rem; - font-weight: 400; - line-height: 1.000em; - -webkit-letter-spacing: 0.013em; - -moz-letter-spacing: 0.013em; - -ms-letter-spacing: 0.013em; - letter-spacing: 0.013em; - text-align: left; -} - -.c6 { - grid-area: right; - text-align: right; -} - -.c1 { - grid-area: left; - display: grid; - grid-template-columns: auto auto; - grid-gap: 24px; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.c5 { - border: none; - border-radius: 0; - box-shadow: inset 0 -1px 0 0 var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - padding-left: 8px; - padding-top: 6px; - padding-right: 8px; - padding-bottom: 6px; - margin: 0; - color: var(--eds_text__static_icons__tertiary,rgba(111,111,111,1)); - font-family: Equinor; - font-size: 1.000rem; - font-weight: 400; - line-height: 1.500em; - -webkit-letter-spacing: 0.025em; - -moz-letter-spacing: 0.025em; - -ms-letter-spacing: 0.025em; - letter-spacing: 0.025em; - text-align: left; - padding-right: calc(8px *2 + 24px); - display: block; - margin: 0; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%236f6f6f' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"), linear-gradient( to bottom, var(--eds_ui_background__light,rgba(247,247,247,1)) 0%, var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - background-repeat: no-repeat,repeat; - background-position: right 8px top 50%; - width: 100%; -} - -.c5:active, -.c5:focus { - box-shadow: none; - outline: 2px solid var(--eds_interactive_primary__resting,rgba(0,112,121,1)); - outline-offset: 0px; -} - -.c5:disabled { - color: var(--eds_interactive__disabled__text,rgba(190,190,190,1)); - background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='%23bebebe' d='M7 9.5l5 5 5-5H7z'/%3E%3C/svg%3E"), linear-gradient( to bottom, var(--eds_ui_background__light,rgba(247,247,247,1)) 0%, var(--eds_ui_background__light,rgba(247,247,247,1)) 100% ); - cursor: not-allowed; - box-shadow: none; - outline: none; -} - -.c5:disabled .arrow-icon { - fill: red; -} - -.c5:disabled:focus, -.c5:disabled:active { - outline: none; -} - -.c2 { - min-width: 100px; - width: 100%; -} - -
-
-
-
- - -
-
- - -
-
-
-
- - Time Steps - - - - - - - - - - - - - -
-
-
-
- - - - - Water Rate 20 -Oil Rate 30 -Gas Rate 40 -Water Injection Rate 50 -Gas Injection Rate 60 - - - - - - Water Rate 25 -Oil Rate 35 -Gas Rate 45 -Water Injection Rate 55 -Gas Injection Rate 65 - - - - - - - - - - - - - - - TRE_1 - - - 5 - - - - Pressure 5 - - - - - - - TRE_1_1 - - - 20 - - - - Pressure 20 -Bottom Hole Pressure 11 -wmctl 12 - - - - - - - TRE_1_2 - - - 22 - - - - Pressure 22 -wmctl 10 - - - - - -
-
-`; diff --git a/python/src/components/GroupTree/storybook/components/DateTimeSlider.stories.tsx b/python/src/components/GroupTree/storybook/components/DateTimeSlider.stories.tsx deleted file mode 100644 index 6ab291962..000000000 --- a/python/src/components/GroupTree/storybook/components/DateTimeSlider.stories.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from "react"; -import DataProvider from "../../components/DataLoader"; -import DateTimeSlider from "../../components/Settings/DateTimeSlider"; - -export default { - component: DateTimeSlider, - title: "GroupTree/Components/Settings/DateTimeSlider", - argTypes: { - id: { - description: - "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.", - }, - data: { - description: "Array of JSON objects describing group tree data.", - }, - }, -}; - -const Template = (args) => { - return ( - - - - ); -}; - -export const Default = Template.bind({}); -Default.args = { - id: "grouptree", - data: require("../../../../../../example-data/group-tree.json"), -}; diff --git a/python/src/components/GroupTree/storybook/components/FlowRateSelector.stories.tsx b/python/src/components/GroupTree/storybook/components/FlowRateSelector.stories.tsx deleted file mode 100644 index a8b83ed47..000000000 --- a/python/src/components/GroupTree/storybook/components/FlowRateSelector.stories.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from "react"; -import DataProvider from "../../components/DataLoader"; -import FlowRateSelector from "../../components/Settings/FlowRateSelector"; - -import { EdgeMetadata } from "@webviz/group-tree-plot"; - -const edgeMetadataList: EdgeMetadata[] = [ - { key: "waterrate", label: "Water Rate" }, - { key: "oilrate", label: "Oil Rate" }, - { key: "gasrate", label: "Gas Rate" }, - { key: "waterinjrate", label: "Water Injection Rate" }, - { key: "gasinjrate", label: "Gas Injection Rate" }, -]; - -export default { - component: FlowRateSelector, - title: "GroupTree/Components/Settings/FlowRateSelector", - argTypes: { - id: { - description: - "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.", - }, - data: { - description: "Array of JSON objects describing group tree data.", - }, - }, -}; - -const Template = (args) => { - return ( - - - - ); -}; - -export const Default = Template.bind({}); -Default.args = { - id: "grouptree", - data: require("../../../../../../example-data/group-tree.json"), - edgeMetadataList, -}; diff --git a/python/src/components/GroupTree/storybook/components/GroupTreeViewer.stories.tsx b/python/src/components/GroupTree/storybook/components/GroupTreeViewer.stories.tsx deleted file mode 100644 index fa90ccf49..000000000 --- a/python/src/components/GroupTree/storybook/components/GroupTreeViewer.stories.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import React from "react"; -import DataProvider from "../../components/DataLoader"; -import GroupTreeViewer from "../../components/GroupTreeViewer"; - -import { EdgeMetadata, NodeMetadata } from "@webviz/group-tree-plot"; - -const edgeMetadataList: EdgeMetadata[] = [ - { key: "waterrate", label: "Water Rate" }, - { key: "oilrate", label: "Oil Rate" }, - { key: "gasrate", label: "Gas Rate" }, - { key: "waterinjrate", label: "Water Injection Rate" }, - { key: "gasinjrate", label: "Gas Injection Rate" }, -]; - -const nodeMetadataList: NodeMetadata[] = [ - { key: "pressure", label: "Pressure" }, - { key: "bhp", label: "Bottom Hole Pressure" }, -]; - -export default { - component: GroupTreeViewer, - title: "GroupTree/Components/GroupTreeViewer", - argTypes: { - id: { - description: - "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.", - }, - data: { - description: "Array of JSON objects describing group tree data.", - }, - }, -}; - -const Template = (args) => { - return ( - - {}} - /> - - ); -}; - -export const Default = Template.bind({}); -Default.args = { - id: "grouptree", - data: require("../../../../../../example-data/group-tree.json"), - edgeMetadataList, - nodeMetadataList, -}; diff --git a/python/src/components/GroupTree/storybook/components/SettingsBar.stories.tsx b/python/src/components/GroupTree/storybook/components/SettingsBar.stories.tsx deleted file mode 100644 index 563da6064..000000000 --- a/python/src/components/GroupTree/storybook/components/SettingsBar.stories.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import React from "react"; -import DataProvider from "../../components/DataLoader"; -import SettingsBar from "../../components/Settings/SettingsBar"; - -import { EdgeMetadata, NodeMetadata } from "@webviz/group-tree-plot"; - -const edgeMetadataList: EdgeMetadata[] = [ - { key: "waterrate", label: "Water Rate" }, - { key: "oilrate", label: "Oil Rate" }, - { key: "gasrate", label: "Gas Rate" }, - { key: "waterinjrate", label: "Water Injection Rate" }, - { key: "gasinjrate", label: "Gas Injection Rate" }, -]; - -const nodeMetadataList: NodeMetadata[] = [ - { key: "pressure", label: "Pressure" }, - { key: "bhp", label: "Bottom Hole Pressure" }, -]; - -export default { - component: SettingsBar, - title: "GroupTree/Components/SettingsBar", - argTypes: { - id: { - description: - "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.", - }, - data: { - description: "Array of JSON objects describing group tree data.", - }, - }, -}; - -const Template = (args) => { - return ( - - - - ); -}; - -export const Default = Template.bind({}); -Default.args = { - id: "grouptree", - data: require("../../../../../../example-data/group-tree.json"), - edgeMetadataList, - nodeMetadataList, -}; diff --git a/python/src/components/GroupTree/test/TestWrapper.tsx b/python/src/components/GroupTree/test/TestWrapper.tsx deleted file mode 100644 index 6195f4934..000000000 --- a/python/src/components/GroupTree/test/TestWrapper.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from "react"; -import { Provider } from "react-redux"; -import { DataContext } from "../components/DataLoader"; -import { createReduxStore } from "../redux/store"; -import { testState } from "./testReduxState"; - -import exampleData from "../../../../../example-data/group-tree.json"; - -export const testStore = createReduxStore(testState); -testStore.dispatch = jest.fn() as never; - -// eslint-disable-next-line react/prop-types -export const Wrapper = ({ - children, -}: { - children: JSX.Element; -}): JSX.Element => { - return ( - - {children} - - ); -}; diff --git a/python/src/components/GroupTree/test/performanceMetrics.ts b/python/src/components/GroupTree/test/performanceMetrics.ts deleted file mode 100644 index c15bcbd72..000000000 --- a/python/src/components/GroupTree/test/performanceMetrics.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -const perf_metrics: any[] = []; - -const logTimes = ( - id: any, - phase: any, - actualDuration: any, - baseDuration: any -) => { - console.log( - `${id}'s phase: ${phase}\nActual time: ${actualDuration} \nBase time: ${baseDuration}` - ); - perf_metrics.push([id, phase, actualDuration, baseDuration]); -}; - -export default logTimes; -export const obj = { - perf_metrics, -}; diff --git a/python/src/components/GroupTree/test/testReduxState.ts b/python/src/components/GroupTree/test/testReduxState.ts deleted file mode 100644 index 50e312de4..000000000 --- a/python/src/components/GroupTree/test/testReduxState.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { UISettings } from "../redux/types"; - -export const testState = { - id: "test", - ui: { - currentDateTime: "2018-02-01", - currentFlowRate: "waterrate", - currentNodeInfo: "pressure", - } as UISettings, -}; diff --git a/typescript/packages/group-tree-plot/example-data/dated-trees.ts b/typescript/packages/group-tree-plot/example-data/dated-trees.ts new file mode 100644 index 000000000..5206e786c --- /dev/null +++ b/typescript/packages/group-tree-plot/example-data/dated-trees.ts @@ -0,0 +1,153 @@ +import { DatedTrees } from "../src/types"; + +/** + * This is example data based on the Group Tree data in `group-tree.json`-file found in the `example-data`-folder. + * + * This is converted to .ts file to obtain type safety. + */ +export const exampleDatedTrees: DatedTrees = [ + { + dates: ["2018-02-01", "2018-03-01"], + tree: { + node_label: "TRE_1", + node_type: "Group", + node_data: { + pressure: [5, 10], + }, + edge_label: "VFP10", + edge_data: { + waterrate: [10, 10], + oilrate: [10, 10], + gasrate: [10, 10], + waterinjrate: [10, 10], + gasinjrate: [10, 10], + }, + children: [ + { + node_label: "TRE_1_1", + node_type: "Well", + node_data: { + pressure: [20, 30], + bhp: [11, 10], + wmctl: [12, 10], + }, + edge_label: "VFP11", + edge_data: { + waterrate: [20, 30], + oilrate: [30, 40], + gasrate: [40, 50], + waterinjrate: [50, 60], + gasinjrate: [60, 70], + }, + }, + { + node_label: "TRE_1_2", + node_type: "Well", + node_data: { + pressure: [22, 30], + wmctl: [10, 10], + }, + edge_label: "VFP12", + edge_data: { + waterrate: [25, 35], + oilrate: [35, 45], + gasrate: [45, 55], + waterinjrate: [55, 65], + gasinjrate: [65, 75], + }, + }, + ], + }, + }, + + { + dates: ["2019-02-01", "2019-03-01"], + tree: { + node_label: "TRE_1", + node_type: "Group", + node_data: { + pressure: [5, 10], + }, + edge_label: "VFP10", + edge_data: { + waterrate: [10, 10], + oilrate: [10, 10], + gasrate: [10, 10], + waterinjrate: [10, 10], + gasinjrate: [10, 10], + }, + children: [ + { + node_label: "TRE_1_1", + node_type: "Well", + node_data: { + pressure: [20, 30], + bhp: [10, 10], + wmctl: [10, 10], + }, + edge_label: "VFP11", + edge_data: { + waterrate: [20, 30], + oilrate: [30, 40], + gasrate: [40, 50], + waterinjrate: [50, 60], + gasinjrate: [60, 70], + }, + children: [ + { + node_label: "TRE_1_1_1", + node_type: "Well", + node_data: { + pressure: [20, 30], + bhp: [10, 10], + wmctl: [10, 10], + }, + edge_label: "VFP12", + edge_data: { + waterrate: [20, 30], + oilrate: [30, 40], + gasrate: [40, 50], + waterinjrate: [50, 60], + gasinjrate: [60, 70], + }, + }, + { + node_label: "TRE_1_1_2", + node_type: "Well", + node_data: { + pressure: [20, 30], + bhp: [10, 10], + wmctl: [10, 10], + }, + edge_label: "VFP13", + edge_data: { + waterrate: [20, 30], + oilrate: [30, 40], + gasrate: [40, 50], + waterinjrate: [50, 60], + gasinjrate: [60, 70], + }, + }, + ], + }, + { + node_label: "TRE_1_2", + node_type: "Well", + node_data: { + pressure: [20, 30], + bhp: [10, 10], + wmctl: [10, 10], + }, + edge_label: "VFP14", + edge_data: { + waterrate: [20, 30], + oilrate: [30, 40], + gasrate: [40, 50], + waterinjrate: [50, 60], + gasinjrate: [60, 70], + }, + }, + ], + }, + }, +]; diff --git a/python/src/components/GroupTree/storybook/GroupTreeComponent.stories.tsx b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx similarity index 50% rename from python/src/components/GroupTree/storybook/GroupTreeComponent.stories.tsx rename to typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx index ee5458171..533f36227 100644 --- a/python/src/components/GroupTree/storybook/GroupTreeComponent.stories.tsx +++ b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx @@ -1,11 +1,13 @@ import React from "react"; -import GroupTreeComponent from "../components/GroupTreeComponent"; +import { GroupTreePlot } from "../GroupTreePlot"; -import { EdgeMetadata, NodeMetadata } from "@webviz/group-tree-plot/src/types"; +import type { EdgeMetadata, NodeMetadata } from "../types"; + +import { exampleDatedTrees } from "../../example-data/dated-trees"; export default { - component: GroupTreeComponent, - title: "GroupTree", + component: GroupTreePlot, + title: "GroupTreePlot", }; const edgeMetadataList: EdgeMetadata[] = [ @@ -23,13 +25,26 @@ const nodeMetadataList: NodeMetadata[] = [ ]; const Template = (args) => { - return ; + return ( + + ); }; export const Default = Template.bind({}); Default.args = { - id: "grouptree", - data: require("../../../../../example-data/group-tree.json"), + id: "grouptreeplot", + datedTrees: exampleDatedTrees, edgeMetadataList: edgeMetadataList, nodeMetadataList: nodeMetadataList, + selectedDateTime: "2018-02-01", + selectedEdgeKey: "oilrate", + selectedNodeKey: "pressure", }; diff --git a/typescript/packages/group-tree-plot/src/types.ts b/typescript/packages/group-tree-plot/src/types.ts index 4e0bb6b90..9c3abdaf2 100644 --- a/typescript/packages/group-tree-plot/src/types.ts +++ b/typescript/packages/group-tree-plot/src/types.ts @@ -23,6 +23,7 @@ export interface EdgeMetadata { } // Recursively defined tree node +// The snake_case naming is to match the python naming export interface RecursiveTreeNode { node_type: "Group" | "Well"; node_label: string; From 80bc93d7894bea0df1ab5c311b5bb6added7f833 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Wed, 29 Nov 2023 10:36:56 +0100 Subject: [PATCH 08/20] Remove unwanted autogenerated file --- .../groupTreeAssembler.d.ts | 60 ------------------- 1 file changed, 60 deletions(-) delete mode 100644 typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.d.ts diff --git a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.d.ts b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.d.ts deleted file mode 100644 index 71263bbed..000000000 --- a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Class to assemble Group tree visualization. Creates an _svg, and appends to the - * assigned HTML element. Draws the tree provided as tree_data with the current flow rate, - * node info and date time. - * - * Provides methods to update selected date time, and change flow rate and node info. * - */ -export default class GroupTreeAssembler { - /** - * Initialize all trees in the group tree datastructure, once for the entire visualization. - * - */ - static initHierarchies(tree_data: any, height: any): any; - /** - * - * @param dom_element_id - id of the HTML element to append the _svg to - * @param {DatedTrees} datedTrees - List of dated tree data structure containing the trees to visualize - * @param initialFlowRate - key identifying the initial selected flow rate for the tree edges - * @param initialNodeInfo - key identifying the initial selected node info for the tree nodes - * @param currentDateTime - the initial/current date time - * @param edgeMetadataList - List of metadata for the edge keys in the tree data structure - * @param nodeMetadataList - List of metadata for the node keys in the tree data structure - */ - constructor(dom_element_id: any, datedTrees: DatedTrees, initialFlowRate: any, initialNodeInfo: any, currentDateTime: any, edgeMetadataList: any, nodeMetadataList: any); - _propertyToLabelMap: Map; - _currentFlowRate: any; - _currentNodeInfo: any; - _currentDateTime: any; - _transitionTime: number; - _path_scale: Map; - _width: number; - _svg: d3.Selection; - _textpaths: d3.Selection; - _renderTree: d3.TreeLayout; - _data: any; - _currentTree: {}; - /** - * @returns {*} -The initialized hierarchical group tree data structure - */ - get data(): any; - /** - * Set the flowrate and update display of all edges accordingly. - * - * @param flowrate - key identifying the flowrate of the incoming edge - */ - set flowrate(arg: any); - get flowrate(): any; - set nodeinfo(arg: any); - get nodeinfo(): any; - getEdgeStrokeWidth(key: any, val: any): string; - /** - * Sets the state of the current tree, and updates the tree visualization accordingly. - * The state is changed either due to a branch open/close, or that the tree is entirely changed - * when moving back and fourth in time. - * - * @param root - */ - update(newDateTime: any): void; -} -import * as d3 from "d3"; From 16502f4938e003cf4af5899a35782e1dfad941ab Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Wed, 29 Nov 2023 10:37:12 +0100 Subject: [PATCH 09/20] Adjust typing in example data --- .../example-data/dated-trees.ts | 275 +++++++++--------- .../src/storybook/GroupTreePlot.stories.tsx | 2 +- 2 files changed, 140 insertions(+), 137 deletions(-) diff --git a/typescript/packages/group-tree-plot/example-data/dated-trees.ts b/typescript/packages/group-tree-plot/example-data/dated-trees.ts index 5206e786c..f5ecd28f3 100644 --- a/typescript/packages/group-tree-plot/example-data/dated-trees.ts +++ b/typescript/packages/group-tree-plot/example-data/dated-trees.ts @@ -1,153 +1,156 @@ -import { DatedTrees } from "../src/types"; +import { DatedTree, DatedTrees } from "../src/types"; /** * This is example data based on the Group Tree data in `group-tree.json`-file found in the `example-data`-folder. * * This is converted to .ts file to obtain type safety. */ -export const exampleDatedTrees: DatedTrees = [ - { - dates: ["2018-02-01", "2018-03-01"], - tree: { - node_label: "TRE_1", - node_type: "Group", - node_data: { - pressure: [5, 10], - }, - edge_label: "VFP10", - edge_data: { - waterrate: [10, 10], - oilrate: [10, 10], - gasrate: [10, 10], - waterinjrate: [10, 10], - gasinjrate: [10, 10], + +const firstDatedTree: DatedTree = { + dates: ["2018-02-01", "2018-03-01"], + tree: { + node_label: "TRE_1", + node_type: "Group", + node_data: { + pressure: [5, 10], + }, + edge_label: "VFP10", + edge_data: { + waterrate: [10, 10], + oilrate: [10, 10], + gasrate: [10, 10], + waterinjrate: [10, 10], + gasinjrate: [10, 10], + }, + children: [ + { + node_label: "TRE_1_1", + node_type: "Well", + node_data: { + pressure: [20, 30], + bhp: [11, 10], + wmctl: [12, 10], + }, + edge_label: "VFP11", + edge_data: { + waterrate: [20, 30], + oilrate: [30, 40], + gasrate: [40, 50], + waterinjrate: [50, 60], + gasinjrate: [60, 70], + }, + children: undefined, }, - children: [ - { - node_label: "TRE_1_1", - node_type: "Well", - node_data: { - pressure: [20, 30], - bhp: [11, 10], - wmctl: [12, 10], - }, - edge_label: "VFP11", - edge_data: { - waterrate: [20, 30], - oilrate: [30, 40], - gasrate: [40, 50], - waterinjrate: [50, 60], - gasinjrate: [60, 70], - }, + { + node_label: "TRE_1_2", + node_type: "Well", + node_data: { + pressure: [22, 30], + wmctl: [10, 10], }, - { - node_label: "TRE_1_2", - node_type: "Well", - node_data: { - pressure: [22, 30], - wmctl: [10, 10], - }, - edge_label: "VFP12", - edge_data: { - waterrate: [25, 35], - oilrate: [35, 45], - gasrate: [45, 55], - waterinjrate: [55, 65], - gasinjrate: [65, 75], - }, + edge_label: "VFP12", + edge_data: { + waterrate: [25, 35], + oilrate: [35, 45], + gasrate: [45, 55], + waterinjrate: [55, 65], + gasinjrate: [65, 75], }, - ], - }, + children: undefined, + }, + ], }, +}; - { - dates: ["2019-02-01", "2019-03-01"], - tree: { - node_label: "TRE_1", - node_type: "Group", - node_data: { - pressure: [5, 10], - }, - edge_label: "VFP10", - edge_data: { - waterrate: [10, 10], - oilrate: [10, 10], - gasrate: [10, 10], - waterinjrate: [10, 10], - gasinjrate: [10, 10], - }, - children: [ - { - node_label: "TRE_1_1", - node_type: "Well", - node_data: { - pressure: [20, 30], - bhp: [10, 10], - wmctl: [10, 10], - }, - edge_label: "VFP11", - edge_data: { - waterrate: [20, 30], - oilrate: [30, 40], - gasrate: [40, 50], - waterinjrate: [50, 60], - gasinjrate: [60, 70], - }, - children: [ - { - node_label: "TRE_1_1_1", - node_type: "Well", - node_data: { - pressure: [20, 30], - bhp: [10, 10], - wmctl: [10, 10], - }, - edge_label: "VFP12", - edge_data: { - waterrate: [20, 30], - oilrate: [30, 40], - gasrate: [40, 50], - waterinjrate: [50, 60], - gasinjrate: [60, 70], - }, +const secondDatedTree: DatedTree = { + dates: ["2019-02-01", "2019-03-01"], + tree: { + node_label: "TRE_1", + node_type: "Group", + node_data: { + pressure: [5, 10], + }, + edge_label: "VFP10", + edge_data: { + waterrate: [10, 10], + oilrate: [10, 10], + gasrate: [10, 10], + waterinjrate: [10, 10], + gasinjrate: [10, 10], + }, + children: [ + { + node_label: "TRE_1_1", + node_type: "Well", + node_data: { + pressure: [20, 30], + bhp: [10, 10], + wmctl: [10, 10], + }, + edge_label: "VFP11", + edge_data: { + waterrate: [20, 30], + oilrate: [30, 40], + gasrate: [40, 50], + waterinjrate: [50, 60], + gasinjrate: [60, 70], + }, + children: [ + { + node_label: "TRE_1_1_1", + node_type: "Well", + node_data: { + pressure: [20, 30], + bhp: [10, 10], + wmctl: [10, 10], }, - { - node_label: "TRE_1_1_2", - node_type: "Well", - node_data: { - pressure: [20, 30], - bhp: [10, 10], - wmctl: [10, 10], - }, - edge_label: "VFP13", - edge_data: { - waterrate: [20, 30], - oilrate: [30, 40], - gasrate: [40, 50], - waterinjrate: [50, 60], - gasinjrate: [60, 70], - }, + edge_label: "VFP12", + edge_data: { + waterrate: [20, 30], + oilrate: [30, 40], + gasrate: [40, 50], + waterinjrate: [50, 60], + gasinjrate: [60, 70], }, - ], - }, - { - node_label: "TRE_1_2", - node_type: "Well", - node_data: { - pressure: [20, 30], - bhp: [10, 10], - wmctl: [10, 10], }, - edge_label: "VFP14", - edge_data: { - waterrate: [20, 30], - oilrate: [30, 40], - gasrate: [40, 50], - waterinjrate: [50, 60], - gasinjrate: [60, 70], + { + node_label: "TRE_1_1_2", + node_type: "Well", + node_data: { + pressure: [20, 30], + bhp: [10, 10], + wmctl: [10, 10], + }, + edge_label: "VFP13", + edge_data: { + waterrate: [20, 30], + oilrate: [30, 40], + gasrate: [40, 50], + waterinjrate: [50, 60], + gasinjrate: [60, 70], + }, }, + ], + }, + { + node_label: "TRE_1_2", + node_type: "Well", + node_data: { + pressure: [20, 30], + bhp: [10, 10], + wmctl: [10, 10], }, - ], - }, + edge_label: "VFP14", + edge_data: { + waterrate: [20, 30], + oilrate: [30, 40], + gasrate: [40, 50], + waterinjrate: [50, 60], + gasinjrate: [60, 70], + }, + }, + ], }, -]; +}; + +export const exampleDatedTrees: DatedTrees = [firstDatedTree, secondDatedTree]; diff --git a/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx index 533f36227..c363124fe 100644 --- a/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx +++ b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx @@ -21,7 +21,7 @@ const edgeMetadataList: EdgeMetadata[] = [ const nodeMetadataList: NodeMetadata[] = [ { key: "pressure", label: "Pressure", unit: "Bar" }, { key: "bhp", label: "Bottom Hole Pressure", unit: "N/m2" }, - { key: "wmctl", label: "Missing label" }, + { key: "wmctl", label: "Missing label", unit: "Unknown unit" }, ]; const Template = (args) => { From e84b65ef4458928d6235fc37023dde331654e6a3 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Wed, 29 Nov 2023 10:55:13 +0100 Subject: [PATCH 10/20] Remove test scripts and config --- typescript/packages/group-tree-plot/jest.config.js | 7 ------- typescript/packages/group-tree-plot/package.json | 5 ----- 2 files changed, 12 deletions(-) delete mode 100644 typescript/packages/group-tree-plot/jest.config.js diff --git a/typescript/packages/group-tree-plot/jest.config.js b/typescript/packages/group-tree-plot/jest.config.js deleted file mode 100644 index 52c5e0f33..000000000 --- a/typescript/packages/group-tree-plot/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -/** @type {import('jest').Config} */ - -const config = { - preset: "../../jest.config.js", -}; - -module.exports = config; diff --git a/typescript/packages/group-tree-plot/package.json b/typescript/packages/group-tree-plot/package.json index e9e19e82b..4f5357ba5 100644 --- a/typescript/packages/group-tree-plot/package.json +++ b/typescript/packages/group-tree-plot/package.json @@ -11,11 +11,6 @@ "transpile": "tsc --project ./tsconfig.json", "copy-files": "copyfiles --up 1 \"src/**/*.css\" dist/", "build": "git clean -xdff dist && npm run transpile && npm run copy-files", - "test_perf": "jest _performance", - "test_correctness": "jest --coverage --testPathIgnorePatterns='_performance'", - "test": "jest --coverage", - "test:update": "npm test -- --u", - "test:watch": "npm test -- --watch", "doc": "git clean -xdff docs && typedoc src" }, "author": "Equinor ", From 0931e8e0cdc94f49868cd050a8449bdf56bd4a45 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Wed, 29 Nov 2023 11:11:35 +0100 Subject: [PATCH 11/20] Deep clone dated trees as it is mutated within assembler --- .../src/GroupTreeAssembler/groupTreeAssembler.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js index 511016d2d..65ffe8585 100644 --- a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js +++ b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js @@ -6,6 +6,7 @@ */ import * as d3 from "d3"; import "./group_tree.css"; +import { cloneDeep } from "lodash"; /* eslint camelcase: "off" */ /* eslint array-callback-return: "off" */ @@ -41,6 +42,9 @@ export default class GroupTreeAssembler { edgeMetadataList, nodeMetadataList ) { + // Cloned as it is mutated within class + let clonedDatedTrees = cloneDeep(datedTrees); + // Add "#" if missing. if (dom_element_id.charAt(0) !== "#") { dom_element_id = "#" + dom_element_id; @@ -57,9 +61,9 @@ export default class GroupTreeAssembler { }); // Represent possible empty data by single empty node. - if (datedTrees.length === 0) { + if (clonedDatedTrees.length === 0) { currentDateTime = ""; - datedTrees = [ + clonedDatedTrees = [ { dates: [currentDateTime], tree: { @@ -80,7 +84,7 @@ export default class GroupTreeAssembler { const tree_values = {}; - datedTrees.map((datedTree) => { + clonedDatedTrees.map((datedTree) => { let tree = datedTree.tree; d3.hierarchy(tree, (d) => d.children).each((node) => { // edge_data @@ -130,7 +134,10 @@ export default class GroupTreeAssembler { this._renderTree = d3.tree().size([height, this._width]); - this._data = GroupTreeAssembler.initHierarchies(datedTrees, height); + this._data = GroupTreeAssembler.initHierarchies( + clonedDatedTrees, + height + ); this._currentTree = {}; From eb85810af023c4fefcc2fda572896ad0893c4821 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Wed, 29 Nov 2023 13:00:05 +0100 Subject: [PATCH 12/20] Fix usage of HTML element id Use the id of the divRef rather than props.id. GroupTreeAssembler was created before render if props.id was updated, thereby the id's were not in synch and the boundinRectClient read crashed. --- typescript/packages/group-tree-plot/src/GroupTreePlot.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx b/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx index 21f00cb33..b125b2a9a 100644 --- a/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx +++ b/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx @@ -42,12 +42,14 @@ export const GroupTreePlot: React.FC = ( if ( isMounted && - (!isEqual(prevDatedTrees, props.datedTrees) || prevId !== props.id) + divRef.current && + (!isEqual(prevDatedTrees, props.datedTrees) || + prevId !== divRef.current.id) ) { setPrevDatedTrees(props.datedTrees); - setPrevId(props.id); + setPrevId(divRef.current.id); groupTreeAssemblerRef.current = new GroupTreeAssembler( - props.id, + divRef.current.id, props.datedTrees, props.selectedEdgeKey, props.selectedNodeKey, From 058eee1ecfecb78c74cae04c0f2ccb8fc62fa637 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Wed, 29 Nov 2023 13:13:09 +0100 Subject: [PATCH 13/20] Remove unused code --- .../src/components/GroupTree/components/DataLoader.tsx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/python/src/components/GroupTree/components/DataLoader.tsx b/python/src/components/GroupTree/components/DataLoader.tsx index 3594943b4..b2b4fa954 100644 --- a/python/src/components/GroupTree/components/DataLoader.tsx +++ b/python/src/components/GroupTree/components/DataLoader.tsx @@ -43,15 +43,6 @@ const DataProvider: React.FC = ( const initialFlowRate = props.edgeMetadataList[0]?.key ?? ""; const initialNodeInfo = props.nodeMetadataList[0]?.key ?? ""; - // const initialFlowRate = - // props.edgeMetadataList?.length > 0 - // ? props.edgeMetadataList[0].key - // : ""; - - // const initialNodeInfo = - // props.nodeMetadataList?.length > 0 - // ? props.nodeMetadataList[0].key - // : ""; return { id: props.id, From 233bf4319bf3de9982de31c63bfc7034e9b26b42 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Wed, 29 Nov 2023 13:21:20 +0100 Subject: [PATCH 14/20] Adjust storybook config --- .../src/storybook/GroupTreePlot.stories.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx index c363124fe..2664d729f 100644 --- a/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx +++ b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx @@ -5,9 +5,19 @@ import type { EdgeMetadata, NodeMetadata } from "../types"; import { exampleDatedTrees } from "../../example-data/dated-trees"; +/** + * Storybook test for the group tree plot component + */ export default { component: GroupTreePlot, - title: "GroupTreePlot", + title: "GroupTreePlot/Demo", + argTypes: { + data: { + control: { + type: "object", + }, + }, + }, }; const edgeMetadataList: EdgeMetadata[] = [ From 9786b0965892fa06d8e65b6dcf55ef5ec935f2a9 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Fri, 1 Dec 2023 13:58:21 +0100 Subject: [PATCH 15/20] Add comments/description to Storybook + minor adjustments --- python/package-lock.json | 4 ++-- python/src/components/GroupTree/GroupTree.jsx | 4 ++-- .../GroupTree/components/DataLoader.tsx | 6 ++--- .../components/GroupTreeComponent.tsx | 8 ++----- .../components/Settings/DateTimeSlider.tsx | 4 ++-- typescript/package-lock.json | 8 +++---- .../example-data/dated-trees.ts | 14 +++++++++-- .../GroupTreeAssembler/groupTreeAssembler.js | 2 +- .../group-tree-plot/src/GroupTreePlot.tsx | 9 +++---- .../packages/group-tree-plot/src/index.ts | 5 +--- .../src/storybook/GroupTreePlot.stories.tsx | 24 +++++++++++++------ .../packages/group-tree-plot/src/types.ts | 6 ----- 12 files changed, 50 insertions(+), 44 deletions(-) diff --git a/python/package-lock.json b/python/package-lock.json index 0fbe15d3e..64b9e6590 100644 --- a/python/package-lock.json +++ b/python/package-lock.json @@ -108,7 +108,7 @@ }, "../typescript/packages/subsurface-viewer": { "name": "@webviz/subsurface-viewer", - "version": "0.7.0", + "version": "0.8.0", "license": "MPL-2.0", "dependencies": { "@deck.gl/core": "^8.9.32", @@ -155,7 +155,7 @@ }, "../typescript/packages/well-log-viewer": { "name": "@webviz/well-log-viewer", - "version": "1.1.5", + "version": "1.1.6", "license": "MPL-2.0", "dependencies": { "@emerson-eps/color-tables": "^0.4.71", diff --git a/python/src/components/GroupTree/GroupTree.jsx b/python/src/components/GroupTree/GroupTree.jsx index 119101dde..ac0dd2af9 100644 --- a/python/src/components/GroupTree/GroupTree.jsx +++ b/python/src/components/GroupTree/GroupTree.jsx @@ -2,7 +2,7 @@ import React from "react"; import PropTypes from "prop-types"; import { - DatedTreesPropTypes, + DatedTreePropTypes, EdgeMetadataPropTypes, NodeMetadataPropTypes, } from "@webviz/group-tree-plot"; @@ -37,7 +37,7 @@ GroupTree.propTypes = { /** * Array of JSON objects describing group tree data. */ - data: DatedTreesPropTypes, + data: PropTypes.arrayOf(DatedTreePropTypes), /** * Arrays of metadata. Used in drop down selectors and tree visualization. diff --git a/python/src/components/GroupTree/components/DataLoader.tsx b/python/src/components/GroupTree/components/DataLoader.tsx index b2b4fa954..838ddb62e 100644 --- a/python/src/components/GroupTree/components/DataLoader.tsx +++ b/python/src/components/GroupTree/components/DataLoader.tsx @@ -6,7 +6,7 @@ import { Provider as ReduxProvider } from "react-redux"; import { createReduxStore } from "../redux/store"; import type { UISettings } from "../redux/types"; import type { - DatedTrees, + DatedTree, EdgeMetadata, NodeMetadata, } from "@webviz/group-tree-plot"; @@ -18,14 +18,14 @@ export type DateTreesIndices = { interface DataProviderProps { id: string; - data: DatedTrees; + data: DatedTree[]; edgeMetadataList: EdgeMetadata[]; nodeMetadataList: NodeMetadata[]; initialIndices: DateTreesIndices; children: ReactNode; } -export const DataContext = React.createContext([]); +export const DataContext = React.createContext([]); const DataProvider: React.FC = ( props: PropsWithChildren diff --git a/python/src/components/GroupTree/components/GroupTreeComponent.tsx b/python/src/components/GroupTree/components/GroupTreeComponent.tsx index d4d6266af..6556f5833 100644 --- a/python/src/components/GroupTree/components/GroupTreeComponent.tsx +++ b/python/src/components/GroupTree/components/GroupTreeComponent.tsx @@ -2,11 +2,7 @@ import React, { useCallback, useState } from "react"; import DataProvider, { DateTreesIndices } from "./DataLoader"; import GroupTreeViewer from "./GroupTreeViewer"; -import { - DatedTrees, - EdgeMetadata, - NodeMetadata, -} from "@webviz/group-tree-plot"; +import { DatedTree, EdgeMetadata, NodeMetadata } from "@webviz/group-tree-plot"; //TODO schema check export interface GroupTreeProps { @@ -19,7 +15,7 @@ export interface GroupTreeProps { /** * Array of JSON objects describing group tree data. */ - data: DatedTrees; + data: DatedTree[]; /** * Arrays of metadata. Used in drop down selectors and tree visualization. diff --git a/python/src/components/GroupTree/components/Settings/DateTimeSlider.tsx b/python/src/components/GroupTree/components/Settings/DateTimeSlider.tsx index d7c2d1cd8..fffa4574c 100644 --- a/python/src/components/GroupTree/components/Settings/DateTimeSlider.tsx +++ b/python/src/components/GroupTree/components/Settings/DateTimeSlider.tsx @@ -6,7 +6,7 @@ import { updateCurrentDateTime } from "../../redux/actions"; import type { GroupTreeState } from "../../redux/store"; import { DataContext } from "../DataLoader"; -import { DatedTree, DatedTrees } from "@webviz/group-tree-plot"; +import { DatedTree } from "@webviz/group-tree-plot"; import "./date_time_slider.css"; @@ -35,7 +35,7 @@ const EdsSlider = styled(Slider)(() => ({ })); const DateTimeSlider: React.FC = React.memo(() => { - const data: DatedTrees = useContext(DataContext); + const data: DatedTree[] = useContext(DataContext); // Redux const dispatch = useDispatch(); diff --git a/typescript/package-lock.json b/typescript/package-lock.json index 5da719d7f..e66f3a952 100644 --- a/typescript/package-lock.json +++ b/typescript/package-lock.json @@ -13605,10 +13605,6 @@ "@xtuc/long": "4.2.2" } }, - "node_modules/@webviz/group-tree": { - "resolved": "packages/group-tree", - "link": true - }, "node_modules/@webviz/group-tree-plot": { "resolved": "packages/group-tree-plot", "link": true @@ -40288,7 +40284,8 @@ }, "packages/group-tree": { "name": "@webviz/group-tree", - "version": "1.0.6", + "version": "1.0.5", + "extraneous": true, "license": "MPL-2.0", "dependencies": { "@equinor/eds-core-react": "^0.33.0", @@ -40304,6 +40301,7 @@ } }, "packages/group-tree-plot": { + "name": "@webviz/group-tree-plot", "version": "0.0.1", "license": "MPL-2.0", "dependencies": { diff --git a/typescript/packages/group-tree-plot/example-data/dated-trees.ts b/typescript/packages/group-tree-plot/example-data/dated-trees.ts index f5ecd28f3..ae329232f 100644 --- a/typescript/packages/group-tree-plot/example-data/dated-trees.ts +++ b/typescript/packages/group-tree-plot/example-data/dated-trees.ts @@ -1,4 +1,14 @@ -import { DatedTree, DatedTrees } from "../src/types"; +import { DatedTree } from "../src/types"; + +/** + * This is the dates present in the dates trees example data. + */ +export const exampleDates: string[] = [ + "2018-02-01", + "2018-03-01", + "2019-02-01", + "2019-03-01", +]; /** * This is example data based on the Group Tree data in `group-tree.json`-file found in the `example-data`-folder. @@ -153,4 +163,4 @@ const secondDatedTree: DatedTree = { }, }; -export const exampleDatedTrees: DatedTrees = [firstDatedTree, secondDatedTree]; +export const exampleDatedTrees: DatedTree[] = [firstDatedTree, secondDatedTree]; diff --git a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js index 65ffe8585..993795316 100644 --- a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js +++ b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js @@ -26,7 +26,7 @@ export default class GroupTreeAssembler { /** * * @param dom_element_id - id of the HTML element to append the _svg to - * @param {DatedTrees} datedTrees - List of dated tree data structure containing the trees to visualize + * @param datedTrees - List of dated tree data structure containing the trees to visualize * @param initialFlowRate - key identifying the initial selected flow rate for the tree edges * @param initialNodeInfo - key identifying the initial selected node info for the tree nodes * @param currentDateTime - the initial/current date time diff --git a/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx b/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx index b125b2a9a..d0eb6cf3d 100644 --- a/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx +++ b/typescript/packages/group-tree-plot/src/GroupTreePlot.tsx @@ -1,14 +1,14 @@ import React from "react"; import GroupTreeAssembler from "./GroupTreeAssembler/groupTreeAssembler"; -import type { DatedTrees, EdgeMetadata, NodeMetadata } from "./types"; +import type { DatedTree, EdgeMetadata, NodeMetadata } from "./types"; import { isEqual } from "lodash"; export interface GroupTreePlotProps { id: string; edgeMetadataList: EdgeMetadata[]; nodeMetadataList: NodeMetadata[]; - datedTrees: DatedTrees; + datedTrees: DatedTree[]; selectedEdgeKey: string; selectedNodeKey: string; selectedDateTime: string; @@ -26,8 +26,9 @@ export const GroupTreePlot: React.FC = ( // Remove when typescript version is implemented using ref const [prevId, setPrevId] = React.useState(null); - const [prevDatedTrees, setPrevDatedTrees] = - React.useState(null); + const [prevDatedTrees, setPrevDatedTrees] = React.useState< + DatedTree[] | null + >(null); const [prevSelectedEdgeKey, setPrevSelectedEdgeKey] = React.useState(props.selectedEdgeKey); diff --git a/typescript/packages/group-tree-plot/src/index.ts b/typescript/packages/group-tree-plot/src/index.ts index 91b388841..bcfe45c34 100644 --- a/typescript/packages/group-tree-plot/src/index.ts +++ b/typescript/packages/group-tree-plot/src/index.ts @@ -1,8 +1,7 @@ export { GroupTreePlot } from "./GroupTreePlot"; -export type { GroupTreePlotProps } from "./GroupTreePlot"; - // Export types +export type { GroupTreePlotProps } from "./GroupTreePlot"; export type { NodeData, NodeDataPropTypes, @@ -16,6 +15,4 @@ export type { RecursiveTreeNodePropTypes, DatedTree, DatedTreePropTypes, - DatedTrees, - DatedTreesPropTypes, } from "./types"; diff --git a/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx index 2664d729f..7cf55c5cc 100644 --- a/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx +++ b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx @@ -3,7 +3,10 @@ import { GroupTreePlot } from "../GroupTreePlot"; import type { EdgeMetadata, NodeMetadata } from "../types"; -import { exampleDatedTrees } from "../../example-data/dated-trees"; +import { + exampleDatedTrees, + exampleDates, +} from "../../example-data/dated-trees"; /** * Storybook test for the group tree plot component @@ -12,10 +15,17 @@ export default { component: GroupTreePlot, title: "GroupTreePlot/Demo", argTypes: { - data: { - control: { - type: "object", - }, + selectedDateTime: { + description: + "The selected `string` must be a date time present in one of the `dates` arrays in an element of the`datedTrees`-prop.", + }, + selectedEdgeKey: { + description: + "The selection `string` must be an edge key present in one of the `edge_data` objects in the `tree`-prop of an element in `datedTrees`-prop.", + }, + selectedNodeKey: { + description: + "The selected `string` must be a node key present in one of the `node_data` objects in the `tree`-prop of an element in `datedTrees`-prop.", }, }, }; @@ -54,7 +64,7 @@ Default.args = { datedTrees: exampleDatedTrees, edgeMetadataList: edgeMetadataList, nodeMetadataList: nodeMetadataList, - selectedDateTime: "2018-02-01", - selectedEdgeKey: "oilrate", + selectedDateTime: exampleDates[0], + selectedEdgeKey: "waterrate", selectedNodeKey: "pressure", }; diff --git a/typescript/packages/group-tree-plot/src/types.ts b/typescript/packages/group-tree-plot/src/types.ts index 9c3abdaf2..6c603748a 100644 --- a/typescript/packages/group-tree-plot/src/types.ts +++ b/typescript/packages/group-tree-plot/src/types.ts @@ -39,9 +39,6 @@ export interface DatedTree { tree: RecursiveTreeNode; } -// List of dated trees -export type DatedTrees = DatedTree[]; - // --------------------------- PropTypes --------------------------------------- export const NodeDataPropTypes = PropTypes.objectOf( @@ -86,6 +83,3 @@ export const DatedTreePropTypes = PropTypes.shape({ dates: PropTypes.arrayOf(PropTypes.string).isRequired, tree: RecursiveTreeNodePropTypes, }); - -// List of dated trees -export const DatedTreesPropTypes = PropTypes.arrayOf(DatedTreePropTypes); From a0e2609c4449d8449a06efa9e1af74065935ce72 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Fri, 1 Dec 2023 16:02:52 +0100 Subject: [PATCH 16/20] Fix groupTreeAssembler bug found using storybook - Handle invalid selected date time for set-methods and Update() - Add overlay and info if invalid date is provided --- .../GroupTreeAssembler/groupTreeAssembler.js | 107 ++++++++++++++---- 1 file changed, 83 insertions(+), 24 deletions(-) diff --git a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js index 993795316..b7db80a0c 100644 --- a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js +++ b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js @@ -106,9 +106,6 @@ export default class GroupTreeAssembler { .range([2, 100]); }); - const select = d3.select(dom_element_id); - this._width = select.node().getBoundingClientRect().width; - const margin = { top: 10, right: 90, @@ -116,8 +113,16 @@ export default class GroupTreeAssembler { left: 90, }; - const height = 700 - margin.top - margin.bottom; - this._width = this._width - margin.left - margin.right; + const select = d3.select(dom_element_id); + + // Svg bounding client rect + this._rectWidth = select.node().getBoundingClientRect().width; + this._rectHeight = 700; + this._rectLeftMargin = -margin.left; + this._rectTopMargin = -margin.top; + + const treeHeight = this._rectHeight - margin.top - margin.bottom; + this._treeWidth = this._rectWidth - margin.left - margin.right; // Clear possible existing svg's. d3.select(dom_element_id).selectAll("svg").remove(); @@ -125,18 +130,18 @@ export default class GroupTreeAssembler { this._svg = d3 .select(dom_element_id) .append("svg") - .attr("width", this._width + margin.right + margin.left) - .attr("height", height + margin.top + margin.bottom) + .attr("width", this._treeWidth + margin.right + margin.left) + .attr("height", treeHeight + margin.top + margin.bottom) .append("g") .attr("transform", `translate(${margin.left},${margin.top})`); this._textpaths = this._svg.append("g"); - this._renderTree = d3.tree().size([height, this._width]); + this._renderTree = d3.tree().size([treeHeight, this._treeWidth]); this._data = GroupTreeAssembler.initHierarchies( clonedDatedTrees, - height + treeHeight ); this._currentTree = {}; @@ -186,10 +191,20 @@ export default class GroupTreeAssembler { return e.dates.includes(this._currentDateTime); }); + if (current_tree_index === -1) { + this._svg.selectAll("path.link").remove(); + return; + } + const date_index = this._data[current_tree_index].dates.indexOf( this._currentDateTime ); + if (date_index === -1) { + this._svg.selectAll("path.link").remove(); + return; + } + this._svg .selectAll("path.link") .transition() @@ -222,10 +237,20 @@ export default class GroupTreeAssembler { return e.dates.includes(this._currentDateTime); }); + if (current_tree_index === -1) { + this._svg.selectAll("path.link").remove(); + return; + } + const date_index = this._data[current_tree_index].dates.indexOf( this._currentDateTime ); + if (date_index === -1) { + this._svg.selectAll("path.link").remove(); + return; + } + this._svg .selectAll(".grouptree__pressurelabel") .text( @@ -262,15 +287,21 @@ export default class GroupTreeAssembler { update(newDateTime) { const self = this; - self._currentDateTime = newDateTime; - const new_tree_index = self._data.findIndex((e) => { return e.dates.includes(newDateTime); }); const root = self._data[new_tree_index]; - const date_index = root.dates.indexOf(self._currentDateTime); + const date_index = root?.dates.indexOf(newDateTime) ?? -1; + + // Invalid date gives invalid indices + const hasInvalidDate = + !root || date_index === -1 || new_tree_index === -1; + + if (hasInvalidDate) { + self._currentDateTime = newDateTime; + } /** * Assigns y coordinates to all tree nodes in the rendered tree. @@ -527,7 +558,7 @@ export default class GroupTreeAssembler { /** * Draw new edges, and update existing ones. * - * @param edges -list of nodes in a tree + * @param edges -list of edges in a tree * @param flowrate - key identifying the flowrate of the incoming edge */ function updateEdges(edges, flowrate) { @@ -600,7 +631,7 @@ export default class GroupTreeAssembler { /** * Add new and update existing texts/textpaths on edges. * - * @param edges - list of nodes in a tree + * @param edges - list of edges in a tree */ function updateEdgeTexts(edges) { const textpath = self._textpaths @@ -628,17 +659,45 @@ export default class GroupTreeAssembler { textpath.exit().remove(); } - const newTree = cloneExistingNodeStates( - growNewTree(this._renderTree(root.tree), this._width), - this._currentTree - ); + // Clear any existing error overlay + this._svg + .selectAll(".error-overlay-background, .error-overlay") + .remove(); + + if (hasInvalidDate) { + // // Add opacity to overlay background + this._svg + .append("rect") + .attr("class", "error-overlay-background") + .attr("width", this._rectWidth) + .attr("height", this._rectHeight) + .attr("x", this._rectLeftMargin) + .attr("y", this._rectTopMargin) + .attr("fill", "rgba(255, 255, 255, 0.8)"); + + // Show overlay text with error message + this._svg + .append("text") + .attr("class", "error-overlay") + .attr("x", this._rectWidth / 2 + 2 * this._rectLeftMargin) + .attr("y", this._rectHeight / 2 + 2 * this._rectTopMargin) + .style("fill", "red") + .style("font-size", "16px") + .text("Date not found in data"); + } else { + // Grow new tree + const newTree = cloneExistingNodeStates( + growNewTree(this._renderTree(root.tree), this._treeWidth), + this._currentTree + ); - // execute visualization operations on enter, update and exit selections - updateNodes(newTree.descendants(), this.nodeinfo); - updateEdges(newTree.descendants().slice(1), this.flowrate); - updateEdgeTexts(newTree.descendants().slice(1)); + // execute visualization operations on enter, update and exit selections + updateNodes(newTree.descendants(), this.nodeinfo); + updateEdges(newTree.descendants().slice(1), this.flowrate); + updateEdgeTexts(newTree.descendants().slice(1)); - // save the state of the now current tree, before next update - this._currentTree = doPostUpdateOperations(newTree); + // save the state of the now current tree, before next update + this._currentTree = doPostUpdateOperations(newTree); + } } } From 952cbdc4f814346d10eee2ce936d3b45c226cda5 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Tue, 5 Dec 2023 11:06:06 +0100 Subject: [PATCH 17/20] Bug fix and adjust storybook --- .../GroupTreeAssembler/groupTreeAssembler.js | 8 +-- .../src/storybook/GroupTreePlot.stories.tsx | 71 ++++++++++--------- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js index b7db80a0c..0c39dc24d 100644 --- a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js +++ b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js @@ -53,10 +53,10 @@ export default class GroupTreeAssembler { // Map from property to [label/name, unit] const metadataList = [...edgeMetadataList, ...nodeMetadataList]; this._propertyToLabelMap = new Map(); - metadataList.forEach((key) => { - this._propertyToLabelMap.set(key.name, [ - key.label ?? "", - key.unit ?? "", + metadataList.forEach((elm) => { + this._propertyToLabelMap.set(elm.key, [ + elm.label ?? "", + elm.unit ?? "", ]); }); diff --git a/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx index 7cf55c5cc..1cde38d82 100644 --- a/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx +++ b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx @@ -11,23 +11,18 @@ import { /** * Storybook test for the group tree plot component */ -export default { - component: GroupTreePlot, - title: "GroupTreePlot/Demo", - argTypes: { - selectedDateTime: { - description: - "The selected `string` must be a date time present in one of the `dates` arrays in an element of the`datedTrees`-prop.", - }, - selectedEdgeKey: { - description: - "The selection `string` must be an edge key present in one of the `edge_data` objects in the `tree`-prop of an element in `datedTrees`-prop.", - }, - selectedNodeKey: { - description: - "The selected `string` must be a node key present in one of the `node_data` objects in the `tree`-prop of an element in `datedTrees`-prop.", - }, - }, +const Template = (args) => { + return ( + + ); }; const edgeMetadataList: EdgeMetadata[] = [ @@ -44,20 +39,6 @@ const nodeMetadataList: NodeMetadata[] = [ { key: "wmctl", label: "Missing label", unit: "Unknown unit" }, ]; -const Template = (args) => { - return ( - - ); -}; - export const Default = Template.bind({}); Default.args = { id: "grouptreeplot", @@ -65,6 +46,30 @@ Default.args = { edgeMetadataList: edgeMetadataList, nodeMetadataList: nodeMetadataList, selectedDateTime: exampleDates[0], - selectedEdgeKey: "waterrate", - selectedNodeKey: "pressure", + selectedEdgeKey: edgeMetadataList[0].key, + selectedNodeKey: nodeMetadataList[0].key, +}; +export default { + component: GroupTreePlot, + title: "GroupTreePlot/Demo", + argTypes: { + selectedDateTime: { + control: "select", + options: exampleDates, + description: + "The selected `string` must be a date time present in one of the `dates` arrays in an element of the`datedTrees`-prop.\n\n **Note:** The options for the date select in this storybook is not updated when the `datedTrees`-prop is updated.\n\n", + }, + selectedEdgeKey: { + control: "select", + options: edgeMetadataList.map((elm) => elm.key), + description: + "The selection `string` must be an edge key present in one of the `edge_data` objects in the `tree`-prop of an element in `datedTrees`-prop.\n\n **Note:** The options for the edge key select in this storybook is not updated when the `edgeMetadataList`-prop is updated.\n\n", + }, + selectedNodeKey: { + control: "select", + options: nodeMetadataList.map((elm) => elm.key), + description: + "The selected `string` must be a node key present in one of the `node_data` objects in the `tree`-prop of an element in `datedTrees`-prop.\n\n **Note:** The options for the node key select in this storybook is not updated when the `nodeMetadataList`-prop is updated.\n\n", + }, + }, }; From 6be57942ffae6a19f7c6109448b882d811ce3159 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Tue, 5 Dec 2023 11:31:51 +0100 Subject: [PATCH 18/20] Revert usage of select for control of strings in storybook options does not change dynamically. Want to represent the actual functionality of component --- .../src/storybook/GroupTreePlot.stories.tsx | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx index 1cde38d82..82da99dc2 100644 --- a/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx +++ b/typescript/packages/group-tree-plot/src/storybook/GroupTreePlot.stories.tsx @@ -54,22 +54,16 @@ export default { title: "GroupTreePlot/Demo", argTypes: { selectedDateTime: { - control: "select", - options: exampleDates, description: - "The selected `string` must be a date time present in one of the `dates` arrays in an element of the`datedTrees`-prop.\n\n **Note:** The options for the date select in this storybook is not updated when the `datedTrees`-prop is updated.\n\n", + "The selected `string` must be a date time present in one of the `dates` arrays in an element of the`datedTrees`-prop.\n\n", }, selectedEdgeKey: { - control: "select", - options: edgeMetadataList.map((elm) => elm.key), description: - "The selection `string` must be an edge key present in one of the `edge_data` objects in the `tree`-prop of an element in `datedTrees`-prop.\n\n **Note:** The options for the edge key select in this storybook is not updated when the `edgeMetadataList`-prop is updated.\n\n", + "The selection `string` must be an edge key present in one of the `edge_data` objects in the `tree`-prop of an element in `datedTrees`-prop.\n\n", }, selectedNodeKey: { - control: "select", - options: nodeMetadataList.map((elm) => elm.key), description: - "The selected `string` must be a node key present in one of the `node_data` objects in the `tree`-prop of an element in `datedTrees`-prop.\n\n **Note:** The options for the node key select in this storybook is not updated when the `nodeMetadataList`-prop is updated.\n\n", + "The selected `string` must be a node key present in one of the `node_data` objects in the `tree`-prop of an element in `datedTrees`-prop.\n\n", }, }, }; From 8ad3541732827ba4f1559d5dea15e069cc04cc84 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Wed, 6 Dec 2023 09:22:15 +0100 Subject: [PATCH 19/20] Remove old typescript/package from packalge-lock.json --- python/package-lock.json | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/python/package-lock.json b/python/package-lock.json index 64b9e6590..024a16513 100644 --- a/python/package-lock.json +++ b/python/package-lock.json @@ -72,24 +72,6 @@ "../typescript/packages/dash-components/dist": { "extraneous": true }, - "../typescript/packages/group-tree": { - "name": "@webviz/group-tree", - "version": "1.0.1", - "extraneous": true, - "license": "MPL-2.0", - "dependencies": { - "@equinor/eds-core-react": "^0.33.0", - "@reduxjs/toolkit": "^1.7.2", - "d3": "^7.8.2", - "lodash": "^4.17.21", - "react-redux": "^8.1.1" - }, - "peerDependencies": { - "@mui/material": "^5.11", - "react": "^17 || ^18", - "react-dom": "^17 || ^18" - } - }, "../typescript/packages/group-tree-plot": { "name": "@webviz/group-tree-plot", "version": "0.0.1", @@ -103,12 +85,9 @@ "react-dom": "^17 || ^18" } }, - "../typescript/packages/group-tree/dist": { - "extraneous": true - }, "../typescript/packages/subsurface-viewer": { "name": "@webviz/subsurface-viewer", - "version": "0.8.0", + "version": "0.9.0", "license": "MPL-2.0", "dependencies": { "@deck.gl/core": "^8.9.32", @@ -125,7 +104,7 @@ "d3": "^7.8.2", "d3-color": "^3.1.0", "d3-format": "^3.1.0", - "deck.gl": "^8.9.31", + "deck.gl": "^8.9.32", "gl-matrix": "^3.4.3", "lodash": "^4.17.21", "mathjs": "^9.4.2", @@ -143,7 +122,7 @@ }, "../typescript/packages/well-completions-plot": { "name": "@webviz/well-completions-plot", - "version": "1.0.5", + "version": "1.0.7", "license": "MPL-2.0", "dependencies": { "react-resize-detector": "^9.1.0", @@ -155,11 +134,11 @@ }, "../typescript/packages/well-log-viewer": { "name": "@webviz/well-log-viewer", - "version": "1.1.6", + "version": "1.1.8", "license": "MPL-2.0", "dependencies": { "@emerson-eps/color-tables": "^0.4.71", - "@equinor/videx-wellog": "^0.8.0", + "@equinor/videx-wellog": "^0.8.1", "@webviz/wsc-common": "*", "convert-units": "^2.3.4", "d3": "^7.8.2" @@ -175,7 +154,7 @@ }, "../typescript/packages/wsc-common": { "name": "@webviz/wsc-common", - "version": "0.2.5", + "version": "0.2.7", "license": "MPL-2.0", "dependencies": { "ajv": "^7.2.1" From e3f1116dffb9fbefbae73868ec88bdf72c8c7117 Mon Sep 17 00:00:00 2001 From: jorgenherje Date: Tue, 12 Dec 2023 20:11:53 +0100 Subject: [PATCH 20/20] Adjustments after review + formatting --- python/src/components/GroupTree/GroupTree.jsx | 8 ++++---- python/webviz_subsurface_components/py_expression_eval.py | 1 + .../src/GroupTreeAssembler/groupTreeAssembler.js | 4 ++-- typescript/packages/group-tree-plot/tsconfig.json | 7 +------ 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/python/src/components/GroupTree/GroupTree.jsx b/python/src/components/GroupTree/GroupTree.jsx index ac0dd2af9..2eec2df48 100644 --- a/python/src/components/GroupTree/GroupTree.jsx +++ b/python/src/components/GroupTree/GroupTree.jsx @@ -14,13 +14,13 @@ const GroupTreeComponent = React.lazy(() => ); export const GroupTree = (props) => { + const { edge_metadata_list, node_metadata_list, ...rest } = props; return ( Loading...}> ); diff --git a/python/webviz_subsurface_components/py_expression_eval.py b/python/webviz_subsurface_components/py_expression_eval.py index 85be28825..8bbd29042 100644 --- a/python/webviz_subsurface_components/py_expression_eval.py +++ b/python/webviz_subsurface_components/py_expression_eval.py @@ -33,6 +33,7 @@ Based on js-expression-eval, by Matthew Crumley https://github.com/silentmatt/js-expression-eval """ + import re import numpy as np diff --git a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js index 0c39dc24d..3d806cf6c 100644 --- a/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js +++ b/typescript/packages/group-tree-plot/src/GroupTreeAssembler/groupTreeAssembler.js @@ -17,10 +17,10 @@ import { cloneDeep } from "lodash"; /** * Class to assemble Group tree visualization. Creates an _svg, and appends to the - * assigned HTML element. Draws the tree provided as tree_data with the current flow rate, + * assigned HTML element. Draws the tree provided in datedTrees with the current flow rate, * node info and date time. * - * Provides methods to update selected date time, and change flow rate and node info. * + * Provides methods to update selected date time, and change flow rate and node info. */ export default class GroupTreeAssembler { /** diff --git a/typescript/packages/group-tree-plot/tsconfig.json b/typescript/packages/group-tree-plot/tsconfig.json index 609cb7acb..0d954e179 100644 --- a/typescript/packages/group-tree-plot/tsconfig.json +++ b/typescript/packages/group-tree-plot/tsconfig.json @@ -5,10 +5,5 @@ "rootDir": "./src" }, "include": ["src/"], - "exclude": [ - "src/test", - "./**/*.test.tsx", - "./**/*.stories.tsx", - "./**/*.stories.jsx" - ] + "exclude": ["src/test", "./**/*.test.tsx", "./**/*.stories.tsx"] }