Skip to content

Commit 78ba6fa

Browse files
Merge pull request #17 from caitlinchan23/renderTab
Render Tab & Toggle Created
2 parents 736b5dd + 7c2d810 commit 78ba6fa

File tree

5 files changed

+289
-235
lines changed

5 files changed

+289
-235
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@
112112
"@fortawesome/free-regular-svg-icons": "^5.15.1",
113113
"@fortawesome/free-solid-svg-icons": "^5.15.1",
114114
"@fortawesome/react-fontawesome": "^0.1.12",
115+
"@material-ui/core": "^4.11.2",
115116
"@visx/axis": "^1.0.0",
116117
"@visx/brush": "^1.2.0",
117118
"@visx/clip-path": "^1.0.0",

src/app/components/BarGraph.tsx

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
// @ts-nocheck
2+
import React from 'react';
3+
import { BarStack } from '@visx/shape';
4+
import { SeriesPoint } from '@visx/shape/lib/types';
5+
import { Group } from '@visx/group';
6+
import { Grid } from '@visx/grid';
7+
import { AxisBottom, AxisLeft } from '@visx/axis';
8+
import { scaleBand, scaleLinear, scaleOrdinal } from '@visx/scale';
9+
import { useTooltip, useTooltipInPortal, defaultStyles } from '@visx/tooltip';
10+
import { Text } from '@visx/text';
11+
import { schemeSet3 } from 'd3-scale-chromatic';
12+
import snapshots from './snapshots';
13+
import { onHover, onHoverExit } from '../actions/actions';
14+
import { useStoreContext } from '../store'
15+
16+
/* TYPESCRIPT */
17+
interface data {
18+
snapshotId?: string;
19+
}
20+
21+
interface margin { top: number; right: number; bottom: number; left: number };
22+
23+
interface snapshot {
24+
snapshotId?: string;
25+
children: [];
26+
componentData: any;
27+
name: string;
28+
state: string;
29+
}
30+
31+
interface TooltipData {
32+
bar: SeriesPoint<snapshot>;
33+
key: string;
34+
index: number;
35+
height: number;
36+
width: number;
37+
x: number;
38+
y: number;
39+
color: string;
40+
}
41+
42+
/* DEFAULTS */
43+
const margin = { top: 60, right: 30, bottom: 0, left: 50 };
44+
const axisColor = '#62d6fb';
45+
const background = '#242529';
46+
const tooltipStyles = {
47+
...defaultStyles,
48+
minWidth: 60,
49+
backgroundColor: 'rgba(0,0,0,0.9)',
50+
color: 'white',
51+
fontSize: '14px',
52+
lineHeight: '18px',
53+
fontFamily: 'Roboto'
54+
};
55+
56+
const BarGraph = (props) => {
57+
const [{ tabs, currentTab }, dispatch] = useStoreContext();
58+
const { width, height, data } = props;
59+
console.log('data: ', data)
60+
const {
61+
tooltipOpen, tooltipLeft, tooltipTop, tooltipData, hideTooltip, showTooltip,
62+
} = useTooltip<TooltipData>();
63+
let tooltipTimeout: number;
64+
const { containerRef, TooltipInPortal } = useTooltipInPortal();
65+
66+
const keys = Object.keys(data.componentData);
67+
68+
// data accessor (used to generate scales) and formatter (add units for on hover box)
69+
const getSnapshotId = (d: snapshot) => d.snapshotId;
70+
const formatSnapshotId = (id) => `Snapshot ID: ${id}`;
71+
const formatRenderTime = (time) => `${time} ms `;
72+
73+
// create visualization SCALES with cleaned data
74+
const snapshotIdScale = scaleBand<string>({
75+
domain: data.barStack.map(getSnapshotId),
76+
padding: 0.2,
77+
});
78+
79+
const renderingScale = scaleLinear<number>({
80+
domain: [0, data.maxTotalRender],
81+
nice: true,
82+
});
83+
84+
const colorScale = scaleOrdinal<string>({
85+
domain: keys,
86+
range: schemeSet3,
87+
});
88+
89+
// setting max dimensions and scale ranges
90+
91+
const xMax = width - margin.left - margin.right;
92+
const yMax = height - margin.top - 150;
93+
snapshotIdScale.rangeRound([0, xMax]);
94+
renderingScale.range([yMax, 0]);
95+
console.log("renderingScale range: ", renderingScale.range([yMax, 0]))
96+
return (
97+
<div>
98+
<svg ref={containerRef} width={width} height={height}>
99+
{}
100+
<rect
101+
x={0}
102+
y={0}
103+
width={width}
104+
height={height}
105+
fill={background}
106+
rx={14}
107+
/>
108+
<Grid
109+
top={margin.top}
110+
left={margin.left}
111+
xScale={snapshotIdScale}
112+
yScale={renderingScale}
113+
width={xMax}
114+
height={yMax}
115+
stroke="black"
116+
strokeOpacity={0.1}
117+
xOffset={snapshotIdScale.bandwidth() / 2}
118+
/>
119+
<Group top={margin.top} left={margin.left}>
120+
<BarStack
121+
data={data.barStack}
122+
keys={keys}
123+
x={getSnapshotId}
124+
xScale={snapshotIdScale}
125+
yScale={renderingScale}
126+
color={colorScale}
127+
>
128+
{barStacks =>
129+
barStacks.map(barStack =>
130+
barStack.bars.map(((bar, idx) => {
131+
// hides new components if components don't exist in previous snapshots
132+
if (Number.isNaN(bar.bar[1]) || bar.height < 0) {
133+
bar.height = 0;
134+
}
135+
return (
136+
<rect
137+
key={`bar-stack-${barStack.index}-${bar.index}`}
138+
x={bar.x}
139+
y={bar.y}
140+
height={bar.height === 0 ? null : bar.height}
141+
width={bar.width}
142+
fill={bar.color}
143+
/* TIP TOOL EVENT HANDLERS */
144+
// Hides tool tip once cursor moves off the current rect
145+
onMouseLeave={() => {
146+
console.log('bar: ', bar)
147+
dispatch(onHoverExit(data.componentData[bar.key].rtid),
148+
tooltipTimeout = window.setTimeout(() => {
149+
hideTooltip()
150+
}, 300))
151+
}}
152+
// Cursor position in window updates position of the tool tip
153+
onMouseMove={event => {
154+
dispatch(onHover(data.componentData[bar.key].rtid))
155+
if (tooltipTimeout) clearTimeout(tooltipTimeout);
156+
const top = event.clientY - margin.top - bar.height;
157+
const left = bar.x + bar.width / 2;
158+
showTooltip({
159+
tooltipData: bar,
160+
tooltipTop: top,
161+
tooltipLeft: left,
162+
});
163+
}}
164+
/>
165+
)})))
166+
}
167+
</BarStack>
168+
</Group>
169+
<AxisLeft
170+
top={margin.top}
171+
left={margin.left}
172+
scale={renderingScale}
173+
stroke={axisColor}
174+
tickStroke={axisColor}
175+
strokeWidth={2}
176+
tickLabelProps={() => ({
177+
fill: 'rgb(231, 231, 231)',
178+
fontSize: 11,
179+
verticalAnchor: 'middle',
180+
textAnchor: 'end',
181+
})}
182+
/>
183+
<AxisBottom
184+
top={yMax + margin.top}
185+
left={margin.left}
186+
scale={snapshotIdScale}
187+
stroke={axisColor}
188+
tickStroke={axisColor}
189+
strokeWidth={2}
190+
tickLabelProps={() => ({
191+
fill: 'rgb(231, 231, 231)',
192+
fontSize: 11,
193+
textAnchor: 'middle',
194+
})}
195+
/>
196+
<Text x={-xMax / 2} y="15" transform="rotate(-90)" fontSize={12} fill="#FFFFFF"> Rendering Time (ms) </Text>
197+
<Text x={xMax / 2} y={yMax + 100} fontSize={12} fill="#FFFFFF"> Snapshot Id </Text>
198+
</svg>
199+
{/* FOR HOVER OVER DISPLAY */}
200+
{tooltipOpen && tooltipData && (
201+
<TooltipInPortal
202+
key={Math.random()} // update tooltip bounds each render
203+
top={tooltipTop}
204+
left={tooltipLeft}
205+
style={tooltipStyles}
206+
>
207+
<div style={{ color: colorScale(tooltipData.key) }}>
208+
{' '}
209+
<strong>{tooltipData.key}</strong>
210+
{' '}
211+
</div>
212+
<div>{data.componentData[tooltipData.key].stateType}</div>
213+
<div>
214+
{' '}
215+
{formatRenderTime(tooltipData.bar.data[tooltipData.key])}
216+
{' '}
217+
</div>
218+
<div>
219+
{' '}
220+
<small>{formatSnapshotId(getSnapshotId(tooltipData.bar.data))}</small>
221+
</div>
222+
</TooltipInPortal>
223+
)}
224+
</div>
225+
)};
226+
227+
export default BarGraph;

0 commit comments

Comments
 (0)