Skip to content

Commit bae1383

Browse files
authored
Merge pull request #7 from oslabs-beta/staging
Updated MVP features
2 parents 2f5c1f2 + f56663f commit bae1383

21 files changed

+4814
-8352
lines changed

package-lock.json

Lines changed: 4437 additions & 8144 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@
106106
"webpack-cli": "^3.3.12"
107107
},
108108
"dependencies": {
109+
"@visx/gradient": "^1.0.0",
110+
"@visx/group": "^1.0.0",
111+
"@visx/hierarchy": "^1.0.0",
112+
"@visx/responsive": "^1.0.0",
113+
"@visx/shape": "^1.0.0",
109114
"acorn": "^7.3.1",
110115
"acorn-jsx": "^5.2.0",
111116
"bower": "^1.8.8",

src/app/actions/actions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,9 @@ export const deleteTab = tab => ({
7777
export const resetSlider = () => ({
7878
type: types.SLIDER_ZERO,
7979
});
80+
81+
export const onHover = () => ({
82+
type: types.ON_HOVER,
83+
//the payload should be something to relate the component we're hovering and highlight that component on the DOM
84+
payload: 'PAYLOAD FROM onHover inside of action.ts'
85+
})

src/app/components/Action.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ interface ActionProps {
3939
*/
4040
// index and delta props were removed from Action.jsx */
4141
// viewIndex and handleonkeyDown added to props
42-
const Action = (props: ActionProps): unknown => {
42+
const Action = (props: ActionProps): JSX.Element => {
4343
const {
4444
selected, last, index, sliderIndex, dispatch, displayName, componentName,
4545
componentData, viewIndex, handleOnkeyDown,
@@ -80,7 +80,7 @@ const Action = (props: ActionProps): unknown => {
8080
return (
8181
<div
8282
// Invoking keyboard functionality; functionality is in ActionContainer;
83-
onKeyDown={(e:string) => handleOnkeyDown(e, viewIndex)}
83+
onKeyDown={(e) => handleOnkeyDown(e, viewIndex)}
8484
className={selected || last ? 'action-component selected' : 'action-component'}
8585
onClick={() => {
8686
dispatch(changeView(index));

src/app/components/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const initialState:{port: null|number,
1010
tabs: {},
1111
};
1212

13-
function App(): unknown {
13+
function App(): JSX.Element {
1414
return (
1515
<StoreContext.Provider value={useReducer(mainReducer, initialState)}>
1616
<MainContainer />
Lines changed: 172 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,179 @@
1-
import React, { Component, useEffect, useState, Fragment } from 'react';
2-
import { Chart } from 'react-google-charts';
3-
4-
function AtomsRelationship(props) {
5-
const { atomsRel } = props;
6-
7-
const atomsAndComp = atomsRel
8-
.filter((e) => e[2] !== 'atoms and selectors')
9-
.map((e) => {
10-
let copy = [...e];
11-
copy[2] = 1;
12-
return [...copy];
13-
});
14-
15-
const atomsAndSelectors = atomsRel
16-
.filter((e) => e[2] === 'atoms and selectors')
17-
.map((e) => {
18-
let copy = [...e];
19-
copy[2] = 1;
20-
return [...copy];
21-
});
22-
23-
const copyatomsRel = atomsRel.map((e) => {
24-
let copy = [...e];
25-
copy[2] = 1;
26-
return copy;
27-
});
28-
const [atoms, setAtoms] = useState([...copyatomsRel]);
29-
const [atomAndSelectorCheck, setAtomAndSelectorCheck] = useState(false);
30-
const [atomAndCompCheck, setAtomAndCompCheck] = useState(false);
31-
32-
useEffect(() => {
33-
if (
34-
(!atomAndSelectorCheck && !atomAndCompCheck) ||
35-
(atomAndSelectorCheck && atomAndCompCheck)
36-
) {
37-
setAtoms(copyatomsRel);
38-
} else if (atomAndSelectorCheck) {
39-
setAtoms(atomsAndSelectors);
40-
} else {
41-
setAtoms(atomsAndComp);
1+
import React, { useMemo } from 'react';
2+
import { Group } from '@visx/group';
3+
import { Cluster, hierarchy } from '@visx/hierarchy';
4+
//import { HierarchyPointNode, HierarchyPointLink } from '@visx/hierarchy/lib/types';
5+
import { LinkVertical } from '@visx/shape';
6+
import { LinearGradient } from '@visx/gradient';
7+
8+
const citrus = '#ddf163';
9+
const white = '#ffffff';
10+
export const green = '#79d259';
11+
const aqua = '#37ac8c';
12+
const merlinsbeard = '#f7f7f3';
13+
export const background = '#242529';
14+
15+
// interface NodeShape {
16+
// name: string;
17+
// children?: NodeShape[];
18+
//
19+
20+
const clusterData = {};
21+
let memoizeObj = {};
22+
23+
function clusterDataPopulate(props) {
24+
let atomCompObj = reorganizedObj(props);
25+
26+
if (props[0].name) {
27+
clusterData.name = props[0].name;
28+
}
29+
30+
let counter = 0;
31+
for (let key in atomCompObj) {
32+
if (atomCompObj[key].length) {
33+
for (let i = 0; i < atomCompObj[key].length; i++) {
34+
if (!memoizeObj[key]) {
35+
memoizeObj[key] = [];
36+
if (!clusterData.children) clusterData.children = [];
37+
clusterData.children.push({ name: key });
38+
}
39+
if (!memoizeObj[key].includes(atomCompObj[key][i])) {
40+
if (!clusterData.children[counter].children)
41+
clusterData.children[counter].children = [];
42+
clusterData.children[counter].children.push({
43+
name: atomCompObj[key][i],
44+
});
45+
}
46+
memoizeObj[key].push(atomCompObj[key][i]);
47+
}
4248
}
43-
}, [atomAndSelectorCheck, atomAndCompCheck, props]);
49+
counter++;
50+
}
51+
}
52+
53+
function reorganizedObj(props) {
54+
let atomsComponentObj = props[0].atomsComponents;
55+
let reorganizedObj = {};
56+
57+
for (const key in atomsComponentObj) {
58+
for (let i = 0; i < atomsComponentObj[key].length; i++) {
59+
if (!reorganizedObj[atomsComponentObj[key][i]]) {
60+
reorganizedObj[atomsComponentObj[key][i]] = [key];
61+
} else {
62+
reorganizedObj[atomsComponentObj[key][i]].push(key);
63+
}
64+
}
65+
}
66+
return reorganizedObj;
67+
}
68+
69+
function Node({ node }) {
70+
const isRoot = node.depth === 0;
71+
const isParent = !!node.children;
72+
73+
if (isRoot) return <RootNode node={node} />;
4474

4575
return (
46-
<div className="history-d3-container">
47-
{atoms && (
48-
<Fragment>
49-
<Chart
50-
width={'100%'}
51-
height={'98%'}
52-
chartType="Sankey"
53-
options={{
54-
sankey: {
55-
link: { color: { fill: '#gray', fillOpacity: 0.1 } },
56-
node: {
57-
colors: [
58-
'#4a91c7',
59-
'#5b9bce',
60-
'#6ba6d5',
61-
'#7bb0dc',
62-
'#8abbe3',
63-
'#99c6ea',
64-
'#a8d0f1',
65-
'#b7dbf8',
66-
'#c6e6ff',
67-
'#46edf2',
68-
'#76f5f3',
69-
'#95B6B7',
70-
'#76dcde',
71-
'#5fdaed',
72-
],
73-
74-
label: { color: '#fff', fontSize: '13', fontName: 'Monaco' },
75-
nodePadding: 50,
76-
width: 15,
77-
},
78-
},
79-
tooltip: { textStyle: { color: 'white', fontSize: 0.1 } },
80-
}}
81-
loader={<div>Loading Chart</div>}
82-
data={[['Atom', 'Selector', ''], ...atoms]}
83-
rootProps={{ 'data-testid': '1' }}
84-
/>
85-
<div>
86-
<input
87-
type="checkbox"
88-
id="atomscomps"
89-
onClick={(e) =>
90-
setAtomAndCompCheck(atomAndCompCheck ? false : true)
91-
}
92-
/>
93-
<label htmlFor="atomscomps">
94-
{' '}
95-
Only Show Atoms (or Selectors) and Components{' '}
96-
</label>
97-
<input
98-
type="checkbox"
99-
id="atomsselectors"
100-
onClick={(e) =>
101-
setAtomAndSelectorCheck(atomAndSelectorCheck ? false : true)
102-
}
103-
/>
104-
<label htmlFor="atomsselectors">
105-
{' '}
106-
Only Show Atoms and Selectors{' '}
107-
</label>
108-
</div>
109-
</Fragment>
76+
<Group top={node.y} left={node.x}>
77+
{node.depth !== 0 && (
78+
<circle
79+
r={12}
80+
fill={background}
81+
stroke={isParent ? white : citrus}
82+
// onClick={() => {
83+
// alert(`clicked: ${JSON.stringify(node.data.name)}`);
84+
// }}
85+
/>
11086
)}
111-
</div>
87+
<text
88+
dy=".33em"
89+
fontSize={9}
90+
fontFamily="Arial"
91+
textAnchor="middle"
92+
style={{ pointerEvents: 'none' }}
93+
fill={isParent ? white : citrus}
94+
>
95+
{node.data.name}
96+
</text>
97+
</Group>
11298
);
11399
}
114100

115-
export default AtomsRelationship;
101+
function RootNode({ node }) {
102+
const width = 40;
103+
const height = 20;
104+
const centerX = -width / 2;
105+
const centerY = -height / 2;
106+
107+
return (
108+
<Group top = {node.y} left = {node.x}>
109+
<rect
110+
width={width}
111+
height={height}
112+
y={centerY}
113+
x={centerX}
114+
fill="url('#top')"
115+
/>
116+
<text
117+
dy=".33em"
118+
top= {node.y}
119+
left = {node.x}
120+
fontSize={9}
121+
fontFamily="Arial"
122+
textAnchor="middle"
123+
style={{ pointerEvents: 'none' }}
124+
fill={background}
125+
>
126+
{node.data.name}
127+
</text>
128+
</Group>
129+
);
130+
}
131+
132+
const defaultMargin = { top: 40, left: 0, right: 0, bottom: 40};
133+
134+
// export type DendrogramProps = {
135+
// width: number;
136+
// height: number;
137+
// margin?: { top: number; right: number; bottom: number; left: number };
138+
// };
139+
140+
export default function Example({
141+
width,
142+
height,
143+
margin = defaultMargin,
144+
snapshots,
145+
}) {
146+
147+
clusterDataPopulate(snapshots);
148+
149+
const data = useMemo(() => hierarchy(clusterData), []);
150+
const xMax = width - margin.left - margin.right;
151+
const yMax = height - margin.top - margin.bottom;
152+
153+
return width < 10 ? null : (
154+
<svg width={width} height={height}>
155+
<LinearGradient id="top" from={green} to={aqua} />
156+
<rect width={width} height={height} rx={14} fill={background} />
157+
158+
<Cluster root={data} size={[xMax, yMax]}>
159+
{(cluster) => (
160+
<Group top={margin.top} left={margin.left}>
161+
{cluster.links().map((link, i) => (
162+
<LinkVertical
163+
key={`cluster-link-${i}`}
164+
data={link}
165+
stroke={merlinsbeard}
166+
strokeWidth="1"
167+
strokeOpacity={0.2}
168+
fill="none"
169+
/>
170+
))}
171+
{cluster.descendants().map((node, i) => (
172+
<Node key={`cluster-node-${i}`} node={node} />
173+
))}
174+
</Group>
175+
)}
176+
</Cluster>
177+
</svg>
178+
);
179+
}

src/app/components/ComponentMap.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import React, { useEffect, useCallback } from 'react';
88
import * as d3 from 'd3';
9+
import { useStoreContext } from '../store'
10+
import { onHover } from '../actions/actions'
911

1012
interface componentMapProps {
1113
x: number;
@@ -22,7 +24,6 @@ const ComponentMap = (props: componentMapProps) => {
2224
let lastSnap: number | null = null;
2325
if (viewIndex < 0) lastSnap = snapshots.length - 1;
2426
else lastSnap = viewIndex;
25-
2627
//external constants
2728
const width: any = '100vw';
2829
const height: any = '100vh';
@@ -34,6 +35,7 @@ const ComponentMap = (props: componentMapProps) => {
3435
return makeChart(data);
3536
}, [data]);
3637

38+
const [{ tabs, currentTab }, dispatch] = useStoreContext();
3739
const makeChart = useCallback(
3840
(data) => {
3941
// Establish Constants
@@ -145,10 +147,12 @@ const ComponentMap = (props: componentMapProps) => {
145147

146148
//TODO -> Alter incoming snapshots so there is useful data to show on hover.
147149
nodeEnter.on('mouseover', function (d: any, i: number): any {
148-
150+
//onHover is an action in progress
151+
dispatch(onHover());
149152
d3.select(this)
150153
.append('text')
151154
.text(() => {
155+
//i want to return to the node in d3 the values listed in a more readable way. Right now it's just a horizontal line of text
152156
return JSON.stringify(d.data.state);
153157
})
154158
.attr('x', -25)
@@ -158,6 +162,8 @@ const ComponentMap = (props: componentMapProps) => {
158162
.attr('stroke', 'white')
159163
.attr('stroke-width', .5)
160164
.attr('id', `popup${i}`);
165+
166+
161167

162168
});
163169
nodeEnter.on('mouseout', function (d: any, i: number): any {

src/app/components/DiffRoute.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ interface DiffRouteProps{
1111
state?: string | unknown
1212
stateSnaphot?: Record<string, unknown>;
1313
children?: unknown[];
14+
atomSelectors?:object;
15+
atomsComponents?:object
1416
}>;
1517
}
1618

17-
const DiffRoute = (props: DiffRouteProps): unknown => (
19+
const DiffRoute = (props: DiffRouteProps): JSX.Element => (
1820

1921
<Router>
2022
<div className="navbar">

0 commit comments

Comments
 (0)