Skip to content

Commit 219c9aa

Browse files
committed
working intial functional version
1 parent 49a32e8 commit 219c9aa

File tree

1 file changed

+170
-147
lines changed

1 file changed

+170
-147
lines changed

src/app/components/PerfView.jsx

Lines changed: 170 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,46 @@
1+
/* eslint-disable indent */
12
/* eslint-disable react/destructuring-assignment */
23
/* eslint-disable react/prop-types */
34
/* eslint-disable no-console */
45
import React, { useEffect, useRef } from 'react';
56
import * as d3 from 'd3';
67

8+
79
// let root = {};
810
const chartData = {
9-
name: 'flare',
11+
name: 'App',
1012
children: [
11-
{
12-
name: 'analytics',
13-
children: [
14-
{
15-
name: 'cluster',
16-
children: [
17-
{ name: 'AgglomerativeCluster', size: 3938 },
18-
{ name: 'CommunityStructure', size: 3812 },
19-
{ name: 'MergeEdge', size: 743 },
20-
],
21-
},
22-
{
23-
name: 'graph',
24-
children: [
25-
{ name: 'BetweennessCentrality', size: 3534 },
26-
{ name: 'LinkDistance', size: 5731 },
27-
],
28-
},
29-
],
30-
},
13+
{ name: 'DisplayPanel', value: 17010 },
14+
{ name: 'AltDisplay', value: 5842 },
15+
{
16+
name: 'Button Panel',
17+
children: [
18+
{ name: 'Button', value: 10000 },
19+
{ name: 'Button', value: 2047 },
20+
{ name: 'Button', value: 1375 },
21+
{ name: 'Button', value: 8746 },
22+
{ name: 'Button', value: 2202 },
23+
{ name: 'Button', value: 1382 },
24+
{ name: 'Button', value: 1629 },
25+
{ name: 'Button', value: 1675 },
26+
{ name: 'Button', value: 2042 },
27+
],
28+
},
29+
{ name: 'MarketSContainer', value: 1041 },
30+
{ name: 'MainSlider', value: 5176 },
31+
{ name: 'Tree', value: 449 },
32+
{ name: 'AnotherTree', value: 5593 },
33+
{ name: 'TreeOfTrees', value: 5534 },
34+
{ name: 'KanyeWest', value: 9201 },
35+
{ name: 'ElectricMeatloaf', value: 19975 },
36+
{ name: 'GuidoTheKillerPimp', value: 1116 },
37+
{ name: 'Gravy', value: 6006 },
3138
],
32-
};
39+
};
3340

34-
const PerfView = ({ width, height }) => {
35-
console.log('Rendering Performance - chartData: ', chartData);
3641

37-
const d3gRef = useRef(null);
42+
const PerfView = ({ width, height }) => {
43+
const svgRef = useRef(null);
3844
// returns color scale function
3945
const color = d3.scaleLinear()
4046
.domain([0, 5])
@@ -49,37 +55,157 @@ const PerfView = ({ width, height }) => {
4955
};
5056

5157
// create a new circle packing layout function
52-
const pack = data => d3.pack()
58+
const packFunc = data => d3.pack()
5359
.size([width, height])
5460
.padding(3)(d3.hierarchy(data)
5561
.sum(d => d.value)
5662
.sort((a, b) => b.value - a.value));
5763

5864
useEffect(() => {
59-
const hierarchy = d3.hierarchy(chartData);
60-
console.log('PerfView -> hierarchy', hierarchy);
61-
62-
const dataRoot = pack(hierarchy);
63-
console.log('PerfView -> dataRoot', dataRoot);
64-
65-
const gElem = d3.select(d3gRef);
66-
67-
gElem.selectAll('circle')
68-
.data(dataRoot.descendants().slice(1))
69-
.enter().append('circle')
70-
.attr('fill', d => (d.children ? color(d.depth) : 'white'));
65+
// const hierarchy = d3.hierarchy(chartData);
66+
const packedRoot = packFunc(chartData);
67+
console.log('** PerfView -> packedRoot', packedRoot);
68+
let focus = packedRoot;
69+
let view;
70+
71+
const svg = d3.select(svgRef.current)
72+
.attr('class', 'd3Container')
73+
.attr('viewBox', `-${width / 2} -${height / 2} ${width} ${height}`)
74+
.style('display', 'block')
75+
.style('margin', '0 -14px')
76+
.style('background', color(0))
77+
.style('cursor', 'pointer')
78+
.on('click', () => zoom(packedRoot));
79+
80+
console.log('packedRoot.descendents().slice(1)', packedRoot.descendants().slice(1));
81+
82+
const node = svg.append('g')
83+
.selectAll('circle')
84+
.data(packedRoot.descendants().slice(1))
85+
// .join('circle')
86+
.enter()
87+
.append('circle')
88+
.attr('fill', d => (d.children ? color(d.depth) : 'white'))
89+
.attr('pointer-events', d => (!d.children ? 'none' : null))
90+
.on('mouseover', function () { d3.select(this).attr('stroke', '#000'); })
91+
.on('mouseout', function () { d3.select(this).attr('stroke', null); })
92+
.on('click', d => focus !== d && (zoom(d), d3.event.stopPropagation()));
93+
94+
const label = svg.append('g')
95+
.style('font', '10px sans-serif')
96+
.attr('pointer-events', 'none')
97+
.attr('text-anchor', 'middle')
98+
.selectAll('text')
99+
.data(packedRoot.descendants())
100+
// .join('text')
101+
.enter()
102+
.append('text')
103+
.style('fill-opacity', d => (d.parent === packedRoot ? 1 : 0))
104+
.style('display', d => (d.parent === packedRoot ? 'inline' : 'none'))
105+
.text(d => d.data.name);
106+
107+
console.log('PerfView -> node', node);
108+
zoomTo([packedRoot.x, packedRoot.y, packedRoot.r * 2]);
109+
110+
function zoomTo(v) {
111+
const k = width / v[2];
112+
view = v;
113+
114+
label.attr('transform', d => `translate(${(d.x - v[0]) * k},${(d.y - v[1]) * k})`);
115+
node.attr('transform', d => `translate(${(d.x - v[0]) * k},${(d.y - v[1]) * k})`);
116+
node.attr('r', d => d.r * k);
117+
}
118+
119+
function zoom(d) {
120+
const focus0 = focus;
121+
122+
focus = d;
123+
124+
const transition = svg.transition()
125+
.duration(d3.event.altKey ? 7500 : 750)
126+
.tween('zoom', d => {
127+
const i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2]);
128+
return t => zoomTo(i(t));
129+
});
130+
131+
label
132+
.filter(function (d) { return d.parent === focus || this.style.display === 'inline'; })
133+
.transition(transition)
134+
.style('fill-opacity', d => (d.parent === focus ? 1 : 0))
135+
.on('start', function (d) { if (d.parent === focus) this.style.display = 'inline'; })
136+
.on('end', function (d) { if (d.parent !== focus) this.style.display = 'none'; });
137+
}
71138
}, [chartData]);
72139

73-
return (
74-
<svg width={width} height={height} className="d3Container">
75-
<g ref={d3gRef} transform={`translate(${50} ${50})`} />
76-
<rect width="100" height="100" x="50" y="20" />
77-
</svg>
78-
);
140+
return <svg ref={svgRef} />;
79141
};
80142

81143
export default PerfView;
82144

145+
146+
// class PerfView extends React.Component {
147+
// constructor(props) {
148+
// super(props);
149+
// this.svgRef = React.createRef();
150+
151+
// // returns color scale function
152+
// this.color = d3.scaleLinear()
153+
// .domain([0, 5])
154+
// .range(['hsl(152,80%,80%)', 'hsl(228,30%,40%)'])
155+
// .interpolate(d3.interpolateHcl);
156+
157+
// // create a new circle packing layout function
158+
// this.pack = data => d3.pack()
159+
// .size([this.props.width, this.props.height])
160+
// .padding(3)(d3.hierarchy(data)
161+
// .sum(d => d.value)
162+
// .sort((a, b) => b.value - a.value));
163+
164+
// // this.drawChart = this.drawChart.bind(this);
165+
// }
166+
167+
// componentDidMount() {
168+
// const { width, height } = this.props;
169+
170+
// const hierarchy = d3.hierarchy(chartData);
171+
// console.log('PerfView -> hierarchy', hierarchy);
172+
// // const dataRoot = pack(chartData);
173+
// const dataRoot = d3.pack(hierarchy);
174+
// console.log('PerfView -> dataRoot', dataRoot);
175+
176+
// const focus = dataRoot;
177+
// let view;
178+
179+
// const svg = d3.select(this.svgRef.current);
180+
// svg
181+
// .attr('class', 'd3Container')
182+
// .attr('viewBox', `-${width / 2} -${height / 2} ${width} ${height}`)
183+
// .style('display', 'block')
184+
// .style('margin', '0 -14px')
185+
// .style('background', this.color(0))
186+
// .style('cursor', 'pointer');
187+
// // .on("click", () => zoom(root));
188+
// }
189+
190+
// componentDidUpdate() {
191+
// const svg = d3.select(this.ref.current);
192+
// }
193+
194+
// // drawChart() {
195+
// // // const hierarchy = d3.hierarchy(chartData);
196+
// // // const dataRoot = this.pack(hierarchy);
197+
198+
// // d3.create("svg").attr("viewBox", );
199+
200+
// // }
201+
202+
// render() {
203+
// return (
204+
// <svg ref={this.svgRef} />
205+
// );
206+
// }
207+
// }
208+
83209
/* eslint-disable indent */
84210

85211

@@ -97,7 +223,6 @@ export default PerfView;
97223
// treeBaseDuration
98224
// }
99225

100-
101226
// const dataMax = d3.max(props.data);
102227

103228
// const yScale = d3.scaleLinear()
@@ -124,105 +249,3 @@ export default PerfView;
124249
// .attr('y', d => props.size[1] - yScale(d))
125250
// .attr('height', d => yScale(d))
126251
// .attr('width', 25);
127-
128-
129-
// const PerfView = ({ width, height }) => {
130-
// const chartData = {
131-
// name: 'flare',
132-
// children: [
133-
// {
134-
// name: 'analytics',
135-
// children: [
136-
// {
137-
// name: 'cluster',
138-
// children: [
139-
// { name: 'AgglomerativeCluster', size: 3938 },
140-
// { name: 'CommunityStructure', size: 3812 },
141-
// { name: 'MergeEdge', size: 743 },
142-
// ],
143-
// },
144-
// {
145-
// name: 'graph',
146-
// children: [
147-
// { name: 'BetweennessCentrality', size: 3534 },
148-
// { name: 'LinkDistance', size: 5731 },
149-
// ],
150-
// },
151-
// ],
152-
// },
153-
// ],
154-
// };
155-
// console.log('Rendering Performance - chartData: ', chartData);
156-
157-
// const d3gRef = useRef(null);
158-
// // returns color scale function
159-
// const color = d3.scaleLinear()
160-
// .domain([0, 5])
161-
// .range(['hsl(152,80%,80%)', 'hsl(228,30%,40%)'])
162-
// .interpolate(d3.interpolateHcl);
163-
164-
// // returns a function that formats numbers
165-
// const numFormat = d3.format(',d');
166-
167-
// const margin = {
168-
// top: 0, right: 60, bottom: 200, left: 120,
169-
// };
170-
171-
// // create a new circle packing layout function
172-
// const pack = data => d3.pack()
173-
// .size([width, height])
174-
// .padding(3)(d3.hierarchy(data)
175-
// .sum(d => d.value)
176-
// .sort((a, b) => b.value - a.value));
177-
178-
// useEffect(() => {
179-
// const hierarchy = d3.hierarchy(chartData);
180-
// console.log('PerfView -> hierarchy', hierarchy);
181-
// // const dataRoot = pack(chartData);
182-
// const dataRoot = pack(hierarchy);
183-
// console.log('PerfView -> dataRoot', dataRoot);
184-
// // const focus = dataRoot;
185-
// // let view;
186-
187-
// // const svg = d3.create('svg')
188-
// // .attr('viewBox', `-${width / 2} -${height / 2} ${width} ${height}`)
189-
// // .style('display', 'block')
190-
// // .style('margin', '0 -14px')
191-
// // .style('background', color(0))
192-
// // .style('cursor', 'pointer');
193-
// // .on('click', () => zoom(dataRoot));
194-
195-
// const gElem = d3.select(d3gRef);
196-
// // const node = g.append('g')
197-
// const node = gElem.selectAll('circle')
198-
// .data(dataRoot.descendants().slice(1));
199-
// // .join('circle')
200-
// node.enter().append('circle')
201-
// .attr('fill', d => (d.children ? color(d.depth) : 'white'));
202-
// // .attr('pointer-events', d => (!d.children ? 'none' : null))
203-
// // .on('mouseover', function () { d3.select(this).attr('stroke', '#000'); })
204-
// // .on('mouseout', function () { d3.select(this).attr('stroke', null); })
205-
// // .on('click', d => focus !== d && (zoom(d), d3.event.stopPropagation()));
206-
207-
// // const label = g.append('g')
208-
// // .style('font', '10px sans-serif')
209-
// // .attr('pointer-events', 'none')
210-
// // .attr('text-anchor', 'middle')
211-
// // .selectAll('text')
212-
// // .data(dataRoot.descendants())
213-
// // // .join('text')
214-
// // .enter()
215-
// // .append('text')
216-
// // .style('fill-opacity', d => (d.parent === dataRoot ? 1 : 0))
217-
// // .style('display', d => (d.parent === dataRoot ? 'inline' : 'none'))
218-
// // .text(d => d.data.name);
219-
// }, [chartData]);
220-
221-
// // return (<svg ref={d3svgRef} width={width} height={height} />);
222-
// return (
223-
// <svg width={width} height={height} className="d3Container">
224-
// <g ref={d3gRef} transform={`translate(${50} ${50})`} />
225-
// <rect width="100" height="100" x="50" y="20" />
226-
// </svg>
227-
// );
228-
// };

0 commit comments

Comments
 (0)