Skip to content

Commit 4460c82

Browse files
authored
Merge pull request #288 from XpressAI/paul/shiny-ui
Node Graph Rendering Facelift
2 parents 526ef75 + d0731d6 commit 4460c82

File tree

6 files changed

+1138
-1139
lines changed

6 files changed

+1138
-1139
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"@jupyterlab/settingregistry": "^4.0.0",
6565
"@projectstorm/geometry": "^7.0.2",
6666
"@projectstorm/react-diagrams": "^7.0.3",
67+
"colorjs.io": "^0.4.5",
6768
"marked": "^11.0.0",
6869
"react-accessible-accordion": "^5.0.0",
6970
"react-numeric-input": "^2.2.3",

src/components/link/CustomLinkFactory.tsx

+19
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,28 @@ namespace S {
2424
2525
fill: none;
2626
pointer-events: auto;
27+
filter: drop-shadow(2px 2px 4px rgb(0 0 0 / 40%)) opacity(60%);
2728
2829
body.low-powered-mode & {
2930
animation: none !important;
3031
}
3132
`;
3233
}
3334

35+
function addHover(model: TriangleLinkModel | ParameterLinkModel){
36+
return (() => {
37+
document.querySelector(`div.port[data-nodeid='${model.getSourcePort().getNode().getID()}'][data-name='${model.getSourcePort().getName()}']>div`).classList.add("hover");
38+
document.querySelector(`div.port[data-nodeid="${model.getTargetPort().getNode().getID()}"][data-name='${model.getTargetPort().getName()}']>div`).classList.add("hover");
39+
});
40+
}
41+
42+
function removeHover(model: TriangleLinkModel | ParameterLinkModel){
43+
return () => {
44+
document.querySelector(`div.port[data-nodeid='${model.getSourcePort().getNode().getID()}'][data-name='${model.getSourcePort().getName()}']>div`).classList.remove("hover");
45+
document.querySelector(`div.port[data-nodeid="${model.getTargetPort().getNode().getID()}"][data-name='${model.getTargetPort().getName()}']>div`).classList.remove("hover");
46+
}
47+
}
48+
3449
export class ParameterLinkFactory extends DefaultLinkFactory {
3550
constructor() {
3651
super('parameter-link');
@@ -43,6 +58,8 @@ export class ParameterLinkFactory extends DefaultLinkFactory {
4358
generateLinkSegment(model: ParameterLinkModel, selected: boolean, path: string) {
4459
return (
4560
<S.Path
61+
onMouseOver={addHover(model)}
62+
onMouseOut={removeHover(model)}
4663
selected={selected}
4764
stroke={selected ? 'yellow' : model.getOptions().color}
4865
strokeWidth={model.getOptions().width}
@@ -64,6 +81,8 @@ export class TriangleLinkFactory extends DefaultLinkFactory {
6481
generateLinkSegment(model: TriangleLinkModel, selected: boolean, path: string) {
6582
return (
6683
<S.Path
84+
onMouseOver={addHover(model)}
85+
onMouseOut={removeHover(model)}
6786
selected={!selected}
6887
stroke={!selected ? model.getOptions().selectedColor : 'yellow'}
6988
strokeWidth={model.getOptions().width}

src/components/node/CustomNodeWidget.tsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,32 @@ import { showFormDialog } from '../../dialog/FormDialog';
1313
import { CommentDialog } from '../../dialog/CommentDialog';
1414
import ReactTooltip from "react-tooltip"
1515
import { marked } from 'marked';
16+
import Color from 'colorjs.io';
1617

1718
var S;
1819
(function (S) {
1920
S.Node = styled.div<{ borderColor:string,background: string; selected: boolean; }>`
20-
background-color: ${(p) => p.background};
21+
background-color: ${(p) => {
22+
const color = new Color(p.background);
23+
color.alpha = 0.75;
24+
color.oklch.c *= 1.2;
25+
return color.to('oklch').toString();
26+
}};
27+
box-shadow: 1px 1px 10px ${(p) => p.selected ? '3px rgb(0 192 255 / 0.5)' : '0px rgb(0 0 0 / 0.5)'};
2128
border-radius: 5px;
2229
font-family: sans-serif;
2330
color: white;
24-
border: solid 2px black;
2531
overflow: visible;
2632
font-size: 11px;
27-
border: solid 2px ${(p) => (p.selected ? (p.borderColor==undefined? 'rgb(0,192,255)': p.borderColor ):'black')};
33+
border: solid 1px ${(p) => (p.selected ? (p.borderColor==undefined? 'rgb(0,192,255)': p.borderColor ):'black')};
2834
`;
2935

3036
S.Title = styled.div`
3137
background: rgba(0, 0, 0, 0.3);
3238
display: flex;
3339
white-space: nowrap;
3440
justify-items: center;
41+
box-shadow: inset 0 -2px 4px 0 rgb(0 0 0 / 0.05);
3542
`;
3643

3744
S.TitleName = styled.div`

src/components/port/CustomPortLabel.tsx

+57-13
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,20 @@ namespace S {
2525
`;
2626

2727
export const SymbolContainer = styled.div<{ symbolType: string; selected: boolean; isOutPort: boolean }>`
28-
width: 17px;
28+
width: 15px;
2929
height: 15px;
30-
border: 5px hidden;
31-
background: ${(p) => (p.selected ? 'white' : 'rgba(0, 0, 0, 0.2)')};
30+
background: ${(p) => (p.selected ? 'oklch(1 0 0 / 0.5)' : 'rgba(0, 0, 0, 0.2)')};
3231
border-radius: ${(p) => (p.isOutPort ? '20px 0px 0px 20px' : '0px 20px 20px 0px')} ;
3332
display: ${(p) => p.symbolType == null ? 'none' : 'visible'};
3433
text-align: center;
34+
box-shadow: inset 0 2px 4px ${(p) => (p.selected ? 'rgb(0 0 0 / 0.05)' : 'rgb(0 0 0 / 0.01)')} ;
35+
border: 1px solid oklch(0 0 0 / 0.2);
36+
padding: 0 2px;
37+
margin: 2px 0;
38+
&:hover, &.hover {
39+
background: rgb(192, 255, 0);
40+
box-shadow: ${(p) => p.selected ? '' : 'inset'} 0 4px 8px rgb(0 0 0 / 0.5);
41+
}
3542
`;
3643

3744
export const Symbol = styled.div<{ isOutPort: boolean }>`
@@ -42,12 +49,29 @@ namespace S {
4249
padding:${(p) => (p.isOutPort ? '2px 0px 0px 2px' : '2px 2px 0px 0px')};
4350
`;
4451

45-
export const Port = styled.div`
52+
export const Port = styled.div<{ isOutPort: boolean, hasLinks: boolean }>`
4653
width: 15px;
4754
height: 15px;
48-
background: rgba(255, 255, 255, 0.2);
49-
&:hover {
55+
background: ${(p) => p.hasLinks ? 'oklch(1 0 0 / 0.5)' : 'oklch(0 0 0 / 0.2)'};
56+
color: ${(p) => p.hasLinks ? 'oklch(0 0 0 / 0.8)' : 'oklch(1 0 0 / 0.8)'};
57+
border: 1px solid oklch(0 0 0 / 0.2);
58+
border-radius: ${(p) => (p.isOutPort ? '20px 0px 0px 20px' : '0px 20px 20px 0px')} ;
59+
box-shadow: ${(p) => p.hasLinks ? '' : 'inset'} 0 2px 4px ${(p) => (p.hasLinks ? 'rgb(0 0 0 / 0.1)' : 'rgb(0 0 0 / 0.05)')} ;
60+
display: flex;
61+
justify-content: center;
62+
align-items: center;
63+
padding: 0 2px;
64+
margin: 2px 0;
65+
&:hover, &.hover {
5066
background: rgb(192, 255, 0);
67+
box-shadow: ${(p) => p.hasLinks ? '' : 'inset'} 0 4px 8px rgb(0 0 0 / 0.5);
68+
}
69+
& svg {
70+
stroke-width: 3;
71+
stroke: currentColor;
72+
fill: none;
73+
stroke-linecap: round;
74+
stroke-linejoin: round;
5175
}
5276
`;
5377
}
@@ -93,10 +117,27 @@ export class CustomPortLabel extends React.Component<CustomPortLabelProps> {
93117
symbolLabel = '◎';
94118
}
95119

120+
const isIn = !!this.props.port.getOptions().in
121+
const hasLinks = Object.keys(this.props.port.getLinks()).length > 0;
122+
const isTrianglePort = this.props.port.getOptions().label.indexOf('▶') >= 0 &&
123+
/* Workaround for Arguments being set up as triangle ports in other places */
124+
!this.props.node['name'].match('Argument \(.+?\):');
125+
96126
const port = (
97-
<PortWidget engine={this.props.engine} port={this.props.port}>
98-
<S.Port />
99-
</PortWidget>
127+
<S.Port isOutPort={!isIn} hasLinks={hasLinks}>
128+
{!isTrianglePort ? null : (isIn ?
129+
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" >
130+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
131+
<path d="M3 12h12" />
132+
<path d="M11 8l4 4l-4 4" />
133+
<path d="M12 21a9 9 0 0 0 0 -18" />
134+
</svg> : <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24">
135+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
136+
<path d="M9 12h12" />
137+
<path d="M17 16l4 -4l-4 -4" />
138+
<path d="M12 3a9 9 0 1 0 0 18" />
139+
</svg>)}
140+
</S.Port>
100141
);
101142

102143
const propLinks = this.props.port.links;
@@ -105,6 +146,7 @@ export class CustomPortLabel extends React.Component<CustomPortLabelProps> {
105146
portHasLink = true;
106147
}
107148

149+
108150
const symbol = (
109151
<S.SymbolContainer symbolType={symbolLabel} selected={portHasLink} isOutPort={isOutPort}>
110152
<S.Symbol isOutPort={isOutPort}>
@@ -116,14 +158,16 @@ export class CustomPortLabel extends React.Component<CustomPortLabelProps> {
116158

117159
const label = (
118160
<S.Label style={{ textAlign: (!this.props.port.getOptions().in && this.props.port.getOptions().label === '▶') ? 'right' : 'left' }}>
119-
{nodeType === "Literal Secret" ? "*****" : this.props.port.getOptions().label}
161+
{nodeType === "Literal Secret" ? "*****" : this.props.port.getOptions().label.replace('▶', '').trim()}
120162
</S.Label>);
121163

122164
return (
123165
<S.PortLabel>
124-
{this.props.port.getOptions().in ? port : label}
125-
{symbol}
126-
{this.props.port.getOptions().in ? label : port}
166+
{this.props.port.getOptions().in ? null : label}
167+
<PortWidget engine={this.props.engine} port={this.props.port}>
168+
{symbolLabel == null ? port : symbol}
169+
</PortWidget>
170+
{this.props.port.getOptions().in ? label : null}
127171
</S.PortLabel>
128172
);
129173
}

src/helpers/XircuitsCanvasWidget.tsx

+5-26
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ export interface XircuitsCanvasWidgetProps {
1111
export const Container = styled.div<{ color: string; background: string }>`
1212
height: 100%;
1313
background-color: ${(p) => p.background};
14-
background-size: 50px 50px;
1514
display: flex;
1615
width : 15360px; // Prevent Dev tool effects on smaller monitors
1716
@@ -20,38 +19,18 @@ export interface XircuitsCanvasWidgetProps {
2019
min-height: 100%;
2120
width: 100%;
2221
}
23-
background-image: linear-gradient(
24-
0deg,
25-
transparent 24%,
26-
${(p) => p.color} 25%,
27-
${(p) => p.color} 26%,
28-
transparent 27%,
29-
transparent 74%,
30-
${(p) => p.color} 75%,
31-
${(p) => p.color} 76%,
32-
transparent 77%,
33-
transparent
34-
),
35-
linear-gradient(
36-
90deg,
37-
transparent 24%,
38-
${(p) => p.color} 25%,
39-
${(p) => p.color} 26%,
40-
transparent 27%,
41-
transparent 74%,
42-
${(p) => p.color} 75%,
43-
${(p) => p.color} 76%,
44-
transparent 77%,
45-
transparent
46-
);
22+
23+
background-image: radial-gradient(oklch(40% 0% 0) 1px, transparent 0);
24+
background-size: 15px 15px;
25+
background-position: -19px -19px;
4726
`;
4827
//}
4928

5029
export class XircuitsCanvasWidget extends React.Component<XircuitsCanvasWidgetProps> {
5130
render() {
5231
return (
5332
<Container
54-
background={this.props.background || 'rgb(60, 60, 60)'}
33+
background={this.props.background || 'oklch(0.3 0.01 300 / 1)'}
5534
color={this.props.color || 'rgba(255,255,255, 0.05)'}>
5635
{this.props.children}
5736
</Container>

0 commit comments

Comments
 (0)