Skip to content

Commit a235867

Browse files
committed
Merge FlameGraphRendererNew to FlameGraphRenderer
1 parent 5c0f137 commit a235867

File tree

2 files changed

+20
-693
lines changed

2 files changed

+20
-693
lines changed

webapp/javascript/components/FlameGraphRenderer.jsx

Lines changed: 20 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ import { bindActionCreators } from "redux";
2727

2828
import { withShortcut } from "react-keybind";
2929

30-
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
31-
import {
32-
faIcicles,
33-
faColumns,
34-
faBars,
35-
} from "@fortawesome/free-solid-svg-icons";
3630
import { fetchJSON } from "../redux/actions";
3731
import { buildRenderURL } from "../util/update_requests";
3832
import {
@@ -41,6 +35,8 @@ import {
4135
DurationFormater,
4236
} from "../util/format";
4337
import { colorBasedOnPackageName, colorGreyscale } from "../util/color";
38+
import ProfilerTable from "./ProfilerTable";
39+
import ProfilerHeader from "./ProfilerHeader";
4440

4541
const PX_PER_LEVEL = 18;
4642
const COLLAPSE_THRESHOLD = 5;
@@ -155,13 +151,13 @@ class FlameGraphRenderer extends React.Component {
155151
};
156152

157153
// binary search of a block in a stack level
158-
binarySearchLevel(x, level) {
154+
binarySearchLevel(x, level, tickToX) {
159155
let i = 0;
160156
let j = level.length - 4;
161157
while (i <= j) {
162158
const m = 4 * ((i / 4 + j / 4) >> 1);
163-
const x0 = this.tickToX(level[m]);
164-
const x1 = this.tickToX(level[m] + level[m + 1]);
159+
const x0 = tickToX(level[m]);
160+
const x1 = tickToX(level[m] + level[m + 1]);
165161
if (x0 <= x && x1 >= x) {
166162
return x1 - x0 > COLLAPSE_THRESHOLD ? m : -1;
167163
}
@@ -208,7 +204,7 @@ class FlameGraphRenderer extends React.Component {
208204
xyToBar = (x, y) => {
209205
const i = Math.floor(y / PX_PER_LEVEL) + this.topLevel;
210206
if (i >= 0 && i < this.levels.length) {
211-
const j = this.binarySearchLevel(x, this.levels[i]);
207+
const j = this.binarySearchLevel(x, this.levels[i], this.tickToX);
212208
return { i, j };
213209
}
214210
return { i: 0, j: 0 };
@@ -420,50 +416,6 @@ class FlameGraphRenderer extends React.Component {
420416
});
421417
};
422418

423-
renderTable = () => {
424-
if (!this.props.flamebearer) {
425-
return [];
426-
}
427-
428-
if (this.props.flamebearer.numTicks == 0) {
429-
return [];
430-
}
431-
432-
return (
433-
<table className="flamegraph-table">
434-
<thead>
435-
<tr>
436-
<th className="sortable" onClick={() => this.updateSortBy("name")}>
437-
Location
438-
<span
439-
className={clsx("sort-arrow", {
440-
[this.state.sortByDirection]: this.state.sortBy == "name",
441-
})}
442-
/>
443-
</th>
444-
<th className="sortable" onClick={() => this.updateSortBy("self")}>
445-
Self
446-
<span
447-
className={clsx("sort-arrow", {
448-
[this.state.sortByDirection]: this.state.sortBy == "self",
449-
})}
450-
/>
451-
</th>
452-
<th className="sortable" onClick={() => this.updateSortBy("total")}>
453-
Total
454-
<span
455-
className={clsx("sort-arrow", {
456-
[this.state.sortByDirection]: this.state.sortBy == "total",
457-
})}
458-
/>
459-
</th>
460-
</tr>
461-
</thead>
462-
<tbody>{this.renderTableBody()}</tbody>
463-
</table>
464-
);
465-
};
466-
467419
updateSortBy = (newSortBy) => {
468420
let dir = this.state.sortByDirection;
469421
if (this.state.sortBy == newSortBy) {
@@ -477,108 +429,27 @@ class FlameGraphRenderer extends React.Component {
477429
});
478430
};
479431

480-
renderTableBody = () => {
481-
const { numTicks, maxSelf, sampleRate, spyName } = this.props.flamebearer;
482-
483-
const table = generateTable(this.props.flamebearer).sort(
484-
(a, b) => b.total - a.total
485-
);
486-
487-
const { sortBy, sortByDirection } = this.state;
488-
const m = sortByDirection == "asc" ? 1 : -1;
489-
let sorted;
490-
if (sortBy == "name") {
491-
sorted = table.sort((a, b) => m * a[sortBy].localeCompare(b[sortBy]));
492-
} else {
493-
sorted = table.sort((a, b) => m * (a[sortBy] - b[sortBy]));
494-
}
495-
496-
const df = new DurationFormater(this.numTicks / this.sampleRate);
497-
498-
return sorted.map((x) => {
499-
const pn = this.getPackageNameFromStackTrace(spyName, x.name);
500-
const color = colorBasedOnPackageName(pn, 1);
501-
const style = {
502-
backgroundColor: color,
503-
};
504-
return (
505-
<tr key={x.name}>
506-
<td>
507-
<span className="color-reference" style={style} />
508-
<span>{x.name}</span>
509-
</td>
510-
<td style={backgroundImageStyle(x.self, maxSelf, color)}>
511-
{/* <span>{ formatPercent(x.self / numTicks) }</span>
512-
&nbsp;
513-
<span>{ shortNumber(x.self) }</span>
514-
&nbsp; */}
515-
<span title={df.format(x.self / sampleRate)}>
516-
{df.format(x.self / sampleRate)}
517-
</span>
518-
</td>
519-
<td style={backgroundImageStyle(x.total, numTicks, color)}>
520-
{/* <span>{ formatPercent(x.total / numTicks) }</span>
521-
&nbsp;
522-
<span>{ shortNumber(x.total) }</span>
523-
&nbsp; */}
524-
<span title={df.format(x.total / sampleRate)}>
525-
{df.format(x.total / sampleRate)}
526-
</span>
527-
</td>
528-
</tr>
529-
);
530-
});
531-
};
532-
533432
render = () => (
534433
<div className="canvas-renderer">
535434
<div className="canvas-container">
536-
<div className="navbar-2">
537-
<input
538-
className="flamegraph-search"
539-
name="flamegraph-search"
540-
placeholder="Search…"
541-
onChange={this.handleSearchChange}
542-
/>
543-
&nbsp;
544-
<button
545-
className={clsx("btn")}
546-
style={this.state.resetStyle}
547-
id="reset"
548-
onClick={this.reset}
549-
>
550-
Reset View
551-
</button>
552-
<div className="navbar-space-filler" />
553-
<div className="btn-group viz-switch">
554-
<button
555-
className={clsx("btn", { active: this.state.view == "table" })}
556-
onClick={() => this.updateView("table")}
557-
>
558-
<FontAwesomeIcon icon={faBars} />
559-
&nbsp;&thinsp;Table
560-
</button>
561-
<button
562-
className={clsx("btn", { active: this.state.view == "both" })}
563-
onClick={() => this.updateView("both")}
564-
>
565-
<FontAwesomeIcon icon={faColumns} />
566-
&nbsp;&thinsp;Both
567-
</button>
568-
<button
569-
className={clsx("btn", { active: this.state.view == "icicle" })}
570-
onClick={() => this.updateView("icicle")}
571-
>
572-
<FontAwesomeIcon icon={faIcicles} />
573-
&nbsp;&thinsp;Flamegraph
574-
</button>
575-
</div>
576-
</div>
435+
<ProfilerHeader
436+
view={this.state.view}
437+
handleSearchChange={this.handleSearchChange}
438+
reset={this.reset}
439+
updateView={this.updateView}
440+
resetStyle={this.state.resetStyle}
441+
/>
577442
<div className="flamegraph-container panes-wrapper">
578443
<div
579444
className={clsx("pane", { hidden: this.state.view === "icicle" })}
580445
>
581-
{this.renderTable()}
446+
<ProfilerTable
447+
flamebearer={this.props.flamebearer}
448+
sortByDirection={this.state.sortByDirection}
449+
sortBy={this.state.sortBy}
450+
updateSortBy={this.updateSortBy}
451+
view={this.state.view}
452+
/>
582453
</div>
583454
<div
584455
className={clsx("pane", { hidden: this.state.view === "table" })}
@@ -631,42 +502,6 @@ const mapDispatchToProps = (dispatch) => ({
631502
),
632503
});
633504

634-
const backgroundImageStyle = (a, b, color) => {
635-
const w = 148;
636-
const k = w - (a / b) * w;
637-
const clr = color.alpha(1.0);
638-
return {
639-
// backgroundColor: 'transparent',
640-
backgroundImage: `linear-gradient(${clr}, ${clr})`,
641-
backgroundPosition: `-${k}px 0px`,
642-
backgroundRepeat: "no-repeat",
643-
};
644-
};
645-
646-
// generates a table from data in flamebearer format
647-
const generateTable = (data) => {
648-
const table = [];
649-
if (!data) {
650-
return table;
651-
}
652-
const { names, levels } = data;
653-
const hash = {};
654-
for (let i = 0; i < levels.length; i++) {
655-
for (let j = 0; j < levels[i].length; j += 4) {
656-
const key = levels[i][j + 3];
657-
const name = names[key];
658-
hash[name] = hash[name] || {
659-
name: name || "<empty>",
660-
self: 0,
661-
total: 0,
662-
};
663-
hash[name].total += levels[i][j + 1];
664-
hash[name].self += levels[i][j + 2];
665-
}
666-
}
667-
return Object.values(hash);
668-
};
669-
670505
export default connect(
671506
mapStateToProps,
672507
mapDispatchToProps

0 commit comments

Comments
 (0)