Skip to content

Commit 10cfb7b

Browse files
authored
Merge pull request #179 from performant-software/feature/udcsl92_project_people
UDCSL #92 - Project people
2 parents 584765b + dd6cebc commit 10cfb7b

File tree

9 files changed

+57
-163
lines changed

9 files changed

+57
-163
lines changed

packages/controlled-vocabulary/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@performant-software/controlled-vocabulary",
3-
"version": "1.0.6",
3+
"version": "1.0.7",
44
"description": "A package of components to allow user to configure dropdown elements. Use with the \"controlled_vocabulary\" gem.",
55
"license": "MIT",
66
"main": "./build/index.js",
@@ -12,8 +12,8 @@
1212
"build": "webpack --mode production && flow-copy-source -v src types"
1313
},
1414
"dependencies": {
15-
"@performant-software/semantic-components": "^1.0.6",
16-
"@performant-software/shared-components": "^1.0.6",
15+
"@performant-software/semantic-components": "^1.0.7",
16+
"@performant-software/shared-components": "^1.0.7",
1717
"i18next": "^21.9.2",
1818
"semantic-ui-react": "^2.1.2",
1919
"underscore": "^1.13.2"

packages/semantic-ui/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@performant-software/semantic-components",
3-
"version": "1.0.6",
3+
"version": "1.0.7",
44
"description": "A package of shared components based on the Semantic UI Framework.",
55
"license": "MIT",
66
"main": "./build/index.js",
@@ -12,7 +12,7 @@
1212
"build": "webpack --mode production && flow-copy-source -v src types"
1313
},
1414
"dependencies": {
15-
"@performant-software/shared-components": "^1.0.6",
15+
"@performant-software/shared-components": "^1.0.7",
1616
"@react-google-maps/api": "^2.8.1",
1717
"axios": "^0.26.1",
1818
"citeproc": "^2.4.62",

packages/shared/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@performant-software/shared-components",
3-
"version": "1.0.6",
3+
"version": "1.0.7",
44
"description": "A package of shared, framework agnostic, components.",
55
"license": "MIT",
66
"main": "./build/index.js",

packages/storybook/src/visualize/TreeGraph.stories.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export default {
1212
};
1313

1414
const data = {
15-
name: 'T',
15+
name: 'A',
1616
isExpanded: true,
1717
children: [
1818
{
@@ -89,8 +89,22 @@ export const Default = () => {
8989
data={items}
9090
layout={select('Layout', ['cartesian', 'polar'])}
9191
linkType={select('Link Type', ['curve', 'line', 'step'])}
92-
onClick={(node) => setItems(updateNode(node, items))}
9392
orientation={select('Orientation', ['horizontal', 'vertical'])}
93+
renderNode={(node) => (
94+
<button
95+
onClick={() => setItems(updateNode(node, items))}
96+
style={{
97+
backgroundColor: '#FFF',
98+
border: '1px solid black',
99+
cursor: 'pointer',
100+
padding: '10px',
101+
width: 'fit-content'
102+
}}
103+
type='button'
104+
>
105+
{ node.name }
106+
</button>
107+
)}
94108
/>
95109
</div>
96110
);

packages/user-defined-fields/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@performant-software/user-defined-fields",
3-
"version": "1.0.6",
3+
"version": "1.0.7",
44
"description": "A package of components used for allowing end users to define fields on models. Use with the \"user_defined_fields\" gem.",
55
"license": "MIT",
66
"main": "./build/index.js",
@@ -9,8 +9,8 @@
99
"build": "webpack --mode production && flow-copy-source -v src types"
1010
},
1111
"dependencies": {
12-
"@performant-software/semantic-components": "^1.0.6",
13-
"@performant-software/shared-components": "^1.0.6",
12+
"@performant-software/semantic-components": "^1.0.7",
13+
"@performant-software/shared-components": "^1.0.7",
1414
"i18next": "^21.9.1",
1515
"semantic-ui-react": "^2.1.2",
1616
"underscore": "^1.13.2"

packages/visualize/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@performant-software/visualize",
3-
"version": "1.0.6",
3+
"version": "1.0.7",
44
"description": "A package of components used for data visualization",
55
"license": "MIT",
66
"main": "./build/index.js",

packages/visualize/src/components/TreeGraph.js

Lines changed: 26 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import './TreeGraph.css';
3232

3333
type Props = ZoomProps & {
3434
data: any,
35-
fontSize: number,
3635
layout: string,
3736
linkType: string,
3837
offset: number,
@@ -47,12 +46,8 @@ type Props = ZoomProps & {
4746
bottom: number,
4847
left: number
4948
},
50-
nodeWidth: number,
51-
onClick?: (data: any) => void,
5249
renderNode?: (data: any) => Element<any>,
53-
renderText?: (data: any) => Element<any>,
54-
stepPercent: number,
55-
textColor: string
50+
stepPercent: number
5651
};
5752

5853
const Layout = {
@@ -71,19 +66,6 @@ const Orientation = {
7166
vertical: 'vertical'
7267
};
7368

74-
const Circle: ComponentType<any> = (props: any) => (
75-
<circle
76-
r={props.radius}
77-
{...props}
78-
/>
79-
);
80-
81-
const Rectangle: ComponentType<any> = (props: any) => (
82-
<rect
83-
{...props}
84-
/>
85-
);
86-
8769
const TreeGraph = (props: Props) => {
8870
const ref = useRef();
8971

@@ -210,59 +192,11 @@ const TreeGraph = (props: Props) => {
210192
};
211193
}, [getMaxDepth, innerHeight, innerWidth, props.data, props.layout, props.orientation]);
212194

213-
/**
214-
* Renders the passed node. If provided, only the "renderNode" prop is called.
215-
*
216-
* @type {(function(*): (*))|*}
217-
*/
218-
const renderNode = useCallback((node) => {
219-
if (props.renderNode) {
220-
return props.renderNode(node.data);
221-
}
222-
223-
if (node.depth === 0) {
224-
return (
225-
<Circle
226-
fill='#FF4A4A'
227-
onClick={props.onClick && props.onClick.bind(this, node.data)}
228-
/>
229-
);
230-
}
231-
232-
return (
233-
<Rectangle
234-
fill='#272b4d'
235-
stroke={node.data.children ? '#03c0dc' : '#26deb0'}
236-
strokeWidth={1}
237-
strokeDasharray={node.data.children ? '0' : '2,2'}
238-
strokeOpacity={node.data.children ? 1 : 0.6}
239-
rx={node.data.children ? 0 : 10}
240-
onClick={props.onClick && props.onClick.bind(this, node.data)}
241-
/>
242-
);
243-
}, [props.onClick, props.renderNode]);
244-
245-
/**
246-
* Renders the text for the passed node.
247-
*
248-
* @type {(function(*): (*))|*}
249-
*/
250-
const renderText = useCallback((node) => {
251-
if (props.renderText) {
252-
return props.renderText(node.data);
253-
}
254-
255-
return (
256-
<text
257-
dy='0.33em'
258-
fontSize={props.fontSize}
259-
textAnchor='middle'
260-
fill={props.textColor}
261-
>
262-
{ node.data.name }
263-
</text>
264-
);
265-
}, [props.renderText]);
195+
const renderNode = useCallback((node) => (
196+
<foreignObject>
197+
{ props.renderNode(node.data) }
198+
</foreignObject>
199+
), [props.renderNode]);
266200

267201
/**
268202
* Renders the group element for the passed node.
@@ -274,15 +208,16 @@ const TreeGraph = (props: Props) => {
274208

275209
return (
276210
<Group
211+
nodeleft={left}
212+
nodetop={top}
277213
top={top}
278214
left={left}
279215
key={key}
280216
>
281217
{ renderNode(node) }
282-
{ renderText(node) }
283218
</Group>
284219
);
285-
}, [renderNode, renderText, props.layout, props.orientation]);
220+
}, [renderNode, props.layout, props.orientation, props.linkType]);
286221

287222
/**
288223
* Resizes the "circle" and "rect" elements based on the text contained in the group. This effect will also
@@ -291,81 +226,32 @@ const TreeGraph = (props: Props) => {
291226
useEffect(() => {
292227
const { current } = ref;
293228
if (current) {
294-
const padding = 15;
295229
const groups = current.getElementsByTagName('g');
296230
_.each(groups, (group) => {
297-
const circle = _.first(group.getElementsByTagName('circle'));
298-
const rect = _.first(group.getElementsByTagName('rect'));
299-
300-
const text = _.first(group.getElementsByTagName('text'));
301-
const { height } = text.getBBox();
302-
303-
if (!text.getElementsByTagName('tspan').length) {
304-
const words = text.innerHTML.split(/\s+/);
231+
const object = _.first(group.getElementsByTagName('foreignObject'));
232+
if (object && object.firstChild) {
233+
const { offsetWidth: width, offsetHeight: height } = object.firstChild;
305234

306-
const lines = [];
307-
let lineIndex = 0;
235+
// Set the width and height of the foreignObject element
236+
object.setAttribute('width', width);
237+
object.setAttribute('height', height);
308238

309-
for (let i = 0; i < words.length; i += 1) {
310-
// Initialize the line array for the current line
311-
if (!lines[lineIndex]) {
312-
lines[lineIndex] = [];
313-
}
239+
// Transform the position of the group element based on the width and height of the contents
240+
const leftPosition = parseFloat(group.getAttribute('nodeleft'));
241+
const topPosition = parseFloat(group.getAttribute('nodetop'));
314242

315-
// Add the current word to the current line
316-
lines[lineIndex].push(words[i]);
317-
318-
// Look ahead to the next word and increment the line index if necessary
319-
if (i < words.length - 1) {
320-
const testElement = text.cloneNode();
321-
testElement.innerHTML = [...lines[lineIndex], words[i + 1]].join(' ');
322-
group.append(testElement);
323-
324-
if (testElement.getBBox().width > props.nodeWidth) {
325-
lineIndex += 1;
326-
}
327-
328-
testElement.remove();
329-
}
330-
}
331-
332-
// Append the lines to the text element
333-
_.each(lines, (line, index) => {
334-
const tspan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
335-
tspan.setAttribute('x', '0');
336-
if (index > 0) {
337-
tspan.setAttribute('dy', `${height}px`);
338-
}
339-
tspan.appendChild(document.createTextNode(line.join(' ')));
340-
341-
if (index === 0) {
342-
text.replaceChildren(tspan);
343-
} else {
344-
text.appendChild(tspan);
345-
}
346-
});
347-
348-
// Set the shape attributes based on the text size
349-
const bbox = text.getBBox();
350-
if (circle && text) {
351-
circle.setAttribute('x', bbox.x - padding);
352-
circle.setAttribute('y', bbox.y - padding);
353-
circle.setAttribute('r', (bbox.width / 2) + padding);
354-
} else if (rect && text) {
355-
rect.setAttribute('x', bbox.x - padding);
356-
rect.setAttribute('y', bbox.y - padding);
357-
rect.setAttribute('width', bbox.width + 2 * padding);
358-
rect.setAttribute('height', bbox.height + 2 * padding);
243+
if (!_.isNaN(leftPosition) && !_.isNaN(topPosition)) {
244+
const transform = `translate(${leftPosition - (width / 2.0)}, ${topPosition - (height / 2.0)})`;
245+
group.setAttribute('transform', transform);
359246
}
360247
}
361248
});
362249
}
363-
}, [props.data]);
250+
}, [props.data, props.layout, props.orientation, props.linkType]);
364251

365252
return (
366253
<div
367254
className='tree-graph'
368-
ref={ref}
369255
style={{
370256
display: 'flex',
371257
flexGrow: '1'
@@ -389,8 +275,9 @@ const TreeGraph = (props: Props) => {
389275
>
390276
{ (tree) => (
391277
<Group
392-
top={root.origin.y}
278+
innerRef={ref}
393279
left={root.origin.x}
280+
top={root.origin.y}
394281
>
395282
{ tree.links().map((link, i) => (
396283
<LinkComponent
@@ -413,7 +300,6 @@ const TreeGraph = (props: Props) => {
413300
};
414301

415302
TreeGraph.defaultProps = {
416-
fontSize: 12,
417303
layout: Layout.cartesian,
418304
linkColor: '#B2B09B',
419305
linkType: LinkType.line,
@@ -424,20 +310,10 @@ TreeGraph.defaultProps = {
424310
right: 30,
425311
bottom: 70
426312
},
427-
nodeWidth: 75,
428313
offset: 0,
429314
orientation: Orientation.horizontal,
430-
stepPercent: 0.5,
431-
textColor: '#FFFFFF'
432-
};
433-
434-
type TreeGraphType = ComponentType<any> & {
435-
Circle: typeof Circle,
436-
Rectangle: typeof Rectangle
315+
stepPercent: 0.5
437316
};
438317

439-
const TreeGraphComponent: TreeGraphType = withParentSize(withZoom(TreeGraph));
440-
TreeGraphComponent.Circle = Circle;
441-
TreeGraphComponent.Rectangle = Rectangle;
442-
318+
const TreeGraphComponent: ComponentType<any> = withParentSize(withZoom(TreeGraph));
443319
export default TreeGraphComponent;

packages/visualize/src/hooks/Zoom.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
.zoom {
2+
position: relative;
3+
}
4+
15
.zoom .btn {
26
margin: 0;
37
text-align: center;

react-components.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
"packages/user-defined-fields",
77
"packages/visualize"
88
],
9-
"version": "1.0.6"
9+
"version": "1.0.7"
1010
}

0 commit comments

Comments
 (0)