Skip to content

Commit

Permalink
Merge pull request #68 from concord-consortium/188245100-add-dataset-…
Browse files Browse the repository at this point in the history
…transition-probabilities

feat: Add transition probabilities to dataset mode [PT-188245100]
  • Loading branch information
dougmartin authored Sep 27, 2024
2 parents a1f15be + 5b6061c commit da0866a
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 49 deletions.
46 changes: 46 additions & 0 deletions src/components/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -245,5 +245,51 @@
}
}

.nodeModalBackground {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #000;
opacity: 0.25;
z-index: 100;
}
.nodeModal {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
z-index: 101;
user-select: none;

.nodeModalContent {
min-width: 200px;

.nodeModalTitle {
background-color: #177991;
color: white;
padding: 5px 10px;
}

form {
padding: 10px;
background-color: white;
display: flex;
flex-direction: column;
gap: 10px;

.nodeModalButtons {
display: flex;
gap: 5px;
justify-content: flex-end;
}
}
}
}
}

17 changes: 16 additions & 1 deletion src/components/dataset.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from "react";
import React, { useState } from "react";
import { Tool, Toolbar } from "./toolbar";
import { Graph } from "./graph";
import { Node, Edge, GraphData } from "../type";
import { NodeModal } from "./drawing/node-modal";

import "./dataset.scss";

Expand Down Expand Up @@ -30,11 +31,17 @@ export const Dataset = (props: Props) => {
graph, graphEmpty, setSelectedNodeId, selectedNodeId, animating,
fitViewAt, recenterViewAt,
onReset, onReturnToMainMenu, onFitView, onRecenterView} = props;
const [selectedNodeForModal, setSelectedNodeForModal] = useState<Node|undefined>(undefined);

const handleToolSelected = (tool: Tool) => {
// TBD
};

const handleNodeDoubleClicked = (id: string) => {
setSelectedNodeForModal(graph.nodes.find(n => n.id === id));
};
const handleClearSelectedNode = () => setSelectedNodeForModal(undefined);

if (graphEmpty) {
return (
<div className="dataset">
Expand Down Expand Up @@ -82,13 +89,21 @@ export const Dataset = (props: Props) => {
highlightAllNextNodes={highlightAllNextNodes}
highlightOutputNodes={highlightOutputNodes}
selectedNodeId={selectedNodeId}
onNodeDoubleClick={handleNodeDoubleClicked}
animating={animating}
allowDragging={true && !animating}
autoArrange={true}
setSelectedNodeId={setSelectedNodeId}
fitViewAt={fitViewAt}
recenterViewAt={recenterViewAt}
/>
<NodeModal
viewMode="dataset"
node={selectedNodeForModal}
graph={graph}
onChange={() => undefined}
onCancel={handleClearSelectedNode}
/>
</div>
);
};
44 changes: 0 additions & 44 deletions src/components/drawing.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,6 @@
pointer-events: none;
}

.nodeModalBackground {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #000;
opacity: 0.25;
z-index: 100;
}
.nodeModal {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
z-index: 101;

.nodeModalContent {
min-width: 200px;

.nodeModalTitle {
background-color: #177991;
color: white;
padding: 5px 10px;
}

form {
padding: 10px;
background-color: white;
display: flex;
flex-direction: column;
gap: 10px;

.nodeModalButtons {
display: flex;
gap: 5px;
justify-content: flex-end;
}
}
}
}

}
1 change: 1 addition & 0 deletions src/components/drawing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ export const Drawing = (props: Props) => {
/>
<DragIcon drawingMode={drawingMode} />
<NodeModal
viewMode="drawing"
node={selectedNodeForModal}
graph={graph}
onChange={handleChangeNode}
Expand Down
28 changes: 27 additions & 1 deletion src/components/drawing/node-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { ProbabilitySelector, percentage, reduceToSum } from "./probability-selector";
import { Node, Edge, GraphData } from "../../type";
import { ViewMode } from "../../hooks/use-codap";

export interface NodeModalProps {
viewMode: ViewMode;
node?: Node,
graph: GraphData;
onChange: (id: string, newNode: Node, newEdge: Edge[]) => void,
onCancel: () => void
}

export const NodeModal = ({ node, graph, onChange, onCancel }: NodeModalProps) => {
export const NodeModal = ({ viewMode, node, graph, onChange, onCancel }: NodeModalProps) => {
const [label, setLabel] = useState(node?.label || "");
const [exactPercentages, _setExactPercentages] = useState<number[]>([]);

Expand Down Expand Up @@ -68,6 +70,29 @@ export const NodeModal = ({ node, graph, onChange, onCancel }: NodeModalProps) =
return null;
}

if (viewMode === "dataset") {
return (
<>
<div className="nodeModalBackground" />
<div className="nodeModal">
<div className="nodeModalContent">
<div className="nodeModalTitle">State: {label}</div>
<form>
<ProbabilitySelector
viewMode={viewMode}
exactPercentages={exactPercentages}
edgeLabels={edgeLabels}
onChange={setExactPercentages} />
<div className="nodeModalButtons">
<button onClick={onCancel}>Close</button>
</div>
</form>
</div>
</div>
</>
);
}

return (
<>
<div className="nodeModalBackground" />
Expand All @@ -77,6 +102,7 @@ export const NodeModal = ({ node, graph, onChange, onCancel }: NodeModalProps) =
<form onSubmit={handleSubmit}>
<input type="text" value={label} onChange={handleChangeLabel} autoFocus={true} />
<ProbabilitySelector
viewMode="drawing"
exactPercentages={exactPercentages}
edgeLabels={edgeLabels}
onChange={setExactPercentages} />
Expand Down
11 changes: 8 additions & 3 deletions src/components/drawing/probability-selector.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useCallback, useMemo } from "react";
import { ViewMode } from "../../hooks/use-codap";

import "./probability-selector.scss";

Expand All @@ -15,6 +16,7 @@ interface ProbabilitySelectorThumbProps {
}

interface ProbabilitySelectorProps {
viewMode: ViewMode;
exactPercentages: number[]
edgeLabels: string[]
onChange: (newPercentages: number[]) => void
Expand Down Expand Up @@ -73,7 +75,7 @@ export const ProbabilitySelectorThumb = (props: ProbabilitySelectorThumbProps) =
);
};

export const ProbabilitySelector = ({exactPercentages, edgeLabels, onChange}: ProbabilitySelectorProps) => {
export const ProbabilitySelector = ({viewMode, exactPercentages, edgeLabels, onChange}: ProbabilitySelectorProps) => {

const roundPercentages = useMemo(() => {
const result = exactPercentages.slice(0, -1).map(exactPercentage => Math.round(exactPercentage));
Expand Down Expand Up @@ -135,13 +137,15 @@ export const ProbabilitySelector = ({exactPercentages, edgeLabels, onChange}: Pr
}
}, [exactPercentages, onChange]);

if (exactPercentages.length < 2) {
const isDrawingMode = viewMode === "drawing";
if (isDrawingMode && (exactPercentages.length < 2)) {
return null;
}

return (
<div className="probability-selector">
<div className="header">Transition Probabilities</div>
{isDrawingMode &&
<div className="svg-container" style={{width: svgWidth, height: svgHeight}}>
<svg viewBox={`0 0 ${svgWidth} ${svgHeight}`}>
{segments.map(({start, end}, i) => (
Expand All @@ -166,9 +170,10 @@ export const ProbabilitySelector = ({exactPercentages, edgeLabels, onChange}: Pr
))}
</svg>
</div>
}
<div className="percentages">
{roundPercentages.map((p, i) => (
<div key={i} style={{color: getDistinctColor(i)}}>To {edgeLabels[i]}: {p}%</div>
<div key={i} style={{color: isDrawingMode ? getDistinctColor(i) : "#000"}}>To {edgeLabels[i]}: {p}%</div>
))}
</div>
</div>
Expand Down

0 comments on commit da0866a

Please sign in to comment.