@grafana/flamegraph
Version:
Grafana flamegraph visualization component
170 lines (167 loc) • 5.04 kB
JavaScript
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
import { cx, css } from '@emotion/css';
import { useState, useEffect } from 'react';
import { Icon } from '@grafana/ui';
import { PIXELS_PER_LEVEL } from '../constants.mjs';
import FlameGraphCanvas from './FlameGraphCanvas.mjs';
import FlameGraphMetadata from './FlameGraphMetadata.mjs';
const FlameGraph = ({
data,
rangeMin,
rangeMax,
matchedLabels,
setRangeMin,
setRangeMax,
onItemFocused,
focusedItemData,
textAlign,
onSandwich,
sandwichItem,
onFocusPillClick,
onSandwichPillClick,
colorScheme,
showFlameGraphOnly,
getExtraContextMenuButtons,
collapsing,
selectedView,
search,
collapsedMap,
setCollapsedMap
}) => {
const styles = getStyles();
const [levels, setLevels] = useState();
const [levelsCallers, setLevelsCallers] = useState();
const [totalProfileTicks, setTotalProfileTicks] = useState(0);
const [totalProfileTicksRight, setTotalProfileTicksRight] = useState();
const [totalViewTicks, setTotalViewTicks] = useState(0);
useEffect(() => {
var _a, _b, _c;
if (data) {
let levels2 = data.getLevels();
let totalProfileTicks2 = levels2.length ? levels2[0][0].value : 0;
let totalProfileTicksRight2 = levels2.length ? levels2[0][0].valueRight : void 0;
let totalViewTicks2 = totalProfileTicks2;
let levelsCallers2 = void 0;
if (sandwichItem) {
const [callers, callees] = data.getSandwichLevels(sandwichItem);
levels2 = callees;
levelsCallers2 = callers;
totalViewTicks2 = (_c = (_b = (_a = callees[0]) == null ? void 0 : _a[0]) == null ? void 0 : _b.value) != null ? _c : 0;
}
setLevels(levels2);
setLevelsCallers(levelsCallers2);
setTotalProfileTicks(totalProfileTicks2);
setTotalProfileTicksRight(totalProfileTicksRight2);
setTotalViewTicks(totalViewTicks2);
}
}, [data, sandwichItem]);
if (!levels) {
return null;
}
const commonCanvasProps = {
data,
rangeMin,
rangeMax,
matchedLabels,
setRangeMin,
setRangeMax,
onItemFocused,
focusedItemData,
textAlign,
onSandwich,
colorScheme,
totalProfileTicks,
totalProfileTicksRight,
totalViewTicks,
showFlameGraphOnly,
collapsedMap,
setCollapsedMap,
getExtraContextMenuButtons,
collapsing,
search,
selectedView
};
let canvas = null;
if (levelsCallers == null ? void 0 : levelsCallers.length) {
canvas = /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsxs("div", { className: styles.sandwichCanvasWrapper, children: [
/* @__PURE__ */ jsxs("div", { className: styles.sandwichMarker, children: [
"Callers",
/* @__PURE__ */ jsx(Icon, { className: styles.sandwichMarkerIcon, name: "arrow-down" })
] }),
/* @__PURE__ */ jsx(
FlameGraphCanvas,
{
...commonCanvasProps,
root: levelsCallers[levelsCallers.length - 1][0],
depth: levelsCallers.length,
direction: "parents",
collapsing: false
}
)
] }),
/* @__PURE__ */ jsxs("div", { className: styles.sandwichCanvasWrapper, children: [
/* @__PURE__ */ jsxs("div", { className: cx(styles.sandwichMarker, styles.sandwichMarkerCalees), children: [
/* @__PURE__ */ jsx(Icon, { className: styles.sandwichMarkerIcon, name: "arrow-up" }),
"Callees"
] }),
/* @__PURE__ */ jsx(
FlameGraphCanvas,
{
...commonCanvasProps,
root: levels[0][0],
depth: levels.length,
direction: "children",
collapsing: false
}
)
] })
] });
} else if (levels == null ? void 0 : levels.length) {
canvas = /* @__PURE__ */ jsx(FlameGraphCanvas, { ...commonCanvasProps, root: levels[0][0], depth: levels.length, direction: "children" });
}
return /* @__PURE__ */ jsxs("div", { className: styles.graph, children: [
/* @__PURE__ */ jsx(
FlameGraphMetadata,
{
data,
focusedItem: focusedItemData,
sandwichedLabel: sandwichItem,
totalTicks: totalViewTicks,
onFocusPillClick,
onSandwichPillClick
}
),
canvas
] });
};
const getStyles = () => ({
graph: css({
label: "graph",
overflow: "auto",
flexGrow: 1,
flexBasis: "50%"
}),
sandwichCanvasWrapper: css({
label: "sandwichCanvasWrapper",
display: "flex",
marginBottom: `${PIXELS_PER_LEVEL / window.devicePixelRatio}px`
}),
sandwichMarker: css({
label: "sandwichMarker",
writingMode: "vertical-lr",
transform: "rotate(180deg)",
overflow: "hidden",
whiteSpace: "nowrap"
}),
sandwichMarkerCalees: css({
label: "sandwichMarkerCalees",
textAlign: "right"
}),
sandwichMarkerIcon: css({
label: "sandwichMarkerIcon",
verticalAlign: "baseline"
})
});
export { FlameGraph as default };
//# sourceMappingURL=FlameGraph.mjs.map